Struct idsp::PLL [−][src]
pub struct PLL { /* fields omitted */ }
Expand description
Type-II, sampled phase, discrete time PLL
This PLL tracks the frequency and phase of an input signal with respect to the sampling clock. The transfer function is I^2,I from input phase to output phase and P,I from input phase to output frequency.
The PLL locks to any frequency (i.e. it locks to the alias in the first Nyquist zone) and is stable for any gain (1 <= shift <= 30). It has a single parameter that determines the loop bandwidth in octave steps. The gain can be changed freely between updates.
The frequency and phase settling time constants for a frequency/phase jump are 1 << shift
update cycles. The loop bandwidth is about 1/(2*pi*(1 << shift))
in units of the sample rate.
While the phase is being settled within one turn, there is a typically very small frequency
overshoot.
All math is naturally wrapping 32 bit integer. Phase and frequency are understood modulo that overflow in the first Nyquist zone. Expressing the IIR equations in other ways (e.g. single (T)-DF-{I,II} biquad/IIR) would break on overflow (i.e. every cycle).
There are no floating point rounding errors here. But there is integer quantization/truncation
error of the shift
lowest bits leading to a phase offset for very low gains. Truncation
bias is applied. Rounding is “half up”. The phase truncation error can be removed very
efficiently by dithering.
This PLL does not unwrap phase slips during lock acquisition. This can and should be implemented elsewhere by unwrapping and scaling the input phase and un-scaling and wrapping output phase and frequency. This affects dynamic range, gain, and noise accordingly.
The extension to I^3,I^2,I behavior to track chirps phase-accurately or to i64 data to increase resolution for extremely narrowband applications is obvious.
Implementations
Update the PLL with a new phase sample. This needs to be called (sampled) periodically. The signal’s phase/frequency is reconstructed relative to the sampling period.
Args:
x
: New input phase sample or None if a sample has been missed.shift_frequency
: Frequency error scaling. The frequency gain per update is1/(1 << shift_frequency)
.shift_phase
: Phase error scaling. The phase gain is1/(1 << shift_phase)
per update. A good value is typicallyshift_frequency - 1
.
Returns: A tuple of instantaneous phase and frequency (the current phase increment).
Trait Implementations
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more