mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-28 21:12:26 -04:00
BFM demod: implemented phase discriminator in a separate utility class
This commit is contained in:
parent
90552271f8
commit
bf926ede36
@ -37,8 +37,7 @@ BFMDemod::BFMDemod(SampleSink* sampleSink, RDSParser *rdsParser) :
|
|||||||
m_pilotPLL(19000/384000, 50/384000, 0.01),
|
m_pilotPLL(19000/384000, 50/384000, 0.01),
|
||||||
m_deemphasisFilterX(default_deemphasis * 48000 * 1.0e-6),
|
m_deemphasisFilterX(default_deemphasis * 48000 * 1.0e-6),
|
||||||
m_deemphasisFilterY(default_deemphasis * 48000 * 1.0e-6),
|
m_deemphasisFilterY(default_deemphasis * 48000 * 1.0e-6),
|
||||||
m_fmExcursion(default_excursion),
|
m_fmExcursion(default_excursion)
|
||||||
m_fmScaling(384000/m_fmExcursion)
|
|
||||||
{
|
{
|
||||||
setObjectName("BFMDemod");
|
setObjectName("BFMDemod");
|
||||||
|
|
||||||
@ -52,6 +51,7 @@ BFMDemod::BFMDemod(SampleSink* sampleSink, RDSParser *rdsParser) :
|
|||||||
m_deemphasisFilterX.configure(default_deemphasis * m_config.m_audioSampleRate * 1.0e-6);
|
m_deemphasisFilterX.configure(default_deemphasis * m_config.m_audioSampleRate * 1.0e-6);
|
||||||
m_deemphasisFilterY.configure(default_deemphasis * m_config.m_audioSampleRate * 1.0e-6);
|
m_deemphasisFilterY.configure(default_deemphasis * m_config.m_audioSampleRate * 1.0e-6);
|
||||||
m_rfFilter = new fftfilt(-50000.0 / 384000.0, 50000.0 / 384000.0, rfFilterFftLength);
|
m_rfFilter = new fftfilt(-50000.0 / 384000.0, 50000.0 / 384000.0, rfFilterFftLength);
|
||||||
|
m_phaseDiscri.setFMScaling(384000/m_fmExcursion);
|
||||||
|
|
||||||
apply();
|
apply();
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
|
|||||||
m_squelchState--;
|
m_squelchState--;
|
||||||
|
|
||||||
//demod = phaseDiscriminator2(rf[i], msq);
|
//demod = phaseDiscriminator2(rf[i], msq);
|
||||||
demod = phaseDiscriminator(rf[i]);
|
demod = m_phaseDiscri.phaseDiscriminator(rf[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -248,7 +248,7 @@ void BFMDemod::start()
|
|||||||
{
|
{
|
||||||
m_squelchState = 0;
|
m_squelchState = 0;
|
||||||
m_audioFifo.clear();
|
m_audioFifo.clear();
|
||||||
m_m1Sample = 0;
|
m_phaseDiscri.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BFMDemod::stop()
|
void BFMDemod::stop()
|
||||||
@ -354,7 +354,7 @@ void BFMDemod::apply()
|
|||||||
Real lowCut = -(m_config.m_rfBandwidth / 2.0) / m_config.m_inputSampleRate;
|
Real lowCut = -(m_config.m_rfBandwidth / 2.0) / m_config.m_inputSampleRate;
|
||||||
Real hiCut = (m_config.m_rfBandwidth / 2.0) / m_config.m_inputSampleRate;
|
Real hiCut = (m_config.m_rfBandwidth / 2.0) / m_config.m_inputSampleRate;
|
||||||
m_rfFilter->create_filter(lowCut, hiCut);
|
m_rfFilter->create_filter(lowCut, hiCut);
|
||||||
m_fmScaling = m_config.m_inputSampleRate / m_fmExcursion;
|
m_phaseDiscri.setFMScaling(m_config.m_inputSampleRate / m_fmExcursion);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
|
|
||||||
qDebug() << "BFMDemod::handleMessage: m_rfFilter->create_filter: sampleRate: "
|
qDebug() << "BFMDemod::handleMessage: m_rfFilter->create_filter: sampleRate: "
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "dsp/fftfilt.h"
|
#include "dsp/fftfilt.h"
|
||||||
#include "dsp/phaselock.h"
|
#include "dsp/phaselock.h"
|
||||||
#include "dsp/filterrc.h"
|
#include "dsp/filterrc.h"
|
||||||
|
#include "dsp/phasediscri.h"
|
||||||
#include "audio/audiofifo.h"
|
#include "audio/audiofifo.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
#include "rdsdemod.h"
|
#include "rdsdemod.h"
|
||||||
@ -184,8 +185,6 @@ private:
|
|||||||
Real m_squelchLevel;
|
Real m_squelchLevel;
|
||||||
int m_squelchState;
|
int m_squelchState;
|
||||||
|
|
||||||
Complex m_m1Sample; //!< x^-1 complex sample
|
|
||||||
Complex m_m2Sample; //!< x^-2 complex sample
|
|
||||||
Real m_m1Arg; //!> x^-1 real sample
|
Real m_m1Arg; //!> x^-1 real sample
|
||||||
|
|
||||||
MovingAverage<Real> m_movingAverage;
|
MovingAverage<Real> m_movingAverage;
|
||||||
@ -210,37 +209,9 @@ private:
|
|||||||
static const Real default_deemphasis = 50.0; // 50 us
|
static const Real default_deemphasis = 50.0; // 50 us
|
||||||
|
|
||||||
Real m_fmExcursion;
|
Real m_fmExcursion;
|
||||||
Real m_fmScaling;
|
|
||||||
static const int default_excursion = 750000; // +/- 75 kHz
|
static const int default_excursion = 750000; // +/- 75 kHz
|
||||||
|
|
||||||
/**
|
PhaseDiscriminators m_phaseDiscri;
|
||||||
* Standard discriminator using atan2. On modern processors this is as efficient as the non atan2 one.
|
|
||||||
* This is better for high fidelity.
|
|
||||||
*/
|
|
||||||
Real phaseDiscriminator(const Complex& sample)
|
|
||||||
{
|
|
||||||
Complex d(std::conj(m_m1Sample) * sample);
|
|
||||||
m_m1Sample = sample;
|
|
||||||
return (std::atan2(d.imag(), d.real()) / M_PI_2) * m_fmScaling;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alternative without atan at the expense of a slight distorsion on very wideband signals
|
|
||||||
* http://www.embedded.com/design/configurable-systems/4212086/DSP-Tricks--Frequency-demodulation-algorithms-
|
|
||||||
* in addition it needs scaling by instantaneous magnitude squared and volume (0..10) adjustment factor
|
|
||||||
*/
|
|
||||||
Real phaseDiscriminator2(const Complex& sample, Real msq)
|
|
||||||
{
|
|
||||||
Real ip = sample.real() - m_m2Sample.real();
|
|
||||||
Real qp = sample.imag() - m_m2Sample.imag();
|
|
||||||
Real h1 = m_m1Sample.real() * qp;
|
|
||||||
Real h2 = m_m1Sample.imag() * ip;
|
|
||||||
|
|
||||||
m_m2Sample = m_m1Sample;
|
|
||||||
m_m1Sample = sample;
|
|
||||||
|
|
||||||
return ((h1 - h2) / (msq * M_PI)) * m_fmScaling;
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply();
|
void apply();
|
||||||
};
|
};
|
||||||
|
@ -243,6 +243,9 @@
|
|||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>100</number>
|
<number>100</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<number>20</number>
|
<number>20</number>
|
||||||
</property>
|
</property>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user