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_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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								FmDecode.h
								
								
								
								
							
							
						
						
									
										30
									
								
								FmDecode.h
								
								
								
								
							|  | @ -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, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue