python-3.xspeech-recognitionraspberry-pi3snowboyraspbian-buster

Python: OSError: [Errno -9985] Device unavailable when using Snowboy and SpeechRecognition on Raspberry PI 3B+


I am building a personal assistant on my 3B+. What I am trying to do now is use Snowboy to detect my hotword (works flawlessly), then after the hotword is detected, use SpeechRecognizer to receive a voice command. Hotword detection works fine, the error happens when sr.Microphone() is called.

Example Code:

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)

I receive the following output:

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 works fine. The program runs as expected until the hotword is detected. I think it must have something to do with the fact that Snowboy and SpeechRecognition are trying to use the microphone. Also note that SpeechRecognition works fine on its own. If I create a program that just uses SpeechRecognition and not Snowboy, it works as expected.

I am using Python3 on the Raspberry Pi 3b+ running Raspbian Buster.

If I can provide more information, please let me know.


Solution

  • The solution is to terminate snowboy before initializing the microphone Ex:

    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)