From 64adb944acd06d0e0b143f0bc4258e4c27c28ae6 Mon Sep 17 00:00:00 2001 From: Jesse Date: Sat, 12 Mar 2022 17:56:23 -0500 Subject: [PATCH] Revert "handle synth failure to speak (needed for Safari and probably ChromeOS), see https://github.com/phetsims/utterance-queue/issues/66" This reverts commit 5f4bc013f57d14686796f2ff15d29a322cdd55ef. --- js/SpeechSynthesisAnnouncer.js | 54 ++-------------------------------- 1 file changed, 3 insertions(+), 51 deletions(-) diff --git a/js/SpeechSynthesisAnnouncer.js b/js/SpeechSynthesisAnnouncer.js index 0191783..ca2fdfe 100644 --- a/js/SpeechSynthesisAnnouncer.js +++ b/js/SpeechSynthesisAnnouncer.js @@ -34,12 +34,6 @@ if ( window.phet && phet.chipper && phet.chipper.queryParameters && phet.chipper // the feature as an optimization. But this workaround gets around it and keeps speech fast. const ENGINE_WAKE_INTERVAL = 10000; -// In ms, how long to wait before we consider the SpeechSynthesis engine as having failed to speak a requested -// utterance. ChromeOS and Safari in particular may simply fail to speak. If the amount of time between our speak() -// request and the time we receive the `start` event is too long then we know there was a failure and we can try -// to handle accordingly. -const PENDING_UTTERANCE_DELAY = 5000; - // In ms. In Safari, the `start` and `end` listener do not fire consistently, especially after interruption // with cancel. But speaking behind a timeout/delay improves the behavior significantly. Timeout of 250 ms was // determined with testing to be a good value to use. Values less than 250 broke the workaround, while larger @@ -100,11 +94,6 @@ class SpeechSynthesisAnnouncer extends Announcer { // fast on Chromebooks, see documentation around ENGINE_WAKE_INTERVAL. this.timeSinceWakingEngine = 0; - // @private {number} - In ms, how long it has been since we requested speech of a new utterance and when - // the synth has successfully started speaking it. It is possible that the synth will fail to speak so if - // this timer gets too high we handle the failure case. - this.timeSincePendingUtterance = 0; - // @private {number} - Amount of time in ms to wait between speaking SpeechSynthesisUtterances, see // VOICING_UTTERANCE_INTERVAL for details about why this is necessary. Initialized to the interval value // so that we can speak instantly the first time. @@ -172,11 +161,6 @@ class SpeechSynthesisAnnouncer extends Announcer { // being spoken by the browser, so we can determine cancelling behavior when it is time to speak the next utterance. // See voicing's supported announcerOptions for details. this.currentlySpeakingUtterance = null; - - // @private {Utterance|null} - A reference to the Utterance that is about to be spoken. Cleared the moment - // speech starts (the start event of the SpeechSynthesisUtterance). Depending on the platform there may be - // a delay between the speak() call and when the synth actually starts speaking. - this.pendingUtterance = null; } /** @@ -251,24 +235,11 @@ class SpeechSynthesisAnnouncer extends Announcer { // start counting up until the synth has finished speaking its current utterance. this.timeSinceUtteranceEnd = this.getSynth().speaking ? 0 : this.timeSinceUtteranceEnd + dt; - this.timeSincePendingUtterance = this.pendingUtterance ? this.timeSincePendingUtterance + dt : 0; - - if ( this.timeSincePendingUtterance > PENDING_UTTERANCE_DELAY ) { - - // It has been too long since we requested speech without speaking, the synth is likely failing on this platform - this.handleAnnouncementFailure( this.pendingUtterance ); - this.pendingUtterance = null; - - // cancel the synth because we really don't want it to keep trying to speak this utterance after handling - // the assumed failure - this.cancelSynth(); - } - // Wait until VOICING_UTTERANCE_INTERVAL to speak again for more consistent behavior on certain platforms, // see documentation for the constant for more information. By setting readyToAnnounce in the step function // we also don't have to rely at all on the SpeechSynthesisUtterance 'end' event, which is inconsistent on - // certain platforms. Also, not ready to announce if we are waiting for the synth to start speaking something. - if ( this.timeSinceUtteranceEnd > VOICING_UTTERANCE_INTERVAL && !this.pendingUtterance ) { + // certain platforms. + if ( this.timeSinceUtteranceEnd > VOICING_UTTERANCE_INTERVAL ) { this.readyToAnnounce = true; } @@ -346,21 +317,10 @@ class SpeechSynthesisAnnouncer extends Announcer { else { // The announcer is not going to announce this utterance, signify that we are done with it. - this.handleAnnouncementFailure( utterance ); + this.announcementCompleteEmitter.emit( utterance, utterance.getAlertText( this.respectResponseCollectorProperties ) ); } } - /** - * The announcement of this utterance has failed in some way, signify to clients of this announcer that the utterance - * will never complete. For example start/end events on the SpeechSynthesisUtterance will never fire. - * @private - * - * @param {Utterance} utterance - */ - handleAnnouncementFailure( utterance ) { - this.announcementCompleteEmitter.emit( utterance, utterance.getAlertText( this.respectResponseCollectorProperties ) ); - } - /** * Use speech synthesis to speak an utterance. No-op unless voicingManager is initialized and other output * controlling Properties are true (see speechAllowedProperty in initialize()). This explicitly ignores @@ -397,11 +357,6 @@ class SpeechSynthesisAnnouncer extends Announcer { const startListener = () => { this.startSpeakingEmitter.emit( stringToSpeak, utterance ); - - // Important that the pendingUtterance is cleared in the start event instead of when `synth.speaking` is set - // to true because `synth.speaking` is incorrectly set to true before there is successful speech in ChromeOS. - // See https://github.com/phetsims/utterance-queue/issues/66 and https://github.com/phetsims/utterance-queue/issues/64 - this.pendingUtterance = null; this.currentlySpeakingUtterance = utterance; assert && assert( this.speakingSpeechSynthesisUtteranceWrapper === null, 'Wrapper should be null, we should have received an end event to clear it.' ); @@ -439,9 +394,6 @@ class SpeechSynthesisAnnouncer extends Announcer { // See https://github.com/phetsims/utterance-queue/issues/40 this.timeSinceUtteranceEnd = 0; - // Utterance is pending until we get a successful 'start' event on the SpeechSynthesisUtterance - this.pendingUtterance = utterance; - this.getSynth().speak( speechSynthUtterance ); if ( !this.hasSpoken ) {