Web Speech APIs

Speech recognition involves three steps:
1) Create a SpeechGrammarList object and add the grammar rules to it.
2) Create a SpeechRecognition object. Set its grammar list and other properties.
3) Call start() on the SpeechRecognition object to start listening for the voice.

RESETRUNFULL
<!DOCTYPE html><html>
<body style="height:100px">
   <button>Say a color</button>
   <p></p>
   <script>
var grammar = `#JSGF V1.0; grammar colors;
 public <color> = aqua | azure | beige | bisque | black | blue | brown | chocolate | coral | crimson | cyan | fuchsia | 
 ghostwhite | gold | goldenrod | gray | green | indigo | ivory | khaki | lavender | lime | linen | magenta | maroon | moccasin | 
 navy | olive | orange | orchid | peru | pink | plum | purple | red | salmon | sienna | silver | snow | tan | teal | thistle | 
 tomato | turquoise | violet | white | yellow ;`

var recognition = webkitSpeechRecognition ? new webkitSpeechRecognition() : new SpeechRecognition();
var speechRecognitionList = webkitSpeechGrammarList ? new webkitSpeechGrammarList() : new SpeechGrammarList();
speechRecognitionList.addFromString(grammar, 1);
recognition.grammars = speechRecognitionList;
recognition.continuous = false;
recognition.lang = 'en-US';
recognition.interimResults = false;
recognition.maxAlternatives = 1;

document.querySelector("button").onclick = function() {
   recognition.start();
   console.log('Ready to receive a color command.');
}
recognition.onresult = function(event) {
   var color = event.results[0][0].transcript;
   document.querySelector("p").innerHTML = 'Result received: ' + color;
   document.body.style.backgroundColor = color;
}
   </script>
</body></html>
Speech synthesis involves three steps:
1) Create an utterance object by passing the text to SpeechSynthesisUtterance().
2) Set the voice, pitch, and rate of the utterance object. (A list of voices available on the device can be obtained with speechSynthesis.getVoices().)
3) Pass the utterance object to speechSynthesis.speak().

RESETRUNFULL
<!DOCTYPE html><html>
<body style="padding:20px;">
   <input type="text" class="txt" value="This is so cool!"/>
   <button id="play">Speak</button><br/>
   
   <label for="rate">Rate</label>
   <input type="range" min="0.5" max="2" value="1" step="0.1" id="rate">
   <span class="rate-value">1</span><br>
   
   <label for="pitch">Pitch</label>
   <input type="range" min="0" max="2" value="1" step="0.1" id="pitch">
   <span class="pitch-value">1</span><br>
   
   <select></select>
   
   <script>
   var synth = window.speechSynthesis;
   var speakButton = document.querySelector('button');
   var inputTxt = document.querySelector('.txt');
   var voiceSelect = document.querySelector('select');
   var pitch = document.querySelector('#pitch');
   var pitchValue = document.querySelector('.pitch-value');
   var rate = document.querySelector('#rate');
   var rateValue = document.querySelector('.rate-value');
   var voices = [];
   
   function populateVoiceList() {
      voices = speechSynthesis.getVoices().sort(function (a, b) {
      const aname = a.name.toUpperCase(),
            bname = b.name.toUpperCase();
      if ( aname < bname ) return -1;
      else if ( aname == bname ) return 0;
      else return +1;
   });

   var selectedIndex = voiceSelect.selectedIndex;
   if (selectedIndex < 0) selectedIndex = 0;
   voiceSelect.innerHTML = '';
   
   for(i = 0; i<voices.length ; i++) {
      var option = document.createElement('option');
      option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
      if(voices[i].default) {
         option.textContent += ' -- DEFAULT';
      }
      option.setAttribute('data-lang', voices[i].lang);
      option.setAttribute('data-name', voices[i].name);
      voiceSelect.appendChild(option);
   }
   voiceSelect.selectedIndex = selectedIndex;}
   populateVoiceList();
   if (speechSynthesis.onvoiceschanged !== undefined) {
      speechSynthesis.onvoiceschanged = populateVoiceList;
   }

   function speak(){
      if (speechSynthesis.speaking) {
         console.error('speechSynthesis.speaking');
         return;
      }
      if (inputTxt.value == '') return;
      var utterThis = new SpeechSynthesisUtterance(inputTxt.value);
      utterThis.onend = function (event) {
         console.log('SpeechSynthesisUtterance.onend');
      }
      utterThis.onerror = function (event) {
         console.error('SpeechSynthesisUtterance.onerror');
      }
      var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
      for(i = 0; i < voices.length ; i++) {
         if(voices[i].name === selectedOption) {
            utterThis.voice = voices[i];
            break;
         }
      }
      utterThis.pitch = pitch.value;
      utterThis.rate = rate.value;
      speechSynthesis.speak(utterThis);
   }
   speakButton.onclick = function(event) { speak(); }
   pitch.onchange = function() { pitchValue.textContent = pitch.value; }
   rate.onchange = function() { rateValue.textContent = rate.value; }
   voiceSelect.onchange = function(){ speak(); }
   // speechSynthesis.pause()
   // speechSynthesis.resume()
   // speechSynthesis.cancel()
   </script>
</body></html>