[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Using SAPI 5 Voices and Methods



Hi!

    I guess in some cases the email message gets messed up so I attached the
SAPI 5 test for voices along with an HTML version using Java Script. It also
has the methods and a voice by name assignment since the voices are an array
list by element. So I use the description to find the name. It also lists
the voice names in the console field.

    I guess you could also use the pyTTS version as well. I did have one
problem and that was the isfilename flag seems to get an error. But, also my
spell tag did not work on my tower computer, but did work on my Lap Top. Do
not know why, but it could be a version issue. Yet the isfilename also does
not work on the Lap Top, so who knows.

    Anyway, have fun and install if for either your games or web pages...

        Bruce
#THE NEXT TO LAST TEST IS THE ISFILE AND I COMMENTED IT OUT FOR THERE IS AN ERROR!
import Sapi5, time, os

av = Sapi5.SynthDriver()
av.init()
SYNC = av._sync
ASYNC = av._async
PURGE = av._purge
ISFILE = av._is_filename
XML = av._xml
NOT_XML = av._not_xml
PERSIST = av._persist_xml
PUNC = av._punc
WAIT = av._wait

av.Speak("Hello!")
av.Speak( "I am speaking in the default voice!")
av.Speak( "Number of voices is: %d" % av.getVoiceCount())
av.Speak( "Hello! Now saying the punctuation in this sentence.", PUNC)
time.sleep(.5)
av.setVoiceByName( "Mike")
av.setVolume( 100)
av.Speak( " The Volume Is Set At Speaker Volume!")
av.setRate( 5)
av.setPitch(0)
av.setVoiceByName( "Mary")
av.setPitch(5)
av.Speak( "Set To Voice Mary and Pitch 5 or 75% of maximum pitch!")
time.sleep(1)
av.setPitch(0)
av.setRate(0)
av.Speak( "The rate and pitch are now set for normal!")
time.sleep(1)
av.read_Voices()
av.setVoiceByName( "Mary")
av.Speak( "Hit enter key to stop speaking!")
av.setPitch(10)
av.Speak("Pitch 100%", ASYNC)
av.setPitch(5)
av.Speak("Pitch 75%", ASYNC)
av.setPitch(0)
av.Speak("Pitch 50%", ASYNC)
av.setPitch( -5)
av.Speak("Pitch 25%", ASYNC)
av.setPitch( -10)
av.Speak("Pitch 0%", ASYNC)
av.setPitch(0)
av.Speak( "Hit enter key!", ASYNC)
hit = raw_input("Hit enter key >")
#av.SpeakFile( "readthis.txt", ASYNC, ISFILE)	
av.Speak(" Now Good bye", ASYNC, PURGE)
av.setVoiceByName( "Sam")
av.Speak( "<volume level='50'/> goodbye")
#DRIVERS FOR SAPI 5 AND VOICES!
#NOTE THE CONSTANTS AND IN THE SPEAK FUNCTION AND THE ADDING/OR OF THE VALUES.
from comtypes.client import CreateObject
import _winreg

class constants4tts:
    Wait = -1
    Sync = 0
    Async = 1
    Purge = 2
    Is_filename = 4
    XML = 8
    Not_XML = 16
    Persist = 32
    Punc = 64

class SynthDriver():
    name="sapi5"
    description="Microsoft Speech API version 5 (sapi.SPVoice)"
    _pitch = 0
    _voices = []
    _wait = -1 #WAIT INDEFINITELY
    _sync = 0 #WAIT UNTIL SPEECH IS DONE.
    _async = 1 #DO NOT WAIT FOR SPEECH
    _purge = 2 #CLEAR SPEAKING BUFFER
    _is_filename = 4 #OPEN WAV FILE TO SPEAK OR SAVE TO WAV FILE
    _xml = 8 #XML COMMANDS, PRONUNCIATION AND GRAMMER.
    _not_xml = 16 #NO XML COMMANDS
    _persist_xml = 32 #Changes made in one speak command persist to other calls to Speak.
    _punc = 64 #PRONOUNCE ALL PUNCTUATION!
    def check(self):
        try:
            r=_winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,"SAPI.SPVoice")
            r.Close()
            return True
        except:
            return False
#INITIALIZE ENGINE!
    def init(self):
        try:
            self.tts = CreateObject( 'sapi.SPVoice')
            self._voice=1
            self._voiceCount = len(self.tts.GetVoices())
            for v in range(self._voiceCount):
                self._voices.append( self.tts.GetVoices()[v])
            return True
        except:
            return False
#TERMINATE INSTANCE OF ENGINE!
    def terminate(self):
        del self.tts
#NUMBER OF VOICES FOR ENGINE!
    def getVoiceCount(self):
        return len(self.tts.GetVoices())
#NAME OF A VOICE NUMBER!
    def getVoiceName(self, num):
        return self.tts.GetVoices()[num-1].GetDescription()
#WHAT IS VOICE RATE?
    def getRate(self):
        "MICROSOFT SAPI 5 RATE IS -10 TO 10"
        return (self.tts.rate)
