#!/usr/bin/python import sys import os import random import xchat __module_name__ = 'polotin' __module_version__ = '0.1' __module_description__ = 'Text to speech module for XChat' random.seed() speechdev = os.popen('/usr/bin/festival --pipe', 'w') defvoices = ['cmu_us_slt_arctic_hts', 'cmu_us_jmk_arctic_hts', 'cmu_us_bdl_arctic_hts', 'ked_diphone', 'kal_diphone'] allvoices = ['cmu_us_slt_arctic_hts', 'cmu_us_jmk_arctic_hts', 'cmu_us_bdl_arctic_hts', 'ked_diphone', 'kal_diphone', 'us1_mbrola', 'us2_mbrola', 'us3_mbrola'] fivoices = ['hy_fi_mv_diphone', 'suo_fi_lj_diphone'] voices = fivoices nicks = {} class Voice: # default to festival defaults def __init__(self, voice='kal_diphone', speed='1.0'): self.dev = speechdev self.voice = voice self.speed = speed def setSpeed(self, speed): self.speed = speed self.dev.write("(Parameter.set 'Duration_Stretch %s)\n" % speed) def setVoice(self, voice): self.voice = voice self.dev.write("(voice_%s)\n" % voice) # This isn't exactly efficient :) def _fixtext(self, text): # Do something about smileys # TODO: need to handle a lot more of them and support several # languages... text = text.replace(':)', 'hymyilee') text = text.replace(':D', 'nauraa') text = text.replace('xD', 'repeilee') text = text.replace(':(', 'suree') text = text.replace(';(', 'murjottaa') # Festival doesn't support utf-8, sigh.. text = text.replace('ö', '\xf6') text = text.replace('Ö', '\xd6') text = text.replace('ä', '\xe4') text = text.replace('Ä', '\xc4') text = text.replace('å', '\xe5') text = text.replace('Å', '\xc5') return text def speak(self, text): if self.voice: self.setVoice(self.voice) if self.speed: self.setSpeed(self.speed) self.dev.write('(SayText "%s")\n' % self._fixtext(text)) self.dev.flush() class randomVoice(Voice): def __init__(self): voice = voices[random.randrange(0, len(voices))] speed = random.randrange(75, 120) / 100.0 Voice.__init__(self, voice=voice, speed=speed) class nickVoice(Voice): def __init__(self, nick): self.nick = nick voice = voices[self._nickVal() % len(voices)] speed = (self._nickVal() % 45 + 75) / 100.0 Voice.__init__(self, voice=voice, speed=speed) def _nickVal(self): i = 0 for a in map(ord, self.nick): i += a return i def speak(word, word_eol, userdata): global nicks nick = word[0] if not nicks.has_key(nick): nickvoice = nickVoice(nick) #nickvoice = randomVoice() nicks[nick] = nickvoice xchat.prnt('new speaker %s (%s, %s)' % (nick, nickvoice.voice, nickvoice.speed)) nicks[nick].speak(word_eol[1]) def say(word, word_eol, userdata): voice = randomVoice() voice.speak(word_eol[1]) return xchat.EAT_ALL if __name__ == '__main__': EVENTS = [ 'Generic Message', 'Channel Message', 'Channel Msg Hilight', 'Private Message', 'Private Message to Dialog', ] for event in EVENTS: xchat.hook_print(event, speak, (event,)) xchat.hook_command('say', say) msg = 'Pölötin aktivoitu' xchat.prnt(msg) voice = randomVoice() voice.speak(msg)