1 // Reverb model implementation
\r
3 // Written by Jezar at Dreampoint, June 2000
\r
4 // http://www.dreampoint.co.uk
\r
5 // This code is public domain
\r
7 #include "revmodel.hpp"
\r
11 // Tie the components to their buffers
\r
12 combL[0].setbuffer(bufcombL1,combtuningL1);
\r
13 combR[0].setbuffer(bufcombR1,combtuningR1);
\r
14 combL[1].setbuffer(bufcombL2,combtuningL2);
\r
15 combR[1].setbuffer(bufcombR2,combtuningR2);
\r
16 combL[2].setbuffer(bufcombL3,combtuningL3);
\r
17 combR[2].setbuffer(bufcombR3,combtuningR3);
\r
18 combL[3].setbuffer(bufcombL4,combtuningL4);
\r
19 combR[3].setbuffer(bufcombR4,combtuningR4);
\r
20 combL[4].setbuffer(bufcombL5,combtuningL5);
\r
21 combR[4].setbuffer(bufcombR5,combtuningR5);
\r
22 combL[5].setbuffer(bufcombL6,combtuningL6);
\r
23 combR[5].setbuffer(bufcombR6,combtuningR6);
\r
24 combL[6].setbuffer(bufcombL7,combtuningL7);
\r
25 combR[6].setbuffer(bufcombR7,combtuningR7);
\r
26 combL[7].setbuffer(bufcombL8,combtuningL8);
\r
27 combR[7].setbuffer(bufcombR8,combtuningR8);
\r
28 allpassL[0].setbuffer(bufallpassL1,allpasstuningL1);
\r
29 allpassR[0].setbuffer(bufallpassR1,allpasstuningR1);
\r
30 allpassL[1].setbuffer(bufallpassL2,allpasstuningL2);
\r
31 allpassR[1].setbuffer(bufallpassR2,allpasstuningR2);
\r
32 allpassL[2].setbuffer(bufallpassL3,allpasstuningL3);
\r
33 allpassR[2].setbuffer(bufallpassR3,allpasstuningR3);
\r
34 allpassL[3].setbuffer(bufallpassL4,allpasstuningL4);
\r
35 allpassR[3].setbuffer(bufallpassR4,allpasstuningR4);
\r
37 // Set default values
\r
38 allpassL[0].setfeedback(0.5f);
\r
39 allpassR[0].setfeedback(0.5f);
\r
40 allpassL[1].setfeedback(0.5f);
\r
41 allpassR[1].setfeedback(0.5f);
\r
42 allpassL[2].setfeedback(0.5f);
\r
43 allpassR[2].setfeedback(0.5f);
\r
44 allpassL[3].setfeedback(0.5f);
\r
45 allpassR[3].setfeedback(0.5f);
\r
47 setroomsize(initialroom);
\r
49 setdamp(initialdamp);
\r
50 setwidth(initialwidth);
\r
51 setmode(initialmode);
\r
53 // Buffer will be full of rubbish - so we MUST mute them
\r
57 void revmodel::mute()
\r
59 if (getmode() >= freezemode)
\r
62 for (int i=0;i<numcombs;i++)
\r
67 for (int i=0;i<numallpasses;i++)
\r
74 void revmodel::processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)
\r
76 float outL,outR,input;
\r
78 while(numsamples-- > 0)
\r
81 input = (*inputL + *inputR) * gain;
\r
83 // Accumulate comb filters in parallel
\r
84 for(int i=0; i<numcombs; i++)
\r
86 outL += combL[i].process(input);
\r
87 outR += combR[i].process(input);
\r
90 // Feed through allpasses in series
\r
91 for(int i=0; i<numallpasses; i++)
\r
93 outL = allpassL[i].process(outL);
\r
94 outR = allpassR[i].process(outR);
\r
97 // Calculate output REPLACING anything already there
\r
98 *outputL = outL*wet1 + outR*wet2 + *inputL*dry;
\r
99 *outputR = outR*wet1 + outL*wet2 + *inputR*dry;
\r
101 // Increment sample pointers, allowing for interleave (if any)
\r
109 void revmodel::processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)
\r
111 float outL,outR,input;
\r
113 while(numsamples-- > 0)
\r
116 input = (*inputL + *inputR) * gain;
\r
118 // Accumulate comb filters in parallel
\r
119 for(int i=0; i<numcombs; i++)
\r
121 outL += combL[i].process(input);
\r
122 outR += combR[i].process(input);
\r
125 // Feed through allpasses in series
\r
126 for(int i=0; i<numallpasses; i++)
\r
128 outL = allpassL[i].process(outL);
\r
129 outR = allpassR[i].process(outR);
\r
132 // Calculate output MIXING with anything already there
\r
133 *outputL += outL*wet1 + outR*wet2 + *inputL*dry;
\r
134 *outputR += outR*wet1 + outL*wet2 + *inputR*dry;
\r
136 // Increment sample pointers, allowing for interleave (if any)
\r
144 void revmodel::update()
\r
146 // Recalculate internal values after parameter change
\r
150 wet1 = wet*(width/2 + 0.5f);
\r
151 wet2 = wet*((1-width)/2);
\r
153 if (mode >= freezemode)
\r
161 roomsize1 = roomsize;
\r
166 for(i=0; i<numcombs; i++)
\r
168 combL[i].setfeedback(roomsize1);
\r
169 combR[i].setfeedback(roomsize1);
\r
172 for(i=0; i<numcombs; i++)
\r
174 combL[i].setdamp(damp1);
\r
175 combR[i].setdamp(damp1);
\r
179 // The following get/set functions are not inlined, because
\r
180 // speed is never an issue when calling them, and also
\r
181 // because as you develop the reverb model, you may
\r
182 // wish to take dynamic action when they are called.
\r
184 void revmodel::setroomsize(float value)
\r
186 roomsize = (value*scaleroom) + offsetroom;
\r
190 float revmodel::getroomsize()
\r
192 return (roomsize-offsetroom)/scaleroom;
\r
195 void revmodel::setdamp(float value)
\r
197 damp = value*scaledamp;
\r
201 float revmodel::getdamp()
\r
203 return damp/scaledamp;
\r
206 void revmodel::setwet(float value)
\r
208 wet = value*scalewet;
\r
212 float revmodel::getwet()
\r
214 return wet/scalewet;
\r
217 void revmodel::setdry(float value)
\r
219 dry = value*scaledry;
\r
222 float revmodel::getdry()
\r
224 return dry/scaledry;
\r
227 void revmodel::setwidth(float value)
\r
233 float revmodel::getwidth()
\r
238 void revmodel::setmode(float value)
\r
244 float revmodel::getmode()
\r
246 if (mode >= freezemode)
\r