Skip to main content
10-Marble
February 25, 2021
Question

Voice Selection on HoloLens 2

  • February 25, 2021
  • 1 reply
  • 2746 views

I'm using the synthesize speech functionality on the HoloLens 2 to read text programatically. 

 

Is there a way to change the voice from the default robotic sounding voice to Cortana or some other voice?

 

Using the code below:

 

function SayText(text) {
$timeout(function(){
$scope.app.speech.synthesizeSpeech( {'text': text });
}, 1500 )
}

1 reply

21-Topaz I
March 2, 2021

Hi @Aouellets ,

you can use on the HoloLens different languages as e.g. described in :

https://developers.google.com/web/updates/2014/01/Web-apps-that-talk-Introduction-to-the-Speech-Synthesis-API

So for example the following code will work in Studio in a HoloLens 2 project:

$scope.app.my_speak = function (msg_txt)
{
 // if preview mode 
 if(twx.app.isPreview() == true){
 //some time on chrome is the voice code not initilized therefor
//also a snackbarmessage
 twx.app.fn.addSnackbarMessage('msg_txt:'+msg_txt, 'voice-response')
 } 

 // in Chrome is this sometimes not correct initilized
//msg.voice = voices[2]; // Note: some voices don't support altering params


 //sometimes this will not initilized need to click again 
// issue is only in preview mode -> on HOLOLENS is working fine
 speechSynthesis.getVoices().forEach(function(voice) {
 console.log(voice.name, voice.default ? voice.default :''); 
 var time_delay=2000*idx++; //time delay 2 secs per item
 var msg = new SpeechSynthesisUtterance();
 msg.onend = function(e) {console.log('Finished in ' + e.elapsedTime + ' seconds.');};
 	msg.voice = voice;
	msg.voiceURI = 'native';
	msg.volume = 1; // 0 to 1
	msg.rate = 1; // 0.1 to 10
	msg.pitch = 0.8; //0 to 2
	msg.text = msg_txt;
	msg.lang = 'en-US';
 $timeout( function(my_msg) {
 //set the label tho the current spoken voice name
 $scope.setWidgetProp('3DLabel-1','text','status: '+ my_msg.voice.name );
 $scope.$applyAsync();
 window.speechSynthesis.speak(my_msg);},time_delay,false,msg); 
 
 });
 //second call 
 var voices = window.speechSynthesis.getVoices()
 var msg1 = new SpeechSynthesisUtterance();
 msg1.voice = voices[2];//Microsoft Zira Desktop - English (United States) 
 msg1.text="another speech test after "+voices.length*2+" seconds"
 
 $timeout(function(my_msg) {
 console.warn(msg1.text);
 $scope.app.speech.synthesizeSpeech(my_msg);
 $scope.setWidgetProp('3DLabel-1','text','status: none');
 $scope.$applyAsync();
 },voices.length*3000,false,msg1); // interval to delay = number of voices * 3 secs 
}
//function for a click button
$scope.app.button1Click=function()
{
console.warn($scope);
$scope.app.my_speak("You clicked the sunflower button");
}

so when I tested it, it printed the message in all possible voices and also displayed   info about the spoken language name

I attached the demo project where I tested it.

Aouellets10-MarbleAuthor
10-Marble
March 8, 2021

Hi Roland, 

 

Thanks for the help. 

 

I'm attempting a simple implementation in studio, but it seems something about how I'm assigning the voice to the variable isn't allowing studio to build the project.

 

See the code below:

 


speechSynthesis.getVoices().forEach(function(voice) {
console.log(voice.name, voice.default ? voice.default :'');
});

var instruction = new SpeechSynthesisUtterance('Hello, my name is Daniel') ;

instruction.voice = 'Daniel';

 

$scope.Test = function() {

$scope.app.speech.synthesizeSpeech({'text': instruction})


}

21-Topaz I
March 10, 2021

Hi @Aouellets ,

looked on your code and I think it could not work . Problem is : voice is an object and could not  be wrapped to a string - I believe it prints such error message into  the chrome console when we try to execute your code. The predefined voices are coming form system and their properties are read only. I think you can only use the voices which are available.  You can   change some attributes like volume, pitch etc.  voice.name and voiceUrl are read only so far I see  in:

https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisVoice/voiceURI

https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisVoice/name

https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisVoice

Another points that on the different platforms we have different predefined voices.

For example  there is difference between chrome preview and on the HoloLens2

I think the correct way is to select one of the available voices on your devices 

You can check in a loop all voices and select one.  For example, one voices which could be used is  English UK George.

This voice is not available e.g. in Chrome so there we can take a voice containing the string ' English Male'

The  following code will work on both - HoloLens 2 and chrome calling depending on the env one of the available voice:

$scope.app.TestC = function() {


 var msg_text="this is my message!"
 var languageNameContains='English Male' // this is vor preview mode /chrome
 if(twx.app.isPreview() != true) languageNameContains='George' // for the HL 2 I want to have George as speaker
 
window.speechSynthesis.getVoices().forEach(function(voice) {
 
 if(voice.name.indexOf(languageNameContains)!=-1) { //only this voice will be used
 
 var utterThis = new SpeechSynthesisUtterance(msg_text); // will also set the message text
 utterThis.voice = voice;
 utterThis.onend = function(e) {console.log('Finished in ' + e.elapsedTime + ' seconds.');};
 utterThis.volume = 1; // 0 to 1
 utterThis.rate = 1; // 0.1 to 10
 utterThis.pitch = 0.8; //0 to 2
 utterThis.text = msg_text + " spoken with voice " + voice.name; //another option to set the msg text
 $scope.app.speech.synthesizeSpeech(utterThis);
 
}else return;
 
return;}) // finish voice funciton
 
} //finsi app.TestC()

 

The  mentioned code will work on both - HoloLens 2 and chrome calling depending on the env one of the available voice.

To call this code use the 2 button "app.TestC".  You can call the Flower button to see all availble voices on The HoloLens 2, so you can later choose one voice which you want to use for the messages

2021-03-10_17-37-15.gif

I attached also the test project.