Skip to content

Commit b57305d

Browse files
authored
Merge 8f70ef1 into 69c8c5b
2 parents 69c8c5b + 8f70ef1 commit b57305d

1 file changed

Lines changed: 19 additions & 5 deletions

File tree

source/synthDrivers/sapi4.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@
4545
PitchCommand,
4646
RateCommand,
4747
VolumeCommand,
48+
BaseProsodyCommand
4849
)
50+
from speech.types import SpeechSequence
4951

5052

5153
class SynthDriverBufSink(COMObject):
@@ -124,19 +126,32 @@ def __init__(self):
124126
def terminate(self):
125127
self._bufSink._allowDelete = True
126128

127-
def speak(self,speechSequence):
129+
def speak(self, speechSequence: SpeechSequence):
128130
textList=[]
129131
charMode=False
130132
item=None
131133
oldPitch = self.pitch
132134
oldVolume = self.volume
133135
oldRate = self.rate
134-
136+
# #15500: Some SAPI4 voices reset all prosody when they receive any prosody command.
137+
prosodyToAdd = [
138+
c() for c in self.supportedCommands
139+
if issubclass(c, BaseProsodyCommand)
140+
]
141+
unprocessedSequence = speechSequence
142+
# Add all default values to the start and end of the sequence,
143+
# but avoid duplicating the first command, if any.
144+
speechSequence = [c for c in prosodyToAdd if not isinstance(unprocessedSequence[0], type(c))]
145+
speechSequence.extend(unprocessedSequence)
146+
# Also, add all default values to the end of the sequence.
147+
speechSequence.extend(prosodyToAdd)
148+
lastHandledIndexInSequence = 0
135149
for item in speechSequence:
136150
if isinstance(item,str):
137151
textList.append(item.replace('\\','\\\\'))
138152
elif isinstance(item, IndexCommand):
139153
textList.append("\\mrk=%d\\"%item.index)
154+
lastHandledIndexInSequence = item.index
140155
elif isinstance(item, CharacterModeCommand):
141156
textList.append("\\RmS=1\\" if item.state else "\\RmS=0\\")
142157
charMode=item.state
@@ -162,9 +177,8 @@ def speak(self,speechSequence):
162177
log.debugWarning("Unsupported speech command: %s"%item)
163178
else:
164179
log.error("Unknown speech: %s"%item)
165-
if isinstance(item, IndexCommand):
166-
# This is the index denoting the end of the speech sequence.
167-
self._finalIndex=item.index
180+
# lastHandledIndexInSequence is the index denoting the end of the speech sequence.
181+
self._finalIndex = lastHandledIndexInSequence
168182
if charMode:
169183
# Some synths stay in character mode if we don't explicitly disable it.
170184
textList.append("\\RmS=0\\")

0 commit comments

Comments
 (0)