Chris@0
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@0
|
2
|
Chris@2
|
3 #define _USE_MATH_DEFINES
|
Chris@2
|
4
|
Chris@0
|
5 #include <iostream>
|
Chris@0
|
6 #include <cmath>
|
Chris@2
|
7 #include <cstdio>
|
Chris@0
|
8
|
Chris@2
|
9 #include "public.sdk/source/vst2.x/audioeffect.h"
|
Chris@2
|
10
|
Chris@2
|
11 #define snprintf _snprintf
|
Chris@2
|
12 #define alloca _alloca
|
Chris@0
|
13
|
Chris@8
|
14 #define FFTSIZE 1024
|
Chris@4
|
15 #define WINSIZE 1024
|
Chris@4
|
16
|
Chris@4
|
17 #include "median.h"
|
Chris@0
|
18
|
Chris@0
|
19 class Devuvuzelator : public AudioEffect
|
Chris@0
|
20 {
|
Chris@0
|
21 enum {
|
Chris@6
|
22 FundamentalParam = 0,
|
Chris@6
|
23 BandwidthParam = 1,
|
Chris@6
|
24 HarmonicsParam = 2,
|
Chris@6
|
25 ReductionParam = 3,
|
Chris@6
|
26 NumParams = 4
|
Chris@0
|
27 };
|
Chris@0
|
28
|
Chris@0
|
29 public:
|
Chris@0
|
30 Devuvuzelator(audioMasterCallback cb);
|
Chris@0
|
31 ~Devuvuzelator();
|
Chris@0
|
32
|
Chris@0
|
33 virtual void getEffectName(char *n) {
|
Chris@0
|
34 vst_strncpy(n, "Devuvuzelator", kVstMaxEffectNameLen);
|
Chris@0
|
35 }
|
Chris@0
|
36 virtual void getProductString(char *n) {
|
Chris@0
|
37 vst_strncpy(n, "Devuvuzelator", kVstMaxProductStrLen);
|
Chris@0
|
38 }
|
Chris@0
|
39 virtual void getVendorString(char *n) {
|
Chris@0
|
40 vst_strncpy(n, "Queen Mary, University of London", kVstMaxVendorStrLen);
|
Chris@0
|
41 }
|
Chris@0
|
42
|
Chris@0
|
43 virtual void setParameter(VstInt32 index, float value);
|
Chris@0
|
44 virtual float getParameter(VstInt32 index);
|
Chris@0
|
45 virtual void getParameterLabel(VstInt32 index, char* label);
|
Chris@0
|
46 virtual void getParameterDisplay(VstInt32 index, char* text);
|
Chris@0
|
47 virtual void getParameterName(VstInt32 index, char* text);
|
Chris@0
|
48
|
Chris@0
|
49 virtual void setSampleRate (float sampleRate) {
|
Chris@0
|
50 m_sampleRate = sampleRate;
|
Chris@0
|
51 AudioEffect::setSampleRate(sampleRate);
|
Chris@0
|
52 }
|
Chris@0
|
53
|
Chris@0
|
54 virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames) {
|
Chris@0
|
55 m_input = inputs[0];
|
Chris@0
|
56 m_output = outputs[0];
|
Chris@0
|
57 runImpl(sampleFrames);
|
Chris@0
|
58 }
|
Chris@0
|
59
|
Chris@0
|
60 void reset();
|
Chris@0
|
61 void window(float *);
|
Chris@0
|
62 void runImpl(unsigned long);
|
Chris@0
|
63 void processFrame();
|
Chris@0
|
64 void processSpectralFrame();
|
Chris@0
|
65
|
Chris@0
|
66 static void fft(unsigned int n, bool inverse,
|
Chris@0
|
67 double *ri, double *ii, double *ro, double *io);
|
Chris@0
|
68
|
Chris@2
|
69 float m_sampleRate;
|
Chris@0
|
70 float *m_input;
|
Chris@0
|
71 float *m_output;
|
Chris@0
|
72
|
Chris@0
|
73 float m_fundamental;
|
Chris@0
|
74 float m_bandwidth;
|
Chris@2
|
75 int m_harmonics;
|
Chris@0
|
76 float m_reduction;
|
Chris@0
|
77
|
Chris@0
|
78 const int m_fftsize;
|
Chris@4
|
79 const int m_winsize;
|
Chris@0
|
80 const int m_increment;
|
Chris@0
|
81 int m_fill;
|
Chris@0
|
82 int m_read;
|
Chris@0
|
83 float *m_buffer;
|
Chris@0
|
84 float *m_outacc;
|
Chris@8
|
85 double *m_frame;
|
Chris@8
|
86 double *m_spare;
|
Chris@0
|
87 double *m_real;
|
Chris@0
|
88 double *m_imag;
|
Chris@0
|
89 double *m_window;
|
Chris@4
|
90 MedianFilter<double> **m_medians;
|
Chris@0
|
91 };
|
Chris@0
|
92
|
Chris@1
|
93 // VST params 0->1
|
Chris@1
|
94
|
Chris@0
|
95 void
|
Chris@0
|
96 Devuvuzelator::setParameter(VstInt32 index, float value)
|
Chris@0
|
97 {
|
Chris@1
|
98 switch (index) {
|
Chris@4
|
99 case 0: m_fundamental = 50 + 720 * value; break;
|
Chris@4
|
100 case 1: m_bandwidth = 20 + 80 * value; break;
|
Chris@4
|
101 case 2: m_harmonics = int(value * 6 + 0.5); break;
|
Chris@4
|
102 case 3: m_reduction = 100 * value; break;
|
Chris@1
|
103 }
|
Chris@0
|
104 }
|
Chris@0
|
105
|
Chris@0
|
106 float
|
Chris@0
|
107 Devuvuzelator::getParameter(VstInt32 index)
|
Chris@0
|
108 {
|
Chris@1
|
109 switch (index) {
|
Chris@4
|
110 case 0: return (m_fundamental - 50) / 720;
|
Chris@4
|
111 case 1: return (m_bandwidth - 20) / 80;
|
Chris@4
|
112 case 2: return (m_harmonics / 6.f);
|
Chris@4
|
113 case 3: return m_reduction / 100;
|
Chris@1
|
114 }
|
Chris@4
|
115 return 0;
|
Chris@0
|
116 }
|
Chris@0
|
117
|
Chris@0
|
118 // NB! The max name length for VST parameter names, labels
|
Chris@0
|
119 // (i.e. units) and display values (i.e. string renderings of current
|
Chris@0
|
120 // value) is a rather amazing 8 bytes
|
Chris@0
|
121
|
Chris@0
|
122 void
|
Chris@0
|
123 Devuvuzelator::getParameterLabel(VstInt32 index, char *label)
|
Chris@0
|
124 {
|
Chris@0
|
125 const char *units[NumParams] = {
|
Chris@0
|
126 "Hz",
|
Chris@0
|
127 "Hz",
|
Chris@0
|
128 "",
|
Chris@4
|
129 "%",
|
Chris@0
|
130 };
|
Chris@0
|
131
|
Chris@0
|
132 vst_strncpy(label, units[index], kVstMaxParamStrLen);
|
Chris@0
|
133 }
|
Chris@0
|
134
|
Chris@0
|
135 void
|
Chris@0
|
136 Devuvuzelator::getParameterDisplay(VstInt32 index, char *label)
|
Chris@0
|
137 {
|
Chris@4
|
138 switch (index) {
|
Chris@4
|
139 case 0: snprintf(label, kVstMaxParamStrLen, "%f", m_fundamental); break;
|
Chris@4
|
140 case 1: snprintf(label, kVstMaxParamStrLen, "%f", m_bandwidth); break;
|
Chris@4
|
141 case 2: snprintf(label, kVstMaxParamStrLen, "%d", m_harmonics); break;
|
Chris@4
|
142 case 3: snprintf(label, kVstMaxParamStrLen, "%f", m_reduction); break;
|
Chris@4
|
143 }
|
Chris@0
|
144 }
|
Chris@0
|
145
|
Chris@0
|
146 void
|
Chris@0
|
147 Devuvuzelator::getParameterName(VstInt32 index, char *label)
|
Chris@0
|
148 {
|
Chris@0
|
149 const char *names[NumParams] = {
|
Chris@0
|
150 "Pitch",
|
Chris@0
|
151 "B/W",
|
Chris@0
|
152 "Partials",
|
Chris@0
|
153 "Reductn",
|
Chris@0
|
154 };
|
Chris@0
|
155
|
Chris@0
|
156 vst_strncpy(label, names[index], kVstMaxParamStrLen);
|
Chris@0
|
157 }
|
Chris@0
|
158
|
Chris@0
|
159 Devuvuzelator::Devuvuzelator(audioMasterCallback cb) :
|
Chris@0
|
160 AudioEffect(cb, 0, NumParams),
|
Chris@0
|
161 m_sampleRate(0),
|
Chris@0
|
162 m_input(0),
|
Chris@0
|
163 m_output(0),
|
Chris@0
|
164 m_fftsize(FFTSIZE),
|
Chris@7
|
165 m_winsize(WINSIZE),
|
Chris@5
|
166 m_increment(m_winsize/2),
|
Chris@0
|
167 m_fill(0),
|
Chris@0
|
168 m_read(0)
|
Chris@0
|
169 {
|
Chris@4
|
170 m_buffer = new float[m_winsize];
|
Chris@4
|
171 m_outacc = new float[m_winsize * 2];
|
Chris@4
|
172 m_window = new double[m_winsize];
|
Chris@8
|
173 m_frame = new double[m_fftsize];
|
Chris@8
|
174 m_spare = new double[m_fftsize];
|
Chris@0
|
175 m_real = new double[m_fftsize];
|
Chris@0
|
176 m_imag = new double[m_fftsize];
|
Chris@4
|
177 m_medians = new MedianFilter<double> *[m_fftsize/2+1];
|
Chris@0
|
178
|
Chris@4
|
179 for (int i = 0; i < m_winsize; ++i) {
|
Chris@4
|
180 m_window[i] = 0.5 - 0.5 * cos(2 * M_PI * i / m_winsize);
|
Chris@4
|
181 }
|
Chris@4
|
182 for (int i = 0; i < m_fftsize/2+1; ++i) {
|
Chris@4
|
183 m_medians[i] = 0;
|
Chris@0
|
184 }
|
Chris@0
|
185
|
Chris@4
|
186 m_fundamental = 230;
|
Chris@0
|
187 m_bandwidth = 60;
|
Chris@0
|
188 m_harmonics = 3;
|
Chris@4
|
189 m_reduction = 30;
|
Chris@0
|
190
|
Chris@2
|
191 setUniqueID('qmvz');
|
Chris@0
|
192 setNumInputs(1);
|
Chris@0
|
193 setNumOutputs(1);
|
Chris@0
|
194 canProcessReplacing(true);
|
Chris@0
|
195 canDoubleReplacing(false);
|
Chris@0
|
196
|
Chris@0
|
197 reset();
|
Chris@0
|
198 }
|
Chris@0
|
199
|
Chris@0
|
200 Devuvuzelator::~Devuvuzelator()
|
Chris@0
|
201 {
|
Chris@0
|
202 delete[] m_buffer;
|
Chris@0
|
203 delete[] m_outacc;
|
Chris@8
|
204 delete[] m_frame;
|
Chris@8
|
205 delete[] m_spare;
|
Chris@0
|
206 delete[] m_real;
|
Chris@0
|
207 delete[] m_imag;
|
Chris@0
|
208 delete[] m_window;
|
Chris@4
|
209 for (int i = 0; i < m_fftsize/2+1; ++i) {
|
Chris@4
|
210 delete m_medians[i];
|
Chris@4
|
211 }
|
Chris@4
|
212 delete[] m_medians;
|
Chris@0
|
213 }
|
Chris@0
|
214
|
Chris@0
|
215 void
|
Chris@0
|
216 Devuvuzelator::reset()
|
Chris@0
|
217 {
|
Chris@4
|
218 for (int i = 0; i < m_winsize; ++i) {
|
Chris@0
|
219 m_buffer[i] = 0.f;
|
Chris@0
|
220 }
|
Chris@4
|
221 for (int i = 0; i < m_winsize*2; ++i) {
|
Chris@0
|
222 m_outacc[i] = 0.f;
|
Chris@0
|
223 }
|
Chris@0
|
224 m_fill = 0;
|
Chris@0
|
225 m_read = 0;
|
Chris@4
|
226 for (int i = 0; i < m_fftsize/2+1; ++i) {
|
Chris@4
|
227 if (m_medians[i]) m_medians[i]->reset();
|
Chris@4
|
228 }
|
Chris@0
|
229 }
|
Chris@0
|
230
|
Chris@0
|
231 void
|
Chris@0
|
232 Devuvuzelator::runImpl(unsigned long sampleCount)
|
Chris@0
|
233 {
|
Chris@0
|
234 if (!m_input || !m_output) return;
|
Chris@0
|
235
|
Chris@4
|
236 const int sc = sampleCount;
|
Chris@8
|
237 /*
|
Chris@8
|
238 static FILE *blah = 0;
|
Chris@8
|
239 if (!blah) {
|
Chris@8
|
240 blah = fopen("d:\\devuvu-counts.txt", "w");
|
Chris@8
|
241 }
|
Chris@0
|
242
|
Chris@8
|
243 if (m_input == m_output) fprintf(blah, "in-place\n");
|
Chris@8
|
244 */
|
Chris@8
|
245 float *output = m_output;
|
Chris@8
|
246 if (m_input == m_output) {
|
Chris@8
|
247 output = (float *)alloca(sampleCount * sizeof(float));
|
Chris@8
|
248 }
|
Chris@8
|
249 /*
|
Chris@8
|
250 float inmean = 0;
|
Chris@8
|
251 for (int i = 0; i < sc; ++i) {
|
Chris@8
|
252 inmean += m_input[i] * m_input[i];
|
Chris@8
|
253 fprintf(blah, "i:%d:%f ", i, m_input[i]);
|
Chris@8
|
254 }
|
Chris@8
|
255 inmean/=sc;
|
Chris@8
|
256 inmean = sqrt(inmean);
|
Chris@0
|
257
|
Chris@8
|
258 fprintf(blah, "%d\n", (int)sampleCount);
|
Chris@8
|
259 fflush(blah);
|
Chris@8
|
260 */
|
Chris@8
|
261 int oi = 0;
|
Chris@8
|
262 for (int ii = 0; ii < sc; ++ii) {
|
Chris@0
|
263
|
Chris@8
|
264 output[oi++] = m_outacc[m_read++];
|
Chris@8
|
265 // m_output[oi++] = inmean * float(ii%100)/100;
|
Chris@8
|
266 // m_read++;
|
Chris@4
|
267 if (m_fill == m_winsize) {
|
Chris@0
|
268
|
Chris@0
|
269 processFrame();
|
Chris@8
|
270 /*
|
Chris@8
|
271 for (int i = 0; i < m_winsize; ++i) {
|
Chris@8
|
272 float v = m_buffer[i];
|
Chris@8
|
273 fprintf(blah, "%f ", v);
|
Chris@8
|
274 m_outacc[m_winsize + i] = m_buffer[i];//m_input[i];//m_buffer[i] ;//* m_window[i];
|
Chris@8
|
275 }
|
Chris@8
|
276 fprintf(blah, "\n");
|
Chris@8
|
277
|
Chris@8
|
278 // for (int j = 0; j < m_winsize; ++j) {
|
Chris@8
|
279 // m_outacc[m_winsize+j] = inmean * float(j%100)/100;
|
Chris@8
|
280 // }
|
Chris@8
|
281 */
|
Chris@0
|
282
|
Chris@4
|
283 for (int j = m_increment; j < m_winsize; ++j) {
|
Chris@0
|
284 m_buffer[j - m_increment] = m_buffer[j];
|
Chris@0
|
285 }
|
Chris@0
|
286
|
Chris@4
|
287 for (int j = m_increment; j < m_winsize*2; ++j) {
|
Chris@0
|
288 m_outacc[j - m_increment] = m_outacc[j];
|
Chris@0
|
289 }
|
Chris@0
|
290
|
Chris@4
|
291 for (int j = m_winsize*2 - m_increment; j < m_winsize*2; ++j) {
|
Chris@0
|
292 m_outacc[j] = 0.f;
|
Chris@0
|
293 }
|
Chris@0
|
294
|
Chris@8
|
295 m_fill = m_fill - m_increment;
|
Chris@8
|
296 m_read = m_read - m_increment;
|
Chris@0
|
297 }
|
Chris@8
|
298 /*
|
Chris@8
|
299 fprintf(blah, "%d:%f ", ii, m_input[ii]);
|
Chris@8
|
300 */
|
Chris@8
|
301 m_buffer[m_fill] = m_input[ii];
|
Chris@8
|
302 ++m_fill;
|
Chris@8
|
303 }
|
Chris@0
|
304
|
Chris@8
|
305 static int block = 0;
|
Chris@8
|
306 for (int i = 0; i < sc; ++i) {
|
Chris@8
|
307 // m_output[i] = float(block % 100) / 100;
|
Chris@8
|
308 // m_output[i] = inmean * float(i % 100) / 100;
|
Chris@8
|
309 }
|
Chris@8
|
310 ++block;
|
Chris@8
|
311
|
Chris@8
|
312 if (m_input == m_output) {
|
Chris@8
|
313 for (int i = 0; i < sc; ++i) m_output[i] = output[i];
|
Chris@8
|
314 }
|
Chris@0
|
315 }
|
Chris@0
|
316
|
Chris@0
|
317 void
|
Chris@0
|
318 Devuvuzelator::processFrame()
|
Chris@0
|
319 {
|
Chris@8
|
320 /* for (int i = 0; i < m_winsize; ++i) {
|
Chris@8
|
321 m_outacc[m_winsize + i] += m_buffer[i] ;//* m_window[i];
|
Chris@8
|
322 }
|
Chris@8
|
323 return;
|
Chris@8
|
324 */
|
Chris@8
|
325
|
Chris@0
|
326 for (int i = 0; i < m_fftsize; ++i) {
|
Chris@8
|
327 m_frame[i] = 0.0;
|
Chris@4
|
328 }
|
Chris@4
|
329
|
Chris@4
|
330 int ix = m_fftsize - m_winsize/2;
|
Chris@4
|
331 while (ix < 0) ix += m_fftsize;
|
Chris@4
|
332 for (int i = 0; i < m_winsize; ++i) {
|
Chris@8
|
333 m_frame[ix++] += m_buffer[i] * m_window[i];
|
Chris@0
|
334 if (ix == m_fftsize) ix = 0;
|
Chris@0
|
335 }
|
Chris@0
|
336
|
Chris@8
|
337 fft(m_fftsize, false, m_frame, 0, m_real, m_imag);
|
Chris@0
|
338
|
Chris@8
|
339 // processSpectralFrame();
|
Chris@0
|
340
|
Chris@0
|
341 for (int i = 0; i < m_fftsize/2-1; ++i) {
|
Chris@3
|
342 m_real[m_fftsize-i-1] = m_real[i+1];
|
Chris@3
|
343 m_imag[m_fftsize-i-1] = -m_imag[i+1];
|
Chris@0
|
344 }
|
Chris@0
|
345
|
Chris@8
|
346 fft(m_fftsize, true, m_real, m_imag, m_frame, m_spare);
|
Chris@0
|
347
|
Chris@4
|
348 ix = m_fftsize - m_winsize/2;
|
Chris@4
|
349 while (ix < 0) ix += m_fftsize;
|
Chris@4
|
350 for (int i = 0; i < m_winsize; ++i) {
|
Chris@8
|
351 m_outacc[m_winsize + i] += m_frame[ix++];
|
Chris@0
|
352 if (ix == m_fftsize) ix = 0;
|
Chris@0
|
353 }
|
Chris@0
|
354 }
|
Chris@0
|
355
|
Chris@0
|
356 // FFT implementation by Don Cross, public domain.
|
Chris@0
|
357 // This version scales the forward transform.
|
Chris@0
|
358
|
Chris@0
|
359 void Devuvuzelator::fft(unsigned int n, bool inverse,
|
Chris@0
|
360 double *ri, double *ii, double *ro, double *io)
|
Chris@0
|
361 {
|
Chris@0
|
362 if (!ri || !ro || !io) return;
|
Chris@0
|
363
|
Chris@0
|
364 unsigned int bits;
|
Chris@0
|
365 unsigned int i, j, k, m;
|
Chris@0
|
366 unsigned int blockSize, blockEnd;
|
Chris@0
|
367
|
Chris@0
|
368 double tr, ti;
|
Chris@0
|
369
|
Chris@0
|
370 if (n < 2) return;
|
Chris@0
|
371 if (n & (n-1)) return;
|
Chris@0
|
372
|
Chris@0
|
373 double angle = 2.0 * M_PI;
|
Chris@0
|
374 if (inverse) angle = -angle;
|
Chris@0
|
375
|
Chris@0
|
376 for (i = 0; ; ++i) {
|
Chris@0
|
377 if (n & (1 << i)) {
|
Chris@0
|
378 bits = i;
|
Chris@0
|
379 break;
|
Chris@0
|
380 }
|
Chris@0
|
381 }
|
Chris@0
|
382
|
Chris@0
|
383 static unsigned int tableSize = 0;
|
Chris@0
|
384 static int *table = 0;
|
Chris@0
|
385
|
Chris@0
|
386 if (tableSize != n) {
|
Chris@0
|
387
|
Chris@0
|
388 delete[] table;
|
Chris@0
|
389
|
Chris@0
|
390 table = new int[n];
|
Chris@0
|
391
|
Chris@0
|
392 for (i = 0; i < n; ++i) {
|
Chris@0
|
393
|
Chris@0
|
394 m = i;
|
Chris@0
|
395
|
Chris@0
|
396 for (j = k = 0; j < bits; ++j) {
|
Chris@0
|
397 k = (k << 1) | (m & 1);
|
Chris@0
|
398 m >>= 1;
|
Chris@0
|
399 }
|
Chris@0
|
400
|
Chris@0
|
401 table[i] = k;
|
Chris@0
|
402 }
|
Chris@0
|
403
|
Chris@0
|
404 tableSize = n;
|
Chris@0
|
405 }
|
Chris@0
|
406
|
Chris@0
|
407 if (ii) {
|
Chris@0
|
408 for (i = 0; i < n; ++i) {
|
Chris@0
|
409 ro[table[i]] = ri[i];
|
Chris@0
|
410 io[table[i]] = ii[i];
|
Chris@0
|
411 }
|
Chris@0
|
412 } else {
|
Chris@0
|
413 for (i = 0; i < n; ++i) {
|
Chris@0
|
414 ro[table[i]] = ri[i];
|
Chris@0
|
415 io[table[i]] = 0.0;
|
Chris@0
|
416 }
|
Chris@0
|
417 }
|
Chris@0
|
418
|
Chris@0
|
419 blockEnd = 1;
|
Chris@0
|
420
|
Chris@0
|
421 for (blockSize = 2; blockSize <= n; blockSize <<= 1) {
|
Chris@0
|
422
|
Chris@0
|
423 double delta = angle / (double)blockSize;
|
Chris@0
|
424 double sm2 = -sin(-2 * delta);
|
Chris@0
|
425 double sm1 = -sin(-delta);
|
Chris@0
|
426 double cm2 = cos(-2 * delta);
|
Chris@0
|
427 double cm1 = cos(-delta);
|
Chris@0
|
428 double w = 2 * cm1;
|
Chris@0
|
429 double ar[3], ai[3];
|
Chris@0
|
430
|
Chris@0
|
431 for (i = 0; i < n; i += blockSize) {
|
Chris@0
|
432
|
Chris@0
|
433 ar[2] = cm2;
|
Chris@0
|
434 ar[1] = cm1;
|
Chris@0
|
435
|
Chris@0
|
436 ai[2] = sm2;
|
Chris@0
|
437 ai[1] = sm1;
|
Chris@0
|
438
|
Chris@0
|
439 for (j = i, m = 0; m < blockEnd; j++, m++) {
|
Chris@0
|
440
|
Chris@0
|
441 ar[0] = w * ar[1] - ar[2];
|
Chris@0
|
442 ar[2] = ar[1];
|
Chris@0
|
443 ar[1] = ar[0];
|
Chris@0
|
444
|
Chris@0
|
445 ai[0] = w * ai[1] - ai[2];
|
Chris@0
|
446 ai[2] = ai[1];
|
Chris@0
|
447 ai[1] = ai[0];
|
Chris@0
|
448
|
Chris@0
|
449 k = j + blockEnd;
|
Chris@0
|
450 tr = ar[0] * ro[k] - ai[0] * io[k];
|
Chris@0
|
451 ti = ar[0] * io[k] + ai[0] * ro[k];
|
Chris@0
|
452
|
Chris@0
|
453 ro[k] = ro[j] - tr;
|
Chris@0
|
454 io[k] = io[j] - ti;
|
Chris@0
|
455
|
Chris@0
|
456 ro[j] += tr;
|
Chris@0
|
457 io[j] += ti;
|
Chris@0
|
458 }
|
Chris@0
|
459 }
|
Chris@0
|
460
|
Chris@0
|
461 blockEnd = blockSize;
|
Chris@0
|
462 }
|
Chris@0
|
463
|
Chris@0
|
464 if (!inverse) {
|
Chris@0
|
465
|
Chris@0
|
466 double denom = (double)n;
|
Chris@0
|
467
|
Chris@0
|
468 for (i = 0; i < n; i++) {
|
Chris@0
|
469 ro[i] /= denom;
|
Chris@0
|
470 io[i] /= denom;
|
Chris@0
|
471 }
|
Chris@0
|
472 }
|
Chris@0
|
473 }
|
Chris@0
|
474
|
Chris@0
|
475 AudioEffect *createEffectInstance(audioMasterCallback audioMaster)
|
Chris@0
|
476 {
|
Chris@0
|
477 return new Devuvuzelator(audioMaster);
|
Chris@0
|
478 }
|
Chris@0
|
479
|
Chris@1
|
480 #include "devuvuzelator.cpp"
|
Chris@1
|
481
|