はじめに
吉浦康裕スペース、楽しかったー!(配信ありがとうございます) nikkieです。
#吉浦康裕スペース めっちゃ楽しんでます!
— nikkie にっきー / アイうた円盤📀発売アドカレ中 (@ftnext) 2022年2月11日
筒井康隆さん小説は全然知らなくて、吉浦監督に限らず「こんなにアニメに影響与えてるのか」と読んでみたくなりましたー
ゲームの話も聞いてみたいです
この記事は、アイの歌声を聴かせてに関する一技術者なりのファン活動の一幕です。
実は私、大好きなアイうたに出てくる"ポンコツAI"シオンを実装しようとしています。
今回はテキストを読み上げるやり方について、これまでに分かったことを書き留めます。
これまではmacOS限定の say
コマンドで実装していましたが、機械学習モデルを使った音声合成に入門しました(レベル感としては「やってみた系」です)。
目次
- はじめに
- 目次
- 背景:技書博にシオン v0.0.1実装で技術同人誌出すぞー!
- 現在のシオン v0.0.1の実装
- 処理された文字列を読み上げる
- ttslearn:『Pythonで学ぶ音声合成』
- sounddevice
- 終わりに
- 変更履歴
背景:技書博にシオン v0.0.1実装で技術同人誌出すぞー!
放っておいたらC99通っていたけれど、書きたいものが変わっていて参加を断念した2021年末1。
大晦日に見た『魔女見習いをさがして』がめっちゃよく2、「アイうたファン活動として、2月の技書博6にアイうたの技術同人誌だそう」と決意。😤
突然明るみにして思わぬ打撃になってたら恐縮ですが、
— nikkie にっきー / アイうた円盤📀発売アドカレ中 (@ftnext) 2022年1月1日
2月の技書博、アイの歌声を聴かせてを題材にした技術同人誌書いて、参加するぞー、おー!
魔女見習いで背中押してもらい、えいやっと飛び込みます
シオン v0.0.1(期間短いので本当に小さく小さく、これから定義)をPythonで実装します https://t.co/u6Z6M6Osb2 pic.twitter.com/NtKb8l57GS
ファン活動に邁進するnikkie
sayコマンドを実行するスクリプトに、音声を入力できるように機能追加して動かせました!
— nikkie にっきー シオンv0.0.1開発中⚒ (@ftnext) 2022年1月9日
入力されたテキストをそのまま返す実装なので、「こんにちは」って言ったら「こんにちは」って言います。
動いた瞬間はプログラミングやってて今までで一番嬉しかったかもしれません #アイの歌声を聴かせて https://t.co/BSLf3YrcoV
しかし、昨今の情勢もあって技書博は中止に😢(仕方ないけれど、残念)
【重要】技術書同人誌博覧会からの #技書博6 中止のお知らせ
— 技術書同人誌博覧会 #技書博 ※技書博7:11/20(日) のサークル募集 始めました (@gishohaku) 2022年1月20日
年明けより、オミクロン株が猛威を振るい、急速にコロナ感染者数が拡大を続けております。
東京都におきましても、まん延防止等重点措置の発令が確定しました。
(1/4)#技書博
私の中での気持ちの整理として、以下に落ち着きました。
- 同人誌は無理して書かない
- ただ、いま作りたいと思っているシオン v0.0.1は3月末までに作る(目標として掲げる)
- 作りたいものを作らないと、自分が後悔する
そういうわけで、シオン v0.0.1実装中のアウトプットを(多分あと数回)お送りします。
今回は、テキストの読み上げ機能です。
現在のシオン v0.0.1の実装
上のツイートにあるように、スクリプトを実行すると以下のように動きます:
- 人が音声で入力
- 音声を文字に起こす
- 文字列を処理(今はオウム返し)
- 処理された文字列を読み上げる
例えば私が「こんにちは」と言うと、「こんにちは」と返します3。
処理された文字列を読み上げる
これまでの実装:sayコマンド
「処理された文字列を読み上げる」のはsubprocess
でsay
コマンドを呼び出して実装していました。
import subprocess def call_say_command(sentence: str): # 処理された文字列がsentenceに渡されます subprocess.run(["say", sentence])
これだとmacOSでは動きますが、他のOSでは動きません。
これを解決したく、機械学習モデルを使ってみることにしました。
上記を解決した先に、Dockerイメージとしてシオンを配布してどんな環境でも動かせたらと思うと、ワクワクしますね。
機械学習モデルを使った現在の実装
import sounddevice as sd from ttslearn.dnntts import DNNTTS dnntts_engine = DNNTTS() def play_text_audio(sentence: str): audio_array, sampling_rate = dnntts_engine.tts(sentence) sd.play(audio_array, sampling_rate) sd.wait()
テキストから音声データを作る部分はttslearn
というライブラリを使い、音声データの再生はsounddevice
を使っています。
ttslearn
:『Pythonで学ぶ音声合成』
テキストの読み上げ(Text-To-Speech:TTS)はすでに使っているsay
コマンド以外にも、クラウドベンダーが提供するAPIもあります。
ですが、シオンはスタンドアローンなので、機械学習モデルを選択しました。
TTSの機械学習モデルもWeb上に大量に情報がありますが、今回扱いたいのは日本語の読み上げです。
書名だけ知っていた『Pythonで学ぶ音声合成』が最初に当たるのにぴったりではないかと思い付き、今回参考にしました。
体系だった説明もあるため、音声の扱いの経験が全然ない身には、この本に当たってよかったです。
上記のコードは、Quick startの「DNN音声合成」そのままです。
手元で動かせたので「完全に理解した!」(←分かってない)って感じです。
音声合成の理論面のキャッチアップは長い道のりですね。
sounddevice
ttslearn
のコードはJupyter Notebookです。
音声データはNumPyのarray4で表されますが、Notebookではそれを再生するUIを埋め込んで対応しています。
シオンはNotebookではなく、Pythonスクリプトで実装したく、音声データ(NumPy array)の再生方法を調べました。
そこで見つかったのがsounddevice
です。
短いコードで使えるので好印象!
音声データを表すNumPyのarrayをsd.play
メソッドに渡すと、音声が再生されます。
続く行でsd.wait()
を呼び出すことで、音声の再生が終わるまで待ちます。
sounddevice
を知ったきっかけはRealPythonの Playing and Recording Sound in Python – Real Python です。
simpleaudio
もよさそうでしたが、こちらは2021年11月にアーカイブが宣言されていました5。
終わりに
シオン v0.0.1の読み上げ機能は、macOS以外の環境でも動作するようになりました!
『Pythonで学ぶ音声合成』、これはとてもよさそうな本です。
この本で音声合成を学んで、まだまだシオンを改良できそうです。
『Pythonで学ぶ音声合成』で素振りhttps://t.co/whqBvkxo1H
— nikkie にっきー / アイうた円盤📀発売アドカレ中 (@ftnext) 2022年2月11日
テキストを音声で読み上げさせたいんですよね
コラムが面白いですし(例:ジョジョで好きなスタンド、ななみんかわいい(乃木坂?AKB?))、
環境構築はAnaconda推奨 + pipとの使い分けも共有しつつ、ふだんAnaconda使っていない人も配慮
アイうたの劇中では、音声合成機能がサラッと出てくるのですが、手を動かした今なら分かります、この実装は相当大変ですよ!
しかもシオンの読み上げには息の音が入りますからね。
フィクションに「魔法」っぽい部分はあっていいと思うんですが、どれくらい魔法か、手を動かして思い知りました。