diff devuvuzelator-vst.cpp @ 4:d90abfa9585a

* Adaptive method
author Chris Cannam
date Fri, 11 Jun 2010 15:38:44 +0100
parents 8b79175c9f02
children 45bcfa3d5da7
line wrap: on
line diff
--- a/devuvuzelator-vst.cpp	Fri Jun 11 11:45:41 2010 +0100
+++ b/devuvuzelator-vst.cpp	Fri Jun 11 15:38:44 2010 +0100
@@ -12,18 +12,19 @@
 #define snprintf _snprintf
 #define alloca _alloca
 
-#define FFTSIZE 1024
+#define FFTSIZE 4096
+#define WINSIZE 1024
+
+#include "median.h"
 
 class Devuvuzelator : public AudioEffect
 {
     enum {
-        LowParam       = 0,
-        HighParam      = 1,
-        FundamentalParam = 2,
-        BandwidthParam = 3,
-        HarmonicsParam = 4,
-        ReductionParam = 5,
-        NumParams      = 6
+        FundamentalParam = 1,
+        BandwidthParam = 2,
+        HarmonicsParam = 3,
+        ReductionParam = 4,
+        NumParams      = 5
     };
 
 public:
@@ -78,6 +79,7 @@
     float m_reduction;
 
     const int m_fftsize;
+    const int m_winsize;
     const int m_increment;
     int m_fill;
     int m_read;
@@ -86,6 +88,7 @@
     double *m_real;
     double *m_imag;
     double *m_window;
+    MedianFilter<double> **m_medians;
 };
 
 // VST params 0->1
@@ -94,12 +97,10 @@
 Devuvuzelator::setParameter(VstInt32 index, float value)
 {
     switch (index) {
-    case 0: m_low = -80 + 80 * value; break;
-    case 1: m_high = -80 + 80 * value; break;
-    case 2: m_fundamental = 110 + 440 * value; break;
-    case 3: m_bandwidth = 20 + 80 * value; break;
-    case 4: m_harmonics = int(value * 6 + 0.5); break;
-    case 5: m_reduction = 20 * value; break;
+    case 0: m_fundamental = 50 + 720 * value; break;
+    case 1: m_bandwidth = 20 + 80 * value; break;
+    case 2: m_harmonics = int(value * 6 + 0.5); break;
+    case 3: m_reduction = 100 * value; break;
     }
 }
 
@@ -107,14 +108,12 @@
 Devuvuzelator::getParameter(VstInt32 index)
 {
     switch (index) {
-    case 0: return (m_low + 80) / 80;
-    case 1: return (m_high + 80) / 80;
-    case 2: return (m_fundamental - 110) / 440;
-    case 3: return (m_bandwidth - 20) / 80;
-    case 4: return (m_harmonics / 6.f);
-    case 5: return m_reduction / 20;
+    case 0: return (m_fundamental - 50) / 720;
+    case 1: return (m_bandwidth - 20) / 80;
+    case 2: return (m_harmonics / 6.f);
+    case 3: return m_reduction / 100;
     }
-	return 0;
+    return 0;
 }
 
 // NB! The max name length for VST parameter names, labels
