add file->load_recent mainmenu item, rm timebomb
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / freeverb / Components / revmodel.cpp
1 // Reverb model implementation\r
2 //\r
3 // Written by Jezar at Dreampoint, June 2000\r
4 // http://www.dreampoint.co.uk\r
5 // This code is public domain\r
6 \r
7 #include "revmodel.hpp"\r
8 \r
9 revmodel::revmodel()\r
10 {\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
36 \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
46         setwet(initialwet);\r
47         setroomsize(initialroom);\r
48         setdry(initialdry);\r
49         setdamp(initialdamp);\r
50         setwidth(initialwidth);\r
51         setmode(initialmode);\r
52 \r
53         // Buffer will be full of rubbish - so we MUST mute them\r
54         mute();\r
55 }\r
56 \r
57 void revmodel::mute()\r
58 {\r
59         if (getmode() >= freezemode)\r
60                 return;\r
61 \r
62         for (int i=0;i<numcombs;i++)\r
63         {\r
64                 combL[i].mute();\r
65                 combR[i].mute();\r
66         }\r
67         for (int i=0;i<numallpasses;i++)\r
68         {\r
69                 allpassL[i].mute();\r
70                 allpassR[i].mute();\r
71         }\r
72 }\r
73 \r
74 void revmodel::processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)\r
75 {\r
76         float outL,outR,input;\r
77 \r
78         while(numsamples-- > 0)\r
79         {\r
80                 outL = outR = 0;\r
81                 input = (*inputL + *inputR) * gain;\r
82 \r
83                 // Accumulate comb filters in parallel\r
84                 for(int i=0; i<numcombs; i++)\r
85                 {\r
86                         outL += combL[i].process(input);\r
87                         outR += combR[i].process(input);\r
88                 }\r
89 \r
90                 // Feed through allpasses in series\r
91                 for(int i=0; i<numallpasses; i++)\r
92                 {\r
93                         outL = allpassL[i].process(outL);\r
94                         outR = allpassR[i].process(outR);\r
95                 }\r
96 \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
100 \r
101                 // Increment sample pointers, allowing for interleave (if any)\r
102                 inputL += skip;\r
103                 inputR += skip;\r
104                 outputL += skip;\r
105                 outputR += skip;\r
106         }\r
107 }\r
108 \r
109 void revmodel::processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)\r
110 {\r
111         float outL,outR,input;\r
112 \r
113         while(numsamples-- > 0)\r
114         {\r
115                 outL = outR = 0;\r
116                 input = (*inputL + *inputR) * gain;\r
117 \r
118                 // Accumulate comb filters in parallel\r
119                 for(int i=0; i<numcombs; i++)\r
120                 {\r
121                         outL += combL[i].process(input);\r
122                         outR += combR[i].process(input);\r
123                 }\r
124 \r
125                 // Feed through allpasses in series\r
126                 for(int i=0; i<numallpasses; i++)\r
127                 {\r
128                         outL = allpassL[i].process(outL);\r
129                         outR = allpassR[i].process(outR);\r
130                 }\r
131 \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
135 \r
136                 // Increment sample pointers, allowing for interleave (if any)\r
137                 inputL += skip;\r
138                 inputR += skip;\r
139                 outputL += skip;\r
140                 outputR += skip;\r
141         }\r
142 }\r
143 \r
144 void revmodel::update()\r
145 {\r
146 // Recalculate internal values after parameter change\r
147 \r
148         int i;\r
149 \r
150         wet1 = wet*(width/2 + 0.5f);\r
151         wet2 = wet*((1-width)/2);\r
152 \r
153         if (mode >= freezemode)\r
154         {\r
155                 roomsize1 = 1;\r
156                 damp1 = 0;\r
157                 gain = muted;\r
158         }\r
159         else\r
160         {\r
161                 roomsize1 = roomsize;\r
162                 damp1 = damp;\r
163                 gain = fixedgain;\r
164         }\r
165 \r
166         for(i=0; i<numcombs; i++)\r
167         {\r
168                 combL[i].setfeedback(roomsize1);\r
169                 combR[i].setfeedback(roomsize1);\r
170         }\r
171 \r
172         for(i=0; i<numcombs; i++)\r
173         {\r
174                 combL[i].setdamp(damp1);\r
175                 combR[i].setdamp(damp1);\r
176         }\r
177 }\r
178 \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
183 \r
184 void revmodel::setroomsize(float value)\r
185 {\r
186         roomsize = (value*scaleroom) + offsetroom;\r
187         update();\r
188 }\r
189 \r
190 float revmodel::getroomsize()\r
191 {\r
192         return (roomsize-offsetroom)/scaleroom;\r
193 }\r
194 \r
195 void revmodel::setdamp(float value)\r
196 {\r
197         damp = value*scaledamp;\r
198         update();\r
199 }\r
200 \r
201 float revmodel::getdamp()\r
202 {\r
203         return damp/scaledamp;\r
204 }\r
205 \r
206 void revmodel::setwet(float value)\r
207 {\r
208         wet = value*scalewet;\r
209         update();\r
210 }\r
211 \r
212 float revmodel::getwet()\r
213 {\r
214         return wet/scalewet;\r
215 }\r
216 \r
217 void revmodel::setdry(float value)\r
218 {\r
219         dry = value*scaledry;\r
220 }\r
221 \r
222 float revmodel::getdry()\r
223 {\r
224         return dry/scaledry;\r
225 }\r
226 \r
227 void revmodel::setwidth(float value)\r
228 {\r
229         width = value;\r
230         update();\r
231 }\r
232 \r
233 float revmodel::getwidth()\r
234 {\r
235         return width;\r
236 }\r
237 \r
238 void revmodel::setmode(float value)\r
239 {\r
240         mode = value;\r
241         update();\r
242 }\r
243 \r
244 float revmodel::getmode()\r
245 {\r
246         if (mode >= freezemode)\r
247                 return 1;\r
248         else\r
249                 return 0;\r
250 }\r
251 \r
252 //ends\r
253 \r
254 \r
255 \r
256 \r
257 \r