Search code examples
javascripttext-to-speechspeech-synthesiswebspeech-api

Speaking words in an array


I have an array of words that I would like to say aloud using the Web Speech API.

The words are one, two, three, four, five.

When speaking the words on Chrome, the script below says the first word and then repeats the last word until the iteration is complete, the speech output is:

one, five, five, five, five.

On Firefox, the script says the first word and then stops, the speech output is:

one.

I've logged things to the console in an attempt to figure out what's going on, this is the result from both browsers.

word: one
message: one 
word: two 
message: two 
word: three 
message: three 
word: four 
message: four 
word: five 
message: five

The output to the console is desired speech output so I am unsure what exactly is happening.

var msg = new SpeechSynthesisUtterance();
var words = ['one', 'two', 'three', 'four', 'five'];

for (var i = 0; i < words.length; i++) {
    msg.text = words[i];

    console.log('word: ' + words[i]);
    console.log('message: ' + msg.text);

    window.speechSynthesis.speak(msg);
}

What could be causing this and how can I go about correcting it?


Solution

  • You need to use a new SpeechSynthesisUtterance instance each time.

    var words = ['one', 'two', 'three', 'four', 'five'];
    
    for (var i = 0; i < words.length; i++) {
        var msg = new SpeechSynthesisUtterance();
        msg.text = words[i];
    
        console.log('word: ' + words[i]);
        console.log('message: ' + msg.text);
    
        window.speechSynthesis.speak(msg);
    }
    

    Speech isn't played in zero time, and it appears that subsequent SpeechSynthesisUtterance instances are placed in a queue until previous speech has finished playing. You're reusing the same instance repeatedly, modifying the values after they've been queued by speak(...) but before they've been popped off the queue and read. The first utterance ("one") is played correctly because there's nothing else in the queue to block it (it's read immediately), but the rest need to wait, and end up modified before being read.