#WHAT IS THE VOICE PITCH?
    def getPitch(self):
        "PITCH FOR MICROSOFT SAPI 5 IS AN XML COMMAND!"
        return self._pitch
#GET THE ENGINE VOLUME!
    def getVolume(self):
        "MICROSOFT SAPI 5 VOLUME IS 1% TO 100%"
        return self.tts.volume
#GET THE VOICE NUMBER!
    def getVoiceNum(self):
        return self._voice
#SET A VOICE BY NAME!
    def setVoiceByName(self, name):
        "VOICE IS SET BY NAME!"
        for i in range( self._voiceCount):
            vp = self.tts.GetVoices()[ i].GetDescription().find( name)
            if vp>0:
                self.tts.Voice = self._voices[i]
#                self.tts.Voice = self.tts.GetVoices()[i]
                self.tts.Speak( "%s Set!" % name)
                self._voice=i+1
                break
        if i >= self._voiceCount:
            self.tts.Speak( "%s Not Found!" % name)
#USED FOR BOOKMARKING AND USE LATER!
    def _get_lastIndex(self):
        bookmark=self.tts.status.LastBookmark
        if bookmark!="" and bookmark is not None:
            return int(bookmark)
        else:
            return -1
#NOW SET ENGINE PARMS!
#SET THE VOICE RATE!
    def setRate(self, rate):
        "MICROSOFT SAPI 5 RATE IS -10 TO 10"
        if rate > 10: rate = 10
        if rate < -10: rate = -10
        self.tts.Rate = rate
#SET PITCH OF THE VOICE!
    def setPitch(self, value):
        "MICROSOFT SAPI 5 pitch is really controled with xml around speECH TEXT AND IS -10 TO 10"
        if value > 10: value = 10
        if value < -10: value = -10
        self._pitch=value
#SET THE VOICE VOLUME!
    def setVolume(self, value):
        "MICROSOFT SAPI 5 VOLUME IS 1% TO 100%"
        self.tts.Volume = value
#CREATE ANOTHER INSTANCE OF A VOICE!
    def createVoice(self, value=1):
        if value > self.getVoiceCount:
            value = self.getVoiceCount
        if value < 1:
            value = 1
        new_tts = CreateObject( 'sapi.SPVoice')
        return (new_tts.GetVoices()[ value-1])
#SPEAKING TEXT!
#SPEAK TEXT USING BOOKMARKS AND PITCH!
    def SpeakText(self, text, wait=False, index=None):
        "SPEAK TEXT AND XML FOR PITCH MUST REPLACE ANY <> SYMBOLS BEFORE USING XML BRACKETED TEXT"
        flags = constants4tts.XML
        text = text.replace( "<", "&lt;")
        pitch = ((self._pitch*2)-100)/10
        if isinstance(index, int):
            bookmarkXML = "<Bookmark Mark = \"%d\" />" % index #NOTE \" FOR XML FORMAT CONVERSION!
        else:
            bookmarkXML = ""
        flags = constants4tts.XML
        if wait is False:
            flags += constants4tts.Async
        self.tts.Speak( "<pitchabsmiddle = \"%s\">%s%s</pitch>" % (pitch, bookmarkXML, text), flags)
#CANCEL SPEAK IN PROGRESS!
    def cancel(self):
        #if self.tts.Status.RunningState == 2:
        self.tts.Speak(None, 1|constants4tts.Purge)
#SPEAK TEXT!
    def Speak(self, text, wait=0, sync=0, async=0, purge=0, isfile=0, xml=0, not_xml=0, persist=0, punc=0):
        "SAPI 5 HAS NO PITCH SO HAS TO BE IN TEXT SPOKEN!"
        pitch=self._pitch
        self.tts.Speak( "<pitch absmiddle='%s'/>%s" % (pitch, text), wait |sync |async |purge |isfile |xml |not_xml |persist |punc)
#SPEAK TEXT WITHOUT PITCH!
    def SpeakFile(self, text, wait=0, sync=0, async=0, purge=0, isfile=0, xml=0, not_xml=0, persist=0, punc=0):
        "SPEAKING A FILE WITHOUT PITCH"
        self.tts.Speak( text, wait |sync |async |purge |isfile |xml |not_xml |persist |punc)
#SET THE VOICE BY VALUE!
    def setVoice(self,value):
        "SET VOICE AND SAY ITS DESCRIPTION!"
        if value < 1:
            value=1
        if value > self._voiceCount:
            value = self._voiceCount
        self.tts.Voice = self._voices[ value-1]
        vd = self.tts.GetVoices()[ value-1].GetDescription()
        self.tts.Speak( vd[ vd.find(" "):])
        self._voice=value
#READ ALL THE VOICES IN THE ENGINE!
    def read_Voices(self):
        self.tts.Speak( "Voices are:")
        for i in range(1, self._voiceCount+1):
            #print self.getVoiceName(i)
            self.tts.Voice = self.tts.GetVoices()[i-1]
            vd = self.tts.GetVoices()[ i-1].GetDescription()
            self.tts.Speak( "%d) %s" % (i, vd[ vd.find(" "):]))
-----------------------------------------------------------------------------------




end_speech()