設備の異常も“声”で伝える、ラズパイによる音声アラート導入事例

Raspberry Pi でTTS(Text To Speech)を使えば、テキストから自然な発話で喋らせることができます。特に固定の短文であれば、Raspberry Piの性能でもほぼリアルタイムで再生ができます。

様々なシチュエーションで利用できますが、産業用途では工場の現場など、センサーを利用している環境に有効的な手段です。
センサーからの異常や機器のシステムイベントを受け取り、アラートを生成後、TTSにより音声で通知ができます。

既存のシステムに組み込まなくても、TTSを実装したRaspberry PiにAPIなどで連携させれば、音声通知や簡易的な制御を担わせることできます。
今回は、産業用ラズパイ「PL-R5m」のRaspberry Pi OS bookwormで使える音声合成ソフトをコード例と共にご紹介します。

音声出力

産業用ラズパイ「PL-R5M」は音声出力端子は搭載していません。Raspberry Pi 5も同様で、3.5mmステレオジャックは省かれているため、音声を出力するには、HDMIモニターに搭載されたスピーカーに頼ることになります。
モニターに接続しない環境では音が鳴りません。その場合はUSB接続のスピーカーを使いましょう。

音声出力を確かめるのに便利なコマンド:

# USB接続デバイスを調べる
lsusb
# デバイス番号を調べる
aplay -l
# Audioの出力先を調べる
sudo raspi-config
# サンプルサウンド再生
aplay /usr/share/sounds/alsa/Front_Center.wav

今回はPL-R5Mに接続したモニターのスピーカーから出力させています。

Open JTalk

Open JTalkは、Raspberry Pi で使う音声合成として、少ないメモリーでも軽快に動作します。
インストールもaptコマンドなので簡単です。

インストールするのは3つ。

  • open-jtalk –> 本体
  • open-jtalk-mecab-naist-jdic –> 辞書データ
  • hts-voice-nitech-jp-atr503-m001 –> 音響モデル
sudo apt update
sudo apt install open-jtalk open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001

docker、homebrew、node.js、.NETなどのパッケージマネージャーに対応しています。

コマンドで実行

Open JTalkはコマンドで実行できます。ターミナル画面で以下をコピペで実行してエラーがないか確認します。

echo "おはようございます" | 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 \
  -ow out.wav
aplay out.wav
  • オプション -xは辞書ファイルへのパス
  • オプション-m は利用する音声モデル
  • オプション-ow は出力WAVファイル名

echoに書いた短文が瞬時にスピーカーから聞こえれば成功です。

コマンド+短文で実行

毎回コマンドで引数オプションを指定するより、シェルスクリプトにして実行した方が便利ですよね。
仮に下記コードをjvoice-m.shと保存して、shファイルがある同ディレクトリでsh jvoice-m.sh "こんにちは"と実行してみてください。

#!/bin/sh
TMP=/tmp/jsay.wav
echo "$1" | open_jtalk \
-m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice \
-x /var/lib/mecab/dic/open-jtalk/naist-jdic \
-ow $TMP && \
aplay -q $TMP
rm -f $TMP

実行権限を付与すれば、更に短くなります。

chmod +x jvoice-m.sh
./jvoice-m.sh おはようございます

予めテキストに収めた文章を喋らせる(シェルスクリプト)

次に、短文より少し長い文章を読ませるなら、テキストファイルに保存して読み込ませます。
文章が長いと再生までタイムラグが出ますので注意してください。

例として、Wikipediaの引用を2行分試してみると、Pi 5やCM5と同等の「PL-R5m」の性能だと約1秒後ほどで再生されました。

Open JTalk は名古屋工業大学にて開発された、日本語を対象とするテキスト音声合成ソフトウェアである。
オープンソースで公開されているスタンドアロン版と、Webサイトで公開されているオンライン版の2種類がある。
引用:https://ja.wikipedia.org/wiki/Open_JTalk

シェルスクリプトの内容:

#!/bin/sh
WAV=~/jvoice.wav
TXT=~/voice_text.txt
echo "$1" | open_jtalk \
-m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice \
-x /var/lib/mecab/dic/open-jtalk/naist-jdic \
-ow $WAV $TXT && \
aplay -q $WAV

このコードでは、先程のようにテンポラリファイルで生成させてから削除していません。
ホームディレクトリにjvoice.wavと生成され、そのまま残されています。

女性メイ(mei)の音声を追加

女性の声も追加しておきます。ver.1.8です。
Raspberry Pi 環境下だと、zipファイルから取り出したディレクトリを指定のディレクトリに配置します。

wget http://downloads.sourceforge.net/project/mmdagent/MMDAgent_Example/MMDAgent_Example-1.8/MMDAgent_Example-1.8.zip

解凍後、/usr/share/hts-voice/内へ移動させます。

unzip MMDAgent_Example-1.8.zip
sudo cp -R ./MMDAgent_Example-1.8/Voice/mei /usr/share/hts-voice/

先程の男性音声とコードは同じでも、-mの引数であるパスを変更して試してます。(4行目)
/usr/share/hts-voice/mei/

#!/bin/sh
TMP=/tmp/jsay.wav
echo "$1" | open_jtalk \
-m /usr/share/hts-voice/mei/mei_normal.htsvoice \
-x /var/lib/mecab/dic/open-jtalk/naist-jdic \
-ow $TMP && \
aplay -q $TMP
rm -f $TMP

ダウンロードした音声ファイル「メイ」は感情別に5つのスタイルがあります。

mei_angry.htsvoice(怒り)
mei_happy.htsvoice(幸せ)
mei_sad.htsvoice(悲しい)
mei_bashful.htsvoice(はにかみ)
mei_normal.htsvoice(普通)

他にも女性音声のtohoku-f01もどうぞ。同じように/usr/share/hts-voice/へコピーすれば使えます。
tohoku-f01:https://github.com/icn-lab/htsvoice-tohoku-f01

Open JTalkをPythonで実行

次はPythonコードで実行するサンプルコードです。python3 test_openjtalk.pyとして保存しました。

subprocessで使う例:

import subprocess

# 入力テキスト
text = "こんにちは。ラズパイダからのお知らせです。"

# ファイルにテキストを書き込む
with open("input.txt", "w", encoding="utf-8") as f:
    f.write(text)

# Open JTalk のコマンド実行
# -m で声質ファイル (HTS Voice)、-x で辞書を指定
subprocess.run([
    "open_jtalk",
    "-x", "/var/lib/mecab/dic/open-jtalk/naist-jdic",
    "-m", "/usr/share/hts-voice/mei/mei_normal.htsvoice",
    "-ow", "output.wav",
    "input.txt"
])

# 再生(aplayコマンド利用)
subprocess.run(["aplay", "output.wav"])

subprocessで使うと軽いためすぐに再生されます。
短文の通知目的であれば、subprocessを使ったaplayでの再生が適しています。必要にして十分です。

VOICEVOX

商用利用も可能な無料ソフト「VOICEVOX」も優秀な音声合成ソフトす。
Raspberry Pi で使いなら、製品版とは別のOSS版VOICEVOXをインストールできます。

但し、Raspberry Piではarm64版のバイナリをそのままダウンロードしても、依存関係エラーで上手くいきません。
Dockerで使用すればエラー無く動作します。
API経由で利用する形式なので、通知用としてむしろ都合が良いでしょう。

Raspberry PiでVOICEVOXをインストールして使用するには、dockerをインストール後、docker-compose.yamlファイルを用意してcompose upするだけです。(~/VOICEVOX を作成して実行しました)

Dockerのインストール:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

# ルートレス化(管理者権限(sudo)付与せずにユーザーで実行できるようにする)
sudo apt install -y uidmap
dockerd-rootless-setuptool.sh install

docker-compose.yaml:

services:
  voicevox:
    image: voicevox/voicevox_engine:cpu-arm64-latest
    container_name: voicevox
    ports:
      - "50021:50021"
    volumes:
      - ./voicevox_data:/workspace
    restart: unless-stopped

コンテナの起動:

docker compose up -d

指定したポート番号でアクセスすると(http://localhost:50021/docs)、Swagger UIで表示され、REST APIで使えます。

今回は次のようなPythonコードで設定し実行しました。
Raspberry Pi OSのデフォルト(標準)では、requestsモジュールが入っていませんので、やはりpipでインストールしておきます。pip3 install requests

VOICEVOX Pythonコード例:

import requests
import subprocess
import os

VOICEVOX_URL = "http://localhost:50021"

text = "温度異常検知!設備を確認してください。"

# 1. audio_query
res = requests.post(f"{VOICEVOX_URL}/audio_query",
                    params={"text": text, "speaker": 14, "style_id": 0})
res.raise_for_status()
audio_query = res.json()

# 2. synthesis
res2 = requests.post(f"{VOICEVOX_URL}/synthesis",
                     params={"speaker": 14, "style_id": 0},
                     json=audio_query)
res2.raise_for_status()

wavfile = "voicevox_output.wav"
with open(wavfile, "wb") as f:  # バイナリ書き込み
    f.write(res2.content)

# 3. 音声再生
subprocess.run(["aplay", wavfile])
os.remove(wavfile)

このコードでは、話者(speakers)は、audio_queryの”speaker”と”style_id”パラメータで指定できます。synthesisにも全く同じパラメータで指定してください。

VOICEVOXの音声の種類は39種類ありました。

Speakersリスト:

実行すると、2〜3秒後に生成されたWAVが再生されました。
OpenJTalkと同じように、subprocessのaplayで再生させています。
VOICEVOXの方が音質が良いこともあって、生成するのにやや時間がかかります。リアルタイム制は僅かに劣りますが、OpenJTalkより自然な発話に聞こえます。

商用利用が可能なVOICEPEAK

商用利用も可能なAI音声合成ソフトといえば、パッケージ製品の「VOICEPEAK」は有名です。この音声を使ったYoutube動画は当たり前に聞くようになりました。

実はRaspberry Pi 4にも対応しています。
ただ、こちらの場合、CLI(コマンドライン)に対応していないため、プログラムに組み込んでは使えません。
音声ファイルとして保存はできますので、予め作成したWAVファイルを使うならプログラムで呼び出せます。

対応OS:
Windows 11/10 またはそれ以降 (64bit)
macOS 10.13 またはそれ以降
Ubuntu 20.04 またはそれ以降 (64bit)
Raspberry Pi (モデル:Raspberry Pi 4 / OS:Raspberry Pi OS (64-bit))

プログラムから呼び出せないので、Raspberry Pi で使うメリットは少ないです。

Raspberry PiならOpen JTalk

結局、Raspberry Piの性能だと、Open JTalkが最適でした。CLIはもちろんのこと、Pythonコードでもsubprocesss+aplayだけなら速く簡単です。
シェルスクリプトやPythonで呼び出してもPi 5、CM5系なら遅延はほぼありません。
aptパッケージでインストールできるのも最適な理由の1つです。

WEB APIと連携すれば、通知用に喋らせるTTS(Text To Speech)として実用的です。
Open JTalkは2018年末から更新されていませんが安定しています。是非一度試して欲しいですね。

VOICEVOXも話者の声が選べるのは、状況に応じて変更できて重宝します。(声色はビジネス用としては可愛らしい過ぎますが・・・)


記事寄稿:ラズパイダ

非エンジニアでも楽しく扱えるRaspberry Pi 情報サイト raspida.com を運営。ラズベリーパイに長年触れた経験をもとに、ラズベリーパイを知る人にも、これから始めたいと興味を持つ人にも参考になる情報・トピックを数多く発信。PiLinkのサイトへは産業用ラズベリーパイについて技術ブログ記事を寄稿。