Skip to content

Commit

Permalink
OneCore Voices: Fix lag when reporting characters. (#7495)
Browse files Browse the repository at this point in the history
When we speak characters, we include indexes, which get translated to SSML marks. Unfortunately, calling WaveOutOpen blocks for ~100 ms if called from the callback when the SSML includes marks. We're not quite sure why.
To work around this, open the device before queuing.
Move the call to player.idle to _processQueue so that it gets called (thus closing the audio device) even if the UWP code encounters an exception.
  • Loading branch information
jcsteh authored Aug 15, 2017
1 parent 1313193 commit ffa71c7
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions source/synthDrivers/oneCore.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ def cancel(self):
def speak(self, speechSequence):
conv = _OcSsmlConverter(self.language, self.rate, self.pitch, self.volume)
text = conv.convertToXml(speechSequence)
# #7495: Calling WaveOutOpen blocks for ~100 ms if called from the callback
# when the SSML includes marks.
# We're not quite sure why.
# To work around this, open the device before queuing.
self._player.open()
self._queueSpeech(text)

def _queueSpeech(self, item):
Expand All @@ -151,6 +156,12 @@ def _queueSpeech(self, item):
self._processQueue()

def _processQueue(self):
if not self._queuedSpeech:
# There are no more queued utterances at this point, so call idle.
# This blocks while waiting for the final chunk to play,
# so by the time this is done, there might be something queued.
log.debug("Calling idle on audio player")
self._player.idle()
if self._queuedSpeech:
item = self._queuedSpeech.pop(0)
self._wasCancelled = False
Expand Down Expand Up @@ -208,13 +219,6 @@ def _callback(self, bytes, len, markers):
if prevMarker:
self.lastIndex = prevMarker
log.debug("Done pushing audio")
if not self._queuedSpeech:
# There are no more queued utterances at this point, so call idle.
# This blocks while waiting for the final chunk to play,
# so by the time this is done, there might be something queued.
# The call to _processQueue will take care of this.
log.debug("Calling idle on audio player")
self._player.idle()
self._processQueue()

def _getAvailableVoices(self, onlyValid=True):
Expand Down

0 comments on commit ffa71c7

Please sign in to comment.