Python: OSError: [Errno -9985] Device unavailable when using Snowboy and SpeechRecognition on Raspberry PI 3B+
Python: OSError: [Errno -9985] Device unavailable when using Snowboy and SpeechRecognition on Raspberry PI 3B+
我正在我的 3B+ 上构建个人助理。我现在想做的是使用 Snowboy 检测我的热词(完美无缺),然后在检测到热词后,使用 SpeechRecognizer 接收语音命令。热词检测工作正常,调用 sr.Microphone() 时发生错误。
示例代码:
import speech_recognition as sr
import snowboydecoder
def detected_callback():
r = sr.Recognizer()
with sr.Microphone() as source:
print('Ready...')
r.adjust_for_ambient_noise(source, duration=.2)
audio = r.listen(source)
try:
command = r.recognize_google(audio).lower()
print('You said: ' + command + '\n')
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
comand = None
detector = snowboydecoder.HotwordDetector("SnowboyDependencies/Ancilla.pmdl", sensitivity=.5, audio_gain=1)
detector.start(detected_callback)
我收到以下输出:
INFO:snowboy:Keyword 1 detected at time: 2020-03-24 21:53:35
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
Traceback (most recent call last):
File "sttTest.py", line 43, in <module>
detector.start(detected_callback)
File "/home/pi/AncillaFiles/SnowboyDependencies/snowboydecoder.py", line 221, in start
callback()
File "sttTest.py", line 27, in detected_callback
with sr.Microphone(device_index = 2, sample_rate = 44100, chunk_size = 512) as source:
File "/home/pi/.local/lib/python3.7/site-packages/speech_recognition/__init__.py", line 141, in __enter__
input=True, # stream is an input stream
File "/usr/local/lib/python3.7/dist-packages/pyaudio.py", line 750, in open
stream = Stream(self, *args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/pyaudio.py", line 441, in __init__
self._stream = pa.open(**arguments)
OSError: [Errno -9985] Device unavailable
Snowboy 工作正常。程序按预期运行,直到检测到热词。我认为这一定与 Snowboy 和 SpeechRecognition 试图使用麦克风这一事实有关。另请注意,SpeechRecognition 本身可以正常工作。如果我创建一个只使用 SpeechRecognition 而不是 Snowboy 的程序,它会按预期工作。
我在 Raspberry Pi 3b+ 运行 Raspbian Buster 上使用 Python3。
如果我能提供更多信息,请告诉我。
解决方法是在初始化麦克风之前终止snowboy
例如:
import speech_recognition as sr
import snowboydecoder
def detected_callback():
detector.terminate() #change here
r = sr.Recognizer()
with sr.Microphone() as source:
print('Ready...')
r.adjust_for_ambient_noise(source, duration=.2)
audio = r.listen(source)
try:
command = r.recognize_google(audio).lower()
print('You said: ' + command + '\n')
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
comand = None
detector = snowboydecoder.HotwordDetector("SnowboyDependencies/Ancilla.pmdl", sensitivity=.5, audio_gain=1)
detector.start(detected_callback)
问题是,两者(Snowboy 和 SpeechRec)都尝试连接到您的麦克风。并且第二次连接尝试将被拒绝。
几天前我遇到了同样的问题。 @Mezex 的解决方案很好,在我的情况下需要很长时间才能关闭 Snowboy 并打开 SpeechRec(大约 2 或 3 秒,直到它准备好收听)
我的方案参考了ALSA。有个插件叫dsnoop
,有点类似于设备文件,可以被多个程序调用。
文件 /etc/asound.config
决定了如何处理您的 hole 操作系统的声音。如果将其更改为:
defaults.pcm.rate_converter "samplerate"
pcm.!default {
type asym
playback.pcm "playback"
capture.pcm "capture"
}
pcm.playback {
type plug
slave.pcm "dmixed"
}
pcm.capture {
type plug
slave.pcm "array"
}
pcm.dmixed {
type dmix
slave.pcm "hw:name_of_your_speaker"
ipc_key 555555
}
pcm.array {
type dsnoop
slave {
pcm "hw:name_of_your_Mic"
channels 2
}
ipc_key 666666
}
并删除您的 ~/asoundrc
文件,它应该可以工作。
您将通过arecord -l
获得您麦克风的名称
In my case it is "wm8960soundcard"
默认调用pcm.!default
。它引用 caputre
的输入流(您的麦克风),它引用 array
。这是通过多个任务同时调用的 type dsnoop
。
看看https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html,插件列表都有
我知道这有点复杂,但对我来说这是最好的解决方案。希望对您有所帮助。
我正在我的 3B+ 上构建个人助理。我现在想做的是使用 Snowboy 检测我的热词(完美无缺),然后在检测到热词后,使用 SpeechRecognizer 接收语音命令。热词检测工作正常,调用 sr.Microphone() 时发生错误。
示例代码:
import speech_recognition as sr
import snowboydecoder
def detected_callback():
r = sr.Recognizer()
with sr.Microphone() as source:
print('Ready...')
r.adjust_for_ambient_noise(source, duration=.2)
audio = r.listen(source)
try:
command = r.recognize_google(audio).lower()
print('You said: ' + command + '\n')
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
comand = None
detector = snowboydecoder.HotwordDetector("SnowboyDependencies/Ancilla.pmdl", sensitivity=.5, audio_gain=1)
detector.start(detected_callback)
我收到以下输出:
INFO:snowboy:Keyword 1 detected at time: 2020-03-24 21:53:35
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
Traceback (most recent call last):
File "sttTest.py", line 43, in <module>
detector.start(detected_callback)
File "/home/pi/AncillaFiles/SnowboyDependencies/snowboydecoder.py", line 221, in start
callback()
File "sttTest.py", line 27, in detected_callback
with sr.Microphone(device_index = 2, sample_rate = 44100, chunk_size = 512) as source:
File "/home/pi/.local/lib/python3.7/site-packages/speech_recognition/__init__.py", line 141, in __enter__
input=True, # stream is an input stream
File "/usr/local/lib/python3.7/dist-packages/pyaudio.py", line 750, in open
stream = Stream(self, *args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/pyaudio.py", line 441, in __init__
self._stream = pa.open(**arguments)
OSError: [Errno -9985] Device unavailable
Snowboy 工作正常。程序按预期运行,直到检测到热词。我认为这一定与 Snowboy 和 SpeechRecognition 试图使用麦克风这一事实有关。另请注意,SpeechRecognition 本身可以正常工作。如果我创建一个只使用 SpeechRecognition 而不是 Snowboy 的程序,它会按预期工作。
我在 Raspberry Pi 3b+ 运行 Raspbian Buster 上使用 Python3。
如果我能提供更多信息,请告诉我。
解决方法是在初始化麦克风之前终止snowboy 例如:
import speech_recognition as sr
import snowboydecoder
def detected_callback():
detector.terminate() #change here
r = sr.Recognizer()
with sr.Microphone() as source:
print('Ready...')
r.adjust_for_ambient_noise(source, duration=.2)
audio = r.listen(source)
try:
command = r.recognize_google(audio).lower()
print('You said: ' + command + '\n')
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
comand = None
detector = snowboydecoder.HotwordDetector("SnowboyDependencies/Ancilla.pmdl", sensitivity=.5, audio_gain=1)
detector.start(detected_callback)
问题是,两者(Snowboy 和 SpeechRec)都尝试连接到您的麦克风。并且第二次连接尝试将被拒绝。
几天前我遇到了同样的问题。 @Mezex 的解决方案很好,在我的情况下需要很长时间才能关闭 Snowboy 并打开 SpeechRec(大约 2 或 3 秒,直到它准备好收听)
我的方案参考了ALSA。有个插件叫dsnoop
,有点类似于设备文件,可以被多个程序调用。
文件 /etc/asound.config
决定了如何处理您的 hole 操作系统的声音。如果将其更改为:
defaults.pcm.rate_converter "samplerate"
pcm.!default {
type asym
playback.pcm "playback"
capture.pcm "capture"
}
pcm.playback {
type plug
slave.pcm "dmixed"
}
pcm.capture {
type plug
slave.pcm "array"
}
pcm.dmixed {
type dmix
slave.pcm "hw:name_of_your_speaker"
ipc_key 555555
}
pcm.array {
type dsnoop
slave {
pcm "hw:name_of_your_Mic"
channels 2
}
ipc_key 666666
}
并删除您的 ~/asoundrc
文件,它应该可以工作。
您将通过arecord -l
获得您麦克风的名称
In my case it is "wm8960soundcard"
默认调用pcm.!default
。它引用 caputre
的输入流(您的麦克风),它引用 array
。这是通过多个任务同时调用的 type dsnoop
。
看看https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html,插件列表都有
我知道这有点复杂,但对我来说这是最好的解决方案。希望对您有所帮助。