Commit Graph

43 Commits

Author SHA1 Message Date
tes 43b3a1a0f1 Test 4a scaffold: csproj for tests/04a-realtime-oneshot-cs 2026-06-12 19:00:57 +00:00
tes e96b6ffd95 Test 4a: implementation plan
Five tasks: scaffold csproj → write full Program.cs (WS + audio
streams + channels + server VAD round-trip) → bin/probe-cs-4a with
~/.openai_key precondition → one-time Pi key setup → hardware
verification against the spec's 8 pass criteria.
2026-06-12 17:34:25 +00:00
tes dea126f994 Test 4a: spec — OpenAI Realtime API one-shot voice round-trip
Boot → beep → user speaks → server VAD ends turn → assistant audio
plays back → exit 0. No wakeword, no loop, no state machine.

Splits Test 4 into 4a (this spec) and 4b (wakeword + loop + 16↔24 kHz
coexistence, future). 4a debugs the OpenAI Realtime surface — auth, WS
handshake, session.update payload, server VAD, base64 audio, streaming-
length output-stream cleanup — in isolation from 4b's harder concurrency.
2026-06-12 16:59:10 +00:00
tes cbb47d1465 Findings: Test 3 C# full-cycle probe outcome 2026-06-12 13:56:16 +00:00
tes a7d408e903 Test 3: scale playback timeout to buffer length (was hardcoded 2 s)
FireAndForgetPlayback's cleanup task had the same 2 s done.Wait timeout
as the beep cleanup. Beep is 200 ms so 2 s is generous; recording
playback is 5 s so the timeout fired mid-playback, cleanup ran
stream.Stop(), and the audio cut at ~2.2 s. Timeout is now
recording-duration + 2 s.
2026-06-12 13:54:16 +00:00
tes 1d9a417cfc Test 3: bin/probe-cs-3 deploy script 2026-06-12 13:40:55 +00:00
tes 070cc0767a Test 3: per-cycle PlaybackDoneFlag + log timeout in fire-and-forget cleanup
Stale Set() from a delayed cleanup task could short-circuit a future
PLAYBACK state; new flag per cycle avoids the cross-cycle leak. Also
log when the 2 s done.Wait timeout fires so silent PortAudio callback
faults are visible during hardware debugging.
2026-06-12 13:38:09 +00:00
tes 5a498e9c91 Test 3: full-cycle state machine (IDLE/BEEPING/RECORDING/PLAYBACK) 2026-06-12 13:31:25 +00:00
tes 222d58baeb Test 3: copy WakewordModel + models from Test 2, add Reset() 2026-06-12 13:25:40 +00:00
tes 6fa2779ea1 Test 3 scaffold: csproj for tests/03-full-cycle-cs 2026-06-12 13:22:23 +00:00
tes 14690484de Test 3 plan: implementation steps for full-cycle C# probe
Five tasks: scaffold csproj, copy WakewordModel + models with Reset(),
write Program.cs with the four-state machine, write bin/probe-cs-3
deploy script, and hardware verification on the Pi.
2026-06-12 13:19:18 +00:00
tes e9730c7e50 Test 3 spec: full-cycle C# probe (wakeword + record + playback)
State machine on a single persistent input stream: IDLE → BEEPING →
RECORDING → PLAYBACK → IDLE. Detector gated during non-IDLE states;
WakewordModel.Reset() called on IDLE re-entry to clear stale ring
buffers and re-arm the warmup guard.
2026-06-12 13:13:59 +00:00
tes b6d9f9a1cf WakewordModel: print shapes at startup + tidy mel-shape comment
Add PrintShapes() helper that writes input/output name, shape, and dtype
for each InferenceSession to stderr at construction time, prefixed with
[wakeword-model]. Called after each of the three session creations so the
geometry is visible on first run without grep-ing logs.

Also rephrase the stale "FIXED:" comment on the mel Dimensions[2] indexing
to plain explanatory text that describes the current invariant.
2026-06-12 12:19:59 +00:00
tes 7d808e6ade Findings: C# wakeword probe outcome 2026-06-12 12:13:01 +00:00
tes 9b63e298d3 Beep cleanup: start before Task.Run + Wait timeout to avoid orphaned task 2026-06-12 12:06:48 +00:00
tes 14e862f50a Beep on detection: fire-and-forget OutputStream, input keeps flowing 2026-06-12 12:03:14 +00:00
tes 2e830eaed4 Live wakeword loop: PortAudio input + queue + threshold detection
Replaces the Task 3 smoke-test Program.cs with the full inference loop:
- PA_ALSA_PLUGHW=1 and ORT_LOGGING_LEVEL=3 via both Environment.SetEnvironmentVariable
  and Libc.setenv (P/Invoke) per the Test 1 findings.md env-var gotcha.
- OrtEnv.CreateInstanceWithOptions with ORT_LOGGING_LEVEL_ERROR to suppress
  early GPU-discovery warnings from device_discovery.cc in ORT 1.26.0
  (the env var alone does not silence these; CreateInstanceWithOptions does).
- Callback-driven PortAudio input stream at 16 kHz / Int16 / 1280 frames/block.
- BlockingCollection<short[]>(16) queue; per-call new short[1280] allocation (no races).
- Main loop: Take() -> WakewordModel.Predict() -> threshold >= 0.5 with 1.0s cooldown
  -> DETECTED alexa score=... t=...s. No beep (Task 5 adds it).
- Console.CancelKeyPress -> cts.Cancel() -> graceful stream.Stop() + model.Dispose()
  + PortAudio.Terminate().
2026-06-12 11:57:54 +00:00
tes b43a1ce17f WakewordModel: clean up stale comment, clarify ring-fill boundary case 2026-06-12 11:43:28 +00:00
tes e18aed53d7 WakewordModel: port openwakeword streaming pipeline (mel→emb→cls)
Ports openwakeword 0.6.0's AudioFeatures._streaming_features() and
Model.predict() to C# / Microsoft.ML.OnnxRuntime 1.26.0.

Bug fixed vs plan: actual melspectrogram.onnx output shape is
(1, 1, n_frames, 32) — n_frames lives at Dimensions[2], not [1].
Access pattern corrected to melOut[0, 0, f, b].

Smoke test on Pi: 25/50 non-zero silence scores, max ≈ 0.000064
(matches Python reference: 45/50 non-zero, same magnitude).
"Predict pipeline ran without throwing." confirmed.
2026-06-12 11:37:53 +00:00
tes bea35c8f1c Add bin/probe-cs-2: build + scp + run the C# wakeword probe on the Pi 2026-06-12 11:29:22 +00:00
tes 849ad47230 Scaffold C# wakeword probe: vendored ONNX models + ORT sanity spike
Models sourced from openwakeword==0.6.0 on the Pi (alexa_v0.1.onnx
vendored as alexa.onnx). ORT 1.26.0 loads all three on linux-arm64
self-contained publish; libonnxruntime.so confirmed in publish dir.

SHA-256:
  melspectrogram.onnx  ba2b0e0f8b7b875369a2c89cb13360ff53bac436f2895cced9f479fa65eb176f
  embedding_model.onnx 70d164290c1d095d1d4ee149bc5e00543250a7316b59f31d056cff7bd3075c1f
  alexa.onnx           6ff566a01d12670e8d9e3c59da32651db1575d17272a601b7f8a39283dfbae3e
2026-06-12 11:24:46 +00:00
tes fe15a009b3 Plan: C# probe re-implementing Test 2 (wakeword) on the Pi 2026-06-12 11:19:22 +00:00
tes 815389ecc2 Spec: C# probe re-implementing Test 2 (wakeword) on the Pi 2026-06-12 10:55:13 +00:00
tes bfd8a05734 Add kickoff prompt for Test 2 (wakeword) C# probe 2026-06-12 10:12:34 +00:00
tes 8fdbedd28f CLAUDE.md: point new sessions at findings.md 2026-06-12 10:11:19 +00:00
tes 7c4621b3b7 Findings: C# record-play probe outcome 2026-06-12 10:11:19 +00:00
tes 87a85db38d Playback: append OutputStream playback of recorded buffer 2026-06-12 10:00:59 +00:00
tes e2bd845abe Record loop: callback InputStream + RMS meter + WAV write 2026-06-12 09:54:43 +00:00
tes 1d08f49204 Add WavWriter: mono PCM16 RIFF writer for the C# probe 2026-06-12 09:38:55 +00:00
tes fec222b6dc Fix bin/probe-cs file mode to executable (100755) 2026-06-12 09:35:47 +00:00
tes 9e8cee7a16 Add bin/probe-cs: build + scp + run the C# probe on the Pi 2026-06-12 09:33:39 +00:00
tes d744a6318f Scaffold C# record-play probe + PortAudio device-list spike 2026-06-12 09:29:26 +00:00
tes 7b1417e885 Plan: use scp instead of rsync in bin/probe-cs (no rsync in build env) 2026-06-12 09:26:13 +00:00
tes 91a1f04b44 Plan: C# probe re-implementing Test 1 (record/play) on the Pi 2026-06-12 09:23:46 +00:00
tes b7fda48e91 Spec: C# probe re-implementing Test 1 (record/play) on the Pi 2026-06-12 09:18:26 +00:00
tes 8bc08f451d Prototype phase findings 2026-06-11 15:05:31 +00:00
tes 46f05bc120 Test 2: detection threshold + cooldown + beep 2026-06-11 14:56:54 +00:00
tes 2cea1e8de0 Test 2 skeleton: openwakeword loads via --no-deps split, scores print 2026-06-11 14:54:45 +00:00
tes a301345ec4 Test 1: add playback step — record-play loop complete 2026-06-11 14:38:41 +00:00
tes 431fe7cfbc Test 1: record 5s from USB mic with RMS meter (PA_ALSA_PLUGHW for resampling) 2026-06-11 14:35:45 +00:00
tes 99be524fab Deploy helper: rsync, venv, run main.py over SSH 2026-06-11 14:27:54 +00:00
tes 24b41ac760 Bootstrap Pi system packages (portaudio, sndfile, venv) 2026-06-11 14:24:21 +00:00
tes e2712be452 Spec: voice assistant prototype phase 2026-06-11 14:18:44 +00:00