1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-21 23:55:13 -05:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Edouard Griffiths
22307b9afc
Merge ef0255f2bb into fcd43df711 2024-08-10 10:21:27 +00:00
f4exb
ef0255f2bb WDSP: impulse responses refactoring (5) 2024-08-10 12:21:04 +02:00
f4exb
12f4d0a0fd WDSP: FIROPT rework 2024-08-10 09:59:42 +02:00
f4exb
e48dc22793 WDSP: impulse responses refactoring (4) 2024-08-10 06:40:35 +02:00
f4exb
ad3e7dfe19 WDSP: fixed missing decalc in USLEW 2024-08-10 02:09:07 +02:00
f4exb
28cfad98ff WDSP: impulse responses refactoring (3) 2024-08-10 02:06:19 +02:00
f4exb
7319e4cb88 WDSP: impulse responses refactoring (2) 2024-08-09 06:33:00 +02:00
f4exb
62f05b3706 WDSP: impulse responses refactoring (1) 2024-08-08 09:09:40 +02:00
Edouard Griffiths
fcd43df711
Merge pull request #2225 from james-pcdr/patch-2
Update scanner.py: fix print to stderr
2024-08-03 03:00:40 +02:00
Edouard Griffiths
ff7c06311b
Merge pull request #2226 from jfdelnero/master
Fix audio glitches in the DAB plugin
2024-08-02 18:56:01 +02:00
Jean-François DEL NERO
5888645957 Don't decimate the audio signal if not needed. 2024-08-02 12:23:27 +02:00
Jean-François DEL NERO
2fddaff6d2 Fix audio glitches in the DAB plugin.
The glitches were generated by an int16 integer overflow.

The issue appeared when the audio was near or at the saturation level.
When the input audio signal is saturated, the polyphase filter based interpolation/decimation functions tend to increase the samples values and then make them pass the int16 limits. The int16 sample scale() parameter defeat the min/max limitation.

This fix removes the intermediate int16 type conversion by using the Complex Real type.

fixes f4exb/sdrangel#1978
2024-08-02 12:17:00 +02:00
james-pcdr
4cf2c0b7c7
Update scanner.py: fix print to stderr 2024-07-31 13:33:28 -04:00
43 changed files with 922 additions and 888 deletions

View File

@ -366,7 +366,7 @@ void DABDemodSink::tii(int tii)
} }
} }
static int16_t scale(int16_t sample, float factor) static int16_t scale(Real sample, float factor)
{ {
int32_t prod = (int32_t)(((int32_t)sample) * factor); int32_t prod = (int32_t)(((int32_t)sample) * factor);
prod = std::min(prod, 32767); prod = std::min(prod, 32767);
@ -403,7 +403,12 @@ void DABDemodSink::audio(int16_t *buffer, int size, int samplerate, bool stereo)
ci.real(0.0f); ci.real(0.0f);
ci.imag(0.0f); ci.imag(0.0f);
} }
if (m_audioInterpolatorDistance < 1.0f) // interpolate
if (m_audioInterpolatorDistance == 1.0f)
{
processOneAudioSample(ci);
}
else if (m_audioInterpolatorDistance < 1.0f) // interpolate
{ {
while (!m_audioInterpolator.interpolate(&m_audioInterpolatorDistanceRemain, ci, &ca)) while (!m_audioInterpolator.interpolate(&m_audioInterpolatorDistanceRemain, ci, &ca))
{ {

View File

@ -279,6 +279,9 @@ QByteArray WDSPRxSettings::serialize() const
s.writeDouble(163 + 100*i, m_profiles[i].m_ssqlTauMute); s.writeDouble(163 + 100*i, m_profiles[i].m_ssqlTauMute);
s.writeDouble(164 + 100*i, m_profiles[i].m_ssqlTauUnmute); s.writeDouble(164 + 100*i, m_profiles[i].m_ssqlTauUnmute);
s.writeDouble(165 + 100*i, m_profiles[i].m_amsqMaxTail); 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 // Equalizer
s.writeBool( 190 + 100*i, m_profiles[i].m_equalizer); s.writeBool( 190 + 100*i, m_profiles[i].m_equalizer);
s.writeFloat(4100 + 100*i, m_profiles[i].m_eqF[0]); 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); d.readU32( 74, &utmp, 0);
if ((utmp > 1023) && (utmp < 65535)) { if ((utmp > 1023) && (utmp < 65535)) {
m_reverseAPIPort = utmp; m_reverseAPIPort = (uint16_t) utmp;
} else { } else {
m_reverseAPIPort = 8888; m_reverseAPIPort = 8888;
} }
d.readU32( 75, &utmp, 0); d.readU32( 75, &utmp, 0);
m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp; m_reverseAPIDeviceIndex = utmp > 99 ? 99 : (uint16_t) utmp;
d.readU32( 76, &utmp, 0); 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); d.readS32( 77, &m_streamIndex, 0);
if (m_rollupState) if (m_rollupState)
@ -464,9 +467,9 @@ bool WDSPRxSettings::deserialize(const QByteArray& data)
// Filter // Filter
d.readS32 (100 + 100*i, &m_profiles[i].m_spanLog2, 3); d.readS32 (100 + 100*i, &m_profiles[i].m_spanLog2, 3);
d.readS32 (101 + 100*i, &tmp, 30); 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); 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); d.readS32 (103 + 100*i, &m_profiles[i].m_fftWindow, 0);
// AGC // AGC
d.readBool( 110 + 100*i, &m_profiles[i].m_agc, true); d.readBool( 110 + 100*i, &m_profiles[i].m_agc, true);

View File

@ -373,7 +373,7 @@ def main():
pass pass
except Exception as ex: except Exception as ex:
tb = traceback.format_exc() tb = traceback.format_exc()
print >> sys.stderr, tb print(tb, file=sys.stderr)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -1006,7 +1006,6 @@ void RXA::updateNBPFilters()
{ {
a->calc_impulse(); a->calc_impulse();
a->fircore->setImpulse(a->impulse, 1); a->fircore->setImpulse(a->impulse, 1);
delete[] (a->impulse);
} }
if (b->bpsnba->fnfrun) if (b->bpsnba->fnfrun)
{ {
@ -1098,7 +1097,6 @@ void RXA::nbpSetNotchesRun(int _run)
bpsnbaCheck(mode, _run); bpsnbaCheck(mode, _run);
b->calc_impulse(); // recalc nbp impulse response b->calc_impulse(); // recalc nbp impulse response
b->fircore->setImpulse(b->impulse, 0); // calculate new filter masks b->fircore->setImpulse(b->impulse, 0); // calculate new filter masks
delete[] (b->impulse);
bpsnbaSet(); bpsnbaSet();
b->fircore->setUpdate(); // apply new filter masks b->fircore->setUpdate(); // apply new filter masks
} }
@ -1116,7 +1114,6 @@ void RXA::nbpSetWindow(int _wintype)
a->wintype = _wintype; a->wintype = _wintype;
a->calc_impulse(); a->calc_impulse();
a->fircore->setImpulse(a->impulse, 1); a->fircore->setImpulse(a->impulse, 1);
delete[] (a->impulse);
} }
if (b->wintype != _wintype) if (b->wintype != _wintype)
@ -1138,7 +1135,6 @@ void RXA::nbpSetAutoIncrease(int _autoincr)
a->autoincr = _autoincr; a->autoincr = _autoincr;
a->calc_impulse(); a->calc_impulse();
a->fircore->setImpulse(a->impulse, 1); a->fircore->setImpulse(a->impulse, 1);
delete[] (a->impulse);
} }
if (b->autoincr != _autoincr) if (b->autoincr != _autoincr)

View File

@ -915,7 +915,9 @@ void TXA::setBandpassNC(int _nc)
if (a->nc != _nc) if (a->nc != _nc)
{ {
a->nc = _nc; a->nc = _nc;
float* impulse = FIR::fir_bandpass ( std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
a->nc, a->nc,
a->f_low, a->f_low,
a->f_high, a->f_high,
@ -924,8 +926,7 @@ void TXA::setBandpassNC(int _nc)
1, 1,
a->gain / (double)(2 * a->size) a->gain / (double)(2 * a->size)
); );
a->fircore->setNc(a->nc, impulse); a->fircore->setNc(impulse);
delete[] impulse;
} }
a = bp1; a = bp1;
@ -933,7 +934,9 @@ void TXA::setBandpassNC(int _nc)
if (a->nc != _nc) if (a->nc != _nc)
{ {
a->nc = _nc; a->nc = _nc;
float* impulse = FIR::fir_bandpass ( std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
a->nc, a->nc,
a->f_low, a->f_low,
a->f_high, a->f_high,
@ -942,8 +945,7 @@ void TXA::setBandpassNC(int _nc)
1, 1,
a->gain / (double)(2 * a->size) a->gain / (double)(2 * a->size)
); );
a->fircore->setNc(a->nc, impulse); a->fircore->setNc(impulse);
delete[] impulse;
} }
a = bp2; a = bp2;
@ -951,7 +953,9 @@ void TXA::setBandpassNC(int _nc)
if (a->nc != _nc) if (a->nc != _nc)
{ {
a->nc = _nc; a->nc = _nc;
float* impulse = FIR::fir_bandpass ( std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
a->nc, a->nc,
a->f_low, a->f_low,
a->f_high, a->f_high,
@ -960,8 +964,7 @@ void TXA::setBandpassNC(int _nc)
1, 1,
a->gain / (double)(2 * a->size) a->gain / (double)(2 * a->size)
); );
a->fircore->setNc(a->nc, impulse); a->fircore->setNc(impulse);
delete[] impulse;
} }
} }
@ -1032,7 +1035,7 @@ void TXA::SetBPSRun (TXA& txa, int _run)
void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high) void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high)
{ {
float* impulse; std::vector<float> impulse;
BPS *a; BPS *a;
a = txa.bps0; a = txa.bps0;
@ -1040,10 +1043,8 @@ void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high)
{ {
a->f_low = _f_low; a->f_low = _f_low;
a->f_high = _f_high; a->f_high = _f_high;
delete[] (a->mults); FIR::fir_bandpass(impulse, a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
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.data());
a->mults = FIR::fftcv_mults (2 * a->size, impulse);
delete[] (impulse);
} }
a = txa.bps1; a = txa.bps1;
@ -1052,10 +1053,8 @@ void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high)
{ {
a->f_low = _f_low; a->f_low = _f_low;
a->f_high = _f_high; a->f_high = _f_high;
delete[] (a->mults); FIR::fir_bandpass(impulse, a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
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.data());
a->mults = FIR::fftcv_mults (2 * a->size, impulse);
delete[] (impulse);
} }
a = txa.bps2; a = txa.bps2;
@ -1064,26 +1063,22 @@ void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high)
{ {
a->f_low = _f_low; a->f_low = _f_low;
a->f_high = _f_high; a->f_high = _f_high;
delete[] (a->mults); FIR::fir_bandpass(impulse, a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
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.data());
a->mults = FIR::fftcv_mults (2 * a->size, impulse);
delete[] (impulse);
} }
} }
void TXA::SetBPSWindow (TXA& txa, int _wintype) void TXA::SetBPSWindow (TXA& txa, int _wintype)
{ {
float* impulse; std::vector<float> impulse;
BPS *a; BPS *a;
a = txa.bps0; a = txa.bps0;
if (a->wintype != _wintype) if (a->wintype != _wintype)
{ {
a->wintype = _wintype; a->wintype = _wintype;
delete[] (a->mults); FIR::fir_bandpass(impulse, a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
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.data());
a->mults = FIR::fftcv_mults (2 * a->size, impulse);
delete[] (impulse);
} }
a = txa.bps1; a = txa.bps1;
@ -1091,10 +1086,8 @@ void TXA::SetBPSWindow (TXA& txa, int _wintype)
if (a->wintype != _wintype) if (a->wintype != _wintype)
{ {
a->wintype = _wintype; a->wintype = _wintype;
delete[] (a->mults); FIR::fir_bandpass(impulse, a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
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.data());
a->mults = FIR::fftcv_mults (2 * a->size, impulse);
delete[] impulse;
} }
a = txa.bps2; a = txa.bps2;
@ -1102,10 +1095,8 @@ void TXA::SetBPSWindow (TXA& txa, int _wintype)
if (a->wintype != _wintype) if (a->wintype != _wintype)
{ {
a->wintype = _wintype; a->wintype = _wintype;
delete[] (a->mults); FIR::fir_bandpass (impulse, a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
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.data());
a->mults = FIR::fftcv_mults (2 * a->size, impulse);
delete[] impulse;
} }
} }

View File

@ -66,7 +66,9 @@ BANDPASS::BANDPASS(
wintype(_wintype), wintype(_wintype),
gain(_gain) gain(_gain)
{ {
float* impulse = FIR::fir_bandpass ( std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc, nc,
f_low, f_low,
f_high, f_high,
@ -75,8 +77,7 @@ BANDPASS::BANDPASS(
1, 1,
gain / (double)(2 * size) gain / (double)(2 * size)
); );
fircore = new FIRCORE(size, in, out, nc, mp, impulse); fircore = new FIRCORE(size, in, out, mp, impulse);
delete[] impulse;
} }
BANDPASS::~BANDPASS() BANDPASS::~BANDPASS()
@ -107,7 +108,9 @@ void BANDPASS::setBuffers(float* _in, float* _out)
void BANDPASS::setSamplerate(int _rate) void BANDPASS::setSamplerate(int _rate)
{ {
samplerate = _rate; samplerate = _rate;
float* impulse = FIR::fir_bandpass ( std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc, nc,
f_low, f_low,
f_high, f_high,
@ -117,7 +120,6 @@ void BANDPASS::setSamplerate(int _rate)
gain / (double) (2 * size) gain / (double) (2 * size)
); );
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
void BANDPASS::setSize(int _size) void BANDPASS::setSize(int _size)
@ -126,7 +128,9 @@ void BANDPASS::setSize(int _size)
size = _size; size = _size;
fircore->setSize(size); fircore->setSize(size);
// recalc impulse because scale factor is a function of 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, nc,
f_low, f_low,
f_high, f_high,
@ -136,13 +140,14 @@ void BANDPASS::setSize(int _size)
gain / (double) (2 * size) gain / (double) (2 * size)
); );
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
void BANDPASS::setGain(double _gain, int _update) void BANDPASS::setGain(double _gain, int _update)
{ {
gain = _gain; gain = _gain;
float* impulse = FIR::fir_bandpass ( std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc, nc,
f_low, f_low,
f_high, f_high,
@ -152,7 +157,6 @@ void BANDPASS::setGain(double _gain, int _update)
gain / (double) (2 * size) gain / (double) (2 * size)
); );
fircore->setImpulse(impulse, _update); fircore->setImpulse(impulse, _update);
delete[] impulse;
} }
void BANDPASS::calcBandpassFilter(double _f_low, double _f_high, double _gain) 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_low = _f_low;
f_high = _f_high; f_high = _f_high;
gain = _gain; gain = _gain;
float* impulse = FIR::fir_bandpass ( std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc, nc,
f_low, f_low,
f_high, f_high,
@ -172,7 +178,6 @@ void BANDPASS::calcBandpassFilter(double _f_low, double _f_high, double _gain)
gain / (double)(2 * size) gain / (double)(2 * size)
); );
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
} }
@ -186,7 +191,9 @@ void BANDPASS::setBandpassFreqs(double _f_low, double _f_high)
{ {
if ((_f_low != f_low) || (_f_high != 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, nc,
_f_low, _f_low,
_f_high, _f_high,
@ -197,7 +204,6 @@ void BANDPASS::setBandpassFreqs(double _f_low, double _f_high)
); );
fircore->setImpulse(impulse, 0); fircore->setImpulse(impulse, 0);
delete[] impulse;
f_low = _f_low; f_low = _f_low;
f_high = _f_high; f_high = _f_high;
fircore->setUpdate(); fircore->setUpdate();
@ -210,7 +216,9 @@ void BANDPASS::SetBandpassNC(int _nc)
if (_nc != nc) if (_nc != nc)
{ {
nc = _nc; nc = _nc;
float* impulse = FIR::fir_bandpass ( std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc, nc,
f_low, f_low,
f_high, f_high,
@ -219,8 +227,7 @@ void BANDPASS::SetBandpassNC(int _nc)
1, 1,
gain / (double)( 2 * size) gain / (double)( 2 * size)
); );
fircore->setNc(nc, impulse); fircore->setNc(impulse);
delete[] impulse;
} }
} }

View File

@ -42,21 +42,28 @@ namespace WDSP {
void BPS::calc() void BPS::calc()
{ {
float* impulse;
infilt.resize(2 * size * 2); infilt.resize(2 * size * 2);
product.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)); std::vector<float> impulse;
mults = FIR::fftcv_mults(2 * size, 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); 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); CRev = fftwf_plan_dft_1d(2 * size, (fftwf_complex *) product.data(), (fftwf_complex *) out, FFTW_BACKWARD, FFTW_PATIENT);
delete[]impulse;
} }
void BPS::decalc() void BPS::decalc()
{ {
fftwf_destroy_plan(CRev); fftwf_destroy_plan(CRev);
fftwf_destroy_plan(CFor); fftwf_destroy_plan(CFor);
delete[] mults;
} }
BPS::BPS( BPS::BPS(

View File

@ -56,7 +56,7 @@ public:
double f_high; double f_high;
std::vector<float> infilt; std::vector<float> infilt;
std::vector<float> product; std::vector<float> product;
float* mults; std::vector<float> mults;
double samplerate; double samplerate;
int wintype; int wintype;
double gain; double gain;

View File

@ -177,7 +177,6 @@ void BPSNBA::recalc_bpsnba_filter(int update)
b->autoincr = autoincr; b->autoincr = autoincr;
b->calc_impulse(); b->calc_impulse();
b->fircore->setImpulse(b->impulse, update); b->fircore->setImpulse(b->impulse, update);
delete[] (b->impulse);
} }
/******************************************************************************************************** /********************************************************************************************************

View File

@ -34,11 +34,10 @@ namespace WDSP {
void CFIR::calc() void CFIR::calc()
{ {
float* impulse; std::vector<float> impulse;
scale = 1.0 / (float)(2 * size); scale = 1.0 / (float)(2 * size);
impulse = cfir_impulse (nc, DD, R, Pairs, runrate, cicrate, cutoff, xtype, xbw, 1, scale, wintype); cfir_impulse (impulse, nc, DD, R, Pairs, runrate, cicrate, cutoff, xtype, xbw, 1, scale, wintype);
p = new FIRCORE(size, in, out, nc, mp, impulse); p = new FIRCORE(size, in, out, mp, impulse);
delete[] impulse;
} }
void CFIR::decalc() void CFIR::decalc()
@ -142,7 +141,8 @@ void CFIR::setOutRate(int rate)
calc(); calc();
} }
float* CFIR::cfir_impulse ( void CFIR::cfir_impulse (
std::vector<float>& impulse,
int _N, int _N,
int _DD, int _DD,
int _R, int _R,
@ -175,7 +175,6 @@ float* CFIR::cfir_impulse (
double ri; double ri;
double mag = 0; double mag = 0;
double fn; double fn;
float* impulse;
std::vector<float> A(_N); std::vector<float> A(_N);
double ft = _cutoff / _cicrate; // normalized cutoff frequency double ft = _cutoff / _cicrate; // normalized cutoff frequency
int u_samps = (_N + 1) / 2; // number of unique samples, OK for odd or even N int u_samps = (_N + 1) / 2; // number of unique samples, OK for odd or even N
@ -254,8 +253,8 @@ float* CFIR::cfir_impulse (
else else
for (i = u_samps, j = 1; i < _N; i++, j++) for (i = u_samps, j = 1; i < _N; i++, j++)
A[i] = A[u_samps - j]; A[i] = A[u_samps - j];
impulse = FIR::fir_fsamp (_N, A.data(), _rtype, 1.0, _wintype); impulse.resize(2 * _N);
return impulse; FIR::fir_fsamp (impulse, _N, A.data(), _rtype, 1.0, _wintype);
} }
/******************************************************************************************************** /********************************************************************************************************

View File

@ -28,6 +28,8 @@ warren@wpratt.com
#ifndef wdsp_cfir_h #ifndef wdsp_cfir_h
#define wdsp_cfir_h #define wdsp_cfir_h
#include <vector>
#include "export.h" #include "export.h"
namespace WDSP { namespace WDSP {
@ -83,7 +85,8 @@ public:
void setSamplerate(int rate); void setSamplerate(int rate);
void setSize(int size); void setSize(int size);
void setOutRate(int rate); void setOutRate(int rate);
static float* cfir_impulse ( static void cfir_impulse (
std::vector<float>& impulse,
int N, int N,
int DD, int DD,
int R, int R,

View File

@ -31,81 +31,84 @@ warren@wpratt.com
namespace WDSP { 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; run = _run;
a->run = run; size = _size;
a->size = size; in = _in;
a->in = in; out = _out;
a->out = out; rate = _rate;
a->rate = rate; tdelta = _tdelta;
a->tdelta = tdelta; tdelay = _tdelay;
a->tdelay = tdelay; L = (int)(0.5 + 1.0 / (tdelta * (float)rate));
a->L = (int)(0.5 + 1.0 / (a->tdelta * (float)a->rate)); adelta = 1.0f / (float) (rate * L);
a->adelta = 1.0 / (a->rate * a->L); ft = 0.45f / (float)L;
a->ft = 0.45 / (float)a->L; ncoef = (int)(60.0 / ft);
a->ncoef = (int)(60.0 / a->ft); ncoef = (ncoef / L + 1) * L;
a->ncoef = (a->ncoef / a->L + 1) * a->L; cpp = ncoef / L;
a->cpp = a->ncoef / a->L; phnum = (int)(0.5 + tdelay / adelta);
a->phnum = (int)(0.5 + a->tdelay / a->adelta); snum = phnum / L;
a->snum = a->phnum / a->L; phnum %= L;
a->phnum %= a->L; idx_in = 0;
a->idx_in = 0; adelay = adelta * (float) (snum * L + phnum);
a->adelay = a->adelta * (a->snum * a->L + a->phnum); FIR::fir_bandpass (h, ncoef,-ft, +ft, 1.0, 1, 0, (float)L);
a->h = FIR::fir_bandpass (a->ncoef,-a->ft, +a->ft, 1.0, 1, 0, (float)a->L); rsize = cpp + (WSDEL - 1);
a->rsize = a->cpp + (WSDEL - 1); ring.resize(rsize * 2);
a->ring = new float[a->rsize * 2]; // (float *) malloc0 (a->rsize * sizeof (complex));
return a;
} }
void DELAY::destroy_delay (DELAY *a) void DELAY::flush()
{ {
delete[] (a->ring); std::fill(ring.begin(), ring.end(), 0);
delete[] (a->h); idx_in = 0;
delete (a);
} }
void DELAY::flush_delay (DELAY *a) void DELAY::execute()
{ {
std::fill(a->ring, a->ring + a->cpp * 2, 0); if (run)
a->idx_in = 0;
}
void DELAY::xdelay (DELAY *a)
{
if (a->run)
{ {
int i, j, k, idx, n; int j;
float Itmp, Qtmp; 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]; ring[2 * idx_in + 0] = in[2 * i + 0];
a->ring[2 * a->idx_in + 1] = a->in[2 * i + 1]; ring[2 * idx_in + 1] = in[2 * i + 1];
Itmp = 0.0; Itmp = 0.0;
Qtmp = 0.0; Qtmp = 0.0;
if ((n = a->idx_in + a->snum) >= a->rsize) if ((n = idx_in + snum) >= rsize)
n -= a->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) if ((idx = n + j) >= rsize)
idx -= a->rsize; idx -= rsize;
Itmp += a->ring[2 * idx + 0] * a->h[k]; Itmp += ring[2 * idx + 0] * h[k];
Qtmp += a->ring[2 * idx + 1] * a->h[k]; Qtmp += ring[2 * idx + 1] * h[k];
} }
a->out[2 * i + 0] = Itmp; out[2 * i + 0] = Itmp;
a->out[2 * i + 1] = Qtmp; out[2 * i + 1] = Qtmp;
if (--a->idx_in < 0) if (--idx_in < 0)
a->idx_in = a->rsize - 1; idx_in = rsize - 1;
} }
} }
else if (a->out != a->in) else if (out != in)
std::copy( a->in, a->in + a->size * 2, a->out); 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; float _adelay;
a->tdelay = tdelay; tdelay = _tdelay;
a->phnum = (int)(0.5 + a->tdelay / a->adelta); phnum = (int)(0.5 + tdelay / adelta);
a->snum = a->phnum / a->L; snum = phnum / L;
a->phnum %= a->L; phnum %= L;
a->adelay = a->adelta * (a->snum * a->L + a->phnum); _adelay = adelta * (float) (snum * L + phnum);
adelay = a->adelay; adelay = _adelay;
return 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; size = _size;
a->in = in; in = _in;
a->out = out; out = _out;
} }
} // namespace WDSP } // namespace WDSP

View File

@ -28,6 +28,8 @@ warren@wpratt.com
#ifndef wdsp_delay_h #ifndef wdsp_delay_h
#define wdsp_delay_h #define wdsp_delay_h
#include <vector>
#include "export.h" #include "export.h"
#define WSDEL 1025 // number of supported whole sample delays #define WSDEL 1025 // number of supported whole sample delays
@ -49,25 +51,36 @@ public:
int ncoef; // number of coefficients int ncoef; // number of coefficients
int cpp; // coefficients per phase int cpp; // coefficients per phase
float ft; // normalized cutoff frequency float ft; // normalized cutoff frequency
float* h; // coefficients std::vector<float> h; // coefficients
int snum; // starting sample number (0 for sub-sample delay) int snum; // starting sample number (0 for sub-sample delay)
int phnum; // phase number int phnum; // phase number
int idx_in; // index for input into ring int idx_in; // index for input into ring
int rsize; // ring size in complex samples int rsize; // ring size in complex samples
float* ring; // ring buffer std::vector<float> ring; // ring buffer
float adelta; // actual delay increment float adelta; // actual delay increment
float adelay; // actual delay float adelay; // actual delay
static DELAY* create_delay (int run, int size, float* in, float* out, int rate, float tdelta, float tdelay); DELAY(
static void destroy_delay (DELAY *a); int run,
static void flush_delay (DELAY *a); int size,
static void xdelay (DELAY *a); 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 // Properties
static void SetDelayRun (DELAY *a, int run); void setRun(int run);
static float SetDelayValue (DELAY *a, float delay); // returns actual delay in seconds float setValue(float delay); // returns actual delay in seconds
static void SetDelayBuffs (DELAY *a, int size, float* in, float* out); void setBuffs(int size, float* in, float* out);
}; };
} // namespace WDSP } // namespace WDSP

View File

@ -43,7 +43,8 @@ void EMPH::calc()
{ {
infilt = new float[2 * size * 2]; infilt = new float[2 * size * 2];
product = new float[2 * size * 2]; product = new float[2 * size * 2];
mults = FCurve::fc_mults( FCurve::fc_mults(
mults,
size, size,
f_low, f_low,
f_high, f_high,
@ -63,7 +64,6 @@ void EMPH::decalc()
{ {
fftwf_destroy_plan(CRev); fftwf_destroy_plan(CRev);
fftwf_destroy_plan(CFor); fftwf_destroy_plan(CFor);
delete[] mults;
delete[] product; delete[] product;
delete[] infilt; delete[] infilt;
} }

View File

@ -34,6 +34,8 @@ warren@wpratt.com
#ifndef _emph_h #ifndef _emph_h
#define _emph_h #define _emph_h
#include <vector>
#include "fftw3.h" #include "fftw3.h"
#include "export.h" #include "export.h"
@ -52,7 +54,7 @@ public:
double f_high; double f_high;
float* infilt; float* infilt;
float* product; float* product;
float* mults; std::vector<float> mults;
double rate; double rate;
fftwf_plan CFor; fftwf_plan CFor;
fftwf_plan CRev; fftwf_plan CRev;

View File

@ -53,7 +53,6 @@ EMPHP::EMPHP(
double _f_high double _f_high
) )
{ {
float* impulse;
run = _run; run = _run;
position = _position; position = _position;
size = _size; size = _size;
@ -65,19 +64,20 @@ EMPHP::EMPHP(
ctype = _ctype; ctype = _ctype;
f_low = _f_low; f_low = _f_low;
f_high = _f_high; f_high = _f_high;
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc);
FCurve::fc_impulse (
impulse,
nc, nc,
f_low, (float) f_low,
f_high, (float) f_high,
-20.0 * log10(f_high / f_low), (float) (-20.0 * log10(f_high / f_low)),
0.0, 0.0,
ctype, ctype,
rate, (float) rate,
1.0 / (2.0 * size), (float) (1.0 / (2.0 * size)),
0, 0 0, 0
); );
p = new FIRCORE(size, in, out, nc, mp, impulse); p = new FIRCORE(size, in, out, mp, impulse);
delete[] (impulse);
} }
EMPHP::~EMPHP() EMPHP::~EMPHP()
@ -107,9 +107,10 @@ void EMPHP::setBuffers(float* _in, float* _out)
void EMPHP::setSamplerate(int _rate) void EMPHP::setSamplerate(int _rate)
{ {
float* impulse;
rate = _rate; rate = _rate;
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc);
FCurve::fc_impulse (
impulse,
nc, nc,
f_low, f_low,
f_high, f_high,
@ -121,15 +122,15 @@ void EMPHP::setSamplerate(int _rate)
0, 0 0, 0
); );
p->setImpulse(impulse, 1); p->setImpulse(impulse, 1);
delete[] (impulse);
} }
void EMPHP::setSize(int _size) void EMPHP::setSize(int _size)
{ {
float* impulse;
size = _size; size = _size;
p->setSize(size); p->setSize(size);
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc);
FCurve::fc_impulse (
impulse,
nc, nc,
f_low, f_low,
f_high, f_high,
@ -142,7 +143,6 @@ void EMPHP::setSize(int _size)
0 0
); );
p->setImpulse(impulse, 1); p->setImpulse(impulse, 1);
delete[] (impulse);
} }
/******************************************************************************************************** /********************************************************************************************************
@ -167,37 +167,36 @@ void EMPHP::setMP(int _mp)
void EMPHP::setNC(int _nc) void EMPHP::setNC(int _nc)
{ {
float* impulse;
if (nc != _nc) if (nc != _nc)
{ {
nc = _nc; nc = _nc;
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc);
FCurve::fc_impulse (
impulse,
nc, nc,
f_low, (float) f_low,
f_high, (float) f_high,
-20.0 * log10(f_high / f_low), (float) (-20.0 * log10(f_high / f_low)),
0.0, 0.0,
ctype, ctype,
rate, (float) rate,
1.0 / (2.0 * size), (float) (1.0 / (2.0 * size)),
0, 0,
0 0
); );
p->setNc(nc, impulse); p->setNc(impulse);
delete[] (impulse);
} }
} }
void EMPHP::setFreqs(double low, double high) void EMPHP::setFreqs(double low, double high)
{ {
float* impulse;
if (f_low != low || f_high != high) if (f_low != low || f_high != high)
{ {
f_low = low; f_low = low;
f_high = high; f_high = high;
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc);
FCurve::fc_impulse (
impulse,
nc, nc,
f_low, f_low,
f_high, f_high,
@ -210,7 +209,6 @@ void EMPHP::setFreqs(double low, double high)
0 0
); );
p->setImpulse(impulse, 1); p->setImpulse(impulse, 1);
delete[] (impulse);
} }
} }

View File

@ -44,12 +44,12 @@ namespace WDSP {
void EQ::eq_mults (std::vector<float>& mults, int size, int nfreqs, float* F, float* G, float samplerate, float scale, int ctfmode, int wintype) void EQ::eq_mults (std::vector<float>& mults, int size, int nfreqs, float* F, float* G, float samplerate, float scale, int ctfmode, int wintype)
{ {
float* impulse = EQP::eq_impulse (size + 1, nfreqs, F, G, samplerate, scale, ctfmode, wintype); std::vector<float> impulse;
float* _mults = FIR::fftcv_mults(2 * size, impulse); EQP::eq_impulse (impulse, size + 1, nfreqs, F, G, samplerate, scale, ctfmode, wintype);
std::vector<float> _mults;
FIR::fftcv_mults(_mults, 2 * size, impulse.data());
mults.resize(2 * size * 2); mults.resize(2 * size * 2);
std::copy(_mults, _mults + 2*size*2, mults.begin()); std::copy(_mults.begin(), _mults.end(), mults.begin());
delete[] _mults;
delete[] impulse;
} }
void EQ::calc() void EQ::calc()

View File

@ -42,25 +42,34 @@ int EQP::fEQcompare (const void * a, const void * b)
return 1; return 1;
} }
float* EQP::eq_impulse (int N, int nfreqs, const float* F, const float* G, double samplerate, double scale, int ctfmode, int wintype) void EQP::eq_impulse (
std::vector<float>& impulse,
int N,
int _nfreqs,
const float* F,
const float* G,
double samplerate,
double scale,
int ctfmode,
int wintype
)
{ {
std::vector<float> fp(nfreqs + 2); std::vector<float> fp(_nfreqs + 2);
std::vector<float> gp(nfreqs + 2); std::vector<float> gp(_nfreqs + 2);
std::vector<float> A(N / 2 + 1); std::vector<float> A(N / 2 + 1);
float* sary = new float[2 * nfreqs]; float* sary = new float[2 * _nfreqs];
double gpreamp; double gpreamp;
double f; double f;
double frac; double frac;
float* impulse;
int i; int i;
int j; int j;
int mid; int mid;
fp[0] = 0.0; fp[0] = 0.0;
fp[nfreqs + 1] = 1.0; fp[_nfreqs + 1] = 1.0;
gpreamp = G[0]; gpreamp = G[0];
for (i = 1; i <= nfreqs; i++) for (i = 1; i <= _nfreqs; i++)
{ {
fp[i] = (float) (2.0 * F[i] / samplerate); fp[i] = (float) (2.0 * F[i] / samplerate);
@ -73,22 +82,22 @@ float* EQP::eq_impulse (int N, int nfreqs, const float* F, const float* G, doubl
gp[i] = G[i]; gp[i] = G[i];
} }
for (i = 1, j = 0; i <= nfreqs; i++, j+=2) for (i = 1, j = 0; i <= _nfreqs; i++, j+=2)
{ {
sary[j + 0] = fp[i]; sary[j + 0] = fp[i];
sary[j + 1] = gp[i]; sary[j + 1] = gp[i];
} }
qsort (sary, nfreqs, 2 * sizeof (float), fEQcompare); qsort (sary, _nfreqs, 2 * sizeof (float), fEQcompare);
for (i = 1, j = 0; i <= nfreqs; i++, j+=2) for (i = 1, j = 0; i <= _nfreqs; i++, j+=2)
{ {
fp[i] = sary[j + 0]; fp[i] = sary[j + 0];
gp[i] = sary[j + 1]; gp[i] = sary[j + 1];
} }
gp[0] = gp[1]; gp[0] = gp[1];
gp[nfreqs + 1] = gp[nfreqs]; gp[_nfreqs + 1] = gp[_nfreqs];
mid = N / 2; mid = N / 2;
j = 0; j = 0;
@ -98,7 +107,7 @@ float* EQP::eq_impulse (int N, int nfreqs, const float* F, const float* G, doubl
{ {
f = (double)i / (double)mid; f = (double)i / (double)mid;
while ((f > fp[j + 1]) && (j < nfreqs)) while ((f > fp[j + 1]) && (j < _nfreqs))
j++; j++;
frac = (f - fp[j]) / (fp[j + 1] - fp[j]); frac = (f - fp[j]) / (fp[j + 1] - fp[j]);
@ -111,7 +120,7 @@ float* EQP::eq_impulse (int N, int nfreqs, const float* F, const float* G, doubl
{ {
f = ((double)i + 0.5) / (double)mid; f = ((double)i + 0.5) / (double)mid;
while ((f > fp[j + 1]) && (j < nfreqs)) while ((f > fp[j + 1]) && (j < _nfreqs))
j++; j++;
frac = (f - fp[j]) / (fp[j + 1] - fp[j]); frac = (f - fp[j]) / (fp[j + 1] - fp[j]);
@ -132,7 +141,7 @@ float* EQP::eq_impulse (int N, int nfreqs, const float* F, const float* G, doubl
if (N & 1) if (N & 1)
{ {
low = (int)(fp[1] * mid); low = (int)(fp[1] * mid);
high = (int)(fp[nfreqs] * mid + 0.5); high = (int)(fp[_nfreqs] * mid + 0.5);
lowmag = A[low]; lowmag = A[low];
highmag = A[high]; highmag = A[high];
flow4 = pow((double)low / (double)mid, 4.0); flow4 = pow((double)low / (double)mid, 4.0);
@ -160,7 +169,7 @@ float* EQP::eq_impulse (int N, int nfreqs, const float* F, const float* G, doubl
else else
{ {
low = (int)(fp[1] * mid - 0.5); low = (int)(fp[1] * mid - 0.5);
high = (int)(fp[nfreqs] * mid - 0.5); high = (int)(fp[_nfreqs] * mid - 0.5);
lowmag = A[low]; lowmag = A[low];
highmag = A[high]; highmag = A[high];
flow4 = pow((double)low / (double)mid, 4.0); flow4 = pow((double)low / (double)mid, 4.0);
@ -187,13 +196,14 @@ float* EQP::eq_impulse (int N, int nfreqs, const float* F, const float* G, doubl
} }
} }
impulse.resize(2 * N);
if (N & 1) if (N & 1)
impulse = FIR::fir_fsamp_odd(N, A.data(), 1, 1.0, wintype); FIR::fir_fsamp_odd(impulse, N, A.data(), 1, 1.0, wintype);
else else
impulse = FIR::fir_fsamp(N, A.data(), 1, 1.0, wintype); FIR::fir_fsamp(impulse, N, A.data(), 1, 1.0, wintype);
delete[] sary; delete[] sary;
return impulse;
} }
/******************************************************************************************************** /********************************************************************************************************
@ -218,7 +228,7 @@ EQP::EQP(
) )
{ {
// NOTE: 'nc' must be >= 'size' // NOTE: 'nc' must be >= 'size'
float* impulse; std::vector<float> impulse;
run = _run; run = _run;
size = _size; size = _size;
nc = _nc; nc = _nc;
@ -233,9 +243,8 @@ EQP::EQP(
ctfmode = _ctfmode; ctfmode = _ctfmode;
wintype = _wintype; wintype = _wintype;
samplerate = (double) _samplerate; samplerate = (double) _samplerate;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype); eq_impulse (impulse, nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore = new FIRCORE(size, in, out, nc, mp, impulse); fircore = new FIRCORE(size, in, out, mp, impulse);
delete[] impulse;
} }
EQP::~EQP() EQP::~EQP()
@ -265,21 +274,19 @@ void EQP::setBuffers(float* _in, float* _out)
void EQP::setSamplerate(int rate) void EQP::setSamplerate(int rate)
{ {
float* impulse; std::vector<float> impulse;
samplerate = rate; samplerate = rate;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype); eq_impulse (impulse, nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
void EQP::setSize(int _size) void EQP::setSize(int _size)
{ {
float* impulse; std::vector<float> impulse;
size = _size; size = _size;
fircore->setSize(size); fircore->setSize(size);
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype); eq_impulse (impulse, nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
/******************************************************************************************************** /********************************************************************************************************
@ -295,14 +302,13 @@ void EQP::setRun(int _run)
void EQP::setNC(int _nc) void EQP::setNC(int _nc)
{ {
float* impulse; std::vector<float> impulse;
if (nc != _nc) if (nc != _nc)
{ {
nc = _nc; nc = _nc;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype); eq_impulse (impulse, nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore->setNc(nc, impulse); fircore->setNc(impulse);
delete[] impulse;
} }
} }
@ -317,38 +323,35 @@ void EQP::setMP(int _mp)
void EQP::setProfile(int _nfreqs, const float* _F, const float* _G) void EQP::setProfile(int _nfreqs, const float* _F, const float* _G)
{ {
float* impulse; std::vector<float> impulse;
nfreqs = _nfreqs; nfreqs = _nfreqs;
F.resize(nfreqs + 1); F.resize(nfreqs + 1);
G.resize(nfreqs + 1); G.resize(nfreqs + 1);
std::copy(_F, _F + (_nfreqs + 1), F.begin()); std::copy(_F, _F + (_nfreqs + 1), F.begin());
std::copy(_G, _G + (_nfreqs + 1), G.begin()); std::copy(_G, _G + (_nfreqs + 1), G.begin());
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype); eq_impulse (impulse, nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
void EQP::setCtfmode(int _mode) void EQP::setCtfmode(int _mode)
{ {
float* impulse; std::vector<float> impulse;
ctfmode = _mode; ctfmode = _mode;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype); eq_impulse (impulse, nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
void EQP::setWintype(int _wintype) void EQP::setWintype(int _wintype)
{ {
float* impulse; std::vector<float> impulse;
wintype = _wintype; wintype = _wintype;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype); eq_impulse (impulse, nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
void EQP::setGrphEQ(const int *rxeq) void EQP::setGrphEQ(const int *rxeq)
{ // three band equalizer (legacy compatibility) { // three band equalizer (legacy compatibility)
float* impulse; std::vector<float> impulse;
nfreqs = 4; nfreqs = 4;
F.resize(nfreqs + 1); F.resize(nfreqs + 1);
G.resize(nfreqs + 1); G.resize(nfreqs + 1);
@ -362,14 +365,13 @@ void EQP::setGrphEQ(const int *rxeq)
G[3] = (float)rxeq[2]; G[3] = (float)rxeq[2];
G[4] = (float)rxeq[3]; G[4] = (float)rxeq[3];
ctfmode = 0; ctfmode = 0;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype); eq_impulse (impulse, nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
void EQP::setGrphEQ10(const int *rxeq) void EQP::setGrphEQ10(const int *rxeq)
{ // ten band equalizer (legacy compatibility) { // ten band equalizer (legacy compatibility)
float* impulse; std::vector<float> impulse;
nfreqs = 10; nfreqs = 10;
F.resize(nfreqs + 1); F.resize(nfreqs + 1);
G.resize(nfreqs + 1); G.resize(nfreqs + 1);
@ -386,9 +388,8 @@ void EQP::setGrphEQ10(const int *rxeq)
for (int i = 0; i <= nfreqs; i++) for (int i = 0; i <= nfreqs; i++)
G[i] = (float)rxeq[i]; G[i] = (float)rxeq[i];
ctfmode = 0; ctfmode = 0;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype); eq_impulse (impulse, nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
} // namespace WDSP } // namespace WDSP

View File

@ -92,7 +92,17 @@ public:
void setGrphEQ(const int *rxeq); void setGrphEQ(const int *rxeq);
void setGrphEQ10(const int *rxeq); void setGrphEQ10(const int *rxeq);
static float* eq_impulse (int N, int nfreqs, const float* F, const float* G, double samplerate, double scale, int ctfmode, int wintype); static void eq_impulse (
std::vector<float>& impulse,
int N,
int nfreqs,
const float* F,
const float* G,
double samplerate,
double scale,
int ctfmode,
int wintype
);
private: private:
static int fEQcompare (const void * a, const void * b); static int fEQcompare (const void * a, const void * b);

View File

@ -31,12 +31,11 @@ warren@wpratt.com
namespace WDSP { namespace WDSP {
float* FCurve::fc_impulse (int nc, float f0, float f1, float g0, float, int curve, float samplerate, float scale, int ctfmode, int wintype) void FCurve::fc_impulse (std::vector<float>& impulse, int nc, float f0, float f1, float g0, float, int curve, float samplerate, float scale, int ctfmode, int wintype)
{ {
float* A = new float[nc / 2 + 1]; // (float *) malloc0 ((nc / 2 + 1) * sizeof (float)); float* A = new float[nc / 2 + 1]; // (float *) malloc0 ((nc / 2 + 1) * sizeof (float));
int i; int i;
float fn, f; float fn, f;
float* impulse;
int mid = nc / 2; int mid = nc / 2;
float g0_lin = pow(10.0, g0 / 20.0); float g0_lin = pow(10.0, g0 / 20.0);
if (nc & 1) if (nc & 1)
@ -140,22 +139,21 @@ float* FCurve::fc_impulse (int nc, float f0, float f1, float g0, float, int curv
} }
} }
} }
if (nc & 1) if (nc & 1)
impulse = FIR::fir_fsamp_odd(nc, A, 1, 1.0, wintype); FIR::fir_fsamp_odd(impulse, nc, A, 1, 1.0, wintype);
else else
impulse = FIR::fir_fsamp(nc, A, 1, 1.0, wintype); FIR::fir_fsamp(impulse, nc, A, 1, 1.0, wintype);
// print_impulse ("emph.txt", size + 1, impulse, 1, 0); // print_impulse ("emph.txt", size + 1, impulse, 1, 0);
delete[] (A); delete[] (A);
return impulse;
} }
// generate mask for Overlap-Save Filter // generate mask for Overlap-Save Filter
float* FCurve::fc_mults (int size, float f0, float f1, float g0, float g1, int curve, float samplerate, float scale, int ctfmode, int wintype) void FCurve::fc_mults (std::vector<float>& mults, int size, float f0, float f1, float g0, float g1, int curve, float samplerate, float scale, int ctfmode, int wintype)
{ {
float* impulse = fc_impulse (size + 1, f0, f1, g0, g1, curve, samplerate, scale, ctfmode, wintype); std::vector<float> impulse(2 * (size + 1));
float* mults = FIR::fftcv_mults(2 * size, impulse); fc_impulse (impulse, size + 1, f0, f1, g0, g1, curve, samplerate, scale, ctfmode, wintype);
delete[] (impulse); FIR::fftcv_mults(mults, 2 * size, impulse.data());
return mults;
} }
} // namespace WDSP } // namespace WDSP

View File

@ -28,6 +28,8 @@ warren@wpratt.com
#ifndef wdsp_fcurve_h #ifndef wdsp_fcurve_h
#define wdsp_fcurve_h #define wdsp_fcurve_h
#include <vector>
#include "export.h" #include "export.h"
namespace WDSP { namespace WDSP {
@ -35,8 +37,8 @@ namespace WDSP {
class WDSP_API FCurve class WDSP_API FCurve
{ {
public: public:
static float* fc_impulse (int nc, float f0, float f1, float g0, float g1, int curve, float samplerate, float scale, int ctfmode, int wintype); static void fc_impulse (std::vector<float>& impulse, int nc, float f0, float f1, float g0, float g1, int curve, float samplerate, float scale, int ctfmode, int wintype);
static float* fc_mults (int size, float f0, float f1, float g0, float g1, int curve, float samplerate, float scale, int ctfmode, int wintype); static void fc_mults (std::vector<float>& mults, int size, float f0, float f1, float g0, float g1, int curve, float samplerate, float scale, int ctfmode, int wintype);
}; };
} // namespace WDSP } // namespace WDSP

View File

@ -35,14 +35,14 @@ warren@pratt.one
namespace WDSP { namespace WDSP {
float* FIR::fftcv_mults (int NM, float* c_impulse) void FIR::fftcv_mults (std::vector<float>& mults, int NM, const float* c_impulse)
{ {
auto mults = new float[NM * 2]; mults.resize(NM * 2);
std::vector<float> cfft_impulse(NM * 2); std::vector<float> cfft_impulse(NM * 2);
fftwf_plan ptmp = fftwf_plan_dft_1d( fftwf_plan ptmp = fftwf_plan_dft_1d(
NM, NM,
(fftwf_complex *) cfft_impulse.data(), (fftwf_complex *) cfft_impulse.data(),
(fftwf_complex *) mults, (fftwf_complex *) mults.data(),
FFTW_FORWARD, FFTW_FORWARD,
FFTW_PATIENT FFTW_PATIENT
); );
@ -51,14 +51,13 @@ float* FIR::fftcv_mults (int NM, float* c_impulse)
std::copy(c_impulse, c_impulse + (NM / 2 + 1) * 2, &(cfft_impulse[NM - 2])); std::copy(c_impulse, c_impulse + (NM / 2 + 1) * 2, &(cfft_impulse[NM - 2]));
fftwf_execute (ptmp); fftwf_execute (ptmp);
fftwf_destroy_plan (ptmp); fftwf_destroy_plan (ptmp);
return mults;
} }
float* FIR::get_fsamp_window(int N, int wintype) void FIR::get_fsamp_window(std::vector<float>& window, int N, int wintype)
{ {
double arg0; double arg0;
double arg1; double arg1;
auto window = new float[N]; window.resize(N);
switch (wintype) switch (wintype)
{ {
case 0: case 0:
@ -92,20 +91,18 @@ float* FIR::get_fsamp_window(int N, int wintype)
for (int i = 0; i < N; i++) for (int i = 0; i < N; i++)
window[i] = 1.0; window[i] = 1.0;
} }
return window;
} }
float* FIR::fir_fsamp_odd (int N, const float* A, int rtype, double scale, int wintype) void FIR::fir_fsamp_odd (std::vector<float>& c_impulse, int N, const float* A, int rtype, double scale, int wintype)
{ {
int mid = (N - 1) / 2; int mid = (N - 1) / 2;
double mag; double mag;
double phs; double phs;
std::vector<float> fcoef(N * 2); std::vector<float> fcoef(N * 2);
auto *c_impulse = new float[N * 2];
fftwf_plan ptmp = fftwf_plan_dft_1d( fftwf_plan ptmp = fftwf_plan_dft_1d(
N, N,
(fftwf_complex *)fcoef.data(), (fftwf_complex *)fcoef.data(),
(fftwf_complex *)c_impulse, (fftwf_complex *)c_impulse.data(),
FFTW_BACKWARD, FFTW_BACKWARD,
FFTW_PATIENT FFTW_PATIENT
); );
@ -124,7 +121,8 @@ float* FIR::fir_fsamp_odd (int N, const float* A, int rtype, double scale, int w
} }
fftwf_execute (ptmp); fftwf_execute (ptmp);
fftwf_destroy_plan (ptmp); fftwf_destroy_plan (ptmp);
float* window = get_fsamp_window(N, wintype); std::vector<float> window;
get_fsamp_window(window, N, wintype);
switch (rtype) switch (rtype)
{ {
case 0: case 0:
@ -141,14 +139,11 @@ float* FIR::fir_fsamp_odd (int N, const float* A, int rtype, double scale, int w
default: default:
break; break;
} }
delete[] window;
return c_impulse;
} }
float* FIR::fir_fsamp (int N, const float* A, int rtype, double scale, int wintype) void FIR::fir_fsamp (std::vector<float>& c_impulse, int N, const float* A, int rtype, double scale, int wintype)
{ {
double sum; double sum;
auto c_impulse = new float[N * 2];
if (N & 1) if (N & 1)
{ {
@ -184,7 +179,8 @@ float* FIR::fir_fsamp (int N, const float* A, int rtype, double scale, int winty
c_impulse[2 * n + 1] = 0.0; c_impulse[2 * n + 1] = 0.0;
} }
} }
float* window = get_fsamp_window (N, wintype); std::vector<float> window;
get_fsamp_window (window, N, wintype);
switch (rtype) switch (rtype)
{ {
case 0: case 0:
@ -201,13 +197,11 @@ float* FIR::fir_fsamp (int N, const float* A, int rtype, double scale, int winty
default: default:
break; break;
} }
delete[] window;
return c_impulse;
} }
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 = (f_high - f_low) / (2.0 * samplerate);
double ft_rad = TWOPI * ft; double ft_rad = TWOPI * ft;
double w_osc = PI * (f_high + f_low) / samplerate; double w_osc = PI * (f_high + f_low) / samplerate;
@ -279,10 +273,9 @@ float* FIR::fir_bandpass (int N, double f_low, double f_high, double samplerate,
break; break;
} }
} }
return c_impulse;
} }
float *FIR::fir_read (int N, const char *filename, int rtype, float scale) void FIR::fir_read (std::vector<float>& c_impulse, int N, const char *filename, int rtype, float scale)
// N = number of real or complex coefficients (see rtype) // N = number of real or complex coefficients (see rtype)
// *filename = filename // *filename = filename
// rtype = 0: real coefficients // rtype = 0: real coefficients
@ -294,12 +287,12 @@ float *FIR::fir_read (int N, const char *filename, int rtype, float scale)
FILE *file; FILE *file;
float I; float I;
float Q; float Q;
auto c_impulse = new float[N * 2]; c_impulse.resize(N * 2);
std::fill(c_impulse, c_impulse + N*2, 0); std::fill(c_impulse.begin(), c_impulse.end(), 0);
file = fopen (filename, "r"); file = fopen (filename, "r");
if (!file) { if (!file) {
return c_impulse; return;
} }
for (int i = 0; i < N; i++) for (int i = 0; i < N; i++)
@ -330,7 +323,6 @@ float *FIR::fir_read (int N, const char *filename, int rtype, float scale)
} }
} }
fclose (file); fclose (file);
return c_impulse;
} }
void FIR::analytic (int N, float* in, float* out) void FIR::analytic (int N, float* in, float* out)
@ -435,7 +427,7 @@ void FIR::mp_imp (int N, std::vector<float>& fir, std::vector<float>& mpfir, int
// impulse response of a zero frequency filter comprising a cascade of two resonators, // impulse response of a zero frequency filter comprising a cascade of two resonators,
// each followed by a detrending filter // each followed by a detrending filter
float* FIR::zff_impulse(int nc, float scale) void FIR::zff_impulse(std::vector<float>& c_dresdet, int nc, float scale)
{ {
// nc = number of coefficients (power of two) // nc = number of coefficients (power of two)
int n_resdet = nc / 2 - 1; // size of single zero-frequency resonator with detrender int n_resdet = nc / 2 - 1; // size of single zero-frequency resonator with detrender
@ -449,7 +441,7 @@ float* FIR::zff_impulse(int nc, float scale)
// allocate the float and complex versions and make the values // allocate the float and complex versions and make the values
std::vector<float> dresdet(n_dresdet); std::vector<float> dresdet(n_dresdet);
auto div = (float) ((nc / 2 + 1) * (nc / 2 + 1)); // calculate divisor auto div = (float) ((nc / 2 + 1) * (nc / 2 + 1)); // calculate divisor
auto c_dresdet = new float[nc * 2]; c_dresdet.resize(nc * 2);
for (int n = 0; n < n_dresdet; n++) // convolve to make the cascade for (int n = 0; n < n_dresdet; n++) // convolve to make the cascade
{ {
for (int k = 0; k < n_resdet; k++) for (int k = 0; k < n_resdet; k++)
@ -459,8 +451,6 @@ float* FIR::zff_impulse(int nc, float scale)
c_dresdet[2 * n + 0] = dresdet[n] * scale; c_dresdet[2 * n + 0] = dresdet[n] * scale;
c_dresdet[2 * n + 1] = 0.0; c_dresdet[2 * n + 1] = 0.0;
} }
return c_dresdet;
} }
} // namespace WDSP } // namespace WDSP

View File

@ -36,17 +36,17 @@ namespace WDSP {
class WDSP_API FIR class WDSP_API FIR
{ {
public: public:
static float* fftcv_mults (int NM, float* c_impulse); static void fftcv_mults (std::vector<float>& mults, int NM, const float* impulse);
static float* fir_fsamp_odd (int N, const float* A, int rtype, double scale, int wintype); static void fir_fsamp_odd (std::vector<float>& c_impulse, int N, const float* A, int rtype, double scale, int wintype);
static float* fir_fsamp (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); static void mp_imp (int N, std::vector<float>& fir, std::vector<float>& mpfir, int pfactor, int polarity);
private: private:
static void analytic (int N, float* in, float* out); static void analytic (int N, float* in, float* out);
static float* get_fsamp_window(int N, int wintype); static void get_fsamp_window(std::vector<float>& window, int N, int wintype);
static float *fir_read (int N, const char *filename, int rtype, float scale); static void fir_read (std::vector<float>& impulse, int N, const char *filename, int rtype, float scale);
static float* zff_impulse(int nc, float scale); static void zff_impulse(std::vector<float>& impulse, int nc, float scale);
}; };
#endif #endif

View File

@ -99,7 +99,7 @@ void FIRCORE::calc(int _flip)
if (mp) if (mp)
FIR::mp_imp (nc, impulse, imp, 16, 0); FIR::mp_imp (nc, impulse, imp, 16, 0);
else else
std::copy(impulse.begin(), impulse.begin() + nc * 2, imp.begin()); std::copy(impulse.begin(), impulse.end(), imp.begin());
for (int i = 0; i < nfor; i++) for (int i = 0; i < nfor; i++)
{ {
@ -122,20 +122,19 @@ FIRCORE::FIRCORE(
int _size, int _size,
float* _in, float* _in,
float* _out, float* _out,
int _nc,
int _mp, int _mp,
float* _impulse const std::vector<float>& _impulse
) )
{ {
size = _size; size = _size;
in = _in; in = _in;
out = _out; out = _out;
nc = _nc; nc = (int) (_impulse.size() / 2);
mp = _mp; mp = _mp;
plan(); plan();
impulse.resize(nc * 2); impulse.resize(_impulse.size());
imp.resize(nc * 2); imp.resize(_impulse.size());
std::copy(_impulse, _impulse + nc * 2, impulse.begin()); std::copy(_impulse.begin(), _impulse.end(), impulse.begin());
calc(1); calc(1);
} }
@ -204,21 +203,29 @@ void FIRCORE::setSize(int _size)
calc(1); calc(1);
} }
void FIRCORE::setImpulse(float* _impulse, int _update) void FIRCORE::setImpulse(const std::vector<float>& _impulse, int _update)
{ {
std::copy(_impulse, _impulse + nc * 2, impulse.begin()); auto imp_nc = (int) (_impulse.size() / 2);
calc(_update);
if (imp_nc == nc) // to be on the safe side but setNc would be called if impulse size changes
{
std::copy(_impulse.begin(), _impulse.end(), impulse.begin());
calc(_update);
}
else{
setNc(_impulse);
}
} }
void FIRCORE::setNc(int _nc, float* _impulse) void FIRCORE::setNc(const std::vector<float>& _impulse)
{ {
// because of FFT planning, this will probably cause a glitch in audio if done during dataflow // because of FFT planning, this will probably cause a glitch in audio if done during dataflow
deplan(); deplan();
nc = _nc; nc = (int) (_impulse.size() / 2);
plan(); plan();
imp.resize(nc * 2); imp.resize(nc * 2);
impulse.resize(nc * 2); impulse.resize(nc * 2);
std::copy(_impulse, _impulse + nc * 2, impulse.begin()); std::copy(_impulse.begin(), _impulse.end(), impulse.begin());
calc(1); calc(1);
} }

View File

@ -70,10 +70,8 @@ public:
int size, int size,
float* in, float* in,
float* out, float* out,
int nc,
int mp, int mp,
float* const std::vector<float>& impulse
impulse
); );
FIRCORE(const FIRCORE&) = delete; FIRCORE(const FIRCORE&) = delete;
FIRCORE& operator=(const FIRCORE& other) = delete; FIRCORE& operator=(const FIRCORE& other) = delete;
@ -83,8 +81,8 @@ public:
void execute(); void execute();
void setBuffers(float* in, float* out); void setBuffers(float* in, float* out);
void setSize(int size); void setSize(int size);
void setImpulse(float* impulse, int update); void setImpulse(const std::vector<float>& impulse, int update);
void setNc(int nc, float* impulse); void setNc(const std::vector<float>& impulse);
void setMp(int mp); void setMp(int mp);
void setUpdate(); void setUpdate();

View File

@ -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); FIR::fir_bandpass (h, nc, f_low, f_high, samplerate, wintype, 1, gain);
a->rsize = a->nc; rsize = nc;
a->mask = a->rsize - 1; mask = rsize - 1;
a->ring = new float[a->rsize * 2]; // (float *) malloc0 (a->rsize * sizeof (complex)); ring.resize(rsize * 2);
a->idx = 0; idx = 0;
} }
FIRMIN* FIRMIN::create_firmin (int run, int position, int size, float* in, float* out, FIRMIN::FIRMIN(
int nc, float f_low, float f_high, int samplerate, int wintype, float gain) 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; run = _run;
a->run = run; position = _position;
a->position = position; size = _size;
a->size = size; in = _in;
a->in = in; out = _out;
a->out = out; nc = _nc;
a->nc = nc; f_low = _f_low;
a->f_low = f_low; f_high = _f_high;
a->f_high = f_high; samplerate = (float) _samplerate;
a->samplerate = samplerate; wintype = _wintype;
a->wintype = wintype; gain = _gain;
a->gain = gain; calc();
calc_firmin (a);
return a;
} }
void FIRMIN::destroy_firmin (FIRMIN *a) void FIRMIN::flush()
{ {
delete[] (a->ring); std::fill(ring.begin(), ring.end(), 0);
delete[] (a->h); idx = 0;
delete (a);
} }
void FIRMIN::flush_firmin (FIRMIN *a) void FIRMIN::execute(int _pos)
{ {
std::fill(a->ring, a->ring + a->rsize * 2, 0); if (run && position == _pos)
a->idx = 0;
}
void FIRMIN::xfirmin (FIRMIN *a, int pos)
{
if (a->run && a->position == pos)
{ {
int i, j, k; int k;
for (i = 0; i < a->size; i++) for (int i = 0; i < size; i++)
{ {
a->ring[2 * a->idx + 0] = a->in[2 * i + 0]; ring[2 * idx + 0] = in[2 * i + 0];
a->ring[2 * a->idx + 1] = a->in[2 * i + 1]; ring[2 * idx + 1] = in[2 * i + 1];
a->out[2 * i + 0] = 0.0; out[2 * i + 0] = 0.0;
a->out[2 * i + 1] = 0.0; out[2 * i + 1] = 0.0;
k = a->idx; k = idx;
for (j = 0; j < a->nc; j++) 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]; out[2 * i + 0] += h[2 * j + 0] * ring[2 * k + 0] - h[2 * j + 1] * 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]; out[2 * i + 1] += h[2 * j + 0] * ring[2 * k + 1] + h[2 * j + 1] * ring[2 * k + 0];
k = (k + a->mask) & a->mask; k = (k + mask) & mask;
} }
a->idx = (a->idx + 1) & a->mask; idx = (idx + 1) & mask;
} }
} }
else if (a->in != a->out) else if (in != out)
std::copy( a->in, a->in + a->size * 2, a->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; in = _in;
a->out = out; out = _out;
} }
void FIRMIN::setSamplerate_firmin (FIRMIN *a, int rate) void FIRMIN::setSamplerate(int _rate)
{ {
a->samplerate = (float)rate; samplerate = (float) _rate;
calc_firmin (a); 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; f_low = _f_low;
a->f_high = f_high; f_high = _f_high;
calc_firmin (a); calc();
} }
} // namespace WDSP } // namespace WDSP

View File

@ -34,6 +34,8 @@ warren@wpratt.com
#ifndef wdsp_firmin_h #ifndef wdsp_firmin_h
#define wdsp_firmin_h #define wdsp_firmin_h
#include <vector>
#include "fftw3.h" #include "fftw3.h"
#include "export.h" #include "export.h"
@ -50,8 +52,8 @@ public:
int nc; // number of filter coefficients, power of two int nc; // number of filter coefficients, power of two
float f_low; // low cutoff frequency float f_low; // low cutoff frequency
float f_high; // high cutoff frequency float f_high; // high cutoff frequency
float* ring; // internal complex ring buffer std::vector<float> ring; // internal complex ring buffer
float* h; // complex filter coefficients std::vector<float> h; // complex filter coefficients
int rsize; // ring size, number of complex samples, power of two int rsize; // ring size, number of complex samples, power of two
int mask; // mask to update indexes int mask; // mask to update indexes
int idx; // ring input/output index int idx; // ring input/output index
@ -59,18 +61,32 @@ public:
int wintype; // filter window type int wintype; // filter window type
float gain; // filter gain float gain; // filter gain
static FIRMIN* create_firmin (int run, int position, int size, float* in, float* out, FIRMIN(
int nc, float f_low, float f_high, int samplerate, int wintype, float gain); int run,
static void destroy_firmin (FIRMIN *a); int position,
static void flush_firmin (FIRMIN *a); int size,
static void xfirmin (FIRMIN *a, int pos); float* in,
static void setBuffers_firmin (FIRMIN *a, float* in, float* out); float* out,
static void setSamplerate_firmin (FIRMIN *a, int rate); int nc,
static void setSize_firmin (FIRMIN *a, int size); float f_low,
static void setFreqs_firmin (FIRMIN *a, float f_low, float f_high); 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: private:
static void calc_firmin (FIRMIN *a); void calc();
}; };
} // namespace WDSP } // namespace WDSP

View File

@ -37,174 +37,169 @@ namespace WDSP {
* * * *
********************************************************************************************************/ ********************************************************************************************************/
void FIROPT::plan_firopt (FIROPT *a) void FIROPT::plan()
{ {
// must call for change in 'nc', 'size', 'out' // must call for change in 'nc', 'size', 'out'
int i; nfor = nc / size;
a->nfor = a->nc / a->size; buffidx = 0;
a->buffidx = 0; idxmask = nfor - 1;
a->idxmask = a->nfor - 1; fftin.resize(2 * size * 2);
a->fftin = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex)); fftout.resize(nfor);
a->fftout = new float*[a->nfor]; // (float **) malloc0 (a->nfor * sizeof (float *)); fmask.resize(nfor);
a->fmask = new float*[a->nfor]; // (float **) malloc0 (a->nfor * sizeof (float *)); maskgen.resize(2 * size * 2);
a->maskgen = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex)); pcfor.resize(nfor);
a->pcfor = new fftwf_plan[a->nfor]; // (fftwf_plan *) malloc0 (a->nfor * sizeof (fftwf_plan)); maskplan.resize(nfor);
a->maskplan = new fftwf_plan[a->nfor]; // (fftwf_plan *) malloc0 (a->nfor * sizeof (fftwf_plan)); for (int i = 0; i < nfor; i++)
for (i = 0; i < a->nfor; i++)
{ {
a->fftout[i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex)); fftout[i].resize(2 * size * 2);
a->fmask[i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex)); fmask[i].resize(2 * size * 2);
a->pcfor[i] = fftwf_plan_dft_1d( pcfor[i] = fftwf_plan_dft_1d(
2 * a->size, 2 * size,
(fftwf_complex *)a->fftin, (fftwf_complex *)fftin.data(),
(fftwf_complex *)a->fftout[i], (fftwf_complex *)fftout[i].data(),
FFTW_FORWARD, FFTW_FORWARD,
FFTW_PATIENT FFTW_PATIENT
); );
a->maskplan[i] = fftwf_plan_dft_1d( maskplan[i] = fftwf_plan_dft_1d(
2 * a->size, 2 * size,
(fftwf_complex *)a->maskgen, (fftwf_complex *)maskgen.data(),
(fftwf_complex *)a->fmask[i], (fftwf_complex *)fmask[i].data(),
FFTW_FORWARD, FFTW_FORWARD,
FFTW_PATIENT FFTW_PATIENT
); );
} }
a->accum = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex)); accum.resize(2 * size * 2);
a->crev = fftwf_plan_dft_1d( crev = fftwf_plan_dft_1d(
2 * a->size, 2 * size,
(fftwf_complex *)a->accum, (fftwf_complex *)accum.data(),
(fftwf_complex *)a->out, (fftwf_complex *)out,
FFTW_BACKWARD, FFTW_BACKWARD,
FFTW_PATIENT FFTW_PATIENT
); );
} }
void FIROPT::calc_firopt (FIROPT *a) void FIROPT::calc()
{ {
// call for change in frequency, rate, wintype, gain // call for change in frequency, rate, wintype, gain
// must also call after a call to plan_firopt() // must also call after a call to plan_firopt()
int i; std::vector<float> impulse;
float* impulse = FIR::fir_bandpass (a->nc, a->f_low, a->f_high, a->samplerate, a->wintype, 1, a->gain); FIR::fir_bandpass (impulse, nc, f_low, f_high, samplerate, wintype, 1, gain);
a->buffidx = 0; buffidx = 0;
for (i = 0; i < a->nfor; i++) for (int i = 0; i < nfor; i++)
{ {
// I right-justified the impulse response => take output from left side of output buff, discard right side // 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. // 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])); std::copy(&(impulse[2 * size * i]), &(impulse[2 * size * i]) + size * 2, &(maskgen[2 * size]));
fftwf_execute (a->maskplan[i]); fftwf_execute (maskplan[i]);
} }
delete[] (impulse);
} }
FIROPT* FIROPT::create_firopt (int run, int position, int size, float* in, float* out, FIROPT::FIROPT(
int nc, float f_low, float f_high, int samplerate, int wintype, float gain) int _run,
int _position,
int _size,
float* _in,
float* _out,
int _nc,
float _f_low,
float _f_high,
int _samplerate,
int _wintype,
float _gain
)
{ {
FIROPT *a = new FIROPT; run = _run;
a->run = run; position = _position;
a->position = position; size = _size;
a->size = size; in = _in;
a->in = in; out = _out;
a->out = out; nc = _nc;
a->nc = nc; f_low = _f_low;
a->f_low = f_low; f_high = _f_high;
a->f_high = f_high; samplerate = (float) _samplerate;
a->samplerate = samplerate; wintype = _wintype;
a->wintype = wintype; gain = _gain;
a->gain = gain; plan();
plan_firopt (a); calc();
calc_firopt (a);
return a;
} }
void FIROPT::deplan_firopt (FIROPT *a) void FIROPT::deplan()
{ {
int i; fftwf_destroy_plan (crev);
fftwf_destroy_plan (a->crev); for (int i = 0; i < nfor; i++)
delete[] (a->accum);
for (i = 0; i < a->nfor; i++)
{ {
delete[] (a->fftout[i]); fftwf_destroy_plan (pcfor[i]);
delete[] (a->fmask[i]); fftwf_destroy_plan (maskplan[i]);
fftwf_destroy_plan (a->pcfor[i]);
fftwf_destroy_plan (a->maskplan[i]);
} }
delete[] (a->maskplan);
delete[] (a->pcfor);
delete[] (a->maskgen);
delete[] (a->fmask);
delete[] (a->fftout);
delete[] (a->fftin);
} }
void FIROPT::destroy_firopt (FIROPT *a) FIROPT::~FIROPT()
{ {
deplan_firopt (a); deplan();
delete (a);
} }
void FIROPT::flush_firopt (FIROPT *a) void FIROPT::flush()
{ {
int i; std::fill(fftin.begin(), fftin.end(), 0);
std::fill(a->fftin, a->fftin + 2 * a->size * 2, 0); for (int i = 0; i < nfor; i++)
for (i = 0; i < a->nfor; i++) std::fill(fftout[i].begin(), fftout[i].end(), 0);
std::fill(a->fftout[i], a->fftout[i] + 2 * a->size * 2, 0); buffidx = 0;
a->buffidx = 0;
} }
void FIROPT::xfiropt (FIROPT *a, int pos) void FIROPT::execute(int pos)
{ {
if (a->run && (a->position == pos)) if (run && (position == pos))
{ {
int i, j, k; int k;
std::copy(a->in, a->in + a->size * 2, &(a->fftin[2 * a->size])); std::copy(in, in + size * 2, &(fftin[2 * size]));
fftwf_execute (a->pcfor[a->buffidx]); fftwf_execute (pcfor[buffidx]);
k = a->buffidx; k = buffidx;
std::fill(a->accum, a->accum + 2 * a->size * 2, 0); std::fill(accum.begin(), accum.end(), 0);
for (j = 0; j < a->nfor; j++) for (int j = 0; j < nfor; j++)
{ {
for (i = 0; i < 2 * a->size; i++) for (int i = 0; i < 2 * 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]; accum[2 * i + 0] += fftout[k][2 * i + 0] * fmask[j][2 * i + 0] - fftout[k][2 * i + 1] * 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]; accum[2 * i + 1] += fftout[k][2 * i + 0] * fmask[j][2 * i + 1] + fftout[k][2 * i + 1] * fmask[j][2 * i + 0];
} }
k = (k + a->idxmask) & a->idxmask; k = (k + idxmask) & idxmask;
} }
a->buffidx = (a->buffidx + 1) & a->idxmask; buffidx = (buffidx + 1) & idxmask;
fftwf_execute (a->crev); fftwf_execute (crev);
std::copy(&(a->fftin[2 * a->size]), &(a->fftin[2 * a->size]) + a->size * 2, a->fftin); std::copy(&(fftin[2 * size]), &(fftin[2 * size]) + size * 2, fftin.begin());
} }
else if (a->in != a->out) else if (in != out)
std::copy( a->in, a->in + a->size * 2, a->out); std::copy( in, in + size * 2, out);
} }
void FIROPT::setBuffers_firopt (FIROPT *a, float* in, float* out) void FIROPT::setBuffers(float* _in, float* _out)
{ {
a->in = in; in = _in;
a->out = out; out = _out;
deplan_firopt (a); deplan();
plan_firopt (a); plan();
calc_firopt (a); calc();
} }
void FIROPT::setSamplerate_firopt (FIROPT *a, int rate) void FIROPT::setSamplerate(int _rate)
{ {
a->samplerate = rate; samplerate = (float) _rate;
calc_firopt (a); calc();
} }
void FIROPT::setSize_firopt (FIROPT *a, int size) void FIROPT::setSize(int _size)
{ {
a->size = size; size = _size;
deplan_firopt (a); deplan();
plan_firopt (a); plan();
calc_firopt (a); calc();
} }
void FIROPT::setFreqs_firopt (FIROPT *a, float f_low, float f_high) void FIROPT::setFreqs(float _f_low, float _f_high)
{ {
a->f_low = f_low; f_low = _f_low;
a->f_high = f_high; f_high = _f_high;
calc_firopt (a); calc();
} }

View File

@ -34,6 +34,8 @@ warren@wpratt.com
#ifndef wdsp_firopt_h #ifndef wdsp_firopt_h
#define wdsp_firopt_h #define wdsp_firopt_h
#include <vector>
#include "fftw3.h" #include "fftw3.h"
#include "export.h" #include "export.h"
@ -41,6 +43,7 @@ namespace WDSP {
class WDSP_API FIROPT class WDSP_API FIROPT
{ {
public:
int run; // run control int run; // run control
int position; // position at which to execute int position; // position at which to execute
int size; // input/output buffer size, power of two int size; // input/output buffer size, power of two
@ -53,31 +56,46 @@ class WDSP_API FIROPT
int wintype; // filter window type int wintype; // filter window type
float gain; // filter gain float gain; // filter gain
int nfor; // number of buffers in delay line int nfor; // number of buffers in delay line
float* fftin; // fft input buffer std::vector<float> fftin; // fft input buffer
float** fmask; // frequency domain masks std::vector<std::vector<float>> fmask; // frequency domain masks
float** fftout; // fftout delay line std::vector<std::vector<float>> fftout; // fftout delay line
float* accum; // frequency domain accumulator std::vector<float> accum; // frequency domain accumulator
int buffidx; // fft out buffer index int buffidx; // fft out buffer index
int idxmask; // mask for index computations int idxmask; // mask for index computations
float* maskgen; // input for mask generation FFT std::vector<float> maskgen; // input for mask generation FFT
fftwf_plan* pcfor; // array of forward FFT plans std::vector<fftwf_plan> pcfor; // array of forward FFT plans
fftwf_plan crev; // reverse fft plan fftwf_plan crev; // reverse fft plan
fftwf_plan* maskplan; // plans for frequency domain masks std::vector<fftwf_plan> maskplan; // plans for frequency domain masks
static FIROPT* create_firopt (int run, int position, int size, float* in, float* out, FIROPT(
int nc, float f_low, float f_high, int samplerate, int wintype, float gain); int run,
static void xfiropt (FIROPT *a, int pos); int position,
static void destroy_firopt (FIROPT *a); int size,
static void flush_firopt (FIROPT *a); float* in,
static void setBuffers_firopt (FIROPT *a, float* in, float* out); float* out,
static void setSamplerate_firopt (FIROPT *a, int rate); int nc,
static void setSize_firopt (FIROPT *a, int size); float f_low,
static void setFreqs_firopt (FIROPT *a, float f_low, float f_high); float f_high,
int samplerate,
int wintype,
float gain
);
FIROPT(const FIROPT&) = delete;
FIROPT& operator=(const FIROPT& other) = delete;
~FIROPT();
void destroy();
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: private:
static void plan_firopt (FIROPT *a); void plan();
static void calc_firopt (FIROPT *a); void calc();
static void deplan_firopt (FIROPT *a); void deplan();
}; };
} // namespace WDSP } // namespace WDSP

View File

@ -143,11 +143,12 @@ FMD::FMD(
lim_gain(0.0001), // 2.5 lim_gain(0.0001), // 2.5
lim_pre_gain(0.01) // 0.4 lim_pre_gain(0.01) // 0.4
{ {
float* impulse;
calc(); calc();
// de-emphasis filter // de-emphasis filter
audio.resize(size * 2); audio.resize(size * 2);
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc_de);
FCurve::fc_impulse (
impulse,
nc_de, nc_de,
(float) f_low, (float) f_low,
(float) f_high, (float) f_high,
@ -158,18 +159,17 @@ FMD::FMD(
0, 0,
0 0
); );
pde = new FIRCORE(size, audio.data(), out, nc_de, mp_de, impulse); pde = new FIRCORE(size, audio.data(), out, mp_de, impulse);
delete[] impulse;
// audio filter // audio filter
impulse = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); std::vector<float> impulseb;
paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulse); FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
delete[] impulse; paud = new FIRCORE(size, out, out, mp_aud, impulseb);
} }
FMD::~FMD() FMD::~FMD()
{ {
delete (paud); delete paud;
delete (pde); delete pde;
decalc(); decalc();
} }
@ -248,12 +248,13 @@ void FMD::setBuffers(float* _in, float* _out)
void FMD::setSamplerate(int _rate) void FMD::setSamplerate(int _rate)
{ {
float* impulse;
decalc(); decalc();
rate = _rate; rate = _rate;
calc(); calc();
// de-emphasis filter // de-emphasis filter
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc_de);
FCurve::fc_impulse (
impulse,
nc_de, nc_de,
(float) f_low, (float) f_low,
(float) f_high, (float) f_high,
@ -266,24 +267,24 @@ void FMD::setSamplerate(int _rate)
0 0
); );
pde->setImpulse(impulse, 1); pde->setImpulse(impulse, 1);
delete[] impulse;
// audio filter // audio filter
impulse = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); std::vector<float> impulseb;
paud->setImpulse(impulse, 1); FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
delete[] impulse; paud->setImpulse(impulseb, 1);
plim->setSamplerate((int) rate); plim->setSamplerate((int) rate);
} }
void FMD::setSize(int _size) void FMD::setSize(int _size)
{ {
float* impulse;
decalc(); decalc();
size = _size; size = _size;
calc(); calc();
audio.resize(size * 2); audio.resize(size * 2);
// de-emphasis filter // de-emphasis filter
delete (pde); delete pde;
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc_de);
FCurve::fc_impulse (
impulse,
nc_de, nc_de,
(float) f_low, (float) f_low,
(float) f_high, (float) f_high,
@ -295,13 +296,12 @@ void FMD::setSize(int _size)
0, 0,
0 0
); );
pde = new FIRCORE(size, audio.data(), out, nc_de, mp_de, impulse); pde = new FIRCORE(size, audio.data(), out, mp_de, impulse);
delete[] impulse;
// audio filter // audio filter
delete (paud); delete paud;
impulse = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); std::vector<float> impulseb;
paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulse); FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
delete[] impulse; paud = new FIRCORE(size, out, out, mp_aud, impulseb);
plim->setSize(size); plim->setSize(size);
} }
@ -331,12 +331,12 @@ void FMD::setCTCSSRun(int _run)
void FMD::setNCde(int nc) void FMD::setNCde(int nc)
{ {
float* impulse;
if (nc_de != nc) if (nc_de != nc)
{ {
nc_de = nc; nc_de = nc;
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc_de);
FCurve::fc_impulse (
impulse,
nc_de, nc_de,
(float) f_low, (float) f_low,
(float) f_high, (float) f_high,
@ -348,8 +348,7 @@ void FMD::setNCde(int nc)
0, 0,
0 0
); );
pde->setNc(nc_de, impulse); pde->setNc(impulse);
delete[] impulse;
} }
} }
@ -364,14 +363,12 @@ void FMD::setMPde(int mp)
void FMD::setNCaud(int nc) void FMD::setNCaud(int nc)
{ {
float* impulse;
if (nc_aud != nc) if (nc_aud != nc)
{ {
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)); std::vector<float> impulse;
paud->setNc(nc_aud, impulse); FIR::fir_bandpass(impulse, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
delete[] impulse; paud->setNc(impulse);
} }
} }
@ -405,14 +402,14 @@ void FMD::setLimGain(double gaindB)
void FMD::setAFFilter(double low, double high) void FMD::setAFFilter(double low, double high)
{ {
float* impulse;
if (f_low != low || f_high != high) if (f_low != low || f_high != high)
{ {
f_low = low; f_low = low;
f_high = high; f_high = high;
// de-emphasis filter // de-emphasis filter
impulse = FCurve::fc_impulse ( std::vector<float> impulse(2 * nc_de);
FCurve::fc_impulse (
impulse,
nc_de, nc_de,
(float) f_low, (float) f_low,
(float) f_high, (float) f_high,
@ -425,11 +422,10 @@ void FMD::setAFFilter(double low, double high)
0 0
); );
pde->setImpulse(impulse, 1); pde->setImpulse(impulse, 1);
delete[] impulse;
// audio filter // audio filter
impulse = FIR::fir_bandpass (nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); std::vector<float> impulseb;
paud->setImpulse(impulse, 1); FIR::fir_bandpass (impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
delete[] impulse; paud->setImpulse(impulseb, 1);
} }
} }

View File

@ -25,6 +25,8 @@ warren@wpratt.com
*/ */
#include <vector>
#include "comm.hpp" #include "comm.hpp"
#include "fircore.hpp" #include "fircore.hpp"
#include "fir.hpp" #include "fir.hpp"
@ -63,7 +65,7 @@ FMMOD::FMMOD(
int _mp int _mp
) )
{ {
float* impulse; std::vector<float> impulse;
run = _run; run = _run;
size = _size; size = _size;
in = _in; in = _in;
@ -79,9 +81,8 @@ FMMOD::FMMOD(
nc = _nc; nc = _nc;
mp = _mp; mp = _mp;
calc(); calc();
impulse = FIR::fir_bandpass(nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); 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); p = new FIRCORE(size, out, out, mp, impulse);
delete[] impulse;
} }
FMMOD::~FMMOD() FMMOD::~FMMOD()
@ -138,23 +139,21 @@ void FMMOD::setBuffers(float* _in, float* _out)
void FMMOD::setSamplerate(int _rate) void FMMOD::setSamplerate(int _rate)
{ {
float* impulse; std::vector<float> impulse;
samplerate = _rate; samplerate = _rate;
calc(); calc();
impulse = FIR::fir_bandpass(nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); FIR::fir_bandpass(impulse, nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
p->setImpulse(impulse, 1); p->setImpulse(impulse, 1);
delete[] impulse;
} }
void FMMOD::setSize(int _size) void FMMOD::setSize(int _size)
{ {
float* impulse; std::vector<float> impulse;
size = _size; size = _size;
calc(); calc();
p->setSize(size); p->setSize(size);
impulse = FIR::fir_bandpass(nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); FIR::fir_bandpass(impulse, nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
p->setImpulse(impulse, 1); p->setImpulse(impulse, 1);
delete[] impulse;
} }
/******************************************************************************************************** /********************************************************************************************************
@ -166,9 +165,9 @@ void FMMOD::setSize(int _size)
void FMMOD::setDeviation(float _deviation) void FMMOD::setDeviation(float _deviation)
{ {
double _bp_fc = f_high + _deviation; double _bp_fc = f_high + _deviation;
float* impulse = FIR::fir_bandpass (nc, -_bp_fc, +_bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); std::vector<float> impulse;
FIR::fir_bandpass (impulse, nc, -_bp_fc, +_bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
p->setImpulse(impulse, 0); p->setImpulse(impulse, 0);
delete[] impulse;
deviation = _deviation; deviation = _deviation;
// mod // mod
sphase = 0.0; sphase = 0.0;
@ -192,14 +191,13 @@ void FMMOD::setCTCSSRun (int _run)
void FMMOD::setNC(int _nc) void FMMOD::setNC(int _nc)
{ {
float* impulse; std::vector<float> impulse;
if (nc != _nc) if (nc != _nc)
{ {
nc = _nc; nc = _nc;
impulse = FIR::fir_bandpass (nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); FIR::fir_bandpass (impulse, nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
p->setNc(nc, impulse); p->setNc(impulse);
delete[] impulse;
} }
} }
@ -214,16 +212,15 @@ void FMMOD::setMP(int _mp)
void FMMOD::setAFFreqs(float _low, float _high) void FMMOD::setAFFreqs(float _low, float _high)
{ {
float* impulse; std::vector<float> impulse;
if (f_low != _low || f_high != _high) if (f_low != _low || f_high != _high)
{ {
f_low = _low; f_low = _low;
f_high = _high; f_high = _high;
bp_fc = deviation + f_high; bp_fc = deviation + f_high;
impulse = FIR::fir_bandpass (nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); FIR::fir_bandpass (impulse, nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size));
p->setImpulse(impulse, 1); p->setImpulse(impulse, 1);
delete[] impulse;
} }
} }

View File

@ -36,7 +36,7 @@ void FMSQ::calc()
{ {
double delta; double delta;
double theta; double theta;
float* impulse; std::vector<float> impulse;
int i; int i;
// noise filter // noise filter
noise.resize(2 * size * 2); noise.resize(2 * size * 2);
@ -48,9 +48,8 @@ void FMSQ::calc()
G[1] = 0.0; G[1] = 0.0;
G[2] = 3.0; G[2] = 3.0;
G[3] = (float) (+20.0 * log10(20000.0 / *pllpole)); G[3] = (float) (+20.0 * log10(20000.0 / *pllpole));
impulse = EQP::eq_impulse (nc, 3, F.data(), G.data(), rate, 1.0 / (2.0 * size), 0, 0); EQP::eq_impulse (impulse, nc, 3, F.data(), G.data(), rate, 1.0 / (2.0 * size), 0, 0);
p = new FIRCORE(size, trigger, noise.data(), nc, mp, impulse); p = new FIRCORE(size, trigger, noise.data(), mp, impulse);
delete[] impulse;
// noise averaging // noise averaging
avm = exp(-1.0 / (rate * avtau)); avm = exp(-1.0 / (rate * avtau));
onem_avm = 1.0 - avm; onem_avm = 1.0 - avm;
@ -286,14 +285,13 @@ void FMSQ::setThreshold(double threshold)
void FMSQ::setNC(int _nc) void FMSQ::setNC(int _nc)
{ {
float* impulse; std::vector<float> impulse;
if (nc != _nc) if (nc != _nc)
{ {
nc = _nc; nc = _nc;
impulse = EQP::eq_impulse (nc, 3, F.data(), G.data(), rate, 1.0 / (2.0 * size), 0, 0); EQP::eq_impulse (impulse, nc, 3, F.data(), G.data(), rate, 1.0 / (2.0 * size), 0, 0);
p->setNc(nc, impulse); p->setNc(impulse);
delete[] impulse;
} }
} }

View File

@ -34,11 +34,10 @@ namespace WDSP {
void ICFIR::calc_icfir (ICFIR *a) void ICFIR::calc_icfir (ICFIR *a)
{ {
float* impulse; std::vector<float> impulse;
a->scale = 1.0f / (float)(2 * a->size); a->scale = 1.0f / (float)(2 * a->size);
impulse = icfir_impulse (a->nc, a->DD, a->R, a->Pairs, (float) a->runrate, (float) a->cicrate, a->cutoff, a->xtype, a->xbw, 1, a->scale, a->wintype); icfir_impulse (impulse, a->nc, a->DD, a->R, a->Pairs, (float) a->runrate, (float) a->cicrate, a->cutoff, a->xtype, a->xbw, 1, a->scale, a->wintype);
a->p = new FIRCORE(a->size, a->in, a->out, a->nc, a->mp, impulse); a->p = new FIRCORE(a->size, a->in, a->out, a->mp, impulse);
delete[] (impulse);
} }
void ICFIR::decalc_icfir (ICFIR *a) void ICFIR::decalc_icfir (ICFIR *a)
@ -145,7 +144,8 @@ void ICFIR::setOutRate_icfir (ICFIR *a, int rate)
calc_icfir (a); calc_icfir (a);
} }
float* ICFIR::icfir_impulse ( void ICFIR::icfir_impulse (
std::vector<float>& impulse,
int N, int N,
int DD, int DD,
int R, int R,
@ -178,7 +178,6 @@ float* ICFIR::icfir_impulse (
float ri; float ri;
float mag; float mag;
float fn; float fn;
float* impulse;
auto* A = new float[N]; auto* A = new float[N];
float ft = cutoff / cicrate; // normalized cutoff frequency float ft = cutoff / cicrate; // normalized cutoff frequency
int u_samps = (N + 1) / 2; // number of unique samples, OK for odd or even N int u_samps = (N + 1) / 2; // number of unique samples, OK for odd or even N
@ -239,10 +238,10 @@ float* ICFIR::icfir_impulse (
else else
for (i = u_samps, j = 1; i < N; i++, j++) for (i = u_samps, j = 1; i < N; i++, j++)
A[i] = A[u_samps - j]; A[i] = A[u_samps - j];
impulse = FIR::fir_fsamp (N, A, rtype, 1.0, wintype); impulse.resize(2 * N);
FIR::fir_fsamp (impulse, N, A, rtype, 1.0, wintype);
delete[] (A); delete[] (A);
delete[] xistion; delete[] xistion;
return impulse;
} }

View File

@ -79,7 +79,8 @@ public:
static void setSamplerate_icfir (ICFIR *a, int rate); static void setSamplerate_icfir (ICFIR *a, int rate);
static void setSize_icfir (ICFIR *a, int size); static void setSize_icfir (ICFIR *a, int size);
static void setOutRate_icfir (ICFIR *a, int rate); static void setOutRate_icfir (ICFIR *a, int rate);
static float* icfir_impulse ( static void icfir_impulse (
std::vector<float>& impulse,
int N, int N,
int DD, int DD,
int R, int R,

View File

@ -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]; impulse.resize(N * 2);
std::fill(impulse, impulse + N*2, 0); std::fill(impulse.begin(), impulse.end(), 0);
for (int k = 0; k < nbp; k++) 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++) for (int i = 0; i < N; i++)
{ {
impulse[2 * i + 0] += imp[2 * i + 0]; impulse[2 * i + 0] += imp[2 * i + 0];
impulse[2 * i + 1] += imp[2 * i + 1]; impulse[2 * i + 1] += imp[2 * i + 1];
} }
delete[] imp;
} }
return impulse;
} }
double NBP::min_notch_width() const double NBP::min_notch_width() const
@ -324,7 +323,8 @@ void NBP::calc_lightweight()
bplow[i] -= offset; bplow[i] -= offset;
bphigh[i] -= offset; bphigh[i] -= offset;
} }
impulse = fir_mbandpass ( fir_mbandpass (
impulse,
nc, nc,
numpb, numpb,
bplow.data(), bplow.data(),
@ -335,7 +335,6 @@ void NBP::calc_lightweight()
); );
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
// print_impulse ("nbp.txt", size + 1, impulse, 1, 0); // print_impulse ("nbp.txt", size + 1, impulse, 1, 0);
delete[] impulse;
} }
hadnotch = havnotch; hadnotch = havnotch;
} }
@ -375,7 +374,8 @@ void NBP::calc_impulse ()
bplow[i] -= offset; bplow[i] -= offset;
bphigh[i] -= offset; bphigh[i] -= offset;
} }
impulse = fir_mbandpass ( fir_mbandpass (
impulse,
nc, nc,
numpb, numpb,
bplow.data(), bplow.data(),
@ -387,7 +387,8 @@ void NBP::calc_impulse ()
} }
else else
{ {
impulse = FIR::fir_bandpass( FIR::fir_bandpass(
impulse,
nc, nc,
flow, flow,
fhigh, fhigh,
@ -437,14 +438,12 @@ NBP::NBP(
bplow.resize(maxpb); bplow.resize(maxpb);
bphigh.resize(maxpb); bphigh.resize(maxpb);
calc_impulse (); calc_impulse ();
fircore = new FIRCORE(size, in, out, nc, mp, impulse); fircore = new FIRCORE(size, in, out, mp, impulse);
// print_impulse ("nbp.txt", size + 1, impulse, 1, 0);
delete[]impulse;
} }
NBP::~NBP() NBP::~NBP()
{ {
delete (fircore); delete fircore;
} }
void NBP::flush() void NBP::flush()
@ -472,7 +471,6 @@ void NBP::setSamplerate(int _rate)
rate = _rate; rate = _rate;
calc_impulse (); calc_impulse ();
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
void NBP::setSize(int _size) void NBP::setSize(int _size)
@ -482,14 +480,12 @@ void NBP::setSize(int _size)
fircore->setSize(size); fircore->setSize(size);
calc_impulse (); calc_impulse ();
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
void NBP::setNc() void NBP::setNc()
{ {
calc_impulse(); calc_impulse();
fircore->setNc(nc, impulse); fircore->setNc(impulse);
delete[] impulse;
} }
void NBP::setMp() void NBP::setMp()
@ -518,7 +514,6 @@ void NBP::SetFreqs(double _flow, double _fhigh)
fhigh = _fhigh; fhigh = _fhigh;
calc_impulse(); calc_impulse();
fircore->setImpulse(impulse, 1); fircore->setImpulse(impulse, 1);
delete[] impulse;
} }
} }

View File

@ -80,7 +80,7 @@ public:
int autoincr; // auto-increment notch width int autoincr; // auto-increment notch width
double flow; // low bandpass cutoff freq double flow; // low bandpass cutoff freq
double fhigh; // high 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 int maxpb; // maximum number of passbands
NOTCHDB* notchdb; // ptr to addr of notch-database data structure NOTCHDB* notchdb; // ptr to addr of notch-database data structure
std::vector<double> bplow; // array of passband lows std::vector<double> bplow; // array of passband lows
@ -129,7 +129,7 @@ public:
void calc_lightweight(); void calc_lightweight();
private: 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; double min_notch_width () const;
static int make_nbp ( static int make_nbp (
int nn, int nn,

View File

@ -47,7 +47,7 @@ void RESAMPLE::calc()
double full_rate; double full_rate;
double fc_norm_high; double fc_norm_high;
double fc_norm_low; double fc_norm_low;
float* impulse; std::vector<float> impulse;
fc = fcin; fc = fcin;
ncoef = ncoefin; ncoef = ncoefin;
x = in_rate; x = in_rate;
@ -88,7 +88,7 @@ void RESAMPLE::calc()
ncoef = (ncoef / L + 1) * L; ncoef = (ncoef / L + 1) * L;
cpp = ncoef / L; cpp = ncoef / L;
h.resize(ncoef); 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; i = 0;
for (int j = 0; j < L; j++) for (int j = 0; j < L; j++)
@ -101,8 +101,6 @@ void RESAMPLE::calc()
ring.resize(ringsize); ring.resize(ringsize);
idx_in = ringsize - 1; idx_in = ringsize - 1;
phnum = 0; phnum = 0;
delete[] impulse;
} }
RESAMPLE::RESAMPLE ( RESAMPLE::RESAMPLE (

View File

@ -25,6 +25,8 @@ warren@wpratt.com
*/ */
#include <vector>
#include "comm.hpp" #include "comm.hpp"
#include "fir.hpp" #include "fir.hpp"
#include "resamplef.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* RESAMPLEF::create_resampleF ( int run, int size, float* in, float* out, int in_rate, int out_rate)
{ {
RESAMPLEF *a = new RESAMPLEF; auto *a = new RESAMPLEF;
int x, y, z; int x;
int i, j, k; int y;
int z;
int i;
int min_rate; int min_rate;
float full_rate; float full_rate;
float fc; float fc;
float fc_norm; float fc_norm;
float* impulse; std::vector<float> impulse;
a->run = run; a->run = run;
a->size = size; a->size = size;
a->in = in; a->in = in;
@ -72,36 +76,35 @@ RESAMPLEF* RESAMPLEF::create_resampleF ( int run, int size, float* in, float* ou
else else
min_rate = out_rate; min_rate = out_rate;
fc = 0.45 * (float)min_rate; fc = 0.45f * (float)min_rate;
full_rate = (float)(in_rate * a->L); full_rate = (float)(in_rate * a->L);
fc_norm = fc / full_rate; fc_norm = fc / full_rate;
a->ncoef = (int)(60.0 / fc_norm); a->ncoef = (int)(60.0 / fc_norm);
a->ncoef = (a->ncoef / a->L + 1) * a->L; a->ncoef = (a->ncoef / a->L + 1) * a->L;
a->cpp = a->ncoef / a->L; a->cpp = a->ncoef / a->L;
a->h = new float[a->ncoef]; // (float *) malloc0 (a->ncoef * sizeof (float)); a->h = new float[a->ncoef];
impulse = FIR::fir_bandpass (a->ncoef, -fc_norm, +fc_norm, 1.0, 1, 0, (float)a->L); FIR::fir_bandpass (impulse, a->ncoef, -fc_norm, +fc_norm, 1.0, 1, 0, (float)a->L);
i = 0; 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->h[i++] = impulse[j + k];
} }
a->ringsize = a->cpp; 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->idx_in = a->ringsize - 1;
a->phnum = 0; a->phnum = 0;
delete[] (impulse);
return a; return a;
} }
void RESAMPLEF::destroy_resampleF (RESAMPLEF *a) void RESAMPLEF::destroy_resampleF (RESAMPLEF *a)
{ {
delete[] (a->ring); delete[] a->ring;
delete[] (a->h); delete[] a->h;
delete (a); delete a;
} }
void RESAMPLEF::flush_resampleF (RESAMPLEF *a) void RESAMPLEF::flush_resampleF (RESAMPLEF *a)
@ -117,20 +120,20 @@ int RESAMPLEF::xresampleF (RESAMPLEF *a)
if (a->run) if (a->run)
{ {
int i, j, n; int n;
int idx_out; int idx_out;
float I; 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) while (a->phnum < a->L)
{ {
I = 0.0; I = 0.0;
n = a->cpp * a->phnum; 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) if ((idx_out = a->idx_in + j) >= a->ringsize)
idx_out -= a->ringsize; idx_out -= a->ringsize;
@ -138,7 +141,7 @@ int RESAMPLEF::xresampleF (RESAMPLEF *a)
I += a->h[n + j] * a->ring[idx_out]; I += a->h[n + j] * a->ring[idx_out];
} }
a->out[outsamps] = (float)I; a->out[outsamps] = I;
outsamps++; outsamps++;
a->phnum += a->M; a->phnum += a->M;
@ -163,13 +166,13 @@ int RESAMPLEF::xresampleF (RESAMPLEF *a)
void* RESAMPLEF::create_resampleFV (int in_rate, int out_rate) 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) 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->in = input;
a->out = output; a->out = output;
a->size = numsamps; a->size = numsamps;

