From b16ab3f0c002e3613e3076aed5ee5fd366289afc Mon Sep 17 00:00:00 2001 From: Ryzerth Date: Fri, 16 Apr 2021 19:53:47 +0200 Subject: [PATCH] Push before merge --- core/src/dsp/demodulator.h | 144 +---------------------------- core/src/dsp/pll.h | 1 + core/src/dsp/processing.h | 1 + core/src/dsp/resampling.h | 69 ++++++++------ core/src/dsp/source.h | 1 + core/src/dsp/types.h | 3 +- core/src/dsp/window.h | 91 ++++-------------- core/src/gui/widgets/waterfall.cpp | 4 +- rx888_source/src/main.cpp | 2 +- 9 files changed, 70 insertions(+), 246 deletions(-) diff --git a/core/src/dsp/demodulator.h b/core/src/dsp/demodulator.h index 685531d..67126c5 100644 --- a/core/src/dsp/demodulator.h +++ b/core/src/dsp/demodulator.h @@ -7,6 +7,7 @@ #include #include #include +#include #define FAST_ATAN2_COEF1 FL_M_PI / 4.0f #define FAST_ATAN2_COEF2 3.0f * FAST_ATAN2_COEF1 @@ -186,149 +187,6 @@ namespace dsp { }; - class StereoFMDemod : public generic_block { - public: - StereoFMDemod() {} - - StereoFMDemod(stream* in, float sampleRate, float deviation) { init(in, sampleRate, deviation); } - - ~StereoFMDemod() { - generic_block::stop(); - delete[] doubledPilot; - delete[] a_minus_b; - delete[] a_out; - delete[] b_out; - } - - void init(stream* in, float sampleRate, float deviation) { - _sampleRate = sampleRate; - - doubledPilot = new float[STREAM_BUFFER_SIZE]; - a_minus_b = new float[STREAM_BUFFER_SIZE]; - a_out = new float[STREAM_BUFFER_SIZE]; - b_out = new float[STREAM_BUFFER_SIZE]; - - fmDemod.init(in, sampleRate, deviation); - split.init(&fmDemod.out); - split.bindStream(&filterInput); - split.bindStream(&decodeInput); - - // Filter init - win.init(1000, 1000, 19000, sampleRate); - filter.init(&filterInput, &win); - agc.init(&filter.out, 20.0f, sampleRate); - - generic_block::registerInput(&decodeInput); - generic_block::registerOutput(&out); - } - - void setInput(stream* in) { - std::lock_guard lck(generic_block::ctrlMtx); - generic_block::tempStop(); - fmDemod.setInput(in); - generic_block::tempStart(); - } - - void setSampleRate(float sampleRate) { - std::lock_guard lck(generic_block::ctrlMtx); - generic_block::tempStop(); - _sampleRate = sampleRate; - fmDemod.setSampleRate(sampleRate); - win.setSampleRate(_sampleRate); - filter.updateWindow(&win); - generic_block::tempStart(); - } - - float getSampleRate() { - return _sampleRate; - } - - void setDeviation(float deviation) { - std::lock_guard lck(generic_block::ctrlMtx); - generic_block::tempStop(); - fmDemod.setDeviation(deviation); - generic_block::tempStart(); - } - - float getDeviation() { - return fmDemod.getDeviation(); - } - - int run() { - count = decodeInput.read(); - if (count < 0) { return -1; } - countFilter = agc.out.read(); - if (countFilter < 0) { return -1; } - - volk_32f_x2_multiply_32f(doubledPilot, agc.out.readBuf, agc.out.readBuf, count); - - volk_32f_x2_multiply_32f(a_minus_b, decodeInput.readBuf, doubledPilot, count); - - volk_32f_x2_add_32f(a_out, decodeInput.readBuf, a_minus_b, count); - volk_32f_x2_subtract_32f(b_out, decodeInput.readBuf, a_minus_b, count); - - decodeInput.flush(); - agc.out.flush(); - - volk_32f_x2_interleave_32fc((lv_32fc_t*)out.writeBuf, a_out, b_out, count); - - if (!out.swap(count)) { return -1; } - return count; - } - - void start() { - std::lock_guard lck(generic_block::ctrlMtx); - if (generic_block::running) { - return; - } - generic_block::running = true; - generic_block::doStart(); - fmDemod.start(); - split.start(); - filter.start(); - agc.start(); - } - - void stop() { - std::lock_guard lck(generic_block::ctrlMtx); - if (!generic_block::running) { - return; - } - fmDemod.stop(); - split.stop(); - filter.stop(); - agc.stop(); - generic_block::doStop(); - generic_block::running = false; - } - - stream out; - - private: - int count; - int countFilter; - - float _sampleRate; - - FloatFMDemod fmDemod; - Splitter split; - - // Pilot tone filtering - stream filterInput; - FIR filter; - filter_window::BlackmanBandpassWindow win; - AGC agc; - - stream decodeInput; - - // Buffers - float* doubledPilot; - float* a_minus_b; - float* a_out; - float* b_out; - - }; - class AMDemod : public generic_block { public: AMDemod() {} diff --git a/core/src/dsp/pll.h b/core/src/dsp/pll.h index 5294992..025657a 100644 --- a/core/src/dsp/pll.h +++ b/core/src/dsp/pll.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace dsp { template diff --git a/core/src/dsp/processing.h b/core/src/dsp/processing.h index ed783e5..7f8724f 100644 --- a/core/src/dsp/processing.h +++ b/core/src/dsp/processing.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace dsp { template diff --git a/core/src/dsp/resampling.h b/core/src/dsp/resampling.h index 0241bc7..44ba2a7 100644 --- a/core/src/dsp/resampling.h +++ b/core/src/dsp/resampling.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace dsp { template @@ -192,11 +193,22 @@ namespace dsp { public: PowerDecimator() {} - PowerDecimator(stream* in, unsigned int power) { init(in, power); } + PowerDecimator(stream* in, int power, int tapCount) { init(in, power, tapCount); } - void init(stream* in, unsigned int power) { + void init(stream* in, int power, int tapCount) { _in = in; _power = power; + _tapCount = tapCount; + + // Allocate buffers + for (int i = 0; i < _power; i++) { + buffers[i] = new complex_t[STREAM_BUFFER_SIZE / (i+1)]; + bufferStart[i] = &buffers[i][_tapCount - 1]; + } + + // Create taps + genHalfbandTaps(); + generic_block::registerInput(_in); generic_block::registerOutput(&out); } @@ -220,29 +232,6 @@ namespace dsp { int run() { int count = _in->read(); if (count < 0) { return -1; } - - if (_power == 0) { - memcpy(out.writeBuf, _in->readBuf, count * sizeof(complex_t)); - } - else if (_power == 1) { - for (int j = 0; j < count; j += 2) { - out.writeBuf[j / 2].re = (_in->readBuf[j].re + _in->readBuf[j + 1].re) * 0.5f; - out.writeBuf[j / 2].im = (_in->readBuf[j].im + _in->readBuf[j + 1].im) * 0.5f; - } - count /= 2; - } - - _in->flush(); - - if (_power > 1) { - for (int i = 1; i < _power; i++) { - for (int j = 0; j < count; j += 2) { - out.writeBuf[j / 2].re = (_in->readBuf[j].re + _in->readBuf[j + 1].re) * 0.5f; - out.writeBuf[j / 2].im = (_in->readBuf[j].im + _in->readBuf[j + 1].im) * 0.5f; - } - count /= 2; - } - } if (!out.swap(count)) { return -1; } return count; @@ -250,10 +239,36 @@ namespace dsp { stream out; - private: - unsigned int _power = 0; + void genHalfbandTaps() { + if (taps != NULL) { delete[] taps; } + taps = new float[_tapCount]; + + // Using Blackman-harris windows + int half = _tapCount / 2; + for (int i = 0; i < _tapCount; i++) { + taps[i] = sinc((FL_M_PI / 2.0f) * (i-half)) * blackmanHarrisWin(i, _tapCount - 1); + printf("%f\n", taps[i]); + } + } + + inline float sinc(float x) { + return ((x == 0) ? 1.0f : (sinf(x)/x)) / FL_M_PI; + } + + inline float blackmanHarrisWin(float n, float N) { + return 0.35875f - (0.48829f*cosf(2.0f*FL_M_PI*(n/N))) + (0.14128f*cosf(4.0f*FL_M_PI*(n/N))) - (0.01168f*cosf(6.0f*FL_M_PI*(n/N))); + } + + int _power = 0; + int _tapCount = 31; stream* _in; + // Buffer lists, sets max decimation to 2^32 + complex_t* buffers[32]; + complex_t* bufferStart[32]; + + float* taps = NULL; + }; } \ No newline at end of file diff --git a/core/src/dsp/source.h b/core/src/dsp/source.h index 29416e9..78c2d2a 100644 --- a/core/src/dsp/source.h +++ b/core/src/dsp/source.h @@ -1,5 +1,6 @@ #pragma once #include +#include namespace dsp { class SineSource : public generic_block { diff --git a/core/src/dsp/types.h b/core/src/dsp/types.h index c446f33..e743e5f 100644 --- a/core/src/dsp/types.h +++ b/core/src/dsp/types.h @@ -1,7 +1,6 @@ #pragma once #include - -#define FL_M_PI 3.1415926535f +#include namespace dsp { struct complex_t { diff --git a/core/src/dsp/window.h b/core/src/dsp/window.h index 8271415..491a119 100644 --- a/core/src/dsp/window.h +++ b/core/src/dsp/window.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace dsp { namespace filter_window { @@ -50,6 +51,25 @@ namespace dsp { } void createTaps(float* taps, int tapCount, float factor = 1.0f) { + // // Calculate cuttoff frequency + // float omega = 2.0f * FL_M_PI * (_cutoff / _sampleRate); + // if (omega > FL_M_PI) { omega = FL_M_PI; } + + // // Generate taps + // float val; + // float sum = 0.0f; + // for (int i = 0; i < tapCount; i++) { + // val = math::sinc(omega, i-(tapCount/2), FL_M_PI) * window_function::blackman(i, tapCount - 1); + // taps[i] = val; + // sum += val; + // } + + // // Normalize taps and multiply by supplied factor + // for (int i = 0; i < tapCount; i++) { + // taps[i] *= factor; + // taps[i] /= sum; + // } + float fc = _cutoff / _sampleRate; if (fc > 1.0f) { fc = 1.0f; @@ -73,79 +93,8 @@ namespace dsp { float _cutoff, _transWidth, _sampleRate; }; - - class BlackmanBandpassWindow : public filter_window::generic_window { - public: - BlackmanBandpassWindow() {} - BlackmanBandpassWindow(float cutoff, float transWidth, float offset, float sampleRate) { init(cutoff, transWidth, offset, sampleRate); } - - void init(float cutoff, float transWidth, float offset, float sampleRate) { - _cutoff = cutoff; - _transWidth = transWidth; - _offset = offset; - _sampleRate = sampleRate; - } - - void setSampleRate(float sampleRate) { - _sampleRate = sampleRate; - } - - void setCutoff(float cutoff) { - _cutoff = cutoff; - } - - void setTransWidth(float transWidth) { - _transWidth = transWidth; - } - - void setOffset(float offset) { - _offset = offset; - } - - int getTapCount() { - float fc = _cutoff / _sampleRate; - if (fc > 1.0f) { - fc = 1.0f; - } - - int _M = 4.0f / (_transWidth / _sampleRate); - if (_M < 4) { - _M = 4; - } - - if (_M % 2 == 0) { _M++; } - - return _M; - } - - void createTaps(float* taps, int tapCount, float factor = 1.0f) { - float fc = _cutoff / _sampleRate; - if (fc > 1.0f) { - fc = 1.0f; - } - float tc = tapCount; - float sum = 0.0f; - float val; - for (int i = 0; i < tapCount; i++) { - val = (sin(2.0f * FL_M_PI * fc * ((float)i - (tc / 2))) / ((float)i - (tc / 2))) * - (0.42f - (0.5f * cos(2.0f * FL_M_PI / tc)) + (0.8f * cos(4.0f * FL_M_PI / tc))); - taps[i] = val; // tapCount - i - 1 - sum += val; - } - for (int i = 0; i < tapCount; i++) { - taps[i] *= cos(2.0f * (_offset / _sampleRate) * FL_M_PI * (float)i); - taps[i] *= factor; - taps[i] /= sum; - } - } - - private: - float _cutoff, _transWidth, _sampleRate, _offset; - - }; } - class RRCTaps : public filter_window::generic_window { public: RRCTaps() {} diff --git a/core/src/gui/widgets/waterfall.cpp b/core/src/gui/widgets/waterfall.cpp index d64b1cd..90b0a2a 100644 --- a/core/src/gui/widgets/waterfall.cpp +++ b/core/src/gui/widgets/waterfall.cpp @@ -69,7 +69,7 @@ double freq_ranges[] = { 10000000.0, 20000000.0, 25000000.0, 50000000.0 }; -double findBestRange(double bandwidth, int maxSteps) { +inline double findBestRange(double bandwidth, int maxSteps) { for (int i = 0; i < 32; i++) { if (bandwidth / freq_ranges[i] < (double)maxSteps) { return freq_ranges[i]; @@ -78,7 +78,7 @@ double findBestRange(double bandwidth, int maxSteps) { return 50000000.0; } -void printAndScale(double freq, char* buf) { +inline void printAndScale(double freq, char* buf) { double freqAbs = fabs(freq); if (freqAbs < 1000) { sprintf(buf, "%.6g", freq); diff --git a/rx888_source/src/main.cpp b/rx888_source/src/main.cpp index 80f7225..16222dd 100644 --- a/rx888_source/src/main.cpp +++ b/rx888_source/src/main.cpp @@ -5,7 +5,7 @@ #include #include #include - +#include #include #include