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