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, ¤t_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