1
0
Fork 0

Prepare pilot PLL to produce PPS events.

This commit is contained in:
Joris van Rantwijk 2014-01-19 12:19:19 +01:00
parent cfc5e07db6
commit f6bca05bf0
2 changed files with 63 additions and 2 deletions

View File

@ -134,6 +134,11 @@ PilotPhaseLock::PilotPhaseLock(double freq, double bandwidth, double minsignal)
m_phasor_q1 = 0; m_phasor_q1 = 0;
m_phasor_q2 = 0; m_phasor_q2 = 0;
m_loopfilter_x1 = 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); samples_out.resize(n);
bool was_locked = (m_lock_cnt >= m_lock_delay);
m_pps_events.clear();
if (n > 0) if (n > 0)
m_pilot_level = 1000.0; m_pilot_level = 1000.0;
@ -202,8 +210,23 @@ void PilotPhaseLock::process(const SampleVector& samples_in,
// Update locked phase. // Update locked phase.
m_phase += m_freq; 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_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. // Update lock status.
@ -213,6 +236,16 @@ void PilotPhaseLock::process(const SampleVector& samples_in,
} else { } else {
m_lock_cnt = 0; 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;
} }

View File

@ -1,6 +1,9 @@
#ifndef SOFTFM_FMDECODE_H #ifndef SOFTFM_FMDECODE_H
#define SOFTFM_FMDECODE_H #define SOFTFM_FMDECODE_H
#include <cstdint>
#include <vector>
#include "SoftFM.h" #include "SoftFM.h"
#include "Filter.h" #include "Filter.h"
@ -36,7 +39,16 @@ class PilotPhaseLock
{ {
public: 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. * Construct phase-locked loop.
@ -66,6 +78,12 @@ public:
return 2 * m_pilot_level; 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: private:
Sample m_minfreq, m_maxfreq; Sample m_minfreq, m_maxfreq;
Sample m_phasor_b0, m_phasor_a1, m_phasor_a2; Sample m_phasor_b0, m_phasor_a1, m_phasor_a2;
@ -77,6 +95,10 @@ private:
Sample m_pilot_level; Sample m_pilot_level;
int m_lock_delay; int m_lock_delay;
int m_lock_cnt; 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 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: private:
/** Demodulate stereo L-R signal. */ /** Demodulate stereo L-R signal. */
void demod_stereo(const SampleVector& samples_baseband, void demod_stereo(const SampleVector& samples_baseband,