pll: add note on dithering
This commit is contained in:
parent
974fa6e220
commit
4cfe6ba416
|
@ -10,9 +10,8 @@ use serde::{Deserialize, Serialize};
|
||||||
/// stable for any gain (1 <= shift <= 30). It has a single parameter that determines the loop
|
/// 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.
|
/// bandwidth in octave steps. The gain can be changed freely between updates.
|
||||||
///
|
///
|
||||||
/// The frequency settling time constant for an (any) frequency jump is `1 << shift` update cycles.
|
/// The frequency and phase settling time constants for an (any) frequency jump are `1 << shift`
|
||||||
/// The phase settling time in response to a frequency jump is about twice that. The loop bandwidth
|
/// update cycles. The loop bandwidth is about `1/(2*pi*(1 << shift))` in units of the sample rate.
|
||||||
/// is about `1/(2*pi*(1 << shift))` in units of the sample rate.
|
|
||||||
///
|
///
|
||||||
/// All math is naturally wrapping 32 bit integer. Phase and frequency are understood modulo that
|
/// 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
|
/// overflow in the first Nyquist zone. Expressing the IIR equations in other ways (e.g. single
|
||||||
|
@ -20,7 +19,8 @@ use serde::{Deserialize, Serialize};
|
||||||
///
|
///
|
||||||
/// There are no floating point rounding errors here. But there is integer quantization/truncation
|
/// 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
|
/// error of the `shift` lowest bits leading to a phase offset for very low gains. Truncation
|
||||||
/// bias is applied. Rounding is "half up".
|
/// 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
|
/// This PLL does not unwrap phase slips during lock acquisition. This can and should be
|
||||||
/// implemented elsewhere by (down) scaling and then unwrapping the input phase and (up) scaling
|
/// implemented elsewhere by (down) scaling and then unwrapping the input phase and (up) scaling
|
||||||
|
@ -89,6 +89,7 @@ mod tests {
|
||||||
assert_eq!(f.wrapping_sub(f0).abs() <= 1, true);
|
assert_eq!(f.wrapping_sub(f0).abs() <= 1, true);
|
||||||
}
|
}
|
||||||
if i > n / 2 {
|
if i > n / 2 {
|
||||||
|
// The remaining error is removed by dithering.
|
||||||
assert_eq!(y.wrapping_sub(x).abs() < 1 << 18, true);
|
assert_eq!(y.wrapping_sub(x).abs() < 1 << 18, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue