miranda/Speak/Speak/TTS/TextToSpeak.cs

184 lines
5.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Speech.Synthesis;
using System.Collections.ObjectModel;
using System.Threading;
namespace Speak.TTS
{
/// <summary>
/// Speak Text
/// </summary>
class TextToSpeak
{
private SpeechSynthesizer syn;
private Queue<string> quene;
private static TextToSpeak instance;
private List<string> last;
private Boolean runner;
private Thread workerThread;
/// <summary>
/// Returns the Instance of TextToSpeak Class
/// </summary>
/// <returns>TextToSpeak</returns>
public static TextToSpeak getInstance()
{
if (instance == null)
instance = new TextToSpeak();
return instance;
}
private TextToSpeak()
{
this.syn = new SpeechSynthesizer();
this.quene = new Queue<string>();
this.last = new List<string>();
this.runner = true;
this.workerThread = new Thread(this.Speaker);
workerThread.Start();
while (!workerThread.IsAlive) ;
}
private void Speaker()
{
while (runner)
{
string text = "";
try
{
text = quene.Dequeue();
}
catch (InvalidOperationException) { }
if (text != "")
{
try
{
this.syn.Speak(text);
}
catch (OutOfMemoryException)
{
string voice = this.syn.Voice.Name;
int vol = this.syn.Volume;
int rate = this.syn.Rate;
this.syn = null;
this.syn = new SpeechSynthesizer();
this.setVoice(voice);
this.setVolume(vol);
this.setRate(rate);
quene.Enqueue(text);
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString(), "Fehler in: " + e.Source, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
}
}
else
{
Thread.Sleep(300);
}
}
}
/// <summary>
/// Adds a Text to the to Speak Quene
/// </summary>
/// <param name="text">Text that will be spoken</param>
/// <param name="signature">Signature of Message, to catch to offten spoken text</param>
public void speak(string text, string signature)
{
if (!last.Contains(signature))
{
last.Add(signature);
quene.Enqueue(text);
}
if (last.Count > 10)
{
last.RemoveAt(0);
}
}
/// <summary>
/// Returns a list of Installed Voices
/// </summary>
/// <returns></returns>
public static List<String> getVoices()
{
List<string> ret = new List<string>();
ReadOnlyCollection<InstalledVoice> voices = new SpeechSynthesizer().GetInstalledVoices();
foreach (InstalledVoice item in voices)
{
ret.Add(item.VoiceInfo.Name);
}
return ret;
}
/// <summary>
/// Sets a voice to the current Speak Engine
/// </summary>
/// <param name="voice">Name of the Voice</param>
/// <returns></returns>
public bool setVoice(string voice)
{
if (voice == "")
return false;
try
{
this.syn.SelectVoice(voice);
}
catch (Exception)
{
return false;
}
return this.syn.Voice.Name == voice;
}
/// <summary>
/// Set a new Volume to the Current Speak Engine
/// </summary>
/// <param name="volume"></param>
/// <returns>from 0 to 100</returns>
public bool setVolume(int volume)
{
if (volume > 100 || volume < 0)
return false;
this.syn.Volume = volume;
return this.syn.Volume == volume;
}
/// <summary>
/// Set a new Rate to the Current Speak engine
/// </summary>
/// <param name="rate"></param>
/// <returns>from 0 to 100</returns>
public bool setRate(int rate)
{
if (rate > 100 || rate < 0)
return false;
rate = rate / 5;
rate = rate - 10;
this.syn.Rate = rate;
return this.syn.Rate == rate;
}
/// <summary>
/// Setting a new Pitch to the current Speak Engine
/// NOT IMPLEMENTED
/// </summary>
/// <param name="pitch"></param>
/// <returns></returns>
public bool setPitch(int pitch)
{
return true;
}
public void Stop()
{
this.workerThread.Abort();
this.runner = false;
}
}
}