1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-05-23 18:52:28 -04:00

Refactor SFFT.

This commit is contained in:
John Greb 2015-01-13 19:14:36 +00:00
parent 1e77911e9c
commit d1a833b43f
6 changed files with 40 additions and 28 deletions

View File

@ -67,7 +67,8 @@ private:
public: public:
sfft(int len); sfft(int len);
~sfft(); ~sfft();
void run(const cmplx& input, cmplx *result); void run(const cmplx& input);
void fetch(float *result);
}; };
#endif #endif

View File

@ -36,6 +36,8 @@ LoRaDemod::LoRaDemod(SampleSink* sampleSink) :
m_chirp = 0; m_chirp = 0;
m_angle = 0; m_angle = 0;
m_bin = 0; m_bin = 0;
m_result = 0;
m_count = 0;
loraFilter = new sfft(LORA_SFFT_LEN); loraFilter = new sfft(LORA_SFFT_LEN);
} }
@ -52,25 +54,28 @@ void LoRaDemod::configure(MessageQueue* messageQueue, Real Bandwidth)
cmd->submit(messageQueue, this); cmd->submit(messageQueue, this);
} }
// Detecting the header needs an sfft with the opposite rotation
int LoRaDemod::detect(Complex c) int LoRaDemod::detect(Complex c)
{ {
int i, result; int i;
Real peak, mag; float peak;
cmplx bins[LORA_SFFT_LEN]; float mag[LORA_SFFT_LEN];
// TODO: don`t need per-sample sliding FFT time resolution loraFilter->run(c);
loraFilter->run(c, bins); if (++m_count & 31)
peak = mag = 0; return m_result;
result = 0;
// process spectrum every 32 samples
loraFilter->fetch(mag);
peak = 0.0f;
m_result = 0;
for (i = 0; i < LORA_SFFT_LEN; i++) { for (i = 0; i < LORA_SFFT_LEN; i++) {
mag = bins[i].real() * bins[i].real() if (mag[i] > peak) {
+ bins[i].imag() * bins[i].imag(); peak = mag[i];
if (mag > peak) { m_result = i;
peak = mag;
result = i;
} }
} }
return result; return m_result;
} }
void LoRaDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool pO) 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); 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)); 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; m_sampleDistanceRemain += (Real)m_sampleRate / m_Bandwidth;
} }
} }

View File

@ -71,6 +71,8 @@ private:
int m_chirp; int m_chirp;
int m_angle; int m_angle;
int m_bin; int m_bin;
int m_result;
int m_count;
sfft* loraFilter; sfft* loraFilter;

View File

@ -136,6 +136,8 @@ LoRaDemodGUI::LoRaDemodGUI(PluginAPI* pluginAPI, QWidget* parent) :
ui->glSpectrum->setDisplayWaterfall(true); ui->glSpectrum->setDisplayWaterfall(true);
ui->glSpectrum->setDisplayMaxHold(true); ui->glSpectrum->setDisplayMaxHold(true);
setTitleColor(Qt::magenta);
m_channelMarker = new ChannelMarker(this); m_channelMarker = new ChannelMarker(this);
m_channelMarker->setColor(Qt::magenta); m_channelMarker->setColor(Qt::magenta);
m_channelMarker->setBandwidth(7813); m_channelMarker->setBandwidth(7813);

View File

@ -40,7 +40,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="mabel">
<property name="text"> <property name="text">
<string>Spreading</string> <string>Spreading</string>
</property> </property>

View File

@ -224,22 +224,24 @@ sfft::~sfft()
// Sliding FFT, cmplx input, cmplx output // Sliding FFT, cmplx input, cmplx output
// FFT is computed for each value from first to last // FFT is computed for each value from first to last
// Values are not stable until more than "len" samples have been processed. // Values are not stable until more than "len" samples have been processed.
// Copies the frequencies to a pointer. void sfft::run(const cmplx& input)
void sfft::run(const cmplx& input, cmplx *result)
{ {
cmplx & de = delay[ptr]; cmplx & de = delay[ptr];
const cmplx z( input.real() - k2 * de.real(), input.imag() - k2 * de.imag()); const cmplx z( input.real() - k2 * de.real(), input.imag() - k2 * de.imag());
de = input; de = input;
++ptr ; if (++ptr >= fftlen)
if( ptr >= fftlen ) ptr = 0 ; 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)
for( vrot_bins_pair itr->bins = (itr->bins + z) * itr->vrot;
*itr = vrot_bins + first,
*end = vrot_bins + last ;
itr != end ;
++itr, result++ ) {
*result = 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();
}