From 789312264451aaeb6a622f8ff8b6691199e6478b Mon Sep 17 00:00:00 2001 From: David CM Date: Sun, 1 Sep 2019 09:16:44 -0600 Subject: [PATCH] version 19.9b1 undo "now volume, rate and speed default parameters are send at start of speak method on ibmeci." Return to 19.b2. update now speech parameters on realtime are send via dll rater than annotations. fix NVDA 2019.2 doesn't change pitch when read upercase letters. fix sometimes voice parameters are sent delayed --- addon/synthDrivers/_ibmeci.py | 5 ++++- addon/synthDrivers/ibmeci.py | 28 ++++++++++++++-------------- buildVars.py | 2 +- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/addon/synthDrivers/_ibmeci.py b/addon/synthDrivers/_ibmeci.py index 09adbb0..1711561 100644 --- a/addon/synthDrivers/_ibmeci.py +++ b/addon/synthDrivers/_ibmeci.py @@ -177,7 +177,7 @@ def eciCheck(): ttsPath = config.conf.profiles[0]['ibmeci']['TTSPath'] if not path.isabs(ttsPath): - ttsPath = path.join(path.abspath(path.dirname(__file__)), ttsPath) + ttsPath = path.abspath(path.join(path.abspath(path.dirname(__file__)), ttsPath)) if path.exists(ttsPath): iniCheck() if not path.exists(ttsPath): return False if dll: return True @@ -365,6 +365,9 @@ def setVParam(pr, vl): param_event.wait() param_event.clear() +def setProsodyParam(pr, vl): + dll.eciSetVoiceParam(handle, 0, pr, vl) + def setVariant(v): user32.PostThreadMessageA(eciThreadId, WM_COPYVOICE, v, 0) param_event.wait() diff --git a/addon/synthDrivers/ibmeci.py b/addon/synthDrivers/ibmeci.py index 26d1d5b..b5c4975 100644 --- a/addon/synthDrivers/ibmeci.py +++ b/addon/synthDrivers/ibmeci.py @@ -46,14 +46,15 @@ def unicode(s): re.compile(r'(\w+)\.([a-zA-Z]+)'): r'\1 dot \2', re.compile(r'([a-zA-Z0-9_]+)@(\w+)'): r'\1 at \2', } + french_fixes = { re.compile(r'([a-zA-Z0-9_]+)@(\w+)'): r'\1 arobase \2' } + spanish_fixes = { #for emails re.compile(r'([a-zA-Z0-9_]+)@(\w+)'): r'\1 arroba \2', re.compile(u'([€$]\d{1,3})((\s\d{3})+\.\d{2})'): r'\1 \2', } - variants = { 1:"Reed", 2:"Shelley", @@ -132,20 +133,19 @@ def __init__(self): self.variant="1" PROSODY_ATTRS = { - speech.PitchCommand: b'vb', - speech.VolumeCommand: b'vv', - speech.RateCommand: b'vs', + speech.PitchCommand: ECIVoiceParam.eciPitchBaseline, + speech.VolumeCommand: ECIVoiceParam.eciVolume, + speech.RateCommand: ECIVoiceParam.eciSpeed, } def speak(self,speechSequence): last = None defaultLanguage=self.language outlist = [] - outlist.append((_ibmeci.speak, (b'`ts0 `pp0 `vb%d `vs%d `vv%d ' %(self.pitch, _ibmeci.getVParam(ECIVoiceParam.eciSpeed), self.volume),))) + outlist.append((_ibmeci.speak, (b"`ts0",))) for item in speechSequence: if isinstance(item, string_types): s = self.processText(unicode(item)) - if not s: continue outlist.append((_ibmeci.speak, (s,))) last = s elif isinstance(item,speech.IndexCommand): @@ -168,10 +168,10 @@ def speak(self,speechSequence): elif type(item) in self.PROSODY_ATTRS: val = max(0, min(item.newValue, 100)) if type(item) == speech.RateCommand: val = self.percentToRate(val) - outlist.append((_ibmeci.speak, (b' `%s%d ' %(self.PROSODY_ATTRS[type(item)], val),))) + outlist.append((_ibmeci.setProsodyParam, (self.PROSODY_ATTRS[type(item)], val))) else: - log.error("Unknown speech: %s" %item) - if last and str(last[-1]) not in punctuation: outlist.append((_ibmeci.speak, (b'`p1. ',))) + log.error("Unknown speech: %s"%item) + if last is not None and not str(last[-1]) in punctuation: outlist.append((_ibmeci.speak, (b'`p1. ',))) outlist.append((_ibmeci.setEndStringMark, ())) outlist.append((_ibmeci.synth, ())) _ibmeci.eciQueue.put(outlist) @@ -185,19 +185,20 @@ def processText(self,text): text = resub(french_fixes, text) text = text.replace('quil', 'qil') #Sometimes this string make everything buggy with IBMTTS in French if self._backquoteVoiceTags: - text = text.replace('`', ' ') #no embedded commands - text = text.encode('mbcs', 'replace') - text = resub(anticrash_res, text) #this converts to ansi for anticrash. If this breaks with foreign langs, we can remove it. + text = text.replace('`', ' ').encode('mbcs', 'replace') #no embedded commands + text = b"`pp0 `vv%d %s" % (_ibmeci.getVParam(ECIVoiceParam.eciVolume), text) + text = resub(anticrash_res, text) else: #this converts to ansi for anticrash. If this breaks with foreign langs, we can remove it. text = text.encode('mbcs', 'replace') - text = text.replace(b'`', b' ') #no embedded commands text = resub(anticrash_res, text) + text = b"`pp0 `vv%d %s" % (_ibmeci.getVParam(ECIVoiceParam.eciVolume), text.replace(b'`', b' ')) #no embedded commands text = pause_re.sub(br'\1 `p1\2\3', text) text = time_re.sub(br'\1:\2 \3', text) return text + def pause(self,switch): _ibmeci.pause(switch) @@ -224,7 +225,6 @@ def _set_rateBoost(self, enable): self._rateBoost = enable self.rate = rate - def _get_rate(self): val = _ibmeci.getVParam(ECIVoiceParam.eciSpeed) if self._rateBoost: val=int(round(val/self.RATE_BOOST_MULTIPLIER)) diff --git a/buildVars.py b/buildVars.py index 4fc5762..62f98c9 100644 --- a/buildVars.py +++ b/buildVars.py @@ -19,7 +19,7 @@ # Translators: Long description to be shown for this add-on on add-on information from add-ons manager "addon_description" : _("""This is the IBMTTS synthesizer driver for NVDA."""), # version - "addon_version" : "19.8B4", + "addon_version" : "19.9B1", # Author(s) "addon_author" : u"David CM and others", # URL for the add-on documentation support