I've just connected python to arduino in order to use vocal input. However the main problem is not in arduino but in python
import speech_recognition as sr
import time
while True:
r = sr.Recognizer()
with sr.Microphone() as source:
audio = r.listen(source)
a = (r.recognize_google(audio))
print(a)
if a == 'light on':
print('ON')
if a == 'switch off':
print('OFF')
Sometimes it returns a NameError: a not defined, so a is not neither None. It happens only as first input. If it recognizes the first command (eg. switch off) it wouldn't happen in the whole runtime.
While sometimes it crashes while running and gives this error:
File "C:\Program Files (x86)\Python36-32\lib\site-packages\speech_recognition\__init__.py", line 858, in recognize_google
if not isinstance(actual_result, dict) or len(actual_result.get("alternative", [])) == 0: raise UnknownValueError()
speech_recognition.UnknownValueError
I can see it, of course, only if I comment out try...except...
try:
a = (r.recognize_google(audio))
print(a)
except:
pass
if a == 'light on':
arduino.write('H'.encode())
if an Exception occurs, a will not defined later and the program will crash.
Do e.g.
try:
a = r.recognize_google(audio)
except NameError:
print('error') # use `traceback`
a = None
Related
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!
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"])
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()
I am a Portuguese High Schooler so sorry if I dont make myself very clear but I will try my best to explain my problem.
So for this project I need to make a program that recognises speech and do what is told to do. But if the speech is not recognisable I want the program to try until it finally catches what is being said. However I dont really know how to do that since this "error" keeps appearing: Error
Here is the code if anyone wants to help:
import speech_recognition as sr
import subprocess as sp
import os
def ouvir_microfone():
audio_Input = sr.Recognizer()
with sr.Microphone() as source:
Ray = "ON"
Open = "Open"
print("Hello my name is Ray pleased to help you")
audio_Input.adjust_for_ambient_noise(source)
print("Say something: ")
audio = audio_Input.listen(source)
frase = audio_Input.recognize_google(audio,language='en-US')
if ValueError: print("Speech not recognised")
else: print("You said: " + frase)
if Open in frase:
print('sucess')
ouvir_microfone()
Use try and exception to handle the error
try:
frase = audio_Input.recognize_google(audio,language='en-US')
print("You said: " + frase)
except ValueError:
print("Speech not recognised")
if Open in frase:
print('sucess')
import speech_recognition as sr
import subprocess as sp
import os
def ouvir_microfone():
audio_Input = sr.Recognizer()
with sr.Microphone() as source:
Ray = "ON"
Open = "Open"
print("Hello my name is Ray pleased to help you")
audio_Input.adjust_for_ambient_noise(source)
print("Say something: ")
audio = audio_Input.listen(source)
try:
# valid
frase = audio_Input.recognize_google(audio,language='en-US')
print("You said: " + frase)
except:
# google could not validate
print("Speech not recognised")
return False
if Open in frase:
print('sucess')
return True
while True:
if ouvir_microfone():
# got a valid response
break
Works as a solid template. Some imports also remain unused as a sidenote. Catch the exception and return False if the speech could not be recognized so it retries. The google voice recognition python library throws an exception in the case that no distinguishable speech can be read.
I'm trying to write a script that uses SpeechRecognition to run a function once say a wake-up word "Run" Everything works perfectly up until I get to my regex search to find my wake-up word in my alpha variable that is assigned to what I say. Upon running I get the error. I have tested my regex alg outside of the SpeechRecognition with a string and it worked perfectly.
ERROR:
raise UnknownValueError()
speech_recognition.UnknownValueError
Could I get some help?
CODE:
import speech_recognition as sr
import re
def stt():
recognizer = sr.Recognizer()
microphone = sr.Microphone()
# check that recognizer and microphone arguments are appropriate type
if not isinstance(recognizer, sr.Recognizer):
raise TypeError("`recognizer` must be `Recognizer` instance")
if not isinstance(microphone, sr.Microphone):
raise TypeError("`microphone` must be `Microphone` instance")
# listen and assign
with microphone as source:
recognizer.adjust_for_ambient_noise(source)
audio = recognizer.listen(source)
# return output
return recognizer.recognize_google(audio)
while True:
alpha = stt()
print(alpha)
if re.search('.+Run.+', alpha):
print("1")
beta = alpha.split()
query = beta.pop()
print("working")
Try putting your whole code under a try and except.
Like this:
import speech_recognition as sr
import re
try:
def stt():
recognizer = sr.Recognizer()
microphone = sr.Microphone()
# check that recognizer and microphone arguments are appropriate type
if not isinstance(recognizer, sr.Recognizer):
raise TypeError("`recognizer` must be `Recognizer` instance")
if not isinstance(microphone, sr.Microphone):
raise TypeError("`microphone` must be `Microphone` instance")
# listen and assign
with microphone as source:
recognizer.adjust_for_ambient_noise(source)
audio = recognizer.listen(source)
# return output
return recognizer.recognize_google(audio)
while True:
alpha = stt()
print(alpha)
if re.search('.+Run.+', alpha):
print("1")
beta = alpha.split()
query = beta.pop()
print("working")
except sr.UnknownValueError() as e:
pass
If that doesn't work. Look at this github issue
I am using an external sound card with a built-in microphone for voice recognition on a Raspberry Pi 3 model B. The issue is that when I run the code the code executes but then stops on "SAY SOMETHING". When I terminate the code I get these errors.
This is my code:
import speech_recognition as voice
def voice_recognition():
speech = voice.Recognizer()
with voice.Microphone() as source:
print("SAY SOMETHING")
audio = speech.listen(source)
try:
command = speech.recognize_google(audio)
check = "forward" in command
check1 = "backward" in command
if(check == True):
print ('1')
if(check1 == True):
print ('2')
else:
print ('3')
except:
pass
voice_recognition()
And I am getting these errors:
Traceback (most recent call last):
File "/home/pi/Desktop/voice.py", line 29, in <module>
voice_recognition()
File "/home/pi/Desktop/voice.py", line 9, in voice_recognition
audio = speech.listen(source)
File "/usr/local/lib/python3.5/dist-packages/speech_recognition/__init__.py", line
620, in listen
buffer = source.stream.read(source.CHUNK)
File "/usr/local/lib/python3.5/dist-packages/speech_recognition/__init__.py", line
161, in read
return self.pyaudio_stream.read(size, exception_on_overflow=False)
File "/usr/local/lib/python3.5/dist-packages/pyaudio.py", line 608, in read
return pa.read_stream(self._stream, num_frames, exception_on_overflow)
The "errors" that you're seeing are normal when you terminate a Python program. If you run any Python code and terminate it (by pressing Ctrl+C on the command line) before it finishes, you will see a traceback of where the code terminated.
According to the speech_recognition library reference, Recognizer.listen() will not use a timeout by default (you can use listen(timeout=20) to timeout if nothing is received in 20 seconds). The code is probably using a wrong microphone, so the library never receives audio, so the program never terminates.
You should be able to use Microphone.list_microphone_names() to get a list of available microphones, and pass the index of your external microphone to the constructor (e.g. Microphone(device_index=3)).
I am using a python script to transfer the contents of three files to a different three files. The original files are data from three thermometers I have connected to an RPI running raspian. All the script is supposed to do is take the contents of the files and move them so that I can have another program (ComScript) read and parse them.
My problem is that if one or more of the thermometers is disconnected before the script starts, it freezes. It doesn't freeze if I disconnect a thermometer while the script is running.
Here is the code
import time
a = 1
while a == 1:
try:
tfile = open("/sys/bus/w1/devices/28-000004d2ca5e/w1_slave")
text = tfile.read()
tfile.close()
temperature = text
tfile2 = open("/sys/bus/w1/devices/28-000004d2fb20/w1_slave")
text2 = tfile2.read()
tfile2.close()
temperature2 = text2
tfile3 = open("/sys/bus/w1/devices/28-000004d30568/w1_slave")
text3 = tfile3.read()
tfile3.close()
temperature3 = text3
textfile = open("/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave1", "w ")
textfile2 = open("/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave2", "w ")
textfile3 = open("/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave3", "w ")
temperature = str(temperature)
temperature2 = str(temperature2)
temperature3 = str(temperature3)
textfile.write(temperature)
textfile2.write(temperature2)
textfile3.write(temperature3)
textfile.close()
textfile2.close()
textfile3.close()
print temperature
print temperature2
print temperature3
time.sleep(3)
except:
pass
I added the exception pass because I need it to keep running even if it gets bad values. WHen one of the thermometers is disconnected the file python is trying to read is blank, but still there.
Remove the blanket except.
Your script is not freezing, but any error you get is being ignored in an endless loop. Because you use a blanket except: you catch all exceptions, including the keyboard interrupt exception KeyboardInterrupt.
At the very least log the exception, and catch only Exception:
except Exception:
import logging
logging.exception('Oops: error occurred')
KeyboardInterrupt is a subclass of BaseException, not Exception and won't be caught by this except handler.
Take a look at the shutil module for copying files, you doing way too much work:
import time
import shutil
import os.path
paths = ('28-000004d2ca5e', '28-000004d2fb20', '28-000004d30568')
while True:
for i, name in enumerate(paths, 1):
src = os.path.join('/sys/bus/w1/devices', name, 'w1_slave')
dst = '/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave{}'.format(i)
try:
shutil.copyfile(src, dst)
except EnvironmentError:
import logging
logging.exception('Oops: error occurred')
time.sleep(3)
Handling files should only ever raise EnvironmentError or it's subclasses, there is no need to catch everything here.
The open of the unplugged device is most likely blocking because the device driver won't open if the device is not present.
You'll need to use os.open which is the equivalent of the Unix system call "open" and specify the flag O_NONBLOCK and check the return code. You can then use os.fdopen to turn the return value of os.open into a normal Python file object.