/******************************************************************
 *	snd_rate.c -- resample soundfiles by integer ratios
 *		stp -- 2/92
 *
 *	usage:	snd_rate orate ifile ofile
 *
 ******************************************************************/
#include <stdio.h>
#include <sys/file.h>
#include <sys/types.h>
#include <unistd.h>
#include <malloc.h>
#include <multimedia/audio_filehdr.h>

#define CBUFS 16384

main(argc, argv) int argc; char *argv[]; {
	short *ibuf, *obuf;
	int srate, i, j, k, v1, v2, isize, osize, rr;
	float ratio;
	FILE *ifd, *ofd;
	char string[128];
	Audio_filehdr *sf_header;

	if (argc != 4)
		usage(argv[0]);

	srate = atoi(argv[1]);
	if (srate == 0) {
		printf("Unknown sample rate\n");
		exit(1);
	}
	ifd = fopen(argv[2], "r");			/* open input file */
	if (ifd == NULL) {
		printf("Error opening input file\n");
		exit(-1);
	}
	ofd = fopen(argv[3], "w");	/* open output file */
	if (ofd == NULL) {
		printf("Error opening output file\n");
		exit(-1);
	}
							/* read soundfile header */
	sf_header = (Audio_filehdr *) calloc(sizeof(Audio_filehdr), 1);
	i = fread(sf_header, sizeof(Audio_filehdr), 1, ifd);
	if (i == 0) {
		fprintf(stderr, "Unable to read SPARC/NeXT sound file header.\n");
		exit(1);
	}
	ratio = ((float) (sf_header->sample_rate) / (float) (srate));

	printf("\n\tinput: %s\t rate: %d\n\toutput: %s\t rate: %d\n\tratio: %g\n\n", 
			argv[2], sf_header->sample_rate, argv[3], srate, ratio);

	sf_header->sample_rate = srate;
	sf_header->data_size = sf_header->data_size / ratio;

	fwrite(sf_header, sizeof(Audio_filehdr), 1, ofd);

							/* allocate buffers */
	isize = CBUFS;
	ibuf = (short *) calloc(sizeof(short), isize);
	if (ibuf == NULL) {
		printf("memory allocation error1\n");
		exit(1);
	}
	osize = CBUFS / ratio;
	obuf = (short *) calloc(sizeof(short), osize);
	if (obuf == NULL) {
		printf("memory allocation error2\n");
		exit(1);
	}
	if (ratio > 1)				/* read and downsample input file */
		while ((i = fread(ibuf, sizeof(short), isize, ifd))) {
			/* printf("read %d\n", i); */
			for (j=0; j<(i/ratio); j++)
				obuf[j] = ibuf[j*(int)ratio];
			i = fwrite(obuf, sizeof(short), (int) (i/ratio), ofd);
			/* printf("wrote %d\n", i); */
		}
	else {						/* read and interpolate input file */
		rr = (int) (1.0 / ratio);
		while ((i = fread(ibuf, sizeof(short), isize, ifd))) {
			/* printf("read %d\n", i); */
			for (j=0; j<i; j++) {
				v1 = ibuf[j];		/* this sample */
				v2 = ibuf[j+1];		/* the next sample */
				for (k=0; k<rr; k++)
					obuf[j*rr+k] = v1 + ((k/rr) * (v2 - v1));
			}
			i = fwrite(obuf, sizeof(short), i*rr, ofd);
			/* printf("wrote %d\n", i); */
		}
	}
	fclose(ifd);
	fclose(ofd);
	sprintf(string, "ls -l %s %s; lsfl %s %s", argv[2], argv[3], argv[2], argv[3]);
	system(string);
}


int
usage(prog)
	char	*prog;
{
	fprintf(stderr, "usage: %s orate ifilename ofilename\n", prog);
	exit(0);
}

