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