mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-21 23:55:13 -05:00
Compare commits
13 Commits
ed6d7a6980
...
22307b9afc
Author | SHA1 | Date | |
---|---|---|---|
|
22307b9afc | ||
|
ef0255f2bb | ||
|
12f4d0a0fd | ||
|
e48dc22793 | ||
|
ad3e7dfe19 | ||
|
28cfad98ff | ||
|
7319e4cb88 | ||
|
62f05b3706 | ||
|
fcd43df711 | ||
|
ff7c06311b | ||
|
5888645957 | ||
|
2fddaff6d2 | ||
|
4cf2c0b7c7 |
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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__":
|
||||||
|
@ -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)
|
||||||
|
61
wdsp/TXA.cpp
61
wdsp/TXA.cpp
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
wdsp/bps.cpp
17
wdsp/bps.cpp
@ -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(
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************************************
|
/********************************************************************************************************
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************************************
|
/********************************************************************************************************
|
||||||
|
@ -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,
|
||||||
|
139
wdsp/delay.cpp
139
wdsp/delay.cpp
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
wdsp/eq.cpp
10
wdsp/eq.cpp
@ -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()
|
||||||
|
95
wdsp/eqp.cpp
95
wdsp/eqp.cpp
@ -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
|
||||||
|
12
wdsp/eqp.hpp
12
wdsp/eqp.hpp
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
50
wdsp/fir.cpp
50
wdsp/fir.cpp
@ -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
|
||||||
|
14
wdsp/fir.hpp
14
wdsp/fir.hpp
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
122
wdsp/firmin.cpp
122
wdsp/firmin.cpp
@ -37,94 +37,96 @@ namespace WDSP {
|
|||||||
* *
|
* *
|
||||||
********************************************************************************************************/
|
********************************************************************************************************/
|
||||||
|
|
||||||
void FIRMIN::calc_firmin (FIRMIN *a)
|
void FIRMIN::calc()
|
||||||
{
|
{
|
||||||
a->h = FIR::fir_bandpass (a->nc, a->f_low, a->f_high, a->samplerate, a->wintype, 1, a->gain);
|
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
|
||||||
|
@ -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
|
||||||
|
217
wdsp/firopt.cpp
217
wdsp/firopt.cpp
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
78
wdsp/fmd.cpp
78
wdsp/fmd.cpp
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
33
wdsp/nbp.cpp
33
wdsp/nbp.cpp
@ -158,21 +158,20 @@ void NOTCHDB::getNumNotches(int* _nnotches) const
|
|||||||
* *
|
* *
|
||||||
********************************************************************************************************/
|
********************************************************************************************************/
|
||||||
|
|
||||||
float* NBP::fir_mbandpass (int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype)
|
void NBP::fir_mbandpass (std::vector<float>& impulse, int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype)
|
||||||
{
|
{
|
||||||
auto* impulse = new float[N * 2];
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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 (
|
||||||
|
@ -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;
|
||||||
|
175
wdsp/rmatch.cpp
175
wdsp/rmatch.cpp
@ -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, ¤t_ratio);
|
AAMAV::xaamav (a->ffmav, change, ¤t_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
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void calc();
|
void calc();
|
||||||
void decalc();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace WDSP
|
} // namespace WDSP
|
||||||
|
280
wdsp/varsamp.cpp
280
wdsp/varsamp.cpp
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user