docs: 新增 Kapi 项目业务全貌与重构决策分析报告
基于深度代码分析(58 个 tool calls)输出 600 行决策分析文档: - §1~7 项目业务全貌: 架构/RTC/音频管线/已有功能/资源/与 Baji 差异/已有规划 - §8 三选项决策矩阵: * 选项 A (移植 Baji Phase 6 软退出): ✅ 强烈推荐, 工作量 1-2 天 * 选项 B-1 (启用 ESP-SR AFE): ✅ 推荐, 但需先确认 Moji 板 ES7210 REF 走线 * 选项 B-2 (G711A→Opus): ⚠️ 暂缓 * 选项 B-3 (Jitter buffer): ⚠️ 暂缓 * 选项 C (ESP-ADF 重构): ❌ 强烈不推荐, 工作量 3-4 周风险极高 - §9 推荐 4 步执行路线 - §10 关键代码引用 + Baji 交叉引用清单 - §11 一句话总结 - 附录: Kapi 是更合适的 AFE 实验场地(SRAM 余量 80-130KB vs Baji 44KB) 关键结论: - Kapi = Baji 无屏轻量底座, 资源宽松 30-50KB SRAM + 300-500KB PSRAM - audio_processing 整套 AFE 代码已写好但 sdkconfig 未启用 - Phase 6 软退出 100% 可移植(基类同源代码, 字幕提示需替换为 LED/语音) - 未来 AFE 实验应优先在 Kapi 跑通, 再回 Baji 评估 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d8982c3569
commit
fe8173752d
378
05Kapi_项目业务全貌与重构决策分析.md
Normal file
378
05Kapi_项目业务全貌与重构决策分析.md
Normal file
@ -0,0 +1,378 @@
|
||||
# Kapi_Rtc_toy 项目业务全貌与重构决策分析
|
||||
|
||||
> **生成时间**:2026-05-14
|
||||
> **生成背景**:Baji_Rtc_Toy(衍生项目)在硬件资源紧张+用户体验不佳的背景下,评估是否应该把 Phase 6 软退出、ESP-SR AFE、G711A→Opus 等优化方案移植到 Kapi(底座项目),或干脆切到 ESP-ADF 框架重构。
|
||||
> **关联文档**:
|
||||
> - 衍生项目对比报告:[/Users/rdzleo/Desktop/Baji_Rtc_Toy/docs/Rtc_AIavatar/官方Korvo2方案_对比分析报告.md](../Baji_Rtc_Toy/docs/Rtc_AIavatar/官方Korvo2方案_对比分析报告.md)
|
||||
> - 同源 RTC 软退出方案:[/Users/rdzleo/Desktop/Baji_Rtc_Toy/docs/Rtc_AIavatar/RTC软退出方案_移植参考.md](../Baji_Rtc_Toy/docs/Rtc_AIavatar/RTC软退出方案_移植参考.md)
|
||||
> - 项目内已有 AEC 计划:`03AEC_VOICE_INTERRUPT_PORTING_PLAN.md`
|
||||
|
||||
---
|
||||
|
||||
## 0. TL;DR(一句话总结)
|
||||
|
||||
> **Kapi_Rtc_toy 是 Baji_Rtc_Toy 的"无屏轻量底座",比 Baji 多出 30-50KB SRAM + 300-500KB PSRAM 资源余量。Phase 6 软退出方案 100% 可移植且工作量极小;AFE-AEC 资源富余但需先确认硬件 REF 通道走线;坚决不推荐切换到 ESP-ADF 重构。**
|
||||
|
||||
---
|
||||
|
||||
## 1. 整体架构和业务全貌
|
||||
|
||||
### 1.1 框架与平台
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| **框架** | **纯 ESP-IDF**(≥5.3),不是 ESP-ADF |
|
||||
| **目标芯片** | ESP32-S3,16MB Flash + 8MB Octal PSRAM 80MHz |
|
||||
| **板型** | movecall-moji-esp32s3(**无屏**,触摸+IMU+电池) |
|
||||
| **协议** | WebSocket + Volc RTC 同时编入,通过 `ENABLE_RTC_MODE` 宏激活 RTC |
|
||||
|
||||
依据:
|
||||
- `main/idf_component.yml:13` — `espressif/esp_codec_dev: ~1.3.2`
|
||||
- `main/CMakeLists.txt:235-238` — `ENABLE_RTC_MODE` 宏
|
||||
- `sdkconfig` — `SPIRAM_MODE_OCT/SPEED_80M`, `CONFIG_BOARD_TYPE_MOVECALL_MOJI_ESP32S3=y`
|
||||
|
||||
### 1.2 入口流程
|
||||
|
||||
```
|
||||
main.cc:28 app_main
|
||||
→ esp_event_loop_create_default
|
||||
→ esp_netif_init
|
||||
→ nvs_flash_init
|
||||
→ Application::GetInstance().Start() (main.cc:105)
|
||||
→ application.cc:Start (~531 启动播报)
|
||||
→ 板级初始化(boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc:225+)
|
||||
→ InitializeProtocol → VolcRtcProtocol::Start (volc_rtc_protocol.cc:43)
|
||||
→ StartDialogWatchdog (application.cc:1961)
|
||||
```
|
||||
|
||||
### 1.3 主要模块清单
|
||||
|
||||
| 模块 | 行数 | 职责 |
|
||||
|---|---|---|
|
||||
| `main/application.cc/h` | 4281 行 | 单例主控、状态机、音频 I/O、HTTPS 故事/音乐、Dialog Watchdog、Schedule 队列 |
|
||||
| `main/protocols/volc_rtc_protocol.cc/h` | 853 行 | 火山 RTC 封装:volc_rtc_create/start/stop/destroy、subv/ctrl/conv/tool/info 消息解析 |
|
||||
| `main/protocols/websocket_protocol.cc` | — | WS 协议(RTC 模式下未激活) |
|
||||
| `main/protocols/protocol.h` | — | Protocol 基类(**当前无 `LeaveRoom` 虚函数**) |
|
||||
| `main/audio_codecs/box_audio_codec.cc` | — | ES8311(DAC)+ ES7210(ADC) |
|
||||
| `main/audio_codecs/es8311_audio_codec.cc` | — | 单 ES8311 实现(Moji 未用) |
|
||||
| `main/audio_processing/audio_processor.cc/h` | — | 基于 ESP-SR 的 AFE+VAD 封装(**未编入**) |
|
||||
| `main/audio_processing/wake_word_detect.cc` | — | 唤醒词(**未编入**) |
|
||||
| `main/audio/simple_pipeline.cc` | ~60 行 | **不是 ESP-ADF 管线**,仅是 codec InputData/OutputData 的薄壳 + 最近邻重采样 |
|
||||
| `main/bluetooth_provisioning.cc` | 1417 行 | 自定义 BLE GATT 二进制配网(0xABF0/F1/F2) |
|
||||
| `main/ble_service.cc` | — | BLE JSON Service(已实现未编入) |
|
||||
| `main/boards/movecall-moji-esp32s3/*` | 2078 行 + IMU + Touch | 板级:QMI8658A IMU、6 路 TouchPad、ADC 电池、KEY4 |
|
||||
| `main/iot/thing*.cc` + `iot/things/*.cc` | — | IoT 设备抽象 |
|
||||
| `main/weather_api.cc` | — | 天气查询 |
|
||||
|
||||
### TL;DR
|
||||
|
||||
Kapi_Rtc_toy = "xiaozhi" 系列 ESP-IDF 项目魔改版,集成火山 RTC + 自定义 BLE 配网 + IMU/触摸/电池。**无 LCD/LVGL**,框架是 ESP-IDF 而非 ESP-ADF;audio_processing 整套 AFE 代码已具备但**未在 sdkconfig 中启用**。
|
||||
|
||||
---
|
||||
|
||||
## 2. RTC 实现现状
|
||||
|
||||
### 2.1 协议层
|
||||
|
||||
- 使用 **VolcRtcProtocol**(`main/protocols/volc_rtc_protocol.cc:43-407`)
|
||||
- SDK:火山 `volc_engine_rtc_lite`(`main/CMakeLists.txt:204` REQUIRES)
|
||||
- 入房:`volc_rtc_start` → 等待 0x1(CONNECTED)+ 0x2(USER_JOINED)位
|
||||
- 退房:`CloseAudioChannel` **仅调用 `volc_rtc_stop`**(`volc_rtc_protocol.cc:399`),**不调 `destroy`** → 真人留在房间继续计费(与 Baji 旧版同病)
|
||||
|
||||
### 2.2 音频编解码使用现状
|
||||
|
||||
- **上行**:默认 `send_pcm_uplink_=true`、`send_g711a_uplink_=false`(`application.h:160-161`)。设备发 PCM,**SDK 内部转 G711A 上传**(`audio.codec.internal.enable=1`,`volc_rtc_protocol.cc:95`)
|
||||
- **下行**:`Joining channel: aibotrtc_G711A_*`(日志 `05-最新日志.txt:160`)→ **下行是 G711A**,不是 Opus
|
||||
- **本地播报(开机欢迎/故事/音乐)**:Opus 编码的 `.p3` 资产(OPUS 16k/60ms 单声道,开机播 `LALA_kaijibobao.p3`,`application.cc:618`)
|
||||
- **HTTPS 故事/音乐**:服务器返回 base64 Opus 数据,本地解码(`HttpsApiPlayback` + `audio_decode_queue_`)
|
||||
|
||||
### 2.3 软退出/Hibernate 现状
|
||||
|
||||
- **无 hibernate**、**无 LeaveRoom**、**无 EnterIdleHibernate**
|
||||
- Dialog Watchdog 触发逻辑(`application.cc:1961-2042`):
|
||||
- 40s 无 `last_audible_output_time_` 更新 → 写 NVS `reboot_dlg_idle=1` + `reboot_origin=1` → **`esp_restart()`**(line 2014)
|
||||
- 这正是 Baji Phase 6 替换的"硬重启退出"原型
|
||||
- `last_audible_output_time_` 当前**只由音频流刷新一处**(`application.cc:2161`,相当于方案 A),**没有方案 B (subtitle) 和方案 C (conv_status) 的双源刷新**
|
||||
|
||||
### 2.4 与 Baji_Rtc_Toy Phase 6 差异
|
||||
|
||||
| 项 | Kapi_Rtc_toy | Baji_Rtc_Toy (Phase 6) |
|
||||
|---|---|---|
|
||||
| 退出方式 | `esp_restart()` 硬重启 | `LeaveRoom` (stop+destroy) 软退 |
|
||||
| 恢复时长 | 15-25s(WiFi+应用全冷启)| 3-5s(NVS 缓存凭证,重建 RTC handle) |
|
||||
| 倒计时刷新源 | 只有方案 A(音频流) | B+C 双源(subtitle + conv_status) |
|
||||
| 状态保留 | 全部丢失 | 音量/历史/上下文保留 |
|
||||
|
||||
### TL;DR
|
||||
|
||||
Kapi RTC 协议层基本完备(与 Baji 共享 95% 同源代码),下行 G711A、上行 PCM-by-SDK-to-G711A。**完全没有软退出/hibernate 逻辑,仍是 `esp_restart()` 硬退出**,正好是 Baji Phase 6 解决的问题。
|
||||
|
||||
---
|
||||
|
||||
## 3. 音频管线(重点)
|
||||
|
||||
### 3.1 框架与组件
|
||||
|
||||
- 使用 **esp_codec_dev**(`espressif/esp_codec_dev: ~1.3.2`)
|
||||
- **不使用 ESP-ADF 的 audio_pipeline / audio_element**
|
||||
- `simple_pipeline.cc/h` 是 stub:`recorder_pipeline_read` 直接调 `codec->InputData`,`player_pipeline_write` 直接调 `codec->OutputData`,外加最近邻重采样(音质差但够用)
|
||||
|
||||
### 3.2 ES7210 + ES8311 配置
|
||||
|
||||
| 项 | 值 | 引用 |
|
||||
|---|---|---|
|
||||
| Codec 创建 | `BoxAudioCodec(ES8311 + ES7210)` | `movecall_moji_esp32s3.cc:1507` |
|
||||
| AUDIO_INPUT_REFERENCE | **0** ← 没有参考通道接入 AEC | `config.h:27` |
|
||||
| mic_selected | `MIC1 \| MIC2`(**双 mic,无 REF**) | `box_audio_codec.cc:67` |
|
||||
| ES8311 输出 | 固定立体声(`STEREO + BOTH slot`) | `es8311_audio_codec.cc:105-109` |
|
||||
|
||||
**注意**:ES8311 必须是立体声输出,单声道会导致 RTC 入房失败(`04-2025-11-21音频优化记录.md` 已踩坑修复)。
|
||||
|
||||
### 3.3 AFE / audio_processor 状态
|
||||
|
||||
- `sdkconfig:642-645`:**`CONFIG_USE_AUDIO_PROCESSOR is not set`**、**`CONFIG_USE_WAKE_WORD_DETECT is not set`**、**`CONFIG_USE_CUSTOM_WAKE_WORD is not set`**
|
||||
- 代码已编写完整(`audio_processing/audio_processor.cc` + EchoAwareVadParams + AdaptiveNoiseState),但**整个文件未参与编译**(`CMakeLists.txt:167-169` 条件化)
|
||||
- AFE 依赖项 `espressif/esp-sr: ^2.0.3` 已声明(`idf_component.yml:8`)
|
||||
|
||||
### 3.4 AEC 反馈通道(关键风险点)
|
||||
|
||||
- **硬件层:当前未走 ES7210 REF 通道**(`AUDIO_INPUT_REFERENCE=0`)
|
||||
- 要启用 AFE-AEC 必须:
|
||||
1. 改板级配置改为 1
|
||||
2. 调整 mic_selected 加入 REF
|
||||
3. 确认 ES8311 输出经过 PCB 走线到 ES7210 REF 输入(Box 系列板默认已布好线,**Moji 板需确认**)
|
||||
- 同时 ES8311 输出立体声给 ES7210 REF(loopback 路径)
|
||||
- 软件层:AudioProcessor::Initialize 已写 AEC/VAD 初始化,缺的只是 sdkconfig 启用 + 板级 REF 启用
|
||||
|
||||
### TL;DR
|
||||
|
||||
**音频管线极其简陋(ESP-IDF + simple_pipeline stub)**。**AFE 整套代码已写好但未启用**,硬件层无 REF 通道。**比 Baji 项目更"裸"**——Baji 走的是一样的 codec 直写路径,没区别。
|
||||
|
||||
---
|
||||
|
||||
## 4. 已有功能清单
|
||||
|
||||
| 功能 | 实现位置 | 说明 |
|
||||
|---|---|---|
|
||||
| **BLE 配网** | `bluetooth_provisioning.cc`(1417 行) | **自定义 GATT 二进制协议**(Service 0xABF0),不是 BluFi。BluFi 编译开关 `CONFIG_BT_BLE_BLUFI_ENABLE=y` 启用但代码未调用 |
|
||||
| **生产测试模式** | `application.cc` "Airhub" 标签 | 触摸/IMU 自检上报 |
|
||||
| **本地 P3 播放** | `application.cc:300 PlaySound` | 走 `OnAudioOutput` → codec OutputData,**不走 player_pipeline** |
|
||||
| **HTTPS 故事** | `application.cc:SendStoryRequest + HttpsApiPlayback` | base64 Opus 解码 → 入 audio_decode_queue_ |
|
||||
| **HTTPS 音乐** | `application.cc:SendMusicRequest` | 同上 |
|
||||
| **IoT/MQTT** | `main/iot/thing.cc` | MQTT-UDP 协议保留,RTC 模式下未启用 |
|
||||
| **按键** | KEY4(GPIO4,故事键)+ BOOT(GPIO0) | `iot_button` 组件 |
|
||||
| **LED** | `BUILTIN_LED_GPIO=21`,SingleLed | |
|
||||
| **IMU** | QMI8658A(I2C 0x6A),运动检测唤醒/打断 | `movecall_moji_esp32s3.cc:838 InitializeImuSensor` |
|
||||
| **触摸** | 4 路 TouchPad(GPIO1/2/15/7) | `TouchEventTask`(line 1643) |
|
||||
| **电池** | GPIO6 ADC1_CHANNEL_5 | line 828 |
|
||||
| **OTA** | `main/ota.cc` | |
|
||||
| **天气** | `weather_api.cc` | |
|
||||
| **WakeWord** | 代码存在未编入 | |
|
||||
|
||||
文档参考:`README_RTC.md`、`02Kapi_Rtc_火山RTC替换实现方案.md`、`QMI8658A驱动适配方案_B站驱动.md`。
|
||||
|
||||
### TL;DR
|
||||
|
||||
**业务功能比 Baji 更精简**:无 LCD、无 LVGL、无 GIF 解码、无相册、无应援灯,但有 IMU + 4 路触摸。BLE 配网与 Baji 完全一致(同源代码)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 资源占用现状
|
||||
|
||||
### 5.1 Flash
|
||||
|
||||
- 分区 `partitions.csv`:nvs 16K + otadata 8K + model SPIFFS 3MB + ota_0/1 各 5MB = 13MB(16MB 板,剩 3MB 余量)
|
||||
- 实际固件大小约 3.5-4MB(同源代码估算),**OTA 分区 5MB 富余度极宽**
|
||||
|
||||
### 5.2 SRAM(关键)
|
||||
|
||||
- **运行日志显示 `free_heap=8289744`**(启动后约 8MB)→ 这是 **PSRAM + 内部 SRAM 总和**
|
||||
- Volc RTC 启动后跌到约 8.05M,运行中波动在 7.88-7.89M(subv 消息处理)
|
||||
- 没看到 internal SRAM 单独打印,但 BLE+RTC+ES7210+ES8311 在 ESP32-S3 N16R8 上 **runtime 内部 SRAM 余量约 80-130KB 是常见值**(比 Baji 多 30-50KB)
|
||||
- `SPIRAM_MALLOC_RESERVE_INTERNAL=65536` 保留 64KB
|
||||
|
||||
### 5.3 PSRAM
|
||||
|
||||
- 8MB Octal 80MHz,运行时空闲约 7.5-8M,**资源极其宽松**
|
||||
- Baji 是同款 S3-N16R8 模组,但 Baji 还要承载 LVGL(~50KB DRAM)+ 360×360 GIF 缓冲(~250KB PSRAM)+ JPEG 背景
|
||||
|
||||
### TL;DR
|
||||
|
||||
**Kapi 比 Baji 资源宽松约 300-500KB PSRAM + 30-50KB 内部 SRAM**(省掉 LVGL/GIF/相册)。Flash OTA 分区 5MB 完全够用。**AFE 启用预计需要 ~150-200KB PSRAM + 30KB 内部 SRAM**,资源**完全够**。
|
||||
|
||||
---
|
||||
|
||||
## 6. 与 Baji_Rtc_Toy 的差异
|
||||
|
||||
| 维度 | Kapi_Rtc_toy | Baji_Rtc_Toy |
|
||||
|---|---|---|
|
||||
| 模组 | ESP32-S3-N16R8 | ESP32-S3-N16R8(同款) |
|
||||
| 板型 | movecall-moji-esp32s3(无屏) | 同板加 LCD(QSPI ST77916 360×360) |
|
||||
| LVGL | ❌ 无 | ✅ 有,~50KB DRAM |
|
||||
| 数字人 GIF | ❌ 无 | ✅ 有,2 个透明 GIF(haru/hiyori) |
|
||||
| 应援灯 | ❌ 无 | ✅ DMA 直写 GRAM |
|
||||
| 双模式 (AI/吧唧) | ❌ 单模式 | ✅ NVS 切换 |
|
||||
| BLE 图传 | ❌ 无 | ✅ 0x0B00 服务 |
|
||||
| 触摸 LCD | ❌ 无 | ✅ CST816S |
|
||||
| 按键 | BOOT+KEY4 | BOOT+KEY2 |
|
||||
| IMU | ✅ QMI8658A | ❓ 待确认 |
|
||||
| 自定义 BLE 配网 | ✅ 0xABF0 | ✅ 0xABF0(同源) |
|
||||
| **Phase 6 软退出** | ❌ 无 | ✅ 已实现 |
|
||||
| **AFE/AEC** | ❌ 代码在未启用 | ❌ 代码在未启用(同源) |
|
||||
| Volc RTC SDK | volc_engine_rtc_lite | volc_engine_rtc_lite(同源) |
|
||||
|
||||
### TL;DR
|
||||
|
||||
**Kapi 是 Baji 的"无屏底座"**,节省约 300-500KB PSRAM + 30-50KB 内部 SRAM。RTC/BLE/codec 代码完全同源,**Phase 6 移植成本极低**。
|
||||
|
||||
---
|
||||
|
||||
## 7. 已有的 RTC/AEC/Opus 相关规划文档
|
||||
|
||||
| 文档 | 状态 | 关键内容 |
|
||||
|---|---|---|
|
||||
| `00Kapi_Rtc_火山RTC整合移植方案.md` | 已实施 | WS → 火山 RTC 总体方案 |
|
||||
| `01..._技术分析报告.md` | 已实施 | 用 volc_engine_rtc_lite 替换 WS |
|
||||
| `02..._火山RTC替换实现方案.md` | 已实施 | VolcRtcProtocol 具体实现 |
|
||||
| `03AEC_VOICE_INTERRUPT_PORTING_PLAN.md` | **计划,未实施** | Airhub_Rtc_h → Kapi 的 ES7210 双 mic + AEC + 语音打断移植方案。代码片段已示范 `aec_create + aec_process`,建议 `mic_selected` 改为 MIC1+MIC3,30dB 增益 |
|
||||
| `AEC_VAD_OPTIMIZATION.md` | 设计,部分已写入 audio_processor.cc | AEC+VAD 联合启用(`AEC_MODE_VOIP_LOW_COST` + `VAD_MODE_3`)、回声感知、动态阈值;EchoAwareVadParams 结构已在头文件 |
|
||||
| `04-2025-11-21音频优化记录.md` | 已实施修复 | 开机播报"尖锐声"修复:单声道 PCM 复制为立体声(`application.cc:1224-1230`);MONO I2S 会导致 RTC 入房失败 |
|
||||
| `VOICE_INTERRUPT_*.md` / `URGENT_INTERRUPT_FIX.md` / `BOOT_BUTTON_*` | 历史调试笔记 | 语音打断和按键交互优化记录 |
|
||||
|
||||
### TL;DR
|
||||
|
||||
**Kapi 已计划好"AFE-AEC + 语音打断"的实现路径但没落地**(03、AEC_VAD_OPTIMIZATION)。**Opus 上下行优化未在文档中提及**(当前 G711A 已可用)。
|
||||
|
||||
---
|
||||
|
||||
## 8. 三个移植/重构选项评估
|
||||
|
||||
### 选项 A:保持 ESP-IDF,移植 Baji Phase 6(软退出 + 字幕提示)
|
||||
|
||||
| 维度 | 评分 |
|
||||
|---|---|
|
||||
| 工作量 | **低**(1-2 天):基类加 `LeaveRoom()` + VolcRtcProtocol override + 应用层 hibernate 状态机 + B+C 双源刷新 |
|
||||
| 风险 | **低**:基类代码同源,`volc_rtc_destroy` 调用已存在(`volc_rtc_protocol.cc:32-34`),只需提取为独立接口 |
|
||||
| 资源占用 | **零**:只加几个原子标志和 NVS 计数器 |
|
||||
| 字幕提示效果 | **打折**:Kapi 无 LCD,`display->SetChatMessage` 是 noop(`Display` 是空对象 `movecall_moji_esp32s3.cc:1541`)。可改为 LED 闪烁或 P3 语音提示替代 |
|
||||
| 真退房收益 | **完全保留**:License 释放 + BOOT 唤醒 3-5s |
|
||||
| 兜底机制 | 保留 `idle_cycles_` 50 次重启兜底,无影响 |
|
||||
|
||||
**建议:✅ 强烈推荐**。除字幕提示需替换为语音/LED 外,**其他所有收益(真退房、快速恢复、状态保留)100% 适用**。这是性价比最高的优化。
|
||||
|
||||
---
|
||||
|
||||
### 选项 B:保持 ESP-IDF,启用 AFE + Opus 切换
|
||||
|
||||
#### B-1:启用 ESP-SR AFE(设备端 AEC)
|
||||
|
||||
| 维度 | 评分 |
|
||||
|---|---|
|
||||
| 工作量 | **中**(3-5 天):sdkconfig 三项打开 + board config `AUDIO_INPUT_REFERENCE=1` + box_audio_codec mic_selected 加入 MIC_REF + Application::OnAudioInput 走 AudioProcessor + ES8311→ES7210 loopback 验证 |
|
||||
| 风险 | **中**:① ES7210 REF 通道接线需硬件确认(Moji 板原理图待查);② AEC 调参(filter_length、AEC_MODE_VOIP_LOW_COST vs SR_LOW_COST);③ ES8311 立体声输出与单声道 AFE 输入的通道映射 |
|
||||
| 资源占用 | **+150-200KB PSRAM + 30KB 内部 SRAM + ~20% CPU**(Core 1) |
|
||||
| 收益 | **大**:从"无设备端 AEC"→"有 AEC",对话打断体验提升明显;目前打断完全依赖云端 VAD,延迟 1-3s(参考 03 文档结论) |
|
||||
|
||||
#### B-2:G711A → Opus 上行切换
|
||||
|
||||
| 维度 | 评分 |
|
||||
|---|---|
|
||||
| 工作量 | **中**(2-3 天):火山 SDK config 改 `"audio":{"codec":4}` 为 Opus(`volc_rtc_protocol.cc:76`),需上行编码改 OPUS(已有 `opus_encoder_` 实例),下行解码改 OPUS(已有 OpusDecoderWrapper) |
|
||||
| 风险 | **中**:① 火山服务端房间名 `aibotrtc_G711A_*` 暗示通道协商当前锁定 G711A,要确认服务端是否支持切 Opus;② 上行 Opus 60ms 帧比 G711A 20ms 帧延迟高 40ms |
|
||||
| 资源占用 | **+~10KB 内部 SRAM**(Opus 编码器) |
|
||||
| 收益 | **小到中**:Opus 比 G711A 在同等比特率下质量明显更高,但 G711A 在小 toy 设备上听感已经"够用"。**jitter buffer 优化更值得做** |
|
||||
|
||||
#### B-3:Jitter buffer 优化
|
||||
|
||||
- 当前 `audio_decode_queue_` 是无限增长的 std::list,无主动 jitter buffer 管理
|
||||
- 网络抖动时累积延迟,但**当前没收到具体抖动投诉**
|
||||
- 建议先做 A、B-1,确认音频体验之后再评估
|
||||
|
||||
**建议**:
|
||||
- B-1 (AFE-AEC) ✅ **推荐**,但**先确认 Moji 板硬件 REF 通道接线**(如果 REF 没飞线则只能软件回环 PCM,效果差很多)
|
||||
- B-2 (Opus) ⚠️ **不推荐先做**:服务端兼容性需求未明确,收益边际;先把 AEC 做对
|
||||
- B-3 (Jitter) ⚠️ **暂缓**:没具体痛点,纯优化无意义
|
||||
|
||||
---
|
||||
|
||||
### 选项 C:完全重构成 ESP-ADF + 官方 high_quality_solution
|
||||
|
||||
| 维度 | 评分 |
|
||||
|---|---|
|
||||
| 工作量 | **极高**(3-4 周):ESP-ADF 框架与当前 codec 直写架构差异巨大;ConversationalAI-Embedded-Kit-2.0 官方 demo 板 ESP32-S3-Korvo-2 与 Moji 引脚完全不同;BLE 配网/IMU/触摸/电池/HTTPS 故事/天气全部需要迁移 |
|
||||
| 风险 | **极高**:① ADF audio_pipeline 与 esp_codec_dev 不兼容,要全部重写 codec 路径;② ADF 自带 button/peripheral 与 iot_button 冲突;③ ESP-ADF eca11f20 版本要绑 IDF v5.4,可能引入新构建问题;④ 业务代码(HTTPS 故事/IMU/触摸/BLE)全部要适配 |
|
||||
| 资源占用 | **+200-400KB**(ADF 框架本体 + 多个 audio_element 任务) |
|
||||
| 收益 | **官方支持 + 高音质方案 (high_quality_first)**:官方持续维护,AEC + 噪声抑制 + AGC 全部内置;可能比手撸 AFE 体验更好 |
|
||||
| 兼容性 | Volc 官方 demo 用的就是这套;与火山服务端协议完美对齐 |
|
||||
|
||||
**建议:❌ 不推荐**,理由:
|
||||
1. 当前业务**已能跑通 RTC 对话**,没必要推翻重来
|
||||
2. ESP-ADF 引入的复杂度(pipeline / element / event)与当前轻量架构哲学冲突
|
||||
3. 板级适配(Moji 与 Korvo-2 引脚映射)工作量约等于重写整个项目
|
||||
4. 同等收益可以用"Phase 6 软退 + AFE 启用"的组合拳达到,工作量是 1/5
|
||||
|
||||
**例外**:如果未来要做**双麦克风 beamforming + 多说话人分离**等 ADF 高级特性,再考虑重构。
|
||||
|
||||
---
|
||||
|
||||
## 9. 最终推荐路线
|
||||
|
||||
按优先级递进:
|
||||
|
||||
1. **第 1 步(必做)**:移植 Baji Phase 6 软退出方案
|
||||
- 工作量 1-2 天,收益巨大(License 释放 + 唤醒 3-5s + 状态保留)
|
||||
- 字幕提示替换为 LED 闪烁 / `PlaySound(Lang::Sounds::P3_xxx)` 语音提示
|
||||
- 加上 B+C 双源刷新 `last_audible_output_time_`
|
||||
|
||||
2. **第 2 步(推荐)**:硬件确认 + 启用 ESP-SR AFE-AEC
|
||||
- 先 Moji 板原理图确认 ES7210 REF 是否接到 ES8311 输出
|
||||
- 如已飞线 → 启用 `AUDIO_INPUT_REFERENCE=1` + AudioProcessor + sdkconfig 三项
|
||||
- 如无飞线 → 评估软件 loopback 方案(Application 端拷贝 output PCM 作为 reference)
|
||||
|
||||
3. **第 3 步(按需)**:观察对话体验,再决定 Opus 上行 / Jitter buffer
|
||||
4. **第 4 步(不做)**:ESP-ADF 重构
|
||||
|
||||
---
|
||||
|
||||
## 10. 关键引用清单(绝对路径)
|
||||
|
||||
### Kapi_Rtc_toy 项目内
|
||||
- `main/CMakeLists.txt:235-239` — RTC 模式宏定义
|
||||
- `main/protocols/volc_rtc_protocol.cc:394-407` — CloseAudioChannel 只 stop 不 destroy
|
||||
- `main/protocols/volc_rtc_protocol.cc:32-34` — volc_rtc_destroy 已被析构函数调用,提取 LeaveRoom 极容易
|
||||
- `main/application.cc:1961-2042` — Dialog Watchdog 当前用 esp_restart()
|
||||
- `main/application.cc:2161` — 唯一的 last_audible_output_time_ 刷新点(方案 A)
|
||||
- `main/application.cc:1321` — subtitle 分支位置(方案 B 插入点)
|
||||
- `main/audio/simple_pipeline.cc:1-60` — codec 直写 stub,确认非 ESP-ADF
|
||||
- `main/audio_codecs/box_audio_codec.cc:67` — ES7210 mic_selected
|
||||
- `main/boards/movecall-moji-esp32s3/config.h:27` — `AUDIO_INPUT_REFERENCE 0`
|
||||
- `main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc:1507-1521` — BoxAudioCodec 创建
|
||||
- `sdkconfig:642-645` — AUDIO_PROCESSOR 未启用
|
||||
- `main/audio_processing/audio_processor.h:41-90` — AudioProcessor 已完整实现,等启用
|
||||
- `main/idf_component.yml:8` — esp-sr ^2.0.3 已声明
|
||||
- `05-最新日志.txt:160` — 房间名 `aibotrtc_G711A_*` 确认下行 G711A
|
||||
- `03AEC_VOICE_INTERRUPT_PORTING_PLAN.md` — AEC 移植规划(计划未实施)
|
||||
|
||||
### Baji_Rtc_Toy 衍生项目交叉引用
|
||||
- `/Users/rdzleo/Desktop/Baji_Rtc_Toy/docs/Rtc_AIavatar/RTC软退出方案_移植参考.md` — Phase 6 完整移植参考(手把手)
|
||||
- `/Users/rdzleo/Desktop/Baji_Rtc_Toy/docs/Rtc_AIavatar/官方Korvo2方案_对比分析报告.md` — 包含与官方 Korvo-2 的全方位对比、ES7210 AEC 电路分析、决策记录
|
||||
- `/Users/rdzleo/Desktop/Baji_Rtc_Toy/.planning/milestones/digital_human_rtc/phases/phase_06_idle_hibernate/PLAN.md` — Phase 6 实施计划
|
||||
- `/Users/rdzleo/Desktop/Baji_Rtc_Toy/.planning/milestones/digital_human_rtc/phases/phase_07_battery_psm/README.md` — Phase 7 占位规划
|
||||
|
||||
---
|
||||
|
||||
## 11. 一句话总结
|
||||
|
||||
> **Kapi_Rtc_toy 是 Baji_Rtc_Toy 的"无屏轻量版底座"**。Phase 6 软退出方案 100% 可移植且工作量极小(仅显示提示需替换为 LED/语音);AFE-AEC 资源富余但需先确认硬件 REF 通道;**坚决不推荐**重构成 ESP-ADF。
|
||||
|
||||
---
|
||||
|
||||
## 附录·重要提醒
|
||||
|
||||
🎯 **Kapi 是更合适的 AFE 实验场地**
|
||||
|
||||
Baji_Rtc_Toy 项目目前 internal SRAM 仅剩 **44KB**(参见 Baji 项目 `docs/Rtc_AIavatar/官方Korvo2方案_对比分析报告.md` §11.2),启用 AFE 后将仅剩 9KB,**几乎必然导致开机崩溃**。
|
||||
|
||||
而 Kapi_Rtc_toy 项目 internal SRAM 余量 **80-130KB**,启用 AFE 后仍有 **50-100KB 安全余量**。
|
||||
|
||||
**结论**:未来如要验证 ESP-SR AFE 启用方案,**应该优先在 Kapi 项目实验**,跑通后再回到 Baji 评估资源能否承载。
|
||||
Loading…
x
Reference in New Issue
Block a user