_EXAMINING AUDIO DSP ALGORITHS_ by Dennis Cronin Listing One /* flange_chorus. Does flanging/chorusing family of effects based on a single varying delay. dry_mix mix of unaffected signal (-0.999 to 0.999) wet_mix mix of affected signal (-0.999 - 0.999) feedback amount of recirculation (-0.9 - 0.9) rate rate of delay change in millisecs per sec sweep sweep range in millisecs delay fixed additional delay in millisecs */ void flange_chorus(struct program *p) { int fp,ep1,ep2; int step,depth,delay,min_sweep,max_sweep; double inval,outval,ifac = 65536.0; long scan = 0; bw data; wl sweep; /* fetch params */ step = (int)(p->rate * 65.536); depth = (int)(p->depth * (double)SampleRate / 1000.0); delay = (int)(p->delay * (double)SampleRate / 1000.0); /* init/calc some stuff */ max_sweep = BFSZ - 2 - delay; min_sweep = max_sweep - depth; if(min_sweep < 0) { printf("Can't do that much delay or depth at this sample rate.\n"); exit(1); } sweep.w[1] = (min_sweep + max_sweep) / 2; sweep.w[0] = 0; /* init store and read ptrs to known value */ fp = ep1 = ep2 = 0; /* disable interrupts, go to it */ disable(); while(1) { while((inp(SR) & 0x20) == 0); /* wait for input ready */ data.b[0] = inp(PDR); /* read input from chip */ data.b[1] = inp(PDR); /* interpolate from the 2 read values */ outval = (Buf[ep1] * sweep.w[0] + Buf[ep2] * (ifac - sweep.w[0])) / ifac; /* store finished input plus feedback */ Buf[fp] = (inval = (double)data.w) + outval * p->feedback; /* develop final output mix */ outval = outval * p->wet_mix + inval * p->dry_mix; if(outval > 32767.0) data.w = 32767; else if(outval < -32768.0) data.w = -32768; else data.w = (int)outval; while((inp(SR) & 0x2) == 0); /* wait for output ready */ outp(PDR,data.b[0]); /* write output to chip */ outp(PDR,data.b[1]); /* update ptrs */ fp = (fp + 1) & (BFSZ - 1); sweep.l += step; ep1 = (fp + sweep.w[1]) & (BFSZ - 1); ep2 = (ep1 - 1) & (BFSZ - 1); /* check for sweep reversal */ if(sweep.w[1] > max_sweep) /* see if we hit top of sweep */ step = -step; /* reverse */ else if(sweep.w[1] < min_sweep) /* or if we hit bottom of sweep */ step = -step; /* reverse */ check_human(); /* check on human every so often */ } }