pub struct PLL { /* private fields */ }
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 open loop transfer function is I^2,I from input phase to output phase and P,I from input phase to output frequency.
The transfer functions (for phase and frequency) contain an additional zero at Nyquist.
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 1/(2*pi*(1 << shift))
in units of the sample rate.
While the phase is being settled after settling the frequency, 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 accumulated during (frequency) 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 then 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.
This PLL implements first order noise shaping to reduce quantization errors.
Implementations§
source§impl PLL
impl PLL
sourcepub fn update(&mut self, x: Option<i32>, k: i32)
pub fn update(&mut self, x: Option<i32>, k: i32)
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.k
: Feedback gain.
Returns: A tuple of instantaneous phase and frequency estimates.
Trait Implementations§
source§impl<'de> Deserialize<'de> for PLL
impl<'de> Deserialize<'de> for PLL
source§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>,
impl Copy for PLL
Auto Trait Implementations§
impl Freeze for PLL
impl RefUnwindSafe for PLL
impl Send for PLL
impl Sync for PLL
impl Unpin for PLL
impl UnwindSafe for PLL
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)