Overflow – reader is not reading fast enough PyAudio

Question:

I’m currently trying to build a voice assistant with Python when I ran into a problem.
I’m using porcupine/picovoice for wakeword detection and then I call a function that recognizes everything I say as soon as I call it.

This is the function:

def recognizevoicecommand():
    try:
        r = sr.Recognizer()
        print("A moment of silence, please...")
        with sr.Microphone() as source:
            time.sleep(2)
            r.adjust_for_ambient_noise(source)
        print("Set minimum energy threshold to {}".format(r.energy_threshold))
        while True:
            print("Say something!")
            with m as source:
                time.sleep(2)
                print("Now!")
                audio = r.listen(source)
            print("Got it! Now to recognize it...")
            try:
    # recognize speech using Google Speech Recognition
                value = r.recognize_google(audio)
                print(value)
                return value
                break
            except sr.UnknownValueError():
                print("OOps")
                break
    except KeyboardInterrupt:
        pass

If i just call the function alone, it works perfectly fine, recognizes what I say and then prints it out.

But the problem is that as soon as I use it together with the wakeword detector, I get spammed with
Overflow – reader is not reading fast enough
after
A moment of silence, please…
is printed out.

This is the wakeword detection code, works fine on it’s own as well as in the script, the problem seems to be in the recognizing part

    porcupine = pvporcupine.create(access_key = accesskey, keywords=['computer'])
    recorder = PvRecorder(device_index = 0, frame_length = porcupine.frame_length)
    recorder.start()

    while True:
        pcm = recorder.read()
         
        result = porcupine.process(pcm)
        if(result >= 0):
            print("Keyword detected")
            print(recognizevoicecommand())
except pvporcupine.PorcupineInvalidArgumentError as e:
    print("One or more arguments provided to Procupine is invalid!")
    raise e
except pvporcupine.PorcupineActivationError as e:
    print("Accesskey denied.")
    raise e
except pvporcupine.PorcupineActivationLimitError as e:
    print("Accesskey has reached it's temporary device limit.")
    raise e
except pvporcupine.PorcupineActivationRefusedError as e:
    print("Accesskey refused.")
    raise e
except pvporcupine.PorcupineActivationThrottledError as e:
    print("Accesskey has been throttled.")
    raise e
except pvporcupine.PorcupineError as e:
    print("Failed to initialize Porcupine.")
    raise e
except KeyboardInterrupt:
    print("Stopping")
finally:
    if porcupine is not None:
        porcupine.delete()
    if recorder is not None:
        recorder.delete()

I am honestly clueless why its not working. Hope to find a solution tho!

Asked By: kingofsquirrel

||

Answers:

I’m working on a similar task and running into the same issue. I’ve found that the solution is to avoid using two different means of recording audio.

The PvRecorder class represents the recorded data as signed integers.

pcm = recorder.read() 
result = porcupine.process(pcm)

This is different AFAIK than how wav data is typically stored in an audio file. If you look to how PvRecorder saves wav files, you can see they use the struct module:

sp = struct.pack("h" * len(pcm), *pcm)

You can use that to construct the audio file to pass along.
I’m using it with Vosk and it works great!

if self.rec.AcceptWaveform(sp):
    res = json.loads(self.rec.Result())
    if res["text"] != "":
        print(res["text"])
Answered By: Rose

I ran in to the same error and it seems to be – as others have indicated – the result of the audio device being used by more than one process. I resolved it by stopping the Pico Voice recorder while the other action was taking place and then starting it again:

# Standard setup
recorder = PvRecorder(
    device_index=self._device_index,
    frame_length=self._picovoice.frame_length,
)
recorder.start()

# Stop the recordeer
recorder.stop()

# Run other function here that uses the device

# Start the recorder again
recorder.start()
Answered By: Maggie
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.