テキスト読み上げの概要

このクイックスタートでは、Speech SDK を使用してテキスト読み上げ合成を行うための一般的な設計パターンについて説明します。 まずは基本的な構成と合成を行った後、次のようなより高度なカスタム アプリケーション開発の例に進みます。

  • インメモリ ストリームとして応答を取得する
  • 出力のサンプル レートとビット レートをカスタマイズする
  • SSML (音声合成マークアップ言語) を使用して合成要求を送信する
  • ニューラル音声を使用する

記事をスキップして GitHub 上のサンプルにアクセスする

この記事をスキップしてサンプル コードをご覧になりたい方は、GitHub 上の C# クイックスタート サンプルを参照してください。

前提条件

この記事は、Azure アカウントと Speech Service サブスクリプションをお持ちであることを前提としています。 アカウントとサブスクリプションをお持ちでない場合は、Speech Service を無料でお試しください

Speech SDK のインストール

何らかの操作を行うには、事前に Speech SDK をインストールしておく必要があります。 ご利用のプラットフォームに応じて、次の手順を行います。

依存関係のインポート

この記事の例を実行するには、スクリプトの先頭に次の using ステートメントを含めます。

using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;

音声構成を作成する

Speech SDK を使用して Speech Service を呼び出すには、SpeechConfig を作成する必要があります。 このクラスには、音声キーとそれに関連付けられた場所/リージョン、エンドポイント、ホスト、認証トークンなど、サブスクリプションに関する情報が含まれています。

注意

音声認識、音声合成、翻訳、またはインテント認識のどれを実行するのかに関係なく、必ず構成を作成します。

SpeechConfig を初期化するには、次に示すようないくつかの方法があります。

  • サブスクリプションの場合: キーと、それに関連付けられた場所またはリージョンを渡します。
  • エンドポイントの場合: Speech Service エンドポイントを渡します。 キーまたは認証トークンは省略可能です。
  • ホストの場合: ホスト アドレスを渡します。 キーまたは認証トークンは省略可能です。
  • 認証トークンの場合: 認証トークンと、それに関連付けられた場所またはリージョンを渡します。

この例では、音声キーと場所/リージョンを使用して SpeechConfig を作成します。 「Speech Service を無料で試す」の手順に従って、これらの資格情報を取得します。 また、この記事の残りの部分で使用する、基本的な定型コードをいくつか作成します。これを変更して、さまざまなカスタマイズを行います。

public class Program
{
    static async Task Main()
    {
        await SynthesizeAudioAsync();
    }

    static async Task SynthesizeAudioAsync()
    {
        var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    }
}

合成言語と音声を選択する

Azure Text to Speech サービスでは、250 を超える音声と 70 を超える言語とバリアントがサポートされています。 すべてのリストを入手することも、テキスト読み上げのデモでそれらを試すこともできます。 入力テキストに合わせて SpeechConfig の言語または音声を指定し、必要な音声を使用します。

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    // Note: if only language is set, the default voice of that language is chosen.
    config.SpeechSynthesisLanguage = "<your-synthesis-language>"; // e.g. "de-DE"
    // The voice setting will overwrite language setting.
    // The voice setting will not overwrite the voice element in input SSML.
    config.SpeechSynthesisVoiceName = "<your-wanted-voice>";
}

音声をファイルに合成する

次に、SpeechSynthesizer オブジェクトを作成します。これにより、テキストから音声への変換と、スピーカー、ファイル、またはその他の出力ストリームへの出力が実行されます。 SpeechSynthesizer は、前の手順で作成した SpeechConfig オブジェクトと、出力結果の処理方法を指定する AudioConfig オブジェクトをパラメーターとして受け取ります。

まず、FromWavFileOutput() 関数を使用して .wav ファイルに出力を自動的に書き込む AudioConfig を作成し、次にそれを using ステートメントでインスタンス化します。 このコンテキストの using ステートメントによって、アンマネージド リソースが自動的に破棄され、破棄後にオブジェクトがスコープ外になります。

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav");
}

次に、別の using ステートメントを使用して SpeechSynthesizer をインスタンス化します。 config オブジェクトと audioConfig オブジェクトをパラメーターとして渡します。 こうすることで、音声合成を実行してファイルに書き込むことが、テキスト文字列を使用して SpeakTextAsync() を実行するのと同じぐらい簡単になります。

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav");
    using var synthesizer = new SpeechSynthesizer(config, audioConfig);
    await synthesizer.SpeakTextAsync("A simple test to write to a file.");
}

このプログラムを実行すると、合成された .wav ファイルが、指定した場所に書き込まれます。 以上は最も基本的な使用方法の好例ですが、この次は、カスタム シナリオに対応できるよう、出力をカスタマイズし、出力応答をインメモリ ストリームとして処理する方法について説明します。

スピーカー出力に合成する

場合によっては、合成された音声をスピーカーに直接出力することが必要になる場合があります。 これは、上記の例で SpeechSynthesizer を作成するときに、AudioConfig パラメーターを省略することで実行できます。 これにより、現在のアクティブな出力デバイスに対して合成が行われます。

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var synthesizer = new SpeechSynthesizer(config);
    await synthesizer.SpeakTextAsync("Synthesizing directly to speaker output.");
}

結果をインメモリ ストリームとして取得する

音声アプリケーション開発の多くのシナリオでは、結果として得られたオーディオ データは、ファイルに直接書き込むのではなく、インメモリ ストリームとして必要となるケースがよくあります。 その場合、次のようなカスタム動作を構築できます。

  • 結果として得られたバイト配列を、カスタム ダウンストリーム サービス向けのシーク可能なストリームとして抽象化する。
  • 結果を他の API またはサービスと統合する。
  • オーディオ データの変更やカスタム .wav ヘッダーの記述などを行う。

この変更は、前の例から簡単に行うことができます。 まず、AudioConfig ブロックを削除します。これは、この時点から出力動作を手動で管理して制御を強化するためです。 次に、SpeechSynthesizer コンストラクターの AudioConfignull を渡します。

注意

前述のスピーカー出力の例のように省略するのではなく、AudioConfignull を渡した場合、既定ではオーディオは現在のアクティブな出力デバイスで再生されません。

今回は、結果を SpeechSynthesisResult 変数に保存します。 AudioData プロパティには、出力データの byte [] が含まれます。 この byte [] を手動で操作することも、AudioDataStream クラスを使用してインメモリ ストリームを管理することもできます。 この例では、AudioDataStream.FromResult() 静的関数を使用して、結果からストリームを取得します。

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var synthesizer = new SpeechSynthesizer(config, null);

    var result = await synthesizer.SpeakTextAsync("Getting the response as an in-memory stream.");
    using var stream = AudioDataStream.FromResult(result);
}

ここから、結果として得られた stream オブジェクトを使用して、任意のカスタム動作を実装できます。

オーディオ形式をカスタマイズする

次のセクションでは、次のようなオーディオ出力属性をカスタマイズする方法について説明します。

  • オーディオ ファイルの種類
  • サンプルレート
  • ビット深度

オーディオ形式を変更するには、SpeechConfig オブジェクトで SetSpeechSynthesisOutputFormat() 関数を使用します。 この関数には、SpeechSynthesisOutputFormat 型の enum が必要です。これは、出力形式を選択するために使用します。 使用できるオーディオ形式の一覧については、リファレンス ドキュメントを参照してください。

要件に応じて、ファイルの種類ごとにさまざまなオプションがあります。 定義上、Raw24Khz16BitMonoPcm のような未加工の形式にはオーディオ ヘッダーが含まれないことに注意してください。 未加工の形式は、ダウンストリームの実装で未加工のビットストリームをデコードできることがわかっている場合か、ビット深度、サンプル レート、チャネル数などに基づいてヘッダーを手動で作成する場合にのみ使用してください。

この例では、SpeechConfig オブジェクトに SpeechSynthesisOutputFormat を設定することにより、高忠実度の RIFF 形式 Riff24Khz16BitMonoPcm を指定します。 前のセクションの例と同様に、AudioDataStream を使用して結果のインメモリ ストリームを取得し、それをファイルに書き込みます。

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    config.SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm);

    using var synthesizer = new SpeechSynthesizer(config, null);
    var result = await synthesizer.SpeakTextAsync("Customizing audio output format.");

    using var stream = AudioDataStream.FromResult(result);
    await stream.SaveToWaveFileAsync("path/to/write/file.wav");
}

プログラムをもう一度実行すると、指定したパスに .wav ファイルが書き込まれます。

SSML を使用して音声の特徴をカスタマイズする

音声合成マークアップ言語 (SSML) を使用すると、XML スキーマから要求を送信して、テキスト読み上げ出力のピッチ、発音、読み上げ速度、ボリュームなどを微調整することができます。 このセクションでは音声を変更する例を紹介しますが、より詳細なガイドについては、SSML の操作方法に関する記事を参照してください。

SSML を使用したカスタマイズを開始するには、音声を切り替える単純な変更を加えます。 まず、ルート プロジェクト ディレクトリに SSML 構成用の新しい XML ファイルを作成します (この例では ssml.xml)。 ルート要素は常に <speak> であり、テキストを <voice> 要素でラップすることで、name パラメーターを使用して音声を変更できます。 サポートされている ニューラル 音声の 全一覧を参照してください。

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

