diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index fb02811e..2d553f2b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -11,6 +11,7 @@ FIRST: Before reporting any bug, make sure that the bug you are reporting has no **Hardware** - CPU: +- RAM: - GPU: - SDR: (Remote or local? If remote, what protocol?) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 1203bca1..499bd41a 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -95,18 +95,18 @@ jobs: - name: Install SDRplay API run: wget https://www.sdrplay.com/software/SDRplay_RSP_API-MacOSX-3.07.3.pkg && sudo installer -pkg SDRplay_RSP_API-MacOSX-3.07.3.pkg -target / - # - name: Install libiio - # run: git clone https://github.com/analogdevicesinc/libiio && cd libiio && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ + - name: Install libiio + run: git clone https://github.com/analogdevicesinc/libiio && cd libiio && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ - # - name: Install libad9361 - # run: git clone https://github.com/analogdevicesinc/libad9361-iio && cd libad9361-iio && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ + - name: Install libad9361 + run: git clone https://github.com/analogdevicesinc/libad9361-iio && cd libad9361-iio && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ - name: Install LimeSuite run: git clone https://github.com/myriadrf/LimeSuite && cd LimeSuite && mkdir builddir && cd builddir && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ - name: Prepare CMake working-directory: ${{runner.workspace}}/build - run: cmake $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=OFF -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=ON -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release - name: Build working-directory: ${{runner.workspace}}/build diff --git a/core/src/dsp/channel/frequency_xlator.h b/core/src/dsp/channel/frequency_xlator.h index 70c33a58..d3713317 100644 --- a/core/src/dsp/channel/frequency_xlator.h +++ b/core/src/dsp/channel/frequency_xlator.h @@ -1,6 +1,6 @@ #pragma once #include "../processor.h" -#include "../math/freq_to_omega.h" +#include "../math/hz_to_rads.h" namespace dsp::channel { class FrequencyXlator : public Processor { @@ -19,7 +19,7 @@ namespace dsp::channel { } void init(stream* in, double offset, double samplerate) { - init(in, math::freqToOmega(offset, samplerate)); + init(in, math::hzToRads(offset, samplerate)); } void setOffset(double offset) { @@ -29,7 +29,7 @@ namespace dsp::channel { } void setOffset(double offset, double samplerate) { - setOffset(math::freqToOmega(offset, samplerate)); + setOffset(math::hzToRads(offset, samplerate)); } void reset() { diff --git a/core/src/dsp/clock_recovery/fd.h b/core/src/dsp/clock_recovery/fd.h index 01759c91..ec468459 100644 --- a/core/src/dsp/clock_recovery/fd.h +++ b/core/src/dsp/clock_recovery/fd.h @@ -168,7 +168,7 @@ namespace dsp::clock_recovery { protected: void generateInterpTaps() { double bw = 0.5 / (double)_interpPhaseCount; - dsp::tap lp = dsp::taps::windowedSinc(_interpPhaseCount * _interpTapCount, dsp::math::freqToOmega(bw, 1.0), dsp::window::nuttall, _interpPhaseCount); + dsp::tap lp = dsp::taps::windowedSinc(_interpPhaseCount * _interpTapCount, dsp::math::hzToRads(bw, 1.0), dsp::window::nuttall, _interpPhaseCount); interpBank = dsp::multirate::buildPolyphaseBank(_interpPhaseCount, lp); taps::free(lp); } diff --git a/core/src/dsp/clock_recovery/mm.h b/core/src/dsp/clock_recovery/mm.h index 60f78e30..497b4427 100644 --- a/core/src/dsp/clock_recovery/mm.h +++ b/core/src/dsp/clock_recovery/mm.h @@ -172,7 +172,7 @@ namespace dsp::clock_recovery { protected: void generateInterpTaps() { double bw = 0.5 / (double)_interpPhaseCount; - dsp::tap lp = dsp::taps::windowedSinc(_interpPhaseCount * _interpTapCount, dsp::math::freqToOmega(bw, 1.0), dsp::window::nuttall, _interpPhaseCount); + dsp::tap lp = dsp::taps::windowedSinc(_interpPhaseCount * _interpTapCount, dsp::math::hzToRads(bw, 1.0), dsp::window::nuttall, _interpPhaseCount); interpBank = dsp::multirate::buildPolyphaseBank(_interpPhaseCount, lp); taps::free(lp); } diff --git a/core/src/dsp/demod/broadcast_fm.h b/core/src/dsp/demod/broadcast_fm.h index df6ae2b7..7e995e9d 100644 --- a/core/src/dsp/demod/broadcast_fm.h +++ b/core/src/dsp/demod/broadcast_fm.h @@ -43,7 +43,7 @@ namespace dsp::demod { pilotFirTaps = taps::bandPass(18750.0, 19250.0, 3000.0, _samplerate, true); pilotFir.init(NULL, pilotFirTaps); rtoc.init(NULL); - pilotPLL.init(NULL, 25000.0 / _samplerate, 0.0, math::freqToOmega(19000.0, _samplerate), math::freqToOmega(18750.0, _samplerate), math::freqToOmega(19250.0, _samplerate)); + pilotPLL.init(NULL, 25000.0 / _samplerate, 0.0, math::hzToRads(19000.0, _samplerate), math::hzToRads(18750.0, _samplerate), math::hzToRads(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); @@ -82,8 +82,8 @@ namespace dsp::demod { 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)); + pilotPLL.setFrequencyLimits(math::hzToRads(18750.0, _samplerate), math::hzToRads(19250.0, _samplerate)); + pilotPLL.setInitialFreq(math::hzToRads(19000.0, _samplerate)); lprDelay.setDelay(((pilotFirTaps.size - 1) / 2) + 1); lmrDelay.setDelay(((pilotFirTaps.size - 1) / 2) + 1); diff --git a/core/src/dsp/demod/quadrature.h b/core/src/dsp/demod/quadrature.h index 9c5cd31e..a59e8d40 100644 --- a/core/src/dsp/demod/quadrature.h +++ b/core/src/dsp/demod/quadrature.h @@ -1,8 +1,8 @@ #pragma once #include "../processor.h" #include "../math/fast_atan2.h" -#include "../math/freq_to_omega.h" -#include "../math/norm_phase_diff.h" +#include "../math/hz_to_rads.h" +#include "../math/normalize_phase.h" namespace dsp::demod { class Quadrature : public Processor { @@ -21,7 +21,7 @@ namespace dsp::demod { } virtual void init(stream* in, double deviation, double samplerate) { - init(in, math::freqToOmega(deviation, samplerate)); + init(in, math::hzToRads(deviation, samplerate)); } void setDeviation(double deviation) { @@ -33,13 +33,13 @@ namespace dsp::demod { void setDeviation(double deviation, double samplerate) { assert(base_type::_block_init); std::lock_guard lck(base_type::ctrlMtx); - _invDeviation = 1.0 / math::freqToOmega(deviation, samplerate); + _invDeviation = 1.0 / math::hzToRads(deviation, samplerate); } inline int process(int count, complex_t* in, float* out) { for (int i = 0; i < count; i++) { float cphase = in[i].phase(); - out[i] = math::normPhaseDiff(cphase - phase) * _invDeviation; + out[i] = math::normalizePhase(cphase - phase) * _invDeviation; phase = cphase; } return count; diff --git a/core/src/dsp/loop/carrier_tracking_pll.h b/core/src/dsp/loop/carrier_tracking_pll.h index 1790f007..3eb89d56 100644 --- a/core/src/dsp/loop/carrier_tracking_pll.h +++ b/core/src/dsp/loop/carrier_tracking_pll.h @@ -5,10 +5,16 @@ namespace dsp::loop { class CarrierTrackingPLL : public PLL { using base_type = PLL; public: + CarrierTrackingPLL() {} + + CarrierTrackingPLL(stream* in, double bandwidth, double initPhase = 0.0, double initFreq = 0.0, double minFreq = -FL_M_PI, double maxFreq = FL_M_PI) { + base_type::init(in, bandwidth, initFreq, initPhase, minFreq, maxFreq); + } + inline int process(int count, complex_t* in, complex_t* out) { for (int i = 0; i < count; i++) { out[i] = in[i] * math::phasor(-pcl.phase); - pcl.advance(math::normPhaseDiff(in[i].phase() - pcl.phase)); + pcl.advance(math::normalizePhase(in[i].phase() - pcl.phase)); } return count; } diff --git a/core/src/dsp/loop/costas.h b/core/src/dsp/loop/costas.h index 62874619..f9ff7fd1 100644 --- a/core/src/dsp/loop/costas.h +++ b/core/src/dsp/loop/costas.h @@ -8,6 +8,12 @@ namespace dsp::loop { static_assert(ORDER == 2 || ORDER == 4 || ORDER == 8, "Invalid costas order"); using base_type = PLL; public: + Costas() {} + + Costas(stream* in, double bandwidth, double initPhase = 0.0, double initFreq = 0.0, double minFreq = -FL_M_PI, double maxFreq = FL_M_PI) { + base_type::init(in, bandwidth, initFreq, initPhase, minFreq, maxFreq); + } + inline int process(int count, complex_t* in, complex_t* out) { for (int i = 0; i < count; i++) { out[i] = in[i] * math::phasor(-pcl.phase); diff --git a/core/src/dsp/loop/pll.h b/core/src/dsp/loop/pll.h index bba16d69..f6a4211a 100644 --- a/core/src/dsp/loop/pll.h +++ b/core/src/dsp/loop/pll.h @@ -1,6 +1,6 @@ #pragma once #include "../processor.h" -#include "../math/norm_phase_diff.h" +#include "../math/normalize_phase.h" #include "../math/phasor.h" #include "phase_control_loop.h" @@ -64,7 +64,7 @@ namespace dsp::loop { virtual inline int process(int count, complex_t* in, complex_t* out) { for (int i = 0; i < count; i++) { out[i] = math::phasor(pcl.phase); - pcl.advance(math::normPhaseDiff(in[i].phase() - pcl.phase)); + pcl.advance(math::normalizePhase(in[i].phase() - pcl.phase)); } return count; } diff --git a/core/src/dsp/math/freq_to_omega.h b/core/src/dsp/math/hz_to_rads.h similarity index 67% rename from core/src/dsp/math/freq_to_omega.h rename to core/src/dsp/math/hz_to_rads.h index 4e1a35d0..542e0de9 100644 --- a/core/src/dsp/math/freq_to_omega.h +++ b/core/src/dsp/math/hz_to_rads.h @@ -3,7 +3,7 @@ #include "constants.h" namespace dsp::math { - inline double freqToOmega(double freq, double samplerate) { + inline double hzToRads(double freq, double samplerate) { return 2.0 * DB_M_PI * (freq / samplerate); } } \ No newline at end of file diff --git a/core/src/dsp/math/norm_phase_diff.h b/core/src/dsp/math/normalize_phase.h similarity index 87% rename from core/src/dsp/math/norm_phase_diff.h rename to core/src/dsp/math/normalize_phase.h index b07baca2..8bff7eb4 100644 --- a/core/src/dsp/math/norm_phase_diff.h +++ b/core/src/dsp/math/normalize_phase.h @@ -3,7 +3,7 @@ namespace dsp::math { template - T normPhaseDiff(T diff) { + T normalizePhase(T diff) { if (diff > FL_M_PI) { diff -= 2.0f * FL_M_PI; } else if (diff <= -FL_M_PI) { diff += 2.0f * FL_M_PI; } return diff; diff --git a/core/src/dsp/mod/gfsk.h b/core/src/dsp/mod/gfsk.h new file mode 100644 index 00000000..9477f710 --- /dev/null +++ b/core/src/dsp/mod/gfsk.h @@ -0,0 +1,86 @@ +#pragma once +#include "../multirate/rrc_interpolator.h" +#include "quadrature.h" + +namespace dsp::mod { + class GFSK : public Processor { + using base_type = Processor; + public: + GFSK() {} + + GFSK(stream* in, double symbolrate, double samplerate, double rrcBeta, int rrcTapCount, double deviation) { + init(in, symbolrate, samplerate, rrcBeta, rrcTapCount, deviation); + } + + void init(stream* in, double symbolrate, double samplerate, double rrcBeta, int rrcTapCount, double deviation) { + _samplerate = samplerate; + _deviation = deviation; + + interp.init(NULL, symbolrate, _samplerate, rrcBeta, rrcTapCount); + mod.init(NULL, _deviation, _samplerate); + + base_type::init(in); + } + + void setRates(double symbolrate, double samplerate) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + _samplerate = samplerate; + interp.setRates(symbolrate, _samplerate); + mod.setDeviation(_deviation, _samplerate); + base_type::tempStart(); + } + + void setRRCParams(double rrcBeta, int rrcTapCount) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + interp.setRRCParam(rrcBeta, rrcTapCount); + base_type::tempStart(); + } + + void setDeviation(double deviation) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + _deviation = deviation; + mod.setDeviation(_deviation, _samplerate); + } + + void reset() { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + interp.reset(); + mod.reset(); + base_type::tempStart(); + } + + inline int process(int count, const float* in, complex_t* out) { + count = interp.process(count, in, interp.out.writeBuf); + mod.process(count, interp.out.writeBuf, out); + return count; + } + + int run() { + int count = base_type::_in->read(); + if (count < 0) { return -1; } + + int outCount = process(count, base_type::_in->readBuf, base_type::out.writeBuf); + + // Swap if some data was generated + base_type::_in->flush(); + if (outCount) { + if (!base_type::out.swap(outCount)) { return -1; } + } + return outCount; + } + + private: + double _samplerate; + double _deviation; + + multirate::RRCInterpolator interp; + Quadrature mod; + }; +} \ No newline at end of file diff --git a/core/src/dsp/mod/psk.h b/core/src/dsp/mod/psk.h new file mode 100644 index 00000000..10c44c17 --- /dev/null +++ b/core/src/dsp/mod/psk.h @@ -0,0 +1,6 @@ +#pragma once +#include "../multirate/rrc_interpolator.h" + +namespace dsp::mod { + typedef multirate::RRCInterpolator PSK; +} \ No newline at end of file diff --git a/core/src/dsp/mod/quadrature.h b/core/src/dsp/mod/quadrature.h new file mode 100644 index 00000000..402e1846 --- /dev/null +++ b/core/src/dsp/mod/quadrature.h @@ -0,0 +1,67 @@ +#pragma once +#include "../processor.h" +#include "../math/phasor.h" +#include "../math/normalize_phase.h" +#include "../math/hz_to_rads.h" + +namespace dsp::mod { + class Quadrature : Processor { + using base_type = Processor; + public: + Quadrature() {} + + Quadrature(stream* in, double deviation) { init(in, deviation); } + + Quadrature(stream* in, double deviation, double samplerate) { init(in, deviation, samplerate); } + + void init(stream* in, double deviation) { + _deviation = deviation; + base_type::init(in); + } + + void init(stream* in, double deviation, double samplerate) { + init(in, math::hzToRads(deviation, samplerate)); + } + + void setDeviation(double deviation) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + _deviation = deviation; + } + + void setDeviation(double deviation, double samplerate) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + _deviation = math::hzToRads(deviation, samplerate); + } + + void reset() { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + phase = 0.0f; + } + + inline int process(int count, const float* in, complex_t* out) { + for (int i = 0; i < count; i++) { + phase = math::normalizePhase(phase + (_deviation * in[i])); + out[i] = math::phasor(phase); + } + return count; + } + + virtual int run() { + int count = base_type::_in->read(); + if (count < 0) { return -1; } + + process(count, base_type::_in->readBuf, base_type::out.writeBuf); + + base_type::_in->flush(); + if (!base_type::out.swap(count)) { return -1; } + return count; + } + + private: + float _deviation; + float phase = 0.0f; + }; +} \ No newline at end of file diff --git a/core/src/dsp/multirate/rational_resampler.h b/core/src/dsp/multirate/rational_resampler.h index 0b1286ed..05386bce 100644 --- a/core/src/dsp/multirate/rational_resampler.h +++ b/core/src/dsp/multirate/rational_resampler.h @@ -69,6 +69,16 @@ namespace dsp::multirate { base_type::tempStart(); } + void setRates(double inSamplerate, double outSamplerate) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + _inSamplerate = inSamplerate; + _outSamplerate = outSamplerate; + reconfigure(); + base_type::tempStart(); + } + inline int process(int count, const T* in, T* out) { switch(mode) { case Mode::BOTH: diff --git a/core/src/dsp/multirate/rrc_interpolator.h b/core/src/dsp/multirate/rrc_interpolator.h new file mode 100644 index 00000000..17c63d7b --- /dev/null +++ b/core/src/dsp/multirate/rrc_interpolator.h @@ -0,0 +1,103 @@ +#pragma once +#include "../multirate/polyphase_resampler.h" +#include "../taps/root_raised_cosine.h" +#include + +namespace dsp::multirate { + template + class RRCInterpolator : public Processor { + using base_type = Processor; + public: + RRCInterpolator() {} + + RRCInterpolator(stream* in, double symbolrate, double samplerate, double rrcBeta, int rrcTapCount) { init(in, symbolrate, samplerate, rrcBeta, rrcTapCount); } + + void init(stream* in, double symbolrate, double samplerate, double rrcBeta, int rrcTapCount) { + _symbolrate = symbolrate; + _samplerate = samplerate; + _rrcTapCount = rrcTapCount; + + rrcTaps = taps::rootRaisedCosine(_rrcTapCount, rrcBeta, _symbolrate, _samplerate); + resamp.init(NULL, 1, 1, rrcTaps); + resamp.out.free(); + genTaps(); + + base_type::init(in); + } + + void setRates(double symbolrate, double samplerate) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + _symbolrate = symbolrate; + _samplerate = samplerate; + genTaps(); + base_type::tempStart(); + } + + void setRRCParam(double rrcBeta, int rrcTapCount) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + _rrcBeta = rrcBeta; + _rrcTapCount = rrcTapCount; + genTaps(); + base_type::tempStart(); + } + + void reset() { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + resamp.reset(); + base_type::tempStart(); + } + + inline int process(int count, const T* in, T* out) { + return resamp.process(count, in, out); + } + + int run() { + int count = base_type::_in->read(); + if (count < 0) { return -1; } + + int outCount = process(count, base_type::_in->readBuf, base_type::out.writeBuf); + + // Swap if some data was generated + base_type::_in->flush(); + if (outCount) { + if (!base_type::out.swap(outCount)) { return -1; } + } + return outCount; + } + + private: + void genTaps() { + // Free current taps if they exist + taps::free(rrcTaps); + + // Calculate the rational samplerate ratio + int InSR = round(_symbolrate); + int OutSR = round(_samplerate); + int gcd = std::gcd(InSR, OutSR); + int interp = OutSR / gcd; + int decim = InSR / gcd; + + spdlog::warn("interp: {0}, decim: {1}", interp, decim); + + // Configure resampler + double tapSamplerate = _symbolrate * (double)interp; + rrcTaps = taps::rootRaisedCosine(_rrcTapCount * interp, _rrcBeta, _symbolrate, tapSamplerate); + resamp.setRatio(interp, decim, rrcTaps); + } + + double _symbolrate; + double _samplerate; + double _rrcBeta; + int _rrcTapCount; + + tap rrcTaps; + multirate::PolyphaseResampler resamp; + + }; +} \ 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 3d8a8eb9..56ac1ac7 100644 --- a/core/src/dsp/taps/band_pass.h +++ b/core/src/dsp/taps/band_pass.h @@ -4,13 +4,13 @@ #include "estimate_tap_count.h" #include "../window/nuttall.h" #include "../math/phasor.h" -#include "../math/freq_to_omega.h" +#include "../math/hz_to_rads.h" namespace dsp::taps { template 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); + float offsetOmega = math::hzToRads((bandStart + bandStop) / 2.0, sampleRate); int count = estimateTapCount(transWidth, sampleRate); if (oddTapCount && !(count % 2)) { count++; } return windowedSinc(count, (bandStop - bandStart) / 2.0, sampleRate, [=](double n, double N) { diff --git a/core/src/dsp/taps/from_array.h b/core/src/dsp/taps/from_array.h index fd960f5d..83df20f5 100644 --- a/core/src/dsp/taps/from_array.h +++ b/core/src/dsp/taps/from_array.h @@ -1,7 +1,7 @@ #pragma once #include "tap.h" #include "../math/sinc.h" -#include "../math/freq_to_omega.h" +#include "../math/hz_to_rads.h" #include "../window/nuttall.h" namespace dsp::taps { diff --git a/core/src/dsp/taps/windowed_sinc.h b/core/src/dsp/taps/windowed_sinc.h index 84c3e1f6..854e6558 100644 --- a/core/src/dsp/taps/windowed_sinc.h +++ b/core/src/dsp/taps/windowed_sinc.h @@ -1,7 +1,7 @@ #pragma once #include "tap.h" #include "../math/sinc.h" -#include "../math/freq_to_omega.h" +#include "../math/hz_to_rads.h" #include "../window/nuttall.h" namespace dsp::taps { @@ -30,6 +30,6 @@ namespace dsp::taps { template inline tap windowedSinc(int count, double cutoff, double samplerate, Func window, double norm = 1.0) { - return windowedSinc(count, math::freqToOmega(cutoff, samplerate), window, norm); + return windowedSinc(count, math::hzToRads(cutoff, samplerate), window, norm); } } \ No newline at end of file diff --git a/core/src/gui/menus/display.cpp b/core/src/gui/menus/display.cpp index 3a65db42..11e9eb90 100644 --- a/core/src/gui/menus/display.cpp +++ b/core/src/gui/menus/display.cpp @@ -11,7 +11,6 @@ namespace displaymenu { bool showWaterfall; - bool fastFFT = true; bool fullWaterfallUpdate = true; int colorMapId = 0; std::vector colorMapNames; @@ -81,9 +80,6 @@ namespace displaymenu { } } - fastFFT = core::configManager.conf["fastFFT"]; - gui::waterfall.setFastFFT(fastFFT); - fullWaterfallUpdate = core::configManager.conf["fullWaterfallUpdate"]; gui::waterfall.setFullWaterfallUpdate(fullWaterfallUpdate); @@ -129,13 +125,6 @@ namespace displaymenu { core::configManager.release(true); } - if (ImGui::Checkbox("Fast FFT##_sdrpp", &fastFFT)) { - gui::waterfall.setFastFFT(fastFFT); - core::configManager.acquire(); - core::configManager.conf["fastFFT"] = fastFFT; - core::configManager.release(true); - } - if (ImGui::Checkbox("Full Waterfall Update##_sdrpp", &fullWaterfallUpdate)) { gui::waterfall.setFullWaterfallUpdate(fullWaterfallUpdate); core::configManager.acquire(); diff --git a/core/src/gui/widgets/waterfall.cpp b/core/src/gui/widgets/waterfall.cpp index df9d1abb..728f2f29 100644 --- a/core/src/gui/widgets/waterfall.cpp +++ b/core/src/gui/widgets/waterfall.cpp @@ -570,11 +570,6 @@ namespace ImGui { return true; } - void WaterFall::setFastFFT(bool fastFFT) { - std::lock_guard lck(buf_mtx); - _fastFFT = fastFFT; - } - void WaterFall::updateWaterfallFb() { if (!waterfallVisible || rawFFTs == NULL) { return; @@ -591,7 +586,7 @@ namespace ImGui { for (int i = 0; i < count; i++) { drawDataSize = (viewBandwidth / wholeBandwidth) * rawFFTSize; drawDataStart = (((double)rawFFTSize / 2.0) * (offsetRatio + 1)) - (drawDataSize / 2); - doZoom(drawDataStart, drawDataSize, dataWidth, &rawFFTs[((i + currentFFTLine) % waterfallHeight) * rawFFTSize], tempData, _fastFFT); + doZoom(drawDataStart, drawDataSize, dataWidth, &rawFFTs[((i + currentFFTLine) % waterfallHeight) * rawFFTSize], tempData); for (int j = 0; j < dataWidth; j++) { pixel = (std::clamp(tempData[j], waterfallMin, waterfallMax) - waterfallMin) / dataRange; waterfallFb[(i * dataWidth) + j] = waterfallPallet[(int)(pixel * (WATERFALL_RESOLUTION - 1))]; @@ -861,18 +856,8 @@ namespace ImGui { int drawDataSize = (viewBandwidth / wholeBandwidth) * rawFFTSize; int drawDataStart = (((double)rawFFTSize / 2.0) * (offsetRatio + 1)) - (drawDataSize / 2); - // If in fast mode, apply IIR filtering - float* buf = &rawFFTs[currentFFTLine * rawFFTSize]; - if (_fastFFT) { - float last = buf[0]; - for (int i = 0; i < rawFFTSize; i++) { - last = (buf[i] * 0.1f) + (last * 0.9f); - buf[i] = last; - } - } - if (waterfallVisible) { - doZoom(drawDataStart, drawDataSize, dataWidth, &rawFFTs[currentFFTLine * rawFFTSize], latestFFT, _fastFFT); + doZoom(drawDataStart, drawDataSize, dataWidth, &rawFFTs[currentFFTLine * rawFFTSize], latestFFT); memmove(&waterfallFb[dataWidth], waterfallFb, dataWidth * (waterfallHeight - 1) * sizeof(uint32_t)); float pixel; float dataRange = waterfallMax - waterfallMin; @@ -884,7 +869,7 @@ namespace ImGui { waterfallUpdate = true; } else { - doZoom(drawDataStart, drawDataSize, dataWidth, rawFFTs, latestFFT, _fastFFT); + doZoom(drawDataStart, drawDataSize, dataWidth, rawFFTs, latestFFT); fftLines = 1; } diff --git a/core/src/gui/widgets/waterfall.h b/core/src/gui/widgets/waterfall.h index 9aa28906..9bea619e 100644 --- a/core/src/gui/widgets/waterfall.h +++ b/core/src/gui/widgets/waterfall.h @@ -90,7 +90,7 @@ namespace ImGui { float* getFFTBuffer(); void pushFFT(); - inline void doZoom(int offset, int width, int outWidth, float* data, float* out, bool fast) { + inline void doZoom(int offset, int width, int outWidth, float* data, float* out) { // NOTE: REMOVE THAT SHIT, IT'S JUST A HACKY FIX if (offset < 0) { offset = 0; @@ -100,28 +100,20 @@ namespace ImGui { } float factor = (float)width / (float)outWidth; - - if (fast) { - for (int i = 0; i < outWidth; i++) { - out[i] = data[(int)(offset + ((float)i * factor))]; - } - } - else { - float sFactor = ceilf(factor); - float uFactor; - float id = offset; - float maxVal; - int sId; - for (int i = 0; i < outWidth; i++) { - maxVal = -INFINITY; - sId = (int)id; - uFactor = (sId + sFactor > rawFFTSize) ? sFactor - ((sId + sFactor) - rawFFTSize) : sFactor; - for (int j = 0; j < uFactor; j++) { - if (data[sId + j] > maxVal) { maxVal = data[sId + j]; } - } - out[i] = maxVal; - id += factor; + float sFactor = ceilf(factor); + float uFactor; + float id = offset; + float maxVal; + int sId; + for (int i = 0; i < outWidth; i++) { + maxVal = -INFINITY; + sId = (int)id; + uFactor = (sId + sFactor > rawFFTSize) ? sFactor - ((sId + sFactor) - rawFFTSize) : sFactor; + for (int j = 0; j < uFactor; j++) { + if (data[sId + j] > maxVal) { maxVal = data[sId + j]; } } + out[i] = maxVal; + id += factor; } } @@ -170,8 +162,6 @@ namespace ImGui { void setRawFFTSize(int size); - void setFastFFT(bool fastFFT); - void setFullWaterfallUpdate(bool fullUpdate); void setBandPlanPos(int pos); @@ -328,7 +318,6 @@ namespace ImGui { bool waterfallVisible = true; bool bandplanVisible = false; - bool _fastFFT = true; bool _fullUpdate = true; int bandPlanPos = BANDPLAN_POS_BOTTOM; diff --git a/decoder_modules/meteor_demodulator/src/meteor_costas.h b/decoder_modules/meteor_demodulator/src/meteor_costas.h index 7c65c5d8..f4c04323 100644 --- a/decoder_modules/meteor_demodulator/src/meteor_costas.h +++ b/decoder_modules/meteor_demodulator/src/meteor_costas.h @@ -39,10 +39,10 @@ namespace dsp::loop { const float PHASE4 = -0.29067248091319986; float phase = val.phase(); - float dp1 = math::normPhaseDiff(phase - PHASE1); - float dp2 = math::normPhaseDiff(phase - PHASE2); - float dp3 = math::normPhaseDiff(phase - PHASE3); - float dp4 = math::normPhaseDiff(phase - PHASE4); + float dp1 = math::normalizePhase(phase - PHASE1); + float dp2 = math::normalizePhase(phase - PHASE2); + float dp3 = math::normalizePhase(phase - PHASE3); + float dp4 = math::normalizePhase(phase - PHASE4); float lowest = dp1; if (fabsf(dp2) < fabsf(lowest)) { lowest = dp2; } if (fabsf(dp3) < fabsf(lowest)) { lowest = dp3; } diff --git a/decoder_modules/radio/src/radio_module.h b/decoder_modules/radio/src/radio_module.h index b7f6748e..8e38ee39 100644 --- a/decoder_modules/radio/src/radio_module.h +++ b/decoder_modules/radio/src/radio_module.h @@ -112,6 +112,7 @@ public: } ~RadioModule() { + core::modComManager.unregisterInterface(name); gui::menu.removeEntry(name); stream.stop(); if (enabled) {