Prepare pilot PLL to produce PPS events.
This commit is contained in:
parent
cfc5e07db6
commit
f6bca05bf0
35
FmDecode.cc
35
FmDecode.cc
|
@ -134,6 +134,11 @@ PilotPhaseLock::PilotPhaseLock(double freq, double bandwidth, double minsignal)
|
|||
m_phasor_q1 = 0;
|
||||
m_phasor_q2 = 0;
|
||||
m_loopfilter_x1 = 0;
|
||||
|
||||
// Initialize PPS generator.
|
||||
m_pilot_periods = 0;
|
||||
m_pps_cnt = 0;
|
||||
m_sample_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -145,6 +150,9 @@ void PilotPhaseLock::process(const SampleVector& samples_in,
|
|||
|
||||
samples_out.resize(n);
|
||||
|
||||
bool was_locked = (m_lock_cnt >= m_lock_delay);
|
||||
m_pps_events.clear();
|
||||
|
||||
if (n > 0)
|
||||
m_pilot_level = 1000.0;
|
||||
|
||||
|
@ -202,8 +210,23 @@ void PilotPhaseLock::process(const SampleVector& samples_in,
|
|||
|
||||
// Update locked phase.
|
||||
m_phase += m_freq;
|
||||
if (m_phase > 2.0 * M_PI)
|
||||
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.abs_sample_index = m_sample_cnt + i;
|
||||
ev.block_sample_index = i;
|
||||
m_pps_events.push_back(ev);
|
||||
m_pps_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update lock status.
|
||||
|
@ -213,6 +236,16 @@ void PilotPhaseLock::process(const SampleVector& samples_in,
|
|||
} 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 += n;
|
||||
}
|
||||
|
||||
|
||||
|
|
30
FmDecode.h
30
FmDecode.h
|
@ -1,6 +1,9 @@
|
|||
#ifndef SOFTFM_FMDECODE_H
|
||||
#define SOFTFM_FMDECODE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "SoftFM.h"
|
||||
#include "Filter.h"
|
||||
|
||||
|
@ -36,7 +39,16 @@ class PilotPhaseLock
|
|||
{
|
||||
public:
|
||||
|
||||
// TODO : pulse-per-second
|
||||
/** Expected pilot frequency (used for PPS events). */
|
||||
static constexpr int pilot_frequency = 19000;
|
||||
|
||||
/** Timestamp event produced once every 19000 pilot periods. */
|
||||
struct PpsEvent
|
||||
{
|
||||
std::uint64_t pps_index;
|
||||
std::uint64_t abs_sample_index;
|
||||
std::uint64_t block_sample_index;
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct phase-locked loop.
|
||||
|
@ -66,6 +78,12 @@ public:
|
|||
return 2 * m_pilot_level;
|
||||
}
|
||||
|
||||
/** Return PPS events from the most recently processed block. */
|
||||
std::vector<PpsEvent> get_pps_events() const
|
||||
{
|
||||
return m_pps_events;
|
||||
}
|
||||
|
||||
private:
|
||||
Sample m_minfreq, m_maxfreq;
|
||||
Sample m_phasor_b0, m_phasor_a1, m_phasor_a2;
|
||||
|
@ -77,6 +95,10 @@ private:
|
|||
Sample m_pilot_level;
|
||||
int m_lock_delay;
|
||||
int m_lock_cnt;
|
||||
int m_pilot_periods;
|
||||
std::uint64_t m_pps_cnt;
|
||||
std::uint64_t m_sample_cnt;
|
||||
std::vector<PpsEvent> m_pps_events;
|
||||
};
|
||||
|
||||
|
||||
|
@ -163,6 +185,12 @@ public:
|
|||
return m_pilotpll.get_pilot_level();
|
||||
}
|
||||
|
||||
/** Return PPS events from the most recently processed block. */
|
||||
std::vector<PilotPhaseLock::PpsEvent> get_pps_events() const
|
||||
{
|
||||
return m_pilotpll.get_pps_events();
|
||||
}
|
||||
|
||||
private:
|
||||
/** Demodulate stereo L-R signal. */
|
||||
void demod_stereo(const SampleVector& samples_baseband,
|
||||
|
|
Loading…
Reference in New Issue