Happylab Logo
Published on

Day23: Speech Synthesis

Authors

Introduction: How to use JavaScript and the Web Speech API to implement speech synthesis.

Project page: https://iris1114.github.io/javascript30/23_Speech-Synthesis/

HTML

  • Contains a select element for choosing a voice.
  • Contains two input elements for adjusting the rate and pitch.
  • Contains a textarea element for inputting the text to be synthesized.
  • Contains two buttons for controlling speech playback and stopping.
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Speech Synthesis</title>
  </head>
  <body>
    <div>
      <select name="voice" id="voices">
        <option value="">Select A Voice</option>
      </select>

      <label for="rate">Rate:</label>
      <input name="rate" type="range" min="0" max="3" value="1" step="0.1" />

      <label for="pitch">Pitch:</label>
      <input name="pitch" type="range" min="0" max="2" step="0.1" />

      <textarea name="text">Hello! I love JavaScript 👍</textarea>
      <button id="stop">Stop!</button>
      <button id="speak">Speak</button>
    </div>

    <script src="scripts.js"></script>
  </body>
</html>

JavaScript

  • Uses JavaScript and the Web Speech API to implement speech synthesis and control speech playback and stopping.
const msg = new SpeechSynthesisUtterance()
let voices = []
const voicesDropdown = document.querySelector('[name="voice"]')
const options = document.querySelectorAll('[type="range"], [name="text"]')
const speakButton = document.querySelector('#speak')
const stopButton = document.querySelector('#stop')
msg.text = document.querySelector('[name="text"]').value

// Populate voice options
function populateVoices() {
  voices = this.getVoices()
  voicesDropdown.innerHTML = voices
    .filter((voice) => voice.lang.includes('en'))
    .map(
      (voice) =>
        `<option value="${voice.name}">${voice.name} (${voice.lang})</option>`
    )
    .join('')
}

// Set voice
function setVoice() {
  msg.voice = voices.find((voice) => voice.name === this.value)
  toggle()
}

// Toggle speech
function toggle(startOver = true) {
  speechSynthesis.cancel()
  if (startOver) {
    speechSynthesis.speak(msg)
  }
}

// Set rate and pitch
function setOption() {
  msg[this.name] = this.value
  toggle()
}

speechSynthesis.addEventListener('voiceschanged', populateVoices)
voicesDropdown.addEventListener('change', setVoice)
options.forEach((option) => option.addEventListener('change', setOption))
speakButton.addEventListener('click', toggle)
stopButton.addEventListener('click', () => toggle(false))

Note

  • Uses speechSynthesis.getVoices to get the list of available voices.
  • Uses SpeechSynthesisUtterance to create a speech synthesis object.
  • Uses speechSynthesis.speak to play the speech and speechSynthesis.cancel to stop the speech.