Esempio n. 1
0
class EspeakDriver(object):
    _moduleInitialized = False
    _defaultVoice = ''

    def __init__(self, proxy):
        if not EspeakDriver._moduleInitialized:
            # espeak cannot initialize more than once per process and has
            # issues when terminating from python (assert error on close)
            # so just keep it alive and init once
            rate = _espeak.Initialize(_espeak.AUDIO_OUTPUT_PLAYBACK, 1000)
            if rate == -1:
                raise RuntimeError('could not initialize espeak')
            EspeakDriver._defaultVoice = self.getProperty('voice')
            EspeakDriver._moduleInitialized = True
        _espeak.SetSynthCallback(self._onSynth)
        # make sure all props reset
        self.setProperty('voice', EspeakDriver._defaultVoice)
        self.setProperty('rate', 200)
        self.setProperty('volume', 1.0)
        self._proxy = proxy
        self._looping = True
        self._stopping = False

    def destroy(self):
        _espeak.SetSynthCallback(None)

    def say(self, text):
        self._proxy.setBusy(True)
        self._proxy.notify('started-utterance')
        _espeak.Synth(text, flags=_espeak.ENDPAUSE)

    def speakToFile(self, text, filename):
        raise NotImplementedError('Not implemented in this driver')

    def stop(self):
        if _espeak.IsPlaying():
            self._stopping = True

    def getProperty(self, name):
        if name == 'voices':
            voices = []
            for v in _espeak.ListVoices(None):
                kwargs = {}
                kwargs['id'] = v.name
                kwargs['name'] = v.name
                if v.languages:
                    kwargs['languages'] = [v.languages]
                genders = [None, 'male', 'female']
                kwargs['gender'] = genders[v.gender]
                kwargs['age'] = v.age or None
                voices.append(Voice(**kwargs))
            return voices
        elif name == 'voice':
            return _espeak.GetCurrentVoice().contents.name
        elif name == 'rate':
            return _espeak.GetParameter(_espeak.RATE)
        elif name == 'volume':
            return _espeak.GetParameter(_espeak.VOLUME) / 100.0
        else:
            raise KeyError('unknown property %s' % name)

    def setProperty(self, name, value):
        if name == 'voice':
            if value is None: return
            try:
                _espeak.SetVoiceByName(value)
            except ctypes.ArgumentError, e:
                raise ValueError(str(e))
        elif name == 'rate':
            try:
                _espeak.SetParameter(_espeak.RATE, value, 0)
            except ctypes.ArgumentError, e:
                raise ValueError(str(e))
Esempio n. 2
0
    def setProperty(self, name, value):
        if name == 'voice':
            if value is None: return
            try:
                _espeak.SetVoiceByName(value)
            except ctypes.ArgumentError, e:
                raise ValueError(str(e))
        elif name == 'rate':
            try:
                _espeak.SetParameter(_espeak.RATE, value, 0)
            except ctypes.ArgumentError, e:
                raise ValueError(str(e))
        elif name == 'volume':
            try:
                _espeak.SetParameter(_espeak.VOLUME, int(round(value * 100,
                                                               2)), 0)
            except TypeError, e:
                raise ValueError(str(e))
        else:
            raise KeyError('unknown property %s' % name)

    def startLoop(self):
        first = True
        self._looping = True
        while self._looping:
            if first:
                # kick the queue
                self._proxy.setBusy(False)
                first = False
            if self._stopping:
                # have to do the cancel on the main thread, not inside the