speech_recognition icon indicating copy to clipboard operation
speech_recognition copied to clipboard

AssertionError: This audio source is already inside a context manager

Open vic047 opened this issue 2 years ago • 0 comments

Steps to reproduce

I am writing an Voice Assistant. It hears wake word and then should do stuff. I installed all the dependencies for speech_recognizion.

I have a recognizer class for wrapping the speech recognition libary

import speech_recognition as sr

class Recognizer(object):
    def __init__(self) -> None:
        self.__recognizer = sr.Recognizer()
        self.__mic = sr.Microphone()
        with self.__mic as source:
            self.__recognizer.adjust_for_ambient_noise(source, duration=0.2)
        self.__stop_listen = None
        self.__callback = None

    def listen(self):
        with self.__mic as source:
            try:
                audio = self.__recognizer.listen(source)
                return self.transcribe(audio)
            except sr.UnknownValueError or sr.RequestError as e:
                self.handle_recognizer_err(e)
                self.listen()

    def recognizer(self, text):
        ...

I also have a Speaker class for wrapping the tts libary ()

import pyttsx3 as tts

class Speaker:
    def __init__(self) -> None:
        self.__speaker = self.default_speaker()
        self.__stop_listen = None

    @staticmethod
    def default_speaker():
        speaker = tts.init()
        speaker.setProperty('rate', 150)
        voices = speaker.getProperty('voices')
        speaker.setProperty('voice', voices[0].id)
        return speaker

    def stopword_callback(self, words):
        print("Something was said!!", words)
        if r.is_stopword(words):
            self.__speaker.stop()
            self.__stop_listen()

    def say(self, msg):
        self.__speaker.say(msg)
        self.__speaker.runAndWait()
        self.__speaker.stop()

    # This is where the error occurs
    def say_stoppable(self, msg):
        self.__stop_listen = r.listen_in_bg(self.stopword_callback)
        self.__speaker.say(msg)
        self.__speaker.runAndWait()
        self.__speaker.stop()
        if callable(self.__stop_listen):
            self.__stop_listen()

Expected behaviour

I want to be able to abort the Assistant while he is speeking with a (or more) stop word(s). Therefore I try using the 'listen_in_background' function.

Actual behaviour

The thread from 'listen_in_background' throws an error

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\threading.py", line 973, in _bootstrap_inner
    self.run()
  File "C:\Program Files\Python39\lib\threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\SmokR\AppData\Roaming\Python\Python39\site-packages\speech_recognition\__init__.py", line 747, in threaded_listen
    with source as s:
  File "C:\Users\SmokR\AppData\Roaming\Python\Python39\site-packages\speech_recognition\__init__.py", line 186, in __enter__
    assert self.stream is None, "This audio source is already inside a context manager"
AssertionError: This audio source is already inside a context manager

System information

My system is "Windows 10 x64"

My Python version is Python 3.9.6

My Pip version is pip 23.0

My SpeechRecognition library version is 3.9.0

My PyAudio library version is 0.2.13

vic047 avatar Feb 10 '23 17:02 vic047