nx_phoneme_synth.nx
buildroot/runtime/nx_phoneme_synth.nx
about
nx_phoneme_synth.nx -- VOICE-CLONE-001 rung 5a: render a PHONEME SEQUENCE into
time-varying speech. This is the mechanism that turns a string of sounds into
a spoken WORD -- the difference between a sustained vowel and reading a book.
Source-filter, integer-only. Each phoneme is a DATA record (so the phoneme
inventory lives in a table, not in code -- "data not code"):
record = [ a1_F1, a1_F2, a1_F3, voiced(1/0), dur_samples ] (PH_REC words)
a1_Fk = the 2-pole resonator coefficient 2*r*cos(2*pi*Fk/fs) in Q15 for
formant k (precomputed per phoneme); shared pole radius r=0.95.
voiced = 1 -> glottal impulse train at f0 ; 0 -> noise (fricatives etc.)
The three formant resonators run in CASCADE and their state is CARRIED ACROSS
phoneme boundaries -- so when the formant targets change, the filter rings
smoothly into the new shape. That is coarticulation-lite: natural glides
between sounds instead of clicks, which is what makes a sequence sound spoken.
license_tier: ORIGINAL
module: nishi-core.audio.phoneme_synth
depends: (none -- pure integer DSP; mmap scratch only)
capability: AUDIO_ARTICULATION
dependencies 1 imports · 2 importers
imports: nx_syscalls_x86_64.nx
imported by: nx_phoneme_synth_gate.nxnx_voice_read.nx
structs
| none |
consts
| 22 | const PH_MAGIC_1103515245: i64 = 1103515245 |
| 23 | const PH_MAGIC_12345: i64 = 12345 |
| 24 | const PH_MAGIC_22695477: i64 = 22695477 |
| 25 | const PH_MAGIC_20000: i64 = 20000 |
| 26 | const PH_MAGIC_32000: i64 = 32000 |
| 28 | const PH_A2Q: i64 = 0 - 29573 // -r^2 in Q15, r=0.95 |
| 29 | const PH_AMP: i64 = 800 // glottal impulse amplitude |
| 30 | const PH_REC: i64 = 5 // i64 words per phoneme record |
functions
| 32 | func _ph_lcg(seed: i64) -> i64 { return (seed * PH_MAGIC_1103515245 + PH_MAGIC_12345) & 0x7fffffff } called by 1: nx_phoneme_synth |
| 36 | func nx_phoneme_synth(seq: *i64, n_phon: i64, f0_hz: i64, fs: i64, |