{"owner":"78","repo":"xiaozhi-esp32","hasSkills":true,"totalSkillsCount":2,"totalTokensCount":1831,"categories":["plugin-manifest","root-instruction"],"hasMcp":false,"mcpConfig":null,"found":["scripts/p3_tools/README.md","AGENTS.md"],"skills":{"scripts/p3_tools/README.md":"# P3音频格式转换与播放工具\n\n这个目录包含两个用于处理P3格式音频文件的Python脚本：\n\n## 1. 音频转换工具 (convert_audio_to_p3.py)\n\n将普通音频文件转换为P3格式（4字节header + Opus数据包的流式结构）并进行响度标准化。\n\n### 使用方法\n\n```bash\npython convert_audio_to_p3.py <输入音频文件> <输出P3文件> [-l LUFS] [-d]\n```\n\n其中，可选选项 `-l` 用于指定响度标准化的目标响度，默认为 -16 LUFS；可选选项 `-d` 可以禁用响度标准化。\n\n如果输入的音频文件符合下面的任一条件，建议使用 `-d` 禁用响度标准化：\n- 音频过短\n- 音频已经调整过响度\n- 音频来自默认 TTS （小智当前使用的 TTS 的默认响度已是 -16 LUFS）\n\n例如：\n```bash\npython convert_audio_to_p3.py input.mp3 output.p3\n```\n\n## 2. P3音频播放工具 (play_p3.py)\n\n播放P3格式的音频文件。\n\n### 特性\n\n- 解码并播放P3格式的音频文件\n- 在播放结束或用户中断时应用淡出效果，避免破音\n- 支持通过命令行参数指定要播放的文件\n\n### 使用方法\n\n```bash\npython play_p3.py <P3文件路径>\n```\n\n例如：\n```bash\npython play_p3.py output.p3\n```\n\n## 3. 音频转回工具 (convert_p3_to_audio.py)\n\n将P3格式转换回普通音频文件。\n\n### 使用方法\n\n```bash\npython convert_p3_to_audio.py <输入P3文件> <输出音频文件>\n```\n\n输出音频文件需要有扩展名。\n\n例如：\n```bash\npython convert_p3_to_audio.py input.p3 output.wav\n```\n## 4. 音频/P3批量转换工具\n\n一个图形化的工具，支持批量转换音频到P3，P3到音频\n\n![](./img/img.png)\n\n### 使用方法：\n```bash\npython batch_convert_gui.py\n```\n\n## 依赖安装\n\n在使用这些脚本前，请确保安装了所需的Python库：\n\n```bash\npip install librosa opuslib numpy tqdm sounddevice pyloudnorm soundfile\n```\n\n或者使用提供的requirements.txt文件：\n\n```bash\npip install -r requirements.txt\n```\n\n## P3格式说明\n\nP3格式是一种简单的流式音频格式，结构如下：\n- 每个音频帧由一个4字节的头部和一个Opus编码的数据包组成\n- 头部格式：[1字节类型, 1字节保留, 2字节长度]\n- 采样率固定为16000Hz，单声道\n- 每帧时长为60ms ","AGENTS.md":"# AGENTS.md\n\n## Project\n\nXiaoZhi is an ESP-IDF C/C++ voice-assistant firmware supporting many chips, boards, displays, audio devices, and network transports. A build selects exactly one board implementation.\n\nUse the ESP-IDF `release/v6.1` branch when possible. The minimum supported SDK is ESP-IDF v6.0.1. IDF 5.x is not supported.\n\n## Architecture\n\n- `main/application.*`: main event loop, protocol lifecycle, and high-level behavior.\n- `main/device_state_machine.*`: legal runtime state transitions.\n- `main/boards/common/`: board interfaces and reusable hardware/network helpers.\n- `main/boards/**/`: board-specific pins, initialization, and build variants.\n- `main/audio/`: codecs, audio tasks, engines, wake words, and queues.\n- `main/protocols/`: transport-neutral API plus WebSocket and MQTT/UDP.\n- `main/display/` and `main/led/`: reusable UI implementations.\n- `main/mcp_server.*`: common device-side MCP tools and dispatch.\n- `main/Kconfig.projbuild`: board and feature configuration.\n- `main/CMakeLists.txt`: source, board, locale, font, and asset selection.\n- `scripts/build.py`: canonical board/variant build entry point.\n\nRead the closest existing implementation before adding a new one. Prefer the narrowest owning layer; do not put board-specific behavior into core modules.\n\n## Required Rules\n\n- Preserve unrelated worktree changes and keep patches focused.\n- A build must export exactly one board factory through `DECLARE_BOARD(...)`.\n- Never alter an existing board's pins to support different hardware. Add a uniquely named board or release variant; board identity affects OTA compatibility.\n- Core code depends on `Board` interfaces, never a concrete board class or board `config.h`.\n- Treat camera, backlight, display, LED, battery, and similar capabilities as optional.\n- Change runtime state through `Application::SetDeviceState()` and the state machine.\n- Callbacks may run outside the main task. Schedule application mutations with `Application::Schedule()` or event bits.\n- Do not block the main event loop or audio tasks. Avoid unbounded queues and repeated large allocations in audio paths.\n- Keep shared message semantics in `Protocol`; verify both transports when changing its contract.\n- Validate network input and preserve `cJSON` ownership. NVS keys are persistent API and require migration when changed.\n- Guard target-specific features with Kconfig/component rules. Do not assume every target has PSRAM or S3/P4 resources.\n- Do not manually edit generated/vendor output: `build/`, `releases/`, `managed_components/`, `components/`, `sdkconfig*`, `main/assets/lang_config.h`, or generated mmap headers.\n- Format only touched C/C++ files with the repository `.clang-format`; avoid unrelated mass formatting.\n\n## Boards and Configuration\n\nBoard selection is a coupled chain:\n\n`config.json` -> `scripts/build.py` -> `main/Kconfig.projbuild` -> `main/CMakeLists.txt` -> board source and `config.h`.\n\nWhen adding a board or variant, update every relevant link in that chain. Include a unique board identity, correct chip target, flash/partition settings, exactly one `DECLARE_BOARD`, and board documentation. Follow `docs/custom-board.md`.\n\n## Commands\n\nSource the intended ESP-IDF environment first:\n\n```sh\nsource /path/to/esp-idf/export.sh\nidf.py --version\n```\n\n```sh\n# Discover exact board and variant names\npython3 scripts/build.py --list-boards\n\n# Canonical variant build\npython3 scripts/build.py <board-directory> --name <variant-name>\n\n# Host-side build tests\npython3 -m unittest discover -s scripts/tests -v\n\n# Format/check touched files\nclang-format -i <files>\nclang-format --dry-run -Werror <files>\n```\n\nThe build script changes local `sdkconfig` and build state. Do not assume the build directory still represents a previous target.\n\n## Validation\n\n- Board-only change: build affected variants and smoke-test changed hardware.\n- Core, common-board, audio, protocol, display, dependency, Kconfig, or CMake change: run host tests and build representative affected chip/network paths.\n- Protocol changes: verify WebSocket and MQTT/UDP when shared behavior changes.\n- Audio changes: verify capture, playback, wake/VAD, interruption, reconnect, and applicable AEC modes.\n- UI/assets changes: verify applicable no-display/OLED/LVGL paths and partition size.\n- Always report what was tested and what still needs physical hardware. A successful build is not hardware validation.\n\n## Authoritative Documentation\n\n- Overview and SDK policy: `README.md`\n- Board guide: `docs/custom-board.md`\n- Audio design: `main/audio/README.md`\n- Code style: `docs/code_style.md`\n- Protocols: `docs/websocket.md`, `docs/mqtt-udp.md`, `docs/mcp-protocol.md`\n- CI matrix: `.github/workflows/build.yml`\n\nKeep detailed or fast-changing information in those files, not here. Add a nested `AGENTS.md` only when a subsystem needs specialized instructions.\n"},"files":{"scripts/p3_tools/README.md":"# P3音频格式转换与播放工具\n\n这个目录包含两个用于处理P3格式音频文件的Python脚本：\n\n## 1. 音频转换工具 (convert_audio_to_p3.py)\n\n将普通音频文件转换为P3格式（4字节header + Opus数据包的流式结构）并进行响度标准化。\n\n### 使用方法\n\n```bash\npython convert_audio_to_p3.py <输入音频文件> <输出P3文件> [-l LUFS] [-d]\n```\n\n其中，可选选项 `-l` 用于指定响度标准化的目标响度，默认为 -16 LUFS；可选选项 `-d` 可以禁用响度标准化。\n\n如果输入的音频文件符合下面的任一条件，建议使用 `-d` 禁用响度标准化：\n- 音频过短\n- 音频已经调整过响度\n- 音频来自默认 TTS （小智当前使用的 TTS 的默认响度已是 -16 LUFS）\n\n例如：\n```bash\npython convert_audio_to_p3.py input.mp3 output.p3\n```\n\n## 2. P3音频播放工具 (play_p3.py)\n\n播放P3格式的音频文件。\n\n### 特性\n\n- 解码并播放P3格式的音频文件\n- 在播放结束或用户中断时应用淡出效果，避免破音\n- 支持通过命令行参数指定要播放的文件\n\n### 使用方法\n\n```bash\npython play_p3.py <P3文件路径>\n```\n\n例如：\n```bash\npython play_p3.py output.p3\n```\n\n## 3. 音频转回工具 (convert_p3_to_audio.py)\n\n将P3格式转换回普通音频文件。\n\n### 使用方法\n\n```bash\npython convert_p3_to_audio.py <输入P3文件> <输出音频文件>\n```\n\n输出音频文件需要有扩展名。\n\n例如：\n```bash\npython convert_p3_to_audio.py input.p3 output.wav\n```\n## 4. 音频/P3批量转换工具\n\n一个图形化的工具，支持批量转换音频到P3，P3到音频\n\n![](./img/img.png)\n\n### 使用方法：\n```bash\npython batch_convert_gui.py\n```\n\n## 依赖安装\n\n在使用这些脚本前，请确保安装了所需的Python库：\n\n```bash\npip install librosa opuslib numpy tqdm sounddevice pyloudnorm soundfile\n```\n\n或者使用提供的requirements.txt文件：\n\n```bash\npip install -r requirements.txt\n```\n\n## P3格式说明\n\nP3格式是一种简单的流式音频格式，结构如下：\n- 每个音频帧由一个4字节的头部和一个Opus编码的数据包组成\n- 头部格式：[1字节类型, 1字节保留, 2字节长度]\n- 采样率固定为16000Hz，单声道\n- 每帧时长为60ms ","AGENTS.md":"# AGENTS.md\n\n## Project\n\nXiaoZhi is an ESP-IDF C/C++ voice-assistant firmware supporting many chips, boards, displays, audio devices, and network transports. A build selects exactly one board implementation.\n\nUse the ESP-IDF `release/v6.1` branch when possible. The minimum supported SDK is ESP-IDF v6.0.1. IDF 5.x is not supported.\n\n## Architecture\n\n- `main/application.*`: main event loop, protocol lifecycle, and high-level behavior.\n- `main/device_state_machine.*`: legal runtime state transitions.\n- `main/boards/common/`: board interfaces and reusable hardware/network helpers.\n- `main/boards/**/`: board-specific pins, initialization, and build variants.\n- `main/audio/`: codecs, audio tasks, engines, wake words, and queues.\n- `main/protocols/`: transport-neutral API plus WebSocket and MQTT/UDP.\n- `main/display/` and `main/led/`: reusable UI implementations.\n- `main/mcp_server.*`: common device-side MCP tools and dispatch.\n- `main/Kconfig.projbuild`: board and feature configuration.\n- `main/CMakeLists.txt`: source, board, locale, font, and asset selection.\n- `scripts/build.py`: canonical board/variant build entry point.\n\nRead the closest existing implementation before adding a new one. Prefer the narrowest owning layer; do not put board-specific behavior into core modules.\n\n## Required Rules\n\n- Preserve unrelated worktree changes and keep patches focused.\n- A build must export exactly one board factory through `DECLARE_BOARD(...)`.\n- Never alter an existing board's pins to support different hardware. Add a uniquely named board or release variant; board identity affects OTA compatibility.\n- Core code depends on `Board` interfaces, never a concrete board class or board `config.h`.\n- Treat camera, backlight, display, LED, battery, and similar capabilities as optional.\n- Change runtime state through `Application::SetDeviceState()` and the state machine.\n- Callbacks may run outside the main task. Schedule application mutations with `Application::Schedule()` or event bits.\n- Do not block the main event loop or audio tasks. Avoid unbounded queues and repeated large allocations in audio paths.\n- Keep shared message semantics in `Protocol`; verify both transports when changing its contract.\n- Validate network input and preserve `cJSON` ownership. NVS keys are persistent API and require migration when changed.\n- Guard target-specific features with Kconfig/component rules. Do not assume every target has PSRAM or S3/P4 resources.\n- Do not manually edit generated/vendor output: `build/`, `releases/`, `managed_components/`, `components/`, `sdkconfig*`, `main/assets/lang_config.h`, or generated mmap headers.\n- Format only touched C/C++ files with the repository `.clang-format`; avoid unrelated mass formatting.\n\n## Boards and Configuration\n\nBoard selection is a coupled chain:\n\n`config.json` -> `scripts/build.py` -> `main/Kconfig.projbuild` -> `main/CMakeLists.txt` -> board source and `config.h`.\n\nWhen adding a board or variant, update every relevant link in that chain. Include a unique board identity, correct chip target, flash/partition settings, exactly one `DECLARE_BOARD`, and board documentation. Follow `docs/custom-board.md`.\n\n## Commands\n\nSource the intended ESP-IDF environment first:\n\n```sh\nsource /path/to/esp-idf/export.sh\nidf.py --version\n```\n\n```sh\n# Discover exact board and variant names\npython3 scripts/build.py --list-boards\n\n# Canonical variant build\npython3 scripts/build.py <board-directory> --name <variant-name>\n\n# Host-side build tests\npython3 -m unittest discover -s scripts/tests -v\n\n# Format/check touched files\nclang-format -i <files>\nclang-format --dry-run -Werror <files>\n```\n\nThe build script changes local `sdkconfig` and build state. Do not assume the build directory still represents a previous target.\n\n## Validation\n\n- Board-only change: build affected variants and smoke-test changed hardware.\n- Core, common-board, audio, protocol, display, dependency, Kconfig, or CMake change: run host tests and build representative affected chip/network paths.\n- Protocol changes: verify WebSocket and MQTT/UDP when shared behavior changes.\n- Audio changes: verify capture, playback, wake/VAD, interruption, reconnect, and applicable AEC modes.\n- UI/assets changes: verify applicable no-display/OLED/LVGL paths and partition size.\n- Always report what was tested and what still needs physical hardware. A successful build is not hardware validation.\n\n## Authoritative Documentation\n\n- Overview and SDK policy: `README.md`\n- Board guide: `docs/custom-board.md`\n- Audio design: `main/audio/README.md`\n- Code style: `docs/code_style.md`\n- Protocols: `docs/websocket.md`, `docs/mqtt-udp.md`, `docs/mcp-protocol.md`\n- CI matrix: `.github/workflows/build.yml`\n\nKeep detailed or fast-changing information in those files, not here. Add a nested `AGENTS.md` only when a subsystem needs specialized instructions.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/78/xiaozhi-esp32/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md\n\n## Project\n\nXiaoZhi is an ESP-IDF C/C++ voice-assistant firmware supporting many chips, boards, displays, audio devices, and network transports. A build selects exactly one board implementation.\n\nUse the ESP-IDF `release/v6.1` branch when possible. The minimum supported SDK is ESP-IDF v6.0.1. IDF 5.x is not supported.\n\n## Architecture\n\n- `main/application.*`: main event loop, protocol lifecycle, and high-level behavior.\n- `main/device_state_machine.*`: legal runtime state transitions.\n- `main/boards/common/`: board interfaces and reusable hardware/network helpers.\n- `main/boards/**/`: board-specific pins, initialization, and build variants.\n- `main/audio/`: codecs, audio tasks, engines, wake words, and queues.\n- `main/protocols/`: transport-neutral API plus WebSocket and MQTT/UDP.\n- `main/display/` and `main/led/`: reusable UI implementations.\n- `main/mcp_server.*`: common device-side MCP tools and dispatch.\n- `main/Kconfig.projbuild`: board and feature configuration.\n- `main/CMakeLists.txt`: source, board, locale, font, and asset selection.\n- `scripts/build.py`: canonical board/variant build entry point.\n\nRead the closest existing implementation before adding a new one. Prefer the narrowest owning layer; do not put board-specific behavior into core modules.\n\n## Required Rules\n\n- Preserve unrelated worktree changes and keep patches focused.\n- A build must export exactly one board factory through `DECLARE_BOARD(...)`.\n- Never alter an existing board's pins to support different hardware. Add a uniquely named board or release variant; board identity affects OTA compatibility.\n- Core code depends on `Board` interfaces, never a concrete board class or board `config.h`.\n- Treat camera, backlight, display, LED, battery, and similar capabilities as optional.\n- Change runtime state through `Application::SetDeviceState()` and the state machine.\n- Callbacks may run outside the main task. Schedule application mutations with `Application::Schedule()` or event bits.\n- Do not block the main event loop or audio tasks. Avoid unbounded queues and repeated large allocations in audio paths.\n- Keep shared message semantics in `Protocol`; verify both transports when changing its contract.\n- Validate network input and preserve `cJSON` ownership. NVS keys are persistent API and require migration when changed.\n- Guard target-specific features with Kconfig/component rules. Do not assume every target has PSRAM or S3/P4 resources.\n- Do not manually edit generated/vendor output: `build/`, `releases/`, `managed_components/`, `components/`, `sdkconfig*`, `main/assets/lang_config.h`, or generated mmap headers.\n- Format only touched C/C++ files with the repository `.clang-format`; avoid unrelated mass formatting.\n\n## Boards and Configuration\n\nBoard selection is a coupled chain:\n\n`config.json` -> `scripts/build.py` -> `main/Kconfig.projbuild` -> `main/CMakeLists.txt` -> board source and `config.h`.\n\nWhen adding a board or variant, update every relevant link in that chain. Include a unique board identity, correct chip target, flash/partition settings, exactly one `DECLARE_BOARD`, and board documentation. Follow `docs/custom-board.md`.\n\n## Commands\n\nSource the intended ESP-IDF environment first:\n\n```sh\nsource /path/to/esp-idf/export.sh\nidf.py --version\n```\n\n```sh\n# Discover exact board and variant names\npython3 scripts/build.py --list-boards\n\n# Canonical variant build\npython3 scripts/build.py <board-directory> --name <variant-name>\n\n# Host-side build tests\npython3 -m unittest discover -s scripts/tests -v\n\n# Format/check touched files\nclang-format -i <files>\nclang-format --dry-run -Werror <files>\n```\n\nThe build script changes local `sdkconfig` and build state. Do not assume the build directory still represents a previous target.\n\n## Validation\n\n- Board-only change: build affected variants and smoke-test changed hardware.\n- Core, common-board, audio, protocol, display, dependency, Kconfig, or CMake change: run host tests and build representative affected chip/network paths.\n- Protocol changes: verify WebSocket and MQTT/UDP when shared behavior changes.\n- Audio changes: verify capture, playback, wake/VAD, interruption, reconnect, and applicable AEC modes.\n- UI/assets changes: verify applicable no-display/OLED/LVGL paths and partition size.\n- Always report what was tested and what still needs physical hardware. A successful build is not hardware validation.\n\n## Authoritative Documentation\n\n- Overview and SDK policy: `README.md`\n- Board guide: `docs/custom-board.md`\n- Audio design: `main/audio/README.md`\n- Code style: `docs/code_style.md`\n- Protocols: `docs/websocket.md`, `docs/mqtt-udp.md`, `docs/mcp-protocol.md`\n- CI matrix: `.github/workflows/build.yml`\n\nKeep detailed or fast-changing information in those files, not here. Add a nested `AGENTS.md` only when a subsystem needs specialized instructions.\n","isInternal":false,"tokens":1067,"sizeBytes":4866},{"name":"README.md","path":"scripts/p3_tools/README.md","rawUrl":"https://raw.githubusercontent.com/78/xiaozhi-esp32/HEAD/scripts/p3_tools/README.md","title":"p3_tools Documentation","category":"plugin-manifest","format":"markdown","content":"# P3音频格式转换与播放工具\n\n这个目录包含两个用于处理P3格式音频文件的Python脚本：\n\n## 1. 音频转换工具 (convert_audio_to_p3.py)\n\n将普通音频文件转换为P3格式（4字节header + Opus数据包的流式结构）并进行响度标准化。\n\n### 使用方法\n\n```bash\npython convert_audio_to_p3.py <输入音频文件> <输出P3文件> [-l LUFS] [-d]\n```\n\n其中，可选选项 `-l` 用于指定响度标准化的目标响度，默认为 -16 LUFS；可选选项 `-d` 可以禁用响度标准化。\n\n如果输入的音频文件符合下面的任一条件，建议使用 `-d` 禁用响度标准化：\n- 音频过短\n- 音频已经调整过响度\n- 音频来自默认 TTS （小智当前使用的 TTS 的默认响度已是 -16 LUFS）\n\n例如：\n```bash\npython convert_audio_to_p3.py input.mp3 output.p3\n```\n\n## 2. P3音频播放工具 (play_p3.py)\n\n播放P3格式的音频文件。\n\n### 特性\n\n- 解码并播放P3格式的音频文件\n- 在播放结束或用户中断时应用淡出效果，避免破音\n- 支持通过命令行参数指定要播放的文件\n\n### 使用方法\n\n```bash\npython play_p3.py <P3文件路径>\n```\n\n例如：\n```bash\npython play_p3.py output.p3\n```\n\n## 3. 音频转回工具 (convert_p3_to_audio.py)\n\n将P3格式转换回普通音频文件。\n\n### 使用方法\n\n```bash\npython convert_p3_to_audio.py <输入P3文件> <输出音频文件>\n```\n\n输出音频文件需要有扩展名。\n\n例如：\n```bash\npython convert_p3_to_audio.py input.p3 output.wav\n```\n## 4. 音频/P3批量转换工具\n\n一个图形化的工具，支持批量转换音频到P3，P3到音频\n\n![](./img/img.png)\n\n### 使用方法：\n```bash\npython batch_convert_gui.py\n```\n\n## 依赖安装\n\n在使用这些脚本前，请确保安装了所需的Python库：\n\n```bash\npip install librosa opuslib numpy tqdm sounddevice pyloudnorm soundfile\n```\n\n或者使用提供的requirements.txt文件：\n\n```bash\npip install -r requirements.txt\n```\n\n## P3格式说明\n\nP3格式是一种简单的流式音频格式，结构如下：\n- 每个音频帧由一个4字节的头部和一个Opus编码的数据包组成\n- 头部格式：[1字节类型, 1字节保留, 2字节长度]\n- 采样率固定为16000Hz，单声道\n- 每帧时长为60ms ","isInternal":false,"tokens":764,"sizeBytes":2260}],"systemPromptSnippet":"<yakaai_skills repo=\"78/xiaozhi-esp32\">\n<!-- File: AGENTS.md (Tokens: ~1067 | Category: root-instruction) -->\n# AGENTS.md\n\n## Project\n\nXiaoZhi is an ESP-IDF C/C++ voice-assistant firmware supporting many chips, boards, displays, audio devices, and network transports. A build selects exactly one board implementation.\n\nUse the ESP-IDF `release/v6.1` branch when possible. The minimum supported SDK is ESP-IDF v6.0.1. IDF 5.x is not supported.\n\n## Architecture\n\n- `main/application.*`: main event loop, protocol lifecycle, and high-level behavior.\n- `main/device_state_machine.*`: legal runtime state transitions.\n- `main/boards/common/`: board interfaces and reusable hardware/network helpers.\n- `main/boards/**/`: board-specific pins, initialization, and build variants.\n- `main/audio/`: codecs, audio tasks, engines, wake words, and queues.\n- `main/protocols/`: transport-neutral API plus WebSocket and MQTT/UDP.\n- `main/display/` and `main/led/`: reusable UI implementations.\n- `main/mcp_server.*`: common device-side MCP tools and dispatch.\n- `main/Kconfig.projbuild`: board and feature configuration.\n- `main/CMakeLists.txt`: source, board, locale, font, and asset selection.\n- `scripts/build.py`: canonical board/variant build entry point.\n\nRead the closest existing implementation before adding a new one. Prefer the narrowest owning layer; do not put board-specific behavior into core modules.\n\n## Required Rules\n\n- Preserve unrelated worktree changes and keep patches focused.\n- A build must export exactly one board factory through `DECLARE_BOARD(...)`.\n- Never alter an existing board's pins to support different hardware. Add a uniquely named board or release variant; board identity affects OTA compatibility.\n- Core code depends on `Board` interfaces, never a concrete board class or board `config.h`.\n- Treat camera, backlight, display, LED, battery, and similar capabilities as optional.\n- Change runtime state through `Application::SetDeviceState()` and the state machine.\n- Callbacks may run outside the main task. Schedule application mutations with `Application::Schedule()` or event bits.\n- Do not block the main event loop or audio tasks. Avoid unbounded queues and repeated large allocations in audio paths.\n- Keep shared message semantics in `Protocol`; verify both transports when changing its contract.\n- Validate network input and preserve `cJSON` ownership. NVS keys are persistent API and require migration when changed.\n- Guard target-specific features with Kconfig/component rules. Do not assume every target has PSRAM or S3/P4 resources.\n- Do not manually edit generated/vendor output: `build/`, `releases/`, `managed_components/`, `components/`, `sdkconfig*`, `main/assets/lang_config.h`, or generated mmap headers.\n- Format only touched C/C++ files with the repository `.clang-format`; avoid unrelated mass formatting.\n\n## Boards and Configuration\n\nBoard selection is a coupled chain:\n\n`config.json` -> `scripts/build.py` -> `main/Kconfig.projbuild` -> `main/CMakeLists.txt` -> board source and `config.h`.\n\nWhen adding a board or variant, update every relevant link in that chain. Include a unique board identity, correct chip target, flash/partition settings, exactly one `DECLARE_BOARD`, and board documentation. Follow `docs/custom-board.md`.\n\n## Commands\n\nSource the intended ESP-IDF environment first:\n\n```sh\nsource /path/to/esp-idf/export.sh\nidf.py --version\n```\n\n```sh\n# Discover exact board and variant names\npython3 scripts/build.py --list-boards\n\n# Canonical variant build\npython3 scripts/build.py <board-directory> --name <variant-name>\n\n# Host-side build tests\npython3 -m unittest discover -s scripts/tests -v\n\n# Format/check touched files\nclang-format -i <files>\nclang-format --dry-run -Werror <files>\n```\n\nThe build script changes local `sdkconfig` and build state. Do not assume the build directory still represents a previous target.\n\n## Validation\n\n- Board-only change: build affected variants and smoke-test changed hardware.\n- Core, common-board, audio, protocol, display, dependency, Kconfig, or CMake change: run host tests and build representative affected chip/network paths.\n- Protocol changes: verify WebSocket and MQTT/UDP when shared behavior changes.\n- Audio changes: verify capture, playback, wake/VAD, interruption, reconnect, and applicable AEC modes.\n- UI/assets changes: verify applicable no-display/OLED/LVGL paths and partition size.\n- Always report what was tested and what still needs physical hardware. A successful build is not hardware validation.\n\n## Authoritative Documentation\n\n- Overview and SDK policy: `README.md`\n- Board guide: `docs/custom-board.md`\n- Audio design: `main/audio/README.md`\n- Code style: `docs/code_style.md`\n- Protocols: `docs/websocket.md`, `docs/mqtt-udp.md`, `docs/mcp-protocol.md`\n- CI matrix: `.github/workflows/build.yml`\n\nKeep detailed or fast-changing information in those files, not here. Add a nested `AGENTS.md` only when a subsystem needs specialized instructions.\n\n<!-- File: scripts/p3_tools/README.md (Tokens: ~764 | Category: plugin-manifest) -->\n# P3音频格式转换与播放工具\n\n这个目录包含两个用于处理P3格式音频文件的Python脚本：\n\n## 1. 音频转换工具 (convert_audio_to_p3.py)\n\n将普通音频文件转换为P3格式（4字节header + Opus数据包的流式结构）并进行响度标准化。\n\n### 使用方法\n\n```bash\npython convert_audio_to_p3.py <输入音频文件> <输出P3文件> [-l LUFS] [-d]\n```\n\n其中，可选选项 `-l` 用于指定响度标准化的目标响度，默认为 -16 LUFS；可选选项 `-d` 可以禁用响度标准化。\n\n如果输入的音频文件符合下面的任一条件，建议使用 `-d` 禁用响度标准化：\n- 音频过短\n- 音频已经调整过响度\n- 音频来自默认 TTS （小智当前使用的 TTS 的默认响度已是 -16 LUFS）\n\n例如：\n```bash\npython convert_audio_to_p3.py input.mp3 output.p3\n```\n\n## 2. P3音频播放工具 (play_p3.py)\n\n播放P3格式的音频文件。\n\n### 特性\n\n- 解码并播放P3格式的音频文件\n- 在播放结束或用户中断时应用淡出效果，避免破音\n- 支持通过命令行参数指定要播放的文件\n\n### 使用方法\n\n```bash\npython play_p3.py <P3文件路径>\n```\n\n例如：\n```bash\npython play_p3.py output.p3\n```\n\n## 3. 音频转回工具 (convert_p3_to_audio.py)\n\n将P3格式转换回普通音频文件。\n\n### 使用方法\n\n```bash\npython convert_p3_to_audio.py <输入P3文件> <输出音频文件>\n```\n\n输出音频文件需要有扩展名。\n\n例如：\n```bash\npython convert_p3_to_audio.py input.p3 output.wav\n```\n## 4. 音频/P3批量转换工具\n\n一个图形化的工具，支持批量转换音频到P3，P3到音频\n\n![](./img/img.png)\n\n### 使用方法：\n```bash\npython batch_convert_gui.py\n```\n\n## 依赖安装\n\n在使用这些脚本前，请确保安装了所需的Python库：\n\n```bash\npip install librosa opuslib numpy tqdm sounddevice pyloudnorm soundfile\n```\n\n或者使用提供的requirements.txt文件：\n\n```bash\npip install -r requirements.txt\n```\n\n## P3格式说明\n\nP3格式是一种简单的流式音频格式，结构如下：\n- 每个音频帧由一个4字节的头部和一个Opus编码的数据包组成\n- 头部格式：[1字节类型, 1字节保留, 2字节长度]\n- 采样率固定为16000Hz，单声道\n- 每帧时长为60ms\n</yakaai_skills>"}