From e48dc227932d7b1c7b51d558359334e68aa74e39 Mon Sep 17 00:00:00 2001
From: f4exb <f4exb06@gmail.com>
Date: Sat, 10 Aug 2024 06:40:35 +0200
Subject: [PATCH] WDSP: impulse responses refactoring (4)

---
 plugins/channelrx/wdsprx/wdsprxsettings.cpp |  13 +-
 wdsp/RXA.cpp                                |  12 +-
 wdsp/TXA.cpp                                |  55 ++--
 wdsp/bandpass.cpp                           |  49 ++--
 wdsp/bps.cpp                                |  16 +-
 wdsp/bpsnba.cpp                             |   3 +-
 wdsp/delay.cpp                              | 139 +++++-----
 wdsp/delay.hpp                              |  31 ++-
 wdsp/fir.cpp                                |   7 +-
 wdsp/fir.hpp                                |   4 +-
 wdsp/fircore.cpp                            |   6 +-
 wdsp/fircore.hpp                            |   7 +-
 wdsp/firmin.cpp                             | 122 ++++-----
 wdsp/firmin.hpp                             |  40 ++-
 wdsp/firopt.cpp                             |  38 ++-
 wdsp/firopt.hpp                             |   2 +
 wdsp/fmd.cpp                                |  29 +-
 wdsp/fmmod.cpp                              |  43 ++-
 wdsp/nbp.cpp                                |  41 ++-
 wdsp/nbp.hpp                                |   4 +-
 wdsp/resample.cpp                           |   6 +-
 wdsp/resamplef.cpp                          |  45 ++--
 wdsp/rmatch.cpp                             | 175 ++++++------
 wdsp/varsamp.cpp                            | 280 +++++++++-----------
 wdsp/varsamp.hpp                            |  36 +--
 25 files changed, 613 insertions(+), 590 deletions(-)

diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.cpp b/plugins/channelrx/wdsprx/wdsprxsettings.cpp
index 335415faf..d36387d9b 100644
--- a/plugins/channelrx/wdsprx/wdsprxsettings.cpp
+++ b/plugins/channelrx/wdsprx/wdsprxsettings.cpp
@@ -279,6 +279,9 @@ QByteArray WDSPRxSettings::serialize() const
         s.writeDouble(163 + 100*i, m_profiles[i].m_ssqlTauMute);
         s.writeDouble(164 + 100*i, m_profiles[i].m_ssqlTauUnmute);
         s.writeDouble(165 + 100*i, m_profiles[i].m_amsqMaxTail);
+        // RIT
+        s.writeBool(  183 + 100*i, m_profiles[i].m_rit);
+        s.writeDouble(184 + 100*i, m_profiles[i].m_ritFrequency);
         // Equalizer
         s.writeBool(  190 + 100*i, m_profiles[i].m_equalizer);
         s.writeFloat(4100 + 100*i, m_profiles[i].m_eqF[0]);
@@ -403,15 +406,15 @@ bool WDSPRxSettings::deserialize(const QByteArray& data)
         d.readU32(   74, &utmp, 0);
 
         if ((utmp > 1023) && (utmp < 65535)) {
-            m_reverseAPIPort = utmp;
+            m_reverseAPIPort = (uint16_t) utmp;
         } else {
             m_reverseAPIPort = 8888;
         }
 
         d.readU32(   75, &utmp, 0);
-        m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp;
+        m_reverseAPIDeviceIndex = utmp > 99 ? 99 : (uint16_t) utmp;
         d.readU32(   76, &utmp, 0);
-        m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp;
+        m_reverseAPIChannelIndex = utmp > 99 ? 99 : (uint16_t) utmp;
         d.readS32(   77, &m_streamIndex, 0);
 
         if (m_rollupState)
@@ -464,9 +467,9 @@ bool WDSPRxSettings::deserialize(const QByteArray& data)
             // Filter
             d.readS32   (100 + 100*i, &m_profiles[i].m_spanLog2, 3);
             d.readS32   (101 + 100*i, &tmp, 30);
-            m_profiles[i].m_highCutoff = tmp * 100.0;
+            m_profiles[i].m_highCutoff = (float) tmp * 100.0f;
             d.readS32   (102 + 100*i, &tmp, 3);
-            m_profiles[i].m_lowCutoff = tmp * 100.0;
+            m_profiles[i].m_lowCutoff = (float) tmp * 100.0f;
             d.readS32   (103 + 100*i, &m_profiles[i].m_fftWindow, 0);
             // AGC
             d.readBool(  110 + 100*i, &m_profiles[i].m_agc, true);
diff --git a/wdsp/RXA.cpp b/wdsp/RXA.cpp
index c030899db..740653271 100644
--- a/wdsp/RXA.cpp
+++ b/wdsp/RXA.cpp
@@ -1005,8 +1005,7 @@ void RXA::updateNBPFilters()
     if (a->fnfrun)
     {
         a->calc_impulse();
-        a->fircore->setImpulse(a->impulse, 1);
-        delete[] (a->impulse);
+        a->fircore->setImpulse(a->impulse.data(), 1);
     }
     if (b->bpsnba->fnfrun)
     {
@@ -1097,8 +1096,7 @@ void RXA::nbpSetNotchesRun(int _run)
         b->fnfrun = a->master_run;
         bpsnbaCheck(mode, _run);
         b->calc_impulse();                           // recalc nbp impulse response
-        b->fircore->setImpulse(b->impulse, 0);       // calculate new filter masks
-        delete[] (b->impulse);
+        b->fircore->setImpulse(b->impulse.data(), 0);       // calculate new filter masks
         bpsnbaSet();
         b->fircore->setUpdate();                       // apply new filter masks
     }
@@ -1115,8 +1113,7 @@ void RXA::nbpSetWindow(int _wintype)
     {
         a->wintype = _wintype;
         a->calc_impulse();
-        a->fircore->setImpulse(a->impulse, 1);
-        delete[] (a->impulse);
+        a->fircore->setImpulse(a->impulse.data(), 1);
     }
 
     if (b->wintype != _wintype)
@@ -1137,8 +1134,7 @@ void RXA::nbpSetAutoIncrease(int _autoincr)
     {
         a->autoincr = _autoincr;
         a->calc_impulse();
-        a->fircore->setImpulse(a->impulse, 1);
-        delete[] (a->impulse);
+        a->fircore->setImpulse(a->impulse.data(), 1);
     }
 
     if (b->autoincr != _autoincr)
