Skip to content

Commit bf2b6d5

Browse files
committed
Compute AC3 DPLL loop gains from explicit design parameters
Port of museld commit b82e92b: the proportional and integral gains are derived from a second-order loop design (natural frequency 1800 Hz, damping factor 0.6) divided by the combined phase-detector/VCO gain of 0.3, instead of the hard-coded 1/16 and 1/512 which ignored the sub-unity detector gain and made the realized loop ~2.5x slower than designed. Per the reference implementation's A/B testing, output is bit-identical on real captures while tracking through wow/flutter improves substantially. Re-verified 100.000% symbol agreement against the updated C++ implementation on the same three captures as before.
1 parent 4d12e05 commit bf2b6d5

1 file changed

Lines changed: 20 additions & 4 deletions

File tree

lddecode/ac3rf.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,26 @@ def process(self, data_re, data_im):
181181
# DPLL counter is c_counter_bits wide; it wraps once per symbol.
182182
_DPLL_COUNTER_BITS = 10
183183
_DPLL_ERROR_SUM_BITS = 15
184-
# Loop filter gains; these yield approximately a natural frequency of
185-
# 2060 Hz and damping factor 0.72 at the nominal symbol rate.
186-
_DPLL_G1 = 1 / 16.0
187-
_DPLL_G2 = 1 / 512.0
184+
185+
# The symbol reclocking loop filter is designed as a second-order loop
186+
# with natural frequency _DPLL_OMEGA and damping factor _DPLL_ZETA,
187+
# updated at the symbol rate.
188+
_DPLL_OMEGA = 2 * np.pi * 1800 # undamped natural frequency [rad/s]
189+
_DPLL_ZETA = 0.6 # damping factor
190+
_DPLL_TS = 1.0 / SYMBOL_RATE
191+
# Combined phase detector and VCO gain; the detector's average gain is
192+
# well below unity since only cycles with exactly one symbol transition
193+
# update the loop.
194+
_DPLL_GPD_GVCO = 0.3
195+
# Proportional and integral gains
196+
_DPLL_G1 = (1 - np.exp(-2 * _DPLL_ZETA * _DPLL_OMEGA * _DPLL_TS)) / _DPLL_GPD_GVCO
197+
_DPLL_G2 = (
198+
1
199+
+ np.exp(-2 * _DPLL_OMEGA * _DPLL_ZETA * _DPLL_TS)
200+
- 2
201+
* np.exp(-_DPLL_OMEGA * _DPLL_ZETA * _DPLL_TS)
202+
* np.cos(_DPLL_OMEGA * _DPLL_TS * np.sqrt(1 - _DPLL_ZETA**2))
203+
) / _DPLL_GPD_GVCO
188204

189205

190206
@jitclass(AC3_DPLL_spec)

0 commit comments

Comments
 (0)