code wiki / _hdl_build / nx_audio_enhance_gate.nx

nx_audio_enhance_gate.nx source

↩ module page · 73 lines · 4498 B

1// nx_audio_enhance_gate.nx -- proves + MEASURES sovereign audio enhancement (nx_audio_enhance), the bad-mic fix. 2// Native nx_cc->nxasm, no node. 3// 1) BAD MIC (AGC boost): a quiet signal is boosted toward the target level (capped), MEASURED 4// 2) limiter: a loud signal is brought down to target and NEVER clips (|out| <= FULL) 5// 3) NOISE GATE: background-noise frames between speech are attenuated; speech frames preserved, MEASURED 6// 4) silence safety (neg): pure silence isn't blown up into noise; speech isn't gated 7// license_tier: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_gate_emit_lib.nx" 10import "nx_audio_enhance.nx" 11 12func g_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 13// a triangle wave of given peak amplitude into s[base..base+len) 14func fill_tri(s: *i64, base: i64, len: i64, peak: i64) -> i64 { 15 var i: i64 = 0 16 while i < len { let p: i64 = ((i % 16) - 8) * peak / 8; s[base + i] = p; i = i + 1 } 17 return 0 18} 19func maxabs(s: *i64, n: i64) -> i64 { var m: i64=0; var i: i64=0; while i<n { let a: i64=g_abs(s[i]); if a>m { m=a } i=i+1 } return m } 20 21func main() -> i64 { 22 g_puts("nx_audio_enhance gate (sovereign bad-mic AGC + noise gate, MEASURED)\n" as *u8) 23 var pass: i64 = 0; var total: i64 = 0 24 let TARGET: i64 = 6000 25 let MAXG: i64 = 800 // 8x max boost 26 let n: i64 = 768 27 let s: *i64 = sys_mmap(n*8) as *i64 28 29 // 1) BAD MIC: a quiet signal (peak ~800) boosted toward target 30 fill_tri(s, 0, n, 800) 31 let rms_in: i64 = ae_rms(s, n) 32 let g: i64 = ae_agc(s, n, TARGET, MAXG) 33 let rms_out: i64 = ae_rms(s, n) 34 g_puts(" [measure] bad mic: rms " as *u8); g_pn(rms_in); g_puts(" -> " as *u8); g_pn(rms_out); g_puts(" (gain x" as *u8); g_pn(g); g_puts("/100, target " as *u8); g_pn(TARGET); g_puts(")\n" as *u8) 35 pass = pass + g_check("AGC boosts a quiet bad mic (rms_out >> rms_in)" as *u8, rms_out > rms_in * 3); total=total+1 36 37 // 2) limiter: a loud signal -> down to ~target, never clips 38 fill_tri(s, 0, n, 30000) 39 ae_agc(s, n, TARGET, MAXG) 40 let mx: i64 = maxabs(s, n) 41 let rms_loud: i64 = ae_rms(s, n) 42 g_puts(" [measure] loud input: out rms=" as *u8); g_pn(rms_loud); g_puts(" peak=" as *u8); g_pn(mx); g_puts(" (<= 32767, no clip)\n" as *u8) 43 pass = pass + g_check("AGC attenuates loud + never clips" as *u8, (mx <= 32767) & (rms_loud < TARGET * 2)); total=total+1 44 45 // 3) NOISE GATE: noise frames (low) around speech frames (high) -> noise attenuated, speech kept 46 fill_tri(s, 0, 256, 300) // frames 0-3: background noise 47 fill_tri(s, 256, 256, 9000) // frames 4-7: speech 48 fill_tri(s, 512, 256, 300) // frames 8-11: background noise 49 let noise_before: i64 = ae_rms(s, 256) // first noise region 50 let speech_before: i64 = ae_rms(((s as i64) + 2048) as *i64, 256) 51 let gated: i64 = ae_noise_gate(s, n, 64, 4, 12) 52 let noise_after: i64 = ae_rms(s, 256) 53 let speech_after: i64 = ae_rms(((s as i64) + 2048) as *i64, 256) 54 g_puts(" [measure] noise region rms " as *u8); g_pn(noise_before); g_puts("->" as *u8); g_pn(noise_after); g_puts(" speech rms " as *u8); g_pn(speech_before); g_puts("->" as *u8); g_pn(speech_after); g_puts(" (frames gated=" as *u8); g_pn(gated); g_puts(")\n" as *u8) 55 var r3: i64 = 1 56 if noise_after * 3 > noise_before { r3 = 0 } // noise cut to < 1/3 57 if speech_after < speech_before - speech_before/8 { r3 = 0 } // speech preserved (within 12.5%) 58 pass = pass + g_check("noise gate: background attenuated, speech preserved" as *u8, r3); total=total+1 59 60 // 4) silence safety: all-zero -> AGC leaves it (no blowup); a pure-speech buffer is NOT gated 61 var i: i64 = 0; while i < n { s[i] = 0; i = i + 1 } 62 let gs: i64 = ae_agc(s, n, TARGET, MAXG) 63 var r4: i64 = 1 64 if gs != 100 { r4 = 0 } // silence -> gain 1.0, not max-boost-into-noise 65 if maxabs(s, n) != 0 { r4 = 0 } 66 fill_tri(s, 0, n, 9000) // uniform speech, no quiet frames 67 if ae_noise_gate(s, n, 64, 4, 12) != 0 { r4 = 0 } // nothing gated (all speech) 68 pass = pass + g_check("safety: silence not blown up; uniform speech not gated (neg)" as *u8, r4); total=total+1 69 70 g_puts("---- audio-enhance gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 71 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 72 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 73}