code wiki / (root) / nx_jitterbuf.nx

nx_jitterbuf.nx source

↩ module page · 35 lines · 2095 B

1// nx_jitterbuf.nx -- sovereign ADAPTIVE PLAYOUT DELAY (jitter buffer) sizing for the snapshot 2// interpolator (nx_interp). The interp playout delay is the latency/smoothness dial: too small -> 3// the buffer starves (peer freezes/extrapolates) under jitter; too large -> needless lag. This sizes 4// it to MEASURED jitter (RFC 3550 interarrival-jitter smoothing) and GROWS FAST / SHRINKS SLOW so a 5// jitter spike is covered immediately but latency creeps back down as the link calms. 100% nx, no 6// syscalls -> wasm-friendly. The host only timestamps arrivals; all control logic is here. 7// 8// State jb[*i64]: [0]=last_recv_ms [1]=jitter_acc(~16x mean|D|) [2]=send_interval [3]=playout_delay 9// [4]=min_delay [5]=max_delay [6]=count 10// license_tier: ORIGINAL 11 12func jb_init(jb: *i64, send_interval: i64, min_delay: i64, max_delay: i64) -> i64 { 13 jb[0]=0; jb[1]=0; jb[2]=send_interval; jb[3]=min_delay; jb[4]=min_delay; jb[5]=max_delay; jb[6]=0 14 return 0 15} 16func jb_jitter(jb: *i64) -> i64 { return jb[1] / 16 } // smoothed mean deviation of interarrival 17func jb_playout(jb: *i64) -> i64 { return jb[3] } 18 19// call on each snapshot arrival (recv wall-clock ms). Updates the jitter estimate + adapts the 20// playout delay. Returns the current playout delay (what the interp render-time should lag by). 21func jb_on_recv(jb: *i64, recv_ms: i64) -> i64 { 22 if jb[6] > 0 { 23 var d: i64 = (recv_ms - jb[0]) - jb[2] // D = actual gap - expected gap 24 if d < 0 { d = 0 - d } // |D| 25 jb[1] = jb[1] - (jb[1] / 16) + d // exp-smoothed, scaled x16 (keeps integer resolution) 26 } 27 jb[0] = recv_ms 28 jb[6] = jb[6] + 1 29 var target: i64 = jb[2] + (jb[1] / 4) // send_interval + 4*jitter cushion 30 if target < jb[4] { target = jb[4] } 31 if target > jb[5] { target = jb[5] } 32 if target > jb[3] { jb[3] = target } // GROW FAST (cover the spike now) 33 else { jb[3] = jb[3] - ((jb[3] - target) / 8) } // SHRINK SLOW (latency creeps back down) 34 return jb[3] 35}