43dc1478b1
The BOX-3 touch gamebook had several blocking bugs that made the voiced+foley story packs unusable. This fixes them end to end. - Stack overflow on story start: gb_play_task kept a 2 KB buffer on its 4 KB stack and rebooted the board. Buffers are now static (the task is a singleton) and the stack is 6 KB. - No sound at all: the ES8311 codec was never initialised — main.c wrote raw I2S to a muted DAC. Output (and the mic) now go through the BSP esp_codec_dev (bsp_audio_codec_speaker/microphone_init, esp_codec_dev_write/read). The power amplifier (GPIO46) is also forced on and volume set to 100, as the es8311 pa_pin handling did not drive it in practice. - First passage silent: gb_play re-mounted the SD that the gamebook had already mounted; the failed second bsp_sdcard_mount tore down the VFS so the first fopen failed. Now we open the file first and only mount if that fails. A short silence lead-in also primes the codec/PA ramp. - No accents: the gamebook used ASCII-only lv_font_montserrat_14/24. Added custom Montserrat fonts (font_fr_14/24, Latin-1 + œŒŸ « » ’ …, uncompressed so they render without LV_USE_FONT_COMPRESSED). - Mic/voice streaming gated behind CONFIG_BOX3_VOICE_STREAMING (default off): as a gamebook the BOX-3 needs no mic, and the constant codec reads + bridge reconnects interfered with playback and flooded the log. plip_virtual + cmd_exec handle types switched from i2s_chan_handle_t to esp_codec_dev_handle_t accordingly.
48 lines
1.8 KiB
C
48 lines
1.8 KiB
C
// cmd_exec.h — BOX-3 executor for structured ESP-NOW CMD frames (D5 contract).
|
|
//
|
|
// Wire format (SCENARIO_MESH_TEXT_CMD, ≤200 bytes):
|
|
// {"op":"<verb>","a":{<args>}}
|
|
//
|
|
// Supported ops:
|
|
// screen {"t":"title","u":"subtitle","y":"symbol","e":"effect"} — display on LCD
|
|
// effect: "pulse"|"glitch"|"gyro"|"none"
|
|
// play {"p":"<path>","l":0|1} — stream WAV via I2S; embedded cue if no file
|
|
// evt {"n":"<name>"} — log the event (future: relay to master)
|
|
// led {"p":"<pattern>"} — log the pattern (stub)
|
|
// <any> unknown op — log warn, ignore
|
|
//
|
|
// Tolerant by design: malformed JSON, missing keys, or unknown ops log a warning
|
|
// and return without crashing. Never asserts on network input.
|
|
|
|
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include "esp_err.h"
|
|
#include "esp_codec_dev.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
// Parse and execute one CMD frame. `data` is the raw UTF-8 payload received via
|
|
// scenario_mesh text callback (NUL-terminated). Returns ESP_OK if the op was
|
|
// recognised and dispatched, ESP_ERR_INVALID_ARG on bad JSON or missing `op`,
|
|
// ESP_ERR_NOT_SUPPORTED for unknown ops (all logged, no crash).
|
|
esp_err_t cmd_exec_handle(const char *data, size_t len);
|
|
|
|
// Provide the speaker codec (ES8311) handle so exec_play() can stream audio.
|
|
// Must be called from main.c after speaker_init(), before any CMD arrives.
|
|
void cmd_exec_set_spk_handle(esp_codec_dev_handle_t h);
|
|
|
|
// Play a 16 kHz mono 16-bit WAV from the SD asynchronously, streamed in chunks
|
|
// (RAM-safe for long narration) and INTERRUPTIBLE: a new call stops the current
|
|
// clip and starts the new one. Used by the touch gamebook for passage audio.
|
|
void cmd_exec_play_file_async(const char *path);
|
|
|
|
// Stop the async narration (no-op if nothing is playing).
|
|
void cmd_exec_stop_play(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|