[Docker]コンテナ内で日本語音声出力環境をOpenJTalkで用意してMacのマイクで発声するまで

- TTS(text to speech)という技術を利用すれば指定したテキストをコンピュータで発声することが可能。
- 例えばMacでは[say](https://ss64.com/osx/say.html)というコマンドを利用すれば、簡単に日本語発声が可能。
- Linuxでも様々なOSS(festival,openJTalk等)があるため容易だが、Dockerコンテナ内で従来通り準備しても正しく動作せず、別途設定が必要。
- そこで今回は、コンテナ内からMacの音声設定を利用して日本語発声させるまでの方法を記録する。

## 環境
- Mac OS 11.2.3
- Docker version 20.10.8

## 手順

### 必要ライブラリインストール
- ホストとコンテナ間での音声設定のため、ホストであるMacに以下で必要システムをインストールする。

```bash
brew update
brew install pulseaudio
```

### 必要ファイル作成

- 任意のディレクトリに以下で必要ファイルを作成する。

```bash
mkdir ~/work/ttstest; cd $_

# ttstestディレクトリ内に作成
touch Dockerfile docker-compose.yml Makefile
```

- 作成後、以下3つのファイルの中身を以下のようにする。

```Dockerfile:Dockerfile
FROM ubuntu:20.04

# 日本設定
ENV TZ Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV LANG ja_JP.UTF-8

# 必要ライブラリ導入
## 音声出力サーバー : pulseaudio
## 音声合成システム : open-jtalk関連(3つ)
## 音声ファイル再生 : sox
RUN apt-get update -yqq && \
    apt-get install -y --no-install-recommends \
    ca-certificates locales pulseaudio \
    open-jtalk open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001 \
    sox && \
    locale-gen ja_JP.UTF-8 && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

RUN echo "完了"
```

```yaml:docker-compose.yml
version: '3.7'
services:
  ttstest:
    # コンテナ指定
    build:
      context: .
    image: ttstest
    restart: always
    # サウンドサーバー環境変数にDocker for Macを指定
    environment:
      - PULSE_SERVER=docker.for.mac.localhost
    tty: true
    # ホスト側のpulse設定をコンテナへバインド
    volumes:
      - type: bind
        source: ~/.config/pulse
        target: /root/.config/pulse
```

```makefile:Makefile
setup:
	pulseaudio --load=module-native-protocol-tcp --exit-idle-time=-1 --daemon
	docker-compose build

start:
	docker-compose up -d
	docker-compose exec ttstest bash

stop:
	docker-compose down
	pulseaudio --kill
```

### サウンドサーバー機動及びイメージの構築
- 以下Makefileで定義したコマンドで、サウンドサーバーの起動及びイメージのビルドを行う。

```bash
make setup

# 完了後、サウンドサーバーの立ち上げ確認
pulseaudio --check -v 
```

- ビルド後、以下で起動してコンテナ内へ入る。

```bash
make start
```

- 上記完了後、コンテナ内へ入っていることを確認する。

### 発声確認
- これまでで日本語音声システム環境及びホストとコンテナ内の音声出力設定が完了。
- その確認として、以下のコマンドで実際に発声されることを確認する。

```bash
echo "こんにちはTODです。" |
open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic/ \
-m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice \
-r 1.0 -ow /dev/stdout |
play - 2>/dev/null
```

- 上記のコマンドの詳細な説明は以下。
  - open_jtalk : 音声合成システム
      - `-x` : システム辞書の指定
      - `-m` : 音声ファイルの指定。別途ダウンロードすることで女性も指定可。
      - `-r` : 速度指定
      - `-ow`: 出力先の指定。通常はwavファイルが作成。今回はファイルを作成しないため標準出力を指定。
  - play : 音声ファイル再生ツール。wavファイルを再生するために必要。
      - ※再生するだけなので、詳細出力は/dev/nullへ捨てている。

- テキストファイルの再生も可能なため、作成して中身を以下のようにする。

```text:sample.txt
みなさま。
おつかれさまです。
私はTODです。
よろしくお願いいたします。
```

- 以下のように改行をスペースへ置換して渡すと、テキストファイルの再生も可能。

```bash
cat sample.txt |
tr '\n' ' ' |
open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic/ \
-m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice \
-r 1.0 -ow /dev/stdout |
play - 2>/dev/null
```

- 完了後、コンテナを抜けて以下で終了及びサウンドサーバー停止を行う。

```bash
make stop

# 終了確認は「pulseaudio --check -v」で行う。
```

## まとめ
- ホストとコンテナ間でのマイク設定及び日本語音声出力システム環境が整った。
- そのため幅広い利用につながっただけでなく、socketの知見も広がった。

## 参考
- [公式](http://open-jtalk.sourceforge.net/)
- [PulseAudio](https://wiki.archlinux.jp/index.php/PulseAudio)
- [sox](http://sox.sourceforge.net/)
- https://qiita.com/Mco7777/items/18e29b98ddbc2614169b