wzpan / wukong-robot

🤖 wukong-robot 是一个简单、灵活、优雅的中文语音对话机器人/智能音箱项目,支持ChatGPT多轮对话能力,还可能是首个支持脑机交互的开源智能音箱项目。
https://wukong.hahack.com/
MIT License
6.36k stars 1.34k forks source link

CRITICAL:snowboy:[Errno Device unavailable] -9985 #147

Closed siemenliu closed 3 years ago

siemenliu commented 3 years ago

确认已寻找过答案

我已确认在 Github issue 页、常见问题页、文档 中都查找过,没有找到类似问题和资料。我也没有 google / bing/ 百度 / duckduckgo 到相关解答。

安装方式

docker安装

操作系统

Raspbian

问题描述

遇到问题场景

打开极客模式或者pardon时会报错。(pardon下默认判断词是''我改成‘嗯’,因为我不给麦克风任何输入音识别结果就是'嗯')

问题描述

无法进入二次录音

INFO:snowboy:Keyword 1 detected at time: 2021-05-01 01:33:56
INFO:__main__:开始录音
INFO:robot.Conversation:结束录音
INFO:robot.ASR:baidu-asr 语音识别到了:['嗯']
INFO:robot.TTS:baidu-tts 语音合成成功,合成路径:/tmp/tmpu9rigvyh.mp3
Expression 'ret' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1736
Expression 'AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1904
Expression 'PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2171
Expression 'PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2840
CRITICAL:snowboy:[Errno Device unavailable] -9985
INFO:robot.AI:emotibot 回答:抱歉, 我的大脑短路了,请稍后再试试.
INFO:robot.Conversation:命中缓存,播放缓存语音
wzpan commented 3 years ago

试试更新到最新版本的wukong-robot?刚修复了用户录音会带上 beep_hi 提示音的 bug ,所以你应该不用改 pardon 的判断词。

siemenliu commented 3 years ago

感谢作者,使用了最新master代码后:

  1. 不说话是会识别成'嗯',不会进入pardon,我用的麦克风是ReSpeaker 2-Mics Pi HAT
  2. 极客模式进入就还是会报错

我尝试修改了下snowboydecoder.py中,将audio.open后的stream_in进行管理,每次open前先关闭现有打开的就可以规避这个问题,但是pardon触发后无法监听到唤醒词了。

感觉问题像是硬件资源占用冲突问题?

root@555d4c7d8c87:~/wukong-robot# python3 wukong.py 

********************************************************
*          wukong-robot - 中文语音对话机器人           *
*          (c) 2019 潘伟洲 <m@hahack.com>              *
*     https://github.com/wzpan/wukong-robot.git        *
********************************************************

            后台管理端:http://0.0.0.0:5000
            如需退出,可以按 Ctrl-4 组合键

INFO:snowboy:Keyword 1 detected at time: 2021-05-03 23:32:10
INFO:__main__:开始录音
INFO:robot.Conversation:结束录音
INFO:robot.ASR:baidu-asr 语音识别到了:['嗯']
INFO:robot.AI:emotibot 回答:叮当出去一下,请稍等片刻,马上回来~~
INFO:robot.TTS:baidu-tts 语音合成成功,合成路径:/tmp/tmpq13u45is.mp3
INFO:snowboy:Keyword 1 detected at time: 2021-05-03 23:32:27
INFO:__main__:开始录音
INFO:robot.Conversation:结束录音
INFO:robot.ASR:baidu-asr 语音识别到了:['进入即刻模式']
INFO:robot.Brain:'进入即刻模式' 命中技能 Geek
INFO:robot.TTS:baidu-tts 语音合成成功,合成路径:/tmp/tmp1in5_95p.mp3
Expression 'ret' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1736
Expression 'AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1904
Expression 'PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2171
Expression 'PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2840
CRITICAL:snowboy:[Errno Device unavailable] -9985
Expression 'ret' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1736
Expression 'AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1904
Expression 'PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2171
Expression 'PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2840
CRITICAL:snowboy:[Errno Device unavailable] -9985
Expression 'ret' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1736
Expression 'AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1904
Expression 'PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2171
Expression 'PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2840
CRITICAL:snowboy:[Errno Device unavailable] -9985
Expression 'ret' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1736
Expression 'AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1904
Expression 'PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2171
Expression 'PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2840
CRITICAL:snowboy:[Errno Device unavailable] -9985
Expression 'ret' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1736
Expression 'AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1904
Expression 'PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2171
Expression 'PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2840
CRITICAL:snowboy:[Errno Device unavailable] -9985
INFO:robot.TTS:baidu-tts 语音合成成功,合成路径:/tmp/tmp96_1jq5k.mp3
^\Quit (core dumped)
root@555d4c7d8c87:~/wukong-robot# git pull
Already up-to-date.
root@555d4c7d8c87:~/wukong-robot# git branch
* master
root@555d4c7d8c87:~/wukong-robot#
siemenliu commented 3 years ago

这是我管理了stream_in后的效果,极客模式正常可以多轮应答,但一旦进入pardon后,完成一轮应答就无法再次唤醒词激活了,但不确定这种修改方式是否合适。

@@ -114,6 +117,11 @@ class ActiveListener(object):
         logger.debug('opening audio stream')

         try:
