nx_lpc_levinson.nx
buildroot/runtime/nx_lpc_levinson.nx
about
nx_lpc_levinson.nx -- Levinson-Durbin recursion in Q30 fixed-point.
Arc 1 Phase A.2 (after nx_lpc_autocorr).
Given autocorrelation R[0..p] (i64 from nx_lpc_autocorr), computes:
- reflection coefficients (PARCOR) k[1..p] in Q30 (|k_i| < 1 for stable)
- LPC predictor coefficients a[1..p] in Q30
- prediction error E[p] in i64 (= R[0] * Π(1 - k_i²))
Re-derived from Levinson-Durbin / Yule-Walker. Patent-clean math.
Per [[feedback-bits-up-exceed-never-match]] — no Opus, no MLow,
no proprietary codec dependency, integer-only.
Algorithm (per any DSP textbook, e.g. Rabiner & Schafer 1978 §8.3):
E = R[0]
for i = 1 to p:
num = -R[i] - Σ_{j=1..i-1} a[j] * R[i-j] (with proper scaling)
k_i = num / E
new_a[i] = k_i
for j = 1 to i-1: new_a[j] = a[j] + k_i * a[i-j]
E = E * (1 - k_i²)
a = new_a
Fixed-point convention:
- R[*] in raw i64 (autocorrelation sums)
- E in raw i64 (always positive, decreasing each iteration)
- k[*] in Q30: real_k = stored_k / 2^30, |real_k| < 1 ⇒ |stored_k| < 2^30
- a[*] in Q30: same convention; final coefs bounded by O(2^p) typically
Returns 0 on success, -1 if R[0] <= 0 (degenerate / silence) or
p > 30 (would overflow Q30 in a coefs).
dependencies 1 imports · 6 importers
imports: nx_syscalls_x86_64.nx
imported by: nx_rvq_gate.nxnx_voice_codec_v2.nxnx_voice_v2_gate.nxnx_voiceprint.nxnx_vq_dred_gate.nxnx_vq_train_gate.nx
structs
| none |
consts
| 33 | const NX_MAGIC_1073741823: i64 = 1073741823 |
| 34 | const NX_MAGIC_1024: i64 = 1024 |
| 36 | const NX_LPC_Q: i64 = 30 |
| 37 | const NX_LPC_ONE_Q30: i64 = 1073741824 // 1 << 30 |
functions
| 42 | func _q30_mul(a: i64, b: i64) -> i64 called by 1: nx_lpc_levinson |
| 48 | func _i64_div(a: i64, b: i64) -> i64 |
| 61 | func nx_lpc_levinson(r_in: *u8, p_order: i64, |