Implements the first working feature: the device records audio to the microSD
card, toggled by the button, with LED status and per-recording JSON metadata.
What changed:
- firmware/src/audio.{h,cpp}: mic capture via the core-bundled ESP_I2S. Dev board
uses I2S standard mode (INMP441/ICS-43434); XIAO uses PDM mode (onboard mic).
Presents 16-bit PCM mono to callers regardless of board.
- firmware/src/storage.{h,cpp}: microSD on a dedicated HSPI bus + a streaming
WavWriter that writes a 44-byte PCM header and patches RIFF/data sizes on close;
plus sidecar JSON metadata writer.
- firmware/src/recorder.{h,cpp}: idle/recording state machine; creates
/recordings/<id>.wav, pumps mic chunks in on update(), finalises + writes
<id>.json (Recording schema from api/openapi.yaml) on stop.
- firmware/src/ux.{h,cpp}: debounced button (short press toggles) + status LED
patterns (idle/recording/error), active-low aware.
- firmware/src/main.cpp: wires ux + recorder; loop toggles on button and drains
the mic while recording.
- firmware/include/audio_config.h: 16 kHz mono 16-bit, chunk size, rec dir.
- firmware/include/pins.h: added XIAO PDM mic + onboard SD pins, LED active-low flag.
- state/: TODO, ARCHITECTURE, NOTES updated for M1 and the deferred follow-ups.
Why:
- Recording is the foundation every later milestone (transfer, upload, transcription)
builds on. Kept dependency-free (only core-bundled ESP_I2S + SD) for simple CI builds.
Notes:
- Not compiled locally (no PlatformIO on the dev host) or hardware-verified; Forgejo
Actions CI builds both board profiles. Follow-ups tracked in state/TODO.md:
INMP441 16-bit level calibration, and real NTP timestamps (ids are uptime-based
until M2 brings WiFi/NTP).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.8 KiB
2.8 KiB
TODO
The current state of play. Keep it honest and current; this is what the next session reads to know what to do. Move items between sections as they progress.
In progress
- M1 Firmware recording core - code complete on
feature/fw-recorder-core, in PR. I2S/PDM mic capture -> WAV on microSD, button start/stop, LED status, sidecar JSON metadata. Not yet compiled locally (no PlatformIO here) or hardware-verified; relies on Forgejo Actions CI to build both board profiles.
Pending (roughly in build order)
- M2 On-device WiFi + REST API: WiFi manager, mDNS, list/get/download(range)/delete
recordings, device status. Implements
api/openapi.yamldevice paths. (branchfeature/fw-rest-api) - M3 Independent uploader: NVS config store, charge/VBUS detect -> powered mode,
S3-compatible + WebDAV upload of audio + metadata. (branch
feature/fw-uploader) - M4 BLE GATT: device info, battery, record control, WiFi provisioning, status
notifications; hand-off to WiFi for transfer. (branch
feature/fw-ble) - M5 Server ingest + transcription: FastAPI ingest from object store/upload, store,
faster-whisper transcription, DB, exports (audio/TXT/SRT/VTT/JSON). REST API.
(branch
feature/server-ingest-stt) - M6 Server summaries: Ollama LLM summary + action items, Markdown export.
(branch
feature/server-summary) - M7 Flutter app: BLE provisioning, device dashboard, library from server API,
playback, transcript/summary view, export/share, settings.
(branch
feature/app-mvp) - M8 3D case: parametric OpenSCAD enclosure fit to the BOM board + battery; print/fit.
(branch
feature/case-v1) - M9 Hardening + OTA: API auth, credential handling, OTA update, docs handoff.
(branch
feature/hardening-ota)
Done
- M0 Scaffold - repo, licences, state docs, BOM, OpenAPI, skeletons, CI
(merged to
main, 2026-07-03) - Create Forgejo repo
laurence/openscribe(public, main) - 2026-07-03 - Decide hardware, sync model, AI stack, app platform, storage, licensing (see DECISIONS.md) - 2026-07-03
Follow-ups (deferred, do when convenient)
- Audio calibration: INMP441 emits 24-bit samples in a 32-bit slot. M1 reads in
16-bit mode (usable for speech, may be quiet). If levels are low on the dev build,
capture 32-bit and right-shift into int16 in
audio.cpp. - Real timestamps: M1 ids/
started_atare uptime-based (no RTC/NTP yet). M2 adds NTP over WiFi; switch ids andstarted_atto real UTC then.
Blocked / waiting
- Physical build + on-device verification - waiting on parts from
hardware/BOM.md. Until parts arrive, firmware is validated by CI build (Forgejo Actions) of both board profiles, not on real hardware.