Change speechSynthesis voice with SpeechRecognition

4.5k views Asked by At

I am using SpeechRecognition with my microphone and having data relayed back to me with speechSynthesis.

I made the the voice be a female voice on page load and want to be able to switch to a male voice by saying "male voice", which will then relay "I am now a man". I also later want to be able to do the opposite - when it set to a male voice, say "female voice" and it switches back.

I can currently do that but the male voice will only be spoken once as the voice is not being saved, only passed as an argument. Therefore, then next thing spoken will be back in the female voice:

let voices = [];
window.speechSynthesis.onvoiceschanged = function() {
  voices = window.speechSynthesis.getVoices();
};

function loadVoices(message, voice) {
  const msg = new SpeechSynthesisUtterance();
  msg.voice = voice || voices[48]; // female voice
  msg.text = message;
  speechSynthesis.speak(msg);
};

// asking for voice change here
  if (transcript.includes('male voice')) {
    let message = ('I am now a man');
    let voice = voices[50]; // male voice
    loadVoices(message, voice);
  }

I tried having a global variable such that msg.voice points to a global variable, but this does not work, plus the voice reverts back to default (electronic voice):

let voiceGender = voices[48];
function loadVoices(message) {
  const msg = new SpeechSynthesisUtterance();
  msg.voice = voiceGender // now a variable pointing to another.
  msg.text = message;
  speechSynthesis.speak(msg);
};

  if (transcript.includes('male voice')) {
    let message = ('I am now a man');
    let voiceGender = voices[50]; // changing the global variable
    loadVoices(message);
  }

If I declare voiceGender inside of loadVoices(), then I can't change it from the if which is inside another function.

How can I set the Javascript structure so that I can achieve this?

1

There are 1 answers

0
Maxime Dore On BEST ANSWER

I solved it by adding a function and a boolean with conditionals in the loadVoices function such that:

// on pageload the voice is set to a female voice
let femaleVoice = true;

function loadVoices(message) {
  const msg = new SpeechSynthesisUtterance();

  // checks the boolean
  if (femaleVoice) {
    msg.voice = voices[48];
  } else {
    msg.voice = voices[50];
  }

  msg.text = message;
  speechSynthesis.speak(msg);
};

// changes the boolean / changes the gender of the SpeechSynthesisUtterance voice
function changeVoice() {
  if (femaleVoice) {
    femaleVoice = false;
  } else {
    femaleVoice = true;
  }
}

if (transcript.includes('male voice') || transcript.includes('female voice') ) {
  // calls the function to change the boolean.
  changeVoice();

  let message = ('I now have a different voice');
  loadVoices(message);
}

It does add a tiny bit more lines than originally wanted but definitely works.