Skip to content

Commit fe03ced

Browse files
authored
Merge 454033e into c756899
2 parents c756899 + 454033e commit fe03ced

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

source/synthDrivers/sapi4.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ def __init__(self):
188188
self._rateDelta = 0
189189
self._pitchDelta = 0
190190
self._volume = 100
191+
self._paused = False
191192
self.voice = str(self._enginesList[0].gModeID)
192193

193194
def terminate(self):
@@ -268,6 +269,12 @@ def cancel(self):
268269
# cancel all pending bookmarks
269270
self._bookmarkLists.clear()
270271
self._bookmarks = None
272+
if self._paused:
273+
# Unpause the voice before resetting,
274+
# because some voices keep the pausing state
275+
# even after resetting.
276+
self._ttsCentral.AudioResume()
277+
self._paused = False
271278
self._ttsCentral.AudioReset()
272279
except COMError:
273280
log.error("Error cancelling speech", exc_info=True)
@@ -282,11 +289,12 @@ def pause(self, switch: bool):
282289
log.debugWarning("Error pausing speech", exc_info=True)
283290
else:
284291
self._ttsCentral.AudioResume()
292+
self._paused = switch
285293

286294
def removeSetting(self, name):
287295
# Putting it here because currently no other synths make use of it. OrderedDict, where you are?
288296
for i, s in enumerate(self.supportedSettings):
289-
if s.name == name:
297+
if s.id == name:
290298
del self.supportedSettings[i]
291299
return
292300

@@ -305,7 +313,18 @@ def _set_voice(self, val):
305313
self._ttsAudio = CoCreateInstance(CLSID_MMAudioDest, IAudioMultiMediaDevice)
306314
self._ttsAudio.DeviceNumSet(_mmDeviceEndpointIdToWaveOutId(config.conf["audio"]["outputDevice"]))
307315
if self._ttsCentral:
308-
self._ttsCentral.UnRegister(self._sinkRegKey)
316+
try:
317+
# Some SAPI4 synthesizers may fail this call.
318+
# Ignore, as _ttsCentral will be destroyed afterwards.
319+
self._ttsCentral.UnRegister(self._sinkRegKey)
320+
except COMError:
321+
pass
322+
# Some SAPI4 synthesizers assume that only one instance of ITTSCentral
323+
# will be created by the client, and will stop working if more are created.
324+
# Here we make sure that the previous _ttsCentral is released
325+
# before the next _ttsCentral is created.
326+
self._ttsCentral = None
327+
self._ttsAttrs = None
309328
self._ttsCentral = POINTER(ITTSCentralW)()
310329
self._ttsEngines.Select(self._currentMode.gModeID, byref(self._ttsCentral), self._ttsAudio)
311330
self._ttsCentral.Register(self._sinkPtr, ITTSNotifySinkW._iid_, byref(self._sinkRegKey))

user_docs/en/changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ In any document, if the cursor is on the last line, it will be moved to the end
126126
* When anchor links point to the same object as the virtual caret is placed, NVDA no longer fails to scroll to the link destination. (#17669, @nvdaes)
127127
* Voice parameters, such as rate and volume, will no longer be reset to default when using the synth settings ring to change between voices in the SAPI5 and SAPI4 synthesizer. (#17693, #2320, @gexgd0419)
128128
* The NVDA Highlighter Window icon is no longer fixed in the taskbar after restarting Explorer. (#17696, @hwf1324)
129+
* Fixed an issue where some SAPI4 voices cannot be loaded and report errors when selected. (#17726, @gexgd0419)
129130

130131
### Changes for Developers
131132

0 commit comments

Comments
 (0)