Hi!
    I am giving you the Python version of creating SAPI methods and properties 
and of course you can change the names of the definitions if you so desire to 
your liking.

    Below is a class setup. You will note several things in this, one of which 
is
the key word "self" which is used to point to the object created by the class 
inside
of it's self...
All procedures first parm is the object itself and since it is it's self, that 
is
what is placed as the first parm.
I added a constants class and use it for XML commands mostly.
This also uses the Windows Registry and that is the second thing imported for we
are only creating an object and looking for a registry key for SAPI installation
on the computer. Of course this registry check could be done for Windoweyes as 
well and you could make up your own Properties/Methods list for Windoweyes.
    You will note that the parms inside the parameter list have assigned values,
that is the default if no values are passed in. This allows you to set defaults.
    I also give you a procedure to making a .wav file of speech being said. You 
can
create an audio file of any spoken text.
Note:
I did not mention before but the next line below a def statement that has quotes
is a description of the procedure which also can be displayed when asking for a 
description of a property/method,
so it is used when exposing the method.
You will also note triple quotes (""") this allows multiple lines with line 
breaks
to be displayed. This comes in handy when making a long help/description list 
having many lines.
I also have methods for bookmarks and spelling, misspelling and all that stuff. 
Methods
for most of the SAPI object.
        Bruce
#Global Stuff:
#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 for SAPI constants:
class constants4tts:
    Wait = -1
    Sync = 0
    Async = 1
    Purge = 2
    Is_filename = 4
    XML = 8
    Not_XML = 16
    Persist = 32
    Punc = 64

#Class for SAPI object, properties and methods:
class SynthDriver():
    name="sapi5"
    description="Microsoft Speech API version 5 (sapi.SPVoice)"
    _pitch = 0 #SAPI itself has no pitch, it is an XML Command
    _voices = [] #Storage for voice list.
    _words = {} #Dictionary storage for word pronounciation substitution.
    _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!

#Check to see if SAPI is installed on your computer:
    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=0
            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].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 pronounce.
    def Pronounce(self):
        return (wordPronounce)

#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 THE VOICE BY VALUE!
    def setVoice(self,value):
        "SET VOICE AND SAY ITS DESCRIPTION!"
        if value < 1:
            value=0
        if value >= self._voiceCount:
            value = self._voiceCount - 1
        self.tts.Voice = self._voices[ value]
        vd = self.tts.GetVoices()[ value].GetDescription().find( " ")
#        self.tts.Speak( vd[ vd.find(" "):])
        self._voice=value

#SET THE VOICE BY ORDINAL VALUE!
    def setVoiceByNum(self,value):
        "SET VOICE BY ITS ORDINAL VALUE STARTING AT 0 AND SAY ITS DESCRIPTION!"
        self.setVoice( value)

#SET A VOICE BY NAME!
    def setVoiceByName(self, name):
        "VOICE IS SET BY NAME!"
        t=-1
        for i in range( self._voiceCount):
            if self.tts.GetVoices()[ i].GetDescription().find( name) >= 0:
                t=i
                self.tts.Voice = self._voices[i]
#                self.tts.Speak( " %s " % "Now") #name)
                self._voice=i
                break
        if t == -1:
            self.tts.Voice = self._voices[i]
            self._voice=i
            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%"
        if value > 100: value = 100
        if value <= 0: value = 0
        self.tts.Volume = value

#CREATE ANOTHER INSTANCE OF A VOICE!
    def createVoice(self, voice):
        num = 0
        for i in range( self._voiceCount):
            if self.tts.GetVoices()[ i].GetDescription().find( voice) >= 0:
                num=i
                break
        new_tts = CreateObject( 'sapi.SPVoice')
        new_tts.Voice = self._voices[ num]
        return (new_tts)

#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)
        try:
            self.tts.Speak( "<pitchabsmiddle = \"%s\">%s%s</pitch>" % (pitch, 
bookmarkXML,
text), flags)
#            self.tts.Speak( "<pitch absmiddle='%s'/>%s" % (pitch, text), wait 
|sync
|async |purge |isfile |xml |not_xml |persist |punc)
        except:
            # Error probably due to no class for voice.
            self.setVoice( 0)
            self.tts.Speak( "<pitchabsmiddle = \"%s\">%s%s</pitch>" % (pitch, 
bookmarkXML,
text), flags)
            #pass

#CANCEL SPEAK IN PROGRESS!
    def cancel(self):
        #if self.tts.Status.RunningState == 2:
        self.tts.Speak(None, 1|constants4tts.Purge)

#SET AUDIO STREAM FOR OUTPUT TO A FILE!
    def SpeakToWav(self, filename, text, voice):
        """THIS METHOD ASSUMES THE IMPORT OF COMTYPES.CLIENT createObject SO
            A VOICE AND FILE STREAM OBJECT ARE CREATED WITH THE PASSING IN OF 3 
STRINGS:
            THE FILE NAME TO SAVE THE VOICE INTO, THE TEXT, AND THE VOICE SPOKEN
IN.
            ONCE THE TEXT IS SPOKEN INTO THE FILE, IT IS CLOSED AND THE OBJECTS 
DESTROYED!"""
        num = 0
        for i in range( self._voiceCount):
            if self.tts.GetVoices()[ i].GetDescription().find( voice) >= 0:
                num=i
                break
        stream = CreateObject("SAPI.SpFileStream")
        tts4file = CreateObject( 'sapi.SPVoice')
        tts4file.Voice = self._voices[ num]
        from comtypes.gen import SpeechLib
        stream.Open( filename, SpeechLib.SSFMCreateForWrite)
        tts4file.AudioOutputStream = stream
        tts4file.Speak( text, 0)
        stream.Close()
        del tts4file
        del stream

#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
        try:
            self.tts.Speak( "<pitch absmiddle='%s'/>%s" % (pitch, text), wait 
|sync
|async |purge |isfile |xml |not_xml |persist |punc)
        except:
            # Error probably due to no class for voice.
            self.setVoice( 1)
            self.tts.Speak( "<pitch absmiddle='%s'/>%s" % (pitch, text), wait 
|sync
|async |purge |isfile |xml |not_xml |persist |punc)
            #pass
#            self.tts.Speak( text, wait |sync |async |purge |isfile |xml 
|not_xml
|persist |punc)

#SPEAK TEXT WITHOUT PITCH!
    def Speaking(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"
        try:
            self.tts.Speak( text, wait |sync |async |purge |isfile |xml |not_xml
|persist |punc)
        except:
            # Error probably due to no class for voice.
            self.setVoice( 1)
            self.tts.Speak( text, wait |sync |async |purge |isfile |xml |not_xml
|persist |punc)
            #pass

#READ ALL THE VOICES IN THE ENGINE!
    def read_Voices(self):
        self.tts.Speak( "Voices are:")
        for i in range( self._voiceCount):
            print self.getVoiceName(i)
            self.tts.Voice = self.tts.GetVoices()[i]
            vd = self.tts.GetVoices()[ i].GetDescription()
            self.tts.Speak( "%d) %s" % (i, vd[ vd.find(" "):]))

#Add words to the pronounciation list:
    def add2Pronounce(self, word, misspelling):
        self._words[ word] = misspelling

#Replace word in sentence before speaking:
    def doPronounce(self, sentence):
        for word, misspelling in self._words.items():
            sentence = sentence.replace( word, misspelling)
        return (sentence)


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

_______________________________________________
Any views or opinions presented in this email are solely those of the author 
and do not necessarily represent those of Ai Squared.

For membership options, visit 
http://lists.window-eyes.com/options.cgi/scripting-window-eyes.com/archive%40mail-archive.com.
For subscription options, visit 
http://lists.window-eyes.com/listinfo.cgi/scripting-window-eyes.com
List archives can be found at 
http://lists.window-eyes.com/private.cgi/scripting-window-eyes.com

Reply via email to