Google TTS API UPDATE is no longer available to the public. The notes below about Microsoft TTS are still relevant and provide equivalent functionality.
You can use the Google TTS API from your WinForm application by playing the answer using the answer option of this question (it took me a while, but I have a real solution):
public partial class Form1 : Form { public Form1() { InitializeComponent(); this.FormClosing += (sender, e) => { if (waiting) stop.Set(); }; } private void ButtonClick(object sender, EventArgs e) { var clicked = sender as Button; var relatedLabel = this.Controls.Find(clicked.Tag.ToString(), true).FirstOrDefault() as Label; if (relatedLabel == null) return; var playThread = new Thread(() => PlayMp3FromUrl("http://translate.google.com/translate_tts?q=" + HttpUtility.UrlEncode(relatedLabel.Text))); playThread.IsBackground = true; playThread.Start(); } bool waiting = false; AutoResetEvent stop = new AutoResetEvent(false); public void PlayMp3FromUrl(string url) { using (Stream ms = new MemoryStream()) { using (Stream stream = WebRequest.Create(url) .GetResponse().GetResponseStream()) { byte[] buffer = new byte[32768]; int read; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, read); } } ms.Position = 0; using (WaveStream blockAlignedStream = new BlockAlignReductionStream( WaveFormatConversionStream.CreatePcmStream( new Mp3FileReader(ms)))) { using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback())) { waveOut.Init(blockAlignedStream); waveOut.PlaybackStopped += (sender, e) => { waveOut.Stop(); }; waveOut.Play(); waiting = true; stop.WaitOne(10000); waiting = false; } } } } }
NOTE. . The above code requires that NAudio work (free / open source) and using for System.Web , System.Threading and NAudio.Wave .
There are two controls in my Form1 :
- Label named
label1 - A button named
button1 with Tag from label1 (used to bind a button to its label)
The above code can be easily simplified if you have different events for each combination of buttons / labels using something like (untested):
private void ButtonClick(object sender, EventArgs e) { var clicked = sender as Button; var playThread = new Thread(() => PlayMp3FromUrl("http://translate.google.com/translate_tts?q=" + HttpUtility.UrlEncode(label1.Text))); playThread.IsBackground = true; playThread.Start(); }
There are problems with this solution though (this list is probably not complete, I am sure that comments and usage in the real world will find others):
- Pay attention to
stop.WaitOne(10000); in the first piece of code. 10000 represents a maximum of 10 seconds of sound to play, so you will need to adjust it if your tag takes longer than reading. This is necessary because the current version of NAudio (v1.5.4.0) seems to have a problem determining when the thread is executing. This may be fixed in a later version or there may be a workaround that I did not take the time to find. One temporary workaround is to use ParameterizedThreadStart , which will use a timeout as a parameter to the thread. This will allow the use of variable timeouts, but will not technically fix the problem. - More importantly, the Google TTS API is unofficial (which means that it cannot be used by applications other than Google), and it is subject to change without notice at any time. If you need something that will work in a commercial environment, I would suggest either a MS TTS solution (in your opinion) or one of many commercial alternatives. None of them are usually even this simple, though.
To answer the other side of your question:
The System.Speech.Synthesis.SpeechSynthesizer class is much easier to use, and you can rely on its reliability (where it may disappear with the Google API tomorrow).
It is as simple as including a link to a System.Speech link and:
public void SaySomething(string somethingToSay) { var synth = new System.Speech.Synthesis.SpeechSynthesizer(); synth.SpeakAsync(somethingToSay); }
It just works.
Trying to use the Google TTS API was a fun experiment, but it would be difficult for me to offer it for use in production, and if you don't want to pay for a commercial alternative, Microsoft's solution is about as good as it gets.