annotate devuvuzelator-vst.cpp @ 19:0cdedb2fab81 tip

* OS/X build fixes
author Chris Cannam
date Fri, 18 Jun 2010 11:18:49 +0100
parents 1e6360396b6c
children
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@13 3 #define _USE_MATH_DEFINES
Chris@13 4 #include <cmath>
Chris@13 5
Chris@9 6 #include "devuvuzelator-vst.h"
Chris@9 7
Chris@0 8 #include <iostream>
Chris@2 9 #include <cstdio>
Chris@0 10
Chris@9 11 #include "params.h"
Chris@2 12
Chris@2 13 #define snprintf _snprintf
Chris@2 14 #define alloca _alloca
Chris@0 15
Chris@1 16 // VST params 0->1
Chris@1 17
Chris@0 18 void
Chris@0 19 Devuvuzelator::setParameter(VstInt32 index, float value)
Chris@0 20 {
Chris@1 21 switch (index) {
Chris@4 22 case 0: m_fundamental = 50 + 720 * value; break;
Chris@4 23 case 1: m_bandwidth = 20 + 80 * value; break;
Chris@4 24 case 2: m_harmonics = int(value * 6 + 0.5); break;
Chris@4 25 case 3: m_reduction = 100 * value; break;
Chris@1 26 }
Chris@0 27 }
Chris@0 28
Chris@0 29 float
Chris@0 30 Devuvuzelator::getParameter(VstInt32 index)
Chris@0 31 {
Chris@1 32 switch (index) {
Chris@4 33 case 0: return (m_fundamental - 50) / 720;
Chris@4 34 case 1: return (m_bandwidth - 20) / 80;
Chris@4 35 case 2: return (m_harmonics / 6.f);
Chris@4 36 case 3: return m_reduction / 100;
Chris@1 37 }
Chris@4 38 return 0;
Chris@0 39 }
Chris@0 40
Chris@0 41 // NB! The max name length for VST parameter names, labels
Chris@0 42 // (i.e. units) and display values (i.e. string renderings of current
Chris@0 43 // value) is a rather amazing 8 bytes
Chris@0 44
Chris@0 45 void
Chris@0 46 Devuvuzelator::getParameterLabel(VstInt32 index, char *label)
Chris@0 47 {
Chris@0 48 const char *units[NumParams] = {
Chris@0 49 "Hz",
Chris@0 50 "Hz",
Chris@0 51 "",
Chris@4 52 "%",
Chris@0 53 };
Chris@0 54
Chris@0 55 vst_strncpy(label, units[index], kVstMaxParamStrLen);
Chris@0 56 }
Chris@0 57
Chris@0 58 void
Chris@0 59 Devuvuzelator::getParameterDisplay(VstInt32 index, char *label)
Chris@0 60 {
Chris@4 61 switch (index) {
Chris@4 62 case 0: snprintf(label, kVstMaxParamStrLen, "%f", m_fundamental); break;
Chris@4 63 case 1: snprintf(label, kVstMaxParamStrLen, "%f", m_bandwidth); break;
Chris@4 64 case 2: snprintf(label, kVstMaxParamStrLen, "%d", m_harmonics); break;
Chris@4 65 case 3: snprintf(label, kVstMaxParamStrLen, "%f", m_reduction); break;
Chris@4 66 }
Chris@0 67 }
Chris@0 68
Chris@0 69 void
Chris@0 70 Devuvuzelator::getParameterName(VstInt32 index, char *label)
Chris@0 71 {
Chris@0 72 const char *names[NumParams] = {
Chris@0 73 "Pitch",
Chris@0 74 "B/W",
Chris@0 75 "Partials",
Chris@0 76 "Reductn",
Chris@0 77 };
Chris@0 78
Chris@0 79 vst_strncpy(label, names[index], kVstMaxParamStrLen);
Chris@0 80 }
Chris@0 81
Chris@0 82 Devuvuzelator::Devuvuzelator(audioMasterCallback cb) :
Chris@0 83 AudioEffect(cb, 0, NumParams),
Chris@0 84 m_sampleRate(0),
Chris@0 85 m_input(0),
Chris@0 86 m_output(0),
Chris@0 87 m_fftsize(FFTSIZE),
Chris@7 88 m_winsize(WINSIZE),
Chris@5 89 m_increment(m_winsize/2),
Chris@9 90 m_filtersecs(FILTERSECS),
Chris@0 91 m_fill(0),
Chris@0 92 m_read(0)
Chris@0 93 {
Chris@4 94 m_buffer = new float[m_winsize];
Chris@4 95 m_outacc = new float[m_winsize * 2];
Chris@4 96 m_window = new double[m_winsize];
Chris@9 97 m_frame = new double[m_fftsize];
Chris@9 98 m_spare = new double[m_fftsize];
Chris@0 99 m_real = new double[m_fftsize];
Chris@0 100 m_imag = new double[m_fftsize];
Chris@4 101 m_medians = new MedianFilter<double> *[m_fftsize/2+1];
Chris@0 102
Chris@4 103 for (int i = 0; i < m_winsize; ++i) {
Chris@4 104 m_window[i] = 0.5 - 0.5 * cos(2 * M_PI * i / m_winsize);
Chris@4 105 }
Chris@4 106 for (int i = 0; i < m_fftsize/2+1; ++i) {
Chris@4 107 m_medians[i] = 0;
Chris@0 108 }
Chris@0 109
Chris@4 110 m_fundamental = 230;
Chris@0 111 m_bandwidth = 60;
Chris@0 112 m_harmonics = 3;
Chris@4 113 m_reduction = 30;
Chris@0 114
Chris@2 115 setUniqueID('qmvz');
Chris@0 116 setNumInputs(1);
Chris@0 117 setNumOutputs(1);
Chris@0 118 canProcessReplacing(true);
Chris@0 119 canDoubleReplacing(false);
Chris@0 120
Chris@0 121 reset();
Chris@0 122 }
Chris@0 123
Chris@0 124 Devuvuzelator::~Devuvuzelator()
Chris@0 125 {
Chris@0 126 delete[] m_buffer;
Chris@0 127 delete[] m_outacc;
Chris@9 128 delete[] m_frame;
Chris@9 129 delete[] m_spare;
Chris@0 130 delete[] m_real;
Chris@0 131 delete[] m_imag;
Chris@0 132 delete[] m_window;
Chris@4 133 for (int i = 0; i < m_fftsize/2+1; ++i) {
Chris@4 134 delete m_medians[i];
Chris@4 135 }
Chris@4 136 delete[] m_medians;
Chris@0 137 }
Chris@0 138
Chris@0 139 void
Chris@0 140 Devuvuzelator::reset()
Chris@0 141 {
Chris@4 142 for (int i = 0; i < m_winsize; ++i) {
Chris@0 143 m_buffer[i] = 0.f;
Chris@0 144 }
Chris@4 145 for (int i = 0; i < m_winsize*2; ++i) {
Chris@0 146 m_outacc[i] = 0.f;
Chris@0 147 }
Chris@0 148 m_fill = 0;
Chris@0 149 m_read = 0;
Chris@4 150 for (int i = 0; i < m_fftsize/2+1; ++i) {
Chris@4 151 if (m_medians[i]) m_medians[i]->reset();
Chris@4 152 }
Chris@0 153 }
Chris@0 154
Chris@0 155 void
Chris@0 156 Devuvuzelator::runImpl(unsigned long sampleCount)
Chris@0 157 {
Chris@0 158 if (!m_input || !m_output) return;
Chris@0 159
Chris@4 160 const int sc = sampleCount;
Chris@0 161
Chris@9 162 float *output = m_output;
Chris@9 163 if (m_input == m_output) {
Chris@9 164 output = (float *)alloca(sampleCount * sizeof(float));
Chris@9 165 }
Chris@0 166
Chris@9 167 int oi = 0;
Chris@9 168 for (int ii = 0; ii < sc; ++ii) {
Chris@0 169
Chris@9 170 output[oi++] = m_outacc[m_read++];
Chris@4 171 if (m_fill == m_winsize) {
Chris@0 172
Chris@0 173 processFrame();
Chris@0 174
Chris@4 175 for (int j = m_increment; j < m_winsize; ++j) {
Chris@0 176 m_buffer[j - m_increment] = m_buffer[j];
Chris@0 177 }
Chris@0 178
Chris@4 179 for (int j = m_increment; j < m_winsize*2; ++j) {
Chris@0 180 m_outacc[j - m_increment] = m_outacc[j];
Chris@0 181 }
Chris@0 182
Chris@4 183 for (int j = m_winsize*2 - m_increment; j < m_winsize*2; ++j) {
Chris@0 184 m_outacc[j] = 0.f;
Chris@0 185 }
Chris@0 186
Chris@8 187 m_fill = m_fill - m_increment;
Chris@8 188 m_read = m_read - m_increment;
Chris@0 189 }
Chris@9 190 m_buffer[m_fill] = m_input[ii];
Chris@9 191 ++m_fill;
Chris@8 192 }
Chris@0 193
Chris@9 194 if (m_input == m_output) {
Chris@9 195 for (int i = 0; i < sc; ++i) m_output[i] = output[i];
Chris@9 196 }
Chris@0 197 }
Chris@0 198
Chris@0 199 void
Chris@0 200 Devuvuzelator::processFrame()
Chris@0 201 {
Chris@0 202 for (int i = 0; i < m_fftsize; ++i) {
Chris@8 203 m_frame[i] = 0.0;
Chris@4 204 }
Chris@4 205
Chris@4 206 int ix = m_fftsize - m_winsize/2;
Chris@4 207 while (ix < 0) ix += m_fftsize;
Chris@4 208 for (int i = 0; i < m_winsize; ++i) {
Chris@8 209 m_frame[ix++] += m_buffer[i] * m_window[i];
Chris@0 210 if (ix == m_fftsize) ix = 0;
Chris@0 211 }
Chris@0 212
Chris@8 213 fft(m_fftsize, false, m_frame, 0, m_real, m_imag);
Chris@0 214
Chris@9 215 processSpectralFrame();
Chris@0 216
Chris@0 217 for (int i = 0; i < m_fftsize/2-1; ++i) {
Chris@3 218 m_real[m_fftsize-i-1] = m_real[i+1];
Chris@3 219 m_imag[m_fftsize-i-1] = -m_imag[i+1];
Chris@0 220 }
Chris@0 221
Chris@8 222 fft(m_fftsize, true, m_real, m_imag, m_frame, m_spare);
Chris@0 223
Chris@4 224 ix = m_fftsize - m_winsize/2;
Chris@4 225 while (ix < 0) ix += m_fftsize;
Chris@4 226 for (int i = 0; i < m_winsize; ++i) {
Chris@8 227 m_outacc[m_winsize + i] += m_frame[ix++];
Chris@0 228 if (ix == m_fftsize) ix = 0;
Chris@0 229 }
Chris@0 230 }
Chris@0 231
Chris@0 232 AudioEffect *createEffectInstance(audioMasterCallback audioMaster)
Chris@0 233 {
Chris@0 234 return new Devuvuzelator(audioMaster);
Chris@0 235 }
Chris@0 236
Chris@1 237