code wiki / _hdl_build / nx_audio_critters.nx
nx_audio_critters.nx source
↩ module page · 106 lines · 5044 B
1// nx_audio_critters.nx -- DOG-TEST sweep sounds (squeak / chirp / whistle), COMPOSED from the canonical audio
2// engine (operator 2026-06-24: "make sure the most capabilities absorb when we dedup and keep the most s class").
3// DEDUP: the private sine table this organ used to carry is now absorbed INTO nx_audio_osc as osc_sine/osc_sweep
4// (the engine's "later rung"), so there is ONE sine implementation; this organ just composes osc_sweep. 48kHz +
5// high-frequency content (dogs hear far above humans; a dog whistle is ultrasonic). 16-bit PCM = lossless.
6// license_tier: ORIGINAL expect_exit: 0
7import "nx_audio_osc.nx" // osc_sweep -- the sine sweep, now canonical (absorbed from here)
8import "nx_audio_wav.nx" // wav_render_stereo, wav_save
9const K_MAGIC_4000: i64 = 4000
10const K_MAGIC_9000: i64 = 9000
11const K_MAGIC_4500: i64 = 4500
12const K_MAGIC_10000: i64 = 10000
13const K_MAGIC_6000: i64 = 6000
14const K_MAGIC_14000: i64 = 14000
15const K_MAGIC_3000: i64 = 3000
16const K_MAGIC_11000: i64 = 11000
17
18const SR: i64 = 48000 // Nyquist 24kHz: reaches the high/near-ultrasonic band dogs respond to
19const NS: i64 = 48000 // 1.0 s
20const AMP: i64 = 12000
21
22func cp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
23func cpn(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 c_abs(v: i64) -> i64 { if v<0 { return 0-v } return v }
32func peak(a: *i64, n: i64) -> i64 { var m: i64=0; var i: i64=0; while i<n { let v: i64=c_abs(a[i]); if v>m{m=v} i=i+1 } return m }
33func clr(a: *i64, n: i64) -> i64 { var i: i64=0; while i<n { a[i]=0; i=i+1 } return 0 }
34
35// compose osc_sweep into tmp, apply attack/decay envelope, place (add) into acc at off.
36func place_sweep(acc: *i64, tmp: *i64, off: i64, seglen: i64, f0: i64, f1: i64) -> i64 {
37 osc_sweep(tmp, seglen, f0, f1, SR, AMP)
38 let at: i64 = seglen/8; let dc: i64 = seglen/2
39 var i: i64 = 0
40 while i < seglen {
41 var e: i64 = 256
42 if i < at { if at>0 { e = 256*i/at } }
43 if i > seglen-dc { if dc>0 { e = 256*(seglen-i)/dc } }
44 if off+i < NS { acc[off+i] = acc[off+i] + ((tmp[i]*e)>>8) }
45 i = i + 1
46 }
47 return 0
48}
49func save_wav(L: *i64, R: *i64, path: *u8) -> i64 {
50 let wavbuf: *u8 = sys_mmap(44 + NS*4 + 64)
51 let wlen: i64 = wav_render_stereo(L, R, NS, SR, wavbuf)
52 return wav_save(path, wavbuf, wlen)
53}
54
55func mk_squeak(acc: *i64, tmp: *i64) -> i64 {
56 clr(acc, NS)
57 let n: i64 = SR*12/100
58 place_sweep(acc, tmp, SR/40, n/2, K_MAGIC_4000, K_MAGIC_9000)
59 place_sweep(acc, tmp, SR/40 + n/2, n/2, K_MAGIC_9000, K_MAGIC_4000)
60 let g: i64 = SR/40 + n + SR/14
61 place_sweep(acc, tmp, g, n/2, K_MAGIC_4500, K_MAGIC_10000)
62 place_sweep(acc, tmp, g + n/2, n/2, K_MAGIC_10000, K_MAGIC_4500)
63 return 0
64}
65func mk_chirp(acc: *i64, tmp: *i64) -> i64 {
66 clr(acc, NS)
67 let n: i64 = SR*6/100
68 var k: i64 = 0; var off: i64 = SR/30
69 while k < 3 { place_sweep(acc, tmp, off, n, K_MAGIC_6000, K_MAGIC_14000); off = off + n + SR*9/100; k = k + 1 }
70 return 0
71}
72func mk_whistle(acc: *i64, tmp: *i64) -> i64 {
73 clr(acc, NS)
74 let n: i64 = SR*6/10
75 place_sweep(acc, tmp, SR/30, n/2, K_MAGIC_3000, K_MAGIC_11000)
76 place_sweep(acc, tmp, SR/30 + n/2, n/2, K_MAGIC_11000, K_MAGIC_3000)
77 return 0
78}
79
80func main() -> i64 {
81 cp("nx_audio_critters: dog squeak/chirp/whistle COMPOSED from nx_audio_osc.osc_sweep (deduped sine), 48kHz\n" as *u8)
82 let acc: *i64 = sys_mmap(NS*8) as *i64
83 let tmp: *i64 = sys_mmap(NS*8) as *i64
84 let R: *i64 = sys_mmap(NS*8) as *i64
85 var ok: i64 = 0
86
87 mk_squeak(acc, tmp)
88 var i: i64 = 0; while i < NS { R[i] = acc[i]; i = i + 1 }
89 let s1: i64 = save_wav(acc, R, "web_assets/ng_dog_squeak.wav\x00" as *u8)
90 cp(" squeak peak=" as *u8); cpn(peak(acc,NS)); cp(" bytes=" as *u8); cpn(s1); cp("\n" as *u8); if s1>44 { if peak(acc,NS)>1000 { ok=ok+1 } }
91
92 mk_chirp(acc, tmp)
93 i = 0; while i < NS { R[i] = acc[i]; i = i + 1 }
94 let s2: i64 = save_wav(acc, R, "web_assets/ng_dog_chirp.wav\x00" as *u8)
95 cp(" chirp peak=" as *u8); cpn(peak(acc,NS)); cp(" bytes=" as *u8); cpn(s2); cp("\n" as *u8); if s2>44 { if peak(acc,NS)>1000 { ok=ok+1 } }
96
97 mk_whistle(acc, tmp)
98 i = 0; while i < NS { R[i] = acc[i]; i = i + 1 }
99 let s3: i64 = save_wav(acc, R, "web_assets/ng_dog_whistle.wav\x00" as *u8)
100 cp(" whistle peak=" as *u8); cpn(peak(acc,NS)); cp(" bytes=" as *u8); cpn(s3); cp("\n" as *u8); if s3>44 { if peak(acc,NS)>1000 { ok=ok+1 } }
101
102 cp(" verdict=" as *u8)
103 if ok == 3 { cp("GREEN (3 sweeps via the canonical osc_sweep -- one sine, no dup; 48kHz lossless)\n" as *u8); sys_exit(0); return 0 }
104 cp("RED\n" as *u8)
105 sys_exit(1); return 1
106}