in static/js/chat.js [389:433]
function speakNext(text, endingSilenceMs = 0) {
const ttsVoice = "en-US-AvaMultilingualNeural";
const personalVoiceSpeakerProfileID = "";
let ssml = `<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts' xml:lang='en-US'>
<voice name='${ttsVoice}'>
<mstts:ttsembedding${personalVoiceSpeakerProfileID ? " speakerProfileId='" + personalVoiceSpeakerProfileID + "'" : ""}>
<mstts:leadingsilence-exact value='0'/>${text}
</mstts:ttsembedding>
</voice>
</speak>`;
if (endingSilenceMs > 0) {
ssml = `<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts' xml:lang='en-US'>
<voice name='${ttsVoice}'>
<mstts:ttsembedding${personalVoiceSpeakerProfileID ? " speakerProfileId='" + personalVoiceSpeakerProfileID + "'" : ""}>
<mstts:leadingsilence-exact value='0'/>${text}<break time='${endingSilenceMs}ms' />
</mstts:ttsembedding>
</voice>
</speak>`;
}
lastSpeakTime = new Date();
isSpeaking = true;
// Ensure the token is valid before speaking
ensureValidToken().then(() => {
avatarSynthesizer.speakSsmlAsync(ssml).then((result) => {
if (result.reason === SpeechSDK.ResultReason.SynthesizingAudioCompleted) {
console.log(`Spoken: [${text}]. Result ID: ${result.resultId}`);
} else {
console.error(`Error speaking text. Result ID: ${result.resultId}`);
}
if (spokenTextQueue.length > 0) {
speakNext(spokenTextQueue.shift());
} else {
isSpeaking = false;
}
}).catch((error) => {
console.error(`Error speaking SSML: [${error}]`);
if (spokenTextQueue.length > 0) {
speakNext(spokenTextQueue.shift());
} else {
isSpeaking = false;
}
});
});
}