ブログ@kaorun55

HoloLensやKinectなどのDepthセンサーを中心に書いています。

Speech Platform 11 で音声合成をする

Kinectは使わないですが...
Speech Platform 11 は音声認識の機能とともに、音声合成(コンピューターに文字を入力すると、音声として出力される)の機能も提供されています。
せっかくなので音声合成もやってみましょう。
環境設定などは、こちらを参照してください。


プロジェクト全体はこちらにあります

プロジェクトの作成

WPFのプロジェクトを作ります。
画面を適当に作ります。喋らせる文字を入力するテキストボックスと、トリガとなるボタンがあればOKです。


参照設定で「Microsoft.Speech.dll」を追加します。前回の動作確認を行っていれば、「参照の追加」から「最近使用したファイル」のタブにあると思います。

コードを書く

こんな感じで書くと動きます。

using System;
using System.IO;
using System.Media;
using System.Windows;
using Microsoft.Speech.Synthesis;

namespace SpeechSynthesizerSample
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        SpeechSynthesizer ss = new SpeechSynthesizer();
        SoundPlayer player = new SoundPlayer();

        public MainWindow()
        {
            InitializeComponent();

            ss.SpeakCompleted +=new EventHandler<SpeakCompletedEventArgs>( ss_SpeakCompleted );
        }

        private void button1_Click( object sender, RoutedEventArgs e )
        {
            try {
                player.Stream = new MemoryStream();
                ss.SetOutputToWaveStream( player.Stream );
                ss.SpeakAsync( textBox1.Text );
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message );
            }
        }

        void ss_SpeakCompleted( object sender, SpeakCompletedEventArgs e )
        {
            try {
                player.Stream.Position = 0;
                player.Play();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message );
            }
        }
    }
}

解説

Speech SDKには「Microsoft.Speech」のほかに「System.Speech」もあるそうです。
今回使っている「Microsoft.Speech」は音声出力にひと手間かけないといけないようなので、少し長めになっています。
やっていることは、次のようになります

  1. ボタンをトリガにして、音声をストリームに出力
  2. 出力が終わったら、そのストリームを使って、プレーヤーからスピーカに出力
フィールド

音声合成のためのSpeechSynthesizerと、スピーカー出力のためのSoundPlayerを宣言します。

SpeechSynthesizer ss = new SpeechSynthesizer();
SoundPlayer player = new SoundPlayer();
コンストラクタ

合成音声を非同期に出力させ、それをスピーカーから出すので、非同期出力の完了イベントを設定します。

public MainWindow()
{
    ....

    ss.SpeakCompleted +=new EventHandler<SpeakCompletedEventArgs>( ss_SpeakCompleted );
}
ボタンクリック

メモリストリームを作成し、合成音声データをそこに出力させます。

private void button1_Click( object sender, RoutedEventArgs e )
{
    try {
        player.Stream = new MemoryStream();
        ss.SetOutputToWaveStream( player.Stream );
        ss.SpeakAsync( textBox1.Text );
    }
    catch ( Exception ex ) {
        MessageBox.Show( ex.Message );
    }
}
スピーカーへの出力

プレーヤー内のストリームに、音声データがあるので、再生位置を0にして再生を開始します。

void ss_SpeakCompleted( object sender, SpeakCompletedEventArgs e )
{
    try {
        player.Stream.Position = 0;
        player.Play();
    }
    catch ( Exception ex ) {
        MessageBox.Show( ex.Message );
    }
}

まとめ

簡単に音声合成ができ、漢字も認識してしゃべってくれるのがすごいですね。
前回の音声認識に、この音声合成を入れてみたところ、
自分が話した内容が音声合成されてスピーカーから出力→それをKinectがマイクから入力して、再度音声合成
のループになっていましたw
Speech Platform で合成された音声は、Speech Platformで音声認識できるようですねw