mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-23 18:52:28 -04:00
Refactor SFFT.
This commit is contained in:
parent
1e77911e9c
commit
d1a833b43f
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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>
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user