HEARTalk で自然な応答システムを作る


YAHAMAが開発した自然応答技術「[HEARTalk(ハートーク)](https://www.yamaha.com/ja/news_release/2016/16051101/)」を実装した、[HEARTalk UU-001](https://www.switch-science.com/catalog/3300/) または [HEARTalk UU-002](https://www.switch-science.com/catalog/3333/)というモジュールを利用すると、簡単にいい感じの(相手の会話の韻律に合わせた)相づちを返すシステムを作ることができます。人間は、「うん」「はい」などの相づちを打つ際、相手の話し方に応じて無意識に声の高さなどを変えた返答をしているようです。それをハードウェアで実現しているのが、HEARTalk UU シリーズです。HEARTalk は会話時に[ドミナントモーション](https://www.google.co.jp/search?q=%E3%83%89%E3%83%9F%E3%83%8A%E3%83%B3%E3%83%88%E3%83%A2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3&ie=&oe=)となるようにあらかじめ登録した音声ファイルを選択して再生を行います。

HEARTalk と、既存の音声認識と組み合わせることで、相づちを返している裏で応答文を生成して、会話を滑らかに行うシステムを作ることが可能です。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">HEARTalkと音声認識を組み合わせてヒミツのクマちゃんと会話が成立した！音声合成は東北きりたん。 <a href="https://t.co/O31lXVG1b6">pic.twitter.com/O31lXVG1b6</a></p>&mdash; ミクミンP/Kazuhiro Sasao (@ksasao) <a href="https://twitter.com/ksasao/status/897068857650630656">2017年8月14日</a></blockquote>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">HEARTalkのマイクのON/OFF状態がわかるようにLEDをつけてみました。 <a href="https://t.co/77aY4UVcyd">pic.twitter.com/77aY4UVcyd</a></p>&mdash; ミクミンP/Kazuhiro Sasao (@ksasao) <a href="https://twitter.com/ksasao/status/897374767912701952">2017年8月15日</a></blockquote>

従来の音声対話システムの技術から大きく進歩した点として、話している途中に適切に相づちを打ったり、ユーザーに待たせることなく応答を返している様子がわかると思います。

以下では、音声認識と組み合わせるために必要となる、HEARTalk モジュールの制御方法について説明します。

なお、モジュールのみを利用する場合には特に電子工作は必要ありません。
詳しい使い方が下記に公開されていますので、参照してください。

- はいぬっかさん: [HEARTalk UU-001であの子とおしゃべり](http://hinzka.hatenablog.com/entry/2017/06/27/150019)


# HEARTalk モジュールのシリアル通信による状態把握
**注：販売元のWebサイトには「シリアルインターフェイス搭載」の記載がありますが、シリアルインターフェースや通信に関する仕様は本記事作成時点(2017/8/16)では公開されていません。 以下の内容は独自に解析したものとなります。仕様は今後変更される可能性があります。YAMAHAなどに問い合わせすることはご遠慮ください。また、この記事に書かれた内容をもとに製作を行う場合は自己責任でお願いします。**

HEARTalk には GPIO が搭載されており、そちらの仕様は[公開されています](http://uda.la/ht/)ので、あわせて参照してください。

## 用意するもの
- [HEARTalk UU-001](https://www.switch-science.com/catalog/3300/) または [HEARTalk UU-002](https://www.switch-science.com/catalog/3333/)  × 1
- [FTDI USBシリアル変換アダプター(5V/3.3V切り替え機能付き)](https://www.switch-science.com/catalog/1032/)  × 1
- 2ポート以上空きがあるUSB2.0または3.0ハブ × 1
- マイクロUSBケーブル × 1
- ミニUSBケーブル × 1
- 配線 少々

## 配線
１）USBシリアルの RX と HEARTalk の TX を配線します。HEARTalk は3.3Vのシリアル出力を行うため、USBシリアルのジャンパピンは3.3V側にしてください。

### HEARTalk UU-001 の場合
![uu001.jpg](https://qiita-image-store.s3.amazonaws.com/0/43450/88a493b1-08d0-2209-dec4-e1b8614fd575.jpeg)
### HEARTalk UU-002 の場合
![uu002.jpg](https://qiita-image-store.s3.amazonaws.com/0/43450/5fc9122f-f691-6c27-d0cf-e6aa3b309c64.jpeg)

写真ではジャンパ線のピンを押し付けていますが、ショートを防ぐため、HEARTalk 側は金属部分があまり露出しないようはんだ付けをしてください。

![handa.jpg](https://qiita-image-store.s3.amazonaws.com/0/43450/e47376b0-0bcc-b666-0212-d0d44a22cceb.jpeg)


２）HEARTalk UU-001 または UU-002 と FTDI USBシリアル変換アダプターをUSBケーブル経由で、同一のUSBハブに接続してください。こうすることで、それぞれのモジュールのGNDの電位がそろいます。なお、HEARTalk の電源を電池など別電源から取得する場合には、GNDの電位をそろえるため、電池のGNDとUSBシリアルのGND間も配線してください（USBハブを利用する場合は、[グランドループ](https://www.google.co.jp/search?q=%E3%82%B0%E3%83%A9%E3%83%B3%E3%83%89%E3%83%AB%E3%83%BC%E3%83%97&ie=&oe=)になってしまい、誤動作の原因となりますのでこの配線をしないでください）。

![usb.jpg](https://qiita-image-store.s3.amazonaws.com/0/43450/2fda958f-1b71-fc0a-208d-aeb440fd1f60.jpeg)

HEARTalk のデータを読み取るために必要な配線は以上です。

##  HEARTalk モジュールのデータを読み取る
上記の配線が終わったら、Tera Term などのCOMポート読み取り可能なソフトでデータが読み取れることを確認します。Tera Term の場合の設定は以下の通りです。

Setup>Terminal..>New-Line
- ReceiveをLFに変更 (今回はReceiveのみ利用)

Setup>Serial Port..
- COM: USBシリアルが接続されたポート
- Baud rate: 115200 bps
- Data: 8 bit
- Parity: none
- Stop: 1 bit
- Flow control: none

HEARTalk のマイクに話しかけると以下のような文字列を読み取ることができます。

```
 HEARTAlk Type = 0, table = 0, duration = 990
*E00 gpio g:7 p:f E00>E07>E05>E09>E04>E03>E02>E10>E08>E06>E01>E11>F00>F07>F05>F09>F04>F03>F02>F10>F08>F06>F01>F11>A00>DAC Start ..........................EDC.BA987654.3210Stop
```

```
 HEARTAlk Type = 2, table = 11, duration = 223
*C11 gpio g:7 p:f C11>C06>C04>C08>C03>C02>C01>C09>C07>C05>C00>C10>G11>G06>G04>G08>G03>G02>G01>G09>G07>G05>G00>G10>empty
```

ここで、duration は話しかけた言葉の長さを表しています。
```
*E00
``` 
などアスタリスクではじまる4文字は、HEARTalk が内部的に最初に選択した音声ファイル名(e00.wavなど)を表します。その後に続く E00>E07>E09.. などは、当該音声ファイルが設定されていなかったために代替のファイルを探していることを表します。

1つ目の例では最終的に A00 が選択され、Start のタイミングで音声発話がスタートし、Stopのタイミングで終了していることがわかります。

2つ目の例では、再生に適した音声ファイルを見つけることができず、empty を返しています。この場合には音声は出力されません。

したがって、 送られてきた文字列中に >DAC という文字列が含まれていた場合には、その前の3文字(1つ目の例ではA00)が最終的に再生された音声ファイルとなります。

# HEARTalk モジュールの音声入力を抑制する
HEARTalk モジュール以外に別途音声合成などを併用してしゃべらせる場合、HEARTalkモジュールがその音声にも反応してしまうことがあります。GPIOピンのマイク感度設定(B7,B4)を[00に設定する](http://uda.la/ht/002.htm)ことで、HEARTalkに搭載されたマイクを一時的に無効化することができますので、USBシリアルのDTRピンを利用してGPIOピン(B7,B4)を制御します。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">HEARTalkのB4, B7ピンとUSBシリアルのDTRピンをつないで、HEARTalkのマイクをソフトウエアでON/OFFできるようにした。音声合成でしゃべっている時にOFFにすることで自分の声に誤反応するのを防げるようになった。 <a href="https://t.co/Rmglu68VXq">pic.twitter.com/Rmglu68VXq</a></p>&mdash; ミクミンP/Kazuhiro Sasao (@ksasao) <a href="https://twitter.com/ksasao/status/897367406988763137">2017年8月15日</a></blockquote>

なお、C#では以下のように書くことができます。

```csharp
SerialPort port = new SerialPort("COM3");
port.BaudRate = 115200;
port.NewLine = "\n";
port.DataReceived += Port_DataReceived; // データ受信時の処理へ
port.DtrEnable = false; // true の時、HEARTalkのマイクをOFF
port.Open();

// 略

port.DtrEnable = true; // 音声合成開始
// 音声合成処理を書く
port.DtrEnable = false; // 発話が終わったら false に戻しておく

```

# 音声合成との連携
詳細はまた別途追記しますが、概要は以下の通りです。

構成図
![system.jpg](https://qiita-image-store.s3.amazonaws.com/0/43450/2b1ce5f9-9b2b-2815-7903-6c17685275cc.jpeg)

[棒読みちゃん](http://chi.usamimi.info/Program/Application/BouyomiChan/)のクリップボード監視プラグインと [VoiceroidTalkPlus](http://ch.nicovideo.jp/Wangdora/blomaga/ar126461) プラグインを利用することで、様々な言語から Voiceroid を介した音声出力が可能となります。