Hello again, everybody.

Now that I've just about learned all I can for programming my robot with 'smarts' (I think), I think I'm ready for a bigger challenge: Having my robot program aspects of itself.

Right now I'm going to try to implement it into my robot's human socialization program. After downloading a python script for the English Dictionary, which I found in Projects for the Beginner, I'm going to sort the words by noun, verb, etc, and then, when the robot is listening for chat, she'll get the sentence through the listening, prepare a verbal response (for example by replacing 'I' with 'you' and 'my' with 'your') and say it out loud through text to speech. It won't be perfect, I know, but I can't resist.:icon_twisted:

I've bookmarked a few tutorials from which I'll implement, but a few things I'd like to ask on top of that:

I want to learn the right syntax for engaging the 'dictation' part of the window's speech recognition, so my robot can listen for any word, pre-put together in the python english dictionary, and then manipulate the sentence and formulate her response.

Also, is there a way I could do a mix between the two: by that I mean pre-built sentences for understanding and the GetSentence function? For instance, I have a prebuilt sentence to recognize, "I'd like you to meet" and I'd like the program to "wait" for a name to catch, like, "Sarah," before saying, "Pleased to meet you, Sarah..." I've tried some experimentation with this, but right after I say "I'd like you to meet" it immediatle comes up with an error that basically says the value for the name of the person has no attribute, without waiting for me to say the name.

I'll be experimenting in the meantime.:icon_cool: Any input would be greatly appreciated. Thanks!

Recommended Answers

All 22 Replies

Okay, I'm trying my experiment in a separate code, scaled down a bit for a prototype script.

Here's what I got so far.

import re
import sys, time, math, string, win32com.client,win32event,pythoncom
from win32com.client import constants
import win32com
import cPickle, zlib

import string
import pickle
import win32api
import win32com.client
import traceback

import threading
import random

speaker = win32com.client.Dispatch("SAPI.SpVoice")

def say(text):
    speaker.Speak(text)

def multiwordReplace(text, wordDic):
    rc = re.compile('|'.join(map(re.escape, wordDic)))
    def translate(match):
        return wordDic[match.group(0)]
    return rc.sub(translate, text)

wordDic = {
    'you' : 'me',
    'I' : 'you',
    'mine' : 'yours',
    'my' : 'your', }

class ContextEvents(win32com.client.getevents("SAPI.SpSharedRecoContext")):
    def OnRecognition(self, StreamNumber, StreamPosition, RecognitionType, Result):
        newResult = win32com.client.Dispatch(Result)
        speaker.Speak(multiwordReplace(GetText.wordDic))

This is what I want to happen in sudo code:

listen for voice

if something is said:
        get text
        replace words according to wordDic
        speak text with replaced wording

if vocalization not understood:
        speak "I'm sorry, what was that?"

This is the first step. I later intent to have my robot 'learn' new words via dictation. A word document with the words of the English language will pre-existant on the system. The plan is to ulimately acheive a human interactor to 'define' knew words, if the robot asks for them, and then have the robot say something like "I see, cheese is a dairy product!" and then save that string to a list preserved for 'learning' new items, and then save the updated python script (so everytime she's powered down her memory doesn't get wiped). That's on the horizon, though.

One muddling road block I've encountered so far with this scaled down version of the script:

Every time I run the program, the python editor seems to close it immediately. Then it names the directory its under and then says "returned exit code 0." Anyone know what this means?

Thanks

