From bf926ede367bf4ebbd45e7a8bc94e1ba5aec8963 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 17 Dec 2015 01:13:42 +0100 Subject: [PATCH] BFM demod: implemented phase discriminator in a separate utility class --- plugins/channel/bfm/bfmdemod.cpp | 10 ++++----- plugins/channel/bfm/bfmdemod.h | 33 ++---------------------------- plugins/channel/wfm/wfmdemodgui.ui | 3 +++ 3 files changed, 10 insertions(+), 36 deletions(-) diff --git a/plugins/channel/bfm/bfmdemod.cpp b/plugins/channel/bfm/bfmdemod.cpp index 69fe47e19..e0ad56b26 100644 --- a/plugins/channel/bfm/bfmdemod.cpp +++ b/plugins/channel/bfm/bfmdemod.cpp @@ -37,8 +37,7 @@ BFMDemod::BFMDemod(SampleSink* sampleSink, RDSParser *rdsParser) : m_pilotPLL(19000/384000, 50/384000, 0.01), m_deemphasisFilterX(default_deemphasis * 48000 * 1.0e-6), m_deemphasisFilterY(default_deemphasis * 48000 * 1.0e-6), - m_fmExcursion(default_excursion), - m_fmScaling(384000/m_fmExcursion) + m_fmExcursion(default_excursion) { 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_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_phaseDiscri.setFMScaling(384000/m_fmExcursion); apply(); @@ -124,7 +124,7 @@ void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto m_squelchState--; //demod = phaseDiscriminator2(rf[i], msq); - demod = phaseDiscriminator(rf[i]); + demod = m_phaseDiscri.phaseDiscriminator(rf[i]); } else { @@ -248,7 +248,7 @@ void BFMDemod::start() { m_squelchState = 0; m_audioFifo.clear(); - m_m1Sample = 0; + m_phaseDiscri.reset(); } void BFMDemod::stop() @@ -354,7 +354,7 @@ void BFMDemod::apply() Real lowCut = -(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_fmScaling = m_config.m_inputSampleRate / m_fmExcursion; + m_phaseDiscri.setFMScaling(m_config.m_inputSampleRate / m_fmExcursion); m_settingsMutex.unlock(); qDebug() << "BFMDemod::handleMessage: m_rfFilter->create_filter: sampleRate: " diff --git a/plugins/channel/bfm/bfmdemod.h b/plugins/channel/bfm/bfmdemod.h index b82266569..348585bbe 100644 --- a/plugins/channel/bfm/bfmdemod.h +++ b/plugins/channel/bfm/bfmdemod.h @@ -28,6 +28,7 @@ #include "dsp/fftfilt.h" #include "dsp/phaselock.h" #include "dsp/filterrc.h" +#include "dsp/phasediscri.h" #include "audio/audiofifo.h" #include "util/message.h" #include "rdsdemod.h" @@ -184,8 +185,6 @@ private: Real m_squelchLevel; int m_squelchState; - Complex m_m1Sample; //!< x^-1 complex sample - Complex m_m2Sample; //!< x^-2 complex sample Real m_m1Arg; //!> x^-1 real sample MovingAverage m_movingAverage; @@ -210,37 +209,9 @@ private: static const Real default_deemphasis = 50.0; // 50 us Real m_fmExcursion; - Real m_fmScaling; static const int default_excursion = 750000; // +/- 75 kHz - /** - * 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; - } + PhaseDiscriminators m_phaseDiscri; void apply(); }; diff --git a/plugins/channel/wfm/wfmdemodgui.ui b/plugins/channel/wfm/wfmdemodgui.ui index 4e1651969..05094c804 100644 --- a/plugins/channel/wfm/wfmdemodgui.ui +++ b/plugins/channel/wfm/wfmdemodgui.ui @@ -243,6 +243,9 @@ 100 + + 1 + 20