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

Reverse SFFT for headers.

This commit is contained in:
John Greb 2015-01-14 00:48:48 +00:00
parent d1a833b43f
commit d93c2f8b14
2 changed files with 20 additions and 9 deletions

View File

@ -40,12 +40,15 @@ LoRaDemod::LoRaDemod(SampleSink* sampleSink) :
m_count = 0; m_count = 0;
loraFilter = new sfft(LORA_SFFT_LEN); loraFilter = new sfft(LORA_SFFT_LEN);
negaFilter = new sfft(LORA_SFFT_LEN);
} }
LoRaDemod::~LoRaDemod() LoRaDemod::~LoRaDemod()
{ {
if (loraFilter) if (loraFilter)
delete loraFilter; delete loraFilter;
if (negaFilter)
delete negaFilter;
} }
void LoRaDemod::configure(MessageQueue* messageQueue, Real Bandwidth) void LoRaDemod::configure(MessageQueue* messageQueue, Real Bandwidth)
@ -54,22 +57,29 @@ 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, Complex a)
{ {
int i; int i;
float peak; float peak;
float mag[LORA_SFFT_LEN]; float mag[LORA_SFFT_LEN];
float rev[LORA_SFFT_LEN];
loraFilter->run(c); loraFilter->run(c * a);
negaFilter->run(c * conj(a));
if (++m_count & 31) if (++m_count & 31)
return m_result; return m_result;
// process spectrum every 32 samples // process spectrum every 32 samples
loraFilter->fetch(mag); loraFilter->fetch(mag);
negaFilter->fetch(rev);
peak = 0.0f; peak = 0.0f;
m_result = 0; m_result = 0;
for (i = 0; i < LORA_SFFT_LEN; i++) { for (i = 0; i < LORA_SFFT_LEN; i++) {
if (rev[i]/3 > peak) {
peak = rev[i]/3;
m_result = i;
}
if (mag[i] > peak) { if (mag[i] > peak) {
peak = mag[i]; peak = mag[i];
m_result = i; m_result = i;
@ -92,11 +102,11 @@ void LoRaDemod::feed(SampleVector::const_iterator begin, SampleVector::const_ite
m_chirp = (m_chirp + 1) & (SPREADFACTOR - 1); m_chirp = (m_chirp + 1) & (SPREADFACTOR - 1);
m_angle = (m_angle + m_chirp) & (SPREADFACTOR - 1); m_angle = (m_angle + m_chirp) & (SPREADFACTOR - 1);
Complex cangle(cos(M_PI*2*m_angle/SPREADFACTOR),-sin(M_PI*2*m_angle/SPREADFACTOR)); Complex cangle(cos(M_PI*2*m_angle/SPREADFACTOR),-sin(M_PI*2*m_angle/SPREADFACTOR));
newangle = detect(ci * cangle); newangle = detect(ci, cangle);
m_bin = (m_bin + newangle) & (LORA_SFFT_LEN - 1); m_bin = (m_bin + newangle) & (2*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*m_bin/LORA_SFFT_LEN),sin(M_PI*m_bin/LORA_SFFT_LEN));
m_sampleBuffer.push_back(Sample(nangle.real() * 500, nangle.imag() * 500)); m_sampleBuffer.push_back(Sample(nangle.real() * 100, nangle.imag() * 100));
m_sampleDistanceRemain += (Real)m_sampleRate / m_Bandwidth; m_sampleDistanceRemain += (Real)m_sampleRate / m_Bandwidth;
} }
} }

View File

@ -27,7 +27,7 @@
#define SPREADFACTOR (1<<8) #define SPREADFACTOR (1<<8)
/* It takes a lot of CPU to run the sliding FFT */ /* Chosen for number of bins, not symbol length */
#define LORA_SFFT_LEN (128) #define LORA_SFFT_LEN (128)
class LoRaDemod : public SampleSink { class LoRaDemod : public SampleSink {
@ -38,7 +38,7 @@ public:
void configure(MessageQueue* messageQueue, Real Bandwidth); void configure(MessageQueue* messageQueue, Real Bandwidth);
void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool pO); void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool pO);
int detect(Complex c); int detect(Complex sample, Complex angle);
void start(); void start();
void stop(); void stop();
bool handleMessage(Message* cmd); bool handleMessage(Message* cmd);
@ -75,6 +75,7 @@ private:
int m_count; int m_count;
sfft* loraFilter; sfft* loraFilter;
sfft* negaFilter;
NCO m_nco; NCO m_nco;
Interpolator m_interpolator; Interpolator m_interpolator;