Okay, I know what's happening now. The program goes through all the code, and once it's done, its done. (I should've seen that...:icon_rolleyes: )

Okay, I'm now modifying Inigo Surgui's speech recognition script, replacing some things and adding some others:

from win32com.client import constants
import win32com.client
import pythoncom
import re

def multiwordReplace(text, wordDic):
    rc = re.compile('|'.join(map(re.escape, wordDic)))
    def translate(match):
        return wordDic[match.group(0)]
    return rc.sub(translate, text)

wordDic = {
    'you' : 'me',
    'I' : 'you',
    'mine' : 'yours',
    'my' : 'your' }

"""Sample code for using the Microsoft Speech SDK 5.1 via COM in Python.
    Requires that the SDK be installed; it's a free download from
            http://microsoft.com/speech
    and that MakePy has been used on it (in PythonWin,
    select Tools | COM MakePy Utility | Microsoft Speech Object Library 5.1).

    After running this, then saying "One", "Two", "Three" or "Four" should
    display "You said One" etc on the console. The recognition can be a bit
    shaky at first until you've trained it (via the Speech entry in the Windows
    Control Panel."""
class SpeechRecognition:
    """ Initialize the speech recognition with the passed in list of words """
    def __init__(self, wordsToAdd):
        # For text-to-speech
        self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
        # For speech recognition - first create a listener
        self.listener = win32com.client.Dispatch("SAPI.SpSharedRecognizer")
        # Then a recognition context
        self.context = self.listener.CreateRecoContext()
        # which has an associated grammar
        self.grammar = self.context.CreateGrammar()
        # Do not allow free word recognition - only command and control
        # recognizing the words in the grammar only
        self.grammar.DictationSetState(0)
        # Create a new rule for the grammar, that is top level (so it begins
        # a recognition) and dynamic (ie we can change it at runtime)
        self.wordsRule = self.grammar.Rules.Add("wordsRule",
                        constants.SRATopLevel + constants.SRADynamic, 0)
        # Clear the rule (not necessary first time, but if we're changing it
        # dynamically then it's useful)
        self.wordsRule.Clear()
        # And go through the list of words, adding each to the rule
        [ self.wordsRule.InitialState.AddWordTransition(None, word) for word in wordsToAdd ]
        # Set the wordsRule to be active
        self.grammar.Rules.Commit()
        self.grammar.CmdSetRuleState("wordsRule", 1)
        # Commit the changes to the grammar
        self.grammar.Rules.Commit()
        # And add an event handler that's called back when recognition occurs
        self.eventHandler = ContextEvents(self.context)
        # Announce we've started using speech synthesis
        self.say("Started successfully")
    """Speak a word or phrase"""
    def say(self, phrase):
        self.speaker.Speak(phrase)


"""The callback class that handles the events raised by the speech object.
    See "Automation | SpSharedRecoContext (Events)" in the MS Speech SDK
    online help for documentation of the other events supported. """
class ContextEvents(win32com.client.getevents("SAPI.SpSharedRecoContext")):
    """Called when a word/phrase is successfully recognized  -
        ie it is found in a currently open grammar with a sufficiently high
        confidence"""
    def OnRecognition(self, StreamNumber, StreamPosition, RecognitionType, Result):
        newResult = win32com.client.Dispatch(Result)
        say("So",newResult.PhraseInfo.GetText(multiwordreplace))
    
if __name__=='__main__':
    wordsToAdd = [ "My", "Name", "is", "Loren" ]
    speechReco = SpeechRecognition(wordsToAdd)
    while 1:
        pythoncom.PumpWaitingMessages()

The goal of the experiment is to be able to say something like , "My name is Loren." And then have the robot catch that string, replace a few words and reply, "So, your name is Loren" That's what I'm shooting for so far.

Now, new problem. I get this error message the moment I say "My":

pythoncom error: Python error invoking COM method.

Traceback (most recent call last):
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 285, in _Invoke_
    return self._invoke_(dispid, lcid, wFlags, args)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 290, in _invoke_
    return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 593, in _invokeex_
    return func(*args)
  File "C:\Users\Loren\Desktop\My Robots\Experimental Code!\Prototype Script B.py", line 74, in OnRecognition
    say("So",newResult.PhraseInfo.GetText(multiwordreplace))
<type 'exceptions.NameError'>: global name 'say' is not defined

Not sure what's going wrong. Because "say" is defined earlier in the script.
Anyone's input would be appreciated. I'll continue experimentation on my end.

Thanks!

New Progress, everyone.

I've been doing my research and I think I'm getting close to acheiving phase 1 of my artificial 'Learning' project. Here's the script I've put together, after some studying, tinkering and debugging:

from win32com.client import constants
import win32com.client
import re

listening = True

class SpeechRecognition:
    def __init__(self, str1):
        self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
        self.listener = win32com.client.Dispatch("SAPI.SpSharedRecognizer")
        self.context = self.listener.CreateRecoContext()
        self.grammar = self.context.CreateGrammar()
        self.eventHandler = ContextEvents(self.context)
        self.say("I am listening for you master")
    def say(self, phrase):
        self.speaker.Speak(phrase)
    def sentence(self, text):
        self.GetText()

class ContextEvents(win32com.client.getevents("SAPI.SpSharedRecoContext")):
    def OnRecognition(self, StreamNumber, StreamPosition, RecognitionType, Result):
        newResult = win32com.client.Dispatch(Result)
        IHeardYou = True
        
while listening == True:
    str1 = SpeechRecognition.sentence(text)
    str2 = multiwordReplace(str1, wordDic)
    if IHeardYou == True:
        say(str2)
        IHeardYou = False

def multiwordReplace(text, wordDic):
    rc = re.compile('|'.join(map(re.escape, wordDic)))
    def translate(match):
        return wordDic[match.group(0)]
    return rc.sub(translate, text)

wordDic = {
    'my': 'your',
    'you': 'me',
    'mine': 'yours',
    'your': 'my',
    'yours': 'mine',
    'me': 'you',
    'I' : 'you' }

The main problem I'm encountering with this one: I get this exception when I try to run the script.

Traceback (most recent call last):
  File "C:\Python25\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 310, in RunScript
    exec codeObject in __main__.__dict__
  File "C:\Users\Loren\Desktop\My Robots\Experimental Code!\Prototype Script C.py", line 26, in <module>
    str1 = SpeechRecognition.sentence(text)
NameError: name 'text' is not defined

for me, its a puzzling exception, because 'text' is defined in the class 'SpeechRecognition' under 'sentence' and I think I calling that function on line 26...but I must be doing something wrong.

Can anyone point out my flaw? In the meantime, I'll be trying to find it myself...

Thanks

Okay, I've decided to start with something even simpler--making one modification to Inigo Surgui's speech recognition recipe:

from win32com.client import constants
import win32com.client
import pythoncom

"""Sample code for using the Microsoft Speech SDK 5.1 via COM in Python.
    Requires that the SDK be installed; it's a free download from
            http://microsoft.com/speech
    and that MakePy has been used on it (in PythonWin,
    select Tools | COM MakePy Utility | Microsoft Speech Object Library 5.1).

    After running this, then saying "One", "Two", "Three" or "Four" should
    display "You said One" etc on the console. The recognition can be a bit
    shaky at first until you've trained it (via the Speech entry in the Windows
    Control Panel."""
class SpeechRecognition:
    """ Initialize the speech recognition with the passed in list of words """
    def __init__(self, wordToAdd):
        # For text-to-speech
        self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
        # For speech recognition - first create a listener
        self.listener = win32com.client.Dispatch("SAPI.SpSharedRecognizer")
        # Then a recognition context
        self.context = self.listener.CreateRecoContext()
        # which has an associated grammar
        self.grammar = self.context.CreateGrammar()
        # Do not allow free word recognition - only command and control
        # recognizing the words in the grammar only
        self.grammar.DictationSetState(0)
        # Create a new rule for the grammar, that is top level (so it begins
        # a recognition) and dynamic (ie we can change it at runtime)
        self.wordsRule = self.grammar.Rules.Add("wordsRule",
                        constants.SRATopLevel + constants.SRADynamic, 0)
        # Clear the rule (not necessary first time, but if we're changing it
        # dynamically then it's useful)
        self.wordsRule.Clear()
        # And go through the list of words, adding each to the rule
        [ self.wordsRule.InitialState.AddWordTransition(None, word) for word in wordsToAdd ]
        # Set the wordsRule to be active
        self.grammar.Rules.Commit()
        self.grammar.CmdSetRuleState("wordsRule", 1)
        # Commit the changes to the grammar
        self.grammar.Rules.Commit()
        # And add an event handler that's called back when recognition occurs
        self.eventHandler = ContextEvents(self.context)
        # Announce we've started using speech synthesis
        self.speaker.Speak("Started successfully")
    """Speak a word or phrase"""
        
"""The callback class that handles the events raised by the speech object.
    See "Automation | SpSharedRecoContext (Events)" in the MS Speech SDK
    online help for documentation of the other events supported. """
class ContextEvents(win32com.client.getevents("SAPI.SpSharedRecoContext")):
    """Called when a word/phrase is successfully recognized  -
        ie it is found in a currently open grammar with a sufficiently high
        confidence"""
    def say(self, phrase):
        self.speaker.Speak(phrase)
    def OnRecognition(self, StreamNumber, StreamPosition, RecognitionType, Result):
        newResult = win32com.client.Dispatch(Result)
        print "You said",newResult.PhraseInfo.GetText()
    
if __name__=='__main__':
    wordsToAdd = [ "One", "Two", "Three", "Four" ]
    speechReco = SpeechRecognition(wordsToAdd)
    while 1:
        pythoncom.PumpWaitingMessages()

All I'm trying to do for this test is switch this bit of code on line 60:

print "You said",newResult.PhraseInfo.GetText()

to this:

say("You said",newResult.PhraseInfo.GetText())

But here's what I get the moment I say "One":

pythoncom error: Python error invoking COM method.

Traceback (most recent call last):
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 285, in _Invoke_
    return self._invoke_(dispid, lcid, wFlags, args)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 290, in _invoke_
    return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 593, in _invokeex_
    return func(*args)
  File "C:\Users\Loren\Desktop\My Robots\SpeechRecognition.py", line 60, in OnRecognition
    say("You said",newResult.PhraseInfo.GetText())
<type 'exceptions.NameError'>: global name 'say' is not defined

from what I understand, 'say' is defined under ContextEvents, the same class under which 'OnRecognition' is defined. So 'say' should be local right?

By the way, I've tried using the global statement before 'say' but that didn't seem to work either.

I've spent hours and hours trying to solve this simple problem but to no avail...
Now I really stumped:-/

Can anyone give me any input? I'd really appreciate it.

Yes, it is defined within the same class but not in the scope of the function OnRecognition. say() is a member of the ContextEvents class so you'll need to call it as self.say()

Okay I think I see now, jlm669. Thanks.

But now its saying this when I say one:

Traceback (most recent call last):
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 285, in _Invoke_
    return self._invoke_(dispid, lcid, wFlags, args)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 290, in _invoke_
    return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line 593, in _invokeex_
    return func(*args)
  File "C:\Users\Loren\Desktop\My Robots\SpeechRecognition.py", line 60, in OnRecognition
    self.say("You said",newResult.PhraseInfo.GetText())
<type 'exceptions.TypeError'>: say() takes exactly 2 arguments (3 given)

Okay, let me see if I can identify this problem visually: the problem starts when the script runs the line: self.say("You said",newResult.PhraseInfo.Get())

am I right?

The problem is that the function 'say' only takes 2 arguments, which are "self and phrase," right? But three arguments are given in the line: self.say("You said",newResult.PhraseInfo.GetText()) So basically, there's an argument I need to add to the function 'say' to make it work. Is this correct? If so, which arguement could that be I wonder...newResult? GetText()? or maybe just text? :confused:

By the way, part of my big difficulty learning to program in python is that I can't see how it works visually, so I have trouble identifying the various names of the parts of code (for example, what part of the code is the argument?). I'd program my robot in visual basic, but I've already done tons of it in python and python gives me more possibilities...

If only they had visual python...:-/

Okay, I tinkered around a bit and I fixed it!

The working script now looks like this:

from win32com.client import constants
import win32com.client
import pythoncom

"""Sample code for using the Microsoft Speech SDK 5.1 via COM in Python.
    Requires that the SDK be installed; it's a free download from
            http://microsoft.com/speech
    and that MakePy has been used on it (in PythonWin,
    select Tools | COM MakePy Utility | Microsoft Speech Object Library 5.1).

    After running this, then saying "One", "Two", "Three" or "Four" should
    display "You said One" etc on the console. The recognition can be a bit
    shaky at first until you've trained it (via the Speech entry in the Windows
    Control Panel."""
class SpeechRecognition:
    """ Initialize the speech recognition with the passed in list of words """
    def __init__(self, wordsToAdd):
        # For text-to-speech
        self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
        # For speech recognition - first create a listener
        self.listener = win32com.client.Dispatch("SAPI.SpSharedRecognizer")
        # Then a recognition context
        self.context = self.listener.CreateRecoContext()
        # which has an associated grammar
        self.grammar = self.context.CreateGrammar()
        # Do not allow free word recognition - only command and control
        # recognizing the words in the grammar only
        self.grammar.DictationSetState(0)
        # Create a new rule for the grammar, that is top level (so it begins
        # a recognition) and dynamic (ie we can change it at runtime)
        self.wordsRule = self.grammar.Rules.Add("wordsRule",
                        constants.SRATopLevel + constants.SRADynamic, 0)
        # Clear the rule (not necessary first time, but if we're changing it
        # dynamically then it's useful)
        self.wordsRule.Clear()
        # And go through the list of words, adding each to the rule
        [ self.wordsRule.InitialState.AddWordTransition(None, word) for word in wordsToAdd ]
        # Set the wordsRule to be active
        self.grammar.Rules.Commit()
        self.grammar.CmdSetRuleState("wordsRule", 1)
        # Commit the changes to the grammar
        self.grammar.Rules.Commit()
        # And add an event handler that's called back when recognition occurs
        self.eventHandler = ContextEvents(self.context)
        # Announce we've started using speech synthesis
        self.speaker.Speak("Started successfully")
    """Speak a word or phrase"""
        
"""The callback class that handles the events raised by the speech object.
    See "Automation | SpSharedRecoContext (Events)" in the MS Speech SDK
    online help for documentation of the other events supported. """
class ContextEvents(win32com.client.getevents("SAPI.SpSharedRecoContext")):
    """Called when a word/phrase is successfully recognized  -
        ie it is found in a currently open grammar with a sufficiently high
        confidence"""
    def OnRecognition(self, StreamNumber, StreamPosition, RecognitionType, Result):
        newResult = win32com.client.Dispatch(Result)
        self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
        print "You said",newResult.PhraseInfo.GetText()
        self.speaker.Speak("You said")
        self.speaker.Speak(newResult.PhraseInfo.GetText())
    
if __name__=='__main__':
    wordsToAdd = [ "One", "Two", "Three", "Four" ]
    speechReco = SpeechRecognition(wordsToAdd)
    while 1:
        pythoncom.PumpWaitingMessages()

Some minor flaws I noticed with my tinkering, the Voice synthesis starts over everytime I speak a number (I presume because I told it to on line 58. Oh well) Also, I don't know why it wouldn't work if I tried to put in "You said: " So I just separated them into two operations.

Now for the next step! Getting my robot to listen for a string of words, and replacing them!

P.S. when you use code tags it helps if you define the language via so that syntax highlighting is turned on. This makes it loads easier to read.

[code=python] for this forum (usually)[code=xxxx] so that syntax highlighting is turned on. This makes it loads easier to read.

for this forum (usually)[code=python] for this forum (usually)

Thanks Jlm699. I'll do that from now on.

Loren

Okay, I've experimened a bit and managed to get my robot to switch a few words around.

My script looks like this:

from win32com.client import constants
import win32com.client
import pythoncom

def multiwordReplace(text, wordDict):
    for key in wordDict:
        text = text.replace(key, wordDict[key])
    return text

wordDict = {
    "you" : "me",
    "I" : "you",
    "yours" : "mine",
    "my" : "your" }

"""Sample code for using the Microsoft Speech SDK 5.1 via COM in Python.
    Requires that the SDK be installed; it's a free download from
            http://microsoft.com/speech
    and that MakePy has been used on it (in PythonWin,
    select Tools | COM MakePy Utility | Microsoft Speech Object Library 5.1).

    After running this, then saying "One", "Two", "Three" or "Four" should
    display "You said One" etc on the console. The recognition can be a bit
    shaky at first until you've trained it (via the Speech entry in the Windows
    Control Panel."""
class SpeechRecognition:
    """ Initialize the speech recognition with the passed in list of words """
    def __init__(self):
        # For text-to-speech
        self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
        # For speech recognition - first create a listener
        self.listener = win32com.client.Dispatch("SAPI.SpSharedRecognizer")
        # Then a recognition context
        self.context = self.listener.CreateRecoContext()
        # which has an associated grammar
        self.grammar = self.context.CreateGrammar()
        #enable free word recognition
        self.grammar.DictationSetState(1)
        # And add an event handler that's called back when recognition occurs
        self.eventHandler = ContextEvents(self.context)
        # Announce we've started using speech synthesis
        self.speaker.Speak("Hello Master. This is Nina. I'm ready for my first lesson.")
    """Speak a word or phrase"""
        
"""The callback class that handles the events raised by the speech object.
    See "Automation | SpSharedRecoContext (Events)" in the MS Speech SDK
    online help for documentation of the other events supported. """
class ContextEvents(win32com.client.getevents("SAPI.SpSharedRecoContext")):
    """Called when a word/phrase is successfully recognized  -
        ie it is found in a currently open grammar with a sufficiently high
        confidence"""
    def OnRecognition(self, StreamNumber, StreamPosition, RecognitionType, Result):
        newResult = win32com.client.Dispatch(Result)
        self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
        print "You said",newResult.PhraseInfo.GetText()
        IHeard = newResult.PhraseInfo.GetText()
        repeat = (multiwordReplace(IHeard, wordDict))
        self.speaker.Speak(repeat)
        print repeat
    
if __name__=='__main__':
    SpeechReco = SpeechRecognition()
    while 1:
        pythoncom.PumpWaitingMessages()

Now, I found that if I told my robot, "I love you," my robot responds, "me love me." I did some detective work and found that this was because "you" in "'I' : 'you'", is being replaced with the "you" in "'you' : me'".

But she does repeat, "The rain in spain stays mainly on the plain" nicely. :P

Anyway, now to come up with a coding solution to fix that little wirk.

By the way, thanks again for the advice, Jlm669. That does make the code easier to read!

Maybe make a convention for sentence order: subject - verb - adverb, so that 'you' as an adverb is left as 'you', and not replaced by 'me ' from your dictionary...What do you think?

I was thinking the same thing, tzushky.

I'll hit the books and see what I can do. Thanks!

Okay.

Thanks to Micheal Gunlach's new speech recognition module, my scripting has become easier to work with!

Here is the next script to test my robot's A.I. and Artificial learning:

#New Speech Recognition for Nina. Speech module provided by Michael Gundlach.
#Thanks, Michael!
import speech
import string

#Define a sentence convention callback everytime dictation text is recognized
def SentenceConvention(phrase, listener):
    #These lists define pronous for my robot to look out for...
    subject_pronouns = [ "you", "he", "she", "I", "it" ]
    subject_pronous_replacement = [ "I", "he", "she", "you", "it" ]
    object_pronouns = [ "you", "him", "her", "me", "it" ]
    object_pronouns_replacement = [ "me", "him", "her", "you", "it" ]
    #now we get to the real processing
    if phrase == "stop please":
        speech.stoplistening(listener)
    else:
        #print what Nina heard
        print "Heard %s" % phrase
        #Now split phrase for analysis
        words = string.split(phrase)
        #count the words
        wordCount = len(words)
        #report back how many words were recognized
        print "I heard you say ", wordCount
        #This is the biggie right here.
        #If the first word in phrase is "I" from the subject pronoun list...
        if words[0] == subject_pronouns[0]:
            #replace "I" with "You" from the list subject_pronouns_replacement
            repeat = phrase.replace(subject_pronouns_replacement[0])
            #now speak the new phrase
            speech.say(repeat)
            #and print it
            print repeat
        

# a callback to run whenever a certain phrase is heard...
def command_callback(phrase, listener):
    if phrase == 'Hello Nina':
        speech.say("Hello Master")
    if phrase == 'How are you today':
        speech.say('Still trying to learn how to speak correctly')
    if phrase == 'Recite the Three Laws of Robotics':
        speech.say('Law One: A robot shall not harm a human being')
        speech.say('Law Two: A robot must obey orders given it by human beings')
        speech.say('Law Three: A robot must defend its existence')
    
#Ignore for now, we'll concentrate on dictation word-replacement...
listener1 = speech.listenfor(['Hello Nina', 'How are you today', 'Recite the Three Laws of Robotics'],
        command_callback)
        
listener2 = speech.listenforanything(SentenceConvention)

# Both listeners are running right now.  When the user says
# "stop please", listener2 will stop itself in the callback.
while speech.islistening(listener2):
    speech.pump_waiting_messages() # safe to call in a tight loop

    # Turn off listener1 as well.
    speech.stoplistening(listener1)

The main problem I'm experiencing right now: I'm not getting a verbal response from the TTS voice. I know it has something to do with my "repeat" equation. Maybe there's no text in it? If so...I wonder what I shoudl try instead?

>>> print str.replace.__doc__
S.replace (old, new[, count]) -> string

hm, I think your code should raise an exception because of a missing argument. Also I suggest you set a logger for the whole conversation (see module logging). You should also modify the code so that your robot always says something.

Loren,

subject_pronouns[0] is "you". So your code actually checks if the first word is "you", not "I". And as the above poster mentioned, string.replace() takes two arguments: the old text, and the new text. Try typing "help(str.replace)" in Python. (The help system is great -- you can type help(anything) and it will probably give you help. Function names, module names, class names...)

Also, it's never guaranteed how speech recognition is going to capitalize your text... When you say "are you there" it may call your callback with the phrase "are you there" or may call it with the phrase "Are you there". That makes string matching difficult. I'd recommend using str.lower() to get an all-lower-case version of the callback phrase before trying to work with it, as in:

phrase = phrase.lower()

Last thing -- be aware that the speech module has a newer version, which you can install with

easy_install speech

which has a slightly simpler interface. The biggest change is that pump_waiting_messages is no longer necessary -- speech events get detected automatically.

Good luck,
Michael

A very interesting project. Can you give us more information about your setup?

Absolutely...um, I'm sorry not sure what you mean by setup. I assumed you mean programming wise so here it goes...:)

While I'm building my robot mechanically, I'm also taking time to work on its programming as well. Right now I'm just experimenting and putting up some test scripts.

The objective of my project right now is just to get a python script that can listen to my voice via the speech module, capture some words via dictation, then change those words around a bit to repeat what I said, but from the robot's first person perspective. For example, if I tell my robot, "I think you are a cool robot," I want my robot to process that recognized phrase, and then repeat, "You think I am a cool robot."

The ultimate goal of the project is to get a fully functional simulated intelligence program to my robot. In this program, my robot starts out its existence with only a limited vocabulary in her python scripting (although she will have a full English dictionary somewhere on the system, so the Windows Vista Speech Recognition will read that and assimilate that into functionality.)

Here's an example of what I want to accomplish ultimately with this A.I. simulation experiment: I tell my robot, "I like cheese." My robot's programming processing this phrase and sees a word not listed in the python script (I intend to use lists to classify words into nouns, verbs, etc. Each word will also have a value to it, and tell if that value is positive or negative, or neutral.) Anyway, when my robot recognizes cheese, she should ask using a predefined string "What is" and then name the new word: "What is cheese?" She will then listen for an explanation. So if I say, "Cheese is a dairy product," my robot can capture that phrase, and append it to the list of nouns, give it a value and reply, "I think I get it. Cheese is a dairy product."

That's basically what I want to accomplish in a nut shell. I also want to accomplish more, but one thing at a time.

Did I answer that question all right? (sorry, I just sounded like a robot...:icon_cheesygrin: )

Hi Loren,

Just a note that the speech module has just become even easier to use, thanks to a new speech.input() function.

It waits for spoken text, and returns it. No more dealing with callbacks!

import speech

response = speech.input("How are you?", ["I'm fine", "Bored"])
print "You said: %s" % response

# Both the prompt and the phraselist are optional.  Without the prompt, 
# no text is printed.  Without the phraselist, you can say anything.

response = speech.input()
print "You said %s" % response

speech.input() blocks your code forever until it hears a response or you hit Ctrl-C -- just like raw_input().

Type

easy_install speech

to get the latest version (0.5.0) which lets you do this.

Good luck!
Michael

Thanks for the details Seagull One!

Looks like all you need is ...
1) A good microphone
2) Michael Gundlach's speech.py module
http://code.google.com/p/pyspeech/
http://pypi.python.org/pypi/speech/
3) pywin32-211.win32-py2.5.exe
http://tinyurl.com/5ezco9
4) The Microsoft Speech Kit
http://tinyurl.com/zflb
5) Apply the speech recognition and text-to-speech
capabilities to something interesting like a robot your are building

Good luck with your great project Loren!

Wow! Thanks Micheal! I'll try out that new version!

Thanks also, Vegaseat. I do intent to get a good microphone (once I have the money) and use that instead of a desktop mic.

As soon as I have my robot complete, (which won't be for a while, but I will get there), maybe I could share a link to some videos or something.

Thanks against everybody!

Loren

Hm, last thing: another user had trouble convincing easy_install to get 0.5.0 when he already had an older version. Just use

easy_install speech==0.5.0

if easy_install thinks it's smarter than you.

I did already. Thanks, Micheal ( :

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.