らくの遊び場

プログラムでやったことを自由に描いていきます。C++/C#/Python/OpenCV/Tensorflow/Unity

【C#】System.Speechを使用し、テキストを読み上げ、音声を保存する

概要

System.Speech.Synthesisを使用して、テキストを読み上げ保存する

環境

実装

using System.Speech.Synthesis;    
using System.Windows.Forms;
using System.Globalization;
using System.Collections.ObjectModel;

public void CreateVoice(string filename, int volume, int speed, string text)
{
    SpeechSynthesizer sz = new SpeechSynthesizer();
    // 設定
    sz.Volume = volume;
    sz.Rate = speed;

    // 使用できる音声合成エンジンを探す
    CultureInfo cultureInfo = Application.CurrentCulture;
    // voicesに使用でききる音声合成エンジンが格納される
    ReadOnlyCollection<InstalledVoice> voices = sz.GetInstalledVoices(cultureInfo);                      
    sz.SelectVoice(voices[0].VoiceInfo.Name);

    sz.SetOutputToWaveFile(filename);
    sz.Speak(text);
}        

解説

SpeechSynthesizer s = new SpeechSynthesizer();
// 設定
s.Volume = volume;
s.Rate = speed;        

で、SpeechSynthesizerの定義と設定を行っています。
次に、どの合成音声エンジンを使用するかですが、まずPCに何がインストールされているかを調べます。

// 使用できる音声合成エンジンを探す
CultureInfo cultureInfo = Application.CurrentCulture;
// voicesに使用でききる音声合成エンジンが格納される
ReadOnlyCollection<InstalledVoice> voices = sz.GetInstalledVoices(cultureInfo);                      

voicesへ情報が格納されるので、中身を見てみると何が使用できるかがわかります。

s.SelectVoice(voices[0].VoiceInfo.Name);

でどのエンジンを使用するか、名前で指定することができます。

また、特に気にせずに初期のまま使用したい場合は

s.SelectVoiceByHints(VoiceGender.Female, VoiceAge.Adult); 

等で性別や年齢を設定できます。

s.SetOutputToWaveFile(filename);
s.Speak(text);

で指定したfilenameで保存することができます。

s.SetOutputToWaveFile(filename);

コメントアウトすると、

s.Speak(text);

単体で、音声を鳴らすことができます。

s.SpeakAsync(text);

とすることで、非同期で再生することも可能です。

問題

アプリが落ちるまで完全に出力されていないのか、サイズが0のままで開くことができません。

追記 2018/12/20

上記問題を以下のように修正することで解決できました。

s.Speak(text);

これを

PromptBuilder builder = new PromptBuilder();
builder.AppendText(text);
sz.Speak(builder);
sz.Dispose();
sz = null;

こう。
PromptBuilderを使用せずにDiposeするとファイルが上手く作成できませんでした。