I'm trying to make a simple python program that is able to listen a text message from multiple sources.
For the moment I want to use stdin and a voice recognizer.
The idea is that the user is capable of inserting text either with voice or keyboard, and when one is ready the value is returned.
so I have something like this:
def keyboard_input():
return input()
def voice_input():
return listener.listen()
def method():
output = ''
# Listen from keyboard_input and voice_input
...
# Input received from one source, terminate the other one
return output
I'm trying with threads, like to run the two input methods in separated threads, however I'm struggling with the return and kill part.
Edited, more details on the methods:
import speech_recognition as sr
def listen():
recognizer = sr.Recognizer()
with sr.Microphone() as source:
recognizer.adjust_for_ambient_noise(source)
print("Listening:...")
audio = recognizer.listen(source)
try:
text = recognizer.recognize_google(audio, language="it-IT")
return text
except Exception as e:
print(e)
def write():
print('Insert text...')
text = input()
print(text)
return text
OUTPUT = None
# Code to run at the same time listen and write on a common variable OUTPUT,
#...
# If one of them gives the output the other method should terminate
print(OUTPUT)
Did you install v_input package ?
You can install this package by copying this code on your Anaconda Prompt:
!pip-install -v_input
Related
I am making a microphone class that recognize user voice. It gives me an UnboundLocalError. That happens when I add a return command to the mic_config() method.
import speech_recognition as sr
import pyaudio
from speaker import Speaker
class Microphone:
"""Microphone class that represent mic and get user's voice..."""
def __init__(self):
"""Initializing of class"""
self.recognizer = sr.Recognizer() # Voice recognizer
self.microphone = sr.Microphone() # Mic
def mic_config(self):
try:
with self.microphone as source: # Getting mic
print('Listening...')
voice = self.recognizer.listen(source)
command = self.recognizer.recognize_google(voice, language='en-IN') # Using google api
print(command)
except:
pass
return command
m1 = Microphone() # just a test
m1.mic_config()```
Yeah as Carcigenicate said it is because command is only defined in the try block. This means that if there is an error then command is not defined. I don't know if it is just in the code you posted here but there is an indent error in the with statement
try:
with self.microphone as source:
print('Listening...')
voice = self.recognizer.listen(source)
command = self.recognizer.recognize_google(voice, language='en-IN')
print(command)
except:
raise CustomError
# or return None, command = None, etc just define command before the last line
# or don't let the function reach the return command statement
return command
This is a part of the program that detects any commands and I tried to do a while True...
def takeCommand():
r = sr.Recognizer()
with sr.Microphone() as source:
print("Listening...")
r.pause_threshold = 1
audio = r.listen(source)
try:
print("Assistant Processing...")
query = r.recognize_google(audio, language='en-us')
print("User said: {query}\n")
except Exception as e:
print(exception handler removed to shorten code here)
return query
if __name__ == '__main__':
clear = lambda: os.system('cls')
# This Function will clean any
# command before execution of this python file
clear()
wishMe()
usrname()
query = takeCommand().lower()
while True:
if assistname in query:
voice_activation = True
query = takeCommand().lower()
# All the commands said by user will be
# stored here in 'query' and will be
(There are commands here)
Then, at the very bottom of all the commands, I have this...
if not assistname in query:
voice_activation = False
assistname is a variable that I identified as the name for the assistant. The while True didnt work and I am wondering how I could program it so that it loops back to the top, waiting for me to say the name over and over until I actually say it and then once the command is carried through, it waits again.
Is this what you wanted?
clear()
wishMe()
usrname()
while True:
if assistname in takeCommand().lower():
voice_activation = True
query = takeCommand().lower()
# All the commands said by user will be
# stored here in 'query' and will be
.
.
.
break #if that's what you want
else:
continue
I am actually the member of NLI(Novitatis Locus Industries) and our team seems to get some issues. While designing a voice enabled program with GUI, tkinter's mainloop seems to be giving us some issues. See our code-
//this function defines the gui//
def gui():
gui_kurooto = Tk()
txt_dsply_var = StringVar()
AUTHN_LBL = Label(gui_kurooto, text=txt_dsply_var)
AUTHN_LBL.pack()
gui_kurooto.mainloop()
//this code defines the microphone input//
def takeCommand():
#It takes microphone input from the user and returns string output
r = sr.Recognizer()
with sr.Microphone() as source:
print("Listening...")
txt_dsply_var = StringVar()
txt_dsply_var.set('Listening')//display listening on gui//
r.pause_threshold = 1
r.energy_threshold = 10000
audio = r.listen(source)
try:
print("Recognizing...")
txt_dsply_var = StringVar()
txt_dsply_var.set('Recognizing')//display recognizing//
query = r.recognize_google(audio, language='en-en')
print(f"User said: {query}\n")
txt_dsply_var = StringVar()
txt_dsply_var.set(f"User said: {query}\n")//display input//
except Exception as e:
# print(e)
print("Say that again please...")
return "None"
return query
//to run//
if __name__ == "__main__":
gui()
while True:
# if 1:
query = takeCommand().lower()
Now when I try to run this, the code never reaches the while loop. I know the mainloop is an infinite loop but is there a substitute present their so I can let it reach other functions. Keeping the function out of function also dosen't work. Can I place it after the query command?
Also I have other question, is there a way by which I can spectra according to the voice input like Google and Siri have bars which move when we speak?
Any help would be appreciated.
Is it possible to print something without overwriting the already written but not sent input?
This is the client side for a socket and I'm wanting to print messages from the server without overwriting/appending the currently written input.
def listen():
while True:
data = s.recv(1024)
print(data.decode('utf-8'))
def write():
while True:
text = input("Text > ")
s.sendall(bytes(text, 'utf-8'))
listener = threading.Thread(target=listen)
listener.start()
writer = threading.Thread(target=write)
writer.start()
I'd want to print the received data above or below the current input line, but right now it just writes it on the input line.
Add time.sleep(10) after s.sendall(bytes(text, 'utf-8')), because you immediately do input while the data is received and printed later. Having time.sleep you give time for the data to be received and printed.
But this won't help you if you enter the data for input too slow. Generally the code is strange, because why would you do input and print on the same terminal? In real life it doesn't make sense.
For academic purposes you can try this:
is_input_active = False
def listen():
while True:
data = s.recv(1024)
while is_input_active:
time.sleep(0.2)
print(data.decode('utf-8'))
def write():
global is_input_active
while True:
is_input_active = True
text = input("Text > ")
is_input_active = False
s.sendall(bytes(text, 'utf-8'))
With this version listen() will block until input function finishes. If you don't want this, try something like:
def listen():
data = b''
while True:
data += s.recv(1024) # accumulate
while not is_input_active:
print(data.decode('utf-8'))
data = b'' # reset
Interactive terminal input is complex and is usually handled with libraries, it's hard to handle it directly. For line input, readline and its alternatives such as libedit are popular. Most shells and REPLs use such libraries.
Python's standard library has readline module, which is interface to readline or libedit. Importing it makes input use realine/libedit, so it obtains cursor navigation and even auto-completion and history capabilities. And it allows to redraw input line after you draw something in terminal.
To print in previous line, you can use ANSI escape codes.
import threading
import sys
from time import sleep
import readline # importing readline makes input() use it
def listen():
i = 0
while True:
i += 1
sleep(1)
# <esc>[s - save cursor position
# <esc>[1A - move cursor up
# \r - carriage return
# print message
# <esc>[u - restore cursor position
sys.stdout.write("\x1b[s\x1b[1A\rOutput: "+str(i)+"\x1b[u")
readline.redisplay()
def write():
while True:
print "" # make space for printing messages
text = input("Text > ")
listener = threading.Thread(target=listen)
listener.daemon = True
listener.start()
write()
readline library also has rl_message and other useful capabilities, but its' not exported by python's readline module.
I am writing a basic talking tom like code which listens to the person and repeats its audio along side i want it to display the text which the speaker has spoken.
the problem I'm facing is i am not able to use the print and listen command simultaneously.
I need to speak the phrase twice i.e, once for printing it on screen and other time for repeating it.
I want to figure it these both things to happen only at once i.e, the audio should be repeated and displayed at the same time without me repeating the phrase twice.
import speech_recognition
import pyttsx
speech_engine = pyttsx.init()
speech_engine.setProperty('rate', 150)
def speak(text):
speech_engine.say(text)
speech_engine.runAndWait()
recognizer = speech_recognition.Recognizer()
def listen():
with speech_recognition.Microphone() as source:
recognizer.adjust_for_ambient_noise(source)
audio = recognizer.listen(source)
try:
return recognizer.recognize_google(audio)
except speech_recognition.UnknownValueError:
print("Could not understand audio")
except speech_recognition.RequestError as e:
print("Recog Error; {0}".format(e))
return ""
speak("Say something!")
print (listen())
speak("I heard you say " + listen())
speak("Say something!")
text = listen()
speak("I heard you say " + text)
Write:
print(audio)
Under:
return recognizer.recognize_google(audio)