@@ -125,12 +124,10 @@
 Devuvuzelator::getParameterLabel(VstInt32 index, char *label)
 {
     const char *units[NumParams] = {
-        "dB",
-        "dB",
         "Hz",
         "Hz",
         "",
-        "dB",
+        "%",
     };
     
     vst_strncpy(label, units[index], kVstMaxParamStrLen);
@@ -139,22 +136,18 @@
 void
 Devuvuzelator::getParameterDisplay(VstInt32 index, char *label)
 {
-	switch (index) {
-		case 0: snprintf(label, kVstMaxParamStrLen, "%f", m_low); break;
-		case 1: snprintf(label, kVstMaxParamStrLen, "%f", m_high); break;
-		case 2: snprintf(label, kVstMaxParamStrLen, "%f", m_fundamental); break;
-		case 3: snprintf(label, kVstMaxParamStrLen, "%f", m_bandwidth); break;
-		case 4: snprintf(label, kVstMaxParamStrLen, "%d", m_harmonics); break;
-		case 5: snprintf(label, kVstMaxParamStrLen, "%f", m_reduction); break;
-	}
+    switch (index) {
+    case 0: snprintf(label, kVstMaxParamStrLen, "%f", m_fundamental); break;
+    case 1: snprintf(label, kVstMaxParamStrLen, "%f", m_bandwidth); break;
+    case 2: snprintf(label, kVstMaxParamStrLen, "%d", m_harmonics); break;
+    case 3: snprintf(label, kVstMaxParamStrLen, "%f", m_reduction); break;
+    }
 }
 
 void
 Devuvuzelator::getParameterName(VstInt32 index, char *label)
 {
     const char *names[NumParams] = {
-        "Floor",
-        "Ceiling",
         "Pitch",
         "B/W",
         "Partials",
@@ -169,29 +162,29 @@
     m_sampleRate(0),
     m_input(0),
     m_output(0),
-    m_low(0),
-    m_high(0),
     m_fftsize(FFTSIZE),
     m_increment(m_fftsize/4),
     m_fill(0),
     m_read(0)
 {
-    m_buffer = new float[m_fftsize];
-    m_outacc = new float[m_fftsize * 2];
+    m_buffer = new float[m_winsize];
+    m_outacc = new float[m_winsize * 2];
+    m_window = new double[m_winsize];
     m_real = new double[m_fftsize];
     m_imag = new double[m_fftsize];
-    m_window = new double[m_fftsize];
+    m_medians = new MedianFilter<double> *[m_fftsize/2+1];
 
-    for (int i = 0; i < m_fftsize; ++i) {
-        m_window[i] = 0.5 - 0.5 * cos(2 * M_PI * i / m_fftsize);
+    for (int i = 0; i < m_winsize; ++i) {
+        m_window[i] = 0.5 - 0.5 * cos(2 * M_PI * i / m_winsize);
+    }
+    for (int i = 0; i < m_fftsize/2+1; ++i) {
+        m_medians[i] = 0;
     }
 
-    m_low = -40;
-    m_high = -20;
-    m_fundamental = 220;
+    m_fundamental = 230;
     m_bandwidth = 60;
     m_harmonics = 3;
-    m_reduction = 10;
+    m_reduction = 30;
     
     setUniqueID('qmvz');
     setNumInputs(1);
@@ -209,19 +202,26 @@
     delete[] m_real;
     delete[] m_imag;
     delete[] m_window;
+    for (int i = 0; i < m_fftsize/2+1; ++i) {
+        delete m_medians[i];
+    }
+    delete[] m_medians;
 }
 
 void
 Devuvuzelator::reset()
 {
-    for (int i = 0; i < m_fftsize; ++i) {
+    for (int i = 0; i < m_winsize; ++i) {
         m_buffer[i] = 0.f;
     }
-    for (int i = 0; i < m_fftsize*2; ++i) {
+    for (int i = 0; i < m_winsize*2; ++i) {
         m_outacc[i] = 0.f;
     }
     m_fill = 0;
     m_read = 0;
+    for (int i = 0; i < m_fftsize/2+1; ++i) {
+        if (m_medians[i]) m_medians[i]->reset();
+    }
 }
 
 void
@@ -231,25 +231,25 @@
 
     int ii = 0;
     int oi = 0;
-	const int sc = sampleCount;
+    const int sc = sampleCount;
 
     while (ii < sc) {
 
-        m_output[oi++] = m_outacc[m_read++] / 1.5f;
+        m_output[oi++] = m_outacc[m_read++];
 
-        if (m_fill == m_fftsize) {
+        if (m_fill == m_winsize) {
 
             processFrame();
 
-            for (int j = m_increment; j < m_fftsize; ++j) {
+            for (int j = m_increment; j < m_winsize; ++j) {
                 m_buffer[j - m_increment] = m_buffer[j];
             }
 
-            for (int j = m_increment; j < m_fftsize*2; ++j) {
+            for (int j = m_increment; j < m_winsize*2; ++j) {
                 m_outacc[j - m_increment] = m_outacc[j];
             }
 
-            for (int j = m_fftsize*2 - m_increment; j < m_fftsize*2; ++j) {
+            for (int j = m_winsize*2 - m_increment; j < m_winsize*2; ++j) {
                 m_outacc[j] = 0.f;
             }
 
@@ -265,9 +265,14 @@
 Devuvuzelator::processFrame()
 {
     double *frame = (double *)alloca(m_fftsize * sizeof(double));
-    int ix = m_fftsize/2;
     for (int i = 0; i < m_fftsize; ++i) {
-        frame[ix++] = m_buffer[i] * m_window[i];
+        frame[i] = 0.0;
+    }
+
+    int ix = m_fftsize - m_winsize/2;
+    while (ix < 0) ix += m_fftsize;
+    for (int i = 0; i < m_winsize; ++i) {
+        frame[ix++] += m_buffer[i] * m_window[i];
         if (ix == m_fftsize) ix = 0;
     }
 
@@ -283,9 +288,10 @@
     double *spare = (double *)alloca(m_fftsize * sizeof(double));
     fft(m_fftsize, true, m_real, m_imag, frame, spare);
 
-    ix = m_fftsize/2;
-    for (int i = 0; i < m_fftsize; ++i) {
-        m_outacc[m_fftsize + i] += frame[ix++] * m_window[i];
+    ix = m_fftsize - m_winsize/2;
+    while (ix < 0) ix += m_fftsize;
+    for (int i = 0; i < m_winsize; ++i) {
+        m_outacc[m_winsize + i] += frame[ix++];
         if (ix == m_fftsize) ix = 0;
     }
 }