+            global stream_in_hotword
+            if stream_in_hotword is not None:
+                stream_in_hotword.stop_stream()
+                stream_in_hotword.close()
+
             self.stream_in = self.audio.open(
                 input=True, output=False,
                 format=self.audio.get_format_from_width(
@@ -122,6 +130,9 @@ class ActiveListener(object):
                 rate=self.detector.SampleRate(),
                 frames_per_buffer=2048,
                 stream_callback=audio_callback)
+
+            global stream_in_active
+            stream_in_active = self.stream_in
         except Exception as e:
             logger.critical(e)
             return 
@@ -300,6 +321,12 @@ class HotwordDetector(object):

         with no_alsa_error():
             self.audio = pyaudio.PyAudio()
+
+        global stream_in_active
+        if stream_in_active is not None:
+            stream_in_active.stop_stream()
+            stream_in_active.close()
+
         self.stream_in = self.audio.open(
             input=True, output=False,
             format=self.audio.get_format_from_width(
@@ -308,6 +335,8 @@ class HotwordDetector(object):
             rate=self.detector.SampleRate(),
             frames_per_buffer=2048,
             stream_callback=audio_callback)
+        global stream_in_hotword
+        stream_in_hotword = self.stream_in

         if interrupt_check():
             logger.debug("detect voice return")
********************************************************
*          wukong-robot - 中文语音对话机器人           *
*          (c) 2019 潘伟洲 <m@hahack.com>              *
*     https://github.com/wzpan/wukong-robot.git        *
********************************************************

            如需退出,可以按 Ctrl-4 组合键。

INFO:snowboy:Keyword 1 detected at time: 2021-05-03 23:46:10
INFO:__main__:开始录音
INFO:robot.Conversation:结束录音
INFO:robot.ASR:baidu-asr 语音识别到了:['进入即刻模式']
INFO:robot.Brain:'进入即刻模式' 命中技能 Geek
INFO:robot.Conversation:命中缓存,播放缓存语音
INFO:robot.ASR:baidu-asr 语音识别到了:['你是谁']
INFO:robot.AI:emotibot 回答:叮当出去一下,请稍等片刻,马上回来~~
INFO:robot.Conversation:命中缓存,播放缓存语音
INFO:robot.ASR:baidu-asr 语音识别到了:['哪个招呼']
INFO:robot.AI:emotibot 回答:叮当出去一下,请稍等片刻,马上回来~~
INFO:robot.Conversation:命中缓存,播放缓存语音
INFO:robot.ASR:baidu-asr 语音识别到了:['打个招呼']
INFO:robot.Brain:'打个招呼' 命中技能 HelloWorld
INFO:robot.Conversation:命中缓存,播放缓存语音
INFO:robot.ASR:baidu-asr 语音识别到了:['嗯']
INFO:robot.ASR:baidu-asr 语音识别到了:['嗯']
INFO:robot.TTS:baidu-tts 语音合成成功,合成路径:/tmp/tmphiuwdzwy.mp3
INFO:robot.ASR:baidu-asr 语音识别到了:['嗯']
INFO:robot.TTS:baidu-tts 语音合成成功,合成路径:/tmp/tmpyrbtambx.mp3
wzpan commented 3 years ago

因为在我的设备(MacBook)上不能复现这个问题,所以难以帮你诊断这个问题。

但是我看你定义了好多个 stream_in 。有 stream_in_hotwordstream_instream_in_active 等等。这些是不能同时工作的,否则会发生资源抢占冲突。所以不建议你这么修改。

不说任何话被误识别成 “嗯” 后,这种情况通常是你的麦克风底噪比较大导致。此时识别成 “嗯” 后也不应该走 pardon 逻辑,而是直接丢弃。可以修改 这里 ,改为:

    def onAsk(self, input):
        if input and input != '嗯':  # 识别为 '嗯' 后当成无输入,丢弃结果
            logger.debug('input: {}'.format(input))
            self.silent_count = 0
            self.con.doResponse(input)
        else:
            self.silent_count += 1
            if self.silent_count >= 5:
                self.say('退出极客模式', cache=True)
                self.clearImmersive()
            else:
                self.onAsk(self.activeListen(silent=True))
siemenliu commented 3 years ago

因为在我的设备(MacBook)上不能复现这个问题,所以难以帮你诊断这个问题。

但是我看你定义了好多个 stream_in 。有 stream_in_hotwordstream_instream_in_active 等等。这些是不能同时工作的,否则会发生资源抢占冲突。所以不建议你这么修改。

不说任何话被误识别成 “嗯” 后,这种情况通常是你的麦克风底噪比较大导致。此时识别成 “嗯” 后也不应该走 pardon 逻辑,而是直接丢弃。可以修改 这里 ,改为:

    def onAsk(self, input):
        if input and input != '嗯':  # 识别为 '嗯' 后当成无输入,丢弃结果
            logger.debug('input: {}'.format(input))
            self.silent_count = 0
            self.con.doResponse(input)
        else:
            self.silent_count += 1
            if self.silent_count >= 5:
                self.say('退出极客模式', cache=True)
                self.clearImmersive()
            else:
                self.onAsk(self.activeListen(silent=True))

好的,我再研究下,感谢。目前看这么干可以,树莓派上必须遵循在某个audio.open时,上一个open的stream需要close才可以正常工作。这块如果我找到更好的解决方案再来交PR,这里先关了。