feat(P4): media_manager vrai playback WAV + /game/media/play #9
Reference in New Issue
Block a user
Delete Branch "feat/p4-media-wav-playback"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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
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>- 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>- 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>