This is quad.c in view mode; [Download] [Up]
#include<stdio.h> #include <math.h> #include <ctype.h> #include <carl/carl.h> #include "list.h" extern int arg_index; /* from crack() in -lsf */ extern char *arg_option; float Pi, Piovr2, Piovr4; int tanit = 1, verbose = 0; char outop; main(argc, argv) char **argv; { LIST *rfun(), *Head, *L; FILE *fp, *fopen(); char ch, crack(); float sfexpr(), getdistance(), *buf, *obuf, Offset; int otty = isatty(1), n, i, nchans = 4, chan = -1, first = 1, len, pos=0, olen=1024; float dur, inc, theta, sig1, sig2, distance, gamp, grev, dopp; float circlemod(), getheta(), getcoeff(), *interp(), doppler(); int getquad(); float vsound = 340.0; /* ~ velocity of sound */ Pi = 4.0 * atan(1.0); Piovr2 = Pi/2.0; Offset = Piovr4 = Pi/4.0; if (argc < 2) exit(-1); while ((ch = crack(argc, argv, "o|L|d|v|1|2|3|4|artbh", 0)) != NULL) { if (isdigit(ch)) { chan = ch - '1'; outop = 'c'; } else switch (ch) { case 'd': dur = sfexpr(arg_option, 1.0); outop = ch; break; case 'v': vsound = sfexpr(arg_option, 1.0); break; case 't': tanit=0; break; case 'a': /* goes with r */ case 'r': outop = ch; break; case 'L': olen = sfexpr(arg_option, 1.0); break; case 'o': Offset = sfexpr(arg_option, 1.0); Offset = 2.0 * Pi * Offset / 360.0; break; case 'b': verbose++; break; case 'h': amphelp(); exit(0); default: amphelp(); exit(-1); } } if (verbose) { for (i = 0; i < argc; i++) fprintf(stderr, "%s ", argv[i]); fprintf(stderr, "\n"); } if (arg_index >= argc) { fprintf(stderr, "quad: missing filename\n"); exit(-1); } if ((Head = rfun(Head, argv[arg_index], 0.0, 0.0, 1.0, 1)) == NULL) { fprintf(stderr, "quad: error reading %s\n", argv[arg_index]); exit(-1); } /* * normal way of specifying doppler duration: * quad -dN file * alternate way of specifying doppler duration: * quad -d file N * This format allows some convenience when called from cmusic */ if (outop == 'd' && dur == 0.0 && arg_index == argc-2) dur = sfexpr(argv[arg_index+1], 1.0); if (outop == 'd' && dur <= 0.0) { fprintf(stderr,"quad: error in specifying doppler duration\n"); exit(-1); } if (outop == 'd') { for (L = Head, n = 0; L; L = L->next) n++; /* count'em up */ inc = n/dur; } for (i = 0, L = Head; L; L = L->next) { float scale, scale1, coeff; float ch[4]; int q; theta = getheta(L->fx, L->fy); q = getquad(theta, Offset); coeff = getcoeff(theta, Offset); getscale(coeff, &scale, &scale1); ch[0] = ch[1] = ch[2] = ch[3] = 0.0; switch (q) { case 1: ch[0] = scale; ch[1] = scale1; break; case 2: ch[1] = scale; ch[2] = scale1; break; case 3: ch[2] = scale; ch[3] = scale1; break; case 4: ch[3] = scale; ch[0] = scale1; break; } distance = getdistance(L->fx, L->fy); if (distance < 1.0) distance = 1.0; gamp = 1.0/distance; grev = 1.0/sqrt(distance); dopp = doppler(L->fx, L->fy, vsound, inc); switch (outop) { case 'c': len = fsave(ch[chan], &buf, pos++, len);break; case 'a': len = fsave(gamp, &buf, pos++, len); break; case 'r': len = fsave(grev, &buf, pos++, len); break; case 'd': if (first) {first=0; break; } len = fsave(dopp, &buf, pos++, len); break; } } obuf = interp(buf, pos-1, olen); if (otty) for (i = 0; i < olen; i++) printf("%f\n", obuf[i]); else { for (i = 0; i < olen; i++) putfloat(&obuf[i]); flushfloat(); } exit(0); } /* * /1* now in nodfun.c *1/ * float getdistance(x, y) * float x, y; * { * return(sqrt(x*x+y*y)); * } */ /* * /1* now in nodfun.c *1/ * float getheta(x, y) * float x, y; * { * register float theta; * theta = atan2(y, x); * if (theta < 0.0) theta = (Pi + theta) + Pi; * return(theta); * } */ /* * /1* now in nodfun.c *1/ * float circlemod(x) * float x; * { * register float twopi = 2.0 * Pi; * while (x > twopi) x -= twopi; * while (x < 0) x += twopi; * return(x); * } */ getquad(theta, offset) float theta, offset; { theta = circlemod(theta-offset); if (theta < Piovr2) return(1); else if (theta < Pi) return(2); else if (theta < 3.0*Piovr2) return(3); else return(4); } float getcoeff(theta, offset) float theta, offset; { float rtn; int q; theta += offset; while (theta >= Piovr2) theta -= Piovr2; return(theta); } getscale(coeff, scale1, scale2) float coeff, *scale1, *scale2; { register float tmp; if (tanit) { *scale1 = sqrt(1.0 - .5 * (1.0 + tan(coeff - Piovr2/2.0))); *scale2 = sqrt(.5 * (1.0 + tan(coeff - Piovr2/2.0))); } else { *scale1 = sqrt(1.0 - coeff/Piovr2); *scale2 = sqrt(coeff/Piovr2); } } float doppler(x, y, vsound, inc) float x, y, vsound, inc; { static float dlast; register float dcur, dD, u, ds; dcur = sqrt(x*x + y*y); dD = dcur - dlast; u = dD * inc; ds = vsound/(vsound + u); dlast = dcur; return(ds); } fsave(x, buf, i, len) float x, **buf; int i, len; { float *b; if (*buf == NULL) { *buf = (float *) calloc(sizeof(float)*BUFSIZ, 1); len = BUFSIZ; } if (i < len) (*buf)[i] = x; else { len += BUFSIZ; *buf = (float *) realloc(*buf, len * sizeof(float)); (*buf)[i] = x; } return(len); } /* * take buf with nipts floats, and return a linearly interpolated array * nopts long. */ float *interp(buf, nipts, nopts) float *buf; int nipts, nopts; { register int i, c; register float rat, fc, frat, *ntbuf; rat = (float) nipts / (float) nopts; ntbuf = (float *) malloc(sizeof(float)*nopts); for (i = fc = c = 0; i < nopts; fc += rat, i++) { c = fc; /* truncate */ frat = fc - c; /* get fraction */ ntbuf[i] = (1.0-frat)*buf[c] + frat*buf[c+1]; } return(ntbuf); } amphelp() { fprintf(stderr, "%s%s%s%s%s%s%s%s%s", "usage: quad [flags] space_path\n", "quad reads functions of time as text [x,y] pairs (1 pair per line)\n", "and calculates Chowning-style amplitude functions for quad distribution.\n", "flags:\n", " -LN cause functions to be scaled to length N\n", " -dN set duration of entire function to N seconds\n", " -N (where N = one of {1,2,3,4}) calculate and output that channel\n", " -a calculate and output global amplitude\n", " -r calculate and output global reverb.\n" ); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.