2 # -*- coding: utf-8 -*-
\r
3 #A part of NonVisual Desktop Access (NVDA)
\r
4 #Copyright (C) 2006-2010 NVDA Contributors <http://www.nvda-project.org/>
\r
5 #This file is covered by the GNU General Public License.
\r
6 #See the file COPYING for more details.
\r
8 # Copyright (C) 2013 Masamitsu Misono (043.jp)
\r
9 # Copyright (C) 2010-2014 Takuya Nishimoto (nishimotz.com)
\r
11 from synthDriverHandler import SynthDriver,VoiceInfo,BooleanSynthSetting
\r
12 from collections import OrderedDict
\r
13 from logHandler import log
\r
15 import synthDriverHandler
\r
16 import languageHandler
\r
17 from jtalk import jtalkDriver
\r
18 from jtalk.jtalkDriver import VoiceProperty
\r
19 from jtalk._nvdajp_espeak import isJapaneseLang
\r
21 class SynthDriver(SynthDriver):
\r
22 """A Japanese synth driver for NVDAjp.
\r
24 name = "nvdajp_jtalk"
\r
25 description = "JTalk"
\r
27 SynthDriver.VoiceSetting(),
\r
28 SynthDriver.RateSetting(),
\r
29 BooleanSynthSetting("rateBoost",_("Rate boos&t")),
\r
30 SynthDriver.PitchSetting(),
\r
31 SynthDriver.InflectionSetting(),
\r
32 SynthDriver.VolumeSetting()
\r
40 self.voice_id = 'V2'
\r
43 self._inflection = 50
\r
44 self._rateBoost = False
\r
45 jtalkDriver.initialize()
\r
48 def speak(self,speechSequence):
\r
51 defaultLanguage = languageHandler.getLanguage()
\r
52 if defaultLanguage[:2] == 'ja': defaultLanguage = 'ja'
\r
53 lang = defaultLanguage
\r
55 for item in speechSequence:
\r
56 if isinstance(item,basestring):
\r
58 p.pitch = self._pitch
\r
59 p.inflection = self._inflection
\r
60 p.characterMode = spellState
\r
62 isMsgJp = isJapaneseLang(msg)
\r
66 elif defaultLanguage != 'ja' and not isMsgJp:
\r
67 lang = defaultLanguage
\r
68 log.debug("lang:%s idx:%s pit:%d inf:%d chr:%d (%s)" % (lang, str(finalIndex), p.pitch, p.inflection, p.characterMode, msg))
\r
69 jtalkDriver.speak(msg, lang, index=finalIndex, voiceProperty_=p)
\r
70 elif isinstance(item,speech.IndexCommand):
\r
71 finalIndex = item.index
\r
72 elif isinstance(item,speech.CharacterModeCommand):
\r
77 elif isinstance(item,speech.LangChangeCommand):
\r
78 lang = (item.lang if item.lang else defaultLanguage).replace('_','-')
\r
79 if lang[:2] == 'ja': lang = 'ja'
\r
81 elif isinstance(item,speech.SpeechCommand):
\r
82 log.debugWarning("Unsupported speech command: %s"%item)
\r
84 log.error("Unknown speech: %s"%item)
\r
89 def pause(self,switch):
\r
90 jtalkDriver.pause(switch)
\r
92 def isSpeaking(self):
\r
93 return jtalkDriver.isSpeaking()
\r
95 def _get_rateBoost(self):
\r
96 return self._rateBoost
\r
98 def _set_rateBoost(self, enable):
\r
99 if enable == self._rateBoost:
\r
102 self._rateBoost = enable
\r
105 def terminate(self):
\r
106 jtalkDriver.terminate()
\r
108 # The current rate; ranges between 0 and 100
\r
109 def _get_rate(self):
\r
110 return jtalkDriver.get_rate(self._rateBoost)
\r
112 def _set_rate(self,rate):
\r
113 jtalkDriver.set_rate(int(rate), self._rateBoost)
\r
115 def _get_pitch(self):
\r
118 def _set_pitch(self,pitch):
\r
119 self._pitch = int(pitch)
\r
121 def _get_volume(self):
\r
122 return self._volume
\r
124 def _set_volume(self,volume_):
\r
125 self._volume = int(volume_)
\r
126 jtalkDriver.set_volume(self._volume)
\r
129 def _get_inflection(self):
\r
130 return self._inflection
\r
132 def _set_inflection(self,val):
\r
133 self._inflection = int(val)
\r
135 def _getAvailableVoices(self):
\r
136 log.debug("_getAvailableVoices called")
\r
137 voices = OrderedDict()
\r
138 for v in jtalkDriver._jtalk_voices:
\r
139 voices[v['id']] = VoiceInfo(v['id'], v['name'], v['lang'])
\r
142 def _get_voice(self):
\r
143 log.debug("_get_voice called")
\r
144 return self.voice_id
\r
146 def _set_voice(self, identifier):
\r
147 log.debug("_set_voice %s" % (identifier))
\r
148 rate = jtalkDriver.get_rate(self._rateBoost)
\r
149 for v in jtalkDriver._jtalk_voices:
\r
150 if v['id'] == identifier:
\r
151 if self.voice_id != identifier:
\r
152 self.voice_id = identifier
\r
153 jtalkDriver.terminate()
\r
154 jtalkDriver.initialize(v)
\r
155 jtalkDriver.set_rate(rate,self._rateBoost)
\r
156 jtalkDriver.set_volume(self._volume)
\r
160 def _get_lastIndex(self):
\r
161 if jtalkDriver.lastIndex is None:
\r
162 #log.debug("_get_lastIndex returns None")
\r
164 #log.debug("_get_lastIndex returns %d" % jtalkDriver.lastIndex)
\r
165 return jtalkDriver.lastIndex
\r