/******************************************************************
 *	snd_chan.c -- change the number of channels of soundfiles
 *		stp -- 2/92
 *
 *	usage:	snd_chan ochan 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 i, j, rr, isize, osize, ochans;
	FILE *ifd, *ofd;
	char string[128];
	Audio_filehdr *sf_header;
	float ratio;

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

	ochans = atoi(argv[1]);
	if (ochans == 0) {
		printf("Unknown channel number\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) (ochans) / (float) (sf_header->channels));
/*
	printf("\n\tinput: %s\tchan: %d\n\toutput: %s\tchan: %d\n\tratio: %g\n\n", 
			argv[2], sf_header->channels, argv[3], ochans, ratio);
*/
	sf_header->channels = ochans;
	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 copy mono to stereo */
		while ((i = fread(ibuf, sizeof(short), isize, ifd))) {
			/* printf("read %d\n", i); */
			for (j=0; j<i; j++) {
				obuf[j*(int)ratio] = ibuf[j];
				obuf[j*(int)ratio+1] = ibuf[j];
			}
			i = fwrite(obuf, sizeof(short), (int) (i*ratio), ofd);
			/* printf("wrote %d\n", i); */
		}
	else if (ratio < 1) {			/* read and merge stereo to mono */
		rr = (int) (1.0 / ratio);
		while ((i = fread(ibuf, sizeof(short), isize, ifd))) {
			printf("read %d\n", i);
			for (j=0; j<i; j+=rr)
				obuf[j] = (ibuf[j] + ibuf[j+1]) / 2;	/* average of the samples */
			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 ochan ifilename ofilename\n", prog);
	exit(0);
}