diff --git a/wdsp/TXA.cpp b/wdsp/TXA.cpp
index 8897f043c..fedb213d1 100644
--- a/wdsp/TXA.cpp
+++ b/wdsp/TXA.cpp
@@ -915,7 +915,9 @@ void TXA::setBandpassNC(int _nc)
     if (a->nc != _nc)
     {
         a->nc = _nc;
-        float* impulse = FIR::fir_bandpass (
+        std::vector<float> impulse;
+        FIR::fir_bandpass (
+            impulse,
             a->nc,
             a->f_low,
             a->f_high,
@@ -924,8 +926,7 @@ void TXA::setBandpassNC(int _nc)
             1,
             a->gain / (double)(2 * a->size)
         );
-        a->fircore->setNc(a->nc, impulse);
-        delete[] impulse;
+        a->fircore->setNc(a->nc, impulse.data());
     }
 
     a = bp1;
@@ -933,7 +934,9 @@ void TXA::setBandpassNC(int _nc)
     if (a->nc != _nc)
     {
         a->nc = _nc;
-        float* impulse = FIR::fir_bandpass (
+        std::vector<float> impulse;
+        FIR::fir_bandpass (
+            impulse,
             a->nc,
             a->f_low,
             a->f_high,
@@ -942,8 +945,7 @@ void TXA::setBandpassNC(int _nc)
             1,
             a->gain / (double)(2 * a->size)
         );
-        a->fircore->setNc(a->nc, impulse);
-        delete[] impulse;
+        a->fircore->setNc(a->nc, impulse.data());
     }
 
     a = bp2;
@@ -951,7 +953,9 @@ void TXA::setBandpassNC(int _nc)
     if (a->nc != _nc)
     {
         a->nc = _nc;
-        float* impulse = FIR::fir_bandpass (
+        std::vector<float> impulse;
+        FIR::fir_bandpass (
+            impulse,
             a->nc,
             a->f_low,
             a->f_high,
@@ -960,8 +964,7 @@ void TXA::setBandpassNC(int _nc)
             1,
             a->gain / (double)(2 * a->size)
         );
-        a->fircore->setNc(a->nc, impulse);
-        delete[] impulse;
+        a->fircore->setNc(a->nc, impulse.data());
     }
 }
 
@@ -1032,7 +1035,7 @@ void TXA::SetBPSRun (TXA& txa, int _run)
 
 void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high)
 {
-    float* impulse;
+    std::vector<float> impulse;
     BPS *a;
     a = txa.bps0;
 
@@ -1040,9 +1043,8 @@ void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high)
     {
         a->f_low = _f_low;
         a->f_high = _f_high;
-        impulse = FIR::fir_bandpass(a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
-        FIR::fftcv_mults (a->mults, 2 * a->size, impulse);
-        delete[] (impulse);
+        FIR::fir_bandpass(impulse, a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
+        FIR::fftcv_mults (a->mults, 2 * a->size, impulse.data());
     }
 
     a = txa.bps1;
@@ -1051,9 +1053,8 @@ void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high)
     {
         a->f_low = _f_low;
         a->f_high = _f_high;
-        impulse = FIR::fir_bandpass(a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
-        FIR::fftcv_mults (a->mults, 2 * a->size, impulse);
-        delete[] (impulse);
+        FIR::fir_bandpass(impulse, a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
+        FIR::fftcv_mults (a->mults, 2 * a->size, impulse.data());
     }
 
     a = txa.bps2;
@@ -1062,24 +1063,22 @@ void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high)
     {
         a->f_low = _f_low;
         a->f_high = _f_high;
-        impulse = FIR::fir_bandpass(a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
-        FIR::fftcv_mults (a->mults, 2 * a->size, impulse);
-        delete[] (impulse);
+        FIR::fir_bandpass(impulse, a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
+        FIR::fftcv_mults (a->mults, 2 * a->size, impulse.data());
     }
 }
 
 void TXA::SetBPSWindow (TXA& txa, int _wintype)
 {
-    float* impulse;
+    std::vector<float> impulse;
     BPS *a;
     a = txa.bps0;
 
     if (a->wintype != _wintype)
     {
         a->wintype = _wintype;
-        impulse = FIR::fir_bandpass(a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
-        FIR::fftcv_mults (a->mults, 2 * a->size, impulse);
-        delete[] (impulse);
+        FIR::fir_bandpass(impulse, a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
+        FIR::fftcv_mults (a->mults, 2 * a->size, impulse.data());
     }
 
     a = txa.bps1;
@@ -1087,9 +1086,8 @@ void TXA::SetBPSWindow (TXA& txa, int _wintype)
     if (a->wintype != _wintype)
     {
         a->wintype = _wintype;
-        impulse = FIR::fir_bandpass(a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
-        FIR::fftcv_mults (a->mults, 2 * a->size, impulse);
-        delete[] impulse;
+        FIR::fir_bandpass(impulse, a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
+        FIR::fftcv_mults (a->mults, 2 * a->size, impulse.data());
     }
 
     a = txa.bps2;
@@ -1097,9 +1095,8 @@ void TXA::SetBPSWindow (TXA& txa, int _wintype)
     if (a->wintype != _wintype)
     {
         a->wintype = _wintype;
-        impulse = FIR::fir_bandpass (a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
-        FIR::fftcv_mults (a->mults, 2 * a->size, impulse);
-        delete[] impulse;
+        FIR::fir_bandpass (impulse, a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
+        FIR::fftcv_mults (a->mults, 2 * a->size, impulse.data());
     }
 }
 
diff --git a/wdsp/bandpass.cpp b/wdsp/bandpass.cpp
index 3bdc00ece..b9989cedc 100644
--- a/wdsp/bandpass.cpp
+++ b/wdsp/bandpass.cpp
@@ -66,7 +66,9 @@ BANDPASS::BANDPASS(
     wintype(_wintype),
     gain(_gain)
 {
-    float* impulse = FIR::fir_bandpass (
+    std::vector<float> impulse;
+    FIR::fir_bandpass (
+        impulse,
         nc,
         f_low,
         f_high,
@@ -75,8 +77,7 @@ BANDPASS::BANDPASS(
         1,
         gain / (double)(2 * size)
     );
-    fircore = new FIRCORE(size, in, out, nc, mp, impulse);
-    delete[] impulse;
+    fircore = new FIRCORE(size, in, out, nc, mp, impulse.data());
 }
 
 BANDPASS::~BANDPASS()
@@ -107,7 +108,9 @@ void BANDPASS::setBuffers(float* _in, float* _out)
 void BANDPASS::setSamplerate(int _rate)
 {
     samplerate = _rate;
-    float* impulse = FIR::fir_bandpass (
+    std::vector<float> impulse;
+    FIR::fir_bandpass (
+        impulse,
         nc,
         f_low,
         f_high,
@@ -116,8 +119,7 @@ void BANDPASS::setSamplerate(int _rate)
         1,
         gain / (double) (2 * size)
     );
-    fircore->setImpulse(impulse, 1);
-    delete[] impulse;
+    fircore->setImpulse(impulse.data(), 1);
 }
 
 void BANDPASS::setSize(int _size)
@@ -126,7 +128,9 @@ void BANDPASS::setSize(int _size)
     size = _size;
     fircore->setSize(size);
     // recalc impulse because scale factor is a function of size
-    float* impulse = FIR::fir_bandpass (
+    std::vector<float> impulse;
+    FIR::fir_bandpass (
+        impulse,
         nc,
         f_low,
         f_high,
@@ -135,14 +139,15 @@ void BANDPASS::setSize(int _size)
         1,
         gain / (double) (2 * size)
     );
-    fircore->setImpulse(impulse, 1);
-    delete[] impulse;
+    fircore->setImpulse(impulse.data(), 1);
 }
 
 void BANDPASS::setGain(double _gain, int _update)
 {
     gain = _gain;
-    float* impulse = FIR::fir_bandpass (
+    std::vector<float> impulse;
+    FIR::fir_bandpass (
+        impulse,
         nc,
         f_low,
         f_high,
@@ -151,8 +156,7 @@ void BANDPASS::setGain(double _gain, int _update)
         1,
         gain / (double) (2 * size)
     );
-    fircore->setImpulse(impulse, _update);
-    delete[] impulse;
+    fircore->setImpulse(impulse.data(), _update);
 }
 
 void BANDPASS::calcBandpassFilter(double _f_low, double _f_high, double _gain)
@@ -162,7 +166,9 @@ void BANDPASS::calcBandpassFilter(double _f_low, double _f_high, double _gain)
         f_low = _f_low;
         f_high = _f_high;
         gain = _gain;
-        float* impulse = FIR::fir_bandpass (
+        std::vector<float> impulse;
+        FIR::fir_bandpass (
+            impulse,
             nc,
             f_low,
             f_high,
@@ -171,8 +177,7 @@ void BANDPASS::calcBandpassFilter(double _f_low, double _f_high, double _gain)
             1,
             gain / (double)(2 * size)
         );
-        fircore->setImpulse(impulse, 1);
-        delete[] impulse;
+        fircore->setImpulse(impulse.data(), 1);
     }
 }
 
@@ -186,7 +191,9 @@ void BANDPASS::setBandpassFreqs(double _f_low, double _f_high)
 {
     if ((_f_low != f_low) || (_f_high != f_high))
     {
-        float* impulse = FIR::fir_bandpass (
+        std::vector<float> impulse;
+        FIR::fir_bandpass (
+            impulse,
             nc,
             _f_low,
             _f_high,
@@ -196,8 +203,7 @@ void BANDPASS::setBandpassFreqs(double _f_low, double _f_high)
             gain / (double)(2 * size)
         );
 
-        fircore->setImpulse(impulse, 0);
-        delete[] impulse;
+        fircore->setImpulse(impulse.data(), 0);
         f_low = _f_low;
         f_high = _f_high;
         fircore->setUpdate();
@@ -210,7 +216,9 @@ void BANDPASS::SetBandpassNC(int _nc)
     if (_nc != nc)
     {
         nc = _nc;
-        float* impulse = FIR::fir_bandpass (
+        std::vector<float> impulse;
+        FIR::fir_bandpass (
+            impulse,
             nc,
             f_low,
             f_high,
@@ -219,8 +227,7 @@ void BANDPASS::SetBandpassNC(int _nc)
             1,
             gain / (double)( 2 * size)
         );
-        fircore->setNc(nc, impulse);
-        delete[] impulse;
+        fircore->setNc(nc, impulse.data());
     }
 }
 
diff --git a/wdsp/bps.cpp b/wdsp/bps.cpp
index 03d9ee0f7..94703af48 100644
--- a/wdsp/bps.cpp
+++ b/wdsp/bps.cpp
@@ -42,14 +42,22 @@ namespace WDSP {
 
 void BPS::calc()
 {
-    float* impulse;
     infilt.resize(2 * size * 2);
     product.resize(2 * size * 2);
-    impulse = FIR::fir_bandpass(size + 1, f_low, f_high, samplerate, wintype, 1, 1.0 / (float)(2 * size));
-    FIR::fftcv_mults(mults, 2 * size, impulse);
+    std::vector<float> impulse;
+    FIR::fir_bandpass(
+        impulse,
+        size + 1,
+        f_low,
+        f_high,
+        samplerate,
+        wintype,
+        1,
+        1.0 / (float)(2 * size)
+    );
+    FIR::fftcv_mults(mults, 2 * size, impulse.data());
     CFor = fftwf_plan_dft_1d(2 * size, (fftwf_complex *) infilt.data(), (fftwf_complex *) product.data(), FFTW_FORWARD, FFTW_PATIENT);
     CRev = fftwf_plan_dft_1d(2 * size, (fftwf_complex *) product.data(), (fftwf_complex *) out, FFTW_BACKWARD, FFTW_PATIENT);
-    delete[]impulse;
 }
 
 void BPS::decalc()
diff --git a/wdsp/bpsnba.cpp b/wdsp/bpsnba.cpp
index 6720871ed..5c28307e6 100644
--- a/wdsp/bpsnba.cpp
+++ b/wdsp/bpsnba.cpp
@@ -176,8 +176,7 @@ void BPSNBA::recalc_bpsnba_filter(int update)
     b->gain = gain;
     b->autoincr = autoincr;
     b->calc_impulse();
-    b->fircore->setImpulse(b->impulse, update);
-    delete[] (b->impulse);
+    b->fircore->setImpulse(b->impulse.data(), update);
 }
 
 /********************************************************************************************************
diff --git a/wdsp/delay.cpp b/wdsp/delay.cpp
index 03b68f20d..4e7b4ca33 100644
--- a/wdsp/delay.cpp
+++ b/wdsp/delay.cpp
@@ -31,81 +31,84 @@ warren@wpratt.com
 
 namespace WDSP {
 
-DELAY* create_delay (int run, int size, float* in, float* out, int rate, float tdelta, float tdelay)
+DELAY::DELAY(
+    int _run,
+    int _size,
+    float* _in,
+    float* _out,
+    int _rate,
+    float _tdelta,
+    float _tdelay
+)
 {
-    DELAY *a = new DELAY;
-    a->run = run;
-    a->size = size;
-    a->in = in;
-    a->out = out;
-    a->rate = rate;
-    a->tdelta = tdelta;
-    a->tdelay = tdelay;
-    a->L = (int)(0.5 + 1.0 / (a->tdelta * (float)a->rate));
-    a->adelta = 1.0 / (a->rate * a->L);
-    a->ft = 0.45 / (float)a->L;
-    a->ncoef = (int)(60.0 / a->ft);
-    a->ncoef = (a->ncoef / a->L + 1) * a->L;
-    a->cpp = a->ncoef / a->L;
-    a->phnum = (int)(0.5 + a->tdelay / a->adelta);
-    a->snum = a->phnum / a->L;
-    a->phnum %= a->L;
-    a->idx_in = 0;
-    a->adelay = a->adelta * (a->snum * a->L + a->phnum);
-    a->h = FIR::fir_bandpass (a->ncoef,-a->ft, +a->ft, 1.0, 1, 0, (float)a->L);
-    a->rsize = a->cpp + (WSDEL - 1);
-    a->ring = new float[a->rsize * 2]; // (float *) malloc0 (a->rsize * sizeof (complex));
-    return a;
+    run = _run;
+    size = _size;
+    in = _in;
+    out = _out;
+    rate = _rate;
+    tdelta = _tdelta;
+    tdelay = _tdelay;
+    L = (int)(0.5 + 1.0 / (tdelta * (float)rate));
+    adelta = 1.0f / (float) (rate * L);
+    ft = 0.45f / (float)L;
+    ncoef = (int)(60.0 / ft);
+    ncoef = (ncoef / L + 1) * L;
+    cpp = ncoef / L;
+    phnum = (int)(0.5 + tdelay / adelta);
+    snum = phnum / L;
+    phnum %= L;
+    idx_in = 0;
+    adelay = adelta * (float) (snum * L + phnum);
+    FIR::fir_bandpass (h, ncoef,-ft, +ft, 1.0, 1, 0, (float)L);
+    rsize = cpp + (WSDEL - 1);
+    ring.resize(rsize * 2);
 }
 
-void DELAY::destroy_delay (DELAY *a)
+void DELAY::flush()
 {
-    delete[] (a->ring);
-    delete[] (a->h);
-    delete (a);
+    std::fill(ring.begin(), ring.end(), 0);
+    idx_in = 0;
 }
 
-void DELAY::flush_delay (DELAY *a)
+void DELAY::execute()
 {
-    std::fill(a->ring, a->ring + a->cpp * 2, 0);
-    a->idx_in = 0;
-}
-
-void DELAY::xdelay (DELAY *a)
-{
-    if (a->run)
+    if (run)
     {
-        int i, j, k, idx, n;
-        float Itmp, Qtmp;
+        int j;
+        int k;
+        int idx;
+        int n;
+        float Itmp;
+        float Qtmp;
 
-        for (i = 0; i < a->size; i++)
+        for (int i = 0; i < size; i++)
         {
-            a->ring[2 * a->idx_in + 0] = a->in[2 * i + 0];
-            a->ring[2 * a->idx_in + 1] = a->in[2 * i + 1];
+            ring[2 * idx_in + 0] = in[2 * i + 0];
+            ring[2 * idx_in + 1] = in[2 * i + 1];
             Itmp = 0.0;
             Qtmp = 0.0;
 
-            if ((n = a->idx_in + a->snum) >= a->rsize)
-                n -= a->rsize;
+            if ((n = idx_in + snum) >= rsize)
+                n -= rsize;
 
-            for (j = 0, k = a->L - 1 - a->phnum; j < a->cpp; j++, k+= a->L)
+            for (j = 0, k = L - 1 - phnum; j < cpp; j++, k+= L)
             {
-                if ((idx = n + j) >= a->rsize)
-                    idx -= a->rsize;
+                if ((idx = n + j) >= rsize)
+                    idx -= rsize;
 
-                Itmp += a->ring[2 * idx + 0] * a->h[k];
-                Qtmp += a->ring[2 * idx + 1] * a->h[k];
+                Itmp += ring[2 * idx + 0] * h[k];
+                Qtmp += ring[2 * idx + 1] * h[k];
             }
 
-            a->out[2 * i + 0] = Itmp;
-            a->out[2 * i + 1] = Qtmp;
+            out[2 * i + 0] = Itmp;
+            out[2 * i + 1] = Qtmp;
 
-            if (--a->idx_in < 0)
-                a->idx_in = a->rsize - 1;
+            if (--idx_in < 0)
+                idx_in = rsize - 1;
         }
     }
-    else if (a->out != a->in)
-        std::copy( a->in,  a->in + a->size * 2, a->out);
+    else if (out != in)
+        std::copy( in,  in + size * 2, out);
 }
 
 /********************************************************************************************************
@@ -114,28 +117,28 @@ void DELAY::xdelay (DELAY *a)
 *                                                                                                       *
 ********************************************************************************************************/
 
-void DELAY::SetDelayRun (DELAY *a, int run)
+void DELAY::setRun(int _run)
 {
-    a->run = run;
+    run = _run;
 }
 
-float DELAY::SetDelayValue (DELAY *a, float tdelay)
+float DELAY::setValue(float _tdelay)
 {
-    float adelay;
-    a->tdelay = tdelay;
-    a->phnum = (int)(0.5 + a->tdelay / a->adelta);
-    a->snum = a->phnum / a->L;
-    a->phnum %= a->L;
-    a->adelay = a->adelta * (a->snum * a->L + a->phnum);
-    adelay = a->adelay;
+    float _adelay;
+    tdelay = _tdelay;
+    phnum = (int)(0.5 + tdelay / adelta);
+    snum = phnum / L;
+    phnum %= L;
+    _adelay = adelta * (float) (snum * L + phnum);
+    adelay = _adelay;
     return adelay;
 }
 
-void DELAY::SetDelayBuffs (DELAY *a, int size, float* in, float* out)
+void DELAY::setBuffs(int _size, float* _in, float* _out)
 {
-    a->size = size;
-    a->in = in;
-    a->out = out;
+    size = _size;
+    in = _in;
+    out = _out;
 }
 
 } // namespace WDSP
diff --git a/wdsp/delay.hpp b/wdsp/delay.hpp
index 01706c541..824035f22 100644
--- a/wdsp/delay.hpp
+++ b/wdsp/delay.hpp
@@ -28,6 +28,8 @@ warren@wpratt.com
 #ifndef wdsp_delay_h
 #define wdsp_delay_h
 
+#include <vector>
+
 #include "export.h"
 
 #define WSDEL   1025    // number of supported whole sample delays
@@ -49,25 +51,36 @@ public:
     int ncoef;          // number of coefficients
     int cpp;            // coefficients per phase
     float ft;          // normalized cutoff frequency
-    float* h;          // coefficients
+    std::vector<float> h;          // coefficients
     int snum;           // starting sample number (0 for sub-sample delay)
     int phnum;          // phase number
 
     int idx_in;         // index for input into ring
     int rsize;          // ring size in complex samples
-    float* ring;       // ring buffer
+    std::vector<float> ring;       // ring buffer
 
     float adelta;      // actual delay increment
     float adelay;      // actual delay
 
-    static DELAY* create_delay (int run, int size, float* in, float* out, int rate, float tdelta, float tdelay);
-    static void destroy_delay (DELAY *a);
-    static void flush_delay (DELAY *a);
-    static void xdelay (DELAY *a);
+    DELAY(
+        int run,
+        int size,
+        float* in,
+        float* out,
+        int rate,
+        float tdelta,
+        float tdelay
+    );
+    DELAY(const DELAY&) = delete;
+    DELAY& operator=(DELAY& other) = delete;
+    ~DELAY() = default;
+
+    void flush();
+    void execute();
     // Properties
-    static void SetDelayRun (DELAY *a, int run);
-    static float SetDelayValue (DELAY *a, float delay);        // returns actual delay in seconds
-    static void SetDelayBuffs (DELAY *a, int size, float* in, float* out);
+    void setRun(int run);
+    float setValue(float delay);        // returns actual delay in seconds
+    void setBuffs(int size, float* in, float* out);
 };
 
 } // namespace WDSP
diff --git a/wdsp/fir.cpp b/wdsp/fir.cpp
index 956aac8ba..dd5fe3ce0 100644
--- a/wdsp/fir.cpp
+++ b/wdsp/fir.cpp
@@ -35,7 +35,7 @@ warren@pratt.one
 
 namespace WDSP {
 
-void FIR::fftcv_mults (std::vector<float>& mults, int NM, float* c_impulse)
+void FIR::fftcv_mults (std::vector<float>& mults, int NM, const float* c_impulse)
 {
     mults.resize(NM * 2);
     std::vector<float> cfft_impulse(NM * 2);
@@ -199,9 +199,9 @@ void FIR::fir_fsamp (std::vector<float>& c_impulse, int N, const float* A, int r
     }
 }
 
-float* FIR::fir_bandpass (int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale)
+void FIR::fir_bandpass (std::vector<float>& c_impulse, int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale)
 {
-    auto *c_impulse = new float[N * 2];
+    c_impulse.resize(N * 2);
     double ft = (f_high - f_low) / (2.0 * samplerate);
     double ft_rad = TWOPI * ft;
     double w_osc = PI * (f_high + f_low) / samplerate;
@@ -273,7 +273,6 @@ float* FIR::fir_bandpass (int N, double f_low, double f_high, double samplerate,
             break;
         }
     }
-    return c_impulse;
 }
 
 void FIR::fir_read (std::vector<float>& c_impulse, int N, const char *filename, int rtype, float scale)
diff --git a/wdsp/fir.hpp b/wdsp/fir.hpp
index 39e3b63e6..99a073f71 100644
--- a/wdsp/fir.hpp
+++ b/wdsp/fir.hpp
@@ -36,10 +36,10 @@ namespace WDSP {
 class WDSP_API FIR
 {
 public:
-    static void fftcv_mults (std::vector<float>& mults, int NM, float* c_impulse);
+    static void fftcv_mults (std::vector<float>& mults, int NM, const float* impulse);
     static void fir_fsamp_odd (std::vector<float>& c_impulse, int N, const float* A, int rtype, double scale, int wintype);
     static void fir_fsamp (std::vector<float>& c_impulse, int N, const float* A, int rtype, double scale, int wintype);
-    static float* fir_bandpass (int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale);
+    static void fir_bandpass (std::vector<float>& impulse, int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale);
     static void mp_imp (int N, std::vector<float>& fir, std::vector<float>& mpfir, int pfactor, int polarity);
 
 private:
diff --git a/wdsp/fircore.cpp b/wdsp/fircore.cpp
index 5bcf996f5..6c4be6a6e 100644
--- a/wdsp/fircore.cpp
+++ b/wdsp/fircore.cpp
@@ -124,7 +124,7 @@ FIRCORE::FIRCORE(
     float* _out,
     int _nc,
     int _mp,
-    float* _impulse
+    const float* _impulse
 )
 {
     size = _size;
@@ -204,13 +204,13 @@ void FIRCORE::setSize(int _size)
     calc(1);
 }
 
-void FIRCORE::setImpulse(float* _impulse, int _update)
+void FIRCORE::setImpulse(const float* _impulse, int _update)
 {
     std::copy(_impulse, _impulse + nc * 2, impulse.begin());
     calc(_update);
 }
 
-void FIRCORE::setNc(int _nc, float* _impulse)
+void FIRCORE::setNc(int _nc, const float* _impulse)
 {
     // because of FFT planning, this will probably cause a glitch in audio if done during dataflow
     deplan();
diff --git a/wdsp/fircore.hpp b/wdsp/fircore.hpp
index 66e2d4832..3fd309a4c 100644
--- a/wdsp/fircore.hpp
+++ b/wdsp/fircore.hpp
@@ -72,8 +72,7 @@ public:
         float* out,
         int nc,
         int mp,
-        float*
-        impulse
+        const float* impulse
     );
     FIRCORE(const FIRCORE&) = delete;
     FIRCORE& operator=(const FIRCORE& other) = delete;
@@ -83,8 +82,8 @@ public:
     void execute();
     void setBuffers(float* in, float* out);
     void setSize(int size);
-    void setImpulse(float* impulse, int update);
-    void setNc(int nc, float* impulse);
+    void setImpulse(const float* impulse, int update);
+    void setNc(int nc, const float* impulse);
     void setMp(int mp);
     void setUpdate();
 
diff --git a/wdsp/firmin.cpp b/wdsp/firmin.cpp
index d3e289bc4..ced48f683 100644
--- a/wdsp/firmin.cpp
+++ b/wdsp/firmin.cpp
@@ -37,94 +37,96 @@ namespace WDSP {
 *                                                                                                       *
 ********************************************************************************************************/
 
-void FIRMIN::calc_firmin (FIRMIN *a)
+void FIRMIN::calc()
 {
-    a->h = FIR::fir_bandpass (a->nc, a->f_low, a->f_high, a->samplerate, a->wintype, 1, a->gain);
-    a->rsize = a->nc;
-    a->mask = a->rsize - 1;
-    a->ring = new float[a->rsize * 2]; // (float *) malloc0 (a->rsize * sizeof (complex));
-    a->idx = 0;
+    FIR::fir_bandpass (h, nc, f_low, f_high, samplerate, wintype, 1, gain);
+    rsize = nc;
+    mask = rsize - 1;
+    ring.resize(rsize * 2);
+    idx = 0;
 }
 
-FIRMIN* FIRMIN::create_firmin (int run, int position, int size, float* in, float* out,
-    int nc, float f_low, float f_high, int samplerate, int wintype, float gain)
+FIRMIN::FIRMIN(
+    int _run,
+    int _position,
+    int _size,
+    float* _in,
+    float* _out,
+    int _nc,
+    float _f_low,
+    float _f_high,
+    int _samplerate,
+    int _wintype,
+    float _gain
+)
 {
-    FIRMIN *a = new FIRMIN;
-    a->run = run;
-    a->position = position;
-    a->size = size;
-    a->in = in;
-    a->out = out;
-    a->nc = nc;
-    a->f_low = f_low;
-    a->f_high = f_high;
-    a->samplerate = samplerate;
-    a->wintype = wintype;
-    a->gain = gain;
-    calc_firmin (a);
-    return a;
+    run = _run;
+    position = _position;
+    size = _size;
+    in = _in;
+    out = _out;
+    nc = _nc;
+    f_low = _f_low;
+    f_high = _f_high;
+    samplerate = (float) _samplerate;
+    wintype = _wintype;
+    gain = _gain;
+    calc();
 }
 
-void FIRMIN::destroy_firmin (FIRMIN *a)
+void FIRMIN::flush()
 {
-    delete[] (a->ring);
-    delete[] (a->h);
-    delete (a);
+    std::fill(ring.begin(), ring.end(), 0);
+    idx = 0;
 }
 
-void FIRMIN::flush_firmin (FIRMIN *a)
+void FIRMIN::execute(int _pos)
 {
-    std::fill(a->ring, a->ring + a->rsize * 2, 0);
-    a->idx = 0;
-}
-
-void FIRMIN::xfirmin (FIRMIN *a, int pos)
-{
-    if (a->run && a->position == pos)
+    if (run && position == _pos)
     {
-        int i, j, k;
-        for (i = 0; i < a->size; i++)
+        int k;
+        for (int i = 0; i < size; i++)
         {
-            a->ring[2 * a->idx + 0] = a->in[2 * i + 0];
-            a->ring[2 * a->idx + 1] = a->in[2 * i + 1];
-            a->out[2 * i + 0] = 0.0;
-            a->out[2 * i + 1] = 0.0;
-            k = a->idx;
-            for (j = 0; j < a->nc; j++)
+            ring[2 * idx + 0] = in[2 * i + 0];
+            ring[2 * idx + 1] = in[2 * i + 1];
+            out[2 * i + 0] = 0.0;
+            out[2 * i + 1] = 0.0;
+            k = idx;
+            for (int j = 0; j < nc; j++)
             {
-                a->out[2 * i + 0] += a->h[2 * j + 0] * a->ring[2 * k + 0] - a->h[2 * j + 1] * a->ring[2 * k + 1];
-                a->out[2 * i + 1] += a->h[2 * j + 0] * a->ring[2 * k + 1] + a->h[2 * j + 1] * a->ring[2 * k + 0];
-                k = (k + a->mask) & a->mask;
+                out[2 * i + 0] += h[2 * j + 0] * ring[2 * k + 0] - h[2 * j + 1] * ring[2 * k + 1];
+                out[2 * i + 1] += h[2 * j + 0] * ring[2 * k + 1] + h[2 * j + 1] * ring[2 * k + 0];
+                k = (k + mask) & mask;
             }
-            a->idx = (a->idx + 1) & a->mask;
+            idx = (idx + 1) & mask;
         }
     }
-    else if (a->in != a->out)
-        std::copy( a->in,  a->in + a->size * 2, a->out);
+    else if (in != out)
+        std::copy( in,  in + size * 2, out);
 }
 
-void FIRMIN::setBuffers_firmin (FIRMIN *a, float* in, float* out)
+void FIRMIN::setBuffers(float* _in, float* _out)
 {
-    a->in = in;
-    a->out = out;
+    in = _in;
+    out = _out;
 }
 
-void FIRMIN::setSamplerate_firmin (FIRMIN *a, int rate)
+void FIRMIN::setSamplerate(int _rate)
 {
-    a->samplerate = (float)rate;
-    calc_firmin (a);
+    samplerate = (float) _rate;
+    calc();
 }
 
-void FIRMIN::setSize_firmin (FIRMIN *a, int size)
+void FIRMIN::setSize(int _size)
 {
-    a->size = size;
+    size = _size;
 }
 
-void FIRMIN::setFreqs_firmin (FIRMIN *a, float f_low, float f_high)
+void FIRMIN::setFreqs(float _f_low, float _f_high)
 {
-    a->f_low = f_low;
-    a->f_high = f_high;
-    calc_firmin (a);
+    f_low = _f_low;
+    f_high = _f_high;
+    calc();
 }
 
 } // namespace WDSP
diff --git a/wdsp/firmin.hpp b/wdsp/firmin.hpp
index 0e0e1b21b..1ef55153f 100644
--- a/wdsp/firmin.hpp
+++ b/wdsp/firmin.hpp
@@ -34,6 +34,8 @@ warren@wpratt.com
 #ifndef wdsp_firmin_h
 #define wdsp_firmin_h
 
+#include <vector>
+
 #include "fftw3.h"
 #include "export.h"
 
@@ -50,8 +52,8 @@ public:
     int nc;                 // number of filter coefficients, power of two
     float f_low;           // low cutoff frequency
     float f_high;          // high cutoff frequency
-    float* ring;           // internal complex ring buffer
-    float* h;              // complex filter coefficients
+    std::vector<float> ring;           // internal complex ring buffer
+    std::vector<float> h;              // complex filter coefficients
     int rsize;              // ring size, number of complex samples, power of two
     int mask;               // mask to update indexes
     int idx;                // ring input/output index
@@ -59,18 +61,32 @@ public:
     int wintype;            // filter window type
     float gain;            // filter gain
 
-    static FIRMIN* create_firmin (int run, int position, int size, float* in, float* out,
-        int nc, float f_low, float f_high, int samplerate, int wintype, float gain);
-    static void destroy_firmin (FIRMIN *a);
-    static void flush_firmin (FIRMIN *a);
-    static void xfirmin (FIRMIN *a, int pos);
-    static void setBuffers_firmin (FIRMIN *a, float* in, float* out);
-    static void setSamplerate_firmin (FIRMIN *a, int rate);
-    static void setSize_firmin (FIRMIN *a, int size);
-    static void setFreqs_firmin (FIRMIN *a, float f_low, float f_high);
+    FIRMIN(
+        int run,
+        int position,
+        int size,
+        float* in,
+        float* out,
+        int nc,
+        float f_low,
+        float f_high,
+        int samplerate,
+        int wintype,
+        float gain
+    );
+    FIRMIN(const FIRMIN&) = delete;
+    FIRMIN& operator=(const FIRMIN& other) = delete;
+    ~FIRMIN() = default;
+
+    void flush();
+    void execute(int pos);
+    void setBuffers(float* in, float* out);
+    void setSamplerate(int rate);
+    void setSize(int size);
+    void setFreqs(float f_low, float f_high);
 
 private:
-    static void calc_firmin (FIRMIN *a);
+    void calc();
 };
 
 } // namespace WDSP
diff --git a/wdsp/firopt.cpp b/wdsp/firopt.cpp
index e466bf109..3d43d0037 100644
--- a/wdsp/firopt.cpp
+++ b/wdsp/firopt.cpp
@@ -44,16 +44,16 @@ void FIROPT::plan_firopt (FIROPT *a)
     a->nfor = a->nc / a->size;
     a->buffidx = 0;
     a->idxmask = a->nfor - 1;
-    a->fftin = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
-    a->fftout = new float*[a->nfor]; //  (float **) malloc0 (a->nfor * sizeof (float *));
-    a->fmask = new float*[a->nfor]; //  (float **) malloc0 (a->nfor * sizeof (float *));
-    a->maskgen = new float[2 * a->size * 2]; //  (float *) malloc0 (2 * a->size * sizeof (complex));
-    a->pcfor = new fftwf_plan[a->nfor]; // (fftwf_plan *) malloc0 (a->nfor * sizeof (fftwf_plan));
-    a->maskplan = new fftwf_plan[a->nfor]; // (fftwf_plan *) malloc0 (a->nfor * sizeof (fftwf_plan));
+    a->fftin = new float[2 * a->size * 2];
+    a->fftout = new float*[a->nfor];
+    a->fmask = new float*[a->nfor];
+    a->maskgen = new float[2 * a->size * 2];
+    a->pcfor = new fftwf_plan[a->nfor];
+    a->maskplan = new fftwf_plan[a->nfor];
     for (i = 0; i < a->nfor; i++)
     {
-        a->fftout[i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
-        a->fmask[i] = new float[2 * a->size * 2]; //  (float *) malloc0 (2 * a->size * sizeof (complex));
+        a->fftout[i] = new float[2 * a->size * 2];
+        a->fmask[i] = new float[2 * a->size * 2];
         a->pcfor[i] = fftwf_plan_dft_1d(
             2 * a->size,
             (fftwf_complex *)a->fftin,
@@ -69,7 +69,7 @@ void FIROPT::plan_firopt (FIROPT *a)
             FFTW_PATIENT
         );
     }
-    a->accum = new float[2 * a->size * 2]; //  (float *) malloc0 (2 * a->size * sizeof (complex));
+    a->accum = new float[2 * a->size * 2];
     a->crev = fftwf_plan_dft_1d(
         2 * a->size,
         (fftwf_complex *)a->accum,
@@ -83,17 +83,16 @@ void FIROPT::calc_firopt (FIROPT *a)
 {
     // call for change in frequency, rate, wintype, gain
     // must also call after a call to plan_firopt()
-    int i;
-    float* impulse = FIR::fir_bandpass (a->nc, a->f_low, a->f_high, a->samplerate, a->wintype, 1, a->gain);
+    std::vector<float> impulse;
+    FIR::fir_bandpass (impulse, a->nc, a->f_low, a->f_high, a->samplerate, a->wintype, 1, a->gain);
     a->buffidx = 0;
-    for (i = 0; i < a->nfor; i++)
+    for (int i = 0; i < a->nfor; i++)
     {
         // I right-justified the impulse response => take output from left side of output buff, discard right side
         // Be careful about flipping an asymmetrical impulse response.
         std::copy(&(impulse[2 * a->size * i]), &(impulse[2 * a->size * i]) + a->size * 2, &(a->maskgen[2 * a->size]));
         fftwf_execute (a->maskplan[i]);
     }
-    delete[] (impulse);
 }
 
 FIROPT* FIROPT::create_firopt (int run, int position, int size, float* in, float* out,
@@ -108,7 +107,7 @@ FIROPT* FIROPT::create_firopt (int run, int position, int size, float* in, float
     a->nc = nc;
     a->f_low = f_low;
     a->f_high = f_high;
-    a->samplerate = samplerate;
+    a->samplerate = (float) samplerate;
     a->wintype = wintype;
     a->gain = gain;
     plan_firopt (a);
@@ -144,9 +143,8 @@ void FIROPT::destroy_firopt (FIROPT *a)
 
 void FIROPT::flush_firopt (FIROPT *a)
 {
-    int i;
     std::fill(a->fftin, a->fftin + 2 * a->size * 2, 0);
-    for (i = 0; i < a->nfor; i++)
+    for (int i = 0; i < a->nfor; i++)
         std::fill(a->fftout[i], a->fftout[i] + 2 * a->size * 2, 0);
     a->buffidx = 0;
 }
@@ -155,14 +153,14 @@ void FIROPT::xfiropt (FIROPT *a, int pos)
 {
     if (a->run && (a->position == pos))
     {
-        int i, j, k;
+        int k;
         std::copy(a->in, a->in + a->size * 2, &(a->fftin[2 * a->size]));
         fftwf_execute (a->pcfor[a->buffidx]);
         k = a->buffidx;
         std::fill(a->accum, a->accum + 2 * a->size * 2, 0);
-        for (j = 0; j < a->nfor; j++)
+        for (int j = 0; j < a->nfor; j++)
         {
-            for (i = 0; i < 2 * a->size; i++)
+            for (int i = 0; i < 2 * a->size; i++)
             {
                 a->accum[2 * i + 0] += a->fftout[k][2 * i + 0] * a->fmask[j][2 * i + 0] - a->fftout[k][2 * i + 1] * a->fmask[j][2 * i + 1];
                 a->accum[2 * i + 1] += a->fftout[k][2 * i + 0] * a->fmask[j][2 * i + 1] + a->fftout[k][2 * i + 1] * a->fmask[j][2 * i + 0];
@@ -188,7 +186,7 @@ void FIROPT::setBuffers_firopt (FIROPT *a, float* in, float* out)
 
 void FIROPT::setSamplerate_firopt (FIROPT *a, int rate)
 {
-    a->samplerate = rate;
+    a->samplerate = (float) rate;
     calc_firopt (a);
 }
 
diff --git a/wdsp/firopt.hpp b/wdsp/firopt.hpp
index 05ea82cfe..343de76c9 100644
--- a/wdsp/firopt.hpp
+++ b/wdsp/firopt.hpp
@@ -34,6 +34,8 @@ warren@wpratt.com
 #ifndef wdsp_firopt_h
 #define wdsp_firopt_h
 
+#include <vector>
+
 #include "fftw3.h"
 #include "export.h"
 
diff --git a/wdsp/fmd.cpp b/wdsp/fmd.cpp
index 8315497fe..144bbb8bc 100644
--- a/wdsp/fmd.cpp
+++ b/wdsp/fmd.cpp
@@ -161,8 +161,9 @@ FMD::FMD(
     );
     pde = new FIRCORE(size, audio.data(), out, nc_de, mp_de, impulse.data());
     // audio filter
-    float *impulseb = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
-    paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulseb);
+    std::vector<float> impulseb;
+    FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
+    paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulseb.data());
 }
 
 FMD::~FMD()
@@ -267,9 +268,9 @@ void FMD::setSamplerate(int _rate)
     );
     pde->setImpulse(impulse.data(), 1);
     // audio filter
-    float* impulseb = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
-    paud->setImpulse(impulseb, 1);
-    delete[] impulseb;
+    std::vector<float> impulseb;
+    FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
+    paud->setImpulse(impulseb.data(), 1);
     plim->setSamplerate((int) rate);
 }
 
@@ -298,9 +299,9 @@ void FMD::setSize(int _size)
     pde = new FIRCORE(size, audio.data(), out, nc_de, mp_de, impulse.data());
     // audio filter
     delete (paud);
-    float* impulseb = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
-    paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulseb);
-    delete[] impulseb;
+    std::vector<float> impulseb;
+    FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
+    paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulseb.data());
     plim->setSize(size);
 }
 
@@ -367,9 +368,9 @@ void FMD::setNCaud(int nc)
     if (nc_aud != nc)
     {
         nc_aud = nc;
-        impulse = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
-        paud->setNc(nc_aud, impulse);
-        delete[] impulse;
+        std::vector<float> impulse;
+        FIR::fir_bandpass(impulse, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
+        paud->setNc(nc_aud, impulse.data());
     }
 }
 
@@ -424,9 +425,9 @@ void FMD::setAFFilter(double low, double high)
         );
         pde->setImpulse(impulse.data(), 1);
         // audio filter
-        float* impulseb = FIR::fir_bandpass (nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
-        paud->setImpulse(impulseb, 1);
-        delete[] impulseb;
+        std::vector<float> impulseb;
+        FIR::fir_bandpass (impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
+        paud->setImpulse(impulseb.data(), 1);
     }
 }
 
diff --git a/wdsp/fmmod.cpp b/wdsp/fmmod.cpp
index ee000b4db..fdbc206c1 100644
--- a/wdsp/fmmod.cpp
+++ b/wdsp/fmmod.cpp
@@ -25,6 +25,8 @@ warren@wpratt.com
 
 */
 
+#include <vector>
+
 #include "comm.hpp"
 #include "fircore.hpp"
 #include "fir.hpp"
@@ -63,7 +65,7 @@ FMMOD::FMMOD(
     int _mp
 )
 {
-    float* impulse;
+    std::vector<float> impulse;
     run = _run;
     size = _size;
     in = _in;
@@ -79,9 +81,8 @@ FMMOD::FMMOD(
     nc = _nc;
     mp = _mp;
     calc();
-    impulse = FIR::fir_bandpass(nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
-    p = new FIRCORE(size, out, out, nc, mp, impulse);
-    delete[] impulse;
+    FIR::fir_bandpass(impulse, nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
+    p = new FIRCORE(size, out, out, nc, mp, impulse.data());
 }
 
 FMMOD::~FMMOD()
@@ -138,23 +139,21 @@ void FMMOD::setBuffers(float* _in, float* _out)
 
 void FMMOD::setSamplerate(int _rate)
 {
-    float* impulse;
+    std::vector<float> impulse;
     samplerate = _rate;
     calc();
-    impulse = FIR::fir_bandpass(nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
-    p->setImpulse(impulse, 1);
-    delete[] impulse;
+    FIR::fir_bandpass(impulse, nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
+    p->setImpulse(impulse.data(), 1);
 }
 
 void FMMOD::setSize(int _size)
 {
-    float* impulse;
+    std::vector<float> impulse;
     size = _size;
     calc();
     p->setSize(size);
-    impulse = FIR::fir_bandpass(nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
-    p->setImpulse(impulse, 1);
-    delete[] impulse;
+    FIR::fir_bandpass(impulse, nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
+    p->setImpulse(impulse.data(), 1);
 }
 
 /********************************************************************************************************
@@ -166,9 +165,9 @@ void FMMOD::setSize(int _size)
 void FMMOD::setDeviation(float _deviation)
 {
     double _bp_fc = f_high + _deviation;
-    float* impulse = FIR::fir_bandpass (nc, -_bp_fc, +_bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
-    p->setImpulse(impulse, 0);
-    delete[] impulse;
+    std::vector<float> impulse;
+    FIR::fir_bandpass (impulse, nc, -_bp_fc, +_bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
+    p->setImpulse(impulse.data(), 0);
     deviation = _deviation;
     // mod
     sphase = 0.0;
@@ -192,14 +191,13 @@ void FMMOD::setCTCSSRun (int _run)
 
 void FMMOD::setNC(int _nc)
 {
-    float* impulse;
+    std::vector<float> impulse;
 
     if (nc != _nc)
     {
         nc = _nc;
-        impulse = FIR::fir_bandpass (nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
-        p->setNc(nc, impulse);
-        delete[] impulse;
+        FIR::fir_bandpass (impulse, nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
+        p->setNc(nc, impulse.data());
     }
 }
 
@@ -214,16 +212,15 @@ void FMMOD::setMP(int _mp)
 
 void FMMOD::setAFFreqs(float _low, float _high)
 {
-    float* impulse;
+    std::vector<float> impulse;
 
     if (f_low != _low || f_high != _high)
     {
         f_low = _low;
         f_high = _high;
         bp_fc = deviation + f_high;
-        impulse = FIR::fir_bandpass (nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
-        p->setImpulse(impulse, 1);
-        delete[] impulse;
+        FIR::fir_bandpass (impulse, nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
+        p->setImpulse(impulse.data(), 1);
     }
 }
 
diff --git a/wdsp/nbp.cpp b/wdsp/nbp.cpp
index 29c2befc7..b3c27e405 100644
--- a/wdsp/nbp.cpp
+++ b/wdsp/nbp.cpp
@@ -158,21 +158,20 @@ void NOTCHDB::getNumNotches(int* _nnotches) const
 *                                                                                                       *
 ********************************************************************************************************/
 
-float* NBP::fir_mbandpass (int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype)
+void NBP::fir_mbandpass (std::vector<float>& impulse, int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype)
 {
-    auto* impulse = new float[N * 2];
-    std::fill(impulse, impulse + N*2, 0);
+    impulse.resize(N * 2);
+    std::fill(impulse.begin(), impulse.end(), 0);
     for (int k = 0; k < nbp; k++)
     {
-        float* imp = FIR::fir_bandpass (N, flow[k], fhigh[k], rate, wintype, 1, scale);
+        std::vector<float> imp;
+        FIR::fir_bandpass (imp, N, flow[k], fhigh[k], rate, wintype, 1, scale);
         for (int i = 0; i < N; i++)
         {
             impulse[2 * i + 0] += imp[2 * i + 0];
             impulse[2 * i + 1] += imp[2 * i + 1];
         }
-        delete[] imp;
     }
-    return impulse;
 }
 
 double NBP::min_notch_width() const
@@ -324,7 +323,8 @@ void NBP::calc_lightweight()
                 bplow[i]  -= offset;
                 bphigh[i] -= offset;
             }
-            impulse = fir_mbandpass (
+            fir_mbandpass (
+                impulse,
                 nc,
                 numpb,
                 bplow.data(),
@@ -333,9 +333,8 @@ void NBP::calc_lightweight()
                 gain / (float)(2 * size),
                 wintype
             );
-            fircore->setImpulse(impulse, 1);
+            fircore->setImpulse(impulse.data(), 1);
             // print_impulse ("nbp.txt", size + 1, impulse, 1, 0);
-            delete[] impulse;
         }
         hadnotch = havnotch;
     }
@@ -375,7 +374,8 @@ void NBP::calc_impulse ()
             bplow[i]  -= offset;
             bphigh[i] -= offset;
         }
-        impulse = fir_mbandpass (
+        fir_mbandpass (
+            impulse,
             nc,
             numpb,
             bplow.data(),
@@ -387,7 +387,8 @@ void NBP::calc_impulse ()
     }
     else
     {
-        impulse = FIR::fir_bandpass(
+        FIR::fir_bandpass(
+            impulse,
             nc,
             flow,
             fhigh,
@@ -437,14 +438,12 @@ NBP::NBP(
     bplow.resize(maxpb);
     bphigh.resize(maxpb);
     calc_impulse ();
-    fircore = new FIRCORE(size, in, out, nc, mp, impulse);
-    // print_impulse ("nbp.txt", size + 1, impulse, 1, 0);
-    delete[]impulse;
+    fircore = new FIRCORE(size, in, out, nc, mp, impulse.data());
 }
 
 NBP::~NBP()
 {
-    delete (fircore);
+    delete fircore;
 }
 
 void NBP::flush()
@@ -471,8 +470,7 @@ void NBP::setSamplerate(int _rate)
 {
     rate = _rate;
     calc_impulse ();
-    fircore->setImpulse(impulse, 1);
-    delete[] impulse;
+    fircore->setImpulse(impulse.data(), 1);
 }
 
 void NBP::setSize(int _size)
@@ -481,15 +479,13 @@ void NBP::setSize(int _size)
     size = _size;
     fircore->setSize(size);
     calc_impulse ();
-    fircore->setImpulse(impulse, 1);
-    delete[] impulse;
+    fircore->setImpulse(impulse.data(), 1);
 }
 
 void NBP::setNc()
 {
     calc_impulse();
-    fircore->setNc(nc, impulse);
-    delete[] impulse;
+    fircore->setNc(nc, impulse.data());
 }
 
 void NBP::setMp()
@@ -517,8 +513,7 @@ void NBP::SetFreqs(double _flow, double _fhigh)
         flow = _flow;
         fhigh = _fhigh;
         calc_impulse();
-        fircore->setImpulse(impulse, 1);
-        delete[] impulse;
+        fircore->setImpulse(impulse.data(), 1);
     }
 }
 
diff --git a/wdsp/nbp.hpp b/wdsp/nbp.hpp
index c56f71225..1b081e5b5 100644
--- a/wdsp/nbp.hpp
+++ b/wdsp/nbp.hpp
@@ -80,7 +80,7 @@ public:
     int autoincr;           // auto-increment notch width
     double flow;            // low bandpass cutoff freq
     double fhigh;           // high bandpass cutoff freq
-    float* impulse;         // filter impulse response
+    std::vector<float> impulse; // filter impulse response
     int maxpb;              // maximum number of passbands
     NOTCHDB* notchdb;       // ptr to addr of notch-database data structure
     std::vector<double> bplow;  // array of passband lows
@@ -129,7 +129,7 @@ public:
     void calc_lightweight();
 
 private:
-    static float* fir_mbandpass (int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype);
+    static void fir_mbandpass (std::vector<float>& impulse, int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype);
     double min_notch_width () const;
     static int make_nbp (
         int nn,
diff --git a/wdsp/resample.cpp b/wdsp/resample.cpp
index 19d16e3b3..826fe45a9 100644
--- a/wdsp/resample.cpp
+++ b/wdsp/resample.cpp
@@ -47,7 +47,7 @@ void RESAMPLE::calc()
     double full_rate;
     double fc_norm_high;
     double fc_norm_low;
-    float* impulse;
+    std::vector<float> impulse;
     fc = fcin;
     ncoef = ncoefin;
     x = in_rate;
@@ -88,7 +88,7 @@ void RESAMPLE::calc()
     ncoef = (ncoef / L + 1) * L;
     cpp = ncoef / L;
     h.resize(ncoef);
-    impulse = FIR::fir_bandpass(ncoef, fc_norm_low, fc_norm_high, 1.0, 1, 0, gain * (double)L);
+    FIR::fir_bandpass(impulse, ncoef, fc_norm_low, fc_norm_high, 1.0, 1, 0, gain * (double)L);
     i = 0;
 
     for (int j = 0; j < L; j++)
@@ -101,8 +101,6 @@ void RESAMPLE::calc()
     ring.resize(ringsize);
     idx_in = ringsize - 1;
     phnum = 0;
-
-    delete[] impulse;
 }
 
 RESAMPLE::RESAMPLE (
diff --git a/wdsp/resamplef.cpp b/wdsp/resamplef.cpp
index a79330f23..6f8e4fbba 100644
--- a/wdsp/resamplef.cpp
+++ b/wdsp/resamplef.cpp
@@ -25,6 +25,8 @@ warren@wpratt.com
 
 */
 
+#include <vector>
+
 #include "comm.hpp"
 #include "fir.hpp"
 #include "resamplef.hpp"
@@ -39,14 +41,16 @@ namespace WDSP {
 
 RESAMPLEF* RESAMPLEF::create_resampleF ( int run, int size, float* in, float* out, int in_rate, int out_rate)
 {
-    RESAMPLEF *a = new RESAMPLEF;
-    int x, y, z;
-    int i, j, k;
+    auto *a = new RESAMPLEF;
+    int x;
+    int y;
+    int z;
+    int i;
     int min_rate;
     float full_rate;
     float fc;
     float fc_norm;
-    float* impulse;
+    std::vector<float> impulse;
     a->run = run;
     a->size = size;
     a->in = in;
@@ -72,36 +76,35 @@ RESAMPLEF* RESAMPLEF::create_resampleF ( int run, int size, float* in, float* ou
     else
         min_rate = out_rate;
 
-    fc = 0.45 * (float)min_rate;
+    fc = 0.45f * (float)min_rate;
     full_rate = (float)(in_rate * a->L);
     fc_norm = fc / full_rate;
     a->ncoef = (int)(60.0 / fc_norm);
     a->ncoef = (a->ncoef / a->L + 1) * a->L;
     a->cpp = a->ncoef / a->L;
-    a->h = new float[a->ncoef]; // (float *) malloc0 (a->ncoef * sizeof (float));
-    impulse = FIR::fir_bandpass (a->ncoef, -fc_norm, +fc_norm, 1.0, 1, 0, (float)a->L);
+    a->h = new float[a->ncoef];
+    FIR::fir_bandpass (impulse, a->ncoef, -fc_norm, +fc_norm, 1.0, 1, 0, (float)a->L);
     i = 0;
 
-    for (j = 0; j < a->L; j ++)
+    for (int j = 0; j < a->L; j ++)
     {
-        for (k = 0; k < a->ncoef; k += a->L)
+        for (int k = 0; k < a->ncoef; k += a->L)
             a->h[i++] = impulse[j + k];
     }
 
     a->ringsize = a->cpp;
-    a->ring = new float[a->ringsize]; //(float *) malloc0 (a->ringsize * sizeof (float));
+    a->ring = new float[a->ringsize];
     a->idx_in = a->ringsize - 1;
     a->phnum = 0;
 
-    delete[] (impulse);
     return a;
 }
 
 void RESAMPLEF::destroy_resampleF (RESAMPLEF *a)
 {
-    delete[] (a->ring);
-    delete[] (a->h);
-    delete (a);
+    delete[] a->ring;
+    delete[] a->h;
+    delete a;
 }
 
 void RESAMPLEF::flush_resampleF (RESAMPLEF *a)
@@ -117,20 +120,20 @@ int RESAMPLEF::xresampleF (RESAMPLEF *a)
 
     if (a->run)
     {
-        int i, j, n;
+        int n;
         int idx_out;
         float I;
 
-        for (i = 0; i < a->size; i++)
+        for (int i = 0; i < a->size; i++)
         {
-            a->ring[a->idx_in] = (float)a->in[i];
+            a->ring[a->idx_in] = a->in[i];
 
             while (a->phnum < a->L)
             {
                 I = 0.0;
                 n = a->cpp * a->phnum;
 
-                for (j = 0; j < a->cpp; j++)
+                for (int j = 0; j < a->cpp; j++)
                 {
                     if ((idx_out = a->idx_in + j) >= a->ringsize)
                         idx_out -= a->ringsize;
@@ -138,7 +141,7 @@ int RESAMPLEF::xresampleF (RESAMPLEF *a)
                     I += a->h[n + j] * a->ring[idx_out];
                 }
 
-                a->out[outsamps] = (float)I;
+                a->out[outsamps] = I;
 
                 outsamps++;
                 a->phnum += a->M;
@@ -163,13 +166,13 @@ int RESAMPLEF::xresampleF (RESAMPLEF *a)
 
 void* RESAMPLEF::create_resampleFV (int in_rate, int out_rate)
 {
-    return (void *) create_resampleF (1, 0, 0, 0, in_rate, out_rate);
+    return (void *) create_resampleF (1, 0, nullptr, nullptr, in_rate, out_rate);
 }
 
 
 void RESAMPLEF::xresampleFV (float* input, float* output, int numsamps, int* outsamps, void* ptr)
 {
-    RESAMPLEF *a = (RESAMPLEF*) ptr;
+    auto *a = (RESAMPLEF*) ptr;
     a->in = input;
     a->out = output;
     a->size = numsamps;
diff --git a/wdsp/rmatch.cpp b/wdsp/rmatch.cpp
index 21fd0ffed..cca11e098 100644
--- a/wdsp/rmatch.cpp
+++ b/wdsp/rmatch.cpp
@@ -36,11 +36,11 @@ namespace WDSP {
 
 MAV* MAV::create_mav (int ringmin, int ringmax, float nom_value)
 {
-    MAV *a = new MAV;
+    auto *a = new MAV;
     a->ringmin = ringmin;
     a->ringmax = ringmax;
     a->nom_value = nom_value;
-    a->ring = new int[a->ringmax]; // (int *) malloc0 (a->ringmax * sizeof (int));
+    a->ring = new int[a->ringmax];
     a->mask = a->ringmax - 1;
     a->i = 0;
     a->load = 0;
@@ -50,8 +50,8 @@ MAV* MAV::create_mav (int ringmin, int ringmax, float nom_value)
 
 void MAV::destroy_mav (MAV *a)
 {
-    delete[] (a->ring);
-    delete (a);
+    delete[] a->ring;
+    delete a;
 }
 
 void MAV::flush_mav (MAV *a)
@@ -79,11 +79,11 @@ void MAV::xmav (MAV *a, int input, float* output)
 
 AAMAV* AAMAV::create_aamav (int ringmin, int ringmax, float nom_ratio)
 {
-    AAMAV *a = new AAMAV;
+    auto *a = new AAMAV;
     a->ringmin = ringmin;
     a->ringmax = ringmax;
     a->nom_ratio = nom_ratio;
-    a->ring = new int[a->ringmax]; // (int *) malloc0 (a->ringmax * sizeof (int));
+    a->ring = new int[a->ringmax];
     a->mask = a->ringmax - 1;
     a->i = 0;
     a->load = 0;
@@ -94,8 +94,8 @@ AAMAV* AAMAV::create_aamav (int ringmin, int ringmax, float nom_ratio)
 
 void AAMAV::destroy_aamav (AAMAV *a)
 {
-    delete[] (a->ring);
-    delete[] (a);
+    delete[] a->ring;
+    delete[] a;
 }
 
 void AAMAV::flush_aamav (AAMAV *a)
@@ -137,37 +137,38 @@ void AAMAV::xaamav (AAMAV *a, int input, float* output)
 void RMATCH::calc_rmatch (RMATCH *a)
 {
     int m;
-    float theta, dtheta;
+    float theta;
+    float dtheta;
     int max_ring_insize;
     a->nom_ratio = (float)a->nom_outrate / (float)a->nom_inrate;
     max_ring_insize = (int)(1.0 + (float)a->insize * (1.05 * a->nom_ratio));
     if (a->ringsize < 2 * max_ring_insize)  a->ringsize = 2 * max_ring_insize;
     if (a->ringsize < 2 * a->outsize) a->ringsize = 2 * a->outsize;
-    a->ring = new float[a->ringsize * 2]; // (float *) malloc0 (a->ringsize * sizeof (complex));
+    a->ring = new float[a->ringsize * 2];
     a->rsize = a->ringsize;
     a->n_ring = a->rsize / 2;
     a->iin = a->rsize / 2;
     a->iout = 0;
-    a->resout = new float[max_ring_insize * 2]; // (float *) malloc0 (max_ring_insize * sizeof (complex));
-    a->v = VARSAMP::create_varsamp (1, a->insize, a->in, a->resout, a->nom_inrate, a->nom_outrate,
+    a->resout = new float[max_ring_insize * 2];
+    a->v = new VARSAMP(1, a->insize, a->in, a->resout, a->nom_inrate, a->nom_outrate,
         a->fc_high, a->fc_low, a->R, a->gain, a->var, a->varmode);
     a->ffmav = AAMAV::create_aamav (a->ff_ringmin, a->ff_ringmax, a->nom_ratio);
     a->propmav = MAV::create_mav (a->prop_ringmin, a->prop_ringmax, 0.0);
-    a->pr_gain = a->prop_gain * 48000.0 / (float)a->nom_outrate;   // adjust gain for rate
+    a->pr_gain = a->prop_gain * 48000.0f / (float)a->nom_outrate;   // adjust gain for rate
     a->inv_nom_ratio = (float)a->nom_inrate / (float)a->nom_outrate;
     a->feed_forward = 1.0;
     a->av_deviation = 0.0;
-    a->ntslew = (int)(a->tslew * a->nom_outrate);
+    a->ntslew = (int)(a->tslew * (float) a->nom_outrate);
     if (a->ntslew + 1 > a->rsize / 2) a->ntslew = a->rsize / 2 - 1;
-    a->cslew = new float[a->ntslew + 1]; // (float *) malloc0 ((a->ntslew + 1) * sizeof (float));
-    dtheta = PI / (float)a->ntslew;
+    a->cslew = new float[a->ntslew + 1];
+    dtheta = (float) PI / (float) a->ntslew;
     theta = 0.0;
     for (m = 0; m <= a->ntslew; m++)
     {
-        a->cslew[m] = 0.5 * (1.0 - cos (theta));
+        a->cslew[m] = 0.5f * (1.0f - cos (theta));
         theta += dtheta;
     }
-    a->baux = new float[a->ringsize / 2 * 2]; // (float *) malloc0 (a->ringsize / 2 * sizeof (complex));
+    a->baux = new float[a->ringsize / 2 * 2];
     a->readsamps = 0;
     a->writesamps = 0;
     a->read_startup = (unsigned int)((float)a->nom_outrate * a->startup_delay);
@@ -184,7 +185,7 @@ void RMATCH::decalc_rmatch (RMATCH *a)
     delete[] (a->cslew);
     MAV::destroy_mav (a->propmav);
     AAMAV::destroy_aamav (a->ffmav);
-    VARSAMP::destroy_varsamp (a->v);
+    delete a->v;
     delete[] (a->resout);
     delete[] (a->ring);
 }
@@ -215,7 +216,7 @@ RMATCH* RMATCH::create_rmatch (
     float tslew            // slew/blend time (seconds)
     )
 {
-    RMATCH *a = new RMATCH;
+    auto *a = new RMATCH;
     a->run = run;
     a->in = in;
     a->out = out;
@@ -246,7 +247,7 @@ RMATCH* RMATCH::create_rmatch (
 void RMATCH::destroy_rmatch (RMATCH *a)
 {
     decalc_rmatch (a);
-    delete (a);
+    delete a;
 }
 
 void RMATCH::reset_rmatch (RMATCH *a)
@@ -264,30 +265,32 @@ void RMATCH::control (RMATCH *a, int change)
         float current_ratio;
         AAMAV::xaamav (a->ffmav, change, &current_ratio);
         current_ratio *= a->inv_nom_ratio;
-        a->feed_forward = a->ff_alpha * current_ratio + (1.0 - a->ff_alpha) * a->feed_forward;
+        a->feed_forward = a->ff_alpha * current_ratio + (1.0f - a->ff_alpha) * a->feed_forward;
     }
     {
         int deviation = a->n_ring - a->rsize / 2;
         MAV::xmav (a->propmav, deviation, &a->av_deviation);
     }
     a->var = a->feed_forward - a->pr_gain * a->av_deviation;
-    if (a->var > 1.04) a->var = 1.04;
-    if (a->var < 0.96) a->var = 0.96;
+    if (a->var > 1.04) a->var = 1.04f;
+    if (a->var < 0.96) a->var = 0.96f;
 }
 
 void RMATCH::blend (RMATCH *a)
 {
-    int i, j;
+    int i;
+    int j;
     for (i = 0, j = a->iout; i <= a->ntslew; i++, j = (j + 1) % a->rsize)
     {
-        a->ring[2 * j + 0] = a->cslew[i] * a->ring[2 * j + 0] + (1.0 - a->cslew[i]) * a->baux[2 * i + 0];
-        a->ring[2 * j + 1] = a->cslew[i] * a->ring[2 * j + 1] + (1.0 - a->cslew[i]) * a->baux[2 * i + 1];
+        a->ring[2 * j + 0] = a->cslew[i] * a->ring[2 * j + 0] + (1.0f - a->cslew[i]) * a->baux[2 * i + 0];
+        a->ring[2 * j + 1] = a->cslew[i] * a->ring[2 * j + 1] + (1.0f - a->cslew[i]) * a->baux[2 * i + 1];
     }
 }
 
 void RMATCH::upslew (RMATCH *a, int newsamps)
 {
-    int i, j;
+    int i;
+    int j;
     i = 0;
     j = a->iin;
     while (a->ucnt >= 0 && i < newsamps)
@@ -302,10 +305,13 @@ void RMATCH::upslew (RMATCH *a, int newsamps)
 
 void RMATCH::xrmatchIN (void* b, float* in)
 {
-    RMATCH *a = (RMATCH*) b;
+    auto *a = (RMATCH*) b;
     if (a->run == 1)
     {
-        int newsamps, first, second, ovfl;
+        int newsamps;
+        int first;
+        int second;
+        int ovfl;
         float var;
         a->v->in = a->in = in;
 
@@ -314,13 +320,12 @@ void RMATCH::xrmatchIN (void* b, float* in)
         else
             var = a->fvar;
 
-        newsamps = VARSAMP::xvarsamp (a->v, var);
+        newsamps = a->v->execute(var);
         a->n_ring += newsamps;
 
         if ((ovfl = a->n_ring - a->rsize) > 0)
         {
             a->overflows += 1;
-            // a->n_ring = a->rsize / 2;
             a->n_ring = a->rsize; //
 
             if ((a->ntslew + 1) > (a->rsize - a->iout))
@@ -336,7 +341,6 @@ void RMATCH::xrmatchIN (void* b, float* in)
 
             std::copy(a->ring + 2 * a->iout, a->ring + 2 * a->iout + first * 2, a->baux);
             std::copy(a->ring, a->ring + second * 2, a->baux + 2 * first);
-            // a->iout = (a->iout + ovfl + a->rsize / 2) % a->rsize;
             a->iout = (a->iout + ovfl) % a->rsize; //
         }
 
@@ -376,8 +380,13 @@ void RMATCH::xrmatchIN (void* b, float* in)
 
 void RMATCH::dslew (RMATCH *a)
 {
-    int i, j, k, n;
-    int zeros, first, second;
+    int i;
+    int j;
+    int k;
+    int n;
+    int zeros;
+    int first;
+    int second;
     if (a->n_ring > a->ntslew + 1)
     {
         i = (a->iout + (a->n_ring - (a->ntslew + 1))) % a->rsize;
@@ -414,7 +423,7 @@ void RMATCH::dslew (RMATCH *a)
         j--;
         n++;
     }
-    // zeros = a->outsize + a->rsize / 2 - n;
+
     if ((zeros = a->outsize - n) > 0) //
     { //
         if (zeros > a->rsize - i)
@@ -429,21 +438,20 @@ void RMATCH::dslew (RMATCH *a)
         }
         std::fill(a->ring + 2 * i, a->ring + 2 * i + first * 2, 0);
         std::fill(a->ring, a->ring + second * 2, 0);
-        n += zeros; //
-    } //
-    // a->n_ring = a->outsize + a->rsize / 2;
-    a->n_ring = n; //
-    // a->iin = (a->iout + a->outsize + a->rsize/2) % a->rsize;
-    a->iin = (a->iout + a->n_ring) % a->rsize; //
+        n += zeros;
+    }
+    a->n_ring = n;
+    a->iin = (a->iout + a->n_ring) % a->rsize;
 }
 
 
 void RMATCH::xrmatchOUT (void* b, float* out)
 {
-    RMATCH *a = (RMATCH*) b;
+    auto *a = (RMATCH*) b;
     if (a->run == 1)
     {
-        int first, second;
+        int first;
+        int second;
         a->out = out;
 
         if (a->n_ring < a->outsize)
@@ -487,7 +495,7 @@ void RMATCH::xrmatchOUT (void* b, float* out)
 
 void RMATCH::getRMatchDiags (void* b, int* underflows, int* overflows, float* var, int* ringsize, int* nring)
 {
-    RMATCH *a = (RMATCH*) b;
+    auto *a = (RMATCH*) b;
     *underflows = a->underflows;
     *overflows = a->overflows;
     a->underflows &= 0xFFFFFFFF;
@@ -500,15 +508,12 @@ void RMATCH::getRMatchDiags (void* b, int* underflows, int* overflows, float* va
 
 void RMATCH::resetRMatchDiags (void*)
 {
-    // RMATCH *a = (RMATCH*) b;
-    // InterlockedExchange (&a->underflows, 0);
-    // InterlockedExchange (&a->overflows,  0);
 }
 
 
 void RMATCH::forceRMatchVar (void* b, int force, float fvar)
 {
-    RMATCH *a = (RMATCH*) b;
+    auto *a = (RMATCH*) b;
     a->force = force;
     a->fvar = fvar;
 }
@@ -518,8 +523,8 @@ void* RMATCH::create_rmatchV(int in_size, int out_size, int nom_inrate, int nom_
 {
     return (void*)create_rmatch (
         1,                      // run
-        0,                      // input buffer, stuffed in other calls
-        0,                      // output buffer, stuffed in other calls
+        nullptr,                      // input buffer, stuffed in other calls
+        nullptr,                      // output buffer, stuffed in other calls
         in_size,                // input buffer size (complex samples)
         out_size,               // output buffer size (complex samples)
         nom_inrate,             // nominal input sample-rate
@@ -534,25 +539,25 @@ void* RMATCH::create_rmatchV(int in_size, int out_size, int nom_inrate, int nom_
         var,                    // initial variable ratio
         4096,                   // feed-forward moving average min size
         262144,                 // feed-forward moving average max size - POWER OF TWO!
-        0.01,                   // feed-forward exponential smoothing
+        0.01f,                   // feed-forward exponential smoothing
         4096,                   // proportional feedback min moving av ringsize
         16384,                  // proportional feedback max moving av ringsize - POWER OF TWO!
-        4.0e-06,                // proportional feedback gain
+        4.0e-06f,                // proportional feedback gain
         1,                      // linearly interpolate cvar by sample
-        0.003 );                // slew time (seconds)
+        0.003f );                // slew time (seconds)
 }
 
 
 void RMATCH::destroy_rmatchV (void* ptr)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     destroy_rmatch (a);
 }
 
 
 void RMATCH::setRMatchInsize (void* ptr, int insize)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
     std::this_thread::sleep_for(std::chrono::seconds(10));
     decalc_rmatch(a);
@@ -564,7 +569,7 @@ void RMATCH::setRMatchInsize (void* ptr, int insize)
 
 void RMATCH::setRMatchOutsize (void* ptr, int outsize)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
     std::this_thread::sleep_for(std::chrono::seconds(10));
     decalc_rmatch(a);
@@ -576,7 +581,7 @@ void RMATCH::setRMatchOutsize (void* ptr, int outsize)
 
 void RMATCH::setRMatchNomInrate (void* ptr, int nom_inrate)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
     std::this_thread::sleep_for(std::chrono::seconds(10));
     decalc_rmatch(a);
@@ -588,7 +593,7 @@ void RMATCH::setRMatchNomInrate (void* ptr, int nom_inrate)
 
 void RMATCH::setRMatchNomOutrate (void* ptr, int nom_outrate)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
     std::this_thread::sleep_for(std::chrono::seconds(10));
     decalc_rmatch(a);
@@ -600,7 +605,7 @@ void RMATCH::setRMatchNomOutrate (void* ptr, int nom_outrate)
 
 void RMATCH::setRMatchRingsize (void* ptr, int ringsize)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
     std::this_thread::sleep_for(std::chrono::seconds(10));
     decalc_rmatch(a);
@@ -612,7 +617,7 @@ void RMATCH::setRMatchRingsize (void* ptr, int ringsize)
 
 void RMATCH::setRMatchFeedbackGain (void* b, float feedback_gain)
 {
-    RMATCH *a = (RMATCH*) b;
+    auto *a = (RMATCH*) b;
     a->prop_gain = feedback_gain;
     a->pr_gain = a->prop_gain * 48000.0 / (float)a->nom_outrate;
 }
@@ -620,9 +625,8 @@ void RMATCH::setRMatchFeedbackGain (void* b, float feedback_gain)
 
 void RMATCH::setRMatchSlewTime (void* b, float slew_time)
 {
-    RMATCH *a = (RMATCH*) b;
-    a->run = 0; // InterlockedBitTestAndReset(&a->run, 0);     // turn OFF new data coming into the rmatch
-    // Sleep(10);                                  // wait for processing to cease
+    auto *a = (RMATCH*) b;
+    a->run = 0;
     decalc_rmatch(a);                           // deallocate all memory EXCEPT the data structure holding all current parameters
     a->tslew = slew_time;                       // change the value of 'slew_time'
     calc_rmatch(a);                             // recalculate/reallocate everything in the RMATCH
@@ -632,21 +636,20 @@ void RMATCH::setRMatchSlewTime (void* b, float slew_time)
 
 void RMATCH::setRMatchSlewTime1(void* b, float slew_time)
 {
-    RMATCH *a = (RMATCH*) b;
-    float theta, dtheta;
-    int m;
+    auto *a = (RMATCH*) b;
+    float theta;
+    float dtheta;
     a->run = 0;
-    // Sleep(10);
-    delete[](a->cslew);
+    delete[] a->cslew;
     a->tslew = slew_time;
-    a->ntslew = (int)(a->tslew * a->nom_outrate);
+    a->ntslew = (int)(a->tslew * (float) a->nom_outrate);
     if (a->ntslew + 1 > a->rsize / 2) a->ntslew = a->rsize / 2 - 1;
     a->cslew = new float[a->ntslew + 1]; // (float*)malloc0((a->ntslew + 1) * sizeof(float));
-    dtheta = PI / (float)a->ntslew;
+    dtheta = (float) PI / (float)a->ntslew;
     theta = 0.0;
-    for (m = 0; m <= a->ntslew; m++)
+    for (int m = 0; m <= a->ntslew; m++)
     {
-        a->cslew[m] = 0.5 * (1.0 - cos(theta));
+        a->cslew[m] = 0.5f * (1.0f - cos(theta));
         theta += dtheta;
     }
     a->run = 1;
@@ -655,9 +658,8 @@ void RMATCH::setRMatchSlewTime1(void* b, float slew_time)
 
 void RMATCH::setRMatchPropRingMin(void* ptr, int prop_min)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
-    // Sleep(10);
     decalc_rmatch(a);
     a->prop_ringmin = prop_min;
     calc_rmatch(a);
@@ -667,9 +669,8 @@ void RMATCH::setRMatchPropRingMin(void* ptr, int prop_min)
 
 void RMATCH::setRMatchPropRingMax(void* ptr, int prop_max)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
-    // Sleep(10);
     decalc_rmatch(a);
     a->prop_ringmax = prop_max; // must be a power of two
     calc_rmatch(a);
@@ -679,9 +680,8 @@ void RMATCH::setRMatchPropRingMax(void* ptr, int prop_max)
 
 void RMATCH::setRMatchFFRingMin(void* ptr, int ff_ringmin)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
-    // Sleep(10);
     decalc_rmatch(a);
     a->ff_ringmin = ff_ringmin;
     calc_rmatch(a);
@@ -691,9 +691,8 @@ void RMATCH::setRMatchFFRingMin(void* ptr, int ff_ringmin)
 
 void RMATCH::setRMatchFFRingMax(void* ptr, int ff_ringmax)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
-    // Sleep(10);
     decalc_rmatch(a);
     a->ff_ringmax = ff_ringmax; // must be a power of two
     calc_rmatch(a);
@@ -703,7 +702,7 @@ void RMATCH::setRMatchFFRingMax(void* ptr, int ff_ringmax)
 
 void RMATCH::setRMatchFFAlpha(void* ptr, float ff_alpha)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    auto *a = (RMATCH*) ptr;
     a->run = 0;
     std::this_thread::sleep_for(std::chrono::seconds(10));
     a->ff_alpha = ff_alpha;
@@ -713,7 +712,7 @@ void RMATCH::setRMatchFFAlpha(void* ptr, float ff_alpha)
 
 void RMATCH::getControlFlag(void* ptr, int* control_flag)
 {
-    RMATCH *a = (RMATCH*) ptr;
+    RMATCH const *a = (RMATCH*) ptr;
     *control_flag = a->control_flag;
 }
 
@@ -724,8 +723,8 @@ void* RMATCH::create_rmatchLegacyV(int in_size, int out_size, int nom_inrate, in
 {
     return (void*) create_rmatch(
         1,                      // run
-        0,                      // input buffer, stuffed in other calls
-        0,                      // output buffer, stuffed in other calls
+        nullptr,                      // input buffer, stuffed in other calls
+        nullptr,                      // output buffer, stuffed in other calls
         in_size,                // input buffer size (complex samples)
         out_size,               // output buffer size (complex samples)
         nom_inrate,             // nominal input sample-rate
@@ -740,12 +739,12 @@ void* RMATCH::create_rmatchLegacyV(int in_size, int out_size, int nom_inrate, in
         1.0,                    // initial variable ratio
         4096,                   // feed-forward moving average min size
         262144,                 // feed-forward moving average max size - POWER OF TWO!
-        0.01,                   // feed-forward exponential smoothing
+        0.01f,                   // feed-forward exponential smoothing
         4096,                   // proportional feedback min moving av ringsize
         16384,                  // proportional feedback max moving av ringsize - POWER OF TWO!
-        1.0e-06,                // proportional feedback gain  ***W4WMT - reduce loop gain a bit for PowerSDR to help Primary buffers > 512
+        1.0e-06f,                // proportional feedback gain  ***W4WMT - reduce loop gain a bit for PowerSDR to help Primary buffers > 512
         0,                      // linearly interpolate cvar by sample  ***W4WMT - set varmode = 0 for PowerSDR (doesn't work otherwise!?!)
-        0.003);                 // slew time (seconds)
+        0.003f);                 // slew time (seconds)
 }
 
 } // namespace WDSP
diff --git a/wdsp/varsamp.cpp b/wdsp/varsamp.cpp
index 5a9e3c7f3..ffbdfcc35 100644
--- a/wdsp/varsamp.cpp
+++ b/wdsp/varsamp.cpp
@@ -31,236 +31,220 @@ warren@wpratt.com
 
 namespace WDSP {
 
-void VARSAMP::calc_varsamp (VARSAMP *a)
+void VARSAMP::calc()
 {
-    float min_rate, max_rate, norm_rate;
-    float fc_norm_high, fc_norm_low;
-    a->nom_ratio = (float)a->out_rate / (float)a->in_rate;
-    a->cvar = a->var * a->nom_ratio;
-    a->inv_cvar = 1.0 / a->cvar;
-    a->old_inv_cvar = a->inv_cvar;
-    a->dicvar = 0.0;
-    a->delta = fabs (1.0 / a->cvar - 1.0);
-    a->fc = a->fcin;
-    if (a->out_rate >= a->in_rate)
+    float min_rate;
+    float max_rate;
+    float norm_rate;
+    float fc_norm_high;
+    float fc_norm_low;
+    nom_ratio = (float)out_rate / (float)in_rate;
+    cvar = var * nom_ratio;
+    inv_cvar = 1.0f / cvar;
+    old_inv_cvar = inv_cvar;
+    dicvar = 0.0;
+    delta = (float) fabs (1.0 / cvar - 1.0);
+    fc = fcin;
+    if (out_rate >= in_rate)
     {
-        min_rate = (float)a->in_rate;
-        max_rate = (float)a->out_rate;
+        min_rate = (float)in_rate;
         norm_rate = min_rate;
     }
     else
     {
-        min_rate = (float)a->out_rate;
-        max_rate = (float)a->in_rate;
+        min_rate = (float)out_rate;
+        max_rate = (float)in_rate;
         norm_rate = max_rate;
     }
-    if (a->fc == 0.0) a->fc = 0.95 * 0.45 * min_rate;
-    fc_norm_high = a->fc / norm_rate;
-    if (a->fc_low < 0.0)
+    if (fc == 0.0) fc = 0.95f * 0.45f * min_rate;
+    fc_norm_high = fc / norm_rate;
+    if (fc_low < 0.0)
         fc_norm_low = - fc_norm_high;
     else
-        fc_norm_low = a->fc_low / norm_rate;
-    a->rsize = (int)(140.0 * norm_rate / min_rate);
-    a->ncoef = a->rsize + 1;
-    a->ncoef += (a->R - 1) * (a->ncoef - 1);
-    a->h = FIR::fir_bandpass(a->ncoef, fc_norm_low, fc_norm_high, (float)a->R, 1, 0, (float)a->R * a->gain);
-    // print_impulse ("imp.txt", a->ncoef, a->h, 0, 0);
-    a->ring = new float[a->rsize * 2]; // (float *)malloc0(a->rsize * sizeof(complex));
-    a->idx_in = a->rsize - 1;
-    a->h_offset = 0.0;
-    a->hs = new float[a->rsize]; // (float *)malloc0 (a->rsize * sizeof (float));
-    a->isamps = 0.0;
+        fc_norm_low = fc_low / norm_rate;
+    rsize = (int)(140.0 * norm_rate / min_rate);
+    ncoef = rsize + 1;
+    ncoef += (R - 1) * (ncoef - 1);
+    FIR::fir_bandpass(h, ncoef, fc_norm_low, fc_norm_high, (float)R, 1, 0, (float)R * gain);
+    ring.resize(rsize * 2);
+    idx_in = rsize - 1;
+    h_offset = 0.0;
+    hs.resize(rsize);
+    isamps = 0.0;
 }
 
-void VARSAMP::decalc_varsamp (VARSAMP *a)
-{
-    delete[] (a->hs);
-    delete[] (a->ring);
-    delete[] (a->h);
-}
-
-VARSAMP* VARSAMP::create_varsamp (
-    int run,
-    int size,
-    float* in,
-    float* out,
-    int in_rate,
-    int out_rate,
-    float fc,
-    float fc_low,
-    int R,
-    float gain,
-    float var,
-    int varmode
+VARSAMP::VARSAMP(
+    int _run,
+    int _size,
+    float* _in,
+    float* _out,
+    int _in_rate,
+    int _out_rate,
+    float _fc,
+    float _fc_low,
+    int _R,
+    float _gain,
+    float _var,
+    int _varmode
 )
 {
-    VARSAMP *a = new VARSAMP;
-
-    a->run = run;
-    a->size = size;
-    a->in = in;
-    a->out = out;
-    a->in_rate = in_rate;
-    a->out_rate = out_rate;
-    a->fcin = fc;
-    a->fc_low = fc_low;
-    a->R = R;
-    a->gain = gain;
-    a->var = var;
-    a->varmode = varmode;
-    calc_varsamp (a);
-    return a;
+    run = _run;
+    size = _size;
+    in = _in;
+    out = _out;
+    in_rate = _in_rate;
+    out_rate = _out_rate;
+    fcin = _fc;
+    fc_low = _fc_low;
+    R = _R;
+    gain = _gain;
+    var = _var;
+    varmode = _varmode;
+    calc();
 }
 
-void VARSAMP::destroy_varsamp (VARSAMP *a)
+void VARSAMP::flush()
 {
-    decalc_varsamp (a);
-    delete (a);
+    std::fill(ring.begin(), ring.end(), 0);
+    idx_in = rsize - 1;
+    h_offset = 0.0;
+    isamps = 0.0;
 }
 
-void VARSAMP::flush_varsamp (VARSAMP *a)
+void VARSAMP::hshift()
 {
-    std::fill(a->ring, a->ring + a->rsize * 2, 0);
-    a->idx_in = a->rsize - 1;
-    a->h_offset = 0.0;
-    a->isamps = 0.0;
-}
-
-void VARSAMP::hshift (VARSAMP *a)
-{
-    int i, j, k;
+    int i;
+    int j;
+    int k;
     int hidx;
-    float frac, pos;
-    pos = (float)a->R * a->h_offset;
+    float frac;
+    float pos;
+    pos = (float)R * h_offset;
     hidx = (int)(pos);
     frac = pos - (float)hidx;
-    for (i = a->rsize - 1, j = hidx, k = hidx + 1; i >= 0; i--, j += a->R, k += a->R)
-        a->hs[i] = a->h[j] + frac * (a->h[k] - a->h[j]);
+    for (i = rsize - 1, j = hidx, k = hidx + 1; i >= 0; i--, j += R, k += R)
+        hs[i] = h[j] + frac * (h[k] - h[j]);
 }
 
-int VARSAMP::xvarsamp (VARSAMP *a, float var)
+int VARSAMP::execute(float _var)
 {
     int outsamps = 0;
-    uint64_t* picvar;
+    uint64_t const* picvar;
     uint64_t N;
-    a->var = var;
-    a->old_inv_cvar = a->inv_cvar;
-    a->cvar = a->var * a->nom_ratio;
-    a->inv_cvar = 1.0 / a->cvar;
-    if (a->varmode)
+    var = _var;
+    old_inv_cvar = inv_cvar;
+    cvar = var * nom_ratio;
+    inv_cvar = 1.0f / cvar;
+    if (varmode)
     {
-        a->dicvar = (a->inv_cvar - a->old_inv_cvar) / (float)a->size;
-        a->inv_cvar = a->old_inv_cvar;
+        dicvar = (inv_cvar - old_inv_cvar) / (float)size;
+        inv_cvar = old_inv_cvar;
     }
-    else            a->dicvar = 0.0;
-    if (a->run)
+    else            dicvar = 0.0;
+    if (run)
     {
-        int i, j;
         int idx_out;
-        float I, Q;
-        for (i = 0; i < a->size; i++)
+        float I;
+        float Q;
+        for (int i = 0; i < size; i++)
         {
-            a->ring[2 * a->idx_in + 0] = a->in[2 * i + 0];
-            a->ring[2 * a->idx_in + 1] = a->in[2 * i + 1];
-            a->inv_cvar += a->dicvar;
-            picvar = (uint64_t*)(&a->inv_cvar);
+            ring[2 * idx_in + 0] = in[2 * i + 0];
+            ring[2 * idx_in + 1] = in[2 * i + 1];
+            inv_cvar += dicvar;
+            picvar = (uint64_t*)(&inv_cvar);
             N = *picvar & 0xffffffffffff0000;
-            a->inv_cvar = static_cast<float>(N);
-            a->delta = 1.0 - a->inv_cvar;
-            while (a->isamps < 1.0)
+            inv_cvar = static_cast<float>(N);
+            delta = 1.0f - inv_cvar;
+            while (isamps < 1.0)
             {
                 I = 0.0;
                 Q = 0.0;
-                hshift (a);
-                a->h_offset += a->delta;
-                while (a->h_offset >= 1.0) a->h_offset -= 1.0;
-                while (a->h_offset <  0.0) a->h_offset += 1.0;
-                for (j = 0; j < a->rsize; j++)
+                hshift();
+                h_offset += delta;
+                while (h_offset >= 1.0) h_offset -= 1.0f;
+                while (h_offset <  0.0) h_offset += 1.0f;
+                for (int j = 0; j < rsize; j++)
                 {
-                    if ((idx_out = a->idx_in + j) >= a->rsize) idx_out -= a->rsize;
-                    I += a->hs[j] * a->ring[2 * idx_out + 0];
-                    Q += a->hs[j] * a->ring[2 * idx_out + 1];
+                    if ((idx_out = idx_in + j) >= rsize) idx_out -= rsize;
+                    I += hs[j] * ring[2 * idx_out + 0];
+                    Q += hs[j] * ring[2 * idx_out + 1];
                 }
-                a->out[2 * outsamps + 0] = I;
-                a->out[2 * outsamps + 1] = Q;
+                out[2 * outsamps + 0] = I;
+                out[2 * outsamps + 1] = Q;
                 outsamps++;
-                a->isamps += a->inv_cvar;
+                isamps += inv_cvar;
             }
-            a->isamps -= 1.0;
-            if (--a->idx_in < 0) a->idx_in = a->rsize - 1;
+            isamps -= 1.0f;
+            if (--idx_in < 0) idx_in = rsize - 1;
         }
     }
-    else if (a->in != a->out)
-        std::copy( a->in,  a->in + a->size * 2, a->out);
+    else if (in != out)
+        std::copy( in,  in + size * 2, out);
     return outsamps;
 }
 
-void VARSAMP::setBuffers_varsamp (VARSAMP *a, float* in, float* out)
+void VARSAMP::setBuffers(float* _in, float* _out)
 {
-    a->in = in;
-    a->out = out;
+    in = _in;
+    out = _out;
 }
 
-void VARSAMP::setSize_varsamp (VARSAMP *a, int size)
+void VARSAMP::setSize(int _size)
 {
-    a->size = size;
-    flush_varsamp (a);
+    size = _size;
+    flush();
 }
 
-void VARSAMP::setInRate_varsamp (VARSAMP *a, int rate)
+void VARSAMP::setInRate(int _rate)
 {
-    decalc_varsamp (a);
-    a->in_rate = rate;
-    calc_varsamp (a);
+    in_rate = _rate;
+    calc();
 }
 
-void VARSAMP::setOutRate_varsamp (VARSAMP *a, int rate)
+void VARSAMP::setOutRate(int _rate)
 {
-    decalc_varsamp (a);
-    a->out_rate = rate;
-    calc_varsamp (a);
+    out_rate = _rate;
+    calc();
 }
 
-void VARSAMP::setFCLow_varsamp (VARSAMP *a, float fc_low)
+void VARSAMP::setFCLow(float _fc_low)
 {
-    if (fc_low != a->fc_low)
+    if (_fc_low != fc_low)
     {
-        decalc_varsamp (a);
-        a->fc_low = fc_low;
-        calc_varsamp (a);
+        fc_low = _fc_low;
+        calc();
     }
 }
 
-void VARSAMP::setBandwidth_varsamp (VARSAMP *a, float fc_low, float fc_high)
+void VARSAMP::setBandwidth(float _fc_low, float _fc_high)
 {
-    if (fc_low != a->fc_low || fc_high != a->fcin)
+    if (_fc_low != fc_low || _fc_high != fcin)
     {
-        decalc_varsamp (a);
-        a->fc_low = fc_low;
-        a->fcin = fc_high;
-        calc_varsamp (a);
+        fc_low = _fc_low;
+        fcin = _fc_high;
+        calc();
     }
 }
 
 // exported calls
 
-void* VARSAMP::create_varsampV (int in_rate, int out_rate, int R)
+void* VARSAMP::create_varsampV (int _in_rate, int _out_rate, int R)
 {
-    return (void *)create_varsamp (1, 0, 0, 0, in_rate, out_rate, 0.0, -1.0, R, 1.0, 1.0, 1);
+    return (void *) new VARSAMP(1, 0, nullptr, nullptr, _in_rate, _out_rate, 0.0, -1.0, R, 1.0, 1.0, 1);
 }
 
 void VARSAMP::xvarsampV (float* input, float* output, int numsamps, float var, int* outsamps, void* ptr)
 {
-    VARSAMP *a = (VARSAMP*) ptr;
+    auto *a = (VARSAMP*) ptr;
     a->in = input;
     a->out = output;
     a->size = numsamps;
-    *outsamps = xvarsamp(a, var);
+    *outsamps = a->execute(var);
 }
 
 void VARSAMP::destroy_varsampV (void* ptr)
 {
-    destroy_varsamp ( (VARSAMP*) ptr );
+    delete (VARSAMP*) ptr;
 }
 
 } // namespace WDSP
diff --git a/wdsp/varsamp.hpp b/wdsp/varsamp.hpp
index 97e21dd00..dacc7948f 100644
--- a/wdsp/varsamp.hpp
+++ b/wdsp/varsamp.hpp
@@ -28,6 +28,8 @@ warren@wpratt.com
 #ifndef wdsp_varsamp_h
 #define wdsp_varsamp_h
 
+#include <vector>
+
 #include "export.h"
 
 namespace WDSP {
@@ -47,9 +49,9 @@ public:
     float gain;
     int idx_in;
     int ncoef;
-    float* h;
+    std::vector<float> h;
     int rsize;
-    float* ring;
+    std::vector<float> ring;
     float var;
     int varmode;
     float cvar;
@@ -57,13 +59,13 @@ public:
     float old_inv_cvar;
     float dicvar;
     float delta;
-    float* hs;
+    std::vector<float> hs;
     int R;
     float h_offset;
     float isamps;
     float nom_ratio;
 
-    static VARSAMP* create_varsamp (
+    VARSAMP(
         int run,
         int size,
         float* in,
@@ -77,24 +79,26 @@ public:
         float var,
         int varmode
     );
-    static void destroy_varsamp (VARSAMP *a);
-    static void flush_varsamp (VARSAMP *a);
-    static int xvarsamp (VARSAMP *a, float var);
-    static void setBuffers_varsamp (VARSAMP *a, float* in, float* out);
-    static void setSize_varsamp (VARSAMP *a, int size);
-    static void setInRate_varsamp (VARSAMP *a, int rate);
-    static void setOutRate_varsamp (VARSAMP *a, int rate);
-    static void setFCLow_varsamp (VARSAMP *a, float fc_low);
-    static void setBandwidth_varsamp (VARSAMP *a, float fc_low, float fc_high);
+    VARSAMP(const VARSAMP&) = delete;
+    VARSAMP& operator=(VARSAMP& other) = delete;
+    ~VARSAMP() = default;
+
+    void flush();
+    int execute(float var);
+    void setBuffers(float* in, float* out);
+    void setSize(int size);
+    void setInRate(int rate);
+    void setOutRate(int rate);
+    void setFCLow(float fc_low);
+    void setBandwidth(float fc_low, float fc_high);
     // Exported calls
     static void* create_varsampV (int in_rate, int out_rate, int R);
     static void xvarsampV (float* input, float* output, int numsamps, float var, int* outsamps, void* ptr);
     static void destroy_varsampV (void* ptr);
 
 private:
-    static void calc_varsamp (VARSAMP *a);
-    static void decalc_varsamp (VARSAMP *a);
-    static void hshift (VARSAMP *a);
+    void calc();
+    void hshift();
 };
 
 } // namespace WDSP