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}