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:
sfft(int len);
~sfft();
void run(const cmplx& input, cmplx *result);
void run(const cmplx& input);
void fetch(float *result);
};
#endif

View File

@ -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;
}
}

View File

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

View File

@ -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);

View File

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

View File

@ -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();
}