Recipe 9.5

Customizing Speech Synthesis

Demo

Code

JavaScript
const voiceSelect = document.querySelector('#voices');

let voices = [];

function speakText(text) {
  const utterance = new SpeechSynthesisUtterance(text);
  utterance.voice = voices[voiceSelect.value];

  const pitch = document.querySelector('#pitch');
  utterance.pitch = pitch.valueAsNumber;

  const rate = document.querySelector('#rate');
  utterance.rate = rate.valueAsNumber;

  speechSynthesis.speak(utterance);
}

function populateVoiceOptions() {
  if (!voices.length) {
    voices = speechSynthesis.getVoices();
    voices.forEach((voice, index) => {
      const option = new Option(voice.name, index);
      if (voice.name === 'Samantha') {
        option.selected = true;
      }
      voiceSelect.appendChild(option);
    });
  }
}

speechSynthesis.addEventListener('voiceschanged', () => populateVoiceOptions());
populateVoiceOptions();

document.querySelector('#speak-button').addEventListener('click', () => {
  speakText(document.querySelector('#speak-text').value);
});
HTML
<div class="mb-4">
  <label for="voices" class="form-label">Voice</label>
  <select class="form-select" id="voices"></select>
</div>

<div class="d-flex">
  <div class="mb-4 me-4">
    <label for="pitch" class="form-label">Pitch</label>
    <input type="range" class="form-range" id="pitch" min="0" max="2" step="0.1">
  </div>
  <div class="mb-4">
    <label for="rate" class="form-label">Rate</label>
    <input type="range" class="form-range" id="rate" min="0.5" max="2" value="1" step="0.1">
  </div>
</div>

<div class="mb-4">
  <label for="speak-text" class="form-label">Text to speak</label>
  <textarea id="speak-text" class="form-control">It was a dark and stormy night.</textarea>
</div>

<button id="speak-button" class="btn btn-primary">Speak!</button>
Web API Cookbook
Joe Attardi