Azure Cognitive Services の 音声サービスで日本語のテキスト読み上げ（ニューラル音声の利用）

この記事は、Azure を使ってテキストの読み上げ（音声合成、Text to Speech）を行ってみた、という話です。

実装の部分については、以下に説明が書かれた「Azure Cognitive Services」の「音声サービス」の中の「テキスト読み上げ」に関し、JavaScript版の [Speech SDK](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/speech-sdk) を利用している形です。

- [Azure Cognitive Services とは - Azure Cognitive Services | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/cognitive-services/what-are-cognitive-services)
- [音声サービスとは - Azure Cognitive Services | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/overview)

そして、この後に少し補足をしますが、「ニューラル テキスト読み上げ・ニューラル音声」を使っています。

- [テキスト読み上げの概要 - 音声サービス - Azure Cognitive Services | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/text-to-speech)
- [言語サポート - 音声サービス - Azure Cognitive Services | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/language-support)

## ニューラル音声に関する補足
ここで、タイトルにも書いている「ニューラル音声」について少し補足します。

上記の「言語サポート - 音声サービス - Azure Cognitive Services | Microsoft Docs」というページの「[テキスト読み上げ](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/language-support#text-to-speech)」の項目を見ると、日本語の読み上げ設定に関して、以下の種類のものがあるようです。

- ニューラル音声の「Locale / 性別 / 音声名」
   - ja-JP / Female / ja-JP-NanamiNeural
   - ja-JP / Male / ja-JP-KeitaNeural
- 標準音声の「Locale / 性別 / 音声名」　（※ 標準音声は 2024年8月31日に廃止予定とのこと）
   - ja-JP / Female / ja-JP-Ayumi
   - ja-JP / Female / ja-JP-HarukaRUS
   - ja-JP / Male / ja-JP-Ichiro

ここで、標準音声とニューラル音声というカテゴリが出てきていますが、ニューラル音声に関しては以下のように説明されています。
![ニューラル音声の説明.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/dbe93434-d976-9834-e5fd-c5bb5a1bdeb4.jpeg)

ここで出てきた標準音声はとニューラル音声の関係ですが、ドキュメントを読んでいくと以下の記載があり、今後はニューラル音声に完全移行していく、という流れのようです。
![ニューラル音声への移行](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/61a7a663-73a1-1003-1584-71ff895dc3b2.jpeg)

## 公式サイト上でのテキスト読み上げのお試し
ここで、いったん公式サイト上の以下の部分を使って、テキスト読み上げを体験してみたいと思います。

●Text to Speech | Microsoft Azure
　https://azure.microsoft.com/ja-jp/services/cognitive-services/text-to-speech/#features
![テキスト読み上げを試せる画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/fdfd3483-c518-cddb-bdf3-7d370049882a.jpeg)

画面左の大きなテキストボックスには、読み上げ対象となる文章を入力します。
そして、画面右側の「言語」・「音声」・「読み上げ速度」・「ピッチ」の設定を変えたりなどして、「再生」ボタンを押してみてください。
このような簡単な操作を公式サイト上で、テキスト読み上げを手軽に体験することができます。

## 日本語でのテキスト読み上げ
それではここから、テキスト読み上げをプログラムで扱う準備などを進めていきます。

### Azure側の準備
まずは、以下の「Azure リソースを作成する」の部分に書かれた手順でを進めます。

●音声サービスとは - Azure Cognitive Services | Microsoft Docs
　https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/overview#create-the-azure-resource

上記の手順の補足ですが、ポータルの「ホーム」の「リソースの作成」を押した後、「音声サービス」などといったキーワードで検索すると、以下の「音声」と書かれた項目が出ています。
![Marketplace_-_Microsoft_Azure.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/3be62e61-6a80-21aa-4532-a416f20f8841.jpeg)

それを選んだ後、以下の「作成」ボタンを押してください。
![音声.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/dff336ac-84c5-00ca-4dc3-2039580c04b3.jpeg)
その後の設定は、上記の公式ドキュメントに書かれている通りです。

この後の手順で必要になる、キーなどが書かれた画面も以下に掲載しておきます。
![キーなど.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e56b99b7-f1e8-e892-01a0-c5b6be821b90.jpeg)

### プログラムを準備していく
#### JavaScript版の Speech SDK やサンプルについて
今回、Azure と連携した処理を行う部分は、JavaScript を用いて作ります。
具体的には、以下に書かれている JavaScript版の Speech SDK を利用します。

●microsoft-cognitiveservices-speech-sdk package | Microsoft Docs
　https://docs.microsoft.com/ja-jp/javascript/api/microsoft-cognitiveservices-speech-sdk/

その際、参考にするサンプルは以下に置かれたものです。

●cognitive-services-speech-sdk/samples/js/browser at master · Azure-Samples/cognitive-services-speech-sdk
　https://github.com/Azure-Samples/cognitive-services-speech-sdk/tree/master/samples/js/browser

そのサンプルの中の「[index.html](https://github.com/Azure-Samples/cognitive-services-speech-sdk/blob/master/samples/js/browser/index.html)」に関し、内容を削ったものを用意していきます。

#### HTML＋JavaScript でプログラムを作る
先に、今回作ったプログラムを掲載してみます。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <title>Azure Cognitive Services の 音声サービスでテキスト読み上げ</title>
    <meta charset="utf-8" />
</head>
<body>
    <input type="text" id="keyText">
    <input type="text" id="regionText">
    <input type="text" id="phraseText">
    <button onclick="synthesizeSpeech()">テキスト読み上げを実行</button>
    <script
        src="https://cdn.jsdelivr.net/npm/microsoft-cognitiveservices-speech-sdk@latest/distrib/browser/microsoft.cognitiveservices.speech.sdk.bundle-min.js"></script>

    <script>
        function synthesizeSpeech() {
            const keyText = document.getElementById("keyText").value,
                regionText = document.getElementById("regionText").value,
                phraseText = document.getElementById("phraseText").value;

            let speechConfig = SpeechSDK.SpeechConfig.fromSubscription(keyText, regionText);
            speechConfig.speechSynthesisLanguage = "ja-JP";
            speechConfig.speechSynthesisVoiceName = "ja-JP-NanamiNeural";

            const synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig);
            synthesizer.speakTextAsync(
                phraseText,
                function (result) {
                    console.log(result);
                    synthesizer.close();
                    synthesizer = undefined;
                }, function (err) {
                    console.log(err);
                    synthesizer.close();
                    synthesizer = undefined;
                }
            )
        }
    </script>
</body>
</html>
```

ブラウザ上に上記の内容を表示させて操作していく話は、プログラムの補足を書いた後に記載していきます。まずは、上記の JavaScript のプログラムについて、少し補足しておきます。

公式サンプルを参考に `SpeechSDK.SpeechConfig.fromSubscription()` でキーなどを設定し、そこに日本語読み上げ用の設定を加えます。サンプルでは、日本語読み上げ用の設定で標準音声が使われていたため、その部分は上にも登場していたニューラル音声の設定を行っています。具体的には以下の部分です。

```javascript
speechConfig.speechSynthesisLanguage = "ja-JP";
speechConfig.speechSynthesisVoiceName = "ja-JP-NanamiNeural";
```

その後、 `SpeechSDK.SpeechSynthesizer()` や `speakTextAsync` の部分で、テキスト読み上げを実行していきます。

この処理の流れの中で、いくつかの内容はユーザがテキストボックスで入力する形にしています。それについて、この後に説明していきます。

#### テキスト読み上げを実行する
今回作った HTMLファイルをブラウザで表示させると、以下の簡素な内容が表示されます。
左から、テキストボックスが 3つとボタン 1つが並ぶ形で、テキストボックスはデフォルトで空です。
![作った画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/5bca3d96-967e-fcbd-19e1-17e8826cc6f2.jpeg)

左の 2つのテキストボックスには、Azure上で取得できる「キー」と「場所/地域」の情報を入力してください。ここが空欄だった場合や、不正な値だった場合の処理は省いているので、その点は注意してご利用ください。

そして一番右のテキストボックスは、読み上げ対象となるテキストを入力する欄なので、内容は色々なパターンのテキストを入れて試してみてください。3つのテキストボックスに、それぞれテキストを入力した後、ボタンを押すとテキスト読み上げが実行されます。

実際に、これを動作させてみた時の様子を、いかに掲載します。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/AzureCognitiveServices?src=hash&amp;ref_src=twsrc%5Etfw">#AzureCognitiveServices</a> の 音声サービスで、ニューラル音声を使った日本語のテキスト読み上げを試しました（JavaScript版の Speech SDK を利用）。<br><br>公式サンプルの内容をがっつり削ったり、少し変更をしたりしたものを使ってます。<br>試した内容について、この後に Qiita で公開予定です。<a href="https://twitter.com/hashtag/Azure?src=hash&amp;ref_src=twsrc%5Etfw">#Azure</a> <a href="https://t.co/6nJz4IXHPZ">pic.twitter.com/6nJz4IXHPZ</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1449671804780376072?ref_src=twsrc%5Etfw">October 17, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## おわりに
今回、Azure Cognitive Services の 音声サービスで、ニューラル音声を利用した日本語のテキスト読み上げを試しました。

公式サイト上でのお試しにあったように、ピッチ等の変更もできそうですし、まだ触れてない機能がいろいろありそうなので、ドキュメントを見たり試したりなどしていければと思います。