Hi,

Attached file, macspeechX.py, is a replacement for macspeech module which used to be included in the Mac-Python distribution. As name indicates, it works with MacOSX and has similar, if not same, interfaces found in the old macspeech module.

It requires ctypes module newer than 0.9.6 and Mac OSX 10.{2,3.4}.
Python interpreter come with MacOSX may not work, at least for me,
so you might need to build and install python from the source code.
Python 2.4.1 and ctypes 0.9.6 should work well.

I hope someone will think it is useful.

Thanks,

Noboru Yamamoto
Accelerator Lab.
KEK, JAPAN
#!/usr/local/bin/python
"""
macspeechX.py ; Python Interface to Speech Syntheis Mangaer on Macintosh OSX.
requires; ctypes module(0.9.6 or later) and latest python interpreter.
Python interpreter pre-installed on OS may not work with latest ctypes module.

macspeechX tryed to simulate old macspeech module bundled with python(in
Pre-MacOSX era). The document for macspeech module should work on macspeechX 
module.

(c) Noboru Yamamoto(KEK,JAPAN),2005
"""
import ctypes
from ctypes import cdll,byref
#load speachSynthesis dll
__SS_Available=None

try:
    
__ssdll=cdll.LoadLibrary("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/SpeechSynthesis.framework/Versions/Current/SpeechSynthesis")
    __SS_Available=1
except:
    raise "Speech Systheis is not available on this machine"

#
def C2PStr(aStr):
    return "%c%s"%(len(aStr),aStr)
#constants
_kNoEndingProsody = 1
_kNoSpeechInterrupt = 2
_kPreflightThenPause = 4

_kNeuter=0
_kMake=1
_kFemale=2

_kImmediate=0
_kEndOfWord=1
_kEndOfSentence=2

# classes
class NumVersion(ctypes.Structure):
    _fields_=[("nonRelRev",ctypes.c_ubyte),
              ("stage",ctypes.c_byte),
              ("minorAndBugRev",ctypes.c_ubyte),
              ("majorRev",ctypes.c_ubyte)]
    
class VoiceSpec(ctypes.Structure):
    _fields_=[ ("creator",ctypes.c_ulong),
               ("id",ctypes.c_ulong),    
               ]

class VoiceDescription(ctypes.Structure):
    _fields_=[ ("length",ctypes.c_long),
               ("Voice",VoiceSpec),    
               ("version",ctypes.c_long),
               ("name",ctypes.c_char*64),
               ("comment",ctypes.c_char*256),
               ("gender",ctypes.c_short),
               ("age",ctypes.c_short),
               ("script",ctypes.c_short),
               ("language",ctypes.c_short),
               ("region",ctypes.c_short),        
               ("reserved",ctypes.c_long*4), 
               ]

class SpeechChannelRecord(ctypes.Structure):
    _fields_=[("data",ctypes.c_long*1)]

# classes for macspeech
__ssdll.GetVoiceDescription.argtypes=[VoiceSpec, 
ctypes.POINTER(VoiceDescription) ]

class SpeechChannel:
    __ssdll=globals()["__ssdll"]
    __ssdll.NewSpeechChannel.argtypes=[ctypes.POINTER(VoiceSpec), 
                                       
ctypes.POINTER(ctypes.POINTER(SpeechChannelRecord))]

    def __init__(self,v=None):
        if not v:
            v=Voice(0)
        self.channel=ctypes.pointer(SpeechChannelRecord())
        
status=SpeechChannel.__ssdll.NewSpeechChannel(byref(v),byref(self.channel))
 
    def __del__(self):
        SpeechChannel.__ssdll.DisposeSpeechChannel(self.channel)
        
    def SpeakText(self,s):
        status=SpeechChannel.__ssdll.SpeakText(self.channel, s, len(s))
        return status

    def SpeakBuffer(self,  s, l, c=0):
        status=SpeechChannel.__ssdll.SpeakText(self.channel, s, 
ctypes.c_ulong(l), ctypes.c_long(c))
        return status

    def Stop(self):
        status=SpeechChannel.__ssdll.StopSpeech(self.channel)
        return status

    def StopAt(self,where=_kImmediate):
        status=SpeechChannel.__ssdll.StopSpeechAt(self.channel,where)
        return status

    def Pause(self,where=_kImmediate):
        status=SpeechChannel.__ssdll.PauseSpeechAt(self.channel,where)
        return status

    def Continue(self):
        status=SpeechChannel.__ssdll.ContinueSpeech(self.channel)
        return status
                    
    def GetPitch(self):
        pitch=ctypes.c_long(0)
        status=SpeechChannel.__ssdll.GetSpeechPitch(self.channel, byref(pitch))
        self.pitch=pitch.value
        return pitch.value

    def SetPitch(self, pitch):
        
status=SpeechChannel.__ssdll.SetSpeechPitch(self.channel,ctypes.c_long(pitch))
        self.pitch=pitch
        return pitch

    def GetRate(self):
        rate=ctypes.c_long(0)
        status=SpeechChannel.__ssdll.GetSpeechRate(self.channel,byref(rate))
        self.rate=rate.value
        return self.rate

    def SetRate(self,rate):
        
status=SpeechChannel.__ssdll.SetSpeechRate(self.channel,ctypes.c_long(rate))
        self.rate=rate
        return rate
    
class Voice:
    __ssdll=globals()["__ssdll"]
    __ssdll.GetVoiceDescription.argtypes=[ctypes.POINTER(VoiceSpec), 
ctypes.POINTER(VoiceDescription) ]
    
    def __init__(self,ind=1):
        self.voice=VoiceSpec()
        Voice.__ssdll.GetIndVoice(ind, byref(self.voice))
        self.desc=VoiceDescription()
        
    def GetDescription(self):
        status=Voice.__ssdll.GetVoiceDescription(ctypes.pointer(self.voice), 
ctypes.pointer(self.desc))
        if status:
            print "GetVoiceDescription RC:",status
        return (self.desc)
            
    def GetGender(self):
        if not self.desc:
            self.GetDescription()
        return self.desc.gender
                    
    def NewChannel(self):
        return SpeechChannel(self.voice)

#
def Available():
    return __SS_Available

def Version():
    vers=NumVersion()
    status=__ssdll.SpeechManagerVersion(byref(vers))
    return 
((vers.nonRelRev<<24)+(vers.stage<<16)+(vers.minorAndBugRev<<8)+(vers.majorRev))
    
def SpeakString(s):
    return __ssdll.SpeakString(C2PStr(s))

def Busy():
    return __ssdll.SpeechBusy()

__ssdll.CountVoices.argtypes=[ctypes.c_void_p]

def CountVoices():
    count=ctypes.c_short(0)
    status=__ssdll.CountVoices(byref(count))
    return count.value
    
def GetIndVoice(n=0):
    return Voice(n)
        
#test function.
def list_voice_name():
    n=CountVoices()
    gender={0:"Neuter",1:"Male",2:"Female"}
    for i in xrange(1,n+1):
        v=GetIndVoice(i)
        while Busy():
            pass
        d=v.GetDescription()
        ch=v.NewChannel()
        print "%d: %s, %d, %s"%(i, d.name[1:], d.age, gender[d.gender])
        ch.SpeakText("my name is %s of age %d."%(d.name[1:],d.age))
        while Busy():
            pass
_______________________________________________
Pythonmac-SIG maillist  -  Pythonmac-SIG@python.org
http://mail.python.org/mailman/listinfo/pythonmac-sig

Reply via email to