feat(P4): media_manager vrai playback WAV + /game/media/play #9

Merged
electron merged 4 commits from feat/p4-media-wav-playback into main 2026-06-13 14:44:30 +00:00
Owner

P4 slice 1 : remplace le stub media_manager par du vrai streaming WAV vers le MAX98357A (via lI2S TX de voice_pipeline), + endpoint POST /game/media/play pour declencher une cue depuis la gateway/atelier.

Valide sur Freenove : upload WAV (/game/file) -> POST /game/media/play -> 32000 B streames en ~1006 ms (cadence DMA = duree fichier). Parse RIFF 16-bit PCM mono/stereo, downmix, volume logiciel, tache dediee.

Empile sur #8 (base = fix/box3-spiffs-channel). Suites P4 : MP3, montage SD, mutex TX TTS/musique.

Generated with Claude Code

P4 slice 1 : remplace le stub media_manager par du vrai streaming WAV vers le MAX98357A (via lI2S TX de voice_pipeline), + endpoint POST /game/media/play pour declencher une cue depuis la gateway/atelier. Valide sur Freenove : upload WAV (/game/file) -> POST /game/media/play -> 32000 B streames en ~1006 ms (cadence DMA = duree fichier). Parse RIFF 16-bit PCM mono/stereo, downmix, volume logiciel, tache dediee. Empile sur #8 (base = fix/box3-spiffs-channel). Suites P4 : MP3, montage SD, mutex TX TTS/musique. Generated with Claude Code
electron changed target branch from fix/box3-spiffs-channel to main 2026-06-13 14:44:16 +00:00
electron added 4 commits 2026-06-13 14:44:16 +00:00
Remplace le stub de media_manager_play() (qui simulait 2 s) par un vrai
streaming audio :
- parse_wav_header : RIFF/WAVE 16-bit PCM mono/stéréo, positionne sur data.
- playback_task : lit le WAV par chunks et le pousse au MAX98357A via
  l'I2S TX de voice_pipeline (play_start/chunk/end), avec downmix stéréo→mono
  et volume logiciel. Tâche dédiée (non bloquante), stop coopératif.
- media_manager_stop() attend la fin de la tâche.

Ajoute POST /game/media/play {path} dans game_endpoint pour déclencher une
lecture (gateway/atelier → cue audio), sans passer par une décision NPC.

Validé sur Freenove : upload WAV via /game/file → POST /game/media/play →
play_start sr=16000 → 32000 B streamés en ~1006 ms (cadence DMA temps réel,
= durée du fichier) → play_end. MP3 + montage SD = slices P4 suivantes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(p4): montage microSD (SDMMC 1-bit) sur /sdcard
CI / platformio (pull_request) Failing after 6m0s
a8f0210567
Nouveau composant sd_storage : monte la carte microSD du Freenove en SDMMC
1-bit (CMD=38, CLK=39, D0=40 — pinout FREENOVE_SDMMC_* du firmware Arduino)
sur /sdcard via esp_vfs_fat_sdmmc_mount. Best-effort au boot : carte absente
= non fatal, fallback LittleFS. Lève le plafond LittleFS 5 Mo pour les assets.

Validé sur Freenove : carte ~3839 MiB montée à /sdcard au boot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(p4): brancher media_manager + /game/file sur /sdcard
CI / platformio (pull_request) Failing after 3m39s
8a58c7d92b
- media_manager resolve_play_path : un chemin relatif préfère désormais
  /sdcard/music/<f> quand il existe (asset store SD), fallback LittleFS.
  Les chemins absolus (/sdcard/... | /littlefs/...) passent inchangés.
- /game/file : route le préfixe `sd/<…>` → /sdcard/<…> (≤8 Mio, exige la
  carte montée) en plus de `apps/<…>` → /littlefs/apps/ (≤256 Kio).
- sd_storage.h : include <stdint.h> (uint32_t).

Validé sur Freenove : POST /game/file?path=sd/music/cue440.wav → écrit sur
la microSD ; POST /game/media/play {path:"cue440.wav"} → résolu en
/sdcard/music/cue440.wav, 32000 B streamés en ~1005 ms au MAX98357A.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(p4): décodeur MP3 (helix) + mutex I2S TTS↔musique + FATFS LFN
CI / platformio (pull_request) Failing after 10m4s
fcb872c226
- voice_pipeline : mutex play_lock pris dans play_start / rendu dans play_end
  (+ tous chemins d'erreur). Sérialise TTS et musique sur le canal I2S TX
  partagé ; un play_start concurrent attend 2 s puis renvoie BUSY.
- media_manager : décodage MP3 via helix (chmorgan/esp-libhelix-mp3). Refactor
  playback_task en dispatcher d'extension → stream_wav / stream_mp3. stream_mp3
  décode frame par frame (buffers heap), downmix stéréo→mono, volume, feed I2S.
  Stack tâche 5120→8192 (le décodeur consomme de la pile).
- sdkconfig.defaults : CONFIG_FATFS_LFN_HEAP — les assets SD ont des noms > 8.3
  (SCENE_WIN.mp3, sonar_hint.mp3…) ; sans LFN fopen échoue ("open failed").

Validé sur Freenove : upload SCENE_WIN.mp3 (510 Ko, stéréo) sur /sdcard →
play → helix décode 22050 Hz 2ch → downmix → I2S MAX98357A. win.mp3 22050 mono
idem. Mutex : TTS et musique ne peuvent plus se chevaucher sur le DAC.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
electron merged commit 7f52d3d759 into main 2026-06-13 14:44:30 +00:00
Sign in to join this conversation.