code wiki / _hdl_build / nx_audio_bark.nx

nx_audio_bark.nx source

↩ module page · 143 lines · 5980 B

1// nx_audio_bark.nx -- dog BARK + GROWL via SOURCE-FILTER synthesis, COMPOSED from the canonical engine (operator 2// 2026-06-24: dedup must ABSORB capabilities + keep the most s-class). The formant source-filter (pitched glottal 3// pulse train -> driven formant-resonator bandpasses) is the NEW capability this organ keeps. DEDUP: cosine now 4// comes from nx_audio_osc.osc_cos_s (one cosine), and the growl rasp uses nx_audio_sfx.sfx_noise (xorshift -- the 5// engine's good noise, replacing this organ's old inferior LCG). 48kHz, peak-normalized no-clip, lossless PCM. 6// First-iteration timbre -- tune by ear. license_tier: ORIGINAL expect_exit: 0 7import "nx_audio_osc.nx" // osc_cos_s (deduped cosine for the formant pole) 8import "nx_audio_sfx.nx" // sfx_noise (xorshift noise -- replaces the old LCG) 9import "nx_audio_wav.nx" // wav_render_stereo, wav_save 10const K_MAGIC_411774: i64 = 411774 11const K_MAGIC_62915: i64 = 62915 12const K_MAGIC_1700: i64 = 1700 13const K_MAGIC_2600: i64 = 2600 14const K_MAGIC_60000: i64 = 60000 15const K_MAGIC_7777: i64 = 7777 16const K_MAGIC_1100: i64 = 1100 17 18const SR: i64 = 48000 19const NS: i64 = 48000 // 1.0 s 20const AMP: i64 = 12000 21 22func bp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 23func bpn(v: i64) -> i64 { 24 let b: *u8 = sys_mmap(28); var x: i64=v 25 if x<0 { b[0]=45; sys_write(1,b,1); x=0-x } 26 if x==0 { b[0]=48; sys_write(1,b,1); return 0 } 27 var d: i64=0; var y: i64=x; while y>0 { d=d+1; y=y/10 } 28 var i: i64=d-1; y=x; while i>=0 { b[i]=(48+(y%10)) as u8; y=y/10; i=i-1 } 29 sys_write(1,b,d); return 0 30} 31func b_abs(v: i64) -> i64 { if v<0 { return 0-v } return v } 32 33// driven 2nd-order bandpass at F Hz (r = pole radius, Q16); ADD output into acc[]. Cosine via the canonical osc_cos_s. 34func add_formant(acc: *i64, src: *i64, n: i64, F: i64, r: i64) -> i64 { 35 let om: i64 = (K_MAGIC_411774 * F) / SR 36 let c: i64 = osc_cos_s(om) 37 let a1: i64 = (2 * r * c) >> 16 38 let a2: i64 = (r * r) >> 16 39 var y1: i64 = 0; var y2: i64 = 0 40 var i: i64 = 0 41 while i < n { 42 let yn: i64 = ((a1 * y1) >> 16) - ((a2 * y2) >> 16) + src[i] 43 acc[i] = acc[i] + yn 44 y2 = y1; y1 = yn 45 i = i + 1 46 } 47 return 0 48} 49func clr(a: *i64, n: i64) -> i64 { var i: i64=0; while i<n { a[i]=0; i=i+1 } return 0 } 50func peak(a: *i64, n: i64) -> i64 { var m: i64=0; var i: i64=0; while i<n { let v: i64=b_abs(a[i]); if v>m{m=v} i=i+1 } return m } 51func normalize(a: *i64, n: i64) -> i64 { 52 let pk: i64 = peak(a, n); if pk == 0 { return 0 } 53 var i: i64 = 0; while i < n { a[i] = a[i] * AMP / pk; i = i + 1 } 54 return pk 55} 56func env(a: *i64, n: i64) -> i64 { 57 let at: i64 = n/12; let dc: i64 = n/2 58 var i: i64 = 0 59 while i < n { 60 var e: i64 = 256 61 if i < at { if at>0 { e = 256*i/at } } 62 if i > n-dc { if dc>0 { e = 256*(n-i)/dc } } 63 a[i] = (a[i] * e) >> 8 64 i = i + 1 65 } 66 return 0 67} 68func build_woof(acc: *i64, src: *i64, wn: i64) -> i64 { 69 clr(acc, wn); clr(src, wn) 70 var i: i64 = 0; var nxt: i64 = 0 71 while i < wn { 72 let pitch: i64 = 340 - (80 * i) / wn 73 let period: i64 = SR / pitch 74 if i >= nxt { src[i] = 300; nxt = i + period } 75 i = i + 1 76 } 77 add_formant(acc, src, wn, 600, K_MAGIC_62915) 78 add_formant(acc, src, wn, K_MAGIC_1700, K_MAGIC_62915) 79 add_formant(acc, src, wn, K_MAGIC_2600, K_MAGIC_60000) 80 env(acc, wn) 81 return 0 82} 83func save_wav(L: *i64, R: *i64, path: *u8) -> i64 { 84 let wavbuf: *u8 = sys_mmap(44 + NS*4 + 64) 85 let wlen: i64 = wav_render_stereo(L, R, NS, SR, wavbuf) 86 return wav_save(path, wavbuf, wlen) 87} 88 89func main() -> i64 { 90 bp("nx_audio_bark: source-filter BARK + GROWL composed from osc_cos_s + sfx_noise (deduped), 48kHz\n" as *u8) 91 let acc: *i64 = sys_mmap(NS*8) as *i64 92 let src: *i64 = sys_mmap(NS*8) as *i64 93 let nz: *i64 = sys_mmap(NS*8) as *i64 94 let R: *i64 = sys_mmap(NS*8) as *i64 95 var ok: i64 = 0 96 97 // BARK: two woofs ("wuff-wuff") 98 clr(acc, NS) 99 let wn: i64 = SR*22/100 100 let woof: *i64 = sys_mmap(NS*8) as *i64 101 let wsrc: *i64 = sys_mmap(NS*8) as *i64 102 build_woof(woof, wsrc, wn) 103 var i: i64 = 0; let o1: i64 = SR/20 104 while i < wn { acc[o1+i] = woof[i]; i = i + 1 } 105 let o2: i64 = o1 + wn + SR*9/100 106 i = 0; while i < wn { if o2+i < NS { acc[o2+i] = woof[i] } i = i + 1 } 107 normalize(acc, NS) 108 i = 0; while i < NS { R[i] = acc[i]; i = i + 1 } 109 let sb: i64 = save_wav(acc, R, "web_assets/ng_dog_bark.wav\x00" as *u8) 110 bp(" bark peak=" as *u8); bpn(peak(acc,NS)); bp(" bytes=" as *u8); bpn(sb); bp("\n" as *u8); if sb>44 { if peak(acc,NS)>1000 { ok=ok+1 } } 111 112 // GROWL: low glottal buzz + xorshift noise (sfx_noise) through 2 formants + triangle roughness 113 clr(acc, NS); clr(src, NS) 114 sfx_noise(nz, NS, 60, K_MAGIC_7777) 115 i = 0; var gnxt: i64 = 0 116 while i < NS { 117 if i >= gnxt { src[i] = src[i] + 260; gnxt = i + SR/95 } 118 src[i] = src[i] + nz[i] 119 i = i + 1 120 } 121 add_formant(acc, src, NS, 380, K_MAGIC_62915) 122 add_formant(acc, src, NS, K_MAGIC_1100, K_MAGIC_60000) 123 let amp_per: i64 = SR / 28 124 i = 0 125 while i < NS { 126 let ph: i64 = i % amp_per 127 var tri: i64 = ph * 512 / amp_per 128 if tri > 256 { tri = 512 - tri } 129 let amf: i64 = 110 + (tri * 146) / 256 130 acc[i] = (acc[i] * amf) >> 8 131 i = i + 1 132 } 133 env(acc, NS) 134 normalize(acc, NS) 135 i = 0; while i < NS { R[i] = acc[i]; i = i + 1 } 136 let sg: i64 = save_wav(acc, R, "web_assets/ng_dog_growl.wav\x00" as *u8) 137 bp(" growl peak=" as *u8); bpn(peak(acc,NS)); bp(" bytes=" as *u8); bpn(sg); bp("\n" as *u8); if sg>44 { if peak(acc,NS)>1000 { ok=ok+1 } } 138 139 bp(" verdict=" as *u8) 140 if ok == 2 { bp("GREEN (bark+growl via formant + deduped osc_cos_s/sfx_noise, 48kHz, normalized lossless)\n" as *u8); sys_exit(0); return 0 } 141 bp("RED\n" as *u8) 142 sys_exit(1); return 1 143}