//========================================================= // MusE // Linux Music Editor // $Id:$ // // based on "freeverb" written by Jezar at Dreampoint, // June 2000 // // (C) Copyright 2007 Werner Schweer (ws@seh.de) //========================================================= #ifndef __REVERB_H__ #define __REVERB_H__ #define undenormalise(sample) \ do { \ volatile float __forced_float = 1e-29 + sample; \ sample = __forced_float - 1e-29; \ } while (0) const int numcombs = 8; const int numallpasses = 4; const float muted = 0; const float fixedgain = 0.015f; const float scaledamp = 0.4f; const float scaleroom = 0.28f; const float offsetroom = 0.7f; const float initialwidth = 1.0; const int stereospread = 23; // These values assume 44.1KHz sample rate // they will probably be OK for 48KHz sample rate // but would need scaling for 96KHz (or other) sample rates. // The values were obtained by listening tests. const int combtuningL1 = 1116; const int combtuningR1 = 1116+stereospread; const int combtuningL2 = 1188; const int combtuningR2 = 1188+stereospread; const int combtuningL3 = 1277; const int combtuningR3 = 1277+stereospread; const int combtuningL4 = 1356; const int combtuningR4 = 1356+stereospread; const int combtuningL5 = 1422; const int combtuningR5 = 1422+stereospread; const int combtuningL6 = 1491; const int combtuningR6 = 1491+stereospread; const int combtuningL7 = 1557; const int combtuningR7 = 1557+stereospread; const int combtuningL8 = 1617; const int combtuningR8 = 1617+stereospread; const int allpasstuningL1 = 556; const int allpasstuningR1 = 556+stereospread; const int allpasstuningL2 = 441; const int allpasstuningR2 = 441+stereospread; const int allpasstuningL3 = 341; const int allpasstuningR3 = 341+stereospread; const int allpasstuningL4 = 225; const int allpasstuningR4 = 225+stereospread; //--------------------------------------------------------- // allpass //--------------------------------------------------------- class allpass { float feedback; float *buffer; int bufsize; int bufidx; public: allpass() { bufidx = 0; } void setbuffer(float *buf, int size) { buffer = buf; bufsize = size; } float process(float input) { float bufout = buffer[bufidx]; undenormalise(bufout); float output = -input + bufout; buffer[bufidx] = input + (bufout*feedback); if (++bufidx >= bufsize) bufidx = 0; return output; } void mute() { memset(buffer, 0, sizeof(float) * bufsize); } void setfeedback(float val) { feedback = val; } float getfeedback() { return feedback; } }; //--------------------------------------------------------- // comb //--------------------------------------------------------- class comb { float feedback; float filterstore; float damp1; float damp2; float *buffer; int bufsize; int bufidx; public: comb() { filterstore = 0; bufidx = 0; } void setbuffer(float *buf, int size) { buffer = buf; bufsize = size; } float process(float input) { float output = buffer[bufidx]; undenormalise(output); filterstore = (output*damp2) + (filterstore*damp1); undenormalise(filterstore); buffer[bufidx] = input + (filterstore*feedback); if (++bufidx >= bufsize) bufidx = 0; return output; } void mute() { for (int i=0; i<bufsize; i++) buffer[i]=0; } void setdamp(float val) { damp1 = val; damp2 = 1-val; } float getdamp() { return damp1; } void setfeedback(float val) { feedback = val; } float getfeedback() { return feedback; } }; //--------------------------------------------------------- // Reverb //--------------------------------------------------------- class Reverb { float gain; float roomsize,roomsize1; float damp,damp1; float width; float mode; // Comb filters comb combL[numcombs]; comb combR[numcombs]; // Allpass filters allpass allpassL[numallpasses]; allpass allpassR[numallpasses]; // Buffers for the combs float bufcombL1[combtuningL1]; float bufcombR1[combtuningR1]; float bufcombL2[combtuningL2]; float bufcombR2[combtuningR2]; float bufcombL3[combtuningL3]; float bufcombR3[combtuningR3]; float bufcombL4[combtuningL4]; float bufcombR4[combtuningR4]; float bufcombL5[combtuningL5]; float bufcombR5[combtuningR5]; float bufcombL6[combtuningL6]; float bufcombR6[combtuningR6]; float bufcombL7[combtuningL7]; float bufcombR7[combtuningR7]; float bufcombL8[combtuningL8]; float bufcombR8[combtuningR8]; // Buffers for the allpasses float bufallpassL1[allpasstuningL1]; float bufallpassR1[allpasstuningR1]; float bufallpassL2[allpasstuningL2]; float bufallpassR2[allpasstuningR2]; float bufallpassL3[allpasstuningL3]; float bufallpassR3[allpasstuningR3]; float bufallpassL4[allpasstuningL4]; float bufallpassR4[allpasstuningR4]; float roomSize; float damping; float wetLevel; void update(); public: Reverb(); void process(float* l, float* r, int numsamples); void setdamp(float value); void setwidth(float value); void setRoomSize(float value); void setMix(float value); }; #endif