~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to arts/modules/freeverb/revmodel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

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