/* Chorus, Flange and Phaser module */ #include #include /* Circular buffer Length and binary mask */ #define BufLen 4096 #define BufMask BufLen-1 /* Valid LFO waveforms */ #define wavSine 0 #define wavTriangle 1 #define wavExp 2 /* Macro to compute current delay buffer position */ #define GetPos(a) (int)(BufLen*((double)(a)/LFORate)) /* Macro to compute current delay LFO waveform position */ #define CalcPos(a) (int)((a)*(double)LFORate/BufLen) /* Internal defaults */ static double Depth=5.0; /* depth[msec] */ static double Delay=20.0; /* delay[msec] */ static double Rate=0.1; /* rate[Hz] */ static int level=0; /* level */ static int FeedBack=0; /* feedback[0..1] */ static int Phase=0; /* stereo de-phase */ /* Initial buffer positions */ static int LFORate=8192; /* LFO Rate (fixed point) */ static int LFOPos=0; /* LFO Position */ static int BufPos=0; /* LFO Buffer Position */ /* Circular buffers: Left, Right and LFO waveform */ static signed short BufL[BufLen]; /* Left Delay Buffer */ static signed short BufR[BufLen]; /* Right Delay Buffer */ static signed short LFO[BufLen]; /* Precalculated LFO waveform */ static void fx_update_phaser(); /* update phaser state */ static int fx_mod_phaser(signed short *data, int len); /* phaser processing */ static int fx_mod_flanger(signed short *data, int len); /* flange & chorus */ double pha, phaBottom, phaTop; /* phaser filter status and range */ double phaStep, phaStepRate; /* phaser change helper vars */ /* Structure to describe this effect module, see fx/fx.h */ FX fx_mod = { FX_MOD, 0, 6, fx_handle, fx_mod_flanger, fx_init, fx_done }; /* Precalculate the LFO waveform */ static void WaveForm(int wave){ int i,j=BufLen/2; /* buffer pointers */ short int depth,delay; /* profundidad y delay del flange/chorus */ static int type=wavSine;/* type of waveform, Sine by default */ if (wave>=0) type=wave; /* get LFO waveform type */ /* Transform miliseconds to sample units */ depth = (short int)(Depth * SAMPLERATE / MSEC); delay = (short int)(Delay * SAMPLERATE / MSEC); switch (type){ case wavSine: for(i=0;i>6; data[i]=sat(smpout); i++; /* Process next channel */ smpin=data[i]; r = smpin + (FeedBack*ry4)/17; ry1 = c * (ry1 + r) - rx1; rx1 = r; ry2 = c * (ry2 + ry1) - rx2; rx2 = ry1; ry3 = c * (ry3 + ry2) - rx3; rx3 = ry2; ry4 = c * (ry4 + ry3) - rx4; rx4 = ry3; smpout = ((int)(ry4 * level + smpin *(0x40-level)))>>6; data[i]=sat(smpout); /* update filter */ pha *= phaStep; if(pha > phaTop) phaStep = 1.0 / phaStepRate; else if(pha < phaBottom) phaStep = phaStepRate; } return len; } /* Flange/Chorus effect */ static int fx_mod_flanger(signed short *data, int len){ long smpout,smpin,Delay; /* sample out/in, delay position */ int j,t; /* input buffer position, base delay position */ for(j=0;j=LFORate ) LFOPos=0; /* Update LFO position */ Delay = (BufPos - Delay) & BufMask; /* Apply circular mask */ smpin = data[j];smpout = BufL[Delay]; /* fetch data */ /* Mix input with buffered input */ smpout = (smpout * level + smpin*(0x40-level))>>6; smpin += ((smpout * FeedBack)>>4); /* apply feedback */ /* Write output value and store in delay buffer */ BufL[BufPos] = sat(smpin); data[j]=sat(smpout); j++; /* Process next channel */ Delay = LFO[(t+Phase) & BufMask]; Delay = (BufPos - Delay) & BufMask; smpin = data[j];smpout = BufR[Delay]; smpout = (smpout * level + smpin*(0x40-level))>>6; smpin += ((smpout * FeedBack)>>4) ; BufR[BufPos] = sat(smpin); data[j]=sat(smpout); data[j]=sat(smpout); BufPos = (++BufPos) & BufMask; } return len; }