]> git.sesse.net Git - vlc/blob - modules/audio_filter/spatializer/revmodel.cpp
demux: ts: don't try to seek on non seekable
[vlc] / modules / audio_filter / spatializer / revmodel.cpp
1 // Reverb model implementation
2 //
3 //
4 // Google Summer of Code 2007
5 //
6 // Authors: Biodun Osunkunle <biodun@videolan.org>
7 //
8 // Mentor : Jean-Baptiste Kempf <jb@videolan.org>
9 //
10 // Original written by Jezar at Dreampoint, June 2000
11
12 // This code is public domain
13
14 #include "revmodel.hpp"
15 #include "tuning.h"
16 #include <stdlib.h>
17
18 revmodel::revmodel() : roomsize(initialroom), damp(initialdamp),
19                        wet(initialwet), dry(initialdry), width(1.), mode(0.)
20 {
21     // Tie the components to their buffers
22     combL[0].setbuffer(bufcombL1,combtuningL1);
23     combR[0].setbuffer(bufcombR1,combtuningR1);
24     combL[1].setbuffer(bufcombL2,combtuningL2);
25     combR[1].setbuffer(bufcombR2,combtuningR2);
26     combL[2].setbuffer(bufcombL3,combtuningL3);
27     combR[2].setbuffer(bufcombR3,combtuningR3);
28     combL[3].setbuffer(bufcombL4,combtuningL4);
29     combR[3].setbuffer(bufcombR4,combtuningR4);
30     combL[4].setbuffer(bufcombL5,combtuningL5);
31     combR[4].setbuffer(bufcombR5,combtuningR5);
32     combL[5].setbuffer(bufcombL6,combtuningL6);
33     combR[5].setbuffer(bufcombR6,combtuningR6);
34     combL[6].setbuffer(bufcombL7,combtuningL7);
35     combR[6].setbuffer(bufcombR7,combtuningR7);
36     combL[7].setbuffer(bufcombL8,combtuningL8);
37     combR[7].setbuffer(bufcombR8,combtuningR8);
38     allpassL[0].setbuffer(bufallpassL1,allpasstuningL1);
39     allpassR[0].setbuffer(bufallpassR1,allpasstuningR1);
40     allpassL[1].setbuffer(bufallpassL2,allpasstuningL2);
41     allpassR[1].setbuffer(bufallpassR2,allpasstuningR2);
42     allpassL[2].setbuffer(bufallpassL3,allpasstuningL3);
43     allpassR[2].setbuffer(bufallpassR3,allpasstuningR3);
44     allpassL[3].setbuffer(bufallpassL4,allpasstuningL4);
45     allpassR[3].setbuffer(bufallpassR4,allpasstuningR4);
46
47     // Set default values
48     allpassL[0].setfeedback(0.5f);
49     allpassR[0].setfeedback(0.5f);
50     allpassL[1].setfeedback(0.5f);
51     allpassR[1].setfeedback(0.5f);
52     allpassL[2].setfeedback(0.5f);
53     allpassR[2].setfeedback(0.5f);
54     allpassL[3].setfeedback(0.5f);
55     allpassR[3].setfeedback(0.5f);
56     setwet(initialwet);
57     setroomsize(initialroom);
58     setdry(initialdry);
59     setdamp(initialdamp);
60     setwidth(initialwidth);
61     setmode(initialmode);
62
63     // Buffer will be full of rubbish - so we MUST mute them
64     mute();
65 }
66
67 void revmodel::mute()
68 {
69     int i;
70     if (mode >= freezemode)
71         return;
72
73     for (i = 0 ; i < numcombs ; i++)
74     {
75         combL[i].mute();
76         combR[i].mute();
77     }
78     for (i=0;i<numallpasses;i++)
79     {
80         allpassL[i].mute();
81         allpassR[i].mute();
82     }
83 }
84
85 /*****************************************************************************
86  *  Transforms the audio stream
87  * /param float *inputL     input buffer
88  * /param float *outputL   output buffer
89  * /param long numsamples  number of samples to be processed
90  * /param int skip             number of channels in the audio stream
91  *****************************************************************************/
92 void revmodel::processreplace(float *inputL, float *outputL, long /* numsamples */, int skip)
93 {
94     float outL,outR,input;
95     float inputR;
96     int i;
97
98     outL = outR = 0;
99         /* TODO this module supports only 2 audio channels, let's improve this */
100         if (skip > 1)
101            inputR = inputL[1];
102         else
103            inputR = inputL[0];
104         input = (inputL[0] + inputR) * gain;
105
106         // Accumulate comb filters in parallel
107         for(i=0; i<numcombs; i++)
108         {
109             outL += combL[i].process(input);
110             outR += combR[i].process(input);
111         }
112
113         // Feed through allpasses in series
114         for(i=0; i<numallpasses; i++)
115         {
116             outL = allpassL[i].process(outL);
117             outR = allpassR[i].process(outR);
118         }
119
120         // Calculate output REPLACING anything already there
121         outputL[0] = (outL*wet1 + outR*wet2 + inputR*dry);
122            if (skip > 1)
123         outputL[1] = (outR*wet1 + outL*wet2 + inputR*dry);
124 }
125
126 void revmodel::processmix(float *inputL, float *outputL, long /* numsamples */, int skip)
127 {
128     float outL,outR,input;
129     float inputR;
130
131     outL = outR = 0;
132         if (skip > 1)
133            inputR = inputL[1];
134         else
135            inputR = inputL[0];
136         input = (inputL[0] + inputR) * gain;
137
138         // Accumulate comb filters in parallel
139         for(int i=0; i<numcombs; i++)
140         {
141             outL += combL[i].process(input);
142             outR += combR[i].process(input);
143         }
144
145         // Feed through allpasses in series
146         for(int i=0; i<numallpasses; i++)
147         {
148             outL = allpassL[i].process(outL);
149             outR = allpassR[i].process(outR);
150         }
151
152         // Calculate output REPLACING anything already there
153         outputL[0] += (outL*wet1 + outR*wet2 + inputR*dry);
154            if (skip > 1)
155         outputL[1] += (outR*wet1 + outL*wet2 + inputR*dry);
156 }
157
158 void revmodel::update()
159 {
160 // Recalculate internal values after parameter change
161
162     wet1 = wet*(width/2 + 0.5f);
163     wet2 = wet*((1-width)/2);
164
165     if (mode >= freezemode)
166     {
167         roomsize1 = 1;
168         damp1 = 0;
169         gain = muted;
170     }
171     else
172     {
173         roomsize1 = roomsize;
174         damp1 = damp;
175         gain = fixedgain;
176     }
177
178     for(int i=0; i<numcombs; i++)
179     {
180         combL[i].setfeedback(roomsize1);
181         combR[i].setfeedback(roomsize1);
182     }
183
184     for(int i=0; i<numcombs; i++)
185     {
186         combL[i].setdamp(damp1);
187         combR[i].setdamp(damp1);
188     }
189 }
190
191 // The following get/set functions are not inlined, because
192 // speed is never an issue when calling them, and also
193 // because as you develop the reverb model, you may
194 // wish to take dynamic action when they are called.
195
196 void revmodel::setroomsize(float value)
197 {
198     roomsize = (value*scaleroom) + offsetroom;
199     update();
200 }
201
202 float revmodel::getroomsize()
203 {
204     return (roomsize-offsetroom)/scaleroom;
205 }
206
207 void revmodel::setdamp(float value)
208 {
209     damp = value*scaledamp;
210     update();
211 }
212
213 float revmodel::getdamp()
214 {
215     return damp/scaledamp;
216 }
217
218 void revmodel::setwet(float value)
219 {
220     wet = value*scalewet;
221     update();
222 }
223
224 float revmodel::getwet()
225 {
226     return wet/scalewet;
227 }
228
229 void revmodel::setdry(float value)
230 {
231     dry = value*scaledry;
232 }
233
234 float revmodel::getdry()
235 {
236     return dry/scaledry;
237 }
238
239 void revmodel::setwidth(float value)
240 {
241     width = value;
242     update();
243 }
244
245 float revmodel::getwidth()
246 {
247     return width;
248 }
249
250 void revmodel::setmode(float value)
251 {
252     mode = value;
253     update();
254 }
255
256 //ends