Finished pilot PLL (not tested).
This commit is contained in:
		
							parent
							
								
									f0d58eac10
								
							
						
					
					
						commit
						f371d1bef3
					
				
							
								
								
									
										32
									
								
								FmDecode.cc
								
								
								
								
							
							
						
						
									
										32
									
								
								FmDecode.cc
								
								
								
								
							|  | @ -84,8 +84,17 @@ void PhaseDiscriminator::process(const IQSampleVector& samples_in, | |||
| // Construct phase-locked loop.
 | ||||
| PilotPhaseLock::PilotPhaseLock(double freq, double bandwidth, double minsignal) | ||||
| { | ||||
|     // This is a type-2, 4th order phase-locked loop.
 | ||||
|     // I don't understand what I'm doing; hopefully it just works.
 | ||||
|     /*
 | ||||
|      * This is a type-2, 4th order phase-locked loop. | ||||
|      * | ||||
|      * Open-loop transfer function: | ||||
|      *   G(z) = K * (z - Qz) / ((z - Qp) * (z - Qp) * (z - 1) * (z - 1)) | ||||
|      *   K  = 3.125 * (bandwidth * 2 * PI)**3 | ||||
|      *   Qz = exp(-0.2 * bandwidth * 2*PI) | ||||
|      *   Qp = exp(-2.5 * bandwidth * 2*PI) | ||||
|      * | ||||
|      * I don't understand what I'm doing; hopefully it just works. | ||||
|      */ | ||||
| 
 | ||||
|     // Set min/max locking frequencies.
 | ||||
|     m_minfreq = (freq - bandwidth) * 2.0 * M_PI; | ||||
|  | @ -101,13 +110,16 @@ PilotPhaseLock::PilotPhaseLock(double freq, double bandwidth, double minsignal) | |||
|     double t = exp(-2.5 * bandwidth * 2.0 * M_PI); | ||||
|     m_phasor_a1 = -2.0 * t; | ||||
|     m_phasor_a2 = t * t; | ||||
|     m_phasor_b0 = m_phasor_a1 + m_phasor_a2; | ||||
|     m_phasor_b0 = 1 + m_phasor_a1 + m_phasor_a2; | ||||
| 
 | ||||
|     // Create loop filter to stabilize the loop.
 | ||||
|     // Zero at z = exp(-0.2 * bandwidth * 2*PI), 
 | ||||
|     m_loopfilter_b0 = 1.0; | ||||
|     m_loopfilter_b1 = - exp(-0.2 * bandwidth * 2.0 * M_PI); | ||||
| // TODO : loop gain 
 | ||||
|     // Filter has one Zero at z = exp(-0.2 * bandwidth * 2*PI).
 | ||||
|     m_loopfilter_b0 = 0.5 * bandwidth * 2.0 * M_PI; | ||||
|     m_loopfilter_b1 = - m_loopfilter_b0 * exp(-0.2 * bandwidth * 2.0 * M_PI); | ||||
| 
 | ||||
|     // After the loop filter, the phase error is integrated to produce
 | ||||
|     // the frequency. Then the frequency is integrated to produce the phase.
 | ||||
|     // These two integrators form the two remaining poles, both at z = 1.
 | ||||
| 
 | ||||
|     // Reset frequency and phase.
 | ||||
|     m_freq  = freq * 2.0 * M_PI; | ||||
|  | @ -159,10 +171,10 @@ void PilotPhaseLock::process(const SampleVector& samples_in, | |||
|             // 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.
 | ||||
|             // We are more than 45 degrees ahead of the input.
 | ||||
|             phase_err = 1; | ||||
|         } else { | ||||
|             // We are more than 45 degrees ahead of the input.
 | ||||
|             // We are lagging more than 45 degrees behind the input.
 | ||||
|             phase_err = -1; | ||||
|         } | ||||
| 
 | ||||
|  | @ -174,7 +186,7 @@ void PilotPhaseLock::process(const SampleVector& samples_in, | |||
|         } | ||||
| 
 | ||||
|         // Run phase error through loop filter and update frequency estimate.
 | ||||
|         m_freq += m_loopfilter_b0 * phase_err | ||||
|         m_freq -= m_loopfilter_b0 * phase_err | ||||
|                   + m_loopfilter_b1 * m_loopfilter_x1; | ||||
|         m_loopfilter_x1 = phase_err; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue