v0.2.16 — Audio smoothness: choppy-audio root causes fixed
"Occasionally choppy" audio — root causes found and fixed
Everything except the PortAudio callback ran on TD's main thread, so any main-thread hitch degraded audio twice over: the continuous params stream (the WS keepalive AND the server's pacing signal, against a 0.25 s lead floor) went silent, and incoming slices stopped being patched — the playhead played stale loop content. The biggest recurring hitch was ours: the hosted-session heartbeat ran a synchronous HTTPS poll (fresh TLS handshake, 10 s timeout) on the main thread every 5 seconds.
- Heartbeat HTTP off the main thread (
queue_worker.py) — status poll + auto-extend on a worker thread; queueleave()calls are fire-and-forget too. - Dedicated params pacer thread (
params_pacer.py, ~16 ms) — the keepalive survives TD frame hitches; also fixes a starved params snapshot and curve-override stomping. - Slices decode + patch on the WS recv thread (
binary_router.py) — the loop stays fresh through any main-thread stall; per-connection zstd; stale recv threads are detached on reconnect. - Audio-callback hygiene — no more logging from the audio thread on underrun (one underrun cascaded into several); the oversized-block fallback played whole blocks as silence — now a zero-allocation chunked fill.
- Smoothness telemetry (
telemetry.py) — a[health]line names the guilty subsystem if chop ever returns. - PortAudio dylib resolution fixed — freshly built .tox files computed a garbage dylib path (file pars are cleared at build time) and lost Python audio out entirely; the binary now resolves from the discovered
vendor/root.
Bug sweep
Connection-generation tagging (stale recv-thread events could tear down a freshly reconnected session), NaN/Inf params no longer emit invalid JSON into the keepalive, decode_slice validates payload length, failover uses the current API key, LoopBuffer channel-race guards, WSClient connect/close lifecycle lock, error-handling polish.
Tests: 181 (up from 105). Full details in CHANGELOG.md.
Install: download demonTD-v0.2.16.zip and keep demonTD.tox next to the vendor/ folder — the bare .tox without vendor/ will not load.