Basic Text to Speech (TTS)
Tags: beginners, javascript, tutorial, basecs
Published: 2020-02-10 03:14:41

This a super impromptu post, but as it turns out the `window` has a lot of secrets! 😱 Just kidding. They're just really cool features, and one of them is text to speech, which I tried today! 

How did that happen? Well, I started working on one of pretty common interview questions that one of my friends showed to me. The problem goes like this: you put in a number into an input field and it gets translated into... words? English? So if you were to input 123 you'd get "one hundred and twenty three". 

While I should have probably finished the solution to this problem, I got distracted and instead tried the text to speech feature. I am not going to talk much about the numbers problem, but there are a few nuances I want to mention. 

For now, my problem only converts integers between 1 and 20 into words (I know, I know... I will finish it). If there is no number, it returns blank. If anything else is entered but numbers 1-20, you get a message saying "undefined" and the browser tells you (with voice) to ented an integer between 1 and 20. 

Now that we got that lazy embarrassing stuff out of the way 🧐, how do we make the browser speak? 

First, we need to define a few things: 
   • `const synth = window.speechSynthesis` - the actual synthesizer 
   • `const voiceList = document.getElementById('voice-list')` - the selector list for all of the voices your system comes with
   • `const btnSpeak = document.getElementById('button-speak')` - the button that we click when need a word spoken
   • `let voices = []` - the array that we will populate with all of the voices your system comes with 


Next, we will populate the selector list with all the voices: 

{% gist https://gist.github.com/yulineko/17152f8b33f6e867a7509dc39f3b86e4.js %}

After that simply call the function: `populateVoices()` and then do this: `if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = populateVoices; }`. Firefox doesn't support `SpeechSynthesis.onvoiceschanged` and will return a list of voices when `SpeechSynthesis.getVoices()` runs. With Chrome we have to wait for the event to fire before populating the list. 

Now all we need is to create an event listener for the button, so once we click on it, we hear speech: 

{% gist https://gist.github.com/yulineko/12ef1e6b2e0a7805b723d2fcff91d4d1.js %}

Because we are not trying to make it speak whatever is in the input field, but the number converted into words, we have to define a variable that holds the `.innerHTML` of the converted word `let numberWord = document.getElementById('words').innerHTML` and pass it into `SpeechSynthesisUtterance(numberWord)`. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t8kweqc0sh2pnr2465e7.jpg)

Now, if the input is not an integer and is `undefined`, if will speak angrily and ask to enter an integer between 1 and 20 😈. It will only speak English in my case (or your native language you're translating digits to words), since it is not reading the numbers in the input field, but the converted words.  



The complete API documentation on speech recognition and synthesis is [here](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API), and while you're checking that out, I am off to finish the number to words conversion problem 😴...