Skip to content

Commit f21446b

Browse files
committed
Another patch for espeak slow downs -- this time caused within navigation.
Previously, I missed adding slow downs for navigation.
1 parent 9c134b7 commit f21446b

File tree

1 file changed

+42
-16
lines changed

1 file changed

+42
-16
lines changed

addon/globalPlugins/MathCAT/MathCAT.py

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
}
8282
RE_MATH_LANG = re.compile(r"""<math .*(xml:)?lang=["']([^'"]+)["'].*>""")
8383

84+
# try to get around espeak bug where voice slows down (for other voices, just a waste of time)
85+
# we use a global that gets set at a time when the rate is probably good (SetMathML)
86+
_synthesizer_rate: int | None = None
87+
8488

8589
def getLanguageToUse(mathMl: str = "") -> str:
8690
"""Get the language specified in a math tag if the language pref is Auto, else the language preference."""
@@ -123,15 +127,12 @@ def ConvertSSMLTextForNVDA(text: str) -> list:
123127
nvdaLanguage = getCurrentLanguage().replace("_", "-")
124128
# log.info(f"mathCATLanguageSetting={mathCATLanguageSetting}, lang={language}, NVDA={nvdaLanguage}")
125129

126-
synth = getSynth()
127130
_monkeyPatchESpeak()
128-
wpm = synth._percentToParam(synth.rate, 80, 450)
129-
try:
130-
if synth.rateBoost:
131-
wpm *= 3 # a guess based on espeak -- not sure what oneCore does
132-
except AttributeError:
133-
pass # SAPI voices don't have 'rateBoost' attr
134-
131+
132+
synth = getSynth()
133+
# I tried the engines on a 180 word excerpt. The speeds do not change linearly and differ a it between engines
134+
# At "50" espeak finished in 46 sec, sapi in 75 sec, and one core in 70; at '100' one core was much slower than the others
135+
wpm = 2*getSynth()._get_rate()
135136
breakMulti = 180.0 / wpm
136137
supported_commands = synth.supportedCommands
137138
use_break = BreakCommand in supported_commands
@@ -224,13 +225,21 @@ def __init__(self, provider=None, mathMl: Optional[str] = None):
224225

225226
def reportFocus(self):
226227
super(MathCATInteraction, self).reportFocus()
228+
# try to get around espeak bug where voice slows down
229+
if _synthesizer_rate and getSynth().name == 'espeak' :
230+
getSynth()._set_rate(_synthesizer_rate)
227231
try:
228232
text = libmathcat.DoNavigateCommand("ZoomIn")
229233
speech.speak(ConvertSSMLTextForNVDA(text))
230234
except Exception as e:
231235
log.exception(e)
232236
# Translators: this message directs users to look in the log file
233237
speech.speakMessage(_("Error in starting navigation of math: see NVDA error log for details"))
238+
finally:
239+
# try to get around espeak bug where voice slows down
240+
if _synthesizer_rate and getSynth().name == 'espeak':
241+
# log.info(f'reportFocus: reset to {_synthesizer_rate}')
242+
getSynth()._set_rate(_synthesizer_rate)
234243

235244
def getBrailleRegions(self, review: bool = False):
236245
# log.info("***MathCAT start getBrailleRegions")
@@ -282,8 +291,10 @@ def getScript(self, gesture: KeyboardInputGesture):
282291
return super().getScript(gesture)
283292

284293
def script_navigate(self, gesture: KeyboardInputGesture):
285-
# log.info("***MathCAT script_navigate")
286294
try:
295+
# try to get around espeak bug where voice slows down
296+
if _synthesizer_rate and getSynth().name == 'espeak' :
297+
getSynth()._set_rate(_synthesizer_rate)
287298
if (gesture is not None): # == None when initial focus -- handled in reportFocus()
288299
modNames = gesture.modifierNames
289300
text = libmathcat.DoNavigateKeyPress(
@@ -299,6 +310,11 @@ def script_navigate(self, gesture: KeyboardInputGesture):
299310
log.exception(e)
300311
# Translators: this message directs users to look in the log file
301312
speech.speakMessage(_("Error in navigating math: see NVDA error log for details"))
313+
finally:
314+
# try to get around espeak bug where voice slows down
315+
if _synthesizer_rate and getSynth().name == 'espeak':
316+
# log.info(f'script_navigate: reset to {_synthesizer_rate}')
317+
getSynth()._set_rate(_synthesizer_rate)
302318

303319
if not braille.handler.enabled:
304320
return
@@ -460,6 +476,14 @@ def __init__(self):
460476
speech.speakMessage(_("MathCAT initialization failed: see NVDA error log for details"))
461477

462478
def getSpeechForMathMl(self, mathml: str):
479+
global _synthesizer_rate
480+
synth = getSynth()
481+
synthConfig = config.conf["speech"][synth.name]
482+
if synth.name == 'espeak':
483+
_synthesizer_rate = synthConfig['rate']
484+
# log.info(f'_synthesizer_rate={_synthesizer_rate}, get_rate()={getSynth()._get_rate()}')
485+
getSynth()._set_rate(_synthesizer_rate)
486+
# log.info(f'..............get_rate()={getSynth()._get_rate()}, name={synth.name}')
463487
try:
464488
# need to set Language before the MathML for DecimalSeparator canonicalization
465489
language = getLanguageToUse(mathml)
@@ -473,8 +497,6 @@ def getSpeechForMathMl(self, mathml: str):
473497
speech.speakMessage(_("Illegal MathML found: see NVDA error log for details"))
474498
libmathcat.SetMathML("<math></math>") # set it to something
475499
try:
476-
synth = getSynth()
477-
synthConfig = config.conf["speech"][synth.name]
478500
supported_commands = synth.supportedCommands
479501
# Set preferences for capital letters
480502
libmathcat.SetPreference(
@@ -502,6 +524,12 @@ def getSpeechForMathMl(self, mathml: str):
502524
# Translators: this message directs users to look in the log file
503525
speech.speakMessage(_("Error in speaking math: see NVDA error log for details"))
504526
return [""]
527+
finally:
528+
# try to get around espeak bug where voice slows down
529+
if _synthesizer_rate and getSynth().name == 'espeak' :
530+
# log.info(f'getSpeechForMathMl: reset to {_synthesizer_rate}')
531+
getSynth()._set_rate(_synthesizer_rate)
532+
505533

506534
def _add_sounds(self):
507535
try:
@@ -612,9 +640,7 @@ def patched_speak(self, speechSequence: SpeechSequence): # noqa: C901
612640
textList.append("</prosody>")
613641
text = "".join(textList)
614642
# log.info(f"monkey-patched text={text}")
615-
# Added saving old rate and then resetting to that -- work around for https://github.com/nvaccess/nvda/issues/15221
616-
# I'm not clear why this works since _set_rate() is called before the speech is finished speaking
617-
synth = getSynth()
618-
oldRate = synth._get_rate()
643+
oldRate: int = getSynth()._get_rate()
619644
_espeak.speak(text)
620-
synth._set_rate(oldRate)
645+
# try to get around espeak bug where voice slows down
646+
getSynth()._set_rate(oldRate)

0 commit comments

Comments
 (0)