次に、XML ファイルを参照するように音声合成要求を変更する必要があります。 要求はほとんど同じですが、SpeakTextAsync() 関数を使用する代わりに、SpeakSsmlAsync() を使用します。 この関数には XML 文字列が必要なので、最初に File.ReadAllText() を使用して SSML 構成を文字列として読み込みます。 ここからは、結果のオブジェクトは前の例とまったく同じです。

注意

Visual Studio を使用している場合、既定では、ビルド構成で XML ファイルが見つからない可能性があります。 この問題を解決するには、該当する XML ファイルを右クリックし、 [プロパティ] を選択します。 [ビルド アクション][コンテンツ] に、 [出力ディレクトリにコピー][常にコピーする] に変更します。

public static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var synthesizer = new SpeechSynthesizer(config, null);

    var ssml = File.ReadAllText("./ssml.xml");
    var result = await synthesizer.SpeakSsmlAsync(ssml);

    using var stream = AudioDataStream.FromResult(result);
    await stream.SaveToWaveFileAsync("path/to/write/file.wav");
}

注意

SSML を使用せずに音声を変更するには、SpeechConfig.SpeechSynthesisVoiceName = "en-US-ChristopherNeural"; を使用して SpeechConfig のプロパティを設定します

表情イベントを取得する

スピーチは、表情のアニメーションを動かす有効な手段となる場合があります。 特定の音素を生成するときの唇、顎、舌の位置など、観察された発話における主要な姿勢を表すために、口形素がよく使用されます。 口形素イベントは、Speech SDK でサブスクライブできます。 その後、口形素イベントを適用すれば、スピーチ音声の再生に伴って、キャラクターに顔のアニメーションを付けることができます。 口形素イベントを取得する方法に関するセクションを参照してください。

このクイックスタートでは、Speech SDK を使用してテキスト読み上げ合成を行うための一般的な設計パターンについて説明します。 まずは基本的な構成と合成を行った後、次のようなより高度なカスタム アプリケーション開発の例に進みます。

  • インメモリ ストリームとして応答を取得する
  • 出力のサンプル レートとビット レートをカスタマイズする
  • SSML (音声合成マークアップ言語) を使用して合成要求を送信する
  • ニューラル音声を使用する

記事をスキップして GitHub 上のサンプルにアクセスする

この記事をスキップしてサンプル コードをご覧になりたい方は、GitHub 上の C++ クイックスタート サンプルを参照してください。

前提条件

この記事は、Azure アカウントと Speech Service サブスクリプションをお持ちであることを前提としています。 アカウントとサブスクリプションをお持ちでない場合は、Speech Service を無料でお試しください

Speech SDK のインストール

何らかの操作を行うには、事前に Speech SDK をインストールしておく必要があります。 ご利用のプラットフォームに応じて、次の手順を行います。

依存関係のインポート

この記事の例を実行するには、スクリプトの先頭に次の import および using ステートメントを含めます。

#include <iostream>
#include <fstream>
#include <string>
#include <speechapi_cxx.h>

using namespace std;
using namespace Microsoft::CognitiveServices::Speech;
using namespace Microsoft::CognitiveServices::Speech::Audio;

音声構成を作成する

Speech SDK を使用して Speech Service を呼び出すには、SpeechConfig を作成する必要があります。 このクラスには、音声キーとそれに関連付けられた場所/リージョン、エンドポイント、ホスト、認証トークンなど、サブスクリプションに関する情報が含まれています。

注意

音声認識、音声合成、翻訳、またはインテント認識のどれを実行するのかに関係なく、必ず構成を作成します。

SpeechConfig を初期化するには、次に示すようないくつかの方法があります。

  • サブスクリプションの場合: キーと、それに関連付けられた場所またはリージョンを渡します。
  • エンドポイントの場合: Speech Service エンドポイントを渡します。 キーまたは認証トークンは省略可能です。
  • ホストの場合: ホスト アドレスを渡します。 キーまたは認証トークンは省略可能です。
  • 認証トークンの場合: 認証トークンと、それに関連付けられた場所またはリージョンを渡します。

この例では、サブスクリプション キーとリージョンを使用して SpeechConfig を作成します。 「Speech Service を無料で試す」の手順に従って、これらの資格情報を取得します。 また、この記事の残りの部分で使用する、基本的な定型コードをいくつか作成します。これを変更して、さまざまなカスタマイズを行います。

int wmain()
{
    try
    {
        synthesizeSpeech();
    }
    catch (exception e)
    {
        cout << e.what();
    }
    return 0;
}

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
}

合成言語と音声を選択する

Azure Text to Speech サービスでは、250 を超える音声と 70 を超える言語とバリアントがサポートされています。 すべてのリストを入手することも、テキスト読み上げのデモでそれらを試すこともできます。 入力テキストに合わせて SpeechConfig の言語または音声を指定し、必要な音声を使用します。

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    // Note: if only language is set, the default voice of that language is chosen.
    config->SetSpeechSynthesisLanguage("<your-synthesis-language>"); // e.g. "de-DE"
    // The voice setting will overwrite language setting.
    // The voice setting will not overwrite the voice element in input SSML.
    config->SetSpeechSynthesisVoiceName("<your-wanted-voice>");
}

音声をファイルに合成する

次に、SpeechSynthesizer オブジェクトを作成します。これにより、テキストから音声への変換と、スピーカー、ファイル、またはその他の出力ストリームへの出力が実行されます。 SpeechSynthesizer は、前の手順で作成した SpeechConfig オブジェクトと、出力結果の処理方法を指定する AudioConfig オブジェクトをパラメーターとして受け取ります。

まず、FromWavFileOutput() 関数を使用して .wav ファイルに出力を自動的に書き込む AudioConfig を作成します。

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav");
}

次に、config オブジェクトと audioConfig オブジェクトをパラメーターとして渡すことで SpeechSynthesizer をインスタンス化します。 こうすることで、音声合成を実行してファイルに書き込むことが、テキスト文字列を使用して SpeakTextAsync() を実行するのと同じぐらい簡単になります。

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav");
    auto synthesizer = SpeechSynthesizer::FromConfig(config, audioConfig);
    auto result = synthesizer->SpeakTextAsync("A simple test to write to a file.").get();
}

このプログラムを実行すると、合成された .wav ファイルが、指定した場所に書き込まれます。 以上は最も基本的な使用方法の好例ですが、この次は、カスタム シナリオに対応できるよう、出力をカスタマイズし、出力応答をインメモリ ストリームとして処理する方法について説明します。

スピーカー出力に合成する

場合によっては、合成された音声をスピーカーに直接出力することが必要になる場合があります。 これは、上記の例で SpeechSynthesizer を作成するときに、AudioConfig パラメーターを省略することで実行できます。 これにより、現在のアクティブな出力デバイスに対して合成が行われます。

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto synthesizer = SpeechSynthesizer::FromConfig(config);
    auto result = synthesizer->SpeakTextAsync("Synthesizing directly to speaker output.").get();
}

結果をインメモリ ストリームとして取得する

音声アプリケーション開発の多くのシナリオでは、結果として得られたオーディオ データは、ファイルに直接書き込むのではなく、インメモリ ストリームとして必要となるケースがよくあります。 その場合、次のようなカスタム動作を構築できます。

  • 結果として得られたバイト配列を、カスタム ダウンストリーム サービス向けのシーク可能なストリームとして抽象化する。
  • 結果を他の API またはサービスと統合する。
  • オーディオ データの変更やカスタム .wav ヘッダーの記述などを行う。

この変更は、前の例から簡単に行うことができます。 まず、AudioConfig を削除します。これは、制御を高めるために、この時点から出力動作を手動で管理するからです。 次に、SpeechSynthesizer コンストラクターの AudioConfigNULL を渡します。

注意

前述のスピーカー出力の例のように省略するのではなく、AudioConfigNULL を渡した場合、既定ではオーディオは現在のアクティブな出力デバイスで再生されません。

今回は、結果を SpeechSynthesisResult 変数に保存します。 GetAudioData ゲッターは、出力データの byte [] を返します。 この byte [] を手動で操作することも、AudioDataStream クラスを使用してインメモリ ストリームを管理することもできます。 この例では、AudioDataStream.FromResult() 静的関数を使用して、結果からストリームを取得します。

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto synthesizer = SpeechSynthesizer::FromConfig(config, NULL);

    auto result = synthesizer->SpeakTextAsync("Getting the response as an in-memory stream.").get();
    auto stream = AudioDataStream::FromResult(result);
}

ここから、結果として得られた stream オブジェクトを使用して、任意のカスタム動作を実装できます。

オーディオ形式をカスタマイズする

次のセクションでは、次のようなオーディオ出力属性をカスタマイズする方法について説明します。

  • オーディオ ファイルの種類
  • サンプルレート
  • ビット深度

オーディオ形式を変更するには、SpeechConfig オブジェクトで SetSpeechSynthesisOutputFormat() 関数を使用します。 この関数には、SpeechSynthesisOutputFormat 型の enum が必要です。これは、出力形式を選択するために使用します。 使用できるオーディオ形式の一覧については、リファレンス ドキュメントを参照してください。

要件に応じて、ファイルの種類ごとにさまざまなオプションがあります。 定義上、Raw24Khz16BitMonoPcm のような未加工の形式にはオーディオ ヘッダーが含まれないことに注意してください。 未加工の形式は、ダウンストリームの実装で未加工のビットストリームをデコードできることがわかっている場合か、ビット深度、サンプル レート、チャネル数などに基づいてヘッダーを手動で作成する場合にのみ使用してください。

この例では、SpeechConfig オブジェクトに SpeechSynthesisOutputFormat を設定することにより、高忠実度の RIFF 形式 Riff24Khz16BitMonoPcm を指定します。 前のセクションの例と同様に、AudioDataStream を使用して結果のインメモリ ストリームを取得し、それをファイルに書き込みます。

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    config->SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat::Riff24Khz16BitMonoPcm);

    auto synthesizer = SpeechSynthesizer::FromConfig(config, NULL);
    auto result = synthesizer->SpeakTextAsync("A simple test to write to a file.").get();

    auto stream = AudioDataStream::FromResult(result);
    stream->SaveToWavFileAsync("path/to/write/file.wav").get();
}

プログラムをもう一度実行すると、指定したパスに .wav ファイルが書き込まれます。

SSML を使用して音声の特徴をカスタマイズする

音声合成マークアップ言語 (SSML) を使用すると、XML スキーマから要求を送信して、テキスト読み上げ出力のピッチ、発音、読み上げ速度、ボリュームなどを微調整することができます。 このセクションでは音声を変更する例を紹介しますが、より詳細なガイドについては、SSML の操作方法に関する記事を参照してください。

SSML を使用したカスタマイズを開始するには、音声を切り替える単純な変更を加えます。 まず、ルート プロジェクト ディレクトリに SSML 構成用の新しい XML ファイルを作成します (この例では ssml.xml)。 ルート要素は常に <speak> であり、テキストを <voice> 要素でラップすることで、name パラメーターを使用して音声を変更できます。 サポートされている ニューラル 音声の 全一覧を参照してください。

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

次に、XML ファイルを参照するように音声合成要求を変更する必要があります。 要求はほとんど同じですが、SpeakTextAsync() 関数を使用する代わりに、SpeakSsmlAsync() を使用します。 この関数には XML 文字列が必要なので、最初に SSML 構成を文字列として読み込みます。 ここからは、結果のオブジェクトは前の例とまったく同じです。

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto synthesizer = SpeechSynthesizer::FromConfig(config, NULL);

    std::ifstream file("./ssml.xml");
    std::string ssml, line;
    while (std::getline(file, line))
    {
        ssml += line;
        ssml.push_back('\n');
    }
    auto result = synthesizer->SpeakSsmlAsync(ssml).get();

    auto stream = AudioDataStream::FromResult(result);
    stream->SaveToWavFileAsync("path/to/write/file.wav").get();
}

注意

SSML を使用せずに音声を変更するには、SpeechConfig.SetSpeechSynthesisVoiceName("en-US-ChristopherNeural") を使用して SpeechConfig のプロパティを設定します

表情イベントを取得する

スピーチは、表情のアニメーションを動かす有効な手段となる場合があります。 特定の音素を生成するときの唇、顎、舌の位置など、観察された発話における主要な姿勢を表すために、口形素がよく使用されます。 口形素イベントは、Speech SDK でサブスクライブできます。 その後、口形素イベントを適用すれば、スピーチ音声の再生に伴って、キャラクターに顔のアニメーションを付けることができます。 口形素イベントを取得する方法に関するセクションを参照してください。

このクイックスタートでは、Speech SDK を使用してテキスト読み上げ合成を行うための一般的な設計パターンについて説明します。

記事をスキップして GitHub 上のサンプルにアクセスする

この記事をスキップしてサンプル コードをご覧になりたい方は、GitHub 上の Go クイックスタート サンプルを参照してください。

前提条件

この記事は、Azure アカウントと Speech Service サブスクリプションをお持ちであることを前提としています。 アカウントとサブスクリプションをお持ちでない場合は、Speech Service を無料でお試しください

Speech SDK のインストール

なんらかの操作を行うには、事前に Speech SDK for Go をインストールしておく必要があります。

スピーカーへのテキスト読み上げ

音声合成を既定のオーディオ出力デバイスに対して実行するには、次のコード サンプルを使用します。 変数 subscriptionregion を、音声キーと場所またはリージョンに置き換えます。 スクリプトを実行すると、入力テキストが既定のスピーカーで読み上げられます。

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
    "time"

    "github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/common"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)

func synthesizeStartedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("Synthesis started.")
}

func synthesizingHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Printf("Synthesizing, audio chunk size %d.\n", len(event.Result.AudioData))
}

func synthesizedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Printf("Synthesized, audio length %d.\n", len(event.Result.AudioData))
}

func cancelledHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("Received a cancellation.")
}

func main() {
    subscription := "<paste-your-speech-key-here>"
    region := "<paste-your-speech-location/region-here>"

    audioConfig, err := audio.NewAudioConfigFromDefaultSpeakerOutput()
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer audioConfig.Close()
    config, err := speech.NewSpeechConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer config.Close()
    speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(config, audioConfig)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechSynthesizer.Close()

    speechSynthesizer.SynthesisStarted(synthesizeStartedHandler)
    speechSynthesizer.Synthesizing(synthesizingHandler)
    speechSynthesizer.SynthesisCompleted(synthesizedHandler)
    speechSynthesizer.SynthesisCanceled(cancelledHandler)

    for {
        fmt.Printf("Enter some text that you want to speak, or enter empty text to exit.\n> ")
        text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
        text = strings.TrimSuffix(text, "\n")
        if len(text) == 0 {
            break
        }

        task := speechSynthesizer.SpeakTextAsync(text)
        var outcome speech.SpeechSynthesisOutcome
        select {
        case outcome = <-task:
        case <-time.After(60 * time.Second):
            fmt.Println("Timed out")
            return
        }
        defer outcome.Close()
        if outcome.Error != nil {
            fmt.Println("Got an error: ", outcome.Error)
            return
        }

        if outcome.Result.Reason == common.SynthesizingAudioCompleted {
            fmt.Printf("Speech synthesized to speaker for text [%s].\n", text)
        } else {
            cancellation, _ := speech.NewCancellationDetailsFromSpeechSynthesisResult(outcome.Result)
            fmt.Printf("CANCELED: Reason=%d.\n", cancellation.Reason)

            if cancellation.Reason == common.Error {
                fmt.Printf("CANCELED: ErrorCode=%d\nCANCELED: ErrorDetails=[%s]\nCANCELED: Did you update the subscription info?\n",
                    cancellation.ErrorCode,
                    cancellation.ErrorDetails)
            }
        }
    }
}

次のコマンドを実行して、GitHub でホストされるコンポーネントにリンクされる go.mod ファイルを作成します。

go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go

次に、コードをビルドして実行します。

go build
go run quickstart

SpeechConfig クラスと SpeechSynthesizer クラスの詳細については、リファレンス ドキュメントを参照してください。

メモリ内ストリームへのテキスト読み上げ

音声アプリケーション開発の多くのシナリオでは、結果として得られたオーディオ データは、ファイルに直接書き込むのではなく、インメモリ ストリームとして必要となるケースがよくあります。 その場合、次のようなカスタム動作を構築できます。

  • 結果として得られたバイト配列を、カスタム ダウンストリーム サービス向けのシーク可能なストリームとして抽象化する。
  • 結果を他の API またはサービスと統合する。
  • オーディオ データの変更やカスタム .wav ヘッダーの記述などを行う。

この変更は、前の例から簡単に行うことができます。 まず、AudioConfig を削除します。これは、制御を高めるために、この時点から出力動作を手動で管理するからです。 次に、SpeechSynthesizer コンストラクターの AudioConfignil を渡します。

注意

前述のスピーカー出力の例のように省略するのではなく、AudioConfignil を渡した場合、既定ではオーディオは現在のアクティブな出力デバイスで再生されません。

今回は、結果を SpeechSynthesisResult 変数に保存します。 AudioData プロパティは、出力データの []byte を返します。 この []byte を手動で操作することも、AudioDataStream クラスを使用してインメモリ ストリームを管理することもできます。 この例では、NewAudioDataStreamFromSpeechSynthesisResult() 静的関数を使用して、結果からストリームを取得します。

変数 subscriptionregion を、音声キーと場所またはリージョンに置き換えます。

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
    "time"

    "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)

func main(subscription string, region string) {
    subscription := "<paste-your-speech-key-here>"
    region := "<paste-your-speech-location/region-here>"

    config, err := speech.NewSpeechConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer config.Close()
    speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(config, nil)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechSynthesizer.Close()

    speechSynthesizer.SynthesisStarted(synthesizeStartedHandler)
    speechSynthesizer.Synthesizing(synthesizingHandler)
    speechSynthesizer.SynthesisCompleted(synthesizedHandler)
    speechSynthesizer.SynthesisCanceled(cancelledHandler)

    for {
        fmt.Printf("Enter some text that you want to speak, or enter empty text to exit.\n> ")
        text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
        text = strings.TrimSuffix(text, "\n")
        if len(text) == 0 {
            break
        }

        // StartSpeakingTextAsync sends the result to channel when the synthesis starts.
        task := speechSynthesizer.StartSpeakingTextAsync(text)
        var outcome speech.SpeechSynthesisOutcome
        select {
        case outcome = <-task:
        case <-time.After(60 * time.Second):
            fmt.Println("Timed out")
            return
        }
        defer outcome.Close()
        if outcome.Error != nil {
            fmt.Println("Got an error: ", outcome.Error)
            return
        }

        // in most case we want to streaming receive the audio to lower the latency,
        // we can use AudioDataStream to do so.
        stream, err := speech.NewAudioDataStreamFromSpeechSynthesisResult(outcome.Result)
        defer stream.Close()
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }

        var all_audio []byte
        audio_chunk := make([]byte, 2048)
        for {
            n, err := stream.Read(audio_chunk)

            if err == io.EOF {
                break
            }

            all_audio = append(all_audio, audio_chunk[:n]...)
        }

        fmt.Printf("Read [%d] bytes from audio data stream.\n", len(all_audio))
    }
}

次のコマンドを実行して、GitHub でホストされるコンポーネントにリンクされる go.mod ファイルを作成します。

go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go

次に、コードをビルドして実行します。

go build
go run quickstart

SpeechConfig クラスと SpeechSynthesizer クラスの詳細については、リファレンス ドキュメントを参照してください。

SSML を使用して音声の特徴をカスタマイズする

音声合成マークアップ言語 (SSML) を使用すると、XML スキーマから要求を送信して、テキスト読み上げ出力のピッチ、発音、読み上げ速度、ボリュームなどを微調整することができます。 このセクションでは音声を変更する例を紹介しますが、より詳細なガイドについては、SSML の操作方法に関する記事を参照してください。

SSML を使用したカスタマイズを開始するには、音声を切り替える単純な変更を加えます。 まず、ルート プロジェクト ディレクトリに SSML 構成用の新しい XML ファイルを作成します (この例では ssml.xml)。 ルート要素は常に <speak> であり、テキストを <voice> 要素でラップすることで、name パラメーターを使用して音声を変更できます。 サポートされている ニューラル 音声の 全一覧を参照してください。

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

次に、XML ファイルを参照するように音声合成要求を変更する必要があります。 要求はほとんど同じですが、SpeakTextAsync() 関数を使用する代わりに、SpeakSsmlAsync() を使用します。 この関数には XML 文字列が必要なので、最初に SSML 構成を文字列として読み込みます。 ここからは、結果のオブジェクトは前の例とまったく同じです。

注意

SSML を使用せずに音声を変更するには、speechConfig.SetSpeechSynthesisVoiceName("en-US-ChristopherNeural") を使用して SpeechConfig のプロパティを設定します

表情イベントを取得する

スピーチは、表情のアニメーションを動かす有効な手段となる場合があります。 特定の音素を生成するときの唇、顎、舌の位置など、観察された発話における主要な姿勢を表すために、口形素がよく使用されます。 口形素イベントは、Speech SDK でサブスクライブできます。 その後、口形素イベントを適用すれば、スピーチ音声の再生に伴って、キャラクターに顔のアニメーションを付けることができます。 口形素イベントを取得する方法に関するセクションを参照してください。

このクイックスタートでは、Speech SDK を使用してテキスト読み上げ合成を行うための一般的な設計パターンについて説明します。 まずは基本的な構成と合成を行った後、次のようなより高度なカスタム アプリケーション開発の例に進みます。

  • インメモリ ストリームとして応答を取得する
  • 出力のサンプル レートとビット レートをカスタマイズする
  • SSML (音声合成マークアップ言語) を使用して合成要求を送信する
  • ニューラル音声を使用する

記事をスキップして GitHub 上のサンプルにアクセスする

この記事をスキップしてサンプル コードをご覧になりたい方は、GitHub 上の Java クイックスタート サンプルを参照してください。

前提条件

この記事は、Azure アカウントと Speech Service サブスクリプションをお持ちであることを前提としています。 アカウントとサブスクリプションをお持ちでない場合は、Speech Service を無料でお試しください

Speech SDK のインストール

何らかの操作を行うには、事前に Speech SDK をインストールしておく必要があります。 ご利用のプラットフォームに応じて、次の手順を行います。

依存関係のインポート

この記事の例を実行するには、スクリプトの先頭に次の import ステートメントを含めます。

import com.microsoft.cognitiveservices.speech.AudioDataStream;
import com.microsoft.cognitiveservices.speech.SpeechConfig;
import com.microsoft.cognitiveservices.speech.SpeechSynthesizer;
import com.microsoft.cognitiveservices.speech.SpeechSynthesisOutputFormat;
import com.microsoft.cognitiveservices.speech.SpeechSynthesisResult;
import com.microsoft.cognitiveservices.speech.audio.AudioConfig;

import java.io.*;
import java.util.Scanner;

音声構成を作成する

Speech SDK を使用して Speech Service を呼び出すには、SpeechConfig を作成する必要があります。 このクラスには、音声キーとそれに関連付けられた場所/リージョン、エンドポイント、ホスト、認証トークンなど、サブスクリプションに関する情報が含まれています。

注意

音声認識、音声合成、翻訳、またはインテント認識のどれを実行するのかに関係なく、必ず構成を作成します。

SpeechConfig を初期化するには、次に示すようないくつかの方法があります。

  • サブスクリプションの場合: 音声キーと、それに関連付けられた場所/リージョンを渡します。
  • エンドポイントの場合: Speech Service エンドポイントを渡します。 音声キーまたは認証トークンは省略可能です。
  • ホストの場合: ホスト アドレスを渡します。 音声キーまたは認証トークンは省略可能です。
  • 認証トークンの場合: 認証トークンと、それに関連付けられた場所またはリージョンを渡します。

この例では、音声キーと場所/リージョンを使用して SpeechConfig を作成します。 「Speech Service を無料で試す」の手順に従って、これらの資格情報を取得します。 また、この記事の残りの部分で使用する、基本的な定型コードをいくつか作成します。これを変更して、さまざまなカスタマイズを行います。

public class Program
{
    public static void main(String[] args) {
        SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    }
}

合成言語と音声を選択する

Azure Text to Speech サービスでは、250 を超える音声と 70 を超える言語とバリアントがサポートされています。 すべてのリストを入手することも、テキスト読み上げのデモでそれらを試すこともできます。 入力テキストに合わせて SpeechConfig の言語または音声を指定し、必要な音声を使用します。

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    // Note: if only language is set, the default voice of that language is chosen.
    config.setSpeechSynthesisLanguage("<your-synthesis-language>"); // e.g. "de-DE"
    // The voice setting will overwrite language setting.
    // The voice setting will not overwrite the voice element in input SSML.
    config.setSpeechSynthesisVoiceName("<your-wanted-voice>");
}

音声をファイルに合成する

次に、SpeechSynthesizer オブジェクトを作成します。これにより、テキストから音声への変換と、スピーカー、ファイル、またはその他の出力ストリームへの出力が実行されます。 SpeechSynthesizer は、前の手順で作成された SpeechConfig オブジェクト、および出力結果の処理方法を指定する AudioConfig オブジェクトをパラメーターとして受け取ります。

まず、fromWavFileOutput() 静的関数を使用して .wav ファイルに出力を自動的に書き込む AudioConfig を作成します。

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav");
}

次に、speechConfig オブジェクトと audioConfig オブジェクトをパラメーターとして渡す SpeechSynthesizer をインスタンス化します。 こうすることで、音声合成を実行してファイルに書き込むことが、テキスト文字列を使用して SpeakText() を実行するのと同じぐらい簡単になります。

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav");

    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    synthesizer.SpeakText("A simple test to write to a file.");
}

このプログラムを実行すると、合成された .wav ファイルが、指定した場所に書き込まれます。 以上は最も基本的な使用方法の好例ですが、この次は、カスタム シナリオに対応できるよう、出力をカスタマイズし、出力応答をインメモリ ストリームとして処理する方法について説明します。

スピーカー出力に合成する

場合によっては、合成された音声をスピーカーに直接出力することが必要になる場合があります。 これを行うには、fromDefaultSpeakerOutput() 静的関数を使用して AudioConfig をインスタンス化します。 これにより、現在のアクティブな出力デバイスに対して出力が行われます。

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    AudioConfig audioConfig = AudioConfig.fromDefaultSpeakerOutput();

    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    synthesizer.SpeakText("Synthesizing directly to speaker output.");
}

結果をインメモリ ストリームとして取得する

音声アプリケーション開発の多くのシナリオでは、結果として得られたオーディオ データは、ファイルに直接書き込むのではなく、インメモリ ストリームとして必要となるケースがよくあります。 その場合、次のようなカスタム動作を構築できます。

  • 結果として得られたバイト配列を、カスタム ダウンストリーム サービス向けのシーク可能なストリームとして抽象化する。
  • 結果を他の API またはサービスと統合する。
  • オーディオ データの変更やカスタム .wav ヘッダーの記述などを行う。

この変更は、前の例から簡単に行うことができます。 まず、AudioConfig ブロックを削除します。これは、この時点から出力動作を手動で管理して制御を強化するためです。 次に、SpeechSynthesizer コンストラクターの AudioConfignull を渡します。

注意

前述のスピーカー出力の例のように省略するのではなく、AudioConfignull を渡した場合、既定ではオーディオは現在のアクティブな出力デバイスで再生されません。

今回は、結果を SpeechSynthesisResult 変数に保存します。 SpeechSynthesisResult.getAudioData() 関数は、出力データの byte [] を返します。 この byte [] を手動で操作することも、AudioDataStream クラスを使用してインメモリ ストリームを管理することもできます。 この例では、AudioDataStream.fromResult() 静的関数を使用して、結果からストリームを取得します。

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, null);

    SpeechSynthesisResult result = synthesizer.SpeakText("Getting the response as an in-memory stream.");
    AudioDataStream stream = AudioDataStream.fromResult(result);
    System.out.print(stream.getStatus());
}

ここから、結果として得られた stream オブジェクトを使用して、任意のカスタム動作を実装できます。

オーディオ形式をカスタマイズする

次のセクションでは、次のようなオーディオ出力属性をカスタマイズする方法について説明します。

  • オーディオ ファイルの種類
  • サンプルレート
  • ビット深度

オーディオ形式を変更するには、SpeechConfig オブジェクトで setSpeechSynthesisOutputFormat() 関数を使用します。 この関数には、SpeechSynthesisOutputFormat 型の enum が必要です。これは、出力形式を選択するために使用します。 使用できるオーディオ形式の一覧については、リファレンス ドキュメントを参照してください。

要件に応じて、ファイルの種類ごとにさまざまなオプションがあります。 定義上、Raw24Khz16BitMonoPcm のような未加工の形式にはオーディオ ヘッダーが含まれないことに注意してください。 未加工の形式は、ダウンストリームの実装で未加工のビットストリームをデコードできることがわかっている場合か、ビット深度、サンプル レート、チャネル数などに基づいてヘッダーを手動で作成する場合にのみ使用してください。

この例では、SpeechConfig オブジェクトに SpeechSynthesisOutputFormat を設定することにより、高忠実度の RIFF 形式 Riff24Khz16BitMonoPcm を指定します。 前のセクションの例と同様に、AudioDataStream を使用して結果のインメモリ ストリームを取得し、それをファイルに書き込みます。

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");

    // set the output format
    speechConfig.setSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm);

    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, null);
    SpeechSynthesisResult result = synthesizer.SpeakText("Customizing audio output format.");
    AudioDataStream stream = AudioDataStream.fromResult(result);
    stream.saveToWavFile("path/to/write/file.wav");
}

プログラムをもう一度実行すると、指定したパスに .wav ファイルが書き込まれます。

SSML を使用して音声の特徴をカスタマイズする

音声合成マークアップ言語 (SSML) を使用すると、XML スキーマから要求を送信して、テキスト読み上げ出力のピッチ、発音、読み上げ速度、ボリュームなどを微調整することができます。 このセクションでは音声を変更する例を紹介しますが、より詳細なガイドについては、SSML の操作方法に関する記事を参照してください。

SSML を使用したカスタマイズを開始するには、音声を切り替える単純な変更を加えます。 まず、ルート プロジェクト ディレクトリに SSML 構成用の新しい XML ファイルを作成します (この例では ssml.xml)。 ルート要素は常に <speak> であり、テキストを <voice> 要素でラップすることで、name パラメーターを使用して音声を変更できます。 サポートされている ニューラル 音声の 全一覧を参照してください。

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

次に、XML ファイルを参照するように音声合成要求を変更する必要があります。 要求はほとんど同じですが、SpeakText() 関数を使用する代わりに、SpeakSsml() を使用します。 この関数には XML 文字列が必要なので、最初に、XML ファイルを読み込んでそれを文字列として返す関数を作成します。

private static String xmlToString(String filePath) {
    File file = new File(filePath);
    StringBuilder fileContents = new StringBuilder((int)file.length());

    try (Scanner scanner = new Scanner(file)) {
        while(scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine() + System.lineSeparator());
        }
        return fileContents.toString().trim();
    } catch (FileNotFoundException ex) {
        return "File not found.";
    }
}

ここからは、結果のオブジェクトは前の例とまったく同じです。

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, null);

    String ssml = xmlToString("ssml.xml");
    SpeechSynthesisResult result = synthesizer.SpeakSsml(ssml);
    AudioDataStream stream = AudioDataStream.fromResult(result);
    stream.saveToWavFile("path/to/write/file.wav");
}

注意

SSML を使用せずに音声を変更するには、SpeechConfig.setSpeechSynthesisVoiceName("en-US-ChristopherNeural"); を使用して SpeechConfig のプロパティを設定します

表情イベントを取得する

スピーチは、表情のアニメーションを動かす有効な手段となる場合があります。 特定の音素を生成するときの唇、顎、舌の位置など、観察された発話における主要な姿勢を表すために、口形素がよく使用されます。 Speech SDK で口形素イベントをサブスクライブすることにより、顔のアニメーション データを取得し、キャラクターに顔のアニメーションを付けるときにそのデータを適用することができます。 口形素イベントを取得する方法に関するセクションを参照してください。

このクイックスタートでは、Speech SDK を使用してテキスト読み上げ合成を行うための一般的な設計パターンについて説明します。 まずは基本的な構成と合成を行った後、次のようなより高度なカスタム アプリケーション開発の例に進みます。

  • インメモリ ストリームとして応答を取得する
  • 出力のサンプル レートとビット レートをカスタマイズする
  • SSML (音声合成マークアップ言語) を使用して合成要求を送信する
  • ニューラル音声を使用する

記事をスキップして GitHub 上のサンプルにアクセスする

この記事をスキップしてサンプル コードをご覧になりたい方は、GitHub 上の JavaScript クイックスタート サンプルを参照してください。

前提条件

この記事は、Azure アカウントと Speech Service リソースがあることを前提としています。 アカウントとリソースがない場合は、Speech Service を無料でお試しください

Speech SDK のインストール

何らかの操作を行うには、事前に Speech SDK for JavaScript をインストールしておく必要があります。 ご利用のプラットフォームに応じて、次の手順を行います。

また、ターゲット環境によっては、次のいずれかを使用します。

Speech SDK for JavaScript microsoft.cognitiveservices.speech.sdk.bundle.js ファイルをダウンロードして抽出し、HTML ファイルにアクセス可能なフォルダーに配置します。

<script src="microsoft.cognitiveservices.speech.sdk.bundle.js"></script>;

ヒント

Web ブラウザーを対象としていて、<script> タグを使用する場合は、sdk プレフィックスは必要ありません。 sdk プレフィックスは、require モジュールに名前を付けるために使用されるエイリアスです。

音声構成を作成する

Speech SDK を使用して Speech Service を呼び出すには、SpeechConfig を作成する必要があります。 このクラスには、音声キーとそれに関連付けられた場所/リージョン、エンドポイント、ホスト、認証トークンなど、リソースに関する情報が含まれています。

注意

音声認識、音声合成、翻訳、またはインテント認識のどれを実行するのかに関係なく、必ず構成を作成します。

SpeechConfig を初期化するには、次に示すようないくつかの方法があります。

  • リソースの場合: 音声キーと、それに関連付けられた場所/リージョンを渡します。
  • エンドポイントの場合: Speech Service エンドポイントを渡します。 音声キーまたは認証トークンは省略可能です。
  • ホストの場合: ホスト アドレスを渡します。 音声キーまたは認証トークンは省略可能です。
  • 認証トークンの場合: 認証トークンと、それに関連付けられた場所またはリージョンを渡します。

この例では、音声キーと場所/リージョンを使用して SpeechConfig を作成します。 「Speech Service を無料で試す」の手順に従って、これらの資格情報を取得します。 また、この記事の残りの部分で使用する、基本的な定型コードをいくつか作成します。これを変更して、さまざまなカスタマイズを行います。

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
}

synthesizeSpeech();

合成言語と音声を選択する

Azure Text to Speech サービスでは、250 を超える音声と 70 を超える言語とバリアントがサポートされています。 すべてのリストを入手することも、テキスト読み上げのデモでそれらを試すこともできます。 入力テキストに合わせて SpeechConfig の言語または音声を指定し、必要な音声を使用します。

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    // Note: if only language is set, the default voice of that language is chosen.
    speechConfig.speechSynthesisLanguage = "<your-synthesis-language>"; // e.g. "de-DE"
    // The voice setting will overwrite language setting.
    // The voice setting will not overwrite the voice element in input SSML.
    speechConfig.speechSynthesisVoiceName = "<your-wanted-voice>";
}

synthesizeSpeech();

音声をファイルに合成する

次に、SpeechSynthesizer オブジェクトを作成します。これにより、テキストから音声への変換と、スピーカー、ファイル、またはその他の出力ストリームへの出力が実行されます。 SpeechSynthesizer は、前の手順で作成された SpeechConfig オブジェクト、および出力結果の処理方法を指定する AudioConfig オブジェクトをパラメーターとして受け取ります。

まず、fromAudioFileOutput() 静的関数を使用して .wav ファイルに出力を自動的に書き込む AudioConfig を作成します。

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const audioConfig = sdk.AudioConfig.fromAudioFileOutput("path/to/file.wav");
}

次に、speechConfig オブジェクトと audioConfig オブジェクトをパラメーターとして渡す SpeechSynthesizer をインスタンス化します。 こうすることで、音声合成を実行してファイルに書き込むことが、テキスト文字列を使用して speakTextAsync() を実行するのと同じぐらい簡単になります。 結果のコールバックは synthesizer.close() を呼び出すのに最適な場所です。実際、合成が正しく機能するためにはこの呼び出しが必要です。

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const audioConfig = sdk.AudioConfig.fromAudioFileOutput("path-to-file.wav");

    const synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    synthesizer.speakTextAsync(
        "A simple test to write to a file.",
        result => {
            synthesizer.close();
            if (result) {
                // return result as stream
                return fs.createReadStream("path-to-file.wav");
            }
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

このプログラムを実行すると、合成された .wav ファイルが、指定した場所に書き込まれます。 以上は最も基本的な使用方法の好例ですが、この次は、カスタム シナリオに対応できるよう、出力をカスタマイズし、出力応答をインメモリ ストリームとして処理する方法について説明します。

スピーカー出力に合成する (ブラウザーのみ)

場合によっては、合成された音声をスピーカーに直接出力することが必要になる場合があります。 これを行うには、fromDefaultSpeakerOutput() 静的関数を使用して AudioConfig をインスタンス化します。 これにより、現在のアクティブな出力デバイスに対して出力が行われます。

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const audioConfig = sdk.AudioConfig.fromDefaultSpeakerOutput();

    const synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    synthesizer.speakTextAsync(
        "Synthesizing directly to speaker output.",
        result => {
            if (result) {
                synthesizer.close();
                return result.audioData;
            }
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

結果をインメモリ ストリームとして取得する

音声アプリケーション開発の多くのシナリオでは、結果として得られたオーディオ データは、ファイルに直接書き込むのではなく、インメモリ ストリームとして必要となるケースがよくあります。 その場合、次のようなカスタム動作を構築できます。

  • 結果として得られたバイト配列を、カスタム ダウンストリーム サービス向けのシーク可能なストリームとして抽象化する。
  • 結果を他の API またはサービスと統合する。
  • オーディオ データの変更やカスタム .wav ヘッダーの記述などを行う。

この変更は、前の例から簡単に行うことができます。 まず、AudioConfig ブロックを削除します。これは、この時点から出力動作を手動で管理して制御を強化するためです。 次に、SpeechSynthesizer コンストラクターの AudioConfigundefined を渡します。

注意

前述のスピーカー出力の例のように省略するのではなく、AudioConfigundefined を渡した場合、既定ではオーディオは現在のアクティブな出力デバイスで再生されません。

今回は、結果を SpeechSynthesisResult 変数に保存します。 SpeechSynthesisResult.audioData プロパティは、既定のブラウザー ストリーム型である、出力データの ArrayBuffer を返します。 サーバー コードの場合、ArrayBuffer をバッファー ストリームに変換します。

次のコードは、クライアント側のコードに対して機能します。

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const synthesizer = new sdk.SpeechSynthesizer(speechConfig);

    synthesizer.speakTextAsync(
        "Getting the response as an in-memory stream.",
        result => {
            synthesizer.close();
            return result.audioData;
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

ここから、結果として得られた ArrayBuffer オブジェクトを使用して、任意のカスタム動作を実装できます。 ArrayBuffer は、ブラウザーで受信し、この形式から再生する共通の型です。

サーバー ベースのコードでは、ArrayBuffer ではなくストリームとしてデータを操作する必要がある場合は、オブジェクトをストリームに変換する必要があります。

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const synthesizer = new sdk.SpeechSynthesizer(speechConfig);

    synthesizer.speakTextAsync(
        "Getting the response as an in-memory stream.",
        result => {
            const { audioData } = result;

            synthesizer.close();

            // convert arrayBuffer to stream
            // return stream
            const bufferStream = new PassThrough();
            bufferStream.end(Buffer.from(audioData));
            return bufferStream;
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

オーディオ形式をカスタマイズする

次のセクションでは、次のようなオーディオ出力属性をカスタマイズする方法について説明します。

  • オーディオ ファイルの種類
  • サンプルレート
  • ビット深度

オーディオ形式を変更するには、SpeechConfig オブジェクトで speechSynthesisOutputFormat プロパティを使用します。 このプロパティには、SpeechSynthesisOutputFormat 型の enum が必要です。これは、出力形式を選択するために使用します。 使用できるオーディオ形式の一覧については、リファレンス ドキュメントを参照してください。

要件に応じて、ファイルの種類ごとにさまざまなオプションがあります。 定義上、Raw24Khz16BitMonoPcm のような未加工の形式にはオーディオ ヘッダーが含まれないことに注意してください。 未加工の形式は、ダウンストリームの実装で未加工のビットストリームをデコードできることがわかっている場合か、ビット深度、サンプル レート、チャネル数などに基づいてヘッダーを手動で作成する場合にのみ使用してください。

この例では、SpeechConfig オブジェクトに speechSynthesisOutputFormat を設定することにより、高忠実度の RIFF 形式 Riff24Khz16BitMonoPcm を指定します。 前のセクションの例と同様に、オーディオ ArrayBuffer データを取得して操作します。

function synthesizeSpeech() {
    const speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");

    // Set the output format
    speechConfig.speechSynthesisOutputFormat = SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm;

    const synthesizer = new sdk.SpeechSynthesizer(speechConfig, undefined);
    synthesizer.speakTextAsync(
        "Customizing audio output format.",
        result => {
            // Interact with the audio ArrayBuffer data
            const audioData = result.audioData;
            console.log(`Audio data byte size: ${audioData.byteLength}.`)

            synthesizer.close();
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

プログラムをもう一度実行すると、指定したパスに .wav ファイルが書き込まれます。

SSML を使用して音声の特徴をカスタマイズする

音声合成マークアップ言語 (SSML) を使用すると、XML スキーマから要求を送信して、テキスト読み上げ出力のピッチ、発音、読み上げ速度、ボリュームなどを微調整することができます。 このセクションでは音声を変更する例を紹介しますが、より詳細なガイドについては、SSML の操作方法に関する記事を参照してください。

SSML を使用したカスタマイズを開始するには、音声を切り替える単純な変更を加えます。 まず、ルート プロジェクト ディレクトリに SSML 構成用の新しい XML ファイルを作成します (この例では ssml.xml)。 ルート要素は常に <speak> であり、テキストを <voice> 要素でラップすることで、name パラメーターを使用して音声を変更できます。 サポートされている ニューラル 音声の 全一覧を参照してください。

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

次に、XML ファイルを参照するように音声合成要求を変更する必要があります。 要求はほとんど同じですが、speakTextAsync() 関数を使用する代わりに、speakSsmlAsync() を使用します。 この関数には XML 文字列が必要なので、最初に、XML ファイルを読み込んでそれを文字列として返す関数を作成します。

function xmlToString(filePath) {
    const xml = readFileSync(filePath, "utf8");
    return xml;
}

readFileSync の詳細については、「Node.js ファイル システム」を参照してください。 ここからは、結果のオブジェクトは前の例とまったく同じです。

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const synthesizer = new sdk.SpeechSynthesizer(speechConfig, undefined);

    const ssml = xmlToString("ssml.xml");
    synthesizer.speakSsmlAsync(
        ssml,
        result => {
            if (result.errorDetails) {
                console.error(result.errorDetails);
            } else {
                console.log(JSON.stringify(result));
            }

            synthesizer.close();
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

注意

SSML を使用せずに音声を変更するには、SpeechConfig.speechSynthesisVoiceName = "en-US-ChristopherNeural"; を使用して SpeechConfig のプロパティを設定します

表情イベントを取得する

スピーチは、表情のアニメーションを動かす有効な手段となる場合があります。 特定の音素を生成するときの唇、顎、舌の位置など、観察された発話における主要な姿勢を表すために、口形素がよく使用されます。 口形素イベントは、Speech SDK でサブスクライブできます。 その後、口形素イベントを適用すれば、スピーチ音声の再生に伴って、キャラクターに顔のアニメーションを付けることができます。 口形素イベントを取得する方法に関するセクションを参照してください。

Swift および Objective-C 用の Speech SDK を使用して、テキストから音声を合成することができます。

前提条件

以下のサンプルは、Azure アカウントと Speech Service サブスクリプションをお持ちであることを前提としています。 アカウントとサブスクリプションをお持ちでない場合は、Speech Service を無料でお試しください

Speech SDK とサンプルをインストールする

Cognitive Services Speech SDK には、iOS と Mac 向けに Objective-C と Swift で作成されたサンプルが含まれています。 リンクをクリックして、各サンプルのインストール手順をご覧ください。

オンラインの「Objective-C 向け Speech SDK リファレンス」もご覧いただけます。

このクイックスタートでは、Speech SDK を使用してテキスト読み上げ合成を行うための一般的な設計パターンについて説明します。 まずは基本的な構成と合成を行った後、次のようなより高度なカスタム アプリケーション開発の例に進みます。

  • インメモリ ストリームとして応答を取得する
  • 出力のサンプル レートとビット レートをカスタマイズする
  • SSML (音声合成マークアップ言語) を使用して合成要求を送信する
  • ニューラル音声を使用する

記事をスキップして GitHub 上のサンプルにアクセスする

この記事をスキップしてサンプル コードをご覧になりたい方は、GitHub 上の Python クイックスタート サンプルを参照してください。

前提条件

この記事は、Azure アカウントと Speech Service サブスクリプションをお持ちであることを前提としています。 アカウントとサブスクリプションをお持ちでない場合は、Speech Service を無料でお試しください

Speech SDK のインストール

何らかの操作を行うには、事前に Speech SDK をインストールしておく必要があります。

pip install azure-cognitiveservices-speech

macOS を使用していて、インストールの問題が発生した場合は、まず次のコマンドを実行することが必要な場合があります。

python3 -m pip install --upgrade pip

Speech SDK がインストールされたら、スクリプトの先頭に次の import ステートメントを含めます。

from azure.cognitiveservices.speech import AudioDataStream, SpeechConfig, SpeechSynthesizer, SpeechSynthesisOutputFormat
from azure.cognitiveservices.speech.audio import AudioOutputConfig

音声構成を作成する

Speech SDK を使用して Speech Service を呼び出すには、SpeechConfig を作成する必要があります。 このクラスには、音声キーとそれに関連付けられた場所/リージョン、エンドポイント、ホスト、認証トークンなど、サブスクリプションに関する情報が含まれています。

注意

音声認識、音声合成、翻訳、またはインテント認識のどれを実行するのかに関係なく、必ず構成を作成します。

SpeechConfig を初期化するには、次に示すようないくつかの方法があります。

  • サブスクリプションの場合: 音声キーと、それに関連付けられた場所/リージョンを渡します。
  • エンドポイントの場合: Speech Service エンドポイントを渡します。 音声キーまたは認証トークンは省略可能です。
  • ホストの場合: ホスト アドレスを渡します。 音声キーまたは認証トークンは省略可能です。
  • 認証トークンの場合: 認証トークンと、それに関連付けられた場所またはリージョンを渡します。

この例では、音声キーと場所/リージョンを使用して SpeechConfig を作成します。 「Speech Service を無料で試す」の手順に従って、これらの資格情報を取得します。

speech_config = SpeechConfig(subscription="<paste-your-speech-key-here>", region="<paste-your-speech-location/region-here>")

合成言語と音声を選択する

Azure Text to Speech サービスでは、250 を超える音声と 70 を超える言語とバリアントがサポートされています。 すべてのリストを入手することも、テキスト読み上げのデモでそれらを試すこともできます。 入力テキストに合わせて SpeechConfig の言語または音声を指定し、必要な音声を使用します。

# Note: if only language is set, the default voice of that language is chosen.
speech_config.speech_synthesis_language = "<your-synthesis-language>" # e.g. "de-DE"
# The voice setting will overwrite language setting.
# The voice setting will not overwrite the voice element in input SSML.
speech_config.speech_synthesis_voice_name ="<your-wanted-voice>"

音声をファイルに合成する

次に、SpeechSynthesizer オブジェクトを作成します。これにより、テキストから音声への変換と、スピーカー、ファイル、またはその他の出力ストリームへの出力が実行されます。 SpeechSynthesizer は、前の手順で作成された SpeechConfig オブジェクト、および出力結果の処理方法を指定する AudioOutputConfig オブジェクトをパラメーターとして受け取ります。

まず、filename コンストラクター パラメーターを使用して .wav ファイルに出力を自動的に書き込む AudioOutputConfig を作成します。

audio_config = AudioOutputConfig(filename="path/to/write/file.wav")

次に、speech_config オブジェクトと audio_config オブジェクトをパラメーターとして渡して SpeechSynthesizer をインスタンス化します。 このようにすれば、音声合成を実行してファイルに書き込むことが、テキスト文字列を使用して speak_text_async() を実行するのと同じぐらい簡単になります。

synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)
synthesizer.speak_text_async("A simple test to write to a file.")

このプログラムを実行すると、合成された .wav ファイルが、指定した場所に書き込まれます。 以上は最も基本的な使用方法の好例ですが、この次は、カスタム シナリオに対応できるよう、出力をカスタマイズし、出力応答をインメモリ ストリームとして処理する方法について説明します。

スピーカー出力に合成する

場合によっては、合成された音声をスピーカーに直接出力することが必要になる場合があります。 これを行うには、前のセクションの例を使用しますが、filename パラメーターを削除して AudioOutputConfig を変更し、use_default_speaker=True を設定します。 これにより、現在のアクティブな出力デバイスに対して出力が行われます。

audio_config = AudioOutputConfig(use_default_speaker=True)

結果をインメモリ ストリームとして取得する

音声アプリケーション開発の多くのシナリオでは、結果として得られたオーディオ データは、ファイルに直接書き込むのではなく、インメモリ ストリームとして必要となるケースがよくあります。 その場合、次のようなカスタム動作を構築できます。

  • 結果として得られたバイト配列を、カスタム ダウンストリーム サービス向けのシーク可能なストリームとして抽象化する。
  • 結果を他の API またはサービスと統合する。
  • オーディオ データの変更やカスタム .wav ヘッダーの記述などを行う。

この変更は、前の例から簡単に行うことができます。 まず、AudioConfig を削除します。これは、制御を高めるために、この時点から出力動作を手動で管理するからです。 次に、SpeechSynthesizer コンストラクターの AudioConfigNone を渡します。

注意

前述のスピーカー出力の例のように省略するのではなく、AudioConfigNone を渡した場合、既定ではオーディオは現在のアクティブな出力デバイスで再生されません。

今回は、結果を SpeechSynthesisResult 変数に保存します。 audio_data プロパティには、出力データの bytes オブジェクトが含まれます。 このオブジェクトを手動で操作することも、AudioDataStream クラスを使用してインメモリ ストリームを管理することもできます。 この例では、AudioDataStream コンストラクターを使用して、結果からストリームを取得します。

synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None)
result = synthesizer.speak_text_async("Getting the response as an in-memory stream.").get()
stream = AudioDataStream(result)

ここから、結果として得られた stream オブジェクトを使用して、任意のカスタム動作を実装できます。

オーディオ形式をカスタマイズする

次のセクションでは、次のようなオーディオ出力属性をカスタマイズする方法について説明します。

  • オーディオ ファイルの種類
  • サンプルレート
  • ビット深度

オーディオ形式を変更するには、SpeechConfig オブジェクトで set_speech_synthesis_output_format() 関数を使用します。 この関数には、SpeechSynthesisOutputFormat 型の enum が必要です。これは、出力形式を選択するために使用します。 使用できるオーディオ形式の一覧については、リファレンス ドキュメントを参照してください。

要件に応じて、ファイルの種類ごとにさまざまなオプションがあります。 定義上、Raw24Khz16BitMonoPcm のような未加工の形式にはオーディオ ヘッダーが含まれないことに注意してください。 未加工の形式は、ダウンストリームの実装で未加工のビットストリームをデコードできることがわかっている場合か、ビット深度、サンプル レート、チャネル数などに基づいてヘッダーを手動で作成する場合にのみ使用してください。

この例では、SpeechConfig オブジェクトに SpeechSynthesisOutputFormat を設定することにより、高忠実度の RIFF 形式 Riff24Khz16BitMonoPcm を指定します。 前のセクションの例と同様に、AudioDataStream を使用して結果のインメモリ ストリームを取得し、それをファイルに書き込みます。

speech_config.set_speech_synthesis_output_format(SpeechSynthesisOutputFormat["Riff24Khz16BitMonoPcm"])
synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None)

result = synthesizer.speak_text_async("Customizing audio output format.").get()
stream = AudioDataStream(result)
stream.save_to_wav_file("path/to/write/file.wav")

プログラムをもう一度実行すると、指定したパスに、カスタマイズされた .wav ファイルが書き込まれます。

SSML を使用して音声の特徴をカスタマイズする

音声合成マークアップ言語 (SSML) を使用すると、XML スキーマから要求を送信して、テキスト読み上げ出力のピッチ、発音、読み上げ速度、ボリュームなどを微調整することができます。 このセクションでは音声を変更する例を紹介しますが、より詳細なガイドについては、SSML の操作方法に関する記事を参照してください。

SSML を使用したカスタマイズを開始するには、音声を切り替える単純な変更を加えます。 まず、ルート プロジェクト ディレクトリに SSML 構成用の新しい XML ファイルを作成します (この例では ssml.xml)。 ルート要素は常に <speak> であり、テキストを <voice> 要素でラップすることで、name パラメーターを使用して音声を変更できます。 サポートされている ニューラル 音声の 全一覧を参照してください。

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

次に、XML ファイルを参照するように音声合成要求を変更する必要があります。 要求はほとんど同じですが、speak_text_async() 関数を使用する代わりに、speak_ssml_async() を使用します。 この関数には XML 文字列が必要なので、最初に SSML 構成を文字列として読み取ります。 ここからは、結果のオブジェクトは前の例とまったく同じです。

注意

ssml_string が文字列の先頭に  を含んでいる場合は、BOM 形式を削除する必要があります。そうしないと、サービスからエラーが返されます。 これを行うには、encoding パラメーターを次のように設定します: open("ssml.xml", "r", encoding="utf-8-sig")

synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None)

ssml_string = open("ssml.xml", "r").read()
result = synthesizer.speak_ssml_async(ssml_string).get()

stream = AudioDataStream(result)
stream.save_to_wav_file("path/to/write/file.wav")

注意

SSML を使用せずに音声を変更するには、SpeechConfig.speech_synthesis_voice_name = "en-US-ChristopherNeural" を使用して SpeechConfig のプロパティを設定します

表情イベントを取得する

スピーチは、表情のアニメーションを動かす有効な手段となる場合があります。 特定の音素を生成するときの唇、顎、舌の位置など、観察された発話における主要な姿勢を表すために、口形素がよく使用されます。 口形素イベントは、Speech SDK でサブスクライブできます。 その後、口形素イベントを適用すれば、スピーチ音声の再生に伴って、キャラクターに顔のアニメーションを付けることができます。 口形素イベントを取得する方法に関するセクションを参照してください。

このクイックスタートでは、Speech Service と cURL を使用してテキストを音声に変換する方法について学習します。

テキスト読み上げの概念の概要については、概要に関する記事を参照してください。

前提条件

この記事は、Azure アカウントと Speech Service サブスクリプションをお持ちであることを前提としています。 アカウントとサブスクリプションをお持ちでない場合は、Speech Service を無料でお試しください

テキストを音声に変換する

コマンド プロンプトで、次のコマンドを実行します。 次の値をコマンドに挿入する必要があります。

  • 音声サービスのサブスクリプション キー。
  • Speech Service のリージョン。

次の値を変更することもできます。

  • オーディオ出力形式を制御する X-Microsoft-OutputFormat ヘッダー値。 サポートされているオーディオ出力形式の一覧については、REST API リファレンスを参照してください。
  • 出力音声。 対象の Speech エンドポイントで使用可能な音声の一覧を取得するには、次のセクションを参照してください。
  • 出力ファイル。 この例では、サーバーからの応答を output.wav という名前のファイルに送信します。
curl --location --request POST 'https://INSERT_REGION_HERE.tts.speech.microsoft.com/cognitiveservices/v1' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: application/ssml+xml' \
--header 'X-Microsoft-OutputFormat: audio-16khz-128kbitrate-mono-mp3' \
--header 'User-Agent: curl' \
--data-raw '<speak version='\''1.0'\'' xml:lang='\''en-US'\''>
    <voice xml:lang='\''en-US'\'' xml:gender='\''Female'\'' name='\''en-US-JennyNeural'\''>
        my voice is my passport verify me
    </voice>
</speak>' > output.mp3

対象の Speech エンドポイントで使用可能な音声を一覧表示する

対象の Speech エンドポイントで使用可能な音声を一覧表示するには、次のコマンドを実行します。

curl --location --request GET 'https://INSERT_ENDPOINT_HERE.tts.speech.microsoft.com/cognitiveservices/voices/list' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE'

次のような応答を受け取ります。

[
    {
        "Name": "Microsoft Server Speech Text to Speech Voice (ar-EG, Hoda)",
        "DisplayName": "Hoda",
        "LocalName": "هدى",
        "ShortName": "ar-EG-Hoda",
        "Gender": "Female",
        "Locale": "ar-EG",
        "SampleRateHertz": "16000",
        "VoiceType": "Standard"
    },
    {
        "Name": "Microsoft Server Speech Text to Speech Voice (ar-SA, Naayf)",
        "DisplayName": "Naayf",
        "LocalName": "نايف",
        "ShortName": "ar-SA-Naayf",
        "Gender": "Male",
        "Locale": "ar-SA",
        "SampleRateHertz": "16000",
        "VoiceType": "Standard"
    },
    {
        "Name": "Microsoft Server Speech Text to Speech Voice (bg-BG, Ivan)",
        "DisplayName": "Ivan",
        "LocalName": "Иван",
        "ShortName": "bg-BG-Ivan",
        "Gender": "Male",
        "Locale": "bg-BG",
        "SampleRateHertz": "16000",
        "VoiceType": "Standard"
    },
    {
        // This response is truncated. The response will include 
        // a complete list of supported languages and specific 
        // details like short name, gender, etc. 
    }
]

このクイックスタートでは、Speech SDK を使用してテキスト読み上げ合成を行うための一般的な設計パターンについて説明します。 まずは基本的な構成と合成を行った後、次のようなより高度なカスタム アプリケーション開発の例に進みます。

  • インメモリ ストリームとして応答を取得する
  • 出力のサンプル レートとビット レートをカスタマイズする
  • SSML (音声合成マークアップ言語) を使用して合成要求を送信する
  • ニューラル音声を使用する

前提条件

この記事は、Azure アカウントと Speech Service サブスクリプションをお持ちであることを前提としています。 アカウントとサブスクリプションをお持ちでない場合は、Speech Service を無料でお試しください

ダウンロードしてインストールする

Windows に Speech CLI をインストールするには、次の手順に従います。

  1. Windows では、お使いのプラットフォームに対応した Microsoft Visual Studio 2019 の Visual C++ 再頒布可能パッケージが必要です。 これを初めてインストールする場合、再起動が必要になる場合があります。

  2. .NET Core 3.1 SDK をインストールします。

  3. 次のコマンドを入力して、NuGet を使用して Speech CLI をインストールします。

    dotnet tool install --global Microsoft.CognitiveServices.Speech.CLI
    

spx」と入力して、Speech CLI のヘルプを表示します。

注意

NuGet を使用せずに、Speech CLI for Windows を ZIP ファイルとしてダウンロードして展開することもできます。

フォントの制限事項

Windows の Speech CLI では、ローカル コンピューター上のコマンド プロンプトで使用できるフォントのみを表示できます。 Windows ターミナルでは、Speech CLI によって対話的に生成されるすべてのフォントがサポートされます。

ファイルに出力すると、メモ帳などのテキスト エディターや、Microsoft Edge などの Web ブラウザーでも、すべてのフォントを表示できます。

サブスクリプション構成の作成

Speech CLI の使用を開始するには、Speech サブスクリプション キーとリージョン識別子を入力する必要があります。 「Speech Service を無料で試す」の手順に従って、これらの資格情報を取得します。 サブスクリプション キーとリージョン識別子 (たとえば、 eastuswestus) を入手したら、次のコマンドを実行します。

spx config @key --set SUBSCRIPTION-KEY
spx config @region --set REGION

これで、今後の SPX 要求のためのサブスクリプション認証が格納されるようになりました。 これらの格納されている値のいずれかを削除する必要がある場合は、spx config @region --clear または spx config @key --clear を実行します。

スピーカーに音声を合成する

Speech CLI を実行して、音声をテキストに合成する準備ができました。 コマンド ラインから、Speech CLI バイナリ ファイルが含まれるディレクトリに変更します。 次に、次のコマンドを実行します。

spx synthesize --text "The speech synthesizer greets you!"

Speech CLI では、コンピューターのスピーカーを通じて、英語の自然言語を生成します。

音声をファイルに合成する

次のコマンドを実行して、スピーカーからの出力を .wav ファイルに変更します。

spx synthesize --text "The speech synthesizer greets you!" --audio output greetings.wav

Speech CLI では、greetings.wav オーディオ ファイルに英語の自然言語を生成します。 Windows では、start greetings.wav と入力すると、オーディオファイルを再生できます。

位置情報を取得する

プロジェクトでは、ある単語がテキスト読み上げによって読み上げられるタイミングに基づいて特定のアクションを実行できるように、そのタイミングを把握することが必要な場合があります。 たとえば、読み上げられた単語を強調表示するには、強調表示する内容、強調表示するタイミング、および強調表示する期間を把握する必要があります。

これは、WordBoundary 内で使用可能な SpeechSynthesizer イベントを使用して実現できます。 このイベントは、新しい音声それぞれの先頭で発生し、音声ストリーム内での時間オフセットと入力プロンプト内でのテキスト オフセットを提供します。

  • AudioOffset は、合成の開始から次の単語の開始までの間の出力オーディオの経過時間を報告します。 これは 100 ナノ秒単位 (HNS) で測定されます (10,000 HNS は 1 ミリ秒に相当します)。
  • WordOffset は、読み上げられようとしている単語の直前に、入力文字列 (元のテキストまたは SSML) の文字位置を報告します。

注意

WordBoundary イベントは、出力オーディオ データが使用可能になると発生します。これは、出力デバイスへの再生よりも高速です。 ストリームのタイミングを "リアルタイム" に適切に同期することは、呼び出し元で行う必要があります。

WordBoundary を使用する例は、GitHub のテキスト読み上げのサンプルにあります。

次のステップ