Skip to content

Commit 135224a

Browse files
authored
Merge pull request #221 from jbienzms/SpeechVoice
Added voice selection to TextToSpeechManager.
2 parents 60cb6bb + c6e7290 commit 135224a

File tree

3 files changed

+96
-286
lines changed

3 files changed

+96
-286
lines changed

Assets/HoloToolkit/Utilities/Scripts/TextToSpeechManager.cs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,38 @@
77
using Windows.Foundation;
88
using Windows.Media.SpeechSynthesis;
99
using Windows.Storage.Streams;
10+
using System.Linq;
1011
using System.Threading.Tasks;
1112
#endif
1213

1314
namespace HoloToolkit.Unity
1415
{
16+
/// <summary>
17+
/// The well-know voices that can be used by <see cref="TextToSpeechManager"/>.
18+
/// </summary>
19+
public enum TextToSpeechVoice
20+
{
21+
/// <summary>
22+
/// The default system voice.
23+
/// </summary>
24+
Default,
25+
26+
/// <summary>
27+
/// Microsoft David Mobile
28+
/// </summary>
29+
David,
30+
31+
/// <summary>
32+
/// Microsoft Mark Mobile
33+
/// </summary>
34+
Mark,
35+
36+
/// <summary>
37+
/// Microsoft Zira Mobile
38+
/// </summary>
39+
Zira,
40+
}
41+
1542
/// <summary>
1643
/// Enables text to speech using the Windows 10 <see cref="SpeechSynthesizer"/> class.
1744
/// </summary>
@@ -27,11 +54,17 @@ public class TextToSpeechManager : MonoBehaviour
2754
{
2855
// Inspector Variables
2956
[Tooltip("The audio source where speech will be played.")]
30-
public AudioSource audioSource;
57+
[SerializeField]
58+
private AudioSource audioSource;
59+
60+
[Tooltip("The voice that will be used to generate speech.")]
61+
[SerializeField]
62+
private TextToSpeechVoice voice;
3163

3264
// Member Variables
3365
#if WINDOWS_UWP
3466
private SpeechSynthesizer synthesizer;
67+
private VoiceInformation voiceInfo;
3568
#endif
3669

3770
// Static Helper Methods
@@ -205,6 +238,30 @@ private void PlaySpeech(string text, Func<IAsyncOperation<SpeechSynthesisStream>
205238
// This is good since it frees up Unity to keep running anyway.
206239
Task.Run(async () =>
207240
{
241+
// Change voice?
242+
if (voice != TextToSpeechVoice.Default)
243+
{
244+
// Get name
245+
var voiceName = Enum.GetName(typeof(TextToSpeechVoice), voice);
246+
247+
// See if it's never been found or is changing
248+
if ((voiceInfo == null) || (!voiceInfo.DisplayName.Contains(voiceName)))
249+
{
250+
// Search for voice info
251+
voiceInfo = SpeechSynthesizer.AllVoices.Where(v => v.DisplayName.Contains(voiceName)).FirstOrDefault();
252+
253+
// If found, select
254+
if (voiceInfo != null)
255+
{
256+
synthesizer.Voice = voiceInfo;
257+
}
258+
else
259+
{
260+
Debug.LogErrorFormat("TTS voice {0} could not be found.", voiceName);
261+
}
262+
}
263+
}
264+
208265
// Speak and get stream
209266
var speechStream = await speakFunc();
210267

@@ -324,5 +381,15 @@ public void SpeakText(string text)
324381
LogSpeech(text);
325382
#endif
326383
}
384+
385+
/// <summary>
386+
/// Gets or sets the audio source where speech will be played.
387+
/// </summary>
388+
public AudioSource AudioSource { get { return audioSource; } set { audioSource = value; } }
389+
390+
/// <summary>
391+
/// Gets or sets the voice that will be used to generate speech.
392+
/// </summary>
393+
public TextToSpeechVoice Voice { get { return voice; } set { voice = value; } }
327394
}
328395
}

0 commit comments

Comments
 (0)