1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-03-20 19:36:16 -04:00

WDSP: impulse responses refactoring (4)

This commit is contained in:
f4exb 2024-08-10 06:40:35 +02:00
parent ad3e7dfe19
commit e48dc22793
25 changed files with 613 additions and 590 deletions

View File

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

View File

@ -1005,8 +1005,7 @@ void RXA::updateNBPFilters()
if (a->fnfrun)
{
a->calc_impulse();
a->fircore->setImpulse(a->impulse, 1);
delete[] (a->impulse);
a->fircore->setImpulse(a->impulse.data(), 1);
}
if (b->bpsnba->fnfrun)
{
@ -1097,8 +1096,7 @@ void RXA::nbpSetNotchesRun(int _run)
b->fnfrun = a->master_run;
bpsnbaCheck(mode, _run);
b->calc_impulse(); // recalc nbp impulse response
b->fircore->setImpulse(b->impulse, 0); // calculate new filter masks
delete[] (b->impulse);
b->fircore->setImpulse(b->impulse.data(), 0); // calculate new filter masks
bpsnbaSet();
b->fircore->setUpdate(); // apply new filter masks
}
@ -1115,8 +1113,7 @@ void RXA::nbpSetWindow(int _wintype)
{
a->wintype = _wintype;
a->calc_impulse();
a->fircore->setImpulse(a->impulse, 1);
delete[] (a->impulse);
a->fircore->setImpulse(a->impulse.data(), 1);
}
if (b->wintype != _wintype)
@ -1137,8 +1134,7 @@ void RXA::nbpSetAutoIncrease(int _autoincr)
{
a->autoincr = _autoincr;
a->calc_impulse();
a->fircore->setImpulse(a->impulse, 1);
delete[] (a->impulse);
a->fircore->setImpulse(a->impulse.data(), 1);
}
if (b->autoincr != _autoincr)

View File

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

View File

@ -66,7 +66,9 @@ BANDPASS::BANDPASS(
wintype(_wintype),
gain(_gain)
{
float* impulse = FIR::fir_bandpass (
std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc,
f_low,
f_high,
@ -75,8 +77,7 @@ BANDPASS::BANDPASS(
1,
gain / (double)(2 * size)
);
fircore = new FIRCORE(size, in, out, nc, mp, impulse);
delete[] impulse;
fircore = new FIRCORE(size, in, out, nc, mp, impulse.data());
}
BANDPASS::~BANDPASS()
@ -107,7 +108,9 @@ void BANDPASS::setBuffers(float* _in, float* _out)
void BANDPASS::setSamplerate(int _rate)
{
samplerate = _rate;
float* impulse = FIR::fir_bandpass (
std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc,
f_low,
f_high,
@ -116,8 +119,7 @@ void BANDPASS::setSamplerate(int _rate)
1,
gain / (double) (2 * size)
);
fircore->setImpulse(impulse, 1);
delete[] impulse;
fircore->setImpulse(impulse.data(), 1);
}
void BANDPASS::setSize(int _size)
@ -126,7 +128,9 @@ void BANDPASS::setSize(int _size)
size = _size;
fircore->setSize(size);
// recalc impulse because scale factor is a function of size
float* impulse = FIR::fir_bandpass (
std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc,
f_low,
f_high,
@ -135,14 +139,15 @@ void BANDPASS::setSize(int _size)
1,
gain / (double) (2 * size)
);
fircore->setImpulse(impulse, 1);
delete[] impulse;
fircore->setImpulse(impulse.data(), 1);
}
void BANDPASS::setGain(double _gain, int _update)
{
gain = _gain;
float* impulse = FIR::fir_bandpass (
std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc,
f_low,
f_high,
@ -151,8 +156,7 @@ void BANDPASS::setGain(double _gain, int _update)
1,
gain / (double) (2 * size)
);
fircore->setImpulse(impulse, _update);
delete[] impulse;
fircore->setImpulse(impulse.data(), _update);
}
void BANDPASS::calcBandpassFilter(double _f_low, double _f_high, double _gain)
@ -162,7 +166,9 @@ void BANDPASS::calcBandpassFilter(double _f_low, double _f_high, double _gain)
f_low = _f_low;
f_high = _f_high;
gain = _gain;
float* impulse = FIR::fir_bandpass (
std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc,
f_low,
f_high,
@ -171,8 +177,7 @@ void BANDPASS::calcBandpassFilter(double _f_low, double _f_high, double _gain)
1,
gain / (double)(2 * size)
);
fircore->setImpulse(impulse, 1);
delete[] impulse;
fircore->setImpulse(impulse.data(), 1);
}
}
@ -186,7 +191,9 @@ void BANDPASS::setBandpassFreqs(double _f_low, double _f_high)
{
if ((_f_low != f_low) || (_f_high != f_high))
{
float* impulse = FIR::fir_bandpass (
std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc,
_f_low,
_f_high,
@ -196,8 +203,7 @@ void BANDPASS::setBandpassFreqs(double _f_low, double _f_high)
gain / (double)(2 * size)
);
fircore->setImpulse(impulse, 0);
delete[] impulse;
fircore->setImpulse(impulse.data(), 0);
f_low = _f_low;
f_high = _f_high;
fircore->setUpdate();
@ -210,7 +216,9 @@ void BANDPASS::SetBandpassNC(int _nc)
if (_nc != nc)
{
nc = _nc;
float* impulse = FIR::fir_bandpass (
std::vector<float> impulse;
FIR::fir_bandpass (
impulse,
nc,
f_low,
f_high,
@ -219,8 +227,7 @@ void BANDPASS::SetBandpassNC(int _nc)
1,
gain / (double)( 2 * size)
);
fircore->setNc(nc, impulse);
delete[] impulse;
fircore->setNc(nc, impulse.data());
}
}

View File

@ -42,14 +42,22 @@ namespace WDSP {
void BPS::calc()
{
float* impulse;
infilt.resize(2 * size * 2);
product.resize(2 * size * 2);
impulse = FIR::fir_bandpass(size + 1, f_low, f_high, samplerate, wintype, 1, 1.0 / (float)(2 * size));
FIR::fftcv_mults(mults, 2 * size, impulse);
std::vector<float> impulse;
FIR::fir_bandpass(
impulse,
size + 1,
f_low,
f_high,
samplerate,
wintype,
1,
1.0 / (float)(2 * size)
);
FIR::fftcv_mults(mults, 2 * size, impulse.data());
CFor = fftwf_plan_dft_1d(2 * size, (fftwf_complex *) infilt.data(), (fftwf_complex *) product.data(), FFTW_FORWARD, FFTW_PATIENT);
CRev = fftwf_plan_dft_1d(2 * size, (fftwf_complex *) product.data(), (fftwf_complex *) out, FFTW_BACKWARD, FFTW_PATIENT);
delete[]impulse;
}
void BPS::decalc()

View File

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

View File

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

View File

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

View File

@ -35,7 +35,7 @@ warren@pratt.one
namespace WDSP {
void FIR::fftcv_mults (std::vector<float>& mults, int NM, float* c_impulse)
void FIR::fftcv_mults (std::vector<float>& mults, int NM, const float* c_impulse)
{
mults.resize(NM * 2);
std::vector<float> cfft_impulse(NM * 2);
@ -199,9 +199,9 @@ void FIR::fir_fsamp (std::vector<float>& c_impulse, int N, const float* A, int r
}
}
float* FIR::fir_bandpass (int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale)
void FIR::fir_bandpass (std::vector<float>& c_impulse, int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale)
{
auto *c_impulse = new float[N * 2];
c_impulse.resize(N * 2);
double ft = (f_high - f_low) / (2.0 * samplerate);
double ft_rad = TWOPI * ft;
double w_osc = PI * (f_high + f_low) / samplerate;
@ -273,7 +273,6 @@ float* FIR::fir_bandpass (int N, double f_low, double f_high, double samplerate,
break;
}
}
return c_impulse;
}
void FIR::fir_read (std::vector<float>& c_impulse, int N, const char *filename, int rtype, float scale)

View File

@ -36,10 +36,10 @@ namespace WDSP {
class WDSP_API FIR
{
public:
static void fftcv_mults (std::vector<float>& mults, int NM, float* c_impulse);
static void fftcv_mults (std::vector<float>& mults, int NM, const float* impulse);
static void fir_fsamp_odd (std::vector<float>& c_impulse, int N, const float* A, int rtype, double scale, int wintype);
static void fir_fsamp (std::vector<float>& c_impulse, int N, const float* A, int rtype, double scale, int wintype);
static float* fir_bandpass (int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale);
static void fir_bandpass (std::vector<float>& impulse, int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale);
static void mp_imp (int N, std::vector<float>& fir, std::vector<float>& mpfir, int pfactor, int polarity);
private:

View File

@ -124,7 +124,7 @@ FIRCORE::FIRCORE(
float* _out,
int _nc,
int _mp,
float* _impulse
const float* _impulse
)
{
size = _size;
@ -204,13 +204,13 @@ void FIRCORE::setSize(int _size)
calc(1);
}
void FIRCORE::setImpulse(float* _impulse, int _update)
void FIRCORE::setImpulse(const float* _impulse, int _update)
{
std::copy(_impulse, _impulse + nc * 2, impulse.begin());
calc(_update);
}
void FIRCORE::setNc(int _nc, float* _impulse)
void FIRCORE::setNc(int _nc, const float* _impulse)
{
// because of FFT planning, this will probably cause a glitch in audio if done during dataflow
deplan();

View File

@ -72,8 +72,7 @@ public:
float* out,
int nc,
int mp,
float*
impulse
const float* impulse
);
FIRCORE(const FIRCORE&) = delete;
FIRCORE& operator=(const FIRCORE& other) = delete;
@ -83,8 +82,8 @@ public:
void execute();
void setBuffers(float* in, float* out);
void setSize(int size);
void setImpulse(float* impulse, int update);
void setNc(int nc, float* impulse);
void setImpulse(const float* impulse, int update);
void setNc(int nc, const float* impulse);
void setMp(int mp);
void setUpdate();

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

View File

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

View File

@ -44,16 +44,16 @@ void FIROPT::plan_firopt (FIROPT *a)
a->nfor = a->nc / a->size;
a->buffidx = 0;
a->idxmask = a->nfor - 1;
a->fftin = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
a->fftout = new float*[a->nfor]; // (float **) malloc0 (a->nfor * sizeof (float *));
a->fmask = new float*[a->nfor]; // (float **) malloc0 (a->nfor * sizeof (float *));
a->maskgen = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
a->pcfor = new fftwf_plan[a->nfor]; // (fftwf_plan *) malloc0 (a->nfor * sizeof (fftwf_plan));
a->maskplan = new fftwf_plan[a->nfor]; // (fftwf_plan *) malloc0 (a->nfor * sizeof (fftwf_plan));
a->fftin = new float[2 * a->size * 2];
a->fftout = new float*[a->nfor];
a->fmask = new float*[a->nfor];
a->maskgen = new float[2 * a->size * 2];
a->pcfor = new fftwf_plan[a->nfor];
a->maskplan = new fftwf_plan[a->nfor];
for (i = 0; i < a->nfor; i++)
{
a->fftout[i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
a->fmask[i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
a->fftout[i] = new float[2 * a->size * 2];
a->fmask[i] = new float[2 * a->size * 2];
a->pcfor[i] = fftwf_plan_dft_1d(
2 * a->size,
(fftwf_complex *)a->fftin,
@ -69,7 +69,7 @@ void FIROPT::plan_firopt (FIROPT *a)
FFTW_PATIENT
);
}
a->accum = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
a->accum = new float[2 * a->size * 2];
a->crev = fftwf_plan_dft_1d(
2 * a->size,
(fftwf_complex *)a->accum,
@ -83,17 +83,16 @@ void FIROPT::calc_firopt (FIROPT *a)
{
// call for change in frequency, rate, wintype, gain
// must also call after a call to plan_firopt()
int i;
float* impulse = FIR::fir_bandpass (a->nc, a->f_low, a->f_high, a->samplerate, a->wintype, 1, a->gain);
std::vector<float> impulse;
FIR::fir_bandpass (impulse, a->nc, a->f_low, a->f_high, a->samplerate, a->wintype, 1, a->gain);
a->buffidx = 0;
for (i = 0; i < a->nfor; i++)
for (int i = 0; i < a->nfor; i++)
{
// I right-justified the impulse response => take output from left side of output buff, discard right side
// Be careful about flipping an asymmetrical impulse response.
std::copy(&(impulse[2 * a->size * i]), &(impulse[2 * a->size * i]) + a->size * 2, &(a->maskgen[2 * a->size]));
fftwf_execute (a->maskplan[i]);
}
delete[] (impulse);
}
FIROPT* FIROPT::create_firopt (int run, int position, int size, float* in, float* out,
@ -108,7 +107,7 @@ FIROPT* FIROPT::create_firopt (int run, int position, int size, float* in, float
a->nc = nc;
a->f_low = f_low;
a->f_high = f_high;
a->samplerate = samplerate;
a->samplerate = (float) samplerate;
a->wintype = wintype;
a->gain = gain;
plan_firopt (a);
@ -144,9 +143,8 @@ void FIROPT::destroy_firopt (FIROPT *a)
void FIROPT::flush_firopt (FIROPT *a)
{
int i;
std::fill(a->fftin, a->fftin + 2 * a->size * 2, 0);
for (i = 0; i < a->nfor; i++)
for (int i = 0; i < a->nfor; i++)
std::fill(a->fftout[i], a->fftout[i] + 2 * a->size * 2, 0);
a->buffidx = 0;
}
@ -155,14 +153,14 @@ void FIROPT::xfiropt (FIROPT *a, int pos)
{
if (a->run && (a->position == pos))
{
int i, j, k;
int k;
std::copy(a->in, a->in + a->size * 2, &(a->fftin[2 * a->size]));
fftwf_execute (a->pcfor[a->buffidx]);
k = a->buffidx;
std::fill(a->accum, a->accum + 2 * a->size * 2, 0);
for (j = 0; j < a->nfor; j++)
for (int j = 0; j < a->nfor; j++)
{
for (i = 0; i < 2 * a->size; i++)
for (int i = 0; i < 2 * a->size; i++)
{
a->accum[2 * i + 0] += a->fftout[k][2 * i + 0] * a->fmask[j][2 * i + 0] - a->fftout[k][2 * i + 1] * a->fmask[j][2 * i + 1];
a->accum[2 * i + 1] += a->fftout[k][2 * i + 0] * a->fmask[j][2 * i + 1] + a->fftout[k][2 * i + 1] * a->fmask[j][2 * i + 0];
@ -188,7 +186,7 @@ void FIROPT::setBuffers_firopt (FIROPT *a, float* in, float* out)
void FIROPT::setSamplerate_firopt (FIROPT *a, int rate)
{
a->samplerate = rate;
a->samplerate = (float) rate;
calc_firopt (a);
}

View File

@ -34,6 +34,8 @@ warren@wpratt.com
#ifndef wdsp_firopt_h
#define wdsp_firopt_h
#include <vector>
#include "fftw3.h"
#include "export.h"

View File

@ -161,8 +161,9 @@ FMD::FMD(
);
pde = new FIRCORE(size, audio.data(), out, nc_de, mp_de, impulse.data());
// audio filter
float *impulseb = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulseb);
std::vector<float> impulseb;
FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulseb.data());
}
FMD::~FMD()
@ -267,9 +268,9 @@ void FMD::setSamplerate(int _rate)
);
pde->setImpulse(impulse.data(), 1);
// audio filter
float* impulseb = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud->setImpulse(impulseb, 1);
delete[] impulseb;
std::vector<float> impulseb;
FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud->setImpulse(impulseb.data(), 1);
plim->setSamplerate((int) rate);
}
@ -298,9 +299,9 @@ void FMD::setSize(int _size)
pde = new FIRCORE(size, audio.data(), out, nc_de, mp_de, impulse.data());
// audio filter
delete (paud);
float* impulseb = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulseb);
delete[] impulseb;
std::vector<float> impulseb;
FIR::fir_bandpass(impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud = new FIRCORE(size, out, out, nc_aud, mp_aud, impulseb.data());
plim->setSize(size);
}
@ -367,9 +368,9 @@ void FMD::setNCaud(int nc)
if (nc_aud != nc)
{
nc_aud = nc;
impulse = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud->setNc(nc_aud, impulse);
delete[] impulse;
std::vector<float> impulse;
FIR::fir_bandpass(impulse, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud->setNc(nc_aud, impulse.data());
}
}
@ -424,9 +425,9 @@ void FMD::setAFFilter(double low, double high)
);
pde->setImpulse(impulse.data(), 1);
// audio filter
float* impulseb = FIR::fir_bandpass (nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud->setImpulse(impulseb, 1);
delete[] impulseb;
std::vector<float> impulseb;
FIR::fir_bandpass (impulseb, nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
paud->setImpulse(impulseb.data(), 1);
}
}

View File

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

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

View File

@ -80,7 +80,7 @@ public:
int autoincr; // auto-increment notch width
double flow; // low bandpass cutoff freq
double fhigh; // high bandpass cutoff freq
float* impulse; // filter impulse response
std::vector<float> impulse; // filter impulse response
int maxpb; // maximum number of passbands
NOTCHDB* notchdb; // ptr to addr of notch-database data structure
std::vector<double> bplow; // array of passband lows
@ -129,7 +129,7 @@ public:
void calc_lightweight();
private:
static float* fir_mbandpass (int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype);
static void fir_mbandpass (std::vector<float>& impulse, int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype);
double min_notch_width () const;
static int make_nbp (
int nn,

View File

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

View File

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

View File

@ -36,11 +36,11 @@ namespace WDSP {
MAV* MAV::create_mav (int ringmin, int ringmax, float nom_value)
{
MAV *a = new MAV;
auto *a = new MAV;
a->ringmin = ringmin;
a->ringmax = ringmax;
a->nom_value = nom_value;
a->ring = new int[a->ringmax]; // (int *) malloc0 (a->ringmax * sizeof (int));
a->ring = new int[a->ringmax];
a->mask = a->ringmax - 1;
a->i = 0;
a->load = 0;
@ -50,8 +50,8 @@ MAV* MAV::create_mav (int ringmin, int ringmax, float nom_value)
void MAV::destroy_mav (MAV *a)
{
delete[] (a->ring);
delete (a);
delete[] a->ring;
delete a;
}
void MAV::flush_mav (MAV *a)
@ -79,11 +79,11 @@ void MAV::xmav (MAV *a, int input, float* output)
AAMAV* AAMAV::create_aamav (int ringmin, int ringmax, float nom_ratio)
{
AAMAV *a = new AAMAV;
auto *a = new AAMAV;
a->ringmin = ringmin;
a->ringmax = ringmax;
a->nom_ratio = nom_ratio;
a->ring = new int[a->ringmax]; // (int *) malloc0 (a->ringmax * sizeof (int));
a->ring = new int[a->ringmax];
a->mask = a->ringmax - 1;
a->i = 0;
a->load = 0;
@ -94,8 +94,8 @@ AAMAV* AAMAV::create_aamav (int ringmin, int ringmax, float nom_ratio)
void AAMAV::destroy_aamav (AAMAV *a)
{
delete[] (a->ring);
delete[] (a);
delete[] a->ring;
delete[] a;
}
void AAMAV::flush_aamav (AAMAV *a)
@ -137,37 +137,38 @@ void AAMAV::xaamav (AAMAV *a, int input, float* output)
void RMATCH::calc_rmatch (RMATCH *a)
{
int m;
float theta, dtheta;
float theta;
float dtheta;
int max_ring_insize;
a->nom_ratio = (float)a->nom_outrate / (float)a->nom_inrate;
max_ring_insize = (int)(1.0 + (float)a->insize * (1.05 * a->nom_ratio));
if (a->ringsize < 2 * max_ring_insize) a->ringsize = 2 * max_ring_insize;
if (a->ringsize < 2 * a->outsize) a->ringsize = 2 * a->outsize;
a->ring = new float[a->ringsize * 2]; // (float *) malloc0 (a->ringsize * sizeof (complex));
a->ring = new float[a->ringsize * 2];
a->rsize = a->ringsize;
a->n_ring = a->rsize / 2;
a->iin = a->rsize / 2;
a->iout = 0;
a->resout = new float[max_ring_insize * 2]; // (float *) malloc0 (max_ring_insize * sizeof (complex));
a->v = VARSAMP::create_varsamp (1, a->insize, a->in, a->resout, a->nom_inrate, a->nom_outrate,
a->resout = new float[max_ring_insize * 2];
a->v = new VARSAMP(1, a->insize, a->in, a->resout, a->nom_inrate, a->nom_outrate,
a->fc_high, a->fc_low, a->R, a->gain, a->var, a->varmode);
a->ffmav = AAMAV::create_aamav (a->ff_ringmin, a->ff_ringmax, a->nom_ratio);
a->propmav = MAV::create_mav (a->prop_ringmin, a->prop_ringmax, 0.0);
a->pr_gain = a->prop_gain * 48000.0 / (float)a->nom_outrate; // adjust gain for rate
a->pr_gain = a->prop_gain * 48000.0f / (float)a->nom_outrate; // adjust gain for rate
a->inv_nom_ratio = (float)a->nom_inrate / (float)a->nom_outrate;
a->feed_forward = 1.0;
a->av_deviation = 0.0;
a->ntslew = (int)(a->tslew * a->nom_outrate);
a->ntslew = (int)(a->tslew * (float) a->nom_outrate);
if (a->ntslew + 1 > a->rsize / 2) a->ntslew = a->rsize / 2 - 1;
a->cslew = new float[a->ntslew + 1]; // (float *) malloc0 ((a->ntslew + 1) * sizeof (float));
dtheta = PI / (float)a->ntslew;
a->cslew = new float[a->ntslew + 1];
dtheta = (float) PI / (float) a->ntslew;
theta = 0.0;
for (m = 0; m <= a->ntslew; m++)
{
a->cslew[m] = 0.5 * (1.0 - cos (theta));
a->cslew[m] = 0.5f * (1.0f - cos (theta));
theta += dtheta;
}
a->baux = new float[a->ringsize / 2 * 2]; // (float *) malloc0 (a->ringsize / 2 * sizeof (complex));
a->baux = new float[a->ringsize / 2 * 2];
a->readsamps = 0;
a->writesamps = 0;
a->read_startup = (unsigned int)((float)a->nom_outrate * a->startup_delay);
@ -184,7 +185,7 @@ void RMATCH::decalc_rmatch (RMATCH *a)
delete[] (a->cslew);
MAV::destroy_mav (a->propmav);
AAMAV::destroy_aamav (a->ffmav);
VARSAMP::destroy_varsamp (a->v);
delete a->v;
delete[] (a->resout);
delete[] (a->ring);
}
@ -215,7 +216,7 @@ RMATCH* RMATCH::create_rmatch (
float tslew // slew/blend time (seconds)
)
{
RMATCH *a = new RMATCH;
auto *a = new RMATCH;
a->run = run;
a->in = in;
a->out = out;
@ -246,7 +247,7 @@ RMATCH* RMATCH::create_rmatch (
void RMATCH::destroy_rmatch (RMATCH *a)
{
decalc_rmatch (a);
delete (a);
delete a;
}
void RMATCH::reset_rmatch (RMATCH *a)
@ -264,30 +265,32 @@ void RMATCH::control (RMATCH *a, int change)
float current_ratio;
AAMAV::xaamav (a->ffmav, change, &current_ratio);
current_ratio *= a->inv_nom_ratio;
a->feed_forward = a->ff_alpha * current_ratio + (1.0 - a->ff_alpha) * a->feed_forward;
a->feed_forward = a->ff_alpha * current_ratio + (1.0f - a->ff_alpha) * a->feed_forward;
}
{
int deviation = a->n_ring - a->rsize / 2;
MAV::xmav (a->propmav, deviation, &a->av_deviation);
}
a->var = a->feed_forward - a->pr_gain * a->av_deviation;
if (a->var > 1.04) a->var = 1.04;
if (a->var < 0.96) a->var = 0.96;
if (a->var > 1.04) a->var = 1.04f;
if (a->var < 0.96) a->var = 0.96f;
}
void RMATCH::blend (RMATCH *a)
{
int i, j;
int i;
int j;
for (i = 0, j = a->iout; i <= a->ntslew; i++, j = (j + 1) % a->rsize)
{
a->ring[2 * j + 0] = a->cslew[i] * a->ring[2 * j + 0] + (1.0 - a->cslew[i]) * a->baux[2 * i + 0];
a->ring[2 * j + 1] = a->cslew[i] * a->ring[2 * j + 1] + (1.0 - a->cslew[i]) * a->baux[2 * i + 1];
a->ring[2 * j + 0] = a->cslew[i] * a->ring[2 * j + 0] + (1.0f - a->cslew[i]) * a->baux[2 * i + 0];
a->ring[2 * j + 1] = a->cslew[i] * a->ring[2 * j + 1] + (1.0f - a->cslew[i]) * a->baux[2 * i + 1];
}
}
void RMATCH::upslew (RMATCH *a, int newsamps)
{
int i, j;
int i;
int j;
i = 0;
j = a->iin;
while (a->ucnt >= 0 && i < newsamps)
@ -302,10 +305,13 @@ void RMATCH::upslew (RMATCH *a, int newsamps)
void RMATCH::xrmatchIN (void* b, float* in)
{
RMATCH *a = (RMATCH*) b;
auto *a = (RMATCH*) b;
if (a->run == 1)
{
int newsamps, first, second, ovfl;
int newsamps;
int first;
int second;
int ovfl;
float var;
a->v->in = a->in = in;
@ -314,13 +320,12 @@ void RMATCH::xrmatchIN (void* b, float* in)
else
var = a->fvar;
newsamps = VARSAMP::xvarsamp (a->v, var);
newsamps = a->v->execute(var);
a->n_ring += newsamps;
if ((ovfl = a->n_ring - a->rsize) > 0)
{
a->overflows += 1;
// a->n_ring = a->rsize / 2;
a->n_ring = a->rsize; //
if ((a->ntslew + 1) > (a->rsize - a->iout))
@ -336,7 +341,6 @@ void RMATCH::xrmatchIN (void* b, float* in)
std::copy(a->ring + 2 * a->iout, a->ring + 2 * a->iout + first * 2, a->baux);
std::copy(a->ring, a->ring + second * 2, a->baux + 2 * first);
// a->iout = (a->iout + ovfl + a->rsize / 2) % a->rsize;
a->iout = (a->iout + ovfl) % a->rsize; //
}
@ -376,8 +380,13 @@ void RMATCH::xrmatchIN (void* b, float* in)
void RMATCH::dslew (RMATCH *a)
{
int i, j, k, n;
int zeros, first, second;
int i;
int j;
int k;
int n;
int zeros;
int first;
int second;
if (a->n_ring > a->ntslew + 1)
{
i = (a->iout + (a->n_ring - (a->ntslew + 1))) % a->rsize;
@ -414,7 +423,7 @@ void RMATCH::dslew (RMATCH *a)
j--;
n++;
}
// zeros = a->outsize + a->rsize / 2 - n;
if ((zeros = a->outsize - n) > 0) //
{ //
if (zeros > a->rsize - i)
@ -429,21 +438,20 @@ void RMATCH::dslew (RMATCH *a)
}
std::fill(a->ring + 2 * i, a->ring + 2 * i + first * 2, 0);
std::fill(a->ring, a->ring + second * 2, 0);
n += zeros; //
} //
// a->n_ring = a->outsize + a->rsize / 2;
a->n_ring = n; //
// a->iin = (a->iout + a->outsize + a->rsize/2) % a->rsize;
a->iin = (a->iout + a->n_ring) % a->rsize; //
n += zeros;
}
a->n_ring = n;
a->iin = (a->iout + a->n_ring) % a->rsize;
}
void RMATCH::xrmatchOUT (void* b, float* out)
{
RMATCH *a = (RMATCH*) b;
auto *a = (RMATCH*) b;
if (a->run == 1)
{
int first, second;
int first;
int second;
a->out = out;
if (a->n_ring < a->outsize)
@ -487,7 +495,7 @@ void RMATCH::xrmatchOUT (void* b, float* out)
void RMATCH::getRMatchDiags (void* b, int* underflows, int* overflows, float* var, int* ringsize, int* nring)
{
RMATCH *a = (RMATCH*) b;
auto *a = (RMATCH*) b;
*underflows = a->underflows;
*overflows = a->overflows;
a->underflows &= 0xFFFFFFFF;
@ -500,15 +508,12 @@ void RMATCH::getRMatchDiags (void* b, int* underflows, int* overflows, float* va
void RMATCH::resetRMatchDiags (void*)
{
// RMATCH *a = (RMATCH*) b;
// InterlockedExchange (&a->underflows, 0);
// InterlockedExchange (&a->overflows, 0);
}
void RMATCH::forceRMatchVar (void* b, int force, float fvar)
{
RMATCH *a = (RMATCH*) b;
auto *a = (RMATCH*) b;
a->force = force;
a->fvar = fvar;
}
@ -518,8 +523,8 @@ void* RMATCH::create_rmatchV(int in_size, int out_size, int nom_inrate, int nom_
{
return (void*)create_rmatch (
1, // run
0, // input buffer, stuffed in other calls
0, // output buffer, stuffed in other calls
nullptr, // input buffer, stuffed in other calls
nullptr, // output buffer, stuffed in other calls
in_size, // input buffer size (complex samples)
out_size, // output buffer size (complex samples)
nom_inrate, // nominal input sample-rate
@ -534,25 +539,25 @@ void* RMATCH::create_rmatchV(int in_size, int out_size, int nom_inrate, int nom_
var, // initial variable ratio
4096, // feed-forward moving average min size
262144, // feed-forward moving average max size - POWER OF TWO!
0.01, // feed-forward exponential smoothing
0.01f, // feed-forward exponential smoothing
4096, // proportional feedback min moving av ringsize
16384, // proportional feedback max moving av ringsize - POWER OF TWO!
4.0e-06, // proportional feedback gain
4.0e-06f, // proportional feedback gain
1, // linearly interpolate cvar by sample
0.003 ); // slew time (seconds)
0.003f ); // slew time (seconds)
}
void RMATCH::destroy_rmatchV (void* ptr)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
destroy_rmatch (a);
}
void RMATCH::setRMatchInsize (void* ptr, int insize)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a);
@ -564,7 +569,7 @@ void RMATCH::setRMatchInsize (void* ptr, int insize)
void RMATCH::setRMatchOutsize (void* ptr, int outsize)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a);
@ -576,7 +581,7 @@ void RMATCH::setRMatchOutsize (void* ptr, int outsize)
void RMATCH::setRMatchNomInrate (void* ptr, int nom_inrate)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a);
@ -588,7 +593,7 @@ void RMATCH::setRMatchNomInrate (void* ptr, int nom_inrate)
void RMATCH::setRMatchNomOutrate (void* ptr, int nom_outrate)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a);
@ -600,7 +605,7 @@ void RMATCH::setRMatchNomOutrate (void* ptr, int nom_outrate)
void RMATCH::setRMatchRingsize (void* ptr, int ringsize)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10));
decalc_rmatch(a);
@ -612,7 +617,7 @@ void RMATCH::setRMatchRingsize (void* ptr, int ringsize)
void RMATCH::setRMatchFeedbackGain (void* b, float feedback_gain)
{
RMATCH *a = (RMATCH*) b;
auto *a = (RMATCH*) b;
a->prop_gain = feedback_gain;
a->pr_gain = a->prop_gain * 48000.0 / (float)a->nom_outrate;
}
@ -620,9 +625,8 @@ void RMATCH::setRMatchFeedbackGain (void* b, float feedback_gain)
void RMATCH::setRMatchSlewTime (void* b, float slew_time)
{
RMATCH *a = (RMATCH*) b;
a->run = 0; // InterlockedBitTestAndReset(&a->run, 0); // turn OFF new data coming into the rmatch
// Sleep(10); // wait for processing to cease
auto *a = (RMATCH*) b;
a->run = 0;
decalc_rmatch(a); // deallocate all memory EXCEPT the data structure holding all current parameters
a->tslew = slew_time; // change the value of 'slew_time'
calc_rmatch(a); // recalculate/reallocate everything in the RMATCH
@ -632,21 +636,20 @@ void RMATCH::setRMatchSlewTime (void* b, float slew_time)
void RMATCH::setRMatchSlewTime1(void* b, float slew_time)
{
RMATCH *a = (RMATCH*) b;
float theta, dtheta;
int m;
auto *a = (RMATCH*) b;
float theta;
float dtheta;
a->run = 0;
// Sleep(10);
delete[](a->cslew);
delete[] a->cslew;
a->tslew = slew_time;
a->ntslew = (int)(a->tslew * a->nom_outrate);
a->ntslew = (int)(a->tslew * (float) a->nom_outrate);
if (a->ntslew + 1 > a->rsize / 2) a->ntslew = a->rsize / 2 - 1;
a->cslew = new float[a->ntslew + 1]; // (float*)malloc0((a->ntslew + 1) * sizeof(float));
dtheta = PI / (float)a->ntslew;
dtheta = (float) PI / (float)a->ntslew;
theta = 0.0;
for (m = 0; m <= a->ntslew; m++)
for (int m = 0; m <= a->ntslew; m++)
{
a->cslew[m] = 0.5 * (1.0 - cos(theta));
a->cslew[m] = 0.5f * (1.0f - cos(theta));
theta += dtheta;
}
a->run = 1;
@ -655,9 +658,8 @@ void RMATCH::setRMatchSlewTime1(void* b, float slew_time)
void RMATCH::setRMatchPropRingMin(void* ptr, int prop_min)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
// Sleep(10);
decalc_rmatch(a);
a->prop_ringmin = prop_min;
calc_rmatch(a);
@ -667,9 +669,8 @@ void RMATCH::setRMatchPropRingMin(void* ptr, int prop_min)
void RMATCH::setRMatchPropRingMax(void* ptr, int prop_max)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
// Sleep(10);
decalc_rmatch(a);
a->prop_ringmax = prop_max; // must be a power of two
calc_rmatch(a);
@ -679,9 +680,8 @@ void RMATCH::setRMatchPropRingMax(void* ptr, int prop_max)
void RMATCH::setRMatchFFRingMin(void* ptr, int ff_ringmin)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
// Sleep(10);
decalc_rmatch(a);
a->ff_ringmin = ff_ringmin;
calc_rmatch(a);
@ -691,9 +691,8 @@ void RMATCH::setRMatchFFRingMin(void* ptr, int ff_ringmin)
void RMATCH::setRMatchFFRingMax(void* ptr, int ff_ringmax)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
// Sleep(10);
decalc_rmatch(a);
a->ff_ringmax = ff_ringmax; // must be a power of two
calc_rmatch(a);
@ -703,7 +702,7 @@ void RMATCH::setRMatchFFRingMax(void* ptr, int ff_ringmax)
void RMATCH::setRMatchFFAlpha(void* ptr, float ff_alpha)
{
RMATCH *a = (RMATCH*) ptr;
auto *a = (RMATCH*) ptr;
a->run = 0;
std::this_thread::sleep_for(std::chrono::seconds(10));
a->ff_alpha = ff_alpha;
@ -713,7 +712,7 @@ void RMATCH::setRMatchFFAlpha(void* ptr, float ff_alpha)
void RMATCH::getControlFlag(void* ptr, int* control_flag)
{
RMATCH *a = (RMATCH*) ptr;
RMATCH const *a = (RMATCH*) ptr;
*control_flag = a->control_flag;
}
@ -724,8 +723,8 @@ void* RMATCH::create_rmatchLegacyV(int in_size, int out_size, int nom_inrate, in
{
return (void*) create_rmatch(
1, // run
0, // input buffer, stuffed in other calls
0, // output buffer, stuffed in other calls
nullptr, // input buffer, stuffed in other calls
nullptr, // output buffer, stuffed in other calls
in_size, // input buffer size (complex samples)
out_size, // output buffer size (complex samples)
nom_inrate, // nominal input sample-rate
@ -740,12 +739,12 @@ void* RMATCH::create_rmatchLegacyV(int in_size, int out_size, int nom_inrate, in
1.0, // initial variable ratio
4096, // feed-forward moving average min size
262144, // feed-forward moving average max size - POWER OF TWO!
0.01, // feed-forward exponential smoothing
0.01f, // feed-forward exponential smoothing
4096, // proportional feedback min moving av ringsize
16384, // proportional feedback max moving av ringsize - POWER OF TWO!
1.0e-06, // proportional feedback gain ***W4WMT - reduce loop gain a bit for PowerSDR to help Primary buffers > 512
1.0e-06f, // proportional feedback gain ***W4WMT - reduce loop gain a bit for PowerSDR to help Primary buffers > 512
0, // linearly interpolate cvar by sample ***W4WMT - set varmode = 0 for PowerSDR (doesn't work otherwise!?!)
0.003); // slew time (seconds)
0.003f); // slew time (seconds)
}
} // namespace WDSP

View File

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

View File

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