ftp.nice.ch/pub/next/unix/audio/sndutil.1.3.s.tar.gz#/sndutil-1.3/sndtools/sndblockdc.c

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

/*
 *	This program reads in a soundfile, removes its mean (DC),
 *	and writes a new soundfile.
 *	Currently supports only SND_FORMAT_LINEAR_16, mono or stereo.
 *
 *	Usage:  sndblockdc <inputSoundFile> <outputSoundFile>
 *
 *	The algorithm:
 *          First the mean is computed, then it is subtracted.
 *
 *	Modification history:
 *	    6/9/95/jos - created.
 *	    10/27/96/aguiar - bug on four channel files was fixed.
 */

#import <stdio.h>
#import <sound/sound.h>

static void fail(char *s, char *s2)
{
    printf("*** %s%s\n\n",s,s2);
    exit(1);                        /* Exit, indicating error */
}

int processSound(int inCount, short *inPtr, short *outPtr, int nChans,
		 double adaption_time)
{
    int i,c;
    double v, xm1, ym1, x, y;
    double a1;

    a1 = 1.0 - 7.0 / adaption_time;

    for (c = 0; c < nChans; c++) {
	x = (double) inPtr[c];
	ym1 = 0.0;
	for (i = 1; i < inCount; i++) {
            xm1 = x;
            x = (double) inPtr[nChans * i + c];
            v =  x  -  xm1;			/* Zero at DC */
            y = (short)( v + a1 * ym1 );	/* Pole near DC */
            outPtr[nChans * i + c] = y;
            ym1 = y;
        }
    }
    return inCount;
}

void main(int argc,char **argv) {
    SNDSoundStruct *sndin, *sndout;
    short *inPtr, *outPtr;
    FILE *outstream;
    int inCount, outCount, width, nChans;
    double adaption_time = 250;

    while (argc>1 && *argv[1] == '-') {
	if (*(argv[1]+1) == 't') {
	    argv++;
	    sscanf(argv[1],"%lf",&adaption_time);
	    printf("DC filter adaption time set to %f\n",adaption_time);
	}
	argv++;
	argc -= 2;
    }

    if (argc != 3) {
	fprintf(stderr,
		"%s - first the mean is computed, then it is subtracted.\n",
		argv[0]);
	printf("Usage: sndblockdc "
	       "[-t60 adaption_time_in_samples] "
	       "in.snd out.snd\n");
	printf("The t60 parameter (default 1000) specifies the number "
	       "of samples the DC-blocking filter needs to fully adapt "
	       "to a drifting DC value. At low values, listen for "
	       "low-frequency attenuation. At high values, look for "
	       "smearing in time or a persisting wandering DC level.\n");
	exit(1);
    }

    if (SNDReadSoundfile(*++argv,&sndin))
      fail("could not open input file ",*argv);
    else
      SNDGetDataPointer(sndin, (char **)(&inPtr), &inCount, &width);
    if (width != 2)
      fail("Can only handle 16-bit soundfiles","");
    nChans = sndin->channelCount;
    inCount /= nChans;		/* to get sample frames */
    SNDSwapSoundToHost(inPtr, inPtr, inCount, nChans, sndin->dataFormat);

    SNDAlloc(&sndout,
	     sndin->dataSize,
	     SND_FORMAT_LINEAR_16,
	     sndin->samplingRate,
	     nChans,4);

    SNDGetDataPointer(sndout, (char **)(&outPtr), &outCount, &width);
    outCount /= nChans;		/* to get sample frames */

    if (NULL == (outstream = fopen(*++argv,"w")))
      fail("could not open output file ",*argv);
    if (SNDWriteHeader(fileno(outstream),sndout))
      fail("could not write output file ",*argv);

    outCount = processSound(inCount, inPtr, outPtr, nChans, adaption_time);

    SNDSwapHostToSound(outPtr, outPtr, outCount, nChans, sndout->dataFormat);
    fwrite(outPtr,2*nChans,outCount,outstream);

    SNDFree(sndin);
    fclose(outstream);
    SNDFree(sndout);

    exit(0);
}



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