xiaozhi-esp32 icon indicating copy to clipboard operation
xiaozhi-esp32 copied to clipboard

小智 IOT 操作时的语音控制问题

Open jiangyanfeng opened this issue 7 months ago • 15 comments

Is your feature request related to a problem?

能否让小智在语音识别后, IOT 调用对应函数的时候,播放完输出内容后,不再切换为 Listening 状态? 目前在做本地 TF 卡音乐的播放,如果直接在 IOT 响应函数里切换状态的话,会导致小智的语音播放不出来。

另外,可否设计小智在关闭服务器连接前不要再语音通知?因为本地 TF 卡音乐播放会被打断。

希望能提供接口实现上述功能。

Describe the solution you'd like.

No response

Describe alternatives you've considered.

No response

Additional context.

No response

jiangyanfeng avatar May 16 '25 05:05 jiangyanfeng

建议在你的IoT函数里直接CloseAudioChannel。

78 avatar May 16 '25 10:05 78

建议在你的IoT函数里直接CloseAudioChannel。

可以,试了下效果达到。麻烦在 Application.h 中添加对应接口:

    void CloseAudioInput() {
        protocol_->CloseAudioChannel();
    }

jiangyanfeng avatar May 17 '25 04:05 jiangyanfeng

也可以判断如果当前 device state 是 listening,则调用一下 Application::ToggleChatState

78 avatar May 17 '25 08:05 78

也可以判断如果当前 device state 是 listening,则调用一下 Application::ToggleChatState 对,谢谢提醒。 如果能增加状态改变回调就更好了。OnDeviceStateChanged()

jiangyanfeng avatar May 17 '25 13:05 jiangyanfeng

你好麻烦请教一下你音乐播放器是不是用adf实现的

bao17634 avatar May 18 '25 13:05 bao17634

你好麻烦请教一下你音乐播放器是不是用adf实现的

是的。碰到的坑太多了,有些到现在还没填平。ADF 里面有些库不是开源的,只提供了静态库文件和头文件,debug 起来可麻烦了。

另外,由于对ESP32硬件不熟悉,内存分配也走了很多弯路。std::map 的表现就和 x86 上的 std::map 不一样,也不敢对框架改太多,怕影响后面版本的合入。

jiangyanfeng avatar May 18 '25 14:05 jiangyanfeng

你好麻烦请教一下你音乐播放器是不是用adf实现的

是的。碰到的坑太多了,有些到现在还没填平。ADF 里面有些库不是开源的,只提供了静态库文件和头文件,debug 起来可麻烦了。

另外,由于对ESP32硬件不熟悉,内存分配也走了很多弯路。std::map 的表现就和 x86 上的 std::map 不一样,也不敢对框架改太多,怕影响后面版本的合入。

我现在就是这种感觉,只能新建文件,不敢改太多,C++我的基础也很薄弱

bao17634 avatar May 18 '25 14:05 bao17634

我在播放音乐的时候复用的音频复用的是audio_code功能,我在启用audio_code的时候然后里面就有个现成禁用了,导致一直无法播放

Image

bao17634 avatar May 25 '25 14:05 bao17634

可以更新一下 last_output_time_ 避免被关闭。

78 avatar May 25 '25 15:05 78

我在播放音乐的时候复用的音频复用的是audio_code功能,我在启用audio_code的时候然后里面就有个现成禁用了,导致一直无法播放

Image

你解码成 PCM 后,直接 codec->OutputData(pcm); 就可以播放音乐了。

jiangyanfeng avatar May 26 '25 00:05 jiangyanfeng

也可以判断如果当前 device state 是 listening,则调用一下 Application::ToggleChatState 对,谢谢提醒。 如果能增加状态改变回调就更好了。OnDeviceStateChanged()

目前是使用下面代码实现的,但是会在切换时咔哒一声。如果有状态改变回调函数使用就好了。 @78 xTaskCreate([](void* arg) { auto& app = Application::GetInstance(); auto last = std::chrono::steady_clock::now(); while (1) { auto state = app.GetDeviceState(); if (state == kDeviceStateListening) { app.ToggleChatState(); break; } else if (state == kDeviceStateIdle) { break; } vTaskDelay(pdMS_TO_TICKS(200)); } vTaskDelete(NULL); }, "idle_task", 2048, NULL, 1, NULL);

jiangyanfeng avatar May 26 '25 00:05 jiangyanfeng

你可以先自己加个回调功能。

78 avatar May 26 '25 02:05 78

我在播放音乐的时候复用的音频复用的是audio_code功能,我在启用audio_code的时候然后里面就有个现成禁用了,导致一直无法播放 Image

你解码成 PCM 后,直接 codec->OutputData(pcm); 就可以播放音乐了。

这个是不要求设备在“说话中”且audio_code开启

bao17634 avatar May 26 '25 02:05 bao17634

@bao17634 不要求说话中,也不要求 codec output enable,因为这里已经绕开了那部分逻辑了。 相反,为了避免和小智AI的说话冲突,需要在小智AI说话时,关闭音乐输出;在小智AI收听时,也关闭音乐输出。但在执行完IOT命令,准备播放音乐前,等待小智说话完成后,小智切换为 listening 状态时,将其状态换成 idle 状态然后播放音乐。

jiangyanfeng avatar May 26 '25 02:05 jiangyanfeng

为了避免和小智AI的说话冲突

老哥能加个qq或者微信吗,真的想跟你请教下,我现在就是在执行完lot断开连接的,但还是播放不了声音

bao17634 avatar May 26 '25 02:05 bao17634