This is mixsf.c in view mode; [Download] [Up]
#include <math.h> #include <stdio.h> #include <carl/sndio.h> #include <carl/carl.h> #include <carl/procom.h> extern int sferror; extern CSNDFILE *rootsfd; /*------------------------------------------------------- mixsf.c This is a program for performing simple arithemetic operations on soundfiles (e.g., addition, subtraction, multiplication, and division). One soundfile is piped in on stdin, the other is named on the command line, and the result is piped out on stdout. The program also allows for simple interleaving of soundfiles (e.g., mono to stereo). The program runs exactly as long as there is input on stdin. To compile: cc mixsf.c -lsf -lcarl -lm -------------------------------------------------------*/ main(argc, argv) int argc; char **argv; { float fsndi(); float in1, /* input from first file */ in2, /* input from second file */ out, /* output */ max = 0., /* maximum output value */ att = 1., /* soundfile input scale factor */ fac = 1., /* output scale factor */ srate; /* sample rate on stdin */ int add = 0, /* flag for addition */ sub = 0, /* flag for subtraction */ mul = 0, /* flag for multiplication */ div = 0, /* flag for division */ mux = 0, /* flag for interleaving */ nchan; /* number of channels on stdin */ long i, /* counter for soundfile samples */ beg = 0, /* first sample of soundfile */ end = 0, /* last sample of soundfile */ del = 0; /* delay before beginning of soundfile */ CSNDFILE *sfd, *opensf(); char ch; char *cbeg = NULL, *cend = NULL, *cdur = NULL, *cdel = NULL; char *file = "test"; char cbuf[72]; /* buffer for strings to write to header */ char *dbuf; /* buffer for strings to read from header */ PROP *proplist; /* from header on stdin */ /* Interpret commandline by calling dgl's subroutine crack. */ if (isatty(0)) usage(1); while ((ch = crack(argc, argv, "b|e|d|q|g|x|iacmsh", 0)) != NULL) { switch (ch) { case 'a': add = 1; break; case 's': sub = 1; break; case 'm': mul = 1; break; case 'c': div = 1; break; case 'i': mux = 1; break; case 'x': fac = sfexpr(arg_option,1.0); break; case 'g': att = sfexpr(arg_option,1.0); break; case 'b': cbeg = arg_option; break; case 'e': cend = arg_option; break; case 'd': cdur = arg_option; break; case 'q': cdel = arg_option; break; case 'h': usage(0); default: usage(1); /* this exits with error */ } } /* Read header from stdin. */ if ((proplist = getheader(stdin)) != NULL) { /* there is a header */ noautocp(); /* suppress hdr copy */ if ((dbuf=getprop(stdin, H_SRATE)) != NULL) srate = atof(dbuf); if ((dbuf=getprop(stdin, H_NCHANS)) != NULL)nchan = atoi(dbuf); } /* Read in second soundfile. */ if (arg_index < argc) file = argv[arg_index]; else fprintf(stderr,"mixsf: soundfile #2 not specified\n"); /* open sound file */ if ((sfd = opensf(file, "-r")) == NULL) { fprintf(stderr,"mixsf: opensf failed on %s\n", file); (void) sfallclose(); exit(1); } /* calculate times */ if (cbeg != NULL) beg = sfexpr(cbeg, sfd->sr)*sfd->nc; if (cend != NULL) end = sfexpr(cend, sfd->sr)*sfd->nc; else if (cdur != NULL) end = sfexpr(cdur, sfd->sr)*sfd->nc + beg; if (cdel != NULL) del = sfexpr(cdel, sfd->sr)*sfd->nc; /* check boundaries */ if (beg < 0 || beg >= sfd->fs) { fprintf(stderr, "mixsf: begin time out of range\n"); quit(); } if (end < 0 || end >= sfd->fs) { fprintf(stderr, "mixsf: end time out of range\n"); quit(); } if (end == 0) end = sfd->fs; i = beg - del; /* counter for soundfile samples */ /* Write header to stdout. */ if (srate != sfd->sr) fprintf(stderr,"mixsf: warning - incompatible sample rates\n"); if (nchan != sfd->nc) fprintf(stderr,"mixsf: warning - incompatible mono/stereo\n"); if (mux){ nchan += sfd->nc; sprintf(cbuf,"%d",nchan); rmprop(stdin,H_NCHANS); addprop(stdin,H_NCHANS,cbuf); } cpoheader(proplist,stdout); putheader(stdout); /* Main loop: Program runs exactly as long as there is input on stdin. */ if (mux){ while (getfloat(&in1) > 0) { if ((i < end) && (i >= beg)) in2 = fsndi(sfd, i++); else in2 = 0.; if (sferror) quit(); if (att != 1.) in2 *= att; if (fac != 1.){ in1 *= fac; in2 *= fac; } putfloat(&in1); putfloat(&in2); } } else { while (getfloat(&in1) > 0) { if ((i < end) && (i >= beg)) in2 = fsndi(sfd, i++); else { in2 = 0.; i++; } if (sferror) quit(); if (att != 1.) in2 *= att; if (sub) out = fac * (in1 - in2); else if (mul) out = fac * in1 * in2; else if (div){ if (in2 > .001) in2 = 1./in2; else in2 = 1000.; out = fac * in1 * in2; } else out = fac * (in1 + in2); if (out > 1.) max = out; if (out < -1.) max = - out; putfloat(&out); } } if (max >= 1.) fprintf(stderr,"mixsf: clipping - max output = %g\n",max); /* close all open files */ (void) sfallclose(); flushfloat(); exit(0); } usage(exitcode) int exitcode; { fprintf(stderr,"%s%s%s%s%s%s%s%s%s%s%s%s%s", "\nusage: mixsf [flags] soundfile < floatsams > floatsams\n", "\nflags:\n", "\ta: add soundfile to stdin\n", "\ts: subtract soundfile from stdin\n", "\tm: multiply soundfile by stdin\n", "\tc: divide stdin by (energy) soundfile (for AGC)\n", "\ti: interleave soundfile with stdin\n", "\tx = output scale factor to avoid clipping (1.)\n", "\tg = input gain factor for soundfile (1.)\n", "\tb = begin time in soundfile (first sample to use) (0.)\n", "\te = end time in soundfile (last sample to use) (end)\n", "\td = duration of soundfile (end - begin)\n", "\tq = quiet time before soundfile (delay before first sample)(0)\n\n"); exit(exitcode); } quit() { fprintf(stderr, "exiting\n"); (void) sfallclose(); exit(1); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.