ftp.nice.ch/pub/next/unix/audio/cmusic.bs.N.tar.gz#/src/srconv/osrconv.c

This is osrconv.c in view mode; [Download] [Up]

/* SRCONV - program for converting sampling rates by integer ratios
 * 	
 * 	Input/output data is 32-bit floating point binary,
 * 	and the user must supply an FIR digital filter as
 * 	designed by the fir program. The subroutines called
 * 	are taken from SRCONV in the IEEE Programs for Digital
 * 	Signal Processing package.
 * 						jos : 22-aug-80
 * 						frm : 18-dec-80
 */

# include <carl/paths.h>
# include <carl/carl.h>
# include <carl/sndio.h>
# include <carl/josprogs.h>

# define NDAT 256	/* number of data samples to read per call */
# define NCMAX 256	/* number of filter coeficients maximum	   */

/* CHANGE THE FOLLOWING LINE OF CODE TO POINT TO DEFAULT FILTER HOME */
# define FLTHOME(name)  libdir(srconv/name)	/* for default filters */

char	progname[] = "srconv";

main(argc,argv)
	char *argv[];
{
	extern	char *xalloc();
	int	i, begsamp, nsamples, nsi, nso, nread;
	int	n, no;			 	/* for the digital filter */
	char	fname[NAMSIZ], dfname[NAMSIZ], ldfname[NAMSIZ];
	float	coef[NCMAX], oc[NCMAX];
	int	l, m, q, nc, nq, ni, ierr;	/* for the converter */
	int	nx,ny,ndata;
	float	*qbuf, *cofs, *bufm, *bufl;
	int	*ictr;
	int	sdiv;
	float	r;

	/* read command line parameters and parameter files here */

	if (argc >= 3) {
		l = atoi(argv[1]);
		m = atoi(argv[2]);
	}
	else {
		l = inint(l = 2, "Interpolation factor l");
		m = inint(m = 3, "Decimation factor m");
	}

	/* Here the common factors of l and m should be canceled out */
	if ((l <= 0) || (m <= 0))
		err("bad parameters");
	if ((l == 1) && (m == 1))
		err("bad parameters");
	if ((((l % m) == 0) && (m != 1)) || (((m % l) == 0) && (l != 1)))
		err("bad parameters");

	/* get the filter */

	sdiv = MAX(l, m);	/* divisor of srate/2 for fir cutoff */

	r = 0.5 / sdiv;		/* fir cutoff value for srate = 1 */

	strcpy(dfname, catm(FLTHOME(d), itoc(sdiv), ".flt", NULL));
	strcpy(ldfname, catm(FLTHOME(ld), itoc(sdiv), ".flt", NULL));

	if (argc >= 4) {
		strcpy(fname, argv[3]);
		if (argv[3][0] == '%')
			strcpy(fname, dfname);
		if (argv[3][1] == '%')
			strcpy(fname, ldfname);
	}
	else {
		fname[0] = NULLC;	/* Force getflt to prompt for file */
		fprintf(stderr,
		"srconv: need a lowpass filter with cutoff at srate/(2*%d)\n",sdiv);
		fprintf(stderr,
		"srconv: for a sampling rate of one, fir stopband begins at %f\n",r);
	}

	if (! getflt(fname, dfname, NCMAX, &n, &no, coef, oc))
		exit(0);

	if (n < 2)
		err("cannot use a filter with no zeros.");

	if (no =! 1)
		err("cannot use filter with poles, only FIR (use fir program)");

	/* Converter parameters: */
	q = ((n - 1) / l) + 1;
	nc = l * q;
	nq = 2 * q;

	for (i = 0; i <= (n - 1) / 2; i++)
		coef[i] = coef[i + n / 2]; /* need right wing */

	for (i = (n + 1) / 2; i < n; i++)
		coef[i] = 0; /* just in case */

	qbuf = (float *) xalloc(2 * q * sizeof(float));
	cofs = (float *) xalloc(nc * sizeof(float));
	ni = 2 * l;
	ictr = (int *) xalloc(ni * sizeof(int));

	srinit_(&m, &l, qbuf, &nq, coef, &n, cofs, &nc, ictr, &ni, &ierr);

	switch(ierr) {
		case 0:
			break;

		case -1:
			err("qbuf (nq) too small");

		case -2:
			err("cofs (nc) too small");
			break;

		case -3:
			err("ictr (2*l) too small");
			break;

		default:
			err("srinit returned a garbage error code");
			break;
	}

	/* set up io buffers */
	ndata = NDAT;
	nx = ndata * m;
	ny = ndata * l;
	bufm = (float *) xalloc(nx * sizeof(float));
	bufl = (float *) xalloc(ny * sizeof(float));

	/* getio(&infile, &outfile, "float.dat", "newsr.dat"); */

	begsamp = 0;
	nsi = nso = 0;

	procomsr(stdin, stdout, (double) l / (double) m);

	do {
		nread = fgetfbuf(bufm, nx, stdin);
		srconv_(bufm, bufl, &ndata, qbuf, cofs, ictr);	/* Conversion */
		fputfbuf(bufl, ny, stdout);
		nsi += nread;
		nso += ny;
	} while (nread == nx);
}

/*
 * change the sample rate in the property
 * list.
 */
procomsr(inp, outp, srchange)
	FILE	*inp, *outp;
	double	srchange;
{
	extern	PROP *getheader();
	extern	char *getprop();
	char	*srate, bsrate[40];
	double	osrate;

	(void) getheader(inp);

	if ((srate = getprop(inp, H_SRATE)) == NULL)
		return;

	if (sscanf(srate, "%f", &osrate) != 1)
		return;

	sprintf(bsrate, "%g", osrate * srchange);

	addprop(outp, H_SRATE, bsrate);
}

char *
xalloc(n) {
	extern	char *malloc();
	char	*cp;

	if ((cp = malloc(n)) == NULL) {
		fprintf(stderr, "srconv: ");
		perror("malloc");
		exit(1);
	}

	return(cp);
}

err(msg)
	char	*msg;
{
	extern	char progname[];

	fprintf(stderr, "%s: ", progname);
	fprintf(stderr, "%s\n", msg);

	exit(1);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.