Hi! Below is the settings to use the built in SAPI 5 voices. It will also read any other voices loaded into the SAPI 5 and stores the list of all of them. You can change the names of the methods if you so desire. I am giving you an example of how to set up your voices. NOTE: The pitch of the voices has to be an XML command and it is built into the speech or Speak method. You will need to understand the XML commands if you wish to use the added XML features. Pitch is just one and there is one for spell, bookmarks, and so on... Bruce #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( "<", "<") 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) #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(" "):])) |