1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-06-05 07:24:44 -04:00

PLL cleanup

This commit is contained in:
f4exb
2015-12-07 22:31:44 +01:00
parent ea5cdb034f
commit 2f8fda7137
4 changed files with 13 additions and 135 deletions
+1 -118
View File
@@ -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<Real>& 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();