#include "/usr/users/paul/cmix/H/sfheader.h"
#include <stdio.h>
#include <sys/file.h>
#include <signal.h>
#include <errno.h>

static SFCODE	ampcode = {
	SF_MAXAMP,
	sizeof(SFMAXAMP) + sizeof(SFCODE)
}; 

static SFCODE	commentcode = {
	SF_COMMENT,
	MINCOMM + sizeof(SFCODE)
};

#define NBYTES 16384

main(argc,argv)

int argc;
char *argv[];

{
	int i,sf,nchars=MINCOMM;
	char *buffer,malloc();
	int nbytes,todo;
	long atol();
	float dur;
	int comment = 0;
	double atof();
	SFHEADER sfh;
	SFMAXAMP sfm;
	SFCOMMENT sfcm;
	FILE *fcom;
	char *sfname,*cp;

usage:	
	if(argc < 7) {
		printf("usage: \"sfcreate -r [s. rate] -c [# chans] -[i=int; f=float] <-w<x commentsize>> <-d [dur]> filename\"\n");
		exit(1);
	}

	dur = 0;

	while((*++argv)[0] == '-') {
		argc -= 2; /* Take away two args */
		for(cp = argv[0]+1; *cp; cp++) {
			switch(*cp) { /* Grap options */
			case 'r': 
				sfsrate(&sfh) = atof(*++argv);
				if(sfsrate(&sfh) < 0 || sfsrate(&sfh) > 60000) {
					printf("Illegal srate\n");
					exit(1);
				}
				printf("Sampling rate set to %f\n",sfsrate(&sfh));
				break;
			case 'd': 
				dur = atof(*++argv);
				printf("Play duration is %f\n",dur);
				break;
			case 'i': 
				sfclass(&sfh) = SF_SHORT;
				break;
			case 'f':
				sfclass(&sfh) = SF_FLOAT;
				break;
			case 'c': 
				sfchans(&sfh) = atoi(*++argv);
				if(sfchans(&sfh) > 4)
/*				if(sfchans(&sfh) != 1 && sfchans(&sfh) != 2 && sfchans(&sfh) != 4)*/ {

					printf("Illegal channel specification\n");
					exit(1);
				}
				printf("Number of channels set to %d\n",sfchans(&sfh));
				break;
			case 'w':
				if(*(argv[0]+2) == 'x') {
					nchars = atoi(*++argv);
					++cp;
				}
				comment = 1;
				break;
			default:  
				printf("Don't know about option: %c\n",*cp);
			}
		}

	}
	if((sfsrate(&sfh) == 0.) || (sfclass(&sfh) == 0) 
	    || (sfchans(&sfh) == 0))  {
		printf("********You are missing specifications!\n");
		goto usage;
	}
	sfmagic(&sfh) = SF_MAGIC;
	while (argc--) {
		sfname = *argv++;
		if((sf = open(sfname,O_CREAT|O_RDWR,0644)) < 0 ) {
			printf("Can't open file %s\n",sfname);
			exit(-2);
		}

		/*put in peak amps of 0*/
		for(i=0; i<sfchans(&sfh); i++)
			sfmaxamp(&sfm,i)=sfmaxamploc(&sfm,i)=sfmaxamploc(&sfm,i)=0;
		sfmaxamptime(&sfm) = 0;
		putsfcode(&sfh,&sfm,&ampcode);

		if(!comment) {
			strcpy(&sfcomm(&sfcm,0),sfname);
			sfcomm(&sfcm,strlen(sfname)) = '\n';
			commentcode.bsize = MAXCOMM + sizeof(SFCODE); 
			if (putsfcode(&sfh,&sfcm,&commentcode) < 0) {
				printf("comment didn't get written, sorry!\n");
				exit(-1);
			}
		}
		else {
			system("vi /tmp/comment");
			fcom = fopen("/tmp/comment","r");
			i=0;
			while ( (sfcomm(&sfcm,i) = getc(fcom)) != EOF ) {
				if (++i > MAXCOMM) {
					printf("Gimme a break! I can only take %d characters\n",MAXCOMM);
					printf("comment truncated to %d characters\n",MAXCOMM);
					commentcode.bsize = MAXCOMM + sizeof(SFCODE);
					break;
				}
			}
			sfcomm(&sfcm,i) = '\0';
			system("rm /tmp/comment");
			if (nchars > MINCOMM)
				commentcode.bsize = nchars + sizeof(SFCODE);
			if (i > nchars)
				commentcode.bsize = i + sizeof(SFCODE);
			if (putsfcode(&sfh,&sfcm,&commentcode) < 0) {
				printf("comment didn't get written, sorry!\n");
				exit(-1);
			}
		}
		if(wheader(sf,(char *)&sfh)) {
			printf("Can't seem to write header on file %s\n",sfname);
			perror("main");
			exit(-1);
		}

		if(dur) {
			nbytes = todo = dur * sfsrate(&sfh) * (float)sfchans(&sfh)
				* (float)sfclass(&sfh) + .5;
			fprintf(stderr,"Blocking out file, %d bytes...",nbytes);
			buffer = (char *)malloc(NBYTES);
			bzero(buffer,NBYTES);
			while(nbytes>0) {
				todo = (nbytes > NBYTES) ? NBYTES : nbytes;
				if(write(sf,buffer,todo) <= 0) {
					printf("Bad write on file\n");
					exit(-1);
				}
				nbytes -= todo;
			}
			printf("\ndone\n");
		}
		if(fsync(sf) < 0) printf("bad fsync\n");
	}
}
