Eigentlich war ich auf der Suche nach Infos zu den Patterns MVC, MVP und MVVM. Dabei bin ich über den TTS gestolpert und habe mir die Klasse Speechsynthesizer etwas angeschaut.

Die Beschreibung der Klasse SpeechSynthesizer findet sich online in der Microsoft Dokumentation.

Damit kann man schön herumspielen und dabei ist eine kleine Demo-Anwendung als C# Windows Forms Projekt entstanden.

Um den TTS in C# nutzen zu können, muss man im Verweismanager einen Verweis auf System.Speech einfügen.

Verweismanager
Verweis im Projektmappenexplorer

Dann sollte man den zugehörigen Namespace einbinden:

using System.Speech.Synthesis;

Anschließend wird ein privates Feld für die Referenz auf ein SpeechSynthesizer-Objekt erstellt und in der Konstruktormethode Form() instanziiert.

public partial class Form1 : Form
{
    private static SpeechSynthesizer speaker;

// In Konstruktormethode Form()
    public Form()
    {
        InitializeComponent();
        // SpeechSynthesizer-Objekt erstellen
        speaker = new SpeechSynthesizer();
        speaker.SetOutputToDefaultAudioDevice();
        speaker.Rate = 0;
        speaker.Volume = 100;
        // Eventhandler für Event angeben
        speaker.SpeakCompleted += Speaker_SpeakCompleted;
}

Mit der Methode SetOutputToDefaultAudioDevice() wird die Ausgabeeinheit festgelegt. Das könnte aber auch ein WAV-Datei sein. Näheres findet man in der Klassenbeschreibung von Microsoft.

Die beiden Properties Rate und Volume sind sicherlich selbst erklärend. Mit Rate stellt man die Sprechgeschwindigkeit ein. Der Wert ist ein int und gültige Werte liegen zwischen -10 und 10. Mit Volume stellt man die Lautstärke ein. Gültige Werte liegen zwischen 0 und 100.

Beide Properties können gelesen und geschrieben werden. Änderungen wirken sich jedoch erst bei einem neuen Sprechvorgang aus. Ich habe auch keine Möglichkeit gefunden, Änderungen während eines Sprechvorganges wirksam werden zu lassen.

Das SpeechSynthesizer-Objekt verfügt über Events. So kann das Objekt z.B. nach Beendigung eines Sprechvorgangs das Event SpeakCompleted feuern. Hierzu füge ich einen Eventhandler hinzu, damit ich nach Beendigung des Sprechvorgangs Aktionen durchführen lassen kann.

Mein Eventhandler schaltet lediglich eine boolsche Variable um und ändert den Text auf einem Button-Objekt.

private void Speaker_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
{
    // Eventhandler für das Event SpeakCompleted vom SpeechSynthesizer-Objekt
    vorlesen = false;
    buttonVorlesen.Text = "Vorlesen";
}

Das Vorlesen starten man z.B. mit der Methode SpeakAsync(). Dadurch wird das Vorlesen in einem Thread ausgeführt und die GUI bleibt bedienbar. Alternativ kann man auch die Methode Speak() verwenden. Diese blockiert aber laut Klassenbeschreibung.

Die Methode erhält einen String, der vorzulesen ist. Bei mir steht der String in einer Textbox namens textBoxSpeechText.

// Asynchrones Vorlesen
speaker.SpeakAsync(textBoxSpeechText.Text);

Soll eine Sprachausgabe vorzeitig beendet werden, gibt es nur für die SpeakAsync()-Methode die Methode SpeakAsyncCancel() oder die Methode SpeakAsyncCancelAll(). Erstere benötigt als Parameter ein sogenanntes Prompt-Objekt für den betreffenden Sprechvorgang, während letztere ohne Parameter alle Sprechvorgänge sofort beendet.

// Sofortiges Beenden aller Sprechvorgänge
speaker.SpeakAsyncCancelAll();

Sehr interessant ist noch die Methode GetInstalledVoices(). Diese liefert in einer ReadOnlyCollection alle installierten Sprachen. Die ReadOnlyCollection wird einem privaten Feld mit diesem Typ zugewiesen. Diese Collection lässt sich dann durchlaufen. Mit dem Property VoiceInfo erhält man ein gleichnamiges Objekt, welches Informationen zur Sprache liefert; z.B. Name, Gender, Culture, Age…

Näheres liefert die Klassenbeschreibung von VoiceInfo.

// benötigter Namespace für die Klasse ReadOnlyCollection
using System.Collections.ObjectModel;

// Feld in der Klasse Form
private ReadOnlyCollection voiceinfos;

// Alle installierten Sprachen ermitteln
voiceinfos = speaker.GetInstalledVoices();

// Sprachen iterieren und Eigenschaften der Sprache,
// die in einem VoiceInfo-Objekt stehen, ermitteln
// und den Namen in einer ComboBox ablegen
foreach (InstalledVoice iv in voiceinfos)
{
    VoiceInfo vi = iv.VoiceInfo;
    comboBoxVocals.Items.Add(vi.Name);
}

Heraus gekommen ist nun folgende kleine Demo-Anwendung. Ich habe bei mir noch einige Sprachen, die TTS unterstützen, nachinstalliert und für jede Sprache einen Demo-Text festgelegt, der bei Sprachwechsel aktiviert wird. Man kann auch eine Textdatei (möglichst UTF-8) laden und vorsprechen lassen.

Neue Sprachen installiert man bei Windows 10 mittels PC-Einstellungen (das Zahnrad-Symbol) und dort auf der Seite „Sprache“ klickt man auf „Sprache hinzufügen“. Wichtig ist dabei, dass bei der Sprache das Symbol für TTS angezeigt wird: Dies ist ein Monitor mit einer Sprechblase.

Hier sieht man das Programm in Aktion 🙂

Demo-Anwendung für Text-to-Speech mit der Microsoft SpeechSynthesizer-Klasse

TTS Demo: Projektmappe Visual Studio 2015 (als tar gepackt mit 7-Zip)