Community Tip - New to the community? Learn how to post a question and get help from PTC and industry experts! X
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 )
}
Hi @Aouellets ,
you can use on the HoloLens different languages as e.g. described in :
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.
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})
}
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
I attached also the test project.
Hello,
Using this implementation, I was able to get the instructions in my own code to work using 'George' / English Male.
However, when I attempt to use say Alice or English female, the voice goes to default. The same happens with David, Susan, etc.
Am I only able to select from voices in the default language of the device?
Code Below:
var instruction = '';
$scope.$on('newStep', function(evt, arg) {
instruction = arg
step = $scope.app.view.Home.wdg['model-1'].currentStep
console.log( 'Current Step Is : ' + step)
$scope.app.view.Home.wdg["3DImage-2"].src="app/resources/Uploaded/" + File_Name + step + ".png" ;
});
/*
$scope.SayStep = function () {
$scope.app.speech.synthesizeSpeech({'text': instruction});
}
*/
$scope.$on('stepstarted', function () {
/// var msg_text="this is my message!" This is replaced by the 'instruction' var
var languageNameContains='English Female' // this is vor preview mode /chrome
if(twx.app.isPreview() != true) languageNameContains= ' Alice ' // for the HL 2 I want to have Alice as speaker
window.speechSynthesis.getVoices().forEach(function(voice) {
if(voice.name.indexOf(languageNameContains)!=-1) { //only this voice will be used
var utterThis = new SpeechSynthesisUtterance(instruction); // 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 = instruction + " spoken with voice " + voice.name; //another option to set the msg text
$scope.app.speech.synthesizeSpeech(utterThis);
}else return;
return;}) // finish voice funciton
})
So far, I remember the voice list is different for the different devices. Possibly on the different devices(OS platforms) you will get different list of voices. So for example on IOS , HoloLens and chrome we have different voices for specifc devices /target platform -. Therefore If you could not find a list with the voices supported thre - you need to test it on particular devices where you can simple get the list and display the list of voice names , let say first in a list or text widget so you can decide which language you want to use (on HoloLens you can display the list in an Image as dynamic generated SVG some thing as described in https://community.ptc.com/t5/Vuforia-Studio/Display-SVG-as-3D-Image-on-Hololens/m-p/591168 and https://community.ptc.com/t5/Vuforia-Studio/Is-it-possible-to-create-Proportional-Chart-or-Progress-Gauge-in/m-p/626967#M6714)