/* *** Audio Record Program (for Sun .au format) *** */
/*      Progrmaed by Yoshihiro Satou(hiro@garuda.ee.uec.ac.jp) */
/*      Record Ver 1.1    1995.9.5 */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#ifdef SVR4
#include <sys/sound.h>		/* OS6 */
#else
#include <newsiodev/sound.h>	/* OS4 */
#endif
#include <signal.h>

struct _aheader {
	unsigned long	magic;
	unsigned long	hdr_size;
	unsigned long	data_size;
	unsigned long	encoding;
	unsigned long	sample_rate;
	unsigned long	channels;
	char *dummy;
	} aheader;

#define SOUNDDEV "/dev/sb0"

int	sbfd, fp;
char	*buf;

int datasize(fp)
int fp;
{
  int	data_size;
  struct stat statbuf;

  fstat(fp, &statbuf);			/* check total file size */
  data_size = statbuf.st_size - 28;	/* Note: header_size = 28 */
  lseek(fp, 8, L_SET);			/* seek file_pointer */
  write(fp, &data_size, 4);		/* write true data_size */
  close(fp);
  return(0);
}


void the_end(sig)
int sig;
{
  int	resid;

  /* check rest data_size in buffer _and_ read&write rest data*/
  ioctl(sbfd, SBIOCBUFRESID, &resid);
  read(sbfd, buf, resid);
  write(fp, buf, resid);
  close(sbfd);		/* when read data(from SOUNDEV) end */
  datasize(fp);		/* write true data_size */
  signal(sig, SIG_IGN);
  exit(0);
}


int main(argc, argv)
int argc;  char *argv[];
{
  struct sbparam sbp;
  int bsize, rfrg=1;

  /* signal trap set*/
  if(signal(SIGINT, SIG_IGN) != SIG_IGN)
    signal(SIGINT, the_end);
  if(signal(SIGTERM,SIG_IGN) != SIG_IGN)
    signal(SIGTERM, the_end);

  /* check command option & open record file */
  if(argc == 1) {
    fprintf(stderr, "Usage : record [file] \n");
    exit(0);
  }
  if((fp = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0664)) < 0) {
    perror("file_open");
    exit(1);
  }

  /* open sound device & reset device for prepare */
  if ((sbfd = open(SOUNDDEV, O_RDONLY)) < 0) {
    perror("sb open");
    exit(1);
  }
  if(ioctl(sbfd, SBIOCRESET, 0) < 0) {
    perror("ioctl(SBIOCRESET)");
    exit(1);
  }
  
  /* check sound buffer size & malloc buffer for read/write data */
  ioctl(sbfd, SBIOCBUFSIZE, &bsize);
  if ((buf = (char *)malloc(bsize)) == NULL) {
    perror("sb malloc");
    exit(1);
  }
   
  /* prepare for Sun .au header */
  aheader.magic = (unsigned long)0x2e736e64;
  aheader.hdr_size = 28;
  aheader.data_size = 0;	/* wriet true data_size later */
  aheader.encoding = 1;
  aheader.sample_rate = 8000;
  aheader.channels = 1;
  aheader.dummy = "\0\0\0\0";
  write(fp, &aheader.magic, 4);
  write(fp, &aheader.hdr_size, 4);
  write(fp, &aheader.data_size, 4);
  write(fp, &aheader.encoding, 4);
  write(fp, &aheader.sample_rate, 4);
  write(fp, &aheader.channels, 4);
  write(fp, aheader.dummy, 4);

  /* ok, now main routine... */
  while(rfrg != 0) {
    if((rfrg = read(sbfd, buf, 1)) == -1) {
      perror("audioread");
      exit(1);
    } 
    if((write(fp, buf, 1)) == -1) {
      perror("fileout");
      exit(1);
    }
  }
  close(sbfd);		/* when read data(from SOUNDEV) end */
  datasize(fp);		/* write true data_size */
  exit(0);
}
/* *** ---------------------------------------------------------- *** */