View File

@ -36,11 +36,11 @@ namespace WDSP {
MAV* MAV::create_mav (int ringmin, int ringmax, float nom_value) MAV* MAV::create_mav (int ringmin, int ringmax, float nom_value)
{ {
MAV *a = new MAV; auto *a = new MAV;
a->ringmin = ringmin; a->ringmin = ringmin;
a->ringmax = ringmax; a->ringmax = ringmax;
a->nom_value = nom_value; 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->mask = a->ringmax - 1;
a->i = 0; a->i = 0;
a->load = 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) void MAV::destroy_mav (MAV *a)
{ {
delete[] (a->ring); delete[] a->ring;
delete (a); delete a;
} }
void MAV::flush_mav (MAV *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* AAMAV::create_aamav (int ringmin, int ringmax, float nom_ratio)
{ {
AAMAV *a = new AAMAV; auto *a = new AAMAV;
a->ringmin = ringmin; a->ringmin = ringmin;
a->ringmax = ringmax; a->ringmax = ringmax;
a->nom_ratio = nom_ratio; 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->mask = a->ringmax - 1;
a->i = 0; a->i = 0;
a->load = 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) void AAMAV::destroy_aamav (AAMAV *a)
{ {
delete[] (a->ring); delete[] a->ring;
delete[] (a); delete[] a;
} }
void AAMAV::flush_aamav (AAMAV *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) void RMATCH::calc_rmatch (RMATCH *a)
{ {
int m; int m;
float theta, dtheta; float theta;
float dtheta;
int max_ring_insize; int max_ring_insize;
a->nom_ratio = (float)a->nom_outrate / (float)a->nom_inrate; 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)); 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 * max_ring_insize) a->ringsize = 2 * max_ring_insize;
if (a->ringsize < 2 * a->outsize) a->ringsize = 2 * a->outsize; 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->rsize = a->ringsize;
a->n_ring = a->rsize / 2; a->n_ring = a->rsize / 2;
a->iin = a->rsize / 2; a->iin = a->rsize / 2;
a->iout = 0; a->iout = 0;
a->resout = new float[max_ring_insize * 2]; // (float *) malloc0 (max_ring_insize * sizeof (complex)); a->resout = new float[max_ring_insize * 2];
a->v = VARSAMP::create_varsamp (1, a->insize, a->in, a->resout, a->nom_inrate, a->nom_outrate, 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->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->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->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->inv_nom_ratio = (float)a->nom_inrate / (float)a->nom_outrate;
a->feed_forward = 1.0; a->feed_forward = 1.0;
a->av_deviation = 0.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; 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)); a->cslew = new float[a->ntslew + 1];
dtheta = PI / (float)a->ntslew; dtheta = (float) PI / (float) a->ntslew;
theta = 0.0; theta = 0.0;
for (m = 0; m <= a->ntslew; m++) 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; 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->readsamps = 0;
a->writesamps = 0; a->writesamps = 0;
a->read_startup = (unsigned int)((float)a->nom_outrate * a->startup_delay); 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); delete[] (a->cslew);
MAV::destroy_mav (a->propmav); MAV::destroy_mav (a->propmav);
AAMAV::destroy_aamav (a->ffmav); AAMAV::destroy_aamav (a->ffmav);
VARSAMP::destroy_varsamp (a->v); delete a->v;
delete[] (a->resout); delete[] (a->resout);
delete[] (a->ring); delete[] (a->ring);
} }
@ -215,7 +216,7 @@ RMATCH* RMATCH::create_rmatch (
float tslew // slew/blend time (seconds) float tslew // slew/blend time (seconds)
) )
{ {
RMATCH *a = new RMATCH; auto *a = new RMATCH;
a->run = run; a->run = run;
a->in = in; a->in = in;
a->out = out; a->out = out;
@ -246,7 +247,7 @@ RMATCH* RMATCH::create_rmatch (
void RMATCH::destroy_rmatch (RMATCH *a) void RMATCH::destroy_rmatch (RMATCH *a)
{ {
decalc_rmatch (a); decalc_rmatch (a);
delete (a); delete a;
} }
void RMATCH::reset_rmatch (RMATCH *a) void RMATCH::reset_rmatch (RMATCH *a)
@ -264,30 +265,32 @@ void RMATCH::control (RMATCH *a, int change)
float current_ratio; float current_ratio;
AAMAV::xaamav (a->ffmav, change, &current_ratio); AAMAV::xaamav (a->ffmav, change, &current_ratio);
current_ratio *= a->inv_nom_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; int deviation = a->n_ring - a->rsize / 2;
MAV::xmav (a->propmav, deviation, &a->av_deviation); MAV::xmav (a->propmav, deviation, &a->av_deviation);
} }
a->var = a->feed_forward - a->pr_gain * 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 > 1.04) a->var = 1.04f;
if (a->var < 0.96) a->var = 0.96; if (a->var < 0.96) a->var = 0.96f;
} }
void RMATCH::blend (RMATCH *a) 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) 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 + 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.0 - a->cslew[i]) * a->baux[2 * i + 1]; 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) void RMATCH::upslew (RMATCH *a, int newsamps)
{ {
int i, j; int i;
int j;
i = 0; i = 0;
j = a->iin; j = a->iin;
while (a->ucnt >= 0 && i < newsamps) while (a->ucnt >= 0 && i < newsamps)
@ -302,10 +305,13 @@ void RMATCH::upslew (RMATCH *a, int newsamps)
void RMATCH::xrmatchIN (void* b, float* in) void RMATCH::xrmatchIN (void* b, float* in)
{ {
RMATCH *a = (RMATCH*) b; auto *a = (RMATCH*) b;
if (a->run == 1) if (a->run == 1)
{ {
int newsamps, first, second, ovfl; int newsamps;
int first;
int second;
int ovfl;
float var; float var;
a->v->in = a->in = in; a->v->in = a->in = in;
@ -314,13 +320,12 @@ void RMATCH::xrmatchIN (void* b, float* in)
else else
var = a->fvar; var = a->fvar;
newsamps = VARSAMP::xvarsamp (a->v, var); newsamps = a->v->execute(var);
a->n_ring += newsamps; a->n_ring += newsamps;
if ((ovfl = a->n_ring - a->rsize) > 0) if ((ovfl = a->n_ring - a->rsize) > 0)
{ {
a->overflows += 1; a->overflows += 1;
// a->n_ring = a->rsize / 2;
a->n_ring = a->rsize; // a->n_ring = a->rsize; //
if ((a->ntslew + 1) > (a->rsize - a->iout)) 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 + 2 * a->iout, a->ring + 2 * a->iout + first * 2, a->baux);
std::copy(a->ring, a->ring + second * 2, a->baux + 2 * first); 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; // a->iout = (a->iout + ovfl) % a->rsize; //
} }
@ -376,8 +380,13 @@ void RMATCH::xrmatchIN (void* b, float* in)
void RMATCH::dslew (RMATCH *a) void RMATCH::dslew (RMATCH *a)
{ {
int i, j, k, n; int i;
int zeros, first, second; int j;
int k;
int n;
int zeros;
int first;
int second;
if (a->n_ring > a->ntslew + 1) if (a->n_ring > a->ntslew + 1)
{ {
i = (a->iout + (a->n_ring - (a->ntslew + 1))) % a->rsize; i = (a->iout + (a->n_ring - (a->ntslew + 1))) % a->rsize;
@ -414,7 +423,7 @@ void RMATCH::dslew (RMATCH *a)
j--; j--;
n++; n++;
} }
// zeros = a->outsize + a->rsize / 2 - n;
if ((zeros = a->outsize - n) > 0) // if ((zeros = a->outsize - n) > 0) //
{ // { //
if (zeros > a->rsize - i) 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 + 2 * i, a->ring + 2 * i + first * 2, 0);
std::fill(a->ring, a->ring + second * 2, 0); std::fill(a->ring, a->ring + second * 2, 0);
n += zeros; // n += zeros;
} // }
// a->n_ring = a->outsize + a->rsize / 2; a->n_ring = n;
a->n_ring = n; // a->iin = (a->iout + a->n_ring) % a->rsize;
// a->iin = (a->iout + a->outsize + a->rsize/2) % a->rsize;
a->iin = (a->iout + a->n_ring) % a->rsize; //
} }
void RMATCH::xrmatchOUT (void* b, float* out) void RMATCH::xrmatchOUT (void* b, float* out)
{ {
RMATCH *a = (RMATCH*) b; auto *a = (RMATCH*) b;
if (a->run == 1) if (a->run == 1)
{ {
int first, second; int first;
int second;
a->out = out; a->out = out;
if (a->n_ring < a->outsize) 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) 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; *underflows = a->underflows;
*overflows = a->overflows; *overflows = a->overflows;
a->underflows &= 0xFFFFFFFF; a->underflows &= 0xFFFFFFFF;
@ -500,15 +508,12 @@ void RMATCH::getRMatchDiags (void* b, int* underflows, int* overflows, float* va
void RMATCH::resetRMatchDiags (void*) 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) void RMATCH::forceRMatchVar (void* b, int force, float fvar)
{ {
RMATCH *a = (RMATCH*) b; auto *a = (RMATCH*) b;
a->force = force; a->force = force;
a->fvar = fvar; 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 ( return (void*)create_rmatch (
1, // run 1, // run
0, // input buffer, stuffed in other calls nullptr, // input buffer, stuffed in other calls
0, // output buffer, stuffed in other calls nullptr, // output buffer, stuffed in other calls
in_size, // input buffer size (complex samples) in_size, // input buffer size (complex samples)
out_size, // output buffer size (complex samples) out_size, // output buffer size (complex samples)
nom_inrate, // nominal input sample-rate 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 var, // initial variable ratio
4096, // feed-forward moving average min size 4096, // feed-forward moving average min size
262144, // feed-forward moving average max size - POWER OF TWO! 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 4096, // proportional feedback min moving av ringsize
16384, // proportional feedback max moving av ringsize - POWER OF TWO! 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 1, // linearly interpolate cvar by sample
0.003 ); // slew time (seconds) 0.003f ); // slew time (seconds)
} }
void RMATCH::destroy_rmatchV (void* ptr) void RMATCH::destroy_rmatchV (void* ptr)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
destroy_rmatch (a); destroy_rmatch (a);
} }
void RMATCH::setRMatchInsize (void* ptr, int insize) void RMATCH::setRMatchInsize (void* ptr, int insize)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10)); std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a); decalc_rmatch(a);
@ -564,7 +569,7 @@ void RMATCH::setRMatchInsize (void* ptr, int insize)
void RMATCH::setRMatchOutsize (void* ptr, int outsize) void RMATCH::setRMatchOutsize (void* ptr, int outsize)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10)); std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a); decalc_rmatch(a);
@ -576,7 +581,7 @@ void RMATCH::setRMatchOutsize (void* ptr, int outsize)
void RMATCH::setRMatchNomInrate (void* ptr, int nom_inrate) void RMATCH::setRMatchNomInrate (void* ptr, int nom_inrate)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10)); std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a); decalc_rmatch(a);
@ -588,7 +593,7 @@ void RMATCH::setRMatchNomInrate (void* ptr, int nom_inrate)
void RMATCH::setRMatchNomOutrate (void* ptr, int nom_outrate) void RMATCH::setRMatchNomOutrate (void* ptr, int nom_outrate)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10)); std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a); decalc_rmatch(a);
@ -600,7 +605,7 @@ void RMATCH::setRMatchNomOutrate (void* ptr, int nom_outrate)
void RMATCH::setRMatchRingsize (void* ptr, int ringsize) void RMATCH::setRMatchRingsize (void* ptr, int ringsize)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10)); std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a); decalc_rmatch(a);
@ -612,7 +617,7 @@ void RMATCH::setRMatchRingsize (void* ptr, int ringsize)
void RMATCH::setRMatchFeedbackGain (void* b, float feedback_gain) void RMATCH::setRMatchFeedbackGain (void* b, float feedback_gain)
{ {
RMATCH *a = (RMATCH*) b; auto *a = (RMATCH*) b;
a->prop_gain = feedback_gain; a->prop_gain = feedback_gain;
a->pr_gain = a->prop_gain * 48000.0 / (float)a->nom_outrate; 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) void RMATCH::setRMatchSlewTime (void* b, float slew_time)
{ {
RMATCH *a = (RMATCH*) b; auto *a = (RMATCH*) b;
a->run = 0; // InterlockedBitTestAndReset(&a->run, 0); // turn OFF new data coming into the rmatch a->run = 0;
// Sleep(10); // wait for processing to cease
decalc_rmatch(a); // deallocate all memory EXCEPT the data structure holding all current parameters decalc_rmatch(a); // deallocate all memory EXCEPT the data structure holding all current parameters
a->tslew = slew_time; // change the value of 'slew_time' a->tslew = slew_time; // change the value of 'slew_time'
calc_rmatch(a); // recalculate/reallocate everything in the RMATCH 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) void RMATCH::setRMatchSlewTime1(void* b, float slew_time)
{ {
RMATCH *a = (RMATCH*) b; auto *a = (RMATCH*) b;
float theta, dtheta; float theta;
int m; float dtheta;
a->run = 0; a->run = 0;
// Sleep(10); delete[] a->cslew;
delete[](a->cslew);
a->tslew = slew_time; 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; 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)); 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; 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; theta += dtheta;
} }
a->run = 1; a->run = 1;
@ -655,9 +658,8 @@ void RMATCH::setRMatchSlewTime1(void* b, float slew_time)
void RMATCH::setRMatchPropRingMin(void* ptr, int prop_min) void RMATCH::setRMatchPropRingMin(void* ptr, int prop_min)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
// Sleep(10);
decalc_rmatch(a); decalc_rmatch(a);
a->prop_ringmin = prop_min; a->prop_ringmin = prop_min;
calc_rmatch(a); calc_rmatch(a);
@ -667,9 +669,8 @@ void RMATCH::setRMatchPropRingMin(void* ptr, int prop_min)
void RMATCH::setRMatchPropRingMax(void* ptr, int prop_max) void RMATCH::setRMatchPropRingMax(void* ptr, int prop_max)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
// Sleep(10);
decalc_rmatch(a); decalc_rmatch(a);
a->prop_ringmax = prop_max; // must be a power of two a->prop_ringmax = prop_max; // must be a power of two
calc_rmatch(a); calc_rmatch(a);
@ -679,9 +680,8 @@ void RMATCH::setRMatchPropRingMax(void* ptr, int prop_max)
void RMATCH::setRMatchFFRingMin(void* ptr, int ff_ringmin) void RMATCH::setRMatchFFRingMin(void* ptr, int ff_ringmin)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
// Sleep(10);
decalc_rmatch(a); decalc_rmatch(a);
a->ff_ringmin = ff_ringmin; a->ff_ringmin = ff_ringmin;
calc_rmatch(a); calc_rmatch(a);
@ -691,9 +691,8 @@ void RMATCH::setRMatchFFRingMin(void* ptr, int ff_ringmin)
void RMATCH::setRMatchFFRingMax(void* ptr, int ff_ringmax) void RMATCH::setRMatchFFRingMax(void* ptr, int ff_ringmax)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
// Sleep(10);
decalc_rmatch(a); decalc_rmatch(a);
a->ff_ringmax = ff_ringmax; // must be a power of two a->ff_ringmax = ff_ringmax; // must be a power of two
calc_rmatch(a); calc_rmatch(a);
@ -703,7 +702,7 @@ void RMATCH::setRMatchFFRingMax(void* ptr, int ff_ringmax)
void RMATCH::setRMatchFFAlpha(void* ptr, float ff_alpha) void RMATCH::setRMatchFFAlpha(void* ptr, float ff_alpha)
{ {
RMATCH *a = (RMATCH*) ptr; auto *a = (RMATCH*) ptr;
a->run = 0; a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10)); std::this_thread::sleep_for(std::chrono::seconds(10));
a->ff_alpha = ff_alpha; 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) void RMATCH::getControlFlag(void* ptr, int* control_flag)
{ {
RMATCH *a = (RMATCH*) ptr; RMATCH const *a = (RMATCH*) ptr;
*control_flag = a->control_flag; *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( return (void*) create_rmatch(
1, // run 1, // run
0, // input buffer, stuffed in other calls nullptr, // input buffer, stuffed in other calls
0, // output buffer, stuffed in other calls nullptr, // output buffer, stuffed in other calls
in_size, // input buffer size (complex samples) in_size, // input buffer size (complex samples)
out_size, // output buffer size (complex samples) out_size, // output buffer size (complex samples)
nom_inrate, // nominal input sample-rate 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 1.0, // initial variable ratio
4096, // feed-forward moving average min size 4096, // feed-forward moving average min size
262144, // feed-forward moving average max size - POWER OF TWO! 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 4096, // proportional feedback min moving av ringsize
16384, // proportional feedback max moving av ringsize - POWER OF TWO! 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, // 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 } // namespace WDSP

View File

@ -157,7 +157,6 @@ void USLEW::setBuffers(float* _in, float* _out)
void USLEW::setSamplerate(int _rate) void USLEW::setSamplerate(int _rate)
{ {
decalc();
rate = _rate; rate = _rate;
calc(); calc();
} }
@ -177,7 +176,6 @@ void USLEW::setSize(int _size)
void USLEW::setuSlewTime(double _time) void USLEW::setuSlewTime(double _time)
{ {
// NOTE: 'time' is in seconds // NOTE: 'time' is in seconds
decalc();
tupslew = _time; tupslew = _time;
calc(); calc();
} }

View File

@ -85,7 +85,6 @@ public:
private: private:
void calc(); void calc();
void decalc();
}; };
} // namespace WDSP } // namespace WDSP

View File

@ -31,236 +31,220 @@ warren@wpratt.com
namespace WDSP { namespace WDSP {
void VARSAMP::calc_varsamp (VARSAMP *a) void VARSAMP::calc()
{ {
float min_rate, max_rate, norm_rate; float min_rate;
float fc_norm_high, fc_norm_low; float max_rate;
a->nom_ratio = (float)a->out_rate / (float)a->in_rate; float norm_rate;
a->cvar = a->var * a->nom_ratio; float fc_norm_high;
a->inv_cvar = 1.0 / a->cvar; float fc_norm_low;
a->old_inv_cvar = a->inv_cvar; nom_ratio = (float)out_rate / (float)in_rate;
a->dicvar = 0.0; cvar = var * nom_ratio;
a->delta = fabs (1.0 / a->cvar - 1.0); inv_cvar = 1.0f / cvar;
a->fc = a->fcin; old_inv_cvar = inv_cvar;
if (a->out_rate >= a->in_rate) dicvar = 0.0;
delta = (float) fabs (1.0 / cvar - 1.0);
fc = fcin;
if (out_rate >= in_rate)
{ {
min_rate = (float)a->in_rate; min_rate = (float)in_rate;
max_rate = (float)a->out_rate;
norm_rate = min_rate; norm_rate = min_rate;
} }
else else
{ {
min_rate = (float)a->out_rate; min_rate = (float)out_rate;
max_rate = (float)a->in_rate; max_rate = (float)in_rate;
norm_rate = max_rate; norm_rate = max_rate;
} }
if (a->fc == 0.0) a->fc = 0.95 * 0.45 * min_rate; if (fc == 0.0) fc = 0.95f * 0.45f * min_rate;
fc_norm_high = a->fc / norm_rate; fc_norm_high = fc / norm_rate;
if (a->fc_low < 0.0) if (fc_low < 0.0)
fc_norm_low = - fc_norm_high; fc_norm_low = - fc_norm_high;
else else
fc_norm_low = a->fc_low / norm_rate; fc_norm_low = fc_low / norm_rate;
a->rsize = (int)(140.0 * norm_rate / min_rate); rsize = (int)(140.0 * norm_rate / min_rate);
a->ncoef = a->rsize + 1; ncoef = rsize + 1;
a->ncoef += (a->R - 1) * (a->ncoef - 1); ncoef += (R - 1) * (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); FIR::fir_bandpass(h, ncoef, fc_norm_low, fc_norm_high, (float)R, 1, 0, (float)R * gain);
// print_impulse ("imp.txt", a->ncoef, a->h, 0, 0); ring.resize(rsize * 2);
a->ring = new float[a->rsize * 2]; // (float *)malloc0(a->rsize * sizeof(complex)); idx_in = rsize - 1;
a->idx_in = a->rsize - 1; h_offset = 0.0;
a->h_offset = 0.0; hs.resize(rsize);
a->hs = new float[a->rsize]; // (float *)malloc0 (a->rsize * sizeof (float)); isamps = 0.0;
a->isamps = 0.0;
} }
void VARSAMP::decalc_varsamp (VARSAMP *a) VARSAMP::VARSAMP(
{ int _run,
delete[] (a->hs); int _size,
delete[] (a->ring); float* _in,
delete[] (a->h); float* _out,
} int _in_rate,
int _out_rate,
VARSAMP* VARSAMP::create_varsamp ( float _fc,
int run, float _fc_low,
int size, int _R,
float* in, float _gain,
float* out, float _var,
int in_rate, int _varmode
int out_rate,
float fc,
float fc_low,
int R,
float gain,
float var,
int varmode
) )
{ {
VARSAMP *a = new VARSAMP; run = _run;
size = _size;
a->run = run; in = _in;
a->size = size; out = _out;
a->in = in; in_rate = _in_rate;
a->out = out; out_rate = _out_rate;
a->in_rate = in_rate; fcin = _fc;
a->out_rate = out_rate; fc_low = _fc_low;
a->fcin = fc; R = _R;
a->fc_low = fc_low; gain = _gain;
a->R = R; var = _var;
a->gain = gain; varmode = _varmode;
a->var = var; calc();
a->varmode = varmode;
calc_varsamp (a);
return a;
} }
void VARSAMP::destroy_varsamp (VARSAMP *a) void VARSAMP::flush()
{ {
decalc_varsamp (a); std::fill(ring.begin(), ring.end(), 0);
delete (a); 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); int i;
a->idx_in = a->rsize - 1; int j;
a->h_offset = 0.0; int k;
a->isamps = 0.0;
}
void VARSAMP::hshift (VARSAMP *a)
{
int i, j, k;
int hidx; int hidx;
float frac, pos; float frac;
pos = (float)a->R * a->h_offset; float pos;
pos = (float)R * h_offset;
hidx = (int)(pos); hidx = (int)(pos);
frac = pos - (float)hidx; frac = pos - (float)hidx;
for (i = a->rsize - 1, j = hidx, k = hidx + 1; i >= 0; i--, j += a->R, k += a->R) for (i = rsize - 1, j = hidx, k = hidx + 1; i >= 0; i--, j += R, k += R)
a->hs[i] = a->h[j] + frac * (a->h[k] - a->h[j]); hs[i] = h[j] + frac * (h[k] - h[j]);
} }
int VARSAMP::xvarsamp (VARSAMP *a, float var) int VARSAMP::execute(float _var)
{ {
int outsamps = 0; int outsamps = 0;
uint64_t* picvar; uint64_t const* picvar;
uint64_t N; uint64_t N;
a->var = var; var = _var;
a->old_inv_cvar = a->inv_cvar; old_inv_cvar = inv_cvar;
a->cvar = a->var * a->nom_ratio; cvar = var * nom_ratio;
a->inv_cvar = 1.0 / a->cvar; inv_cvar = 1.0f / cvar;
if (a->varmode) if (varmode)
{ {
a->dicvar = (a->inv_cvar - a->old_inv_cvar) / (float)a->size; dicvar = (inv_cvar - old_inv_cvar) / (float)size;
a->inv_cvar = a->old_inv_cvar; inv_cvar = old_inv_cvar;
} }
else a->dicvar = 0.0; else dicvar = 0.0;
if (a->run) if (run)
{ {
int i, j;
int idx_out; int idx_out;
float I, Q; float I;
for (i = 0; i < a->size; i++) float Q;
for (int i = 0; i < size; i++)
{ {
a->ring[2 * a->idx_in + 0] = a->in[2 * i + 0]; ring[2 * idx_in + 0] = in[2 * i + 0];
a->ring[2 * a->idx_in + 1] = a->in[2 * i + 1]; ring[2 * idx_in + 1] = in[2 * i + 1];
a->inv_cvar += a->dicvar; inv_cvar += dicvar;
picvar = (uint64_t*)(&a->inv_cvar); picvar = (uint64_t*)(&inv_cvar);
N = *picvar & 0xffffffffffff0000; N = *picvar & 0xffffffffffff0000;
a->inv_cvar = static_cast<float>(N); inv_cvar = static_cast<float>(N);
a->delta = 1.0 - a->inv_cvar; delta = 1.0f - inv_cvar;
while (a->isamps < 1.0) while (isamps < 1.0)
{ {
I = 0.0; I = 0.0;
Q = 0.0; Q = 0.0;
hshift (a); hshift();
a->h_offset += a->delta; h_offset += delta;
while (a->h_offset >= 1.0) a->h_offset -= 1.0; while (h_offset >= 1.0) h_offset -= 1.0f;
while (a->h_offset < 0.0) a->h_offset += 1.0; while (h_offset < 0.0) h_offset += 1.0f;
for (j = 0; j < a->rsize; j++) for (int j = 0; j < rsize; j++)
{ {
if ((idx_out = a->idx_in + j) >= a->rsize) idx_out -= a->rsize; if ((idx_out = idx_in + j) >= rsize) idx_out -= rsize;
I += a->hs[j] * a->ring[2 * idx_out + 0]; I += hs[j] * ring[2 * idx_out + 0];
Q += a->hs[j] * a->ring[2 * idx_out + 1]; Q += hs[j] * ring[2 * idx_out + 1];
} }
a->out[2 * outsamps + 0] = I; out[2 * outsamps + 0] = I;
a->out[2 * outsamps + 1] = Q; out[2 * outsamps + 1] = Q;
outsamps++; outsamps++;
a->isamps += a->inv_cvar; isamps += inv_cvar;
} }
a->isamps -= 1.0; isamps -= 1.0f;
if (--a->idx_in < 0) a->idx_in = a->rsize - 1; if (--idx_in < 0) idx_in = rsize - 1;
} }
} }
else if (a->in != a->out) else if (in != out)
std::copy( a->in, a->in + a->size * 2, a->out); std::copy( in, in + size * 2, out);
return outsamps; return outsamps;
} }
void VARSAMP::setBuffers_varsamp (VARSAMP *a, float* in, float* out) void VARSAMP::setBuffers(float* _in, float* _out)
{ {
a->in = in; in = _in;
a->out = out; out = _out;
} }
void VARSAMP::setSize_varsamp (VARSAMP *a, int size) void VARSAMP::setSize(int _size)
{ {
a->size = size; size = _size;
flush_varsamp (a); flush();
} }
void VARSAMP::setInRate_varsamp (VARSAMP *a, int rate) void VARSAMP::setInRate(int _rate)
{ {
decalc_varsamp (a); in_rate = _rate;
a->in_rate = rate; calc();
calc_varsamp (a);
} }
void VARSAMP::setOutRate_varsamp (VARSAMP *a, int rate) void VARSAMP::setOutRate(int _rate)
{ {
decalc_varsamp (a); out_rate = _rate;
a->out_rate = rate; calc();
calc_varsamp (a);
} }
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); fc_low = _fc_low;
a->fc_low = fc_low; calc();
calc_varsamp (a);
} }
} }
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); fc_low = _fc_low;
a->fc_low = fc_low; fcin = _fc_high;
a->fcin = fc_high; calc();
calc_varsamp (a);
} }
} }
// exported calls // 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) 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->in = input;
a->out = output; a->out = output;
a->size = numsamps; a->size = numsamps;
*outsamps = xvarsamp(a, var); *outsamps = a->execute(var);
} }
void VARSAMP::destroy_varsampV (void* ptr) void VARSAMP::destroy_varsampV (void* ptr)
{ {
destroy_varsamp ( (VARSAMP*) ptr ); delete (VARSAMP*) ptr;
} }
} // namespace WDSP } // namespace WDSP

View File

@ -28,6 +28,8 @@ warren@wpratt.com
#ifndef wdsp_varsamp_h #ifndef wdsp_varsamp_h
#define wdsp_varsamp_h #define wdsp_varsamp_h
#include <vector>
#include "export.h" #include "export.h"
namespace WDSP { namespace WDSP {
@ -47,9 +49,9 @@ public:
float gain; float gain;
int idx_in; int idx_in;
int ncoef; int ncoef;
float* h; std::vector<float> h;
int rsize; int rsize;
float* ring; std::vector<float> ring;
float var; float var;
int varmode; int varmode;
float cvar; float cvar;
@ -57,13 +59,13 @@ public:
float old_inv_cvar; float old_inv_cvar;
float dicvar; float dicvar;
float delta; float delta;
float* hs; std::vector<float> hs;
int R; int R;
float h_offset; float h_offset;
float isamps; float isamps;
float nom_ratio; float nom_ratio;
static VARSAMP* create_varsamp ( VARSAMP(
int run, int run,
int size, int size,
float* in, float* in,
@ -77,24 +79,26 @@ public:
float var, float var,
int varmode int varmode
); );
static void destroy_varsamp (VARSAMP *a); VARSAMP(const VARSAMP&) = delete;
static void flush_varsamp (VARSAMP *a); VARSAMP& operator=(VARSAMP& other) = delete;
static int xvarsamp (VARSAMP *a, float var); ~VARSAMP() = default;
static void setBuffers_varsamp (VARSAMP *a, float* in, float* out);
static void setSize_varsamp (VARSAMP *a, int size); void flush();
static void setInRate_varsamp (VARSAMP *a, int rate); int execute(float var);
static void setOutRate_varsamp (VARSAMP *a, int rate); void setBuffers(float* in, float* out);
static void setFCLow_varsamp (VARSAMP *a, float fc_low); void setSize(int size);
static void setBandwidth_varsamp (VARSAMP *a, float fc_low, float fc_high); void setInRate(int rate);
void setOutRate(int rate);
void setFCLow(float fc_low);
void setBandwidth(float fc_low, float fc_high);
// Exported calls // Exported calls
static void* create_varsampV (int in_rate, int out_rate, int R); 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 xvarsampV (float* input, float* output, int numsamps, float var, int* outsamps, void* ptr);
static void destroy_varsampV (void* ptr); static void destroy_varsampV (void* ptr);
private: private:
static void calc_varsamp (VARSAMP *a); void calc();
static void decalc_varsamp (VARSAMP *a); void hshift();
static void hshift (VARSAMP *a);
}; };
} // namespace WDSP } // namespace WDSP