comparison devuvuzelator-vst.cpp @ 1:0d2126c32309

* split out core code, fix some things
author Chris Cannam
date Fri, 11 Jun 2010 10:31:29 +0100
parents fe4c331213c5
children e621e794011f
comparison
equal deleted inserted replaced
0:fe4c331213c5 1:0d2126c32309
62 62
63 int m_sampleRate; 63 int m_sampleRate;
64 float *m_input; 64 float *m_input;
65 float *m_output; 65 float *m_output;
66 66
67 float m_low;
67 float m_high; 68 float m_high;
68 float m_low;
69 float m_fundamental; 69 float m_fundamental;
70 float m_bandwidth; 70 float m_bandwidth;
71 float m_harmonics; 71 float m_harmonics;
72 float m_reduction; 72 float m_reduction;
73 73
80 double *m_real; 80 double *m_real;
81 double *m_imag; 81 double *m_imag;
82 double *m_window; 82 double *m_window;
83 }; 83 };
84 84
85 // VST params 0->1
86
85 void 87 void
86 Devuvuzelator::setParameter(VstInt32 index, float value) 88 Devuvuzelator::setParameter(VstInt32 index, float value)
87 { 89 {
88 float *params[NumParams] = { 90 switch (index) {
89 m_low, 91 case 0: m_low = -80 + 80 * value; break;
90 m_high, 92 case 1: m_high = -80 + 80 * value; break;
91 m_fundamental, 93 case 2: m_fundamental = 110 + 440 * value; break;
92 m_bandwidth, 94 case 3: m_bandwidth = 20 + 80 * value; break;
93 m_harmonics, 95 case 4: m_harmonics = int(value * 6 + 0.5); break;
94 m_reduction, 96 case 5: m_reduction = 20 * value; break;
95 }; 97 }
96
97 *params[index] = value;
98 } 98 }
99 99
100 float 100 float
101 Devuvuzelator::getParameter(VstInt32 index) 101 Devuvuzelator::getParameter(VstInt32 index)
102 { 102 {
103 float *params[NumParams] = { 103 switch (index) {
104 m_low, 104 case 0: return (m_low + 80) / 80;
105 m_high, 105 case 1: return (m_high + 80) / 80;
106 m_fundamental, 106 case 2: return (m_fundamental - 110) / 440;
107 m_bandwidth, 107 case 3: return (m_bandwidth - 20) / 80;
108 m_harmonics, 108 case 4: return (m_harmonics / 6.0);
109 m_reduction, 109 case 5: return m_reduction / 20;
110 }; 110 }
111
112 return *params[index];
113 } 111 }
114 112
115 // NB! The max name length for VST parameter names, labels 113 // NB! The max name length for VST parameter names, labels
116 // (i.e. units) and display values (i.e. string renderings of current 114 // (i.e. units) and display values (i.e. string renderings of current
117 // value) is a rather amazing 8 bytes 115 // value) is a rather amazing 8 bytes
132 } 130 }
133 131
134 void 132 void
135 Devuvuzelator::getParameterDisplay(VstInt32 index, char *label) 133 Devuvuzelator::getParameterDisplay(VstInt32 index, char *label)
136 { 134 {
137 snprintf(label, kVstMaxParamStrLen, "%f", getParameter(index)); 135 float *params[NumParams] = {
136 m_low,
137 m_high,
138 m_fundamental,
139 m_bandwidth,
140 m_harmonics,
141 m_reduction,
142 };
143
144 snprintf(label, kVstMaxParamStrLen, "%f", *params[index]);
138 } 145 }
139 146
140 void 147 void
141 Devuvuzelator::getParameterName(VstInt32 index, char *label) 148 Devuvuzelator::getParameterName(VstInt32 index, char *label)
142 { 149 {
275 m_outacc[m_fftsize + i] += frame[ix++] * m_window[i]; 282 m_outacc[m_fftsize + i] += frame[ix++] * m_window[i];
276 if (ix == m_fftsize) ix = 0; 283 if (ix == m_fftsize) ix = 0;
277 } 284 }
278 } 285 }
279 286
280 void
281 Devuvuzelator::processSpectralFrame()
282 {
283 const int hs = m_fftsize/2 + 1;
284 double *mags = (double *)alloca(hs * sizeof(double));
285 double *ratios = (double *)alloca(hs * sizeof(double));
286 for (int i = 0; i < hs; ++i) {
287 ratios[i] = 1.0;
288 mags[i] = sqrt(m_real[i] * m_real[i] + m_imag[i] * m_imag[i]);
289 }
290
291 double low = -35;
292 double high = -20;
293
294 if (m_low) low = *m_low;
295 if (m_high) high = *m_high;
296
297 int harmonics = 3;
298 if (m_harmonics) harmonics = int(*m_harmonics + 0.5);
299
300 double fun = 200;
301 if (m_fundamental) fun = *m_fundamental;
302
303 double bw = 40;
304 if (m_bandwidth) bw = *m_bandwidth;
305
306 double lowfun = fun - bw/2;
307 double highfun = fun + bw+2;
308
309 double reduction = 10;
310 if (m_reduction) reduction = *m_reduction;
311
312 for (int h = 0; h < harmonics; ++h) {
313
314 double lowfreq = lowfun * (h+1);
315 double highfreq = highfun * (h+1);
316
317 int lowbin = (m_fftsize * lowfreq) / m_sampleRate;
318 int highbin = (m_fftsize * highfreq) / m_sampleRate;
319
320 for (int i = lowbin; i <= highbin; ++i) {
321 ratios[i] = 1.0;
322 double db = 10 * log10(mags[i]);
323 if (db > low && db < high) {
324 double r = reduction;
325 ratios[i] = pow(10, -r / 10);
326 }
327 }
328 }
329
330 for (int i = 0; i < hs-1; ++i) {
331 if (ratios[i] == 1.0 && ratios[i+1] < 1.0) {
332 ratios[i] = (ratios[i+1] + 1) / 2;
333 } else if (ratios[i] < 1.0 && ratios[i+1] == 1.0) {
334 ratios[i+1] = (ratios[i] + 1) / 2;
335 ++i;
336 }
337 }
338
339 for (int i = 0; i < hs; ++i) {
340 m_real[i] *= ratios[i];
341 m_imag[i] *= ratios[i];
342 }
343 }
344
345 // FFT implementation by Don Cross, public domain. 287 // FFT implementation by Don Cross, public domain.
346 // This version scales the forward transform. 288 // This version scales the forward transform.
347 289
348 void Devuvuzelator::fft(unsigned int n, bool inverse, 290 void Devuvuzelator::fft(unsigned int n, bool inverse,
349 double *ri, double *ii, double *ro, double *io) 291 double *ri, double *ii, double *ro, double *io)
464 AudioEffect *createEffectInstance(audioMasterCallback audioMaster) 406 AudioEffect *createEffectInstance(audioMasterCallback audioMaster)
465 { 407 {
466 return new Devuvuzelator(audioMaster); 408 return new Devuvuzelator(audioMaster);
467 } 409 }
468 410
411 #include "devuvuzelator.cpp"
412