From 2f8fda7137272ef4524da42298e75e57ff3b7cde Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 7 Dec 2015 22:31:44 +0100 Subject: [PATCH] PLL cleanup --- include/dsp/phaselock.h | 19 ++--- plugins/channel/bfm/bfmdemod.cpp | 7 +- plugins/channel/bfm/bfmdemod.h | 3 +- sdrbase/dsp/phaselock.cpp | 119 +------------------------------ 4 files changed, 13 insertions(+), 135 deletions(-) diff --git a/include/dsp/phaselock.h b/include/dsp/phaselock.h index 4776d139c..5ec4de32d 100644 --- a/include/dsp/phaselock.h +++ b/include/dsp/phaselock.h @@ -65,20 +65,13 @@ public: void process(const std::vector& samples_in, std::vector& samples_out); /** - * Process samples and extract pilot tone. Generate phase-locked twice - * the frequency tone with unit amplitude. Mostly useful for 19 kHz stereo - * pilot tone on broadcast FM. - * In flow version - */ - void process(const Real& sample_in, Real& sample_out); - - /** - * Process samples and track a pilot tone. Generate samples for multiple phase-locked + * Process samples and track a pilot tone. Generate samples for single or multiple phase-locked * signals. Implement the processPhase virtual method to produce the output samples. * In flow version. Ex: Use 19 kHz stereo pilot tone to generate 38 kHz (stereo) and 57 kHz * pilots (see RDSPhaseLock class below). + * This is the in flow version */ - void process(const Real& sample_in, std::vector& samples_out); + void process(const Real& sample_in, Real *samples_out); /** Return true if the phase-locked loop is locked. */ bool locked() const @@ -100,7 +93,7 @@ protected: * Callback method to produce multiple outputs from the current phase value in m_phase * and/or the sin and cos values in m_psin and m_pcos */ - virtual void processPhase(std::vector& samples_out) const {}; + virtual void processPhase(Real *samples_out) const {}; private: Real m_minfreq, m_maxfreq; @@ -132,7 +125,7 @@ public: {} protected: - virtual void processPhase(std::vector& samples_out) const + virtual void processPhase(Real *samples_out) const { samples_out[0] = m_psin; // f Pilot // Generate double-frequency output. @@ -153,7 +146,7 @@ public: {} protected: - virtual void processPhase(std::vector& samples_out) const + virtual void processPhase(Real *samples_out) const { samples_out[0] = m_psin; // f Pilot // Generate double-frequency output. diff --git a/plugins/channel/bfm/bfmdemod.cpp b/plugins/channel/bfm/bfmdemod.cpp index 7d3d7c0ed..2fed4cb94 100644 --- a/plugins/channel/bfm/bfmdemod.cpp +++ b/plugins/channel/bfm/bfmdemod.cpp @@ -126,11 +126,12 @@ void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto if (m_running.m_audioStereo) { - Real pilotSample; - m_pilotPLL.process(demod, pilotSample); + //Real pilotSample; + //m_pilotPLL.process(demod, pilotSample); + m_pilotPLL.process(demod, m_pilotPLLSamples); //m_sampleBuffer.push_back(Sample(pilotSample * (1<<15), 0.0)); // debug pilot - Complex s(demod*2.0*pilotSample, 0); + Complex s(demod*2.0*m_pilotPLLSamples[1], 0); if (m_interpolatorStereo.interpolate(&m_interpolatorStereoDistanceRemain, s, &cs)) { diff --git a/plugins/channel/bfm/bfmdemod.h b/plugins/channel/bfm/bfmdemod.h index 32541fbd1..114aacd96 100644 --- a/plugins/channel/bfm/bfmdemod.h +++ b/plugins/channel/bfm/bfmdemod.h @@ -144,7 +144,8 @@ private: SampleVector m_sampleBuffer; QMutex m_settingsMutex; - PhaseLock m_pilotPLL; + StereoPhaseLock m_pilotPLL; + Real m_pilotPLLSamples[2]; void apply(); }; diff --git a/sdrbase/dsp/phaselock.cpp b/sdrbase/dsp/phaselock.cpp index b0fdff8c7..4840b9a60 100644 --- a/sdrbase/dsp/phaselock.cpp +++ b/sdrbase/dsp/phaselock.cpp @@ -263,125 +263,8 @@ void PhaseLock::process(const Real& sample_in, Real& sample_out) }*/ -// Process samples. -void PhaseLock::process(const Real& sample_in, Real& sample_out) -{ - bool was_locked = (m_lock_cnt >= m_lock_delay); - m_pps_events.clear(); - - //if (n > 0) m_pilot_level = 1000.0; - - { - - // Generate locked pilot tone. - Real psin = sin(m_phase); - Real pcos = cos(m_phase); - - // Generate double-frequency output. - // sin(2*x) = 2 * sin(x) * cos(x) - sample_out = 2 * psin * pcos; - - // Multiply locked tone with input. - Real x = sample_in; - Real phasor_i = psin * x; - Real phasor_q = pcos * x; - - // Run IQ phase error through low-pass filter. - phasor_i = m_phasor_b0 * phasor_i - - m_phasor_a1 * m_phasor_i1 - - m_phasor_a2 * m_phasor_i2; - phasor_q = m_phasor_b0 * phasor_q - - m_phasor_a1 * m_phasor_q1 - - m_phasor_a2 * m_phasor_q2; - m_phasor_i2 = m_phasor_i1; - m_phasor_i1 = phasor_i; - m_phasor_q2 = m_phasor_q1; - m_phasor_q1 = phasor_q; - - // Convert I/Q ratio to estimate of phase error. - Real phase_err; - if (phasor_i > abs(phasor_q)) { - // We are within +/- 45 degrees from lock. - // Use simple linear approximation of arctan. - phase_err = phasor_q / phasor_i; - } else if (phasor_q > 0) { - // We are lagging more than 45 degrees behind the input. - phase_err = 1; - } else { - // We are more than 45 degrees ahead of the input. - phase_err = -1; - } - - // Detect pilot level (conservative). - // m_pilot_level = std::min(m_pilot_level, phasor_i); - m_pilot_level = phasor_i; - - // Run phase error through loop filter and update frequency estimate. - m_freq += m_loopfilter_b0 * phase_err - + m_loopfilter_b1 * m_loopfilter_x1; - m_loopfilter_x1 = phase_err; - - // Limit frequency to allowable range. - m_freq = std::max(m_minfreq, std::min(m_maxfreq, m_freq)); - - // Update locked phase. - m_phase += m_freq; - if (m_phase > 2.0 * M_PI) { - m_phase -= 2.0 * M_PI; - m_pilot_periods++; - - // Generate pulse-per-second. - if (m_pilot_periods == pilot_frequency) { - m_pilot_periods = 0; - //if (was_locked) { - // struct PpsEvent ev; - // ev.pps_index = m_pps_cnt; - // ev.sample_index = m_sample_cnt + i; - // ev.block_position = double(i) / double(n); - // m_pps_events.push_back(ev); - // m_pps_cnt++; - //} - } - } - } - - // Update lock status. - if (2 * m_pilot_level > m_minsignal) - { - if (m_lock_cnt < m_lock_delay) - { - m_lock_cnt += 1; // n - } - else - { - m_unlock_cnt = 0; - } - } - else - { - if (m_unlock_cnt < m_unlock_delay) - { - m_unlock_cnt += 1; - } - else - { - m_lock_cnt = 0; - } - } - - // Drop PPS events when pilot not locked. - if (m_lock_cnt < m_lock_delay) { - m_pilot_periods = 0; - m_pps_cnt = 0; - m_pps_events.clear(); - } - - // Update sample counter. - m_sample_cnt += 1; // n -} - // Process samples. Multiple output -void PhaseLock::process(const Real& sample_in, std::vector& samples_out) +void PhaseLock::process(const Real& sample_in, Real *samples_out) { bool was_locked = (m_lock_cnt >= m_lock_delay); m_pps_events.clear();