b1577d8418
fix: 软 RTC 退出待命音三连修 + 尾音延迟
...
问题与修复(按发现顺序):
【问题1】AudioLoop guard 冻结 OnAudioOutput → 待命音队列永远不被消费
- 现象: WaitForAudioPlayback 3秒超时, 无声
- 根因: EnterIdleHibernate Step 0 设 hibernating_=true, AudioLoop 顶层
if(hibernating_) continue 会同时跳过 OnAudioInput + OnAudioOutput,
PlaySound 入队的 Opus 永远不解码。
- 修复: guard 下沉到 OnAudioInput 入口(仅 input 侧关 codec 有 bad_alloc 风险),
OnAudioOutput 自带 codec->output_enabled() 保护。
【问题2】volc_rtc_stop 副作用关 I2S 通道 → codec 状态错位
- 现象: 听到杂音而非待命音; i2s_channel_disable "not enabled yet" 错误
- 根因: 火山 RTC SDK 的 stop 内部关闭 ES8311 I2S, 但 codec class 内部
output_enabled_ 标志仍是 true → 状态错位, PlaySound 写入到 disabled 的 I2S。
- 修复: EnterIdleHibernate 在 PlaySound 前显式 EnableOutput(false→true)
强制重新激活 I2S, 并灌 200ms silence 覆盖 DMA 残留。
【问题3 - 真因】protocol downlink_is_pcm_ 标志位污染 → Opus 被当 PCM 字节流写出
- 现象: 杂音仍在
- 根因: 火山 RTC 下行音频是 PCM, DataCallback 设 downlink_is_pcm_=true。
LeaveRoom 没重置这个 flag, 后续 hibernate 中 PlaySound 入队的 Opus 包,
OnAudioOutput 读到 protocol_->downlink_is_pcm() 返回 true →
treat_as_pcm=true → 跳过 opus_decoder, 直接把 Opus 编码字节当 int16
PCM 样本写到 codec → 杂音。
- 修复: VolcRtcProtocol::LeaveRoom 末尾重置 downlink_is_pcm_=false +
first_downlink_logged_=false。唤醒重连后 DataCallback 收到首包会立即
重新设置该 flag, 不影响欢迎语 PCM 播放。
【问题4】WaitForAudioPlayback 完成 ≠ DMA 输出完成 → 尾音被截
- 现象: 待命音能听见但提前结束约 1 秒
- 根因: WaitForAudioPlayback 只判断 audio_decode_queue_ 出队完毕。
OnAudioOutput 是 background_task Schedule 异步执行 codec write,
队列空 ≠ codec 写完; codec.Write 返回 ≠ I2S DMA + ES8311 FIFO 输出完毕。
- 修复: WaitForAudioPlayback 之后追加 background_task->WaitForCompletion +
vTaskDelay(1000) 让 DMA 尾音自然衰减, 才关 player_pipeline。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:29:09 +08:00
a3a476f857
feat: Phase 6 软退出方案 C+ — 修复待命音无声 + 唤醒重连失败
...
问题(上次提交 d5239cf 之后实测):
1. EnterIdleHibernate 触发的 LeaveRoom() 顺手关闭了 codec output:
LeaveRoom → on_audio_channel_closed_ → player_pipeline_close → EnableOutput(false)
导致后续 PlaySound(P3_KAKA_DAIMING) 入队后 AudioLoop 写不出声音,
WaitForAudioPlayback 3 秒超时退出, 用户听不到待命音。
2. LeaveRoom 调用 volc_rtc_destroy 后 rtc_handle_ = nullptr,
WakeFromHibernate → ToggleChatState → OpenAudioChannel 直接返回 false,
触发 2 秒重试循环, 同时每次失败回退 idle 都重新 PlaySound,
codec 状态震荡产生杂音, 服务端 AI 任务也无法重新加入房间。
方案 C+ 修复:
- Protocol::LeaveRoom() 新增 bool notify_closed=true 参数 (默认行为不变)。
- VolcRtcProtocol::LeaveRoom(notify_closed):
* 只 volc_rtc_stop, 不 volc_rtc_destroy, 保留 rtc_handle_ 供唤醒复用。
* notify_closed=false 时跳过 on_audio_channel_closed_, 不连带关 codec。
- EnterIdleHibernate:
* 调用 LeaveRoom(false) → codec output 保留。
* 手动 background_task_->WaitForCompletion + 清空队列 + 关麦克风。
* SetDeviceState(idle) 后 PlaySound 真正能播出来。
* WaitForAudioPlayback 完才 player_pipeline_close (这里再正常关 output)。
- WakeFromHibernate:
* 先放下 hibernating_ 让 AudioLoop guard 通过, 再 ToggleChatState。
* 因 rtc_handle_ 仍有效, OpenAudioChannel 走 volc_rtc_start 重启路径,
on_audio_channel_opened_ 回调重开 player_pipeline + 灌 200ms silence。
编译: kapi.bin 0x2e6330 (3.04MB), 分区 42% 空闲。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 17:43:29 +08:00
d5239cf471
docs: 决策分析报告 v1.1-v1.2 — Kapi 流畅根因 + 综合优化方案评估
...
v1.1 §12 Kapi 流畅根因实测对比:
- 同一份日志含 Baji+Kapi 在同一 Wi-Fi 下的 RTC 通话数据
- SSID/BSSID/RSSI 完全等价, 但 Baji reor=1790 / Kapi reor=0~226 (8 倍)
- 根因 1: Kapi WiFi 缓冲 16/16 vs Baji 8/10
- 根因 2: Kapi 无 LCD/LVGL/GIF, PSRAM 总线宽松
- 给出 Baji 卡顿最终定论(不是网络问题)
- 反向给 Kapi 的预防指导(未来加 LCD/动画的避坑)
v1.2 §12.7 综合内存 + GIF 4 方案评估(交叉引用 Baji v2.2):
- 同步否决方案 A (GIF EMBED 爆 OTA) + 方案 C (RGB565 Flash 不够)
- 同步推荐方案 B (通话期暂停 GIF)
- Kapi 本身无 LCD/GIF 不需做这些, 但作为底座项目记录
- 给未来 Kapi 加 LCD/动画的指导: 学 Baji 教训, 不要用 GIF 持续解码
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:51:36 +08:00
fe8173752d
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>
2026-05-14 14:37:29 +08:00
d8982c3569
1、新增讲故事和播放音乐的function call配置文件(原小智项目)
...
2、更新cJSON格式提交AgentConfig参数更新提示词(当前项目暂不需更新提示词)
2026-03-05 17:17:42 +08:00
f011b94efe
1、新增obtain_music Function Calling音乐播放功能,4处协议分支均支持URL直播和音乐API两种HTTPS方式;
...
2、Kconfig新增MUSIC_API_URL音乐播放API地址配置;
3、重构SendStoryRequest和SendMusicRequest为HttpsApiPlayback通用方法,消除故事/音乐播放~440行重复代码;
4、修正4处obtain_story注释和日志:WebSocket描述改为HTTPS API(与实际实现一致);
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:43:11 +08:00
dad9fe03ac
更新联网问答Agent参数为公司账户的bot_id
2026-03-05 14:18:58 +08:00
180057d427
设备注册RTC服务时,设备名称从Wi-Fi的MAC地址改为使用蓝牙的MAC地址
2026-03-05 13:31:59 +08:00
b9bbcc456c
1、新增HTTPS故事播放功能(SendStoryRequest通过蓝牙MAC请求故事API,支持intro+body两段式无缝播放);
...
2、新增HttpsPlaybackFromUrl通用HTTPS音频下载播放方法,obtain_story同时支持HTTPS URL和WebSocket两种方式;
3、新增RTC↔HTTPS双向音频切换三标志位状态机(opus_playback_active_/https_playback_active_/https_playback_abort_),HTTPS播放期间静默丢弃RTC PCM包,OnAudioOutput捕获is_opus_frame防止残留Opus帧杂音;
4、新增AbortHttpsPlayback中止方法,使用独立高优先级任务(priority=10)执行DMA flush;
5、协议层新增OnBotMessage回调,Bot下行消息立即中止HTTPS播放;volc_rtc_protocol移除is_binary依赖改为直接前缀检测,新增info前缀和subv跳过逻辑;
6、新增subtitle字幕消息解析,通过bot_前缀区分USER/AI,用户说话时立即中止HTTPS播放;
7、AbortSpeaking新增HTTPS中止信号和DMA缓冲区flush;
8、Kconfig新增STORY_API_URL故事播放API地址配置;
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 11:27:07 +08:00
d494a1025f
1、新增Function Calling的讲故事功能,可以语音获取小故事
2026-03-02 14:48:42 +08:00
7663018d4c
1、删除.cache文件
2026-03-02 14:47:12 +08:00
7431a630e4
1、注释了BLE JSON Service 相关实现代码,因为当前蓝牙通讯仍然使用二进制方式进行通讯,只是替换了之前官方的BluFi方式
2026-02-12 16:53:30 +08:00
60a2c7b068
1、所有日志和上报数据的MAC地址从WiFi MAC改为蓝牙MAC(eFuse读取,无需启动蓝牙);
...
2、电量上报扩展为设备状态上报,新增is_online/volume/brightness字段;
3、新增RTC火山引擎连接状态追踪(检测kDeviceStateDialog);
4、新增重启前上报设备离线状态(OnBeforeRestart虚方法);
5、重命名BATTERY_REPORT为DEVICE_STATUS_REPORT(Kconfig/变量/函数/日志);
6、对齐服务端接口:URL端口和路径修正,JSON字段名battery_level改为battery,移除wifi_rssi;
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:38:31 +08:00
903a61678c
1、Wi-Fi发送列表过滤了5G频段并且只发送最强信号的2.4G频段Wi-Fi;
...
2、测试脚本的蓝牙设备名称改为Airhub_开头
2026-02-10 18:28:35 +08:00
d7ec6a5e63
1、取消了蓝牙连接成功后发送蓝牙MAC地址的逻辑;
...
2、新增了蓝牙名称显示为“Airhub_”接蓝牙MAC地址的明文显示;
3、取消SDK配置蓝牙名称;
2026-02-10 16:16:28 +08:00
1a48e387a8
1、新增了蓝牙连接成功后发送蓝牙的MAC地址
2026-02-10 15:16:17 +08:00
94067d4adc
1、本次修改了关于BluFi关键字的日志和方法名称替换为Ble关键字
2026-02-10 15:00:57 +08:00
77c7283d09
重构蓝牙配网: 替换BluFi为自定义GATT Server,修复手机蓝牙不可见问题
...
核心改动:
- bluetooth_provisioning: 使用 esp_ble_gap_config_adv_data_raw() 原始广播
替代 BluFi API,采用自定义 GATT Server (Service 0xABF0, Write 0xABF1,
Notify 0xABF2) 实现二进制配网协议,保留全部WiFi配网业务逻辑
- ble_service: 广播包名称移至 Scan Response,避免超31字节限制;
GAP事件改用位掩码确保 adv_data 和 scan_rsp 都完成后再启动广播
- application: BLE JSON 服务从 Application 移至 WifiBoard 管理,
HandleBleJsonCommand 改为接收 BleJsonService 引用参数
- wifi_board: 新增 StartBleJsonProvisioning(),配网入口切换回
StartBluFiProvisioning() 使用重构后的 GATT Server
- 蓝牙设备名统一为 "Airhub_Ble"
- 配网模式下跳过电量上报,避免无WiFi时HTTP请求失败
- 新增 tests/ble_provision_test.py 配网协议测试脚本
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 14:32:55 +08:00
02ae116488
fix blue server
2026-02-10 10:54:42 +08:00
ea5050309e
修正了分压系数:根据满电电压4.2V和ADC读数更新电池电量
2026-01-29 10:06:38 +08:00
a54773f71a
Kapi_RTC版本初始化
2026-01-20 16:55:17 +08:00