meSpeak.js Update, v. 2.0.7

Text to Speech in JS, and a curious bug. Also, Safari desktop compatibility.

meSpeak Update 2.0.7

A curious bug, believed mitigated long ago, crept up again in meSpeak.js (an open source TTS for the Web in JavaScript maintained by me). On each 80th call, the internal eSpeak engine would crash on a round-off by one error. However, that error message never seemed right, as the abort message indicated a size of more than 1.8 GB for a relatively small and static internal file. Also, this didn’t happen on all browsers. A workaround was eventually found, where we would intercept this error, restart the engine, reload all relevant internal files and start over automatically.

However, this stopped working and the bug rose its head of rare, but questionable beauty once again. It doesn’t happen on all browsers, but, for me, it happens at least in current versions of Firefox. Even more, it seems to be a real Heisenbug, since the script exits on an “out of memory” exception on varying points depending on the specific version of the code. In the minimized production version, the code makes it to several debug messages before the final exit, in the unminimized test version, however, it exits on a different point, which renders intercepting that specific error a somewhat impractical endeavor. Also, the exception dosen’t depend on the length of the utterances spoken (thus suggesting that the “out of memory” exception isn’t caused by memory allocation of the actual code, but the result of cascading failures internal to the JS engine), it just happens on each 80th call of the method “speak()”, which triggers a run of the internal eSpeak engine. Which, on the other hand, provides a suitable point of access to an otherwise somewhat cryptic and inaccessible failure mode, namely, simply keeping track of the number of calls and automatically restarting the engine on every 80th call. (Mind that this may cause a small delay, but it’s still better than the script stalling on an uncatchable exception.)

Shout-out to Trent Murgatroyd for reporting the fault and testing!

This had actually been addressed in version 2.0.6, as of a few days ago (2020-04-17), already. But there was another issue, which had passed my radar, namely, the Safari desktop browser muting Web Audio on default. This is now addressed similar to how mobile devices are handled, by attempting to unlock audio on the first mousedown event occuring in the window. (Unlocking requires a direct user interaction. Hence, meSpeak.js must listen for a global user event. However, it neither blocks or consumes the event in any way, nor does it extract any data.) Additionally to this, meSpeak.js now also attempts to resume the audio-context on every call of the method “speak()” prior to playing any audio, in case it’s found in suspended state. (Again, this will be of any effect only, if the call was issued from code triggered by a user event. On the other hand, it doesn’t hurt trying.)

If you’re using meSpeak.js, please update: