code wiki / _hdl_build / nx_squeaker.nx

nx_squeaker.nx

buildroot/runtime/_hdl_build/nx_squeaker.nx

14542 B290 linesdepth 4pulls 4 transitivereach 1 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_squeaker.nx -- THE TOY. A dog-toy ball that makes its noise because a dog's jaw compresses it. Operator 2026-07-25: "a dog toy ball that is designed to make the noise when compressed by a dog's mouth". This is the physical model of that object, from the bite down: jaw force -> shell compression -> air displaced -> chamber pressure -> reed valve flutters -> flow through the neck -> radiated sound Every stage is a real physical quantity in manufacturable units (newtons, millimetres, cubic millimetres), because the whole point of rung R5 is to INVERT this model and hand back a geometry somebody can actually mould. A model in arbitrary units cannot produce a spec. WHY THE PITCH GLIDES, AND WHY THAT IS THE PRODUCT. The chamber is a Helmholtz resonator: w = c * sqrt(A_neck / (V_chamber * L_neck)) A dog's bite REMOVES volume from the chamber, and w rises as V falls. So the sound a dog produces by biting is not a fixed beep -- it is a rising squeal whose contour is drawn by the dog's own jaw. Prey distress calls rise in pitch too. That correspondence is the reason this object can sound like something worth catching instead of like a rubber toy, and it is measurable: the gate checks that a harder bite raises the pitch and that a bigger chamber lowers it, both in the direction the physics demands rather than the direction I would like. THE REED IS THE SAME PHYSICS AS A VOCAL FOLD. A squeaker tongue and a larynx are both elastic valves driven unstably by the flow past them, so this organ does not implement a second oscillator: it drives nx_vox_source with the chamber pressure and takes its flow back. That reuse is not just DRY, it is why the toy inherits nonlinear regimes -- the roughness, the pitch breaks and the cycle-to-cycle variation that stop a dog habituating -- from a model already gated at 13/13. Integer fixed-point, deterministic. license_tier: ORIGINAL expect_exit: 0

dependencies 3 imports · 1 importers

nx_syscalls.nx nx_isqrt.nx nx_vox_source.nx nx_squeaker.nx nx_squeaker_design.nx

imports: nx_syscalls.nxnx_isqrt.nxnx_vox_source.nx

imported by: nx_squeaker_design.nx

structs

none

consts

34const SQ_Q: i64 = 65536
35const SQ_C: i64 = 343000 // speed of sound, mm/s
38const SQ_P_V0: i64 = 0 // mm^3 chamber volume at rest
39const SQ_P_AN_X100: i64 = 1 // mm^2 neck cross-section, x100
40const SQ_P_LN_X100: i64 = 2 // mm neck length, x100
41const SQ_P_DVDF_X100: i64 = 3 // mm^3/N volume displaced per newton of bite, x100 (shell durometer)
42const SQ_P_BITE_N: i64 = 4 // N peak bite force
43const SQ_P_RISE_MS: i64 = 5 // ms jaw closing time
44const SQ_P_HOLD_MS: i64 = 6 // ms
45const SQ_P_REL_MS: i64 = 7 // ms
46const SQ_P_ZETA: i64 = 8 // Q16 acoustic damping of the resonator
47const SQ_P_REED_F0: i64 = 9 // Hz reed natural frequency
48const SQ_P_REED_DET: i64 = 10 // Hz second-reed detune -> nonlinear regimes
49const SQ_P_REED_ZETA: i64 = 11 // Q16
50const SQ_P_FLOWGAIN: i64 = 12 // Q16 reed opening -> neck conductance
51const SQ_P_PGAIN: i64 = 13 // Q16 chamber pressure -> reed drive
52const SQ_P_OVS: i64 = 14
53const SQ_P_SEED: i64 = 15
54const SQ_P_JITTER: i64 = 16 // Q16
55const SQ_P_N: i64 = 17
84const SQ_S_P: i64 = 0 // chamber overpressure (Q16, normalised)
85const SQ_S_U: i64 = 1 // neck volume flow (Q16)
86const SQ_S_VOL: i64 = 2 // current chamber volume, mm^3
87const SQ_S_N: i64 = 3
133const SQ_D_PPEAK: i64 = 0
134const SQ_D_VEND: i64 = 1
135const SQ_D_CYC: i64 = 2
136const SQ_D_N: i64 = 3

functions

57func sq_defaults(p: *i64) -> i64
called by 1: sqd_to_params
93func sq_omega(p: *i64, vol: i64, sr: i64) -> i64
called by 1: sq_render calls 1: nx_isqrt
110func sq_bite(p: *i64, i: i64, sr: i64) -> i64
called by 1: sq_render
138func sq_render(out: *i64, n: i64, rate: i64, p: *i64, diag: *i64) -> i64
250func sq_render_audio(out: *i64, n: i64, rate: i64, p: *i64, amp: i64, diag: *i64) -> i64
calls 1: sq_render
275func sq_f_at(p: *i64, vol: i64) -> i64
called by 2: sq_f_restsq_f_bitten calls 1: nx_isqrt
283func sq_vol_bitten(p: *i64) -> i64
called by 1: sq_f_bitten
289func sq_f_rest(p: *i64) -> i64 { return sq_f_at(p, p[SQ_P_V0]) }
called by 1: sqd_card calls 1: sq_f_at
290func sq_f_bitten(p: *i64) -> i64 { return sq_f_at(p, sq_vol_bitten(p)) }
called by 1: sqd_card calls 2: sq_f_atsq_vol_bitten