diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index c3316f7b..0dee4f9c 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -58,7 +58,7 @@ jobs: - name: Prepare CMake working-directory: ${{runner.workspace}}/build - run: cmake "$Env:GITHUB_WORKSPACE" "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON + run: cmake "$Env:GITHUB_WORKSPACE" "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF - name: Build working-directory: ${{runner.workspace}}/build @@ -106,7 +106,7 @@ jobs: - name: Prepare CMake working-directory: ${{runner.workspace}}/build - run: cmake $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release + run: cmake $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release - name: Build working-directory: ${{runner.workspace}}/build @@ -309,7 +309,7 @@ jobs: - name: Prepare CMake working-directory: ${{runner.workspace}}/build - run: cmake $GITHUB_WORKSPACE -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON + run: cmake $GITHUB_WORKSPACE -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF - name: Build working-directory: ${{runner.workspace}}/build diff --git a/core/src/dsp/bench/peak_level_meter.h b/core/src/dsp/bench/peak_level_meter.h index 64817d12..aaea6dbd 100644 --- a/core/src/dsp/bench/peak_level_meter.h +++ b/core/src/dsp/bench/peak_level_meter.h @@ -3,12 +3,22 @@ namespace dsp::bench { template - class PeakLevelMeter : Sink { + class PeakLevelMeter : public Sink { using base_type = Sink; public: PeakLevelMeter() {} - PeakLevelMeter(stream* in) { base_type::init(in); } + PeakLevelMeter(stream* in) { init(in); } + + void init(stream* in) { + if constexpr (std::is_same_v) { + level = 0.0f; + } + if constexpr (std::is_same_v || std::is_same_v) { + level = { 0.0f, 0.0f }; + } + base_type::init(in); + } T getLevel() { return level; diff --git a/core/src/dsp/channel/rx_vfo.h b/core/src/dsp/channel/rx_vfo.h index e1c6a209..556c1f9b 100644 --- a/core/src/dsp/channel/rx_vfo.h +++ b/core/src/dsp/channel/rx_vfo.h @@ -82,12 +82,12 @@ namespace dsp::channel { } inline int process(int count, const complex_t* in, complex_t* out) { - xlator.process(count, in, xlator.out.writeBuf); + xlator.process(count, in, out); if (!filterNeeded) { - return resamp.process(count, xlator.out.writeBuf, out); + return resamp.process(count, out, out); } - count = resamp.process(count, xlator.out.writeBuf, resamp.out.writeBuf); - filter.process(count, resamp.out.writeBuf, out); + count = resamp.process(count, out, out); + filter.process(count, out, out); return count; } diff --git a/core/src/dsp/demod/am.h b/core/src/dsp/demod/am.h index a7949e74..e385cf93 100644 --- a/core/src/dsp/demod/am.h +++ b/core/src/dsp/demod/am.h @@ -18,8 +18,8 @@ namespace dsp::demod { void init(stream* in, AGCMode agcMode, double agcRate) { _agcMode = agcMode; - carrierAgc.init(NULL, 1.0, agcRate); - audioAgc.init(NULL, 1.0, agcRate); + carrierAgc.init(NULL, 1.0, agcRate, 10e6, 10.0); + audioAgc.init(NULL, 1.0, agcRate, 10e6, 10.0); base_type::init(in); } @@ -63,6 +63,9 @@ namespace dsp::demod { if (_agcMode == AGCMode::AUDIO) { audioAgc.process(count, out, out); } + else { + volk_32f_s32f_add_32f(out, out, -1.0f, count); + } return count; } diff --git a/core/src/dsp/demod/broadcast_fm.h b/core/src/dsp/demod/broadcast_fm.h index 81061c17..54c2c016 100644 --- a/core/src/dsp/demod/broadcast_fm.h +++ b/core/src/dsp/demod/broadcast_fm.h @@ -1,5 +1,6 @@ #pragma once #include "fm.h" +#include "../taps/low_pass.h" #include "../taps/band_pass.h" #include "../filter/fir.h" #include "../loop/pll.h" @@ -18,7 +19,7 @@ namespace dsp::demod { public: BroadcastFM() {} - BroadcastFM(stream* in, double deviation, double samplerate, bool stereo = true) { init(in, deviation, samplerate, stereo); } + BroadcastFM(stream* in, double deviation, double samplerate, bool stereo = true, bool lowPass = true) { init(in, deviation, samplerate, stereo, lowPass); } ~BroadcastFM() { if (!base_type::_block_init) { return; } @@ -26,19 +27,26 @@ namespace dsp::demod { buffer::free(lmr); buffer::free(l); buffer::free(r); + taps::free(pilotFirTaps); + taps::free(audioFirTaps); } - virtual void init(stream* in, double deviation, double samplerate, bool stereo = true) { + virtual void init(stream* in, double deviation, double samplerate, bool stereo = true, bool lowPass = true) { _deviation = deviation; _samplerate = samplerate; _stereo = stereo; + _lowPass = lowPass; demod.init(NULL, _deviation, _samplerate); - pilotFirTaps = taps::bandPass(18750.0, 19250.0, 3000.0, _samplerate); + pilotFirTaps = taps::bandPass(18750.0, 19250.0, 3000.0, _samplerate, true); pilotFir.init(NULL, pilotFirTaps); rtoc.init(NULL); - pilotPLL.init(NULL, 0.1/*TODO: adapt to samplerate*/, 0.0, math::freqToOmega(19000.0, _samplerate), math::freqToOmega(18750.0, _samplerate), math::freqToOmega(19250.0, _samplerate)); - delay.init(NULL, pilotFirTaps.size / 2.0); + pilotPLL.init(NULL, 25000.0 / _samplerate, 0.0, math::freqToOmega(19000.0, _samplerate), math::freqToOmega(18750.0, _samplerate), math::freqToOmega(19250.0, _samplerate)); + lprDelay.init(NULL, ((pilotFirTaps.size - 1) / 2) + 1); + lmrDelay.init(NULL, ((pilotFirTaps.size - 1) / 2) + 1); + audioFirTaps = taps::lowPass(15000.0, 4000.0, _samplerate); + alFir.init(NULL, audioFirTaps); + arFir.init(NULL, audioFirTaps); lmr = buffer::alloc(STREAM_BUFFER_SIZE); l = buffer::alloc(STREAM_BUFFER_SIZE); @@ -62,11 +70,18 @@ namespace dsp::demod { demod.setDeviation(_deviation, _samplerate); taps::free(pilotFirTaps); - pilotFirTaps = taps::bandPass(18750.0, 19250.0, 3000.0, samplerate); + pilotFirTaps = taps::bandPass(18750.0, 19250.0, 3000.0, samplerate, true); pilotFir.setTaps(pilotFirTaps); + pilotPLL.setFrequencyLimits(math::freqToOmega(18750.0, _samplerate), math::freqToOmega(19250.0, _samplerate)); pilotPLL.setInitialFreq(math::freqToOmega(19000.0, _samplerate)); - delay.setDelay(pilotFirTaps.size / 2); + lprDelay.setDelay(((pilotFirTaps.size - 1) / 2) + 1); + lmrDelay.setDelay(((pilotFirTaps.size - 1) / 2) + 1); + + taps::free(audioFirTaps); + audioFirTaps = taps::lowPass(15000.0, 4000.0, _samplerate); + alFir.setTaps(audioFirTaps); + arFir.setTaps(audioFirTaps); reset(); base_type::tempStart(); @@ -81,6 +96,15 @@ namespace dsp::demod { base_type::tempStart(); } + void setLowPass(bool lowPass) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + _lowPass = lowPass; + reset(); + base_type::tempStart(); + } + void reset() { assert(base_type::_block_init); std::lock_guard lck(base_type::ctrlMtx); @@ -88,7 +112,10 @@ namespace dsp::demod { demod.reset(); pilotFir.reset(); pilotPLL.reset(); - delay.reset(); + lprDelay.reset(); + lmrDelay.reset(); + alFir.reset(); + arFir.reset(); base_type::tempStart(); } @@ -103,21 +130,40 @@ namespace dsp::demod { pilotFir.process(count, rtoc.out.writeBuf, pilotFir.out.writeBuf); pilotPLL.process(count, pilotFir.out.writeBuf, pilotPLL.out.writeBuf); - // Conjugate PLL output to down convert the L-R signal + // Delay + lprDelay.process(count, demod.out.writeBuf, demod.out.writeBuf); + lmrDelay.process(count, rtoc.out.writeBuf, rtoc.out.writeBuf); + + // Double and conjugate PLL output to down convert the L-R signal + math::Multiply::process(count, pilotPLL.out.writeBuf, pilotPLL.out.writeBuf, pilotPLL.out.writeBuf); math::Conjugate::process(count, pilotPLL.out.writeBuf, pilotPLL.out.writeBuf); math::Multiply::process(count, rtoc.out.writeBuf, pilotPLL.out.writeBuf, rtoc.out.writeBuf); // Convert output back to real for further processing convert::ComplexToReal::process(count, rtoc.out.writeBuf, lmr); + // Amplify by 2x + volk_32f_s32f_multiply_32f(lmr, lmr, 2.0f, count); + // Do L = (L+R) + (L-R), R = (L+R) - (L-R) math::Add::process(count, demod.out.writeBuf, lmr, l); math::Subtract::process(count, demod.out.writeBuf, lmr, r); + // Filter if needed + if (_lowPass) { + alFir.process(count, l, l); + arFir.process(count, r, r); + } + // Interleave into stereo convert::LRToStereo::process(count, l, r, out); } else { + // Filter if needed + if (_lowPass) { + alFir.process(count, demod.out.writeBuf, demod.out.writeBuf); + } + // Interleave raw MPX to stereo convert::LRToStereo::process(count, demod.out.writeBuf, demod.out.writeBuf, out); } @@ -140,13 +186,18 @@ namespace dsp::demod { double _deviation; double _samplerate; bool _stereo; + bool _lowPass = true; FM demod; tap pilotFirTaps; filter::FIR pilotFir; convert::RealToComplex rtoc; loop::PLL pilotPLL; - math::Delay delay; + math::Delay lprDelay; + math::Delay lmrDelay; + tap audioFirTaps; + filter::FIR arFir; + filter::FIR alFir; float* lmr; float* l; diff --git a/core/src/dsp/demod/ssb.h b/core/src/dsp/demod/ssb.h index fd7e21c7..ed4378bc 100644 --- a/core/src/dsp/demod/ssb.h +++ b/core/src/dsp/demod/ssb.h @@ -32,7 +32,7 @@ namespace dsp::demod { _bandwidth = bandwidth; _samplerate = samplerate; xlator.init(NULL, getTranslation(), _samplerate); - agc.init(NULL, 1.0, agcRate); + agc.init(NULL, 1.0, agcRate, 10e6, 10.0); base_type::init(in); } diff --git a/core/src/dsp/loop/agc.h b/core/src/dsp/loop/agc.h index 0463132a..1cd58ab5 100644 --- a/core/src/dsp/loop/agc.h +++ b/core/src/dsp/loop/agc.h @@ -8,11 +8,14 @@ namespace dsp::loop { public: AGC() {} - AGC(stream* in) { init(in); } + AGC(stream* in, double setPoint, double rate, double maxGain, double maxOutputAmp, double initGain = 1.0) { init(in, setPoint, rate, maxGain, maxOutputAmp, initGain); } - void init(stream* in, double setPoint, double rate, double initGain = 1.0) { + void init(stream* in, double setPoint, double rate, double maxGain, double maxOutputAmp, double initGain = 1.0) { _setPoint = setPoint; _rate = rate; + _invRate = 1.0f - _rate; + _maxGain = maxGain; + _maxOutputAmp = maxOutputAmp; _initGain = initGain; gain = _initGain; base_type::init(in); @@ -28,6 +31,19 @@ namespace dsp::loop { assert(base_type::_block_init); std::lock_guard lck(base_type::ctrlMtx); _rate = rate; + _invRate = 1.0f - _rate; + } + + void setMaxGain(double maxGain) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + _maxGain = maxGain; + } + + void setMaxOutputAmp(double maxOutputAmp) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + _maxOutputAmp = maxOutputAmp; } void setInitialGain(double initGain) { @@ -40,22 +56,29 @@ namespace dsp::loop { assert(base_type::_block_init); std::lock_guard lck(base_type::ctrlMtx); gain = _initGain; + amp = 1.0f; } inline int process(int count, T* in, T* out) { for (int i = 0; i < count; i++) { - // Scale output by gain - out[i] = in[i] * gain; - - // Update gain according to setpoint and rate + // Get signal amplitude + float inAmp; if constexpr (std::is_same_v) { - gain += (_setPoint - out[i].amplitude()) * _rate; + inAmp = in[i].amplitude(); } if constexpr (std::is_same_v) { - gain += (_setPoint - fabsf(out[i])) * _rate; + inAmp = fabsf(in[i]); } + + // Update average amplitude + if (inAmp != 0.0f) { + amp = (amp * _invRate) + (inAmp * _rate); + gain = std::min(_setPoint / amp, _maxGain); + } + + // Scale output by gain + out[i] = in[i] * gain; } - printf("%f\n", gain); return count; } @@ -73,9 +96,13 @@ namespace dsp::loop { protected: float _setPoint; float _rate; + float _invRate; + float _maxGain; + float _maxOutputAmp; float _initGain; float gain; + float amp = 1.0; }; } \ No newline at end of file diff --git a/core/src/dsp/loop/phase_control_loop.h b/core/src/dsp/loop/phase_control_loop.h index 7c9063d9..2ad32156 100644 --- a/core/src/dsp/loop/phase_control_loop.h +++ b/core/src/dsp/loop/phase_control_loop.h @@ -35,6 +35,11 @@ namespace dsp::loop { beta = (4 * bandwidth * bandwidth) / denominator; } + void setCoefficients(T alpha, T beta) { + _alpha = alpha: + _beta = beta; + } + void setPhaseLimits(T minPhase, T maxPhase) { assert(maxPhase > minPhase); _minPhase = minPhase; diff --git a/core/src/dsp/loop/pll.h b/core/src/dsp/loop/pll.h index afb98f44..d3b9c197 100644 --- a/core/src/dsp/loop/pll.h +++ b/core/src/dsp/loop/pll.h @@ -24,6 +24,16 @@ namespace dsp::loop { base_type::init(in); } + void setBandwidth(double bandwidth) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + float alpha, beta; + PhaseControlLoop::criticallyDamped(bandwidth, alpha, beta); + + base_type::tempStart(); + } + void setInitialPhase(double initPhase) { assert(base_type::_block_init); std::lock_guard lck(base_type::ctrlMtx); diff --git a/core/src/dsp/math/delay.h b/core/src/dsp/math/delay.h index 508e8e91..2b71ac59 100644 --- a/core/src/dsp/math/delay.h +++ b/core/src/dsp/math/delay.h @@ -19,7 +19,7 @@ namespace dsp::math { void init(stream* in, int delay) { _delay = delay; - buffer = buffer::alloc(STREAM_BUFFER_SIZE + 64000); + buffer = buffer::alloc(STREAM_BUFFER_SIZE + 64000); bufStart = &buffer[_delay]; buffer::clear(buffer, _delay); diff --git a/core/src/dsp/multirate/power_decimator.h b/core/src/dsp/multirate/power_decimator.h index 0ad27b96..f937e25f 100644 --- a/core/src/dsp/multirate/power_decimator.h +++ b/core/src/dsp/multirate/power_decimator.h @@ -60,8 +60,8 @@ namespace dsp::multirate { int last = stageCount - 1; for (int i = 0; i < stageCount; i++) { auto fir = decimFirs[i]; - count = fir->process(count, data, (i == last) ? out : fir->out.writeBuf); - data = fir->out.writeBuf; + count = fir->process(count, data, out); + data = out; } return count; } diff --git a/core/src/dsp/multirate/rational_resampler.h b/core/src/dsp/multirate/rational_resampler.h index 5902f243..328cca4c 100644 --- a/core/src/dsp/multirate/rational_resampler.h +++ b/core/src/dsp/multirate/rational_resampler.h @@ -63,8 +63,8 @@ namespace dsp::multirate { inline int process(int count, const T* in, T* out) { switch(mode) { case Mode::BOTH: - count = decim.process(count, in, decim.out.writeBuf); - return resamp.process(count, decim.out.writeBuf, out); + count = decim.process(count, in, out); + return resamp.process(count, out, out); case Mode::DECIM_ONLY: return decim.process(count, in, out); case Mode::RESAMP_ONLY: diff --git a/core/src/dsp/routing/stream_link.h b/core/src/dsp/routing/stream_link.h new file mode 100644 index 00000000..4d385ee8 --- /dev/null +++ b/core/src/dsp/routing/stream_link.h @@ -0,0 +1,44 @@ +#pragma once +#include "../sink.h" + +namespace dsp::routing { + template + class StreamLink : public Sink { + using base_type = Sink; + public: + StreamLink() {} + + StreamLink(stream* in, stream* out) { init(in, out); } + + void init(stream* in, stream* out) { + _out = out; + base_type::registerOutput(_out); + base_type::init(in); + } + + void setOutput(stream* out) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + base_type::unregisterOutput(_out); + _out = out; + base_type::registerOutput(_out); + base_type::tempStart(); + } + + int run() { + int count = _in->read(); + if (count < 0) { return -1; } + + memcpy(_out->writeBuf, _in->readBuf, count * sizeof(T)); + + _in->flush(); + if (!_out->swap(count)) { return -1; } + return count; + } + + protected: + stream* _out; + + }; +} \ No newline at end of file diff --git a/core/src/dsp/taps/band_pass.h b/core/src/dsp/taps/band_pass.h index 9b6fbab6..3d8a8eb9 100644 --- a/core/src/dsp/taps/band_pass.h +++ b/core/src/dsp/taps/band_pass.h @@ -8,15 +8,18 @@ namespace dsp::taps { template - inline tap bandPass(double bandStart, double bandStop, double transWidth, double sampleRate) { + inline tap bandPass(double bandStart, double bandStop, double transWidth, double sampleRate, bool oddTapCount = false) { assert(bandStop > bandStart); float offsetOmega = math::freqToOmega((bandStart + bandStop) / 2.0, sampleRate); - return windowedSinc(estimateTapCount(transWidth, sampleRate), (bandStop - bandStart) / 2.0, sampleRate, [=](double n, double N) { + int count = estimateTapCount(transWidth, sampleRate); + if (oddTapCount && !(count % 2)) { count++; } + return windowedSinc(count, (bandStop - bandStart) / 2.0, sampleRate, [=](double n, double N) { if constexpr (std::is_same_v) { return cosf(offsetOmega * (float)n) * window::nuttall(n, N); } if constexpr (std::is_same_v) { - return math::phasor(offsetOmega * (float)n) * window::nuttall(n, N); + // The offset is negative to flip the taps. Complex bandpass are asymetric + return math::phasor(-offsetOmega * (float)n) * window::nuttall(n, N); } }); } diff --git a/core/src/dsp/taps/high_pass.h b/core/src/dsp/taps/high_pass.h index 6f925584..88fd7ae8 100644 --- a/core/src/dsp/taps/high_pass.h +++ b/core/src/dsp/taps/high_pass.h @@ -4,8 +4,10 @@ #include "../window/nuttall.h" namespace dsp::taps { - inline tap highPass(double cutoff, double transWidth, double sampleRate) { - return windowedSinc(estimateTapCount(transWidth, sampleRate), (sampleRate / 2.0) - cutoff, sampleRate, [=](double n, double N){ + inline tap highPass(double cutoff, double transWidth, double sampleRate, bool oddTapCount = false) { + int count = estimateTapCount(transWidth, sampleRate); + if (oddTapCount && !(count % 2)) { count++; } + return windowedSinc(count, (sampleRate / 2.0) - cutoff, sampleRate, [=](double n, double N){ return window::nuttall(n, N) * (((int)round(n) % 2) ? -1.0f : 1.0f); }); } diff --git a/core/src/dsp/taps/low_pass.h b/core/src/dsp/taps/low_pass.h index 67f6641f..1356a9c6 100644 --- a/core/src/dsp/taps/low_pass.h +++ b/core/src/dsp/taps/low_pass.h @@ -4,7 +4,9 @@ #include "../window/nuttall.h" namespace dsp::taps { - inline tap lowPass(double cutoff, double transWidth, double sampleRate) { - return windowedSinc(estimateTapCount(transWidth, sampleRate), cutoff, sampleRate, window::nuttall); + inline tap lowPass(double cutoff, double transWidth, double sampleRate, bool oddTapCount = false) { + int count = estimateTapCount(transWidth, sampleRate); + if (oddTapCount && !(count % 2)) { count++; } + return windowedSinc(count, cutoff, sampleRate, window::nuttall); } } \ No newline at end of file diff --git a/core/src/version.h b/core/src/version.h index f1d72943..60ee5ef6 100644 --- a/core/src/version.h +++ b/core/src/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_STR "1.0.6" \ No newline at end of file +#define VERSION_STR "1.1.0" \ No newline at end of file diff --git a/decoder_modules/radio/src/demodulators/am.h b/decoder_modules/radio/src/demodulators/am.h index a80cd041..808dc7e1 100644 --- a/decoder_modules/radio/src/demodulators/am.h +++ b/decoder_modules/radio/src/demodulators/am.h @@ -20,7 +20,7 @@ namespace demod { this->name = name; // Define structure - demod.init(input, dsp::demod::AM::AGCMode::CARRIER, 200000.0 / getIFSampleRate()); + demod.init(input, dsp::demod::AM::AGCMode::CARRIER, 24.0 / getIFSampleRate()); m2s.init(&demod.out); } diff --git a/decoder_modules/radio/src/demodulators/cw.h b/decoder_modules/radio/src/demodulators/cw.h index 11c953c6..095167ea 100644 --- a/decoder_modules/radio/src/demodulators/cw.h +++ b/decoder_modules/radio/src/demodulators/cw.h @@ -34,7 +34,7 @@ namespace demod { // Define structure xlator.init(input, tone, getIFSampleRate()); c2r.init(&xlator.out); - agc.init(&c2r.out, 1.0, 200000.0 / getIFSampleRate()); + agc.init(&c2r.out, 1.0, 24.0 / getIFSampleRate(), 10e6, 10.0); m2s.init(&agc.out); } diff --git a/decoder_modules/radio/src/demodulators/dsb.h b/decoder_modules/radio/src/demodulators/dsb.h index dac1d109..7488c7e5 100644 --- a/decoder_modules/radio/src/demodulators/dsb.h +++ b/decoder_modules/radio/src/demodulators/dsb.h @@ -20,7 +20,7 @@ namespace demod { this->name = name; // Define structure - demod.init(input, dsp::demod::SSB::Mode::DSB, bandwidth, getIFSampleRate(), 200000.0 / getIFSampleRate()); + demod.init(input, dsp::demod::SSB::Mode::DSB, bandwidth, getIFSampleRate(), 24.0 / getIFSampleRate()); m2s.init(&demod.out); } diff --git a/decoder_modules/radio/src/demodulators/lsb.h b/decoder_modules/radio/src/demodulators/lsb.h index 53a39b13..bab3450c 100644 --- a/decoder_modules/radio/src/demodulators/lsb.h +++ b/decoder_modules/radio/src/demodulators/lsb.h @@ -20,7 +20,7 @@ namespace demod { this->name = name; // Define structure - demod.init(input, dsp::demod::SSB::Mode::LSB, bandwidth, getIFSampleRate(), 200000.0 / getIFSampleRate()); + demod.init(input, dsp::demod::SSB::Mode::LSB, bandwidth, getIFSampleRate(), 24.0 / getIFSampleRate()); m2s.init(&demod.out); } diff --git a/decoder_modules/radio/src/demodulators/usb.h b/decoder_modules/radio/src/demodulators/usb.h index eeb35cea..b25456b4 100644 --- a/decoder_modules/radio/src/demodulators/usb.h +++ b/decoder_modules/radio/src/demodulators/usb.h @@ -20,7 +20,7 @@ namespace demod { this->name = name; // Define structure - demod.init(input, dsp::demod::SSB::Mode::USB, bandwidth, getIFSampleRate(), 200000.0 / getIFSampleRate()); + demod.init(input, dsp::demod::SSB::Mode::USB, bandwidth, getIFSampleRate(), 24.0 / getIFSampleRate()); m2s.init(&demod.out); } diff --git a/decoder_modules/radio/src/demodulators/wfm.h b/decoder_modules/radio/src/demodulators/wfm.h index 2291bcb2..59d4dbc7 100644 --- a/decoder_modules/radio/src/demodulators/wfm.h +++ b/decoder_modules/radio/src/demodulators/wfm.h @@ -47,6 +47,9 @@ namespace demod { _config->conf[name][getName()]["stereo"] = _stereo; _config->release(true); } + if (ImGui::Checkbox(("Low Pass##_radio_wfm_lowpass_" + name).c_str(), &_lowPass)) { + demod.setLowPass(_lowPass); + } } void setBandwidth(double bandwidth) { @@ -93,6 +96,7 @@ namespace demod { ConfigManager* _config = NULL; bool _stereo = false; + bool _lowPass = true; std::string name; EventHandler*> outputChangeHandler; diff --git a/docker_builds/debian_bullseye/do_build.sh b/docker_builds/debian_bullseye/do_build.sh index 05a0a32e..224321e4 100644 --- a/docker_builds/debian_bullseye/do_build.sh +++ b/docker_builds/debian_bullseye/do_build.sh @@ -18,7 +18,7 @@ cp inc/* /usr/include/ cd SDRPlusPlus mkdir build cd build -cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON +cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF make VERBOSE=1 -j2 cd .. diff --git a/docker_builds/debian_buster/do_build.sh b/docker_builds/debian_buster/do_build.sh index cbefd63f..2367bf96 100644 --- a/docker_builds/debian_buster/do_build.sh +++ b/docker_builds/debian_buster/do_build.sh @@ -18,7 +18,7 @@ cp inc/* /usr/include/ cd SDRPlusPlus mkdir build cd build -cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON +cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF make VERBOSE=1 -j2 cd .. diff --git a/docker_builds/debian_sid/do_build.sh b/docker_builds/debian_sid/do_build.sh index 05a0a32e..224321e4 100644 --- a/docker_builds/debian_sid/do_build.sh +++ b/docker_builds/debian_sid/do_build.sh @@ -18,7 +18,7 @@ cp inc/* /usr/include/ cd SDRPlusPlus mkdir build cd build -cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON +cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF make VERBOSE=1 -j2 cd .. diff --git a/docker_builds/ubuntu_bionic/do_build.sh b/docker_builds/ubuntu_bionic/do_build.sh index 92d0a75f..3ac017dc 100644 --- a/docker_builds/ubuntu_bionic/do_build.sh +++ b/docker_builds/ubuntu_bionic/do_build.sh @@ -47,7 +47,7 @@ echo 'Cflags: -I/usr/include/codec2' >> /usr/share/pkgconfig/codec2.pc cd SDRPlusPlus mkdir build cd build -cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_OVERRIDE_STD_FILESYSTEM=ON -DOPT_BUILD_M17_DECODER=ON +cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_OVERRIDE_STD_FILESYSTEM=ON -DOPT_BUILD_M17_DECODER=OFF make VERBOSE=1 -j2 # Generate package diff --git a/docker_builds/ubuntu_focal/do_build.sh b/docker_builds/ubuntu_focal/do_build.sh index 05a0a32e..224321e4 100644 --- a/docker_builds/ubuntu_focal/do_build.sh +++ b/docker_builds/ubuntu_focal/do_build.sh @@ -18,7 +18,7 @@ cp inc/* /usr/include/ cd SDRPlusPlus mkdir build cd build -cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON +cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF make VERBOSE=1 -j2 cd .. diff --git a/docker_builds/ubuntu_hirsute/do_build.sh b/docker_builds/ubuntu_hirsute/do_build.sh index 05a0a32e..224321e4 100644 --- a/docker_builds/ubuntu_hirsute/do_build.sh +++ b/docker_builds/ubuntu_hirsute/do_build.sh @@ -18,7 +18,7 @@ cp inc/* /usr/include/ cd SDRPlusPlus mkdir build cd build -cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON +cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF make VERBOSE=1 -j2 cd .. diff --git a/docker_builds/ubuntu_impish/do_build.sh b/docker_builds/ubuntu_impish/do_build.sh index 05a0a32e..224321e4 100644 --- a/docker_builds/ubuntu_impish/do_build.sh +++ b/docker_builds/ubuntu_impish/do_build.sh @@ -18,7 +18,7 @@ cp inc/* /usr/include/ cd SDRPlusPlus mkdir build cd build -cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON +cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF make VERBOSE=1 -j2 cd .. diff --git a/docker_builds/ubuntu_jammy/do_build.sh b/docker_builds/ubuntu_jammy/do_build.sh index 05a0a32e..224321e4 100644 --- a/docker_builds/ubuntu_jammy/do_build.sh +++ b/docker_builds/ubuntu_jammy/do_build.sh @@ -18,7 +18,7 @@ cp inc/* /usr/include/ cd SDRPlusPlus mkdir build cd build -cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON +cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF make VERBOSE=1 -j2 cd .. diff --git a/misc_modules/frequency_manager/src/main.cpp b/misc_modules/frequency_manager/src/main.cpp index 9c244613..849d3b68 100644 --- a/misc_modules/frequency_manager/src/main.cpp +++ b/misc_modules/frequency_manager/src/main.cpp @@ -12,6 +12,7 @@ #include #include #include +#include SDRPP_MOD_INFO{ /* Name: */ "frequency_manager", diff --git a/misc_modules/recorder/src/main.cpp b/misc_modules/recorder/src/main.cpp index 320172de..6d621d43 100644 --- a/misc_modules/recorder/src/main.cpp +++ b/misc_modules/recorder/src/main.cpp @@ -3,7 +3,10 @@ #include #include #include -#include +#include +#include +#include +#include #include #include #include @@ -72,7 +75,7 @@ public: config.release(created); // Init audio path - vol.init(&dummyStream, audioVolume); + vol.init(&dummyStream, audioVolume, false); audioSplit.init(&vol.out); audioSplit.bindStream(&meterStream); meter.init(&meterStream); @@ -269,13 +272,14 @@ private: if (recording) { style::endDisabled(); } double frameTime = 1.0 / ImGui::GetIO().Framerate; - lvlL = std::max(lvlL - (frameTime * 50.0), -90); - lvlR = std::max(lvlR - (frameTime * 50.0), -90); + lvlL = std::clamp(lvlL - (frameTime * 50.0), -90.0f, 10.0f); + lvlR = std::clamp(lvlR - (frameTime * 50.0), -90.0f, 10.0f); - float _lvlL = meter.getLeftLevel(); - float _lvlR = meter.getRightLevel(); - if (_lvlL > lvlL) { lvlL = _lvlL; } - if (_lvlR > lvlR) { lvlR = _lvlR; } + dsp::stereo_t rawLvl = meter.getLevel(); + meter.resetLevel(); + dsp::stereo_t dbLvl = { 10.0f * log10f(rawLvl.l), 10.0f * log10f(rawLvl.r) }; + if (dbLvl.l > lvlL) { lvlL = dbLvl.l; } + if (dbLvl.r > lvlR) { lvlR = dbLvl.r; } ImGui::VolumeMeter(lvlL, lvlL, -60, 10); ImGui::VolumeMeter(lvlR, lvlR, -60, 10); @@ -485,12 +489,12 @@ private: // Audio path dsp::stream* audioInput = NULL; - dsp::Volume vol; - dsp::Splitter audioSplit; + dsp::audio::Volume vol; + dsp::routing::Splitter audioSplit; dsp::stream meterStream; - dsp::LevelMeter meter; + dsp::bench::PeakLevelMeter meter; dsp::stream audioHandlerStream; - dsp::HandlerSink audioHandler; + dsp::sink::Handler audioHandler; WavWriter* audioWriter; std::vector streamNames; @@ -501,7 +505,7 @@ private: // Baseband path dsp::stream basebandStream; - dsp::HandlerSink basebandHandler; + dsp::sink::Handler basebandHandler; WavWriter* basebandWriter; uint64_t samplesWritten; diff --git a/sink_modules/network_sink/src/main.cpp b/sink_modules/network_sink/src/main.cpp index e2b2c583..09b747f8 100644 --- a/sink_modules/network_sink/src/main.cpp +++ b/sink_modules/network_sink/src/main.cpp @@ -4,8 +4,9 @@ #include #include #include -#include -#include +#include +#include +#include #include #include #include @@ -271,10 +272,10 @@ private: } SinkManager::Stream* _stream; - dsp::Packer packer; - dsp::StereoToMono s2m; - dsp::HandlerSink monoSink; - dsp::HandlerSink stereoSink; + dsp::buffer::Packer packer; + dsp::convert::StereoToMono s2m; + dsp::sink::Handler monoSink; + dsp::sink::Handler stereoSink; std::string _streamName; diff --git a/sink_modules/new_portaudio_sink/src/main.cpp b/sink_modules/new_portaudio_sink/src/main.cpp index 85bc299e..d2af130a 100644 --- a/sink_modules/new_portaudio_sink/src/main.cpp +++ b/sink_modules/new_portaudio_sink/src/main.cpp @@ -4,8 +4,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -374,8 +374,8 @@ private: std::string selectedDevName; SinkManager::Stream* _stream; - dsp::Packer packer; - dsp::StereoToMono s2m; + dsp::buffer::Packer packer; + dsp::convert::StereoToMono s2m; PaStream* devStream; diff --git a/source_modules/sdrpp_server_source/src/main.cpp b/source_modules/sdrpp_server_source/src/main.cpp index 3493f1c6..0eeb7e3e 100644 --- a/source_modules/sdrpp_server_source/src/main.cpp +++ b/source_modules/sdrpp_server_source/src/main.cpp @@ -32,10 +32,10 @@ public: if (core::args["server"].b()) { return; } // Initialize lists - sampleTypeList.define("Int8", dsp::PCM_TYPE_I8); - sampleTypeList.define("Int16", dsp::PCM_TYPE_I16); - sampleTypeList.define("Float32", dsp::PCM_TYPE_F32); - sampleTypeId = sampleTypeList.valueId(dsp::PCM_TYPE_I16); + sampleTypeList.define("Int8", dsp::compression::PCM_TYPE_I8); + sampleTypeList.define("Int16", dsp::compression::PCM_TYPE_I16); + sampleTypeList.define("Float32", dsp::compression::PCM_TYPE_F32); + sampleTypeId = sampleTypeList.valueId(dsp::compression::PCM_TYPE_I16); handler.ctx = this; handler.selectHandler = menuSelected; @@ -238,7 +238,7 @@ private: devConfName = buf; // Load settings - sampleTypeId = sampleTypeList.valueId(dsp::PCM_TYPE_I16); + sampleTypeId = sampleTypeList.valueId(dsp::compression::PCM_TYPE_I16); if (config.conf["servers"][devConfName].contains("sampleType")) { std::string key = config.conf["servers"][devConfName]["sampleType"]; if (sampleTypeList.keyExists(key)) { sampleTypeId = sampleTypeList.keyId(key); } @@ -269,7 +269,7 @@ private: dsp::stream stream; SourceManager::SourceHandler handler; - OptionList sampleTypeList; + OptionList sampleTypeList; int sampleTypeId; bool compression = false; diff --git a/source_modules/sdrpp_server_source/src/sdrpp_server_client.cpp b/source_modules/sdrpp_server_source/src/sdrpp_server_client.cpp index cc29de98..6bd05211 100644 --- a/source_modules/sdrpp_server_source/src/sdrpp_server_client.cpp +++ b/source_modules/sdrpp_server_source/src/sdrpp_server_client.cpp @@ -109,7 +109,7 @@ namespace server { return currentSampleRate; } - void ClientClass::setSampleType(dsp::PCMType type) { + void ClientClass::setSampleType(dsp::compression::PCMType type) { s_cmd_data[0] = type; sendCommand(COMMAND_SET_SAMPLE_TYPE, 1); } diff --git a/source_modules/sdrpp_server_source/src/sdrpp_server_client.h b/source_modules/sdrpp_server_source/src/sdrpp_server_client.h index afdba726..d3b75fb2 100644 --- a/source_modules/sdrpp_server_source/src/sdrpp_server_client.h +++ b/source_modules/sdrpp_server_source/src/sdrpp_server_client.h @@ -8,9 +8,9 @@ #include #include #include -#include +#include #include -#include +#include #include #define RFSPACE_MAX_SIZE 8192 @@ -85,7 +85,7 @@ namespace server { void setFrequency(double freq); double getSampleRate(); - void setSampleType(dsp::PCMType type); + void setSampleType(dsp::compression::PCMType type); void setCompression(bool enabled); void start(); @@ -115,8 +115,8 @@ namespace server { net::Conn client; dsp::stream decompIn; - dsp::DynamicRangeDecompressor decomp; - dsp::Link link; + dsp::compression::SampleStreamDecompressor decomp; + dsp::routing::StreamLink link; dsp::stream* output; uint8_t* rbuffer = NULL;