nvda
e1c76187 - Make synth fallback check all other synths, not just later ones (#19603)

Commit
19 days ago
Make synth fallback check all other synths, not just later ones (#19603) Summary of the issue: If the default speech synthesizer is set to a synth that can't be loaded for some reason, and the only working synth(s) are before that synth in `synthDriverHandler.defaultSynthPriorityList`, NVDA will fall back to `silence`. That is, as reported in #19582, if the default synth is eSpeak and it can't be loaded, NVDA doesn't produce speech at all. Description of user facing changes: If eSpeak is set as the default synth and it can't be loaded, NVDA will first try to use OneCore before falling back to no speech. Description of developer facing changes: `synthDriverHandler.setSynth` and `findAndSetNextSynth` now optionally take an internal-only keyword-only `_leftToTry` list of synth names (in reverse order of priority). The behaviour of `findAndSetNextSynth` has changed to find the first working synth in `defaultSynthPriorityList`, rather than only considering synths after `currentSynthName`. As a result, `setSynth` may fall back to a synth anywhere in `defaultSynthPriorityList`, and will preference synths earlier therein. Description of development approach: Update `synthDriverHandler.setSynth` and `findNextSynth` to take an optional list of synth names. If `None`, it is calculated in `findAndSetNextSynth` from `currentSynthName` and `defaultSynthPriorityList`. In `findAndSetNextSynth`, rather than finding the index of `currentSynthName` in `defaultSynthPriorityList` and attempting to use the next synth, pop a synth name from `leftToTry` and attempt to use that synth. as `findAndSetNextSynth` calls `setSynth` with the popped name and the remainder of `leftToTry`, and `setSynth` calls `findAndSetNextSynth` with what it received as `leftToTry`, this will consume `leftToTry` tail-first until either a working synth is found or `leftToTry` is exhausted. If `findAndSetNextSynth` receives `None` as the value of `leftToTry`, it uses `defaultSynthPriorityList` in reverse order, excluding `currentSynthName`. Otherwise, `currentSynthName` is ignored. Since, if unspecified, `leftToTry` defaults to `defaultSynthPriorityList`, and `findAndSetNextSynth` consumes `leftToTry` in reverse, we try synths from `defaultSynthPriorityList` in order (axiomatically, `reverss(reverse(sequence)) = sequence`). Testing strategy: Raised `RuntimeError` from `synthDrivers.espeak.SynthDriver.__init__` and/or `synthDriverHandler.OneCore.OneCoreSynthDriver.__init__`. Observed the following behaviour: * Default synth OneCore: * OneCore raises: eSpeak NG is used at startup * oneCore does not raise: OneCore is used at startup * Default synth eSpeak NG: * eSpeak NG raises: oneCore is used at startup * eSpeak NG does not raise: eSpeak NG is used at startup * Default synth OneCore or eSpeak NG: * OneCore and eSpeak NG raise: No speech is used at startup * Default synth SAPI 5: * eSpeak NG raises: when attempting to select eSpeak NG, SAPI 5 continues to be used and an error is shown. Known issues with pull request: None known
Author
Parents
Loading