From 34917a0b214b74a90e5b9e8c19deba2aee188a95 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 5 Aug 2024 20:05:59 +0200 Subject: [PATCH] WDSP: more rework --- plugins/channelrx/wdsprx/wdsprxsink.cpp | 78 +-- plugins/channelrx/wdsprx/wdsprxsink.h | 9 +- wdsp/CMakeLists.txt | 2 + wdsp/RXA.cpp | 47 +- wdsp/RXA.hpp | 14 +- wdsp/TXA.cpp | 157 ++++-- wdsp/TXA.hpp | 6 +- wdsp/amd.cpp | 30 +- wdsp/ammod.cpp | 82 +-- wdsp/ammod.hpp | 32 +- wdsp/anb.cpp | 11 +- wdsp/anf.cpp | 2 +- wdsp/bldr.cpp | 351 ++++++------ wdsp/bldr.hpp | 79 +-- wdsp/bps.cpp | 282 +++------- wdsp/bps.hpp | 52 +- wdsp/bqbp.cpp | 19 +- wdsp/bqlp.cpp | 16 +- wdsp/bqlp.hpp | 13 +- wdsp/cblock.cpp | 16 +- wdsp/cfcomp.cpp | 676 ++++++++++++------------ wdsp/cfcomp.hpp | 127 ++--- wdsp/compress.cpp | 16 +- wdsp/compress.hpp | 4 +- wdsp/dbqbp.cpp | 16 +- wdsp/dbqbp.hpp | 13 +- wdsp/dsphp.cpp | 16 +- wdsp/emnr.cpp | 6 +- wdsp/emph.cpp | 274 +++------- wdsp/emph.hpp | 89 +--- wdsp/emphp.cpp | 217 ++++++++ wdsp/emphp.hpp | 91 ++++ 32 files changed, 1483 insertions(+), 1360 deletions(-) create mode 100644 wdsp/emphp.cpp create mode 100644 wdsp/emphp.hpp diff --git a/plugins/channelrx/wdsprx/wdsprxsink.cpp b/plugins/channelrx/wdsprx/wdsprxsink.cpp index 3ba83b5ff..3c198ad47 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsink.cpp @@ -26,7 +26,6 @@ #include "util/messagequeue.h" #include "maincore.h" #include "RXA.hpp" -#include "nbp.hpp" #include "meter.hpp" #include "patchpanel.hpp" #include "wcpAGC.hpp" @@ -83,10 +82,10 @@ void WDSPRxSink::SpectrumProbe::proceed(const float *in, int nb_samples) { if (!(m_undersampleCount++ & decim_mask)) { - float avgr = m_sum.real() / decim; - float avgi = m_sum.imag() / decim; + float avgr = m_sum.real() / (float) decim; + float avgi = m_sum.imag() / (float) decim; - if (!m_dsb & !m_usb) + if (!m_dsb && !m_usb) { // invert spectrum for LSB m_sampleVector.push_back(Sample(avgi*SDR_RX_SCALEF, avgr*SDR_RX_SCALEF)); } @@ -175,14 +174,14 @@ void WDSPRxSink::feed(const SampleVector::const_iterator& begin, const SampleVec } } -void WDSPRxSink::getMagSqLevels(double& avg, double& peak, int& nbSamples) +void WDSPRxSink::getMagSqLevels(double& avg, double& peak, int& nbSamples) const { avg = m_sAvg; peak = m_sPeak; nbSamples = m_sCount; } -void WDSPRxSink::processOneSample(Complex &ci) +void WDSPRxSink::processOneSample(const Complex &ci) { m_rxa->get_inbuff()[2*m_inCount] = ci.imag() / SDR_RX_SCALEF; m_rxa->get_inbuff()[2*m_inCount+1] = ci.real() / SDR_RX_SCALEF; @@ -204,10 +203,10 @@ void WDSPRxSink::processOneSample(Complex &ci) } else { - const double& cr = m_rxa->get_outbuff()[2*i+1]; - const double& ci = m_rxa->get_outbuff()[2*i]; - qint16 zr = cr * 32768.0; - qint16 zi = ci * 32768.0; + const double& dr = m_rxa->get_outbuff()[2*i+1]; + const double& di = m_rxa->get_outbuff()[2*i]; + qint16 zr = dr * 32768.0; + qint16 zi = di * 32768.0; m_audioBuffer[m_audioBufferFill].r = zr; m_audioBuffer[m_audioBufferFill].l = zi; @@ -219,7 +218,7 @@ void WDSPRxSink::processOneSample(Complex &ci) else { Real demod = (zr + zi) * 0.7; - qint16 sample = (qint16)(demod); + auto sample = (qint16)(demod); m_demodBuffer[m_demodBufferFill++] = sample; } @@ -228,13 +227,11 @@ void WDSPRxSink::processOneSample(Complex &ci) QList dataPipes; MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes); - if (dataPipes.size() > 0) + if (!dataPipes.empty()) { - QList::iterator it = dataPipes.begin(); - - for (; it != dataPipes.end(); ++it) + for (auto dataPipe : dataPipes) { - DataFifo *fifo = qobject_cast((*it)->m_element); + DataFifo *fifo = qobject_cast(dataPipe->m_element); if (fifo) { @@ -245,7 +242,7 @@ void WDSPRxSink::processOneSample(Complex &ci) ); } } - } + } m_demodBufferFill = 0; } @@ -316,7 +313,7 @@ void WDSPRxSink::applyAudioSampleRate(int sampleRate) QList pipes; MainCore::instance()->getMessagePipes().getMessagePipes(m_channel, "reportdemod", pipes); - if (pipes.size() > 0) + if (!pipes.empty()) { for (const auto& pipe : pipes) { @@ -385,8 +382,13 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) (m_settings.m_demod != settings.m_demod) || (m_settings.m_dsb != settings.m_dsb) || force) { - float band, low, high, fLow, fHigh; - bool usb, dsb; + float band; + float low; + float high; + float fLow; + float fHigh; + bool usb; + bool dsb; band = settings.m_profiles[settings.m_profileIndex].m_highCutoff; high = band; @@ -770,8 +772,8 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) || (m_settings.m_agcHangThreshold != settings.m_agcHangThreshold) || (m_settings.m_agcGain != settings.m_agcGain) || force) { - m_rxa->agc->setSlope(settings.m_agcSlope); // SetRXAAGCSlope(id, rx->agc_slope); - m_rxa->agc->setTop((float) settings.m_agcGain); // SetRXAAGCTop(id, rx->agc_gain); + m_rxa->agc->setSlope(settings.m_agcSlope); + m_rxa->agc->setTop((float) settings.m_agcGain); if (settings.m_agc) { @@ -779,31 +781,31 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) { case WDSPRxProfile::WDSPRxAGCMode::AGCLong: m_rxa->agc->setMode(1); - m_rxa->agc->setAttack(2); // SetRXAAGCAttack(id, 2); - m_rxa->agc->setHang(2000); // SetRXAAGCHang(id, 2000); - m_rxa->agc->setDecay(2000); // SetRXAAGCDecay(id, 2000); - m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold); + m_rxa->agc->setAttack(2); + m_rxa->agc->setHang(2000); + m_rxa->agc->setDecay(2000); + m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); break; case WDSPRxProfile::WDSPRxAGCMode::AGCSlow: m_rxa->agc->setMode(2); - m_rxa->agc->setAttack(2); // SetRXAAGCAttack(id, 2); - m_rxa->agc->setHang(1000); // SetRXAAGCHang(id, 1000); - m_rxa->agc->setDecay(500); // SetRXAAGCDecay(id, 500); - m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold); + m_rxa->agc->setAttack(2); + m_rxa->agc->setHang(1000); + m_rxa->agc->setDecay(500); + m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); break; case WDSPRxProfile::WDSPRxAGCMode::AGCMedium: m_rxa->agc->setMode(3); - m_rxa->agc->setAttack(2); // SetRXAAGCAttack(id, 2); - m_rxa->agc->setHang(0); // SetRXAAGCHang(id, 0); - m_rxa->agc->setDecay(250); // SetRXAAGCDecay(id, 250); - m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100); + m_rxa->agc->setAttack(2); + m_rxa->agc->setHang(0); + m_rxa->agc->setDecay(250); + m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); break; case WDSPRxProfile::WDSPRxAGCMode::AGCFast: m_rxa->agc->setMode(4); - m_rxa->agc->setAttack(2); // SetRXAAGCAttack(id, 2); - m_rxa->agc->setHang(0); // SetRXAAGCHang(id, 0); - m_rxa->agc->setDecay(50); // SetRXAAGCDecay(id, 50); - m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100); + m_rxa->agc->setAttack(2); + m_rxa->agc->setHang(0); + m_rxa->agc->setDecay(50); + m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); break; } } diff --git a/plugins/channelrx/wdsprx/wdsprxsink.h b/plugins/channelrx/wdsprx/wdsprxsink.h index 8e0a73206..22624cc49 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.h +++ b/plugins/channelrx/wdsprx/wdsprxsink.h @@ -55,13 +55,14 @@ public: bool getAudioActive() const { return m_audioActive; } void setChannel(ChannelAPI *channel) { m_channel = channel; } void setAudioFifoLabel(const QString& label) { m_audioFifo.setLabel(label); } - void getMagSqLevels(double& avg, double& peak, int& nbSamples); + void getMagSqLevels(double& avg, double& peak, int& nbSamples) const; private: class SpectrumProbe : public WDSP::BufferProbe { public: - SpectrumProbe(SampleVector& sampleVector); + explicit SpectrumProbe(SampleVector& sampleVector); + virtual ~SpectrumProbe() = default; virtual void proceed(const float *in, int nbSamples); void setSpanLog2(int spanLog2); void setDSB(bool dsb) { m_dsb = dsb; } @@ -102,8 +103,6 @@ private: Interpolator m_interpolator; Real m_interpolatorDistance; Real m_interpolatorDistanceRemain; - // fftfilt* SSBFilter; - // fftfilt* DSBFilter; SpectrumVis* m_spectrumSink; SampleVector m_sampleBuffer; @@ -123,7 +122,7 @@ private: static const int m_wdspSampleRate; static const int m_wdspBufSize; - void processOneSample(Complex &ci); + void processOneSample(const Complex &ci); }; #endif // INCLUDE_SSBDEMODSINK_H diff --git a/wdsp/CMakeLists.txt b/wdsp/CMakeLists.txt index 59f76a89b..3a277b7fc 100644 --- a/wdsp/CMakeLists.txt +++ b/wdsp/CMakeLists.txt @@ -25,6 +25,7 @@ set(wdsp_SOURCES dsphp.cpp emnr.cpp emph.cpp + emphp.cpp eqp.cpp fcurve.cpp fir.cpp @@ -93,6 +94,7 @@ set(wdsp_HEADERS dsphp.hpp emnr.hpp emph.hpp + emphp.hpp eqp.hpp fcurve.hpp fir.hpp diff --git a/wdsp/RXA.cpp b/wdsp/RXA.cpp index 940911ea3..91fef39d9 100644 --- a/wdsp/RXA.cpp +++ b/wdsp/RXA.cpp @@ -55,6 +55,7 @@ warren@wpratt.com #include "nob.hpp" #include "speak.hpp" #include "mpeak.hpp" +#include "fir.hpp" namespace WDSP { @@ -71,7 +72,7 @@ RXA::RXA( ) { mode = RXA::RXA_LSB; - std::fill(meter, meter + RXA::RXA_METERTYPE_LAST, 0); + std::fill(meter.begin(), meter.end(), 0); // Noise blanker (ANB or "NB") anb = new ANB( @@ -127,17 +128,17 @@ RXA::RXA( // Input meter - ADC adcmeter = new METER( 0, // run - 0, // optional pointer to another 'run' + nullptr, // optional pointer to another 'run' dsp_size, // size midbuff, // pointer to buffer dsp_rate, // samplerate 0.100, // averaging time constant 0.100, // peak decay time constant - meter, // result vector + meter.data(), // result vector RXA_ADC_AV, // index for average value RXA_ADC_PK, // index for peak value -1, // index for gain value - disabled - 0); // pointer for gain computation + nullptr); // pointer for gain computation // Notched bandpass section @@ -200,17 +201,17 @@ RXA::RXA( // S-meter smeter = new METER( 1, // run - 0, // optional pointer to another 'run' + nullptr, // optional pointer to another 'run' dsp_size, // size midbuff, // pointer to buffer dsp_rate, // samplerate 0.100, // averaging time constant 0.100, // peak decay time constant - meter, // result vector + meter.data(), // result vector RXA_S_AV, // index for average value RXA_S_PK, // index for peak value -1, // index for gain value - disabled - 0); // pointer for gain computation + nullptr); // pointer for gain computation // AM squelch capture (for other modes than FM) amsq = new AMSQ( @@ -416,13 +417,13 @@ RXA::RXA( // AGC meter agcmeter = new METER( 0, // run - 0, // optional pointer to another 'run' + nullptr, // optional pointer to another 'run' dsp_size, // size midbuff, // pointer to buffer dsp_rate, // samplerate 0.100, // averaging time constant 0.100, // peak decay time constant - meter, // result vector + meter.data(), // result vector RXA_AGC_AV, // index for average value RXA_AGC_PK, // index for peak value RXA_AGC_GAIN, // index for gain value @@ -903,7 +904,7 @@ void RXA::bp1Set () a->run = 0; if (!old && a->run) a->flush(); - FIRCORE::setUpdate_fircore (a->fircore); + FIRCORE::setUpdate_fircore(a->fircore); } void RXA::bpsnbaCheck(int _mode, int _notch_run) @@ -988,7 +989,7 @@ void RXA::bpsnbaSet() default: break; } - FIRCORE::setUpdate_fircore (a->bpsnba->fircore); + FIRCORE::setUpdate_fircore(a->bpsnba->fircore); } void RXA::updateNBPFiltersLightWeight() @@ -1004,7 +1005,7 @@ void RXA::updateNBPFilters() if (a->fnfrun) { a->calc_impulse(); - FIRCORE::setImpulse_fircore (a->fircore, a->impulse, 1); + FIRCORE::setImpulse_fircore(a->fircore, a->impulse, 1); delete[] (a->impulse); } if (b->bpsnba->fnfrun) @@ -1025,7 +1026,7 @@ int RXA::nbpAddNotch(int _notch, double _fcenter, double _fwidth, int _active) return rval; } -int RXA::nbpGetNotch(int _notch, double* _fcenter, double* _fwidth, int* _active) +int RXA::nbpGetNotch(int _notch, double* _fcenter, double* _fwidth, int* _active) const { NOTCHDB *a = ndb; int rval = a->getNotch(_notch, _fcenter, _fwidth, _active); @@ -1056,7 +1057,7 @@ int RXA::nbpEditNotch(int _notch, double _fcenter, double _fwidth, int _active) return rval; } -void RXA::nbpGetNumNotches(int* _nnotches) +void RXA::nbpGetNumNotches(int* _nnotches) const { const NOTCHDB *a = ndb; a->getNumNotches(_nnotches); @@ -1096,10 +1097,10 @@ void RXA::nbpSetNotchesRun(int _run) b->fnfrun = a->master_run; bpsnbaCheck(mode, _run); b->calc_impulse(); // recalc nbp impulse response - FIRCORE::setImpulse_fircore (b->fircore, b->impulse, 0); // calculate new filter masks + FIRCORE::setImpulse_fircore(b->fircore, b->impulse, 0); // calculate new filter masks delete[] (b->impulse); bpsnbaSet(); - FIRCORE::setUpdate_fircore (b->fircore); // apply new filter masks + FIRCORE::setUpdate_fircore(b->fircore); // apply new filter masks } } @@ -1110,15 +1111,15 @@ void RXA::nbpSetWindow(int _wintype) a = nbp0; b = bpsnba; - if ((a->wintype != _wintype)) + if (a->wintype != _wintype) { a->wintype = _wintype; a->calc_impulse(); - FIRCORE::setImpulse_fircore (a->fircore, a->impulse, 1); + FIRCORE::setImpulse_fircore(a->fircore, a->impulse, 1); delete[] (a->impulse); } - if ((b->wintype != _wintype)) + if (b->wintype != _wintype) { b->wintype = _wintype; b->recalc_bpsnba_filter(1); @@ -1132,15 +1133,15 @@ void RXA::nbpSetAutoIncrease(int _autoincr) a = nbp0; b = bpsnba; - if ((a->autoincr != _autoincr)) + if (a->autoincr != _autoincr) { a->autoincr = _autoincr; a->calc_impulse(); - FIRCORE::setImpulse_fircore (a->fircore, a->impulse, 1); + FIRCORE::setImpulse_fircore(a->fircore, a->impulse, 1); delete[] (a->impulse); } - if ((b->autoincr != _autoincr)) + if (b->autoincr != _autoincr) { b->autoincr = _autoincr; b->recalc_bpsnba_filter(1); @@ -1260,7 +1261,7 @@ void RXA::setEMNRPosition(int _position) bp1->position = _position; } -void RXA::getAGCThresh(double *_thresh, double _size, double _rate) +void RXA::getAGCThresh(double *_thresh, double _size, double _rate) const //for line on bandscope. { double noise_offset; diff --git a/wdsp/RXA.hpp b/wdsp/RXA.hpp index 1f1fc6b0a..8578eded2 100644 --- a/wdsp/RXA.hpp +++ b/wdsp/RXA.hpp @@ -28,6 +28,8 @@ warren@wpratt.com #ifndef wdsp_rxa_h #define wdsp_rxa_h +#include + #include "comm.hpp" #include "unit.hpp" #include "export.h" @@ -95,7 +97,7 @@ public: }; int mode; - double meter[RXA_METERTYPE_LAST]; + std::array meter; ANB *anb; NOB *nob; @@ -119,7 +121,6 @@ public: WCPAGC *agc; METER *agcmeter; BANDPASS *bp1; - BPS *bps1; SIPHON *sip1; CBL *cbl; SPEAK *speak; @@ -136,7 +137,7 @@ public: ); RXA(const RXA&) = delete; RXA& operator=(const RXA& other) = delete; - ~RXA(); + virtual ~RXA(); void flush(); void execute(); @@ -161,10 +162,10 @@ public: void updateNBPFiltersLightWeight(); void updateNBPFilters(); int nbpAddNotch(int notch, double fcenter, double fwidth, int active); - int nbpGetNotch(int notch, double* fcenter, double* fwidth, int* active); + int nbpGetNotch(int notch, double* fcenter, double* fwidth, int* active) const; int nbpDeleteNotch(int notch); int nbpEditNotch(int notch, double fcenter, double fwidth, int active); - void nbpGetNumNotches(int* nnotches); + void nbpGetNumNotches(int* nnotches) const; void nbpSetTuneFrequency(double tunefreq); void nbpSetShiftFrequency(double shift); void nbpSetNotchesRun(int run); @@ -185,7 +186,8 @@ public: void setEMNRPosition(int position); // WCPAGC void setAGCThresh(double thresh, double size, double rate); - void getAGCThresh(double *thresh, double size, double rate); + void getAGCThresh(double *thresh, double size, double rate) const; + // Collectives void setPassband(float f_low, float f_high); void setNC(int nc); diff --git a/wdsp/TXA.cpp b/wdsp/TXA.cpp index 8532a0c6f..9521d88a3 100644 --- a/wdsp/TXA.cpp +++ b/wdsp/TXA.cpp @@ -39,7 +39,7 @@ warren@wpratt.com #include "bps.hpp" #include "osctrl.hpp" #include "wcpAGC.hpp" -#include "emph.hpp" +#include "emphp.hpp" #include "fmmod.hpp" #include "siphon.hpp" #include "gen.hpp" @@ -171,7 +171,7 @@ TXA::TXA( -1, // index for gain value nullptr); // pointer for gain computation - preemph = EMPHP::create_emphp ( + preemph = new EMPHP( 0, // run 1, // position dsp_size, // size @@ -224,10 +224,10 @@ TXA::TXA( &leveler->gain); // pointer for gain computation { - std::array default_F = {200.0, 1000.0, 2000.0, 3000.0, 4000.0}; - std::array default_G = { 0.0, 5.0, 10.0, 10.0, 5.0}; - std::array default_E = { 7.0, 7.0, 7.0, 7.0, 7.0}; - cfcomp = CFCOMP::create_cfcomp( + std::array default_F = {200.0, 1000.0, 2000.0, 3000.0, 4000.0}; + std::array default_G = { 0.0, 5.0, 10.0, 10.0, 5.0}; + std::array default_E = { 7.0, 7.0, 7.0, 7.0, 7.0}; + cfcomp = new CFCOMP( 0, // run 0, // position 0, // post-equalizer run @@ -359,7 +359,7 @@ TXA::TXA( 2.000, // hang_thresh 0.100); // tau_hang_decay - ammod = AMMOD::create_ammod ( + ammod = new AMMOD( 0, // run - OFF by default 0, // mode: 0=>AM, 1=>DSB dsp_size, // size @@ -514,7 +514,7 @@ TXA::~TXA() USLEW::destroy_uslew (uslew); delete gen1; FMMOD::destroy_fmmod (fmmod); - AMMOD::destroy_ammod (ammod); + delete ammod; delete alc; delete compmeter; delete bp2; @@ -523,10 +523,10 @@ TXA::~TXA() COMPRESSOR::destroy_compressor (compressor); delete bp0; delete cfcmeter; - CFCOMP::destroy_cfcomp (cfcomp); + delete cfcomp; delete lvlrmeter; delete leveler; - EMPHP::destroy_emphp (preemph); + delete preemph; delete eqmeter; delete eqp; delete amsq; @@ -548,10 +548,10 @@ void TXA::flush() amsq->flush (); eqp->flush(); eqmeter->flush (); - EMPHP::flush_emphp (preemph); + preemph->flush(); leveler->flush(); lvlrmeter->flush (); - CFCOMP::flush_cfcomp (cfcomp); + cfcomp->flush(); cfcmeter->flush (); bp0->flush (); COMPRESSOR::flush_compressor (compressor); @@ -560,7 +560,7 @@ void TXA::flush() bp2->flush (); compmeter->flush (); alc->flush (); - AMMOD::flush_ammod (ammod); + ammod->flush(); FMMOD::flush_fmmod (fmmod); gen1->flush(); USLEW::flush_uslew (uslew); @@ -583,10 +583,10 @@ void TXA::execute() amsq->execute (); // downward expander action eqp->execute (); // pre-EQ eqmeter->execute (); // EQ meter - EMPHP::xemphp (preemph, 0); // FM pre-emphasis (first option) + preemph->execute(0); // FM pre-emphasis (first option) leveler->execute (); // Leveler lvlrmeter->execute (); // Leveler Meter - CFCOMP::xcfcomp (cfcomp, 0); // Continuous Frequency Compressor with post-EQ + cfcomp->execute(0); // Continuous Frequency Compressor with post-EQ cfcmeter->execute (); // CFC+PostEQ Meter bp0->execute (0); // primary bandpass filter COMPRESSOR::xcompressor (compressor); // COMP compressor @@ -595,8 +595,8 @@ void TXA::execute() bp2->execute (0); // aux bandpass (runs if CESSB) compmeter->execute (); // COMP meter alc->execute (); // ALC - AMMOD::xammod (ammod); // AM Modulator - EMPHP::xemphp (preemph, 1); // FM pre-emphasis (second option) + ammod->execute(); // AM Modulator + preemph->execute(1); // FM pre-emphasis (second option) FMMOD::xfmmod (fmmod); // FM Modulator gen1->execute(); // output signal generator (TUN and Two-tone) USLEW::xuslew (uslew); // up-slew for AM, FM, and gens @@ -648,10 +648,10 @@ void TXA::setDSPSamplerate(int dsp_rate) amsq->setSamplerate (dsp_rate); eqp->setSamplerate (dsp_rate); eqmeter->setSamplerate (dsp_rate); - EMPHP::setSamplerate_emphp (preemph, dsp_rate); + preemph->setSamplerate(dsp_rate); leveler->setSamplerate (dsp_rate); lvlrmeter->setSamplerate (dsp_rate); - CFCOMP::setSamplerate_cfcomp (cfcomp, dsp_rate); + cfcomp->setSamplerate(dsp_rate); cfcmeter->setSamplerate (dsp_rate); bp0->setSamplerate (dsp_rate); COMPRESSOR::setSamplerate_compressor (compressor, dsp_rate); @@ -660,7 +660,7 @@ void TXA::setDSPSamplerate(int dsp_rate) bp2->setSamplerate (dsp_rate); compmeter->setSamplerate (dsp_rate); alc->setSamplerate (dsp_rate); - AMMOD::setSamplerate_ammod (ammod, dsp_rate); + ammod->setSamplerate(dsp_rate); FMMOD::setSamplerate_fmmod (fmmod, dsp_rate); gen1->setSamplerate(dsp_rate); USLEW::setSamplerate_uslew (uslew, dsp_rate); @@ -698,14 +698,14 @@ void TXA::setDSPBuffsize(int dsp_size) eqp->setSize (dsp_size); eqmeter->setBuffers (midbuff); eqmeter->setSize (dsp_size); - EMPHP::setBuffers_emphp (preemph, midbuff, midbuff); - EMPHP::setSize_emphp (preemph, dsp_size); + preemph->setBuffers(midbuff, midbuff); + preemph->setSize(dsp_size); leveler->setBuffers(midbuff, midbuff); leveler->setSize(dsp_size); lvlrmeter->setBuffers(midbuff); lvlrmeter->setSize(dsp_size); - CFCOMP::setBuffers_cfcomp (cfcomp, midbuff, midbuff); - CFCOMP::setSize_cfcomp (cfcomp, dsp_size); + cfcomp->setBuffers(midbuff, midbuff); + cfcomp->setSize(dsp_size); cfcmeter->setBuffers(midbuff); cfcmeter->setSize(dsp_size); bp0->setBuffers (midbuff, midbuff); @@ -722,8 +722,8 @@ void TXA::setDSPBuffsize(int dsp_size) compmeter->setSize(dsp_size); alc->setBuffers(midbuff, midbuff); alc->setSize( dsp_size); - AMMOD::setBuffers_ammod (ammod, midbuff, midbuff); - AMMOD::setSize_ammod (ammod, dsp_size); + ammod->setBuffers(midbuff, midbuff); + ammod->setSize(dsp_size); FMMOD::setBuffers_fmmod (fmmod, midbuff, midbuff); FMMOD::setSize_fmmod (fmmod, dsp_size); gen1->setBuffers(midbuff, midbuff); @@ -925,7 +925,7 @@ void TXA::setBandpassNC(int _nc) 1, a->gain / (double)(2 * a->size) ); - FIRCORE::setNc_fircore (a->fircore, a->nc, impulse); + FIRCORE::setNc_fircore(a->fircore, a->nc, impulse); delete[] impulse; } @@ -943,7 +943,7 @@ void TXA::setBandpassNC(int _nc) 1, a->gain / (double)(2 * a->size) ); - FIRCORE::setNc_fircore (a->fircore, a->nc, impulse); + FIRCORE::setNc_fircore(a->fircore, a->nc, impulse); delete[] impulse; } @@ -961,7 +961,7 @@ void TXA::setBandpassNC(int _nc) 1, a->gain / (double)(2 * a->size) ); - FIRCORE::setNc_fircore (a->fircore, a->nc, impulse); + FIRCORE::setNc_fircore(a->fircore, a->nc, impulse); delete[] impulse; } } @@ -974,7 +974,7 @@ void TXA::setBandpassMP(int _mp) if (_mp != a->mp) { a->mp = _mp; - FIRCORE::setMp_fircore (a->fircore, a->mp); + FIRCORE::setMp_fircore(a->fircore, a->mp); } a = bp1; @@ -982,7 +982,7 @@ void TXA::setBandpassMP(int _mp) if (_mp != a->mp) { a->mp = _mp; - FIRCORE::setMp_fircore (a->fircore, a->mp); + FIRCORE::setMp_fircore(a->fircore, a->mp); } a = bp2; @@ -990,7 +990,7 @@ void TXA::setBandpassMP(int _mp) if (_mp != a->mp) { a->mp = _mp; - FIRCORE::setMp_fircore (a->fircore, a->mp); + FIRCORE::setMp_fircore(a->fircore, a->mp); } } @@ -1005,7 +1005,7 @@ void TXA::setNC(int _nc) int oldstate = state; setBandpassNC (_nc); - EMPHP::SetFMEmphNC (*this, _nc); + preemph->setNC (_nc); eqp->setNC (_nc); FMMOD::SetFMNC (*this, _nc); CFIR::SetCFIRNC (*this, _nc); @@ -1015,15 +1015,100 @@ void TXA::setNC(int _nc) void TXA::setMP(int _mp) { setBandpassMP (_mp); - EMPHP::SetFMEmphMP (*this, _mp); + preemph->setMP (_mp); eqp->setMP (_mp); FMMOD::SetFMMP (*this, _mp); } void TXA::setFMAFFilter(float _low, float _high) { - EMPHP::SetFMPreEmphFreqs (*this, _low, _high); - FMMOD::SetFMAFFreqs (*this, _low, _high); + preemph->setFreqs (_low, _high); + FMMOD::SetFMAFFreqs(*this, _low, _high); } +void TXA::SetBPSRun (TXA& txa, int _run) +{ + txa.bp1->run = _run; +} + +void TXA::SetBPSFreqs (TXA& txa, double _f_low, double _f_high) +{ + float* impulse; + BPS *a; + a = txa.bps0; + + if ((_f_low != a->f_low) || (_f_high != a->f_high)) + { + a->f_low = _f_low; + a->f_high = _f_high; + delete[] (a->mults); + impulse = FIR::fir_bandpass(a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); + a->mults = FIR::fftcv_mults (2 * a->size, impulse); + delete[] (impulse); + } + + a = txa.bps1; + + if ((_f_low != a->f_low) || (_f_high != a->f_high)) + { + a->f_low = _f_low; + a->f_high = _f_high; + delete[] (a->mults); + impulse = FIR::fir_bandpass(a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); + a->mults = FIR::fftcv_mults (2 * a->size, impulse); + delete[] (impulse); + } + + a = txa.bps2; + + if ((_f_low != a->f_low) || (_f_high != a->f_high)) + { + a->f_low = _f_low; + a->f_high = _f_high; + delete[] (a->mults); + impulse = FIR::fir_bandpass(a->size + 1, _f_low, _f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); + a->mults = FIR::fftcv_mults (2 * a->size, impulse); + delete[] (impulse); + } +} + +void TXA::SetBPSWindow (TXA& txa, int _wintype) +{ + float* impulse; + BPS *a; + a = txa.bps0; + + if (a->wintype != _wintype) + { + a->wintype = _wintype; + delete[] (a->mults); + impulse = FIR::fir_bandpass(a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); + a->mults = FIR::fftcv_mults (2 * a->size, impulse); + delete[] (impulse); + } + + a = txa.bps1; + + if (a->wintype != _wintype) + { + a->wintype = _wintype; + delete[] (a->mults); + impulse = FIR::fir_bandpass(a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); + a->mults = FIR::fftcv_mults (2 * a->size, impulse); + delete[] (impulse); + } + + a = txa.bps2; + + if (a->wintype != _wintype) + { + a->wintype = _wintype; + delete[] (a->mults); + impulse = FIR::fir_bandpass (a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); + a->mults = FIR::fftcv_mults (2 * a->size, impulse); + delete[] (impulse); + } +} + + } // namespace WDSP diff --git a/wdsp/TXA.hpp b/wdsp/TXA.hpp index 19e5a5771..55da102fb 100644 --- a/wdsp/TXA.hpp +++ b/wdsp/TXA.hpp @@ -172,7 +172,7 @@ public: ); TXA(const TXA&) = delete; TXA& operator=(const TXA& other) = delete; - ~TXA(); + virtual ~TXA(); void flush(); void execute(); @@ -190,6 +190,10 @@ public: void setBandpassFreqs(float f_low, float f_high); void setBandpassNC(int nc); void setBandpassMP(int mp); + // BPS + static void SetBPSRun (TXA& txa, int run); + static void SetBPSFreqs (TXA& txa, double low, double high); + static void SetBPSWindow (TXA& txa, int wintype); // Collectives void setNC(int nc); diff --git a/wdsp/amd.cpp b/wdsp/amd.cpp index 6b1aefe3f..820e1b4b7 100644 --- a/wdsp/amd.cpp +++ b/wdsp/amd.cpp @@ -53,22 +53,22 @@ AMD::AMD double _omegaN, double _tauR, double _tauI -) +) : + run(_run), + buff_size(_buff_size), + in_buff(_in_buff), + out_buff(_out_buff), + mode(_mode), + sample_rate((double) _sample_rate), + fmin(_fmin), + fmax(_fmax), + zeta(_zeta), + omegaN(_omegaN), + tauR(_tauR), + tauI(_tauI), + sbmode(_sbmode), + levelfade(_levelfade) { - run = _run; - buff_size = _buff_size; - in_buff = _in_buff; - out_buff = _out_buff; - mode = _mode; - levelfade = _levelfade; - sbmode = _sbmode; - sample_rate = (double) _sample_rate; - fmin = _fmin; - fmax = _fmax; - zeta = _zeta; - omegaN = _omegaN; - tauR = _tauR; - tauI = _tauI; init(); } diff --git a/wdsp/ammod.cpp b/wdsp/ammod.cpp index b1301e351..e884143a4 100644 --- a/wdsp/ammod.cpp +++ b/wdsp/ammod.cpp @@ -33,72 +33,74 @@ warren@wpratt.com namespace WDSP { -AMMOD* AMMOD::create_ammod (int run, int mode, int size, float* in, float* out, float c_level) +AMMOD::AMMOD( + int _run, + int _mode, + int _size, + float* _in, + float* _out, + double _c_level +) { - AMMOD *a = new AMMOD; - a->run = run; - a->mode = mode; - a->size = size; - a->in = in; - a->out = out; - a->c_level = c_level; - a->a_level = 1.0 - a->c_level; - a->mult = 1.0 / sqrt (2.0); - return a; + run = _run; + mode = _mode; + size = _size; + in = _in; + out = _out; + c_level = _c_level; + a_level = 1.0 - c_level; + mult = 1.0 / sqrt (2.0); } -void AMMOD::destroy_ammod(AMMOD *a) +void AMMOD::flush() { - delete a; + // Nothing to flush } -void AMMOD::flush_ammod(AMMOD *) +void AMMOD::execute() { - -} - -void AMMOD::xammod(AMMOD *a) -{ - if (a->run) + if (run) { int i; - switch (a->mode) + switch (mode) { case 0: // AM - for (i = 0; i < a->size; i++) - a->out[2 * i + 0] = a->out[2 * i + 1] = a->mult * (a->c_level + a->a_level * a->in[2 * i + 0]); + for (i = 0; i < size; i++) + out[2 * i + 0] = out[2 * i + 1] = (float) (mult * (c_level + a_level * in[2 * i + 0])); break; case 1: // DSB - for (i = 0; i < a->size; i++) - a->out[2 * i + 0] = a->out[2 * i + 1] = a->mult * a->in[2 * i + 0]; + for (i = 0; i < size; i++) + out[2 * i + 0] = out[2 * i + 1] = (float) (mult * in[2 * i + 0]); break; case 2: // SSB w/Carrier - for (i = 0; i < a->size; i++) + for (i = 0; i < size; i++) { - a->out[2 * i + 0] = a->mult * a->c_level + a->a_level * a->in[2 * i + 0]; - a->out[2 * i + 1] = a->mult * a->c_level + a->a_level * a->in[2 * i + 1]; + out[2 * i + 0] = (float) (mult * c_level + a_level * in[2 * i + 0]); + out[2 * i + 1] = (float) (mult * c_level + a_level * in[2 * i + 1]); } break; + default: + break; } } - else if (a->in != a->out) - std::copy( a->in, a->in + a->size * 2, a->out); + else if (in != out) + std::copy( in, in + size * 2, out); } -void AMMOD::setBuffers_ammod(AMMOD *a, float* in, float* out) +void AMMOD::setBuffers(float* _in, float* _out) { - a->in = in; - a->out = out; + in = _in; + out = _out; } -void AMMOD::setSamplerate_ammod(AMMOD *, int) +void AMMOD::setSamplerate(int) { - + // Nothing to do } -void AMMOD::setSize_ammod(AMMOD *a, int size) +void AMMOD::setSize(int _size) { - a->size = size; + size = _size; } /******************************************************************************************************** @@ -107,10 +109,10 @@ void AMMOD::setSize_ammod(AMMOD *a, int size) * * ********************************************************************************************************/ -void AMMOD::SetAMCarrierLevel (TXA& txa, float c_level) +void AMMOD::setAMCarrierLevel(double _c_level) { - txa.ammod->c_level = c_level; - txa.ammod->a_level = 1.0 - c_level; + c_level = _c_level; + a_level = 1.0 - _c_level; } } // namespace WDSP diff --git a/wdsp/ammod.hpp b/wdsp/ammod.hpp index 09f724fe9..e5ba7ad51 100644 --- a/wdsp/ammod.hpp +++ b/wdsp/ammod.hpp @@ -42,19 +42,29 @@ public: int size; float* in; float* out; - float c_level; - float a_level; - float mult; + double c_level; + double a_level; + double mult; - static AMMOD* create_ammod(int run, int mode, int size, float* in, float* out, float c_level); - static void destroy_ammod (AMMOD *a); - static void flush_ammod (AMMOD *a); - static void xammod (AMMOD *a); - static void setBuffers_ammod (AMMOD *a, float* in, float* out); - static void setSamplerate_ammod (AMMOD *a, int rate); - static void setSize_ammod (AMMOD *a, int size); + AMMOD( + int run, + int mode, + int size, + float* in, + float* out, + double c_level + ); + AMMOD(const AMMOD&) = delete; + AMMOD& operator=(const AMMOD& other) = delete; + ~AMMOD() = default; + + void flush(); + void execute(); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); // TXA Properties - static void SetAMCarrierLevel (TXA& txa, float c_level); + void setAMCarrierLevel(double c_level); }; } // namespace WDSP diff --git a/wdsp/anb.cpp b/wdsp/anb.cpp index 7b3183909..f9717d399 100644 --- a/wdsp/anb.cpp +++ b/wdsp/anb.cpp @@ -81,13 +81,12 @@ ANB::ANB ( hangtime(_hangtime), advtime(_advtime), backtau(_backtau), - threshold(_threshold) + threshold(_threshold), + dtime(0), + htime(0), + itime(0), + atime(0) { - dtime = 0; - htime = 0; - itime = 0; - atime = 0; - if (tau < 0.0) { tau = 0.0; } else if (tau > MAX_TAU) { diff --git a/wdsp/anf.cpp b/wdsp/anf.cpp index cee3e3341..af13b1635 100644 --- a/wdsp/anf.cpp +++ b/wdsp/anf.cpp @@ -65,6 +65,7 @@ ANF::ANF( delay(_delay), two_mu(_two_mu), gamma(_gamma), + in_idx(0), lidx(_lidx), lidx_min(_lidx_min), lidx_max(_lidx_max), @@ -73,7 +74,6 @@ ANF::ANF( lincr(_lincr), ldecr(_ldecr) { - in_idx = 0; std::fill(d.begin(), d.end(), 0); std::fill(w.begin(), w.end(), 0); } diff --git a/wdsp/bldr.cpp b/wdsp/bldr.cpp index ddbbb9c16..a234dd1c2 100644 --- a/wdsp/bldr.cpp +++ b/wdsp/bldr.cpp @@ -30,138 +30,102 @@ warren@wpratt.com namespace WDSP { -BLDR* BLDR::create_builder(int points, int ints) +BLDR::BLDR(int points, int ints) { // for the create function, 'points' and 'ints' are the MAXIMUM values that will be encountered - BLDR *a = new BLDR; - a->catxy = new float[2 * points]; // (float*)malloc0(2 * points * sizeof(float)); - a->sx = new float[points]; // (float*)malloc0( points * sizeof(float)); - a->sy = new float[points]; // (float*)malloc0( points * sizeof(float)); - a->h = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->p = new int[ints]; // (int*) malloc0( ints * sizeof(int)); - a->np = new int[ints]; // (int*) malloc0( ints * sizeof(int)); - a->taa = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->tab = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->tag = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->tad = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->tbb = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->tbg = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->tbd = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->tgg = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->tgd = new float[ints]; // (float*)malloc0( ints * sizeof(float)); - a->tdd = new float[ints]; // (float*)malloc0( ints * sizeof(float)); + catxy = new double[2 * points]; + sx.resize(points); + sy.resize(points); + h .resize(ints); + p.resize(ints); + np.resize(ints); + taa.resize(ints); + tab.resize(ints); + tag.resize(ints); + tad.resize(ints); + tbb.resize(ints); + tbg.resize(ints); + tbd.resize(ints); + tgg.resize(ints); + tgd.resize(ints); + tdd.resize(ints); int nsize = 3 * ints + 1; int intp1 = ints + 1; int intm1 = ints - 1; - a->A = new float[intp1 * intp1]; // (float*)malloc0(intp1 * intp1 * sizeof(float)); - a->B = new float[intp1 * intp1]; // (float*)malloc0(intp1 * intp1 * sizeof(float)); - a->C = new float[intp1 * intp1]; // (float*)malloc0(intm1 * intp1 * sizeof(float)); - a->D = new float[intp1]; // (float*)malloc0(intp1 * sizeof(float)); - a->E = new float[intp1 * intp1]; // (float*)malloc0(intp1 * intp1 * sizeof(float)); - a->F = new float[intm1 * intp1]; // (float*)malloc0(intm1 * intp1 * sizeof(float)); - a->G = new float[intp1]; // (float*)malloc0(intp1 * sizeof(float)); - a->MAT = new float[nsize * nsize]; // (float*)malloc0(nsize * nsize * sizeof(float)); - a->RHS = new float[nsize]; // (float*)malloc0(nsize * sizeof(float)); - a->SLN = new float[nsize]; // (float*)malloc0(nsize * sizeof(float)); - a->z = new float[intp1]; // (float*)malloc0(intp1 * sizeof(float)); - a->zp = new float[intp1]; // (float*)malloc0(intp1 * sizeof(float)); - a->wrk = new float[nsize]; // (float*)malloc0(nsize * sizeof(float)); - a->ipiv = new int[nsize]; // (int*) malloc0(nsize * sizeof(int)); - return a; + A .resize(intp1 * intp1); + B .resize(intp1 * intp1); + C .resize(intp1 * intp1); + D .resize(intp1); + E .resize(intp1 * intp1); + F .resize(intm1 * intp1); + G .resize(intp1); + MAT.resize(nsize * nsize); + RHS.resize(nsize); + SLN.resize(nsize); + z .resize(intp1); + zp.resize(intp1); + wrk.resize(nsize); + ipiv.resize(nsize); } -void BLDR::destroy_builder(BLDR *a) +BLDR::~BLDR() { - delete[](a->ipiv); - delete[](a->wrk); - delete[](a->catxy); - delete[](a->sx); - delete[](a->sy); - delete[](a->h); - delete[](a->p); - delete[](a->np); - - delete[](a->taa); - delete[](a->tab); - delete[](a->tag); - delete[](a->tad); - delete[](a->tbb); - delete[](a->tbg); - delete[](a->tbd); - delete[](a->tgg); - delete[](a->tgd); - delete[](a->tdd); - - delete[](a->A); - delete[](a->B); - delete[](a->C); - delete[](a->D); - delete[](a->E); - delete[](a->F); - delete[](a->G); - - delete[](a->MAT); - delete[](a->RHS); - delete[](a->SLN); - - delete[](a->z); - delete[](a->zp); - - delete(a); + delete[]catxy; } -void BLDR::flush_builder(BLDR *a, int points, int ints) +void BLDR::flush(int points) { - memset(a->catxy, 0, 2 * points * sizeof(float)); - memset(a->sx, 0, points * sizeof(float)); - memset(a->sy, 0, points * sizeof(float)); - memset(a->h, 0, ints * sizeof(float)); - memset(a->p, 0, ints * sizeof(int)); - memset(a->np, 0, ints * sizeof(int)); - memset(a->taa, 0, ints * sizeof(float)); - memset(a->tab, 0, ints * sizeof(float)); - memset(a->tag, 0, ints * sizeof(float)); - memset(a->tad, 0, ints * sizeof(float)); - memset(a->tbb, 0, ints * sizeof(float)); - memset(a->tbg, 0, ints * sizeof(float)); - memset(a->tbd, 0, ints * sizeof(float)); - memset(a->tgg, 0, ints * sizeof(float)); - memset(a->tgd, 0, ints * sizeof(float)); - memset(a->tdd, 0, ints * sizeof(float)); - int nsize = 3 * ints + 1; - int intp1 = ints + 1; - int intm1 = ints - 1; - memset(a->A, 0, intp1 * intp1 * sizeof(float)); - memset(a->B, 0, intp1 * intp1 * sizeof(float)); - memset(a->C, 0, intm1 * intp1 * sizeof(float)); - memset(a->D, 0, intp1 * sizeof(float)); - memset(a->E, 0, intp1 * intp1 * sizeof(float)); - memset(a->F, 0, intm1 * intp1 * sizeof(float)); - memset(a->G, 0, intp1 * sizeof(float)); - memset(a->MAT, 0, nsize * nsize * sizeof(float)); - memset(a->RHS, 0, nsize * sizeof(float)); - memset(a->SLN, 0, nsize * sizeof(float)); - memset(a->z, 0, intp1 * sizeof(float)); - memset(a->zp, 0, intp1 * sizeof(float)); - memset(a->wrk, 0, nsize * sizeof(float)); - memset(a->ipiv, 0, nsize * sizeof(int)); + memset(catxy, 0, 2 * points * sizeof(double)); + std::fill(sx.begin(), sx.end(), 0); + std::fill(sy.begin(), sy.end(), 0); + std::fill(h.begin(), h.end(), 0); + std::fill(p.begin(), p.end(), 0); + std::fill(np.begin(), np.end(), 0); + std::fill(taa.begin(), taa.end(), 0); + std::fill(tab.begin(), tab.end(), 0); + std::fill(tag.begin(), tag.end(), 0); + std::fill(tad.begin(), tad.end(), 0); + std::fill(tbb.begin(), tbb.end(), 0); + std::fill(tbg.begin(), tbg.end(), 0); + std::fill(tbd.begin(), tbd.end(), 0); + std::fill(tgg.begin(), tgg.end(), 0); + std::fill(tgd.begin(), tgd.end(), 0); + std::fill(tdd.begin(), tdd.end(), 0); + std::fill(A.begin(), A.end(), 0); + std::fill(B.begin(), B.end(), 0); + std::fill(C.begin(), C.end(), 0); + std::fill(D.begin(), D.end(), 0); + std::fill(E.begin(), E.end(), 0); + std::fill(F.begin(), F.end(), 0); + std::fill(G.begin(), G.end(), 0); + std::fill(MAT.begin(), MAT.end(), 0); + std::fill(RHS.begin(), RHS.end(), 0); + std::fill(SLN.begin(), SLN.end(), 0); + std::fill(z.begin(), z.end(), 0); + std::fill(zp.begin(), zp.end(), 0); + std::fill(wrk.begin(), wrk.end(), 0); + std::fill(ipiv.begin(), ipiv.end(), 0); } int BLDR::fcompare(const void* a, const void* b) { - if (*(float*)a < *(float*)b) + if (*(double*)a < *(double*)b) return -1; - else if (*(float*)a == *(float*)b) + else if (*(double*)a == *(double*)b) return 0; else return 1; } -void BLDR::decomp(int n, float* a, int* piv, int* info, float* wrk) +void BLDR::decomp(int n, std::vector& a, std::vector& piv, int* info, std::vector& wrk) { - int i, j, k; + int i; + int j; int t_piv; - float m_row, mt_row, m_col, mt_col; + double m_row; + double mt_row; + double m_col; + double mt_col; *info = 0; for (i = 0; i < n; i++) { @@ -180,7 +144,7 @@ void BLDR::decomp(int n, float* a, int* piv, int* info, float* wrk) } wrk[i] = m_row; } - for (k = 0; k < n - 1; k++) + for (int k = 0; k < n - 1; k++) { j = k; m_col = a[n * piv[k] + k] / wrk[piv[k]]; @@ -216,10 +180,11 @@ cleanup: return; } -void BLDR::dsolve(int n, float* a, int* piv, float* b, float* x) +void BLDR::dsolve(int n, std::vector& a, std::vector& piv, std::vector& b, std::vector& x) { - int j, k; - float sum; + int j; + int k; + double sum; for (k = 0; k < n; k++) { @@ -238,7 +203,7 @@ void BLDR::dsolve(int n, float* a, int* piv, float* b, float* x) } } -void BLDR::cull(int* n, int ints, float* x, float* t, float ptol) +void BLDR::cull(int* n, int ints, std::vector& x, const double* t, double ptol) { int k = 0; int i = *n; @@ -255,28 +220,36 @@ void BLDR::cull(int* n, int ints, float* x, float* t, float ptol) *n -= k; } -void BLDR::xbuilder(BLDR *a, int points, float* x, float* y, int ints, float* t, int* info, float* c, float ptol) +void BLDR::execute(int points, const double* x, const double* y, int ints, const double* t, int* info, double* c, double ptol) { - float u, v, alpha, beta, gamma, delta; + double u; + double v; + double alpha; + double beta; + double gamma; + double delta; int nsize = 3 * ints + 1; int intp1 = ints + 1; int intm1 = ints - 1; - int i, j, k, m; + int i; + int j; + int k; + int m; int dinfo; - flush_builder(a, points, ints); + flush(points); for (i = 0; i < points; i++) { - a->catxy[2 * i + 0] = x[i]; - a->catxy[2 * i + 1] = y[i]; + catxy[2 * i + 0] = x[i]; + catxy[2 * i + 1] = y[i]; } - qsort(a->catxy, points, 2 * sizeof(float), fcompare); + qsort(catxy, points, 2 * sizeof(double), fcompare); for (i = 0; i < points; i++) { - a->sx[i] = a->catxy[2 * i + 0]; - a->sy[i] = a->catxy[2 * i + 1]; + sx[i] = catxy[2 * i + 0]; + sy[i] = catxy[2 * i + 1]; } - cull(&points, ints, a->sx, t, ptol); - if (points <= 0 || a->sx[points - 1] > t[ints]) + cull(&points, ints, sx, t, ptol); + if (points <= 0 || sx[points - 1] > t[ints]) { *info = -1000; goto cleanup; @@ -284,101 +257,101 @@ void BLDR::xbuilder(BLDR *a, int points, float* x, float* y, int ints, float* t, else *info = 0; for (j = 0; j < ints; j++) - a->h[j] = t[j + 1] - t[j]; - a->p[0] = 0; + h[j] = t[j + 1] - t[j]; + p[0] = 0; j = 0; for (i = 0; i < points; i++) { - if (a->sx[i] <= t[j + 1]) - a->np[j]++; + if (sx[i] <= t[j + 1]) + np[j]++; else { - a->p[++j] = i; - while (a->sx[i] > t[j + 1]) - a->p[++j] = i; - a->np[j] = 1; + p[++j] = i; + while (sx[i] > t[j + 1]) + p[++j] = i; + np[j] = 1; } } for (i = 0; i < ints; i++) - for (j = a->p[i]; j < a->p[i] + a->np[i]; j++) + for (j = p[i]; j < p[i] + np[i]; j++) { - u = (a->sx[j] - t[i]) / a->h[i]; + u = (sx[j] - t[i]) / h[i]; v = u - 1.0; alpha = (2.0 * u + 1.0) * v * v; beta = u * u * (1.0 - 2.0 * v); - gamma = a->h[i] * u * v * v; - delta = a->h[i] * u * u * v; - a->taa[i] += alpha * alpha; - a->tab[i] += alpha * beta; - a->tag[i] += alpha * gamma; - a->tad[i] += alpha * delta; - a->tbb[i] += beta * beta; - a->tbg[i] += beta * gamma; - a->tbd[i] += beta * delta; - a->tgg[i] += gamma * gamma; - a->tgd[i] += gamma * delta; - a->tdd[i] += delta * delta; - a->D[i + 0] += 2.0 * a->sy[j] * alpha; - a->D[i + 1] += 2.0 * a->sy[j] * beta; - a->G[i + 0] += 2.0 * a->sy[j] * gamma; - a->G[i + 1] += 2.0 * a->sy[j] * delta; + gamma = h[i] * u * v * v; + delta = h[i] * u * u * v; + taa[i] += alpha * alpha; + tab[i] += alpha * beta; + tag[i] += alpha * gamma; + tad[i] += alpha * delta; + tbb[i] += beta * beta; + tbg[i] += beta * gamma; + tbd[i] += beta * delta; + tgg[i] += gamma * gamma; + tgd[i] += gamma * delta; + tdd[i] += delta * delta; + D[i + 0] += 2.0 * sy[j] * alpha; + D[i + 1] += 2.0 * sy[j] * beta; + G[i + 0] += 2.0 * sy[j] * gamma; + G[i + 1] += 2.0 * sy[j] * delta; } for (i = 0; i < ints; i++) { - a->A[(i + 0) * intp1 + (i + 0)] += 2.0 * a->taa[i]; - a->A[(i + 1) * intp1 + (i + 1)] = 2.0 * a->tbb[i]; - a->A[(i + 0) * intp1 + (i + 1)] = 2.0 * a->tab[i]; - a->A[(i + 1) * intp1 + (i + 0)] = 2.0 * a->tab[i]; - a->B[(i + 0) * intp1 + (i + 0)] += 2.0 * a->tag[i]; - a->B[(i + 1) * intp1 + (i + 1)] = 2.0 * a->tbd[i]; - a->B[(i + 0) * intp1 + (i + 1)] = 2.0 * a->tbg[i]; - a->B[(i + 1) * intp1 + (i + 0)] = 2.0 * a->tad[i]; - a->E[(i + 0) * intp1 + (i + 0)] += 2.0 * a->tgg[i]; - a->E[(i + 1) * intp1 + (i + 1)] = 2.0 * a->tdd[i]; - a->E[(i + 0) * intp1 + (i + 1)] = 2.0 * a->tgd[i]; - a->E[(i + 1) * intp1 + (i + 0)] = 2.0 * a->tgd[i]; + A[(i + 0) * intp1 + (i + 0)] += 2.0 * taa[i]; + A[(i + 1) * intp1 + (i + 1)] = 2.0 * tbb[i]; + A[(i + 0) * intp1 + (i + 1)] = 2.0 * tab[i]; + A[(i + 1) * intp1 + (i + 0)] = 2.0 * tab[i]; + B[(i + 0) * intp1 + (i + 0)] += 2.0 * tag[i]; + B[(i + 1) * intp1 + (i + 1)] = 2.0 * tbd[i]; + B[(i + 0) * intp1 + (i + 1)] = 2.0 * tbg[i]; + B[(i + 1) * intp1 + (i + 0)] = 2.0 * tad[i]; + E[(i + 0) * intp1 + (i + 0)] += 2.0 * tgg[i]; + E[(i + 1) * intp1 + (i + 1)] = 2.0 * tdd[i]; + E[(i + 0) * intp1 + (i + 1)] = 2.0 * tgd[i]; + E[(i + 1) * intp1 + (i + 0)] = 2.0 * tgd[i]; } for (i = 0; i < intm1; i++) { - a->C[i * intp1 + (i + 0)] = +3.0 * a->h[i + 1] / a->h[i]; - a->C[i * intp1 + (i + 2)] = -3.0 * a->h[i] / a->h[i + 1]; - a->C[i * intp1 + (i + 1)] = -a->C[i * intp1 + (i + 0)] - a->C[i * intp1 + (i + 2)]; - a->F[i * intp1 + (i + 0)] = a->h[i + 1]; - a->F[i * intp1 + (i + 1)] = 2.0 * (a->h[i] + a->h[i + 1]); - a->F[i * intp1 + (i + 2)] = a->h[i]; + C[i * intp1 + (i + 0)] = +3.0 * h[i + 1] / h[i]; + C[i * intp1 + (i + 2)] = -3.0 * h[i] / h[i + 1]; + C[i * intp1 + (i + 1)] = -C[i * intp1 + (i + 0)] - C[i * intp1 + (i + 2)]; + F[i * intp1 + (i + 0)] = h[i + 1]; + F[i * intp1 + (i + 1)] = 2.0 * (h[i] + h[i + 1]); + F[i * intp1 + (i + 2)] = h[i]; } for (i = 0, k = 0; i < intp1; i++, k++) { for (j = 0, m = 0; j < intp1; j++, m++) - a->MAT[k * nsize + m] = a->A[i * intp1 + j]; + MAT[k * nsize + m] = A[i * intp1 + j]; for (j = 0, m = intp1; j < intp1; j++, m++) - a->MAT[k * nsize + m] = a->B[j * intp1 + i]; + MAT[k * nsize + m] = B[j * intp1 + i]; for (j = 0, m = 2 * intp1; j < intm1; j++, m++) - a->MAT[k * nsize + m] = a->C[j * intp1 + i]; - a->RHS[k] = a->D[i]; + MAT[k * nsize + m] = C[j * intp1 + i]; + RHS[k] = D[i]; } for (i = 0, k = intp1; i < intp1; i++, k++) { for (j = 0, m = 0; j < intp1; j++, m++) - a->MAT[k * nsize + m] = a->B[i * intp1 + j]; + MAT[k * nsize + m] = B[i * intp1 + j]; for (j = 0, m = intp1; j < intp1; j++, m++) - a->MAT[k * nsize + m] = a->E[i * intp1 + j]; + MAT[k * nsize + m] = E[i * intp1 + j]; for (j = 0, m = 2 * intp1; j < intm1; j++, m++) - a->MAT[k * nsize + m] = a->F[j * intp1 + i]; - a->RHS[k] = a->G[i]; + MAT[k * nsize + m] = F[j * intp1 + i]; + RHS[k] = G[i]; } for (i = 0, k = 2 * intp1; i < intm1; i++, k++) { for (j = 0, m = 0; j < intp1; j++, m++) - a->MAT[k * nsize + m] = a->C[i * intp1 + j]; + MAT[k * nsize + m] = C[i * intp1 + j]; for (j = 0, m = intp1; j < intp1; j++, m++) - a->MAT[k * nsize + m] = a->F[i * intp1 + j]; + MAT[k * nsize + m] = F[i * intp1 + j]; for (j = 0, m = 2 * intp1; j < intm1; j++, m++) - a->MAT[k * nsize + m] = 0.0; - a->RHS[k] = 0.0; + MAT[k * nsize + m] = 0.0; + RHS[k] = 0.0; } - decomp(nsize, a->MAT, a->ipiv, &dinfo, a->wrk); - dsolve(nsize, a->MAT, a->ipiv, a->RHS, a->SLN); + decomp(nsize, MAT, ipiv, &dinfo, wrk); + dsolve(nsize, MAT, ipiv, RHS, SLN); if (dinfo != 0) { *info = dinfo; @@ -387,15 +360,15 @@ void BLDR::xbuilder(BLDR *a, int points, float* x, float* y, int ints, float* t, for (i = 0; i <= ints; i++) { - a->z[i] = a->SLN[i]; - a->zp[i] = a->SLN[i + ints + 1]; + z[i] = SLN[i]; + zp[i] = SLN[i + ints + 1]; } for (i = 0; i < ints; i++) { - c[4 * i + 0] = a->z[i]; - c[4 * i + 1] = a->zp[i]; - c[4 * i + 2] = -3.0 / (a->h[i] * a->h[i]) * (a->z[i] - a->z[i + 1]) - 1.0 / a->h[i] * (2.0 * a->zp[i] + a->zp[i + 1]); - c[4 * i + 3] = 2.0 / (a->h[i] * a->h[i] * a->h[i]) * (a->z[i] - a->z[i + 1]) + 1.0 / (a->h[i] * a->h[i]) * (a->zp[i] + a->zp[i + 1]); + c[4 * i + 0] = z[i]; + c[4 * i + 1] = zp[i]; + c[4 * i + 2] = -3.0 / (h[i] * h[i]) * (z[i] - z[i + 1]) - 1.0 / h[i] * (2.0 * zp[i] + zp[i + 1]); + c[4 * i + 3] = 2.0 / (h[i] * h[i] * h[i]) * (z[i] - z[i + 1]) + 1.0 / (h[i] * h[i]) * (zp[i] + zp[i + 1]); } cleanup: return; diff --git a/wdsp/bldr.hpp b/wdsp/bldr.hpp index 9c643ddd9..09d2d00b5 100644 --- a/wdsp/bldr.hpp +++ b/wdsp/bldr.hpp @@ -28,6 +28,8 @@ warren@wpratt.com #ifndef wdsp_bldr_h #define wdsp_bldr_h +#include + #include "export.h" namespace WDSP { @@ -35,47 +37,50 @@ namespace WDSP { class WDSP_API BLDR { public: - float* catxy; - float* sx; - float* sy; - float* h; - int* p; - int* np; - float* taa; - float* tab; - float* tag; - float* tad; - float* tbb; - float* tbg; - float* tbd; - float* tgg; - float* tgd; - float* tdd; - float* A; - float* B; - float* C; - float* D; - float* E; - float* F; - float* G; - float* MAT; - float* RHS; - float* SLN; - float* z; - float* zp; - float* wrk; - int* ipiv; + double* catxy; + std::vector sx; + std::vector sy; + std::vector h; + std::vector p; + std::vector np; + std::vector taa; + std::vector tab; + std::vector tag; + std::vector tad; + std::vector tbb; + std::vector tbg; + std::vector tbd; + std::vector tgg; + std::vector tgd; + std::vector tdd; + std::vector A; + std::vector B; + std::vector C; + std::vector D; + std::vector E; + std::vector F; + std::vector G; + std::vector MAT; + std::vector RHS; + std::vector SLN; + std::vector z; + std::vector zp; + std::vector wrk; + std::vector ipiv; - static BLDR* create_builder(int points, int ints); - static void destroy_builder(BLDR *a); - static void flush_builder(BLDR *a, int points, int ints); - static void xbuilder(BLDR *a, int points, float* x, float* y, int ints, float* t, int* info, float* c, float ptol); + BLDR(int points, int ints); + BLDR(const BLDR&) = delete; + BLDR& operator=(const BLDR& other) = delete; + ~BLDR(); + + void flush(int points); + void execute(int points, const double* x, const double* y, int ints, const double* t, int* info, double* c, double ptol); private: static int fcompare(const void* a, const void* b); - static void decomp(int n, float* a, int* piv, int* info, float* wrk); - static void dsolve(int n, float* a, int* piv, float* b, float* x); - static void cull(int* n, int ints, float* x, float* t, float ptol); + static void decomp(int n, std::vector& a, std::vector& piv, int* info, std::vector& wrk); + static void dsolve(int n, std::vector& a, std::vector& piv, std::vector& b, std::vector& x); + static void cull(int* n, int ints, std::vector& x, const double* t, double ptol); }; } // namespace WDSP diff --git a/wdsp/bps.cpp b/wdsp/bps.cpp index 168cf95d0..af99c0e19 100644 --- a/wdsp/bps.cpp +++ b/wdsp/bps.cpp @@ -40,116 +40,116 @@ namespace WDSP { * * ********************************************************************************************************/ -void BPS::calc_bps (BPS *a) +void BPS::calc() { float* impulse; - a->infilt = new float[2 * a->size * 2]; - a->product = new float[2 * a->size * 2]; - impulse = FIR::fir_bandpass(a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); - a->mults = FIR::fftcv_mults(2 * a->size, impulse); - a->CFor = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->infilt, (fftwf_complex *)a->product, FFTW_FORWARD, FFTW_PATIENT); - a->CRev = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->product, (fftwf_complex *)a->out, FFTW_BACKWARD, FFTW_PATIENT); - delete[](impulse); + infilt.resize(2 * size * 2); + product.resize(2 * size * 2); + impulse = FIR::fir_bandpass(size + 1, f_low, f_high, samplerate, wintype, 1, 1.0 / (float)(2 * size)); + mults = FIR::fftcv_mults(2 * size, impulse); + CFor = fftwf_plan_dft_1d(2 * size, (fftwf_complex *) infilt.data(), (fftwf_complex *) product.data(), FFTW_FORWARD, FFTW_PATIENT); + CRev = fftwf_plan_dft_1d(2 * size, (fftwf_complex *) product.data(), (fftwf_complex *) out, FFTW_BACKWARD, FFTW_PATIENT); + delete[]impulse; } -void BPS::decalc_bps (BPS *a) +void BPS::decalc() { - fftwf_destroy_plan(a->CRev); - fftwf_destroy_plan(a->CFor); - delete[] (a->mults); - delete[] (a->product); - delete[] (a->infilt); + fftwf_destroy_plan(CRev); + fftwf_destroy_plan(CFor); + delete[] mults; } -BPS* BPS::create_bps ( - int run, - int position, - int size, - float* in, - float* out, - float f_low, - float f_high, - int samplerate, - int wintype, - float gain -) +BPS::BPS( + int _run, + int _position, + int _size, + float* _in, + float* _out, + double _f_low, + double _f_high, + int _samplerate, + int _wintype, + double _gain +) : + run(_run), + position(_position), + size(_size), + in(_in), + out(_out), + f_low(_f_low), + f_high(_f_high), + samplerate((double) _samplerate), + wintype(_wintype), + gain(_gain) { - BPS *a = new BPS; - a->run = run; - a->position = position; - a->size = size; - a->samplerate = (float)samplerate; - a->wintype = wintype; - a->gain = gain; - a->in = in; - a->out = out; - a->f_low = f_low; - a->f_high = f_high; - calc_bps (a); - return a; + calc(); } -void BPS::destroy_bps (BPS *a) +BPS::~BPS() { - decalc_bps (a); - delete a; + decalc(); } -void BPS::flush_bps (BPS *a) +void BPS::flush() { - std::fill(a->infilt, a->infilt + 2 * a->size * 2, 0); + std::fill(infilt.begin(), infilt.end(), 0); } -void BPS::xbps (BPS *a, int pos) +void BPS::execute(int pos) { - int i; - float I, Q; - if (a->run && pos == a->position) + double I; + double Q; + if (run && pos == position) { - std::copy(a->in, a->in + a->size * 2, &(a->infilt[2 * a->size])); - fftwf_execute (a->CFor); - for (i = 0; i < 2 * a->size; i++) + std::copy(in, in + size * 2, &(infilt[2 * size])); + fftwf_execute (CFor); + for (int i = 0; i < 2 * size; i++) { - I = a->gain * a->product[2 * i + 0]; - Q = a->gain * a->product[2 * i + 1]; - a->product[2 * i + 0] = I * a->mults[2 * i + 0] - Q * a->mults[2 * i + 1]; - a->product[2 * i + 1] = I * a->mults[2 * i + 1] + Q * a->mults[2 * i + 0]; + I = gain * product[2 * i + 0]; + Q = gain * product[2 * i + 1]; + product[2 * i + 0] = (float) (I * mults[2 * i + 0] - Q * mults[2 * i + 1]); + product[2 * i + 1] = (float) (I * mults[2 * i + 1] + Q * mults[2 * i + 0]); } - fftwf_execute (a->CRev); - std::copy(&(a->infilt[2 * a->size]), &(a->infilt[2 * a->size]) + a->size * 2, a->infilt); + fftwf_execute (CRev); + std::copy(&(infilt[2 * size]), &(infilt[2 * size]) + size * 2, infilt.begin()); } - else if (a->in != a->out) - std::copy( a->in, a->in + a->size * 2, a->out); + else if (in != out) + std::copy( in, in + size * 2, out); } -void BPS::setBuffers_bps (BPS *a, float* in, float* out) +void BPS::setBuffers(float* _in, float* _out) { - decalc_bps (a); - a->in = in; - a->out = out; - calc_bps (a); + decalc(); + in = _in; + out = _out; + calc(); } -void BPS::setSamplerate_bps (BPS *a, int rate) +void BPS::setSamplerate(int rate) { - decalc_bps (a); - a->samplerate = rate; - calc_bps (a); + decalc(); + samplerate = rate; + calc(); } -void BPS::setSize_bps (BPS *a, int size) +void BPS::setSize(int _size) { - decalc_bps (a); - a->size = size; - calc_bps (a); + decalc(); + size = _size; + calc(); } -void BPS::setFreqs_bps (BPS *a, float f_low, float f_high) +void BPS::setFreqs(double _f_low, double _f_high) { - decalc_bps (a); - a->f_low = f_low; - a->f_high = f_high; - calc_bps (a); + decalc(); + f_low = _f_low; + f_high = _f_high; + calc(); +} + +void BPS::setRun(int _run) +{ + run = _run; } /******************************************************************************************************** @@ -158,132 +158,4 @@ void BPS::setFreqs_bps (BPS *a, float f_low, float f_high) * * ********************************************************************************************************/ -void BPS::SetBPSRun (RXA& rxa, int run) -{ - rxa.bp1->run = run; -} - -void BPS::SetBPSFreqs (RXA& rxa, float f_low, float f_high) -{ - float* impulse; - BPS *a1; - a1 = rxa.bps1; - - if ((f_low != a1->f_low) || (f_high != a1->f_high)) - { - a1->f_low = f_low; - a1->f_high = f_high; - delete[] (a1->mults); - impulse = FIR::fir_bandpass(a1->size + 1, f_low, f_high, a1->samplerate, a1->wintype, 1, 1.0 / (float)(2 * a1->size)); - a1->mults = FIR::fftcv_mults (2 * a1->size, impulse); - delete[] (impulse); - } -} - -void BPS::SetBPSWindow (RXA& rxa, int wintype) -{ - float* impulse; - BPS *a1; - a1 = rxa.bps1; - - if ((a1->wintype != wintype)) - { - a1->wintype = wintype; - delete[] (a1->mults); - impulse = FIR::fir_bandpass(a1->size + 1, a1->f_low, a1->f_high, a1->samplerate, a1->wintype, 1, 1.0 / (float)(2 * a1->size)); - a1->mults = FIR::fftcv_mults (2 * a1->size, impulse); - delete[] (impulse); - } -} - -/******************************************************************************************************** -* * -* TXA Properties * -* * -********************************************************************************************************/ -// UNCOMMENT properties when pointers in place in txa -void BPS::SetBPSRun (TXA& txa, int run) -{ - txa.bp1->run = run; -} - -void BPS::SetBPSFreqs (TXA& txa, float f_low, float f_high) -{ - float* impulse; - BPS *a; - a = txa.bps0; - - if ((f_low != a->f_low) || (f_high != a->f_high)) - { - a->f_low = f_low; - a->f_high = f_high; - delete[] (a->mults); - impulse = FIR::fir_bandpass(a->size + 1, f_low, f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); - a->mults = FIR::fftcv_mults (2 * a->size, impulse); - delete[] (impulse); - } - - a = txa.bps1; - - if ((f_low != a->f_low) || (f_high != a->f_high)) - { - a->f_low = f_low; - a->f_high = f_high; - delete[] (a->mults); - impulse = FIR::fir_bandpass(a->size + 1, f_low, f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); - a->mults = FIR::fftcv_mults (2 * a->size, impulse); - delete[] (impulse); - } - - a = txa.bps2; - - if ((f_low != a->f_low) || (f_high != a->f_high)) - { - a->f_low = f_low; - a->f_high = f_high; - delete[] (a->mults); - impulse = FIR::fir_bandpass(a->size + 1, f_low, f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); - a->mults = FIR::fftcv_mults (2 * a->size, impulse); - delete[] (impulse); - } -} - -void BPS::SetBPSWindow (TXA& txa, int wintype) -{ - float* impulse; - BPS *a; - a = txa.bps0; - - if (a->wintype != wintype) - { - a->wintype = wintype; - delete[] (a->mults); - impulse = FIR::fir_bandpass(a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); - a->mults = FIR::fftcv_mults (2 * a->size, impulse); - delete[] (impulse); - } - - a = txa.bps1; - - if (a->wintype != wintype) - { - a->wintype = wintype; - delete[] (a->mults); - impulse = FIR::fir_bandpass(a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); - a->mults = FIR::fftcv_mults (2 * a->size, impulse); - delete[] (impulse); - } - - a = txa.bps2; - - if (a->wintype != wintype) - { - a->wintype = wintype; - delete[] (a->mults); - impulse = FIR::fir_bandpass (a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); - a->mults = FIR::fftcv_mults (2 * a->size, impulse); - delete[] (impulse); - } -} - } // namespace WDSP diff --git a/wdsp/bps.hpp b/wdsp/bps.hpp index b4ceb3cee..8133bef58 100644 --- a/wdsp/bps.hpp +++ b/wdsp/bps.hpp @@ -34,6 +34,8 @@ warren@wpratt.com #ifndef wdsp_bps_h #define wdsp_bps_h +#include + #include "fftw3.h" #include "export.h" @@ -50,48 +52,44 @@ public: int size; float* in; float* out; - float f_low; - float f_high; - float* infilt; - float* product; + double f_low; + double f_high; + std::vector infilt; + std::vector product; float* mults; - float samplerate; + double samplerate; int wintype; - float gain; + double gain; fftwf_plan CFor; fftwf_plan CRev; - static BPS* create_bps ( + BPS( int run, int position, int size, float* in, float* out, - float f_low, - float f_high, + double f_low, + double f_high, int samplerate, int wintype, - float gain + double gain ); - static void destroy_bps (BPS *a); - static void flush_bps (BPS *a); - static void xbps (BPS *a, int pos); - static void setBuffers_bps (BPS *a, float* in, float* out); - static void setSamplerate_bps (BPS *a, int rate); - static void setSize_bps (BPS *a, int size); - static void setFreqs_bps (BPS *a, float f_low, float f_high); - // RXA Prototypes - static void SetBPSRun (RXA& rxa, int run); - static void SetBPSFreqs (RXA& rxa, float low, float high); - static void SetBPSWindow (RXA& rxa, int wintype); - // TXA Prototypes - static void SetBPSRun (TXA& txa, int run); - static void SetBPSFreqs (TXA& txa, float low, float high); - static void SetBPSWindow (TXA& txa, int wintype); + BPS(const BPS&) = delete; + BPS& operator=(const BPS& other) = delete; + ~BPS(); + + void flush(); + void execute(int pos); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); + void setFreqs(double f_low, double f_high); + void setRun(int run); private: - static void calc_bps (BPS *a); - static void decalc_bps (BPS *a); + void calc(); + void decalc(); }; } // namespace WDSP diff --git a/wdsp/bqbp.cpp b/wdsp/bqbp.cpp index 49d8fba14..8a60e285a 100644 --- a/wdsp/bqbp.cpp +++ b/wdsp/bqbp.cpp @@ -38,7 +38,14 @@ namespace WDSP { void BQBP::calc() { - double f0, w0, bw, q, sn, cs, c, den; + double f0; + double w0; + double bw; + double q; + double sn; + double cs; + double c; + double den; bw = f_high - f_low; f0 = (f_high + f_low) / 2.0; @@ -99,15 +106,13 @@ void BQBP::execute() { if (run) { - int i, j, n; - - for (i = 0; i < size; i++) + for (int i = 0; i < size; i++) { - for (j = 0; j < 2; j++) + for (int j = 0; j < 2; j++) { x0[j] = gain * in[2 * i + j]; - for (n = 0; n < nstages; n++) + for (int n = 0; n < nstages; n++) { if (n > 0) x0[2 * n + j] = y0[2 * (n - 1) + j]; @@ -123,7 +128,7 @@ void BQBP::execute() x1[2 * n + j] = x0[2 * n + j]; } - out[2 * i + j] = y0[2 * (nstages - 1) + j]; + out[2 * i + j] = (float) y0[2 * (nstages - 1) + j]; } } } diff --git a/wdsp/bqlp.cpp b/wdsp/bqlp.cpp index f7ba6af5f..a062af522 100644 --- a/wdsp/bqlp.cpp +++ b/wdsp/bqlp.cpp @@ -38,9 +38,12 @@ namespace WDSP { void BQLP::calc() { - double w0, cs, c, den; + double w0; + double cs; + double c; + double den; - w0 = TWOPI * fc / (double)rate; + w0 = TWOPI * fc / rate; cs = cos(w0); c = sin(w0) / (2.0 * Q); den = 1.0 + c; @@ -95,15 +98,14 @@ void BQLP::execute() { if (run) { - int i, j, n; - for (i = 0; i < size; i++) + for (int i = 0; i < size; i++) { - for (j = 0; j < 2; j++) + for (int j = 0; j < 2; j++) { x0[j] = gain * in[2 * i + j]; - for (n = 0; n < nstages; n++) + for (int n = 0; n < nstages; n++) { if (n > 0) x0[2 * n + j] = y0[2 * (n - 1) + j]; @@ -118,7 +120,7 @@ void BQLP::execute() x1[2 * n + j] = x0[2 * n + j]; } - out[2 * i + j] = y0[2 * (nstages - 1) + j]; + out[2 * i + j] = (float) y0[2 * (nstages - 1) + j]; } } } diff --git a/wdsp/bqlp.hpp b/wdsp/bqlp.hpp index 5cebf3bb1..235876b48 100644 --- a/wdsp/bqlp.hpp +++ b/wdsp/bqlp.hpp @@ -52,8 +52,17 @@ public: double Q; double gain; int nstages; - double a0, a1, a2, b1, b2; - std::vector x0, x1, x2, y0, y1, y2; + double a0; + double a1; + double a2; + double b1; + double b2; + std::vector x0; + std::vector x1; + std::vector x2; + std::vector y0; + std::vector y1; + std::vector y2; BQLP( int run, diff --git a/wdsp/cblock.cpp b/wdsp/cblock.cpp index 1548d1698..0a5ce4fac 100644 --- a/wdsp/cblock.cpp +++ b/wdsp/cblock.cpp @@ -47,15 +47,15 @@ CBL::CBL( int _mode, int _sample_rate, double _tau -) +) : + run(_run), + buff_size(_buff_size), + in_buff(_in_buff), + out_buff(_out_buff), + mode(_mode), + sample_rate((double) _sample_rate), + tau(_tau) { - run = _run; - buff_size = _buff_size; - in_buff = _in_buff; - out_buff = _out_buff; - mode = _mode; - sample_rate = (double) _sample_rate; - tau = _tau; calc(); } diff --git a/wdsp/cfcomp.cpp b/wdsp/cfcomp.cpp index 4a7e67533..c05569682 100644 --- a/wdsp/cfcomp.cpp +++ b/wdsp/cfcomp.cpp @@ -32,381 +32,384 @@ warren@wpratt.com namespace WDSP { -void CFCOMP::calc_cfcwindow (CFCOMP *a) +void CFCOMP::calc_cfcwindow() { int i; - float arg0, arg1, cgsum, igsum, coherent_gain, inherent_power_gain, wmult; - switch (a->wintype) + double arg0; + double arg1; + double cgsum; + double igsum; + double coherent_gain; + double inherent_power_gain; + double wmult; + switch (wintype) { case 0: - arg0 = 2.0 * PI / (float)a->fsize; + arg0 = 2.0 * PI / (float)fsize; cgsum = 0.0; igsum = 0.0; - for (i = 0; i < a->fsize; i++) + for (i = 0; i < fsize; i++) { - a->window[i] = sqrt (0.54 - 0.46 * cos((float)i * arg0)); - cgsum += a->window[i]; - igsum += a->window[i] * a->window[i]; + window[i] = sqrt (0.54 - 0.46 * cos((float)i * arg0)); + cgsum += window[i]; + igsum += window[i] * window[i]; } - coherent_gain = cgsum / (float)a->fsize; - inherent_power_gain = igsum / (float)a->fsize; + coherent_gain = cgsum / (float)fsize; + inherent_power_gain = igsum / (float)fsize; wmult = 1.0 / sqrt (inherent_power_gain); - for (i = 0; i < a->fsize; i++) - a->window[i] *= wmult; - a->winfudge = sqrt (1.0 / coherent_gain); + for (i = 0; i < fsize; i++) + window[i] *= wmult; + winfudge = sqrt (1.0 / coherent_gain); break; case 1: - arg0 = 2.0 * PI / (float)a->fsize; + arg0 = 2.0 * PI / (float)fsize; cgsum = 0.0; igsum = 0.0; - for (i = 0; i < a->fsize; i++) + for (i = 0; i < fsize; i++) { arg1 = cos(arg0 * (float)i); - a->window[i] = sqrt (+0.21747 + window[i] = sqrt (+0.21747 + arg1 * (-0.45325 + arg1 * (+0.28256 + arg1 * (-0.04672)))); - cgsum += a->window[i]; - igsum += a->window[i] * a->window[i]; + cgsum += window[i]; + igsum += window[i] * window[i]; } - coherent_gain = cgsum / (float)a->fsize; - inherent_power_gain = igsum / (float)a->fsize; + coherent_gain = cgsum / (float)fsize; + inherent_power_gain = igsum / (float)fsize; wmult = 1.0 / sqrt (inherent_power_gain); - for (i = 0; i < a->fsize; i++) - a->window[i] *= wmult; - a->winfudge = sqrt (1.0 / coherent_gain); + for (i = 0; i < fsize; i++) + window[i] *= wmult; + winfudge = sqrt (1.0 / coherent_gain); + break; + default: break; } } int CFCOMP::fCOMPcompare (const void *a, const void *b) { - if (*(float*)a < *(float*)b) + if (*(double*)a < *(double*)b) return -1; - else if (*(float*)a == *(float*)b) + else if (*(double*)a == *(double*)b) return 0; else return 1; } -void CFCOMP::calc_comp (CFCOMP *a) +void CFCOMP::calc_comp() { - int i, j; - float f, frac, fincr, fmax; - float* sary; - a->precomplin = pow (10.0, 0.05 * a->precomp); - a->prepeqlin = pow (10.0, 0.05 * a->prepeq); - fmax = 0.5 * a->rate; - for (i = 0; i < a->nfreqs; i++) + int i; + int j; + double f; + double frac; + double fincr; + double fmax; + double* sary; + precomplin = pow (10.0, 0.05 * precomp); + prepeqlin = pow (10.0, 0.05 * prepeq); + fmax = 0.5 * rate; + for (i = 0; i < nfreqs; i++) { - a->F[i] = std::max (a->F[i], 0.0f); - a->F[i] = std::min (a->F[i], fmax); - a->G[i] = std::max (a->G[i], 0.0f); + F[i] = std::max (F[i], 0.0); + F[i] = std::min (F[i], fmax); + G[i] = std::max (G[i], 0.0); } - sary = new float[3 * a->nfreqs]; // (float *)malloc0 (3 * a->nfreqs * sizeof (float)); - for (i = 0; i < a->nfreqs; i++) + sary = new double[3 * nfreqs]; + for (i = 0; i < nfreqs; i++) { - sary[3 * i + 0] = a->F[i]; - sary[3 * i + 1] = a->G[i]; - sary[3 * i + 2] = a->E[i]; + sary[3 * i + 0] = F[i]; + sary[3 * i + 1] = G[i]; + sary[3 * i + 2] = E[i]; } - qsort (sary, a->nfreqs, 3 * sizeof (float), fCOMPcompare); - for (i = 0; i < a->nfreqs; i++) + qsort (sary, nfreqs, 3 * sizeof (float), fCOMPcompare); + for (i = 0; i < nfreqs; i++) { - a->F[i] = sary[3 * i + 0]; - a->G[i] = sary[3 * i + 1]; - a->E[i] = sary[3 * i + 2]; + F[i] = sary[3 * i + 0]; + G[i] = sary[3 * i + 1]; + E[i] = sary[3 * i + 2]; } - a->fp[0] = 0.0; - a->fp[a->nfreqs + 1] = fmax; - a->gp[0] = a->G[0]; - a->gp[a->nfreqs + 1] = a->G[a->nfreqs - 1]; - a->ep[0] = a->E[0]; // cutoff? - a->ep[a->nfreqs + 1] = a->E[a->nfreqs - 1]; // cutoff? - for (i = 0, j = 1; i < a->nfreqs; i++, j++) + fp[0] = 0.0; + fp[nfreqs + 1] = fmax; + gp[0] = G[0]; + gp[nfreqs + 1] = G[nfreqs - 1]; + ep[0] = E[0]; // cutoff? + ep[nfreqs + 1] = E[nfreqs - 1]; // cutoff? + for (i = 0, j = 1; i < nfreqs; i++, j++) { - a->fp[j] = a->F[i]; - a->gp[j] = a->G[i]; - a->ep[j] = a->E[i]; + fp[j] = F[i]; + gp[j] = G[i]; + ep[j] = E[i]; } - fincr = a->rate / (float)a->fsize; + fincr = rate / (float)fsize; j = 0; - // print_impulse ("gp.txt", a->nfreqs+2, a->gp, 0, 0); - for (i = 0; i < a->msize; i++) + + for (i = 0; i < msize; i++) { f = fincr * (float)i; - while (f >= a->fp[j + 1] && j < a->nfreqs) j++; - frac = (f - a->fp[j]) / (a->fp[j + 1] - a->fp[j]); - a->comp[i] = pow (10.0, 0.05 * (frac * a->gp[j + 1] + (1.0 - frac) * a->gp[j])); - a->peq[i] = pow (10.0, 0.05 * (frac * a->ep[j + 1] + (1.0 - frac) * a->ep[j])); - a->cfc_gain[i] = a->precomplin * a->comp[i]; + while (f >= fp[j + 1] && j < nfreqs) j++; + frac = (f - fp[j]) / (fp[j + 1] - fp[j]); + comp[i] = pow (10.0, 0.05 * (frac * gp[j + 1] + (1.0 - frac) * gp[j])); + peq[i] = pow (10.0, 0.05 * (frac * ep[j + 1] + (1.0 - frac) * ep[j])); + cfc_gain[i] = precomplin * comp[i]; } - // print_impulse ("comp.txt", a->msize, a->comp, 0, 0); + delete[] sary; } -void CFCOMP::calc_cfcomp(CFCOMP *a) +void CFCOMP::calc_cfcomp() { - int i; - a->incr = a->fsize / a->ovrlp; - if (a->fsize > a->bsize) - a->iasize = a->fsize; + incr = fsize / ovrlp; + if (fsize > bsize) + iasize = fsize; else - a->iasize = a->bsize + a->fsize - a->incr; - a->iainidx = 0; - a->iaoutidx = 0; - if (a->fsize > a->bsize) + iasize = bsize + fsize - incr; + iainidx = 0; + iaoutidx = 0; + if (fsize > bsize) { - if (a->bsize > a->incr) a->oasize = a->bsize; - else a->oasize = a->incr; - a->oainidx = (a->fsize - a->bsize - a->incr) % a->oasize; + if (bsize > incr) oasize = bsize; + else oasize = incr; + oainidx = (fsize - bsize - incr) % oasize; } else { - a->oasize = a->bsize; - a->oainidx = a->fsize - a->incr; + oasize = bsize; + oainidx = fsize - incr; } - a->init_oainidx = a->oainidx; - a->oaoutidx = 0; - a->msize = a->fsize / 2 + 1; - a->window = new float[a->fsize]; // (float *)malloc0 (a->fsize * sizeof(float)); - a->inaccum = new float[a->iasize]; // (float *)malloc0 (a->iasize * sizeof(float)); - a->forfftin = new float[a->fsize]; // (float *)malloc0 (a->fsize * sizeof(float)); - a->forfftout = new float[a->msize * 2]; // (float *)malloc0 (a->msize * sizeof(complex)); - a->cmask = new float[a->msize]; // (float *)malloc0 (a->msize * sizeof(float)); - a->mask = new float[a->msize]; // (float *)malloc0 (a->msize * sizeof(float)); - a->cfc_gain = new float[a->msize]; // (float *)malloc0 (a->msize * sizeof(float)); - a->revfftin = new float[a->msize * 2]; // (float *)malloc0 (a->msize * sizeof(complex)); - a->revfftout = new float[a->fsize]; // (float *)malloc0 (a->fsize * sizeof(float)); - a->save = new float*[a->ovrlp]; // (float **)malloc0(a->ovrlp * sizeof(float *)); - for (i = 0; i < a->ovrlp; i++) - a->save[i] = new float[a->fsize]; // (float *)malloc0(a->fsize * sizeof(float)); - a->outaccum = new float[a->oasize]; // (float *)malloc0(a->oasize * sizeof(float)); - a->nsamps = 0; - a->saveidx = 0; - a->Rfor = fftwf_plan_dft_r2c_1d(a->fsize, a->forfftin, (fftwf_complex *)a->forfftout, FFTW_ESTIMATE); - a->Rrev = fftwf_plan_dft_c2r_1d(a->fsize, (fftwf_complex *)a->revfftin, a->revfftout, FFTW_ESTIMATE); - calc_cfcwindow(a); + init_oainidx = oainidx; + oaoutidx = 0; + msize = fsize / 2 + 1; + window.resize(fsize); + inaccum.resize(iasize); + forfftin.resize(fsize); + forfftout.resize(msize * 2); + cmask.resize(msize); + mask.resize(msize); + cfc_gain.resize(msize); + revfftin.resize(msize * 2); + revfftout.resize(fsize); + save.resize(ovrlp); + for (int i = 0; i < ovrlp; i++) + save[i].resize(fsize); + outaccum.resize(oasize); + nsamps = 0; + saveidx = 0; + Rfor = fftwf_plan_dft_r2c_1d(fsize, forfftin.data(), (fftwf_complex *)forfftout.data(), FFTW_ESTIMATE); + Rrev = fftwf_plan_dft_c2r_1d(fsize, (fftwf_complex *)revfftin.data(), revfftout.data(), FFTW_ESTIMATE); + calc_cfcwindow(); - a->pregain = (2.0 * a->winfudge) / (float)a->fsize; - a->postgain = 0.5 / ((float)a->ovrlp * a->winfudge); + pregain = (2.0 * winfudge) / (double)fsize; + postgain = 0.5 / ((double)ovrlp * winfudge); - a->fp = new float[a->nfreqs + 2]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float)); - a->gp = new float[a->nfreqs + 2]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float)); - a->ep = new float[a->nfreqs + 2]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float)); - a->comp = new float[a->msize]; // (float *) malloc0 (a->msize * sizeof (float)); - a->peq = new float[a->msize]; // (float *) malloc0 (a->msize * sizeof (float)); - calc_comp (a); + fp.resize(nfreqs + 2); + gp.resize(nfreqs + 2); + ep.resize(nfreqs + 2); + comp.resize(msize); + peq.resize(msize); + calc_comp(); - a->gain = 0.0; - a->mmult = exp (-1.0 / (a->rate * a->ovrlp * a->mtau)); - a->dmult = exp (-(float)a->fsize / (a->rate * a->ovrlp * a->dtau)); + gain = 0.0; + mmult = exp (-1.0 / (rate * ovrlp * mtau)); + dmult = exp (-(float)fsize / (rate * ovrlp * dtau)); - a->delta = new float[a->msize]; // (float*)malloc0 (a->msize * sizeof(float)); - a->delta_copy = new float[a->msize]; // (float*)malloc0 (a->msize * sizeof(float)); - a->cfc_gain_copy = new float[a->msize]; // (float*)malloc0 (a->msize * sizeof(float)); + delta.resize(msize); + delta_copy.resize(msize); + cfc_gain_copy.resize(msize); } -void CFCOMP::decalc_cfcomp(CFCOMP *a) +void CFCOMP::decalc_cfcomp() +{ + fftwf_destroy_plan(Rrev); + fftwf_destroy_plan(Rfor); +} + +CFCOMP::CFCOMP( + int _run, + int _position, + int _peq_run, + int _size, + float* _in, + float* _out, + int _fsize, + int _ovrlp, + int _rate, + int _wintype, + int _comp_method, + int _nfreqs, + double _precomp, + double _prepeq, + const double* _F, + const double* _G, + const double* _E, + double _mtau, + double _dtau +) : + run (_run), + position(_position), + bsize(_size), + in(_in), + out(_out), + fsize(_fsize), + ovrlp(_ovrlp), + rate(_rate), + wintype(_wintype), + comp_method(_comp_method), + nfreqs(_nfreqs), + precomp(_precomp), + peq_run(_peq_run), + prepeq(_prepeq), + mtau(_mtau), // compression metering time constant + dtau(_dtau) // compression display time constant +{ + F.resize(nfreqs); + G.resize(nfreqs); + E.resize(nfreqs); + std::copy(_F, _F + nfreqs, F.begin()); + std::copy(_G, _G + nfreqs, G.begin()); + std::copy(_E, _E + nfreqs, E.begin()); + calc_cfcomp(); +} + +CFCOMP::~CFCOMP() +{ + decalc_cfcomp(); +} + +void CFCOMP::flush() +{ + std::fill(inaccum.begin(), inaccum.end(), 0); + for (int i = 0; i < ovrlp; i++) + std::fill(save[i].begin(), save[i].end(), 0); + std::fill(outaccum.begin(), outaccum.end(), 0); + nsamps = 0; + iainidx = 0; + iaoutidx = 0; + oainidx = init_oainidx; + oaoutidx = 0; + saveidx = 0; + gain = 0.0; + std::fill(delta.begin(), delta.end(), 0); +} + + + +void CFCOMP::calc_mask() { int i; - delete[] (a->cfc_gain_copy); - delete[] (a->delta_copy); - delete[] (a->delta); - delete[] (a->peq); - delete[] (a->comp); - delete[] (a->ep); - delete[] (a->gp); - delete[] (a->fp); - - fftwf_destroy_plan(a->Rrev); - fftwf_destroy_plan(a->Rfor); - delete[](a->outaccum); - for (i = 0; i < a->ovrlp; i++) - delete[](a->save[i]); - delete[](a->save); - delete[](a->revfftout); - delete[](a->revfftin); - delete[](a->cfc_gain); - delete[](a->mask); - delete[](a->cmask); - delete[](a->forfftout); - delete[](a->forfftin); - delete[](a->inaccum); - delete[](a->window); -} - -CFCOMP* CFCOMP::create_cfcomp (int run, int position, int peq_run, int size, float* in, float* out, int fsize, int ovrlp, - int rate, int wintype, int comp_method, int nfreqs, float precomp, float prepeq, float* F, float* G, float* E, float mtau, float dtau) -{ - CFCOMP *a = new CFCOMP; - a->run = run; - a->position = position; - a->peq_run = peq_run; - a->bsize = size; - a->in = in; - a->out = out; - a->fsize = fsize; - a->ovrlp = ovrlp; - a->rate = rate; - a->wintype = wintype; - a->comp_method = comp_method; - a->nfreqs = nfreqs; - a->precomp = precomp; - a->prepeq = prepeq; - a->mtau = mtau; // compression metering time constant - a->dtau = dtau; // compression display time constant - a->F = new float[a->nfreqs]; // (float *)malloc0 (a->nfreqs * sizeof (float)); - a->G = new float[a->nfreqs]; // (float *)malloc0 (a->nfreqs * sizeof (float)); - a->E = new float[a->nfreqs]; // (float *)malloc0 (a->nfreqs * sizeof (float)); - memcpy (a->F, F, a->nfreqs * sizeof (float)); - memcpy (a->G, G, a->nfreqs * sizeof (float)); - memcpy (a->E, E, a->nfreqs * sizeof (float)); - calc_cfcomp (a); - return a; -} - -void CFCOMP::flush_cfcomp (CFCOMP *a) -{ - int i; - memset (a->inaccum, 0, a->iasize * sizeof (float)); - for (i = 0; i < a->ovrlp; i++) - memset (a->save[i], 0, a->fsize * sizeof (float)); - memset (a->outaccum, 0, a->oasize * sizeof (float)); - a->nsamps = 0; - a->iainidx = 0; - a->iaoutidx = 0; - a->oainidx = a->init_oainidx; - a->oaoutidx = 0; - a->saveidx = 0; - a->gain = 0.0; - memset(a->delta, 0, a->msize * sizeof(float)); -} - -void CFCOMP::destroy_cfcomp (CFCOMP *a) -{ - decalc_cfcomp (a); - delete[] (a->E); - delete[] (a->G); - delete[] (a->F); - delete (a); -} - - -void CFCOMP::calc_mask (CFCOMP *a) -{ - int i; - float comp, mask, delta; - switch (a->comp_method) + double _comp; + double _mask; + double _delta; + if (comp_method == 0) { - case 0: + double mag; + double test; + for (i = 0; i < msize; i++) { - float mag, test; - for (i = 0; i < a->msize; i++) - { - mag = sqrt (a->forfftout[2 * i + 0] * a->forfftout[2 * i + 0] - + a->forfftout[2 * i + 1] * a->forfftout[2 * i + 1]); - comp = a->cfc_gain[i]; - test = comp * mag; - if (test > 1.0) - mask = 1.0 / mag; - else - mask = comp; - a->cmask[i] = mask; - if (test > a->gain) a->gain = test; - else a->gain = a->mmult * a->gain; + mag = sqrt (forfftout[2 * i + 0] * forfftout[2 * i + 0] + + forfftout[2 * i + 1] * forfftout[2 * i + 1]); + _comp = cfc_gain[i]; + test = _comp * mag; + if (test > 1.0) + _mask = 1.0 / mag; + else + _mask = _comp; + cmask[i] = _mask; + if (test > gain) gain = test; + else gain = mmult * gain; - delta = a->cfc_gain[i] - a->cmask[i]; - if (delta > a->delta[i]) a->delta[i] = delta; - else a->delta[i] *= a->dmult; + _delta = cfc_gain[i] - cmask[i]; + if (_delta > delta[i]) delta[i] = _delta; + else delta[i] *= dmult; + } + } + if (peq_run) + { + for (i = 0; i < msize; i++) + { + mask[i] = cmask[i] * prepeqlin * peq[i]; + } + } + else + std::copy(cmask.begin(), cmask.end(), mask.begin()); + mask_ready = 1; +} + +void CFCOMP::execute(int pos) +{ + if (run && pos == position) + { + int i; + int j; + int k; + int sbuff; + int sbegin; + for (i = 0; i < 2 * bsize; i += 2) + { + inaccum[iainidx] = in[i]; + iainidx = (iainidx + 1) % iasize; + } + nsamps += bsize; + while (nsamps >= fsize) + { + for (i = 0, j = iaoutidx; i < fsize; i++, j = (j + 1) % iasize) + forfftin[i] = (float) (pregain * window[i] * inaccum[j]); + iaoutidx = (iaoutidx + incr) % iasize; + nsamps -= incr; + fftwf_execute (Rfor); + calc_mask(); + for (i = 0; i < msize; i++) + { + revfftin[2 * i + 0] = (float) (mask[i] * forfftout[2 * i + 0]); + revfftin[2 * i + 1] = (float) (mask[i] * forfftout[2 * i + 1]); } - break; - } - } - if (a->peq_run) - { - for (i = 0; i < a->msize; i++) - { - a->mask[i] = a->cmask[i] * a->prepeqlin * a->peq[i]; - } - } - else - memcpy (a->mask, a->cmask, a->msize * sizeof (float)); - // print_impulse ("mask.txt", a->msize, a->mask, 0, 0); - a->mask_ready = 1; -} - -void CFCOMP::xcfcomp (CFCOMP *a, int pos) -{ - if (a->run && pos == a->position) - { - int i, j, k, sbuff, sbegin; - for (i = 0; i < 2 * a->bsize; i += 2) - { - a->inaccum[a->iainidx] = a->in[i]; - a->iainidx = (a->iainidx + 1) % a->iasize; - } - a->nsamps += a->bsize; - while (a->nsamps >= a->fsize) - { - for (i = 0, j = a->iaoutidx; i < a->fsize; i++, j = (j + 1) % a->iasize) - a->forfftin[i] = a->pregain * a->window[i] * a->inaccum[j]; - a->iaoutidx = (a->iaoutidx + a->incr) % a->iasize; - a->nsamps -= a->incr; - fftwf_execute (a->Rfor); - calc_mask(a); - for (i = 0; i < a->msize; i++) + fftwf_execute (Rrev); + for (i = 0; i < fsize; i++) + save[saveidx][i] = postgain * window[i] * revfftout[i]; + for (i = ovrlp; i > 0; i--) { - a->revfftin[2 * i + 0] = a->mask[i] * a->forfftout[2 * i + 0]; - a->revfftin[2 * i + 1] = a->mask[i] * a->forfftout[2 * i + 1]; - } - fftwf_execute (a->Rrev); - for (i = 0; i < a->fsize; i++) - a->save[a->saveidx][i] = a->postgain * a->window[i] * a->revfftout[i]; - for (i = a->ovrlp; i > 0; i--) - { - sbuff = (a->saveidx + i) % a->ovrlp; - sbegin = a->incr * (a->ovrlp - i); - for (j = sbegin, k = a->oainidx; j < a->incr + sbegin; j++, k = (k + 1) % a->oasize) + sbuff = (saveidx + i) % ovrlp; + sbegin = incr * (ovrlp - i); + for (j = sbegin, k = oainidx; j < incr + sbegin; j++, k = (k + 1) % oasize) { - if ( i == a->ovrlp) - a->outaccum[k] = a->save[sbuff][j]; + if ( i == ovrlp) + outaccum[k] = save[sbuff][j]; else - a->outaccum[k] += a->save[sbuff][j]; + outaccum[k] += save[sbuff][j]; } } - a->saveidx = (a->saveidx + 1) % a->ovrlp; - a->oainidx = (a->oainidx + a->incr) % a->oasize; + saveidx = (saveidx + 1) % ovrlp; + oainidx = (oainidx + incr) % oasize; } - for (i = 0; i < a->bsize; i++) + for (i = 0; i < bsize; i++) { - a->out[2 * i + 0] = a->outaccum[a->oaoutidx]; - a->out[2 * i + 1] = 0.0; - a->oaoutidx = (a->oaoutidx + 1) % a->oasize; + out[2 * i + 0] = (float) (outaccum[oaoutidx]); + out[2 * i + 1] = 0.0; + oaoutidx = (oaoutidx + 1) % oasize; } } - else if (a->out != a->in) - std::copy(a->in, a->in + a->bsize * 2, a->out); + else if (out != in) + std::copy(in, in + bsize * 2, out); } -void CFCOMP::setBuffers_cfcomp (CFCOMP *a, float* in, float* out) +void CFCOMP::setBuffers(float* _in, float* _out) { - a->in = in; - a->out = out; + in = _in; + out = _out; } -void CFCOMP::setSamplerate_cfcomp (CFCOMP *a, int rate) +void CFCOMP::setSamplerate(int _rate) { - decalc_cfcomp (a); - a->rate = rate; - calc_cfcomp (a); + decalc_cfcomp(); + rate = _rate; + calc_cfcomp(); } -void CFCOMP::setSize_cfcomp (CFCOMP *a, int size) +void CFCOMP::setSize(int size) { - decalc_cfcomp (a); - a->bsize = size; - calc_cfcomp (a); + decalc_cfcomp(); + bsize = size; + calc_cfcomp(); } /******************************************************************************************************** @@ -415,94 +418,75 @@ void CFCOMP::setSize_cfcomp (CFCOMP *a, int size) * * ********************************************************************************************************/ -void CFCOMP::SetCFCOMPRun (TXA& txa, int run) +void CFCOMP::setRun(int _run) { - CFCOMP *a = txa.cfcomp; - - if (a->run != run) { - a->run = run; + if (run != _run) { + run = _run; } } -void CFCOMP::SetCFCOMPPosition (TXA& txa, int pos) +void CFCOMP::setPosition(int pos) { - CFCOMP *a = txa.cfcomp; - - if (a->position != pos) { - a->position = pos; + if (position != pos) { + position = pos; } } -void CFCOMP::SetCFCOMPprofile (TXA& txa, int nfreqs, float* F, float* G, float *E) +void CFCOMP::setProfile(int _nfreqs, const double* _F, const double* _G, const double* _E) { - CFCOMP *a = txa.cfcomp; - a->nfreqs = nfreqs < 1 ? 1 : nfreqs; - delete[] (a->E); - delete[] (a->F); - delete[] (a->G); - a->F = new float[a->nfreqs]; // (float *)malloc0 (a->nfreqs * sizeof (float)); - a->G = new float[a->nfreqs]; // (float *)malloc0 (a->nfreqs * sizeof (float)); - a->E = new float[a->nfreqs]; // (float *)malloc0 (a->nfreqs * sizeof (float)); - memcpy (a->F, F, a->nfreqs * sizeof (float)); - memcpy (a->G, G, a->nfreqs * sizeof (float)); - memcpy (a->E, E, a->nfreqs * sizeof (float)); - delete[] (a->ep); - delete[] (a->gp); - delete[] (a->fp); - a->fp = new float[a->nfreqs + 2]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float)); - a->gp = new float[a->nfreqs + 2]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float)); - a->ep = new float[a->nfreqs + 2]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float)); - calc_comp(a); + nfreqs = _nfreqs < 1 ? 1 : _nfreqs; + F.resize(nfreqs); + G.resize(nfreqs); + E.resize(nfreqs); + std::copy(_F, _F + nfreqs, F.begin()); + std::copy(_G, _G + nfreqs, G.begin()); + std::copy(_E, _E + nfreqs, E.begin()); + fp.resize(nfreqs + 2); + gp.resize(nfreqs + 2); + ep.resize(nfreqs + 2); + calc_comp(); } -void CFCOMP::SetCFCOMPPrecomp (TXA& txa, float precomp) +void CFCOMP::setPrecomp(double _precomp) { - CFCOMP *a = txa.cfcomp; - - if (a->precomp != precomp) + if (precomp != _precomp) { - a->precomp = precomp; - a->precomplin = pow (10.0, 0.05 * a->precomp); + precomp = _precomp; + precomplin = pow (10.0, 0.05 * precomp); - for (int i = 0; i < a->msize; i++) + for (int i = 0; i < msize; i++) { - a->cfc_gain[i] = a->precomplin * a->comp[i]; + cfc_gain[i] = precomplin * comp[i]; } } } -void CFCOMP::SetCFCOMPPeqRun (TXA& txa, int run) +void CFCOMP::setPeqRun(int _run) { - CFCOMP *a = txa.cfcomp; - - if (a->peq_run != run) { - a->peq_run = run; + if (peq_run != _run) { + peq_run = _run; } } -void CFCOMP::SetCFCOMPPrePeq (TXA& txa, float prepeq) +void CFCOMP::setPrePeq(double _prepeq) { - CFCOMP *a = txa.cfcomp; - a->prepeq = prepeq; - a->prepeqlin = pow (10.0, 0.05 * a->prepeq); + prepeq = _prepeq; + prepeqlin = pow (10.0, 0.05 * prepeq); } -void CFCOMP::GetCFCOMPDisplayCompression (TXA& txa, float* comp_values, int* ready) +void CFCOMP::getDisplayCompression(double* comp_values, int* ready) { - int i; - CFCOMP *a = txa.cfcomp; - - if ((*ready = a->mask_ready)) + if ((*ready = mask_ready)) { - memcpy(a->delta_copy, a->delta, a->msize * sizeof(float)); - memcpy(a->cfc_gain_copy, a->cfc_gain, a->msize * sizeof(float)); - a->mask_ready = 0; + std::copy(delta.begin(), delta.end(), delta_copy.begin()); + std::copy(cfc_gain.begin(), cfc_gain.end(), cfc_gain_copy.begin()); + mask_ready = 0; } if (*ready) { - for (i = 0; i < a->msize; i++) - comp_values[i] = 20.0 * MemLog::mlog10 (a->cfc_gain_copy[i] / (a->cfc_gain_copy[i] - a->delta_copy[i])); + for (int i = 0; i < msize; i++) + comp_values[i] = 20.0 * MemLog::mlog10 (cfc_gain_copy[i] / (cfc_gain_copy[i] - delta_copy[i])); } } diff --git a/wdsp/cfcomp.hpp b/wdsp/cfcomp.hpp index a0e043b4c..1f917f929 100644 --- a/wdsp/cfcomp.hpp +++ b/wdsp/cfcomp.hpp @@ -28,6 +28,8 @@ warren@wpratt.com #ifndef wdsp_cfcomp_h #define wdsp_cfcomp_h +#include + #include "fftw3.h" #include "export.h" @@ -46,25 +48,25 @@ public: int fsize; int ovrlp; int incr; - float* window; + std::vector window; int iasize; - float* inaccum; - float* forfftin; - float* forfftout; + std::vector inaccum; + std::vector forfftin; + std::vector forfftout; int msize; - float* cmask; - float* mask; + std::vector cmask; + std::vector mask; int mask_ready; - float* cfc_gain; - float* revfftin; - float* revfftout; - float** save; + std::vector cfc_gain; + std::vector revfftin; + std::vector revfftout; + std::vector> save; int oasize; - float* outaccum; - float rate; + std::vector outaccum; + double rate; int wintype; - float pregain; - float postgain; + double pregain; + double postgain; int nsamps; int iainidx; int iaoutidx; @@ -77,32 +79,32 @@ public: int comp_method; int nfreqs; - float* F; - float* G; - float* E; - float* fp; - float* gp; - float* ep; - float* comp; - float precomp; - float precomplin; - float* peq; + std::vector F; + std::vector G; + std::vector E; + std::vector fp; + std::vector gp; + std::vector ep; + std::vector comp; + double precomp; + double precomplin; + std::vector peq; int peq_run; - float prepeq; - float prepeqlin; - float winfudge; + double prepeq; + double prepeqlin; + double winfudge; - float gain; - float mtau; - float mmult; + double gain; + double mtau; + double mmult; // display stuff - float dtau; - float dmult; - float* delta; - float* delta_copy; - float* cfc_gain_copy; + double dtau; + double dmult; + std::vector delta; + std::vector delta_copy; + std::vector cfc_gain_copy; - static CFCOMP* create_cfcomp ( + CFCOMP( int run, int position, int peq_run, @@ -115,36 +117,39 @@ public: int wintype, int comp_method, int nfreqs, - float precomp, - float prepeq, - float* F, - float* G, - float* E, - float mtau, - float dtau + double precomp, + double prepeq, + const double* F, + const double* G, + const double* E, + double mtau, + double dtau ); - static void destroy_cfcomp (CFCOMP *a); - static void flush_cfcomp (CFCOMP *a); - static void xcfcomp (CFCOMP *a, int pos); - static void setBuffers_cfcomp (CFCOMP *a, float* in, float* out); - static void setSamplerate_cfcomp (CFCOMP *a, int rate); - static void setSize_cfcomp (CFCOMP *a, int size); + CFCOMP(const CFCOMP&) = delete; + CFCOMP& operator=(CFCOMP& other) = delete; + ~CFCOMP(); + + void flush(); + void execute(int pos); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); // TXA Properties - static void SetCFCOMPRun (TXA& txa, int run); - static void SetCFCOMPPosition (TXA& txa, int pos); - static void SetCFCOMPprofile (TXA& txa, int nfreqs, float* F, float* G, float *E); - static void SetCFCOMPPrecomp (TXA& txa, float precomp); - static void SetCFCOMPPeqRun (TXA& txa, int run); - static void SetCFCOMPPrePeq (TXA& txa, float prepeq); - static void GetCFCOMPDisplayCompression (TXA& txa, float* comp_values, int* ready); + void setRun(int run); + void setPosition(int pos); + void setProfile(int nfreqs, const double* F, const double* G, const double *E); + void setPrecomp(double precomp); + void setPeqRun(int run); + void setPrePeq(double prepeq); + void getDisplayCompression(double* comp_values, int* ready); private: - static void calc_cfcwindow (CFCOMP *a); + void calc_cfcwindow(); static int fCOMPcompare (const void *a, const void *b); - static void calc_comp (CFCOMP *a); - static void calc_cfcomp(CFCOMP *a); - static void decalc_cfcomp(CFCOMP *a); - static void calc_mask (CFCOMP *a); + void calc_comp(); + void calc_cfcomp(); + void decalc_cfcomp(); + void calc_mask(); }; } // namespace WDSP diff --git a/wdsp/compress.cpp b/wdsp/compress.cpp index 5a8d2a556..a36e32927 100644 --- a/wdsp/compress.cpp +++ b/wdsp/compress.cpp @@ -35,13 +35,14 @@ in the January 2010 issue of RadCom magazine. namespace WDSP { COMPRESSOR* COMPRESSOR::create_compressor ( - int run, - int buffsize, - float* inbuff, - float* outbuff, - float gain ) + int run, + int buffsize, + float* inbuff, + float* outbuff, + double gain +) { - COMPRESSOR *a = new COMPRESSOR; + auto *a = new COMPRESSOR; a->run = run; a->inbuff = inbuff; a->outbuff = outbuff; @@ -61,10 +62,9 @@ void COMPRESSOR::flush_compressor (COMPRESSOR *) void COMPRESSOR::xcompressor (COMPRESSOR *a) { - int i; float mag; if (a->run) - for (i = 0; i < a->buffsize; i++) + for (int i = 0; i < a->buffsize; i++) { mag = sqrt(a->inbuff[2 * i + 0] * a->inbuff[2 * i + 0] + a->inbuff[2 * i + 1] * a->inbuff[2 * i + 1]); if (a->gain * mag > 1.0) diff --git a/wdsp/compress.hpp b/wdsp/compress.hpp index 392072094..dc134bb58 100644 --- a/wdsp/compress.hpp +++ b/wdsp/compress.hpp @@ -41,14 +41,14 @@ public: int buffsize; float *inbuff; float *outbuff; - float gain; + double gain; static COMPRESSOR* create_compressor ( int run, int buffsize, float* inbuff, float* outbuff, - float gain + double gain ); static void destroy_compressor (COMPRESSOR *a); static void flush_compressor (COMPRESSOR *a); diff --git a/wdsp/dbqbp.cpp b/wdsp/dbqbp.cpp index a600f6b83..86856acd5 100644 --- a/wdsp/dbqbp.cpp +++ b/wdsp/dbqbp.cpp @@ -38,7 +38,14 @@ namespace WDSP { void DBQBP::calc() { - double f0, w0, bw, q, sn, cs, c, den; + double f0; + double w0; + double bw; + double q; + double sn; + double cs; + double c; + double den; bw = f_high - f_low; f0 = (f_high + f_low) / 2.0; @@ -98,13 +105,12 @@ void DBQBP::execute() { if (run) { - int i, n; - for (i = 0; i < size; i++) + for (int i = 0; i < size; i++) { x0[0] = gain * in[i]; - for (n = 0; n < nstages; n++) + for (int n = 0; n < nstages; n++) { if (n > 0) x0[n] = y0[n - 1]; @@ -120,7 +126,7 @@ void DBQBP::execute() x1[n] = x0[n]; } - out[i] = y0[nstages - 1]; + out[i] = (float) y0[nstages - 1]; } } else if (out != in) diff --git a/wdsp/dbqbp.hpp b/wdsp/dbqbp.hpp index e043426fb..0f1083f40 100644 --- a/wdsp/dbqbp.hpp +++ b/wdsp/dbqbp.hpp @@ -52,8 +52,17 @@ public: double f_high; double gain; int nstages; - double a0, a1, a2, b1, b2; - std::vector x0, x1, x2, y0, y1, y2; + double a0; + double a1; + double a2; + double b1; + double b2; + std::vector x0; + std::vector x1; + std::vector x2; + std::vector y0; + std::vector y1; + std::vector y2; // Double Bi-Quad Band-Pass DBQBP( diff --git a/wdsp/dsphp.cpp b/wdsp/dsphp.cpp index 4c6ad9981..62b74dfda 100644 --- a/wdsp/dsphp.cpp +++ b/wdsp/dsphp.cpp @@ -57,15 +57,15 @@ DSPHP::DSPHP( double _rate, double _fc, int _nstages -) +) : + run(_run), + size(_size), + in(_in), + out(_out), + rate(_rate), + fc(_fc), + nstages(_nstages) { - run = _run; - size = _size; - in = _in; - out = _out; - rate = _rate; - fc = _fc; - nstages = _nstages; calc(); } diff --git a/wdsp/emnr.cpp b/wdsp/emnr.cpp index 6baca2b2c..27c656710 100644 --- a/wdsp/emnr.cpp +++ b/wdsp/emnr.cpp @@ -118,7 +118,9 @@ EMNR::NP::NP( rate(_rate), msize(_msize), lambda_y(_lambda_y), - lambda_d(_lambda_d) + lambda_d(_lambda_d), + invQeqMax(0.5), + av(2.12) { double tau0 = -128.0 / 8000.0 / log(0.7); @@ -132,8 +134,6 @@ EMNR::NP::NP( snrq = -incr / (0.064 * rate); double tau4 = -128.0 / 8000.0 / log(0.8); betamax = exp(-incr / rate / tau4); - invQeqMax = 0.5; - av = 2.12; Dtime = 8.0 * 12.0 * 128.0 / 8000.0; U = 8; V = (int)(0.5 + (Dtime * rate / (U * incr))); diff --git a/wdsp/emph.cpp b/wdsp/emph.cpp index 90498c1e7..552ac1539 100644 --- a/wdsp/emph.cpp +++ b/wdsp/emph.cpp @@ -33,239 +33,117 @@ warren@wpratt.com namespace WDSP { -/******************************************************************************************************** -* * -* Partitioned Overlap-Save FM Pre-Emphasis * -* * -********************************************************************************************************/ - -EMPHP* EMPHP::create_emphp (int run, int position, int size, int nc, int mp, float* in, float* out, int rate, int ctype, float f_low, float f_high) -{ - EMPHP *a = new EMPHP; - float* impulse; - a->run = run; - a->position = position; - a->size = size; - a->nc = nc; - a->mp = mp; - a->in = in; - a->out = out; - a->rate = rate; - a->ctype = ctype; - a->f_low = f_low; - a->f_high = f_high; - impulse = FCurve::fc_impulse (a->nc, a->f_low, a->f_high, -20.0 * log10(a->f_high / a->f_low), 0.0, a->ctype, a->rate, 1.0 / (2.0 * a->size), 0, 0); - a->p = FIRCORE::create_fircore (a->size, a->in, a->out, a->nc, a->mp, impulse); - delete[] (impulse); - return a; -} - -void EMPHP::destroy_emphp (EMPHP *a) -{ - FIRCORE::destroy_fircore (a->p); - delete (a); -} - -void EMPHP::flush_emphp (EMPHP *a) -{ - FIRCORE::flush_fircore (a->p); -} - -void EMPHP::xemphp (EMPHP *a, int position) -{ - if (a->run && a->position == position) - FIRCORE::xfircore (a->p); - else if (a->in != a->out) - std::copy( a->in, a->in + a->size * 2, a->out); -} - -void EMPHP::setBuffers_emphp (EMPHP *a, float* in, float* out) -{ - a->in = in; - a->out = out; - FIRCORE::setBuffers_fircore (a->p, a->in, a->out); -} - -void EMPHP::setSamplerate_emphp (EMPHP *a, int rate) -{ - float* impulse; - a->rate = rate; - impulse = FCurve::fc_impulse (a->nc, a->f_low, a->f_high, -20.0 * log10(a->f_high / a->f_low), 0.0, a->ctype, a->rate, 1.0 / (2.0 * a->size), 0, 0); - FIRCORE::setImpulse_fircore (a->p, impulse, 1); - delete[] (impulse); -} - -void EMPHP::setSize_emphp (EMPHP *a, int size) -{ - float* impulse; - a->size = size; - FIRCORE::setSize_fircore (a->p, a->size); - impulse = FCurve::fc_impulse (a->nc, a->f_low, a->f_high, -20.0 * log10(a->f_high / a->f_low), 0.0, a->ctype, a->rate, 1.0 / (2.0 * a->size), 0, 0); - FIRCORE::setImpulse_fircore (a->p, impulse, 1); - delete[] (impulse); -} - -/******************************************************************************************************** -* * -* Partitioned Overlap-Save FM Pre-Emphasis: TXA Properties * -* * -********************************************************************************************************/ - -void EMPHP::SetFMEmphPosition (TXA& txa, int position) -{ - txa.preemph->position = position; -} - -void EMPHP::SetFMEmphMP (TXA& txa, int mp) -{ - EMPHP *a; - a = txa.preemph; - if (a->mp != mp) - { - a->mp = mp; - FIRCORE::setMp_fircore (a->p, a->mp); - } -} - -void EMPHP::SetFMEmphNC (TXA& txa, int nc) -{ - EMPHP *a; - float* impulse; - a = txa.preemph; - - if (a->nc != nc) - { - a->nc = nc; - impulse = FCurve::fc_impulse (a->nc, a->f_low, a->f_high, -20.0 * log10(a->f_high / a->f_low), 0.0, a->ctype, a->rate, 1.0 / (2.0 * a->size), 0, 0); - FIRCORE::setNc_fircore (a->p, a->nc, impulse); - delete[] (impulse); - } -} - -void EMPHP::SetFMPreEmphFreqs (TXA& txa, float low, float high) -{ - EMPHP *a; - float* impulse; - a = txa.preemph; - - if (a->f_low != low || a->f_high != high) - { - a->f_low = low; - a->f_high = high; - impulse = FCurve::fc_impulse (a->nc, a->f_low, a->f_high, -20.0 * log10(a->f_high / a->f_low), 0.0, a->ctype, a->rate, 1.0 / (2.0 * a->size), 0, 0); - FIRCORE::setImpulse_fircore (a->p, impulse, 1); - delete[] (impulse); - } -} - /******************************************************************************************************** * * * Overlap-Save FM Pre-Emphasis * * * ********************************************************************************************************/ -void EMPH::calc_emph (EMPH *a) +void EMPH::calc() { - a->infilt = new float[2 * a->size * 2]; // (float *)malloc0(2 * a->size * sizeof(complex)); - a->product = new float[2 * a->size * 2]; // (float *)malloc0(2 * a->size * sizeof(complex)); - a->mults = FCurve::fc_mults(a->size, a->f_low, a->f_high, -20.0 * log10(a->f_high / a->f_low), 0.0, a->ctype, a->rate, 1.0 / (2.0 * a->size), 0, 0); - a->CFor = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->infilt, (fftwf_complex *)a->product, FFTW_FORWARD, FFTW_PATIENT); - a->CRev = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->product, (fftwf_complex *)a->out, FFTW_BACKWARD, FFTW_PATIENT); + infilt = new float[2 * size * 2]; + product = new float[2 * size * 2]; + mults = FCurve::fc_mults( + size, + f_low, + f_high, + -20.0 * log10(f_high / f_low), + 0.0, + ctype, + rate, + 1.0 / (2.0 * size), + 0, + 0 + ); + CFor = fftwf_plan_dft_1d(2 * size, (fftwf_complex *)infilt, (fftwf_complex *)product, FFTW_FORWARD, FFTW_PATIENT); + CRev = fftwf_plan_dft_1d(2 * size, (fftwf_complex *)product, (fftwf_complex *)out, FFTW_BACKWARD, FFTW_PATIENT); } -void EMPH::decalc_emph (EMPH *a) +void EMPH::decalc() { - fftwf_destroy_plan(a->CRev); - fftwf_destroy_plan(a->CFor); - delete[] (a->mults); - delete[] (a->product); - delete[] (a->infilt); + fftwf_destroy_plan(CRev); + fftwf_destroy_plan(CFor); + delete[] mults; + delete[] product; + delete[] infilt; } -EMPH* EMPH::create_emph (int run, int position, int size, float* in, float* out, int rate, int ctype, float f_low, float f_high) +EMPH::EMPH( + int _run, + int _position, + int _size, + float* _in, + float* _out, + int _rate, + int _ctype, + double _f_low, + double _f_high +) : + run(_run), + position(_position), + size(_size), + in(_in), + out(_out), + ctype(_ctype), + f_low(_f_low), + f_high(_f_high), + rate((double) _rate) { - EMPH *a = new EMPH; - a->run = run; - a->position = position; - a->size = size; - a->in = in; - a->out = out; - a->rate = (float)rate; - a->ctype = ctype; - a->f_low = f_low; - a->f_high = f_high; - calc_emph (a); - return a; + calc(); } -void EMPH::destroy_emph (EMPH *a) +EMPH::~EMPH() { - decalc_emph (a); - delete (a); + decalc(); } -void EMPH::flush_emph (EMPH *a) +void EMPH::flush() { - std::fill(a->infilt, a->infilt + 2 * a->size * 2, 0); + std::fill(infilt, infilt + 2 * size * 2, 0); } -void EMPH::xemph (EMPH *a, int position) +void EMPH::execute(int _position) { - int i; - float I, Q; - if (a->run && a->position == position) + double I; + double Q; + if (run && position == _position) { - std::copy(a->in, a->in + a->size * 2, &(a->infilt[2 * a->size])); - fftwf_execute (a->CFor); - for (i = 0; i < 2 * a->size; i++) + std::copy(in, in + size * 2, &(infilt[2 * size])); + fftwf_execute (CFor); + for (int i = 0; i < 2 * size; i++) { - I = a->product[2 * i + 0]; - Q = a->product[2 * i + 1]; - a->product[2 * i + 0] = I * a->mults[2 * i + 0] - Q * a->mults[2 * i + 1]; - a->product[2 * i + 1] = I * a->mults[2 * i + 1] + Q * a->mults[2 * i + 0]; + I = product[2 * i + 0]; + Q = product[2 * i + 1]; + product[2 * i + 0] = (float) (I * mults[2 * i + 0] - Q * mults[2 * i + 1]); + product[2 * i + 1] = (float) (I * mults[2 * i + 1] + Q * mults[2 * i + 0]); } - fftwf_execute (a->CRev); - std::copy(&(a->infilt[2 * a->size]), &(a->infilt[2 * a->size]) + a->size * 2, a->infilt); + fftwf_execute (CRev); + std::copy(&(infilt[2 * size]), &(infilt[2 * size]) + size * 2, infilt); } - else if (a->in != a->out) - std::copy( a->in, a->in + a->size * 2, a->out); + else if (in != out) + std::copy( in, in + size * 2, out); } -void EMPH::setBuffers_emph (EMPH *a, float* in, float* out) +void EMPH::setBuffers(float* _in, float* _out) { - decalc_emph (a); - a->in = in; - a->out = out; - calc_emph (a); + decalc(); + in = _in; + out = _out; + calc(); } -void EMPH::setSamplerate_emph (EMPH *a, int rate) +void EMPH::setSamplerate(int _rate) { - decalc_emph (a); - a->rate = rate; - calc_emph (a); + decalc(); + rate = _rate; + calc(); } -void EMPH::setSize_emph (EMPH *a, int size) +void EMPH::setSize(int _size) { - decalc_emph(a); - a->size = size; - calc_emph(a); + decalc(); + size = _size; + calc(); } -/******************************************************************************************************** -* * -* Overlap-Save FM Pre-Emphasis: TXA Properties * -* * -********************************************************************************************************/ -/* // Uncomment when needed -PORT -void SetTXAFMEmphPosition (int channel, int position) -{ - ch.csDSP.lock(); - txa.preemph->position = position; - ch.csDSP.unlock(); -} -*/ - } // namespace WDSP diff --git a/wdsp/emph.hpp b/wdsp/emph.hpp index e64c107a9..21b9f8fc1 100644 --- a/wdsp/emph.hpp +++ b/wdsp/emph.hpp @@ -25,57 +25,6 @@ warren@wpratt.com */ -/******************************************************************************************************** -* * -* Partitioned Overlap-Save FM Pre-Emphasis * -* * -********************************************************************************************************/ - -#ifndef wdsp_emphp_h -#define wdsp_emphp_h - -#include "export.h" - -namespace WDSP { - -class FIRCORE; -class TXA; - -class WDSP_API EMPHP -{ -public: - int run; - int position; - int size; - int nc; - int mp; - float* in; - float* out; - int ctype; - float f_low; - float f_high; - float rate; - FIRCORE *p; - - static EMPHP* create_emphp (int run, int position, int size, int nc, int mp, - float* in, float* out, int rate, int ctype, float f_low, float f_high); - static void destroy_emphp (EMPHP *a); - static void flush_emphp (EMPHP *a); - static void xemphp (EMPHP *a, int position); - static void setBuffers_emphp (EMPHP *a, float* in, float* out); - static void setSamplerate_emphp (EMPHP *a, int rate); - static void setSize_emphp (EMPHP *a, int size); - // TXA Properties - static void SetFMEmphPosition (TXA& txa, int position); - static void SetFMEmphMP (TXA& txa, int mp); - static void SetFMEmphNC (TXA& txa, int nc); - static void SetFMPreEmphFreqs(TXA& txa, float low, float high); -}; - -} // namespace WDSP - -#endif - /******************************************************************************************************** * * * Overlap-Save FM Pre-Emphasis * @@ -92,32 +41,46 @@ namespace WDSP { class WDSP_API EMPH { +public: int run; int position; int size; float* in; float* out; int ctype; - float f_low; - float f_high; + double f_low; + double f_high; float* infilt; float* product; float* mults; - float rate; + double rate; fftwf_plan CFor; fftwf_plan CRev; - static EMPH* create_emph (int run, int position, int size, float* in, float* out, int rate, int ctype, float f_low, float f_high); - static void destroy_emph (EMPH *a); - static void flush_emph (EMPH *a); - static void xemph (EMPH *a, int position); - static void setBuffers_emph (EMPH *a, float* in, float* out); - static void setSamplerate_emph (EMPH *a, int rate); - static void setSize_emph (EMPH *a, int size); + EMPH( + int run, + int position, + int size, + float* in, + float* out, + int rate, + int ctype, + double f_low, + double f_high + ); + EMPH(const EMPH&) = delete; + EMPH& operator=(const EMPH& other) = delete; + ~EMPH(); + + void flush(); + void execute(int position); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); private: - static void calc_emph (EMPH *a); - static void decalc_emph (EMPH *a); + void calc(); + void decalc(); }; } // namespace WDSP diff --git a/wdsp/emphp.cpp b/wdsp/emphp.cpp new file mode 100644 index 000000000..cb1fb8abd --- /dev/null +++ b/wdsp/emphp.cpp @@ -0,0 +1,217 @@ +/* emph.c + +This file is part of a program that implements a Software-Defined Radio. + +Copyright (C) 2014, 2016, 2023 Warren Pratt, NR0V +Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +The author can be reached by email at + +warren@wpratt.com + +*/ + +#include "comm.hpp" +#include "emphp.hpp" +#include "fcurve.hpp" +#include "fircore.hpp" +#include "TXA.hpp" + +namespace WDSP { + +/******************************************************************************************************** +* * +* Partitioned Overlap-Save FM Pre-Emphasis * +* * +********************************************************************************************************/ + +EMPHP::EMPHP( + int _run, + int _position, + int _size, + int _nc, + int _mp, + float* _in, + float* _out, + int _rate, + int _ctype, + double _f_low, + double _f_high +) +{ + float* impulse; + run = _run; + position = _position; + size = _size; + nc = _nc; + mp = _mp; + in = _in; + out = _out; + rate = _rate; + ctype = _ctype; + f_low = _f_low; + f_high = _f_high; + impulse = FCurve::fc_impulse ( + nc, + f_low, + f_high, + -20.0 * log10(f_high / f_low), + 0.0, + ctype, + rate, + 1.0 / (2.0 * size), + 0, 0 + ); + p = FIRCORE::create_fircore(size, in, out, nc, mp, impulse); + delete[] (impulse); +} + +EMPHP::~EMPHP() +{ + delete (p); +} + +void EMPHP::flush() +{ + FIRCORE::flush_fircore(p); +} + +void EMPHP::execute(int _position) +{ + if (run && position == _position) + FIRCORE::xfircore(p); + else if (in != out) + std::copy( in, in + size * 2, out); +} + +void EMPHP::setBuffers(float* _in, float* _out) +{ + in = _in; + out = _out; + FIRCORE::setBuffers_fircore(p, in, out); +} + +void EMPHP::setSamplerate(int _rate) +{ + float* impulse; + rate = _rate; + impulse = FCurve::fc_impulse ( + nc, + f_low, + f_high, + -20.0 * log10(f_high / f_low), + 0.0, + ctype, + rate, + 1.0 / (2.0 * size), + 0, 0 + ); + FIRCORE::setImpulse_fircore(p, impulse, 1); + delete[] (impulse); +} + +void EMPHP::setSize(int _size) +{ + float* impulse; + size = _size; + FIRCORE::setSize_fircore(p, size); + impulse = FCurve::fc_impulse ( + nc, + f_low, + f_high, + -20.0 * log10(f_high / f_low), + 0.0, + ctype, + rate, + 1.0 / (2.0 * size), + 0, + 0 + ); + FIRCORE::setImpulse_fircore(p, impulse, 1); + delete[] (impulse); +} + +/******************************************************************************************************** +* * +* Partitioned Overlap-Save FM Pre-Emphasis: TXA Properties * +* * +********************************************************************************************************/ + +void EMPHP::setPosition(int _position) +{ + position = _position; +} + +void EMPHP::setMP(int _mp) +{ + if (mp != _mp) + { + mp = _mp; + FIRCORE::setMp_fircore(p, mp); + } +} + +void EMPHP::setNC(int _nc) +{ + float* impulse; + + if (nc != _nc) + { + nc = _nc; + impulse = FCurve::fc_impulse ( + nc, + f_low, + f_high, + -20.0 * log10(f_high / f_low), + 0.0, + ctype, + rate, + 1.0 / (2.0 * size), + 0, + 0 + ); + FIRCORE::setNc_fircore(p, nc, impulse); + delete[] (impulse); + } +} + +void EMPHP::setFreqs(double low, double high) +{ + float* impulse; + + if (f_low != low || f_high != high) + { + f_low = low; + f_high = high; + impulse = FCurve::fc_impulse ( + nc, + f_low, + f_high, + -20.0 * log10(f_high / f_low), + 0.0, + ctype, + rate, + 1.0 / (2.0 * size), + 0, + 0 + ); + FIRCORE::setImpulse_fircore(p, impulse, 1); + delete[] (impulse); + } +} + +} // namespace WDSP diff --git a/wdsp/emphp.hpp b/wdsp/emphp.hpp new file mode 100644 index 000000000..b887b0444 --- /dev/null +++ b/wdsp/emphp.hpp @@ -0,0 +1,91 @@ +/* emph.h + +This file is part of a program that implements a Software-Defined Radio. + +Copyright (C) 2014, 2016, 2023 Warren Pratt, NR0V +Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +The author can be reached by email at + +warren@wpratt.com + +*/ + +/******************************************************************************************************** +* * +* Partitioned Overlap-Save FM Pre-Emphasis * +* * +********************************************************************************************************/ + +#ifndef wdsp_emphp_h +#define wdsp_emphp_h + +#include "export.h" + +namespace WDSP { + +class FIRCORE; +class TXA; + +class WDSP_API EMPHP +{ +public: + int run; + int position; + int size; + int nc; + int mp; + float* in; + float* out; + int ctype; + double f_low; + double f_high; + double rate; + FIRCORE *p; + + EMPHP( + int run, + int position, + int size, + int nc, + int mp, + float* in, + float* out, + int rate, + int ctype, + double f_low, + double f_high + ); + EMPHP(const EMPHP&) = delete; + EMPHP& operator=(const EMPHP& other) = delete; + ~EMPHP(); + + void flush(); + void execute(int position); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); + // TXA Properties + void setPosition(int position); + void setMP(int mp); + void setNC(int nc); + void setFreqs(double low, double high); +}; + +} // namespace WDSP + +#endif