code wiki / _hdl_build / nx_denoise_spectral_gate.nx

nx_denoise_spectral_gate.nx source

↩ module page · 45 lines · 2797 B

1// nx_denoise_spectral_gate.nx -- proves + MEASURES sovereign spectral denoise (nx_denoise_spectral): estimate the 2// noise floor from a silence frame, then remove broadband noise from a speech+noise frame while keeping the speech. 3import "nx_syscalls.nx" 4import "nx_gate_emit_lib.nx" 5import "nx_denoise_spectral.nx" 6 7func tri8(i: i64) -> i64 { let p: i64 = i % 8; if p <= 4 { return p } return 8 - p } 8// power of bin `b` of a signal (copies it, doesn't modify) 9func bin_power(sig: *i64, n: i64, b: i64) -> i64 { 10 let re: *i64 = sys_mmap(n*8) as *i64; let im: *i64 = sys_mmap(n*8) as *i64 11 var i: i64=0; while i<n { re[i]=sig[i]; im[i]=0; i=i+1 } 12 nx_fft_forward(re, im, n) 13 return re[b]*re[b] + im[b]*im[b] 14} 15 16func main() -> i64 { 17 g_puts("nx_denoise_spectral gate (FFT noise-floor + spectral gate, MEASURED)\n" as *u8) 18 var pass: i64 = 0; var total: i64 = 0 19 let n: i64 = 16 20 21 // noise-only frame (silence): just the ±5 high-frequency hiss (Nyquist, bin 8) 22 let noise: *i64 = sys_mmap(n*8) as *i64; let nim: *i64 = sys_mmap(n*8) as *i64 23 var i: i64=0; while i<n { var v: i64 = 5; if (i & 1) == 1 { v = 0 - 5 } noise[i] = v; nim[i] = 0; i=i+1 } 24 let floor: i64 = ds_noise_floor(noise, nim, n, 512) // 2x the loudest noise bin 25 g_puts(" [measure] estimated noise floor (power) = " as *u8); g_pn(floor); g_puts("\n" as *u8) 26 27 // speech+noise frame: triangle speech (bin 2) + the ±5 hiss (bin 8) 28 let sig: *i64 = sys_mmap(n*8) as *i64; let sim: *i64 = sys_mmap(n*8) as *i64 29 i=0; while i<n { var v: i64 = 50 + 30*tri8(i); if (i & 1) == 0 { v = v + 5 } else { v = v - 5 } sig[i] = v; sim[i] = 0; i=i+1 } 30 let speech_before: i64 = bin_power(sig, n, 2) // the speech carrier 31 let hiss_before: i64 = bin_power(sig, n, 8) // the Nyquist hiss (noise) 32 33 ds_spectral_gate(sig, sim, n, floor, 20) // denoise (attenuate sub-floor bins to ~8%) 34 35 let speech_after: i64 = bin_power(sig, n, 2) 36 let hiss_after: i64 = bin_power(sig, n, 8) 37 g_puts(" [measure] speech bin: " as *u8); g_pn(speech_before); g_puts("->" as *u8); g_pn(speech_after); g_puts(" hiss bin: " as *u8); g_pn(hiss_before); g_puts("->" as *u8); g_pn(hiss_after); g_puts("\n" as *u8) 38 39 pass = pass + g_check("noise hiss bin attenuated >= 4x (removed during speech)" as *u8, hiss_after * 4 < hiss_before); total=total+1 40 pass = pass + g_check("speech carrier preserved (>= half its energy)" as *u8, speech_after * 2 > speech_before); total=total+1 41 42 g_puts("---- denoise-spectral gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 43 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 44 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 45}