From d1a833b43f71c28e6b4211ca1f40a32af274e411 Mon Sep 17 00:00:00 2001 From: John Greb Date: Tue, 13 Jan 2015 19:14:36 +0000 Subject: [PATCH] Refactor SFFT. --- include-gpl/dsp/fftfilt.h | 3 ++- plugins/channel/lora/lorademod.cpp | 33 +++++++++++++++------------ plugins/channel/lora/lorademod.h | 2 ++ plugins/channel/lora/lorademodgui.cpp | 2 ++ plugins/channel/lora/lorademodgui.ui | 2 +- sdrbase/dsp/fftfilt.cxx | 26 +++++++++++---------- 6 files changed, 40 insertions(+), 28 deletions(-) diff --git a/include-gpl/dsp/fftfilt.h b/include-gpl/dsp/fftfilt.h index 44e7531f4..618d23d86 100644 --- a/include-gpl/dsp/fftfilt.h +++ b/include-gpl/dsp/fftfilt.h @@ -67,7 +67,8 @@ private: public: sfft(int len); ~sfft(); - void run(const cmplx& input, cmplx *result); + void run(const cmplx& input); + void fetch(float *result); }; #endif diff --git a/plugins/channel/lora/lorademod.cpp b/plugins/channel/lora/lorademod.cpp index 435278b56..53d369536 100644 --- a/plugins/channel/lora/lorademod.cpp +++ b/plugins/channel/lora/lorademod.cpp @@ -36,6 +36,8 @@ LoRaDemod::LoRaDemod(SampleSink* sampleSink) : m_chirp = 0; m_angle = 0; m_bin = 0; + m_result = 0; + m_count = 0; loraFilter = new sfft(LORA_SFFT_LEN); } @@ -52,25 +54,28 @@ void LoRaDemod::configure(MessageQueue* messageQueue, Real Bandwidth) cmd->submit(messageQueue, this); } +// Detecting the header needs an sfft with the opposite rotation int LoRaDemod::detect(Complex c) { - int i, result; - Real peak, mag; - cmplx bins[LORA_SFFT_LEN]; + int i; + float peak; + float mag[LORA_SFFT_LEN]; - // TODO: don`t need per-sample sliding FFT time resolution - loraFilter->run(c, bins); - peak = mag = 0; - result = 0; + loraFilter->run(c); + if (++m_count & 31) + return m_result; + + // process spectrum every 32 samples + loraFilter->fetch(mag); + peak = 0.0f; + m_result = 0; for (i = 0; i < LORA_SFFT_LEN; i++) { - mag = bins[i].real() * bins[i].real() - + bins[i].imag() * bins[i].imag(); - if (mag > peak) { - peak = mag; - result = i; + if (mag[i] > peak) { + peak = mag[i]; + m_result = i; } } - return result; + return m_result; } void LoRaDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool pO) @@ -91,7 +96,7 @@ void LoRaDemod::feed(SampleVector::const_iterator begin, SampleVector::const_ite m_bin = (m_bin + newangle) & (LORA_SFFT_LEN - 1); Complex nangle(cos(M_PI*2*m_bin/LORA_SFFT_LEN),sin(M_PI*2*m_bin/LORA_SFFT_LEN)); - m_sampleBuffer.push_back(Sample(nangle.real() * 1000, nangle.imag() * 1000)); + m_sampleBuffer.push_back(Sample(nangle.real() * 500, nangle.imag() * 500)); m_sampleDistanceRemain += (Real)m_sampleRate / m_Bandwidth; } } diff --git a/plugins/channel/lora/lorademod.h b/plugins/channel/lora/lorademod.h index f1d5317b7..9e2ef443d 100644 --- a/plugins/channel/lora/lorademod.h +++ b/plugins/channel/lora/lorademod.h @@ -71,6 +71,8 @@ private: int m_chirp; int m_angle; int m_bin; + int m_result; + int m_count; sfft* loraFilter; diff --git a/plugins/channel/lora/lorademodgui.cpp b/plugins/channel/lora/lorademodgui.cpp index a05c9ba9a..0827edcae 100644 --- a/plugins/channel/lora/lorademodgui.cpp +++ b/plugins/channel/lora/lorademodgui.cpp @@ -136,6 +136,8 @@ LoRaDemodGUI::LoRaDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : ui->glSpectrum->setDisplayWaterfall(true); ui->glSpectrum->setDisplayMaxHold(true); + setTitleColor(Qt::magenta); + m_channelMarker = new ChannelMarker(this); m_channelMarker->setColor(Qt::magenta); m_channelMarker->setBandwidth(7813); diff --git a/plugins/channel/lora/lorademodgui.ui b/plugins/channel/lora/lorademodgui.ui index 276ed0bb6..7f3eedebf 100644 --- a/plugins/channel/lora/lorademodgui.ui +++ b/plugins/channel/lora/lorademodgui.ui @@ -40,7 +40,7 @@ - + Spreading diff --git a/sdrbase/dsp/fftfilt.cxx b/sdrbase/dsp/fftfilt.cxx index 2957c421e..45f19c365 100644 --- a/sdrbase/dsp/fftfilt.cxx +++ b/sdrbase/dsp/fftfilt.cxx @@ -224,22 +224,24 @@ sfft::~sfft() // Sliding FFT, cmplx input, cmplx output // FFT is computed for each value from first to last // Values are not stable until more than "len" samples have been processed. -// Copies the frequencies to a pointer. -void sfft::run(const cmplx& input, cmplx *result) +void sfft::run(const cmplx& input) { cmplx & de = delay[ptr]; const cmplx z( input.real() - k2 * de.real(), input.imag() - k2 * de.imag()); de = input; - ++ptr ; - if( ptr >= fftlen ) ptr = 0 ; + if (++ptr >= fftlen) + ptr = 0; - // It is more efficient to have vrot and bins very close to each other. - for( vrot_bins_pair - *itr = vrot_bins + first, - *end = vrot_bins + last ; - itr != end ; - ++itr, result++ ) { - *result = itr->bins = (itr->bins + z) * itr->vrot; - } + for (vrot_bins_pair *itr = vrot_bins + first, *end = vrot_bins + last; itr != end ; ++itr) + itr->bins = (itr->bins + z) * itr->vrot; } + +// Copies the frequencies to a pointer. +void sfft::fetch(float *result) +{ + for (vrot_bins_pair *itr = vrot_bins, *end = vrot_bins + last; itr != end; ++itr, ++result) + *result = itr->bins.real() * itr->bins.real() + + itr->bins.imag() * itr->bins.imag(); +} +