統計的声質変換 (3) メルケプストラムの抽出
統計的声質変換 (2) ボイスチェンジャーを作ろう(2015/2/25)の続き。
前回は音声から抽出したメルケプストラムやピッチのパラメータを直接いじることで簡単なボイスチェンジャーを作った。今回からAさんの音声をBさんの音声に変換する規則を機械学習の手法で学習する声質変換の実験をしていきたい。今回は学習データとなる音声データをダウンロードするところとメルケプストラムを抽出するところまで。
音声データのダウンロード
チュートリアルと同じようにCMU ARCTIC Databasesという公開データを使う。このデータは7名の英語話者が同じ文章を朗読した音声がついている。今回作る統計的声質変換の手法は、変換元のAさんと変換先のBさんが同じ文章を読んだ音声が必要になるのでちょうどよいデータ。英語なのが残念。日本語の音声は探したけどなかった。あとで自分の声でやってみたい。
一括ダウンロードするスクリプトは、download_cmu_arctic.shをお借りした。curlというコマンドがなかったのでインストール。Windowsの場合はCygwinについている。
ダウンロードするとFestvox用のデータがいろいろついているけど今回必要なのは各話者のwavだけ。そのためwav以外は削除して下のようなディレクトリ構造にした。
% ls wav awb/ bdl/ clb/ jmk/ ksp/ rms/ slt/ % ls wav/clb/ arctic_a0001.wav arctic_a0002.wav ...
awbなどは話者IDみたい。各話者1132文を収録しているようだ。フォーマットは16kHz、16bit、monoだった。
こんな声
clb
slt
bdl
rms
今回の実験ではチュートリアルと元論文にならって
- 女性のclbさんの声をsltさんにするモデル
- 男性のbdlさんの声をrmsさんにするモデル
の二種類を実験していきたい。今回の実験ではメルケプストラムしか変換しないので男声を女声にするのは難しいと思われる。男声と女声ではピッチ(声の高さ)がだいぶ違うので。たぶん、ピッチも変換モデルを学習すればよいと思うのであとで試してみたい。
メルケプストラムの抽出
まずは音声データからメルケプストラムを抽出する。チュートリアルではWORLDを使っているけど今回はSPTKを使った。SPTKは今までもけっこう活用していたので。SPTKを使ったメルケプストラムの抽出は下の記事を参照のこと。まあ前回のボイスチェンジャーを作ろうでも使ってたけど。
音声データからメルケプストラムを一括抽出するスクリプト。
python extract_mcep.py wav/clb mcep/clb python extract_mcep.py wav/slt mcep/slt python extract_mcep.py wav/bdl mcep/bdl python extract_mcep.py wav/rms mcep/rms
のようなコマンドを実行するとmcepディレクトリの下にメルケプストラムが保存される。あとでnumpyを使って簡単にデータを読み込めるようにテキスト形式で保存している。ファイルを開くと1行に1フレーム分のメルケプストラム係数(26次元データ)がずらずら並ぶファイル形式になっている。SPTKのmcepコマンドの-m
オプションに指定するメルケプストラム次数は25次だけど0次元目にパワーの値が入るので実際は26次元のベクトルになる。ここがずれているのに気がつかなくてはまった・・・
メルケプストラムの描画
clbさんとsltさんのメルケプストラムを比較してみたい。メルケプストラムは26次元の時系列データなので全部表示するとわかりにくくなる。というわけで0次(order=0)、1次(order=1)、2次(order=2)の値をそれぞれ描画してみよう。横軸が時間(フレーム)になる。
同じ文章(音韻)をしゃべっているため概形は似ているが、話者によって細部の形が異なることがわかる。この違いが個人の声質の違いを表すそうだ。あとしゃべる速さが違うこともあり、山のフレーム位置がずれていることがわかる。次回に紹介するDTWというアルゴリズムを使うとこのずれを補正できる。
統計的声質変換 (2) ボイスチェンジャーを作ろう
統計的声質変換 (1) ロードマップ(2015/2/11)の続き。
統計的声質変換の第二回ということでまずは統計的じゃない声質変換の枠組みで簡単なボイスチェンジャーを作ってみたい。いきなり本題とずれているけれどここをしっかり理解できていないと統計的な方はまったく歯が立たないため整理しておきたい。
ソース・フィルタモデル
人間の音声は、ノドの声帯を振動させたブザー音が声道、口、唇を通過することで出てくる仕組みになっている。これを数学的にモデル化したのがソース・フィルタモデル。
このモデルでは、音源にあたるブザー音を作り出し、ブザー音をディジタルフィルタに通すことで音声を作る。音源のパラメータとして声の高さを表すピッチ、声道のパラメータとしてメルケプストラムというのがよく使われる。メルケプストラムは音韻を表すだけでなく、個人の声質の特徴も表している。
簡単にまとめると「人間の音声からピッチとメルケプストラムというパラメータを抽出でき、そのパラメータからフィルタを用いて音声を再合成できる」ってところが非常に重要になる。最初に勉強したときはここがピンとこなくてずいぶん苦労した・・・*1。
ボイスチェンジャーを作ろう
簡単なボイスチェンジャーは、音声からメルケプストラムとピッチを抽出し、それらのパラメータに何らかの変換を施したあとに再合成することで実現できる。
上の図でmcep、pitchなどのコマンドが書いてあるが、これらはSPTKという音声信号処理のツールのコマンドを表している。SPTKを使うとパラメータの抽出や変換がコマンドの組み合わせで簡単にできる。今回はこれを使って簡単なボイスチェンジャーを実装してみた。SPTKの具体的な使い方は前に書いたことがあるので今回は触れない。
マイクから自分の声を入力し、SPTKでパラメータを抽出・変換・再合成し、スピーカーから変換した声が出てくるスクリプトを作ってみる。
このスクリプトを実行するには、PyAudioというPythonの音声ライブラリが必要。音声の録音と再生に使っている。SPTKのコマンドもパスが通ったところに置く必要がある。SPTKのインストール方法は、SPTKの使い方 (1) インストール・波形描画・音声再生(2012/7/1)を参照。あとパソコンに接続したマイクも必要。
スクリプトを起動する(-u
をつけないと出力がバッファリングされて表示されない場合があるので注意)と、*** Now recording ... (10 sec)
と出てくるので適当に10秒しゃべるとしばらくして変換された音声がスピーカーから流れるようにしてみた。
$ python -u easy_vc.py *** Now recording ... (10 sec) *** extract pitch ... *** extract mel cepstrum *** modify parameters ... *** play!
コードの下の部分はどれか1つコメントを外しておくといろいろな声が出せる。
# どれか一つしか有効にできない # modify_pitch(0.3, pitch_file, mcep_file, output_file) # modify_speed(300, pitch_file, mcep_file, output_file) # hoarse_voice(pitch_file, mcep_file, output_file) # robot_voice(100, record_seconds, mcep_file, output_file) # child_voice(pitch_file, mcep_file, output_file) deep_voice(pitch_file, mcep_file, output_file)
管理人の声で試してみた
元の音声は恥ずかしくて投稿できないので変換後の音声だけ・・・
ロボット声
太い声
子供声
えー、管理人は男です(笑)
これから実験していく統計的声質変換は先の図のパラメータ変換のところを統計的な変換モデルにした場合にあたる。具体的に言うと混合ガウスモデル。今回作ったようにピッチを上げたり、αパラメータでメルケプストラムをいじるような単純な変換ではなく、Aさんの声のメルケプストラムをBさんの声のメルケプストラムに変換するモデルを音声データから学習するというのがポイント。というわけで次回から始めたい。
実はもうほとんどできているので次の投稿は早いと思う。
統計的声質変換 (1) ロードマップ
Pythonで音声信号処理(2011/5/14)のつづき。
@r9y9さんの以下のチュートリアル記事をきっかけに興味をもった統計的声質変換の実験をしてみたい。統計的声質変換とはAさんの声を別のBさんの声に変換する技術のこと。
統計的声質変換クッソムズすぎワロタ(チュートリアル編) - LESS IS MORE
「統計的」という名前からわかるように今回対象としているのはデータに基づいた声質変換である。簡単に手順をまとめると、
- 変換元のAさんと変換先のBさんの音声データを用意する
- この音声データを学習データとしてAさんの声をBさんの声に変換する統計モデルを学習する
- Aさんの任意の音声を統計モデルに入力するとBさんの声になって出てくる
という感じ。コナンの声が毛利小五郎の声になって出てくるという例の蝶ネクタイ型マイクの背景技術である。あのマイクの中にはコナンの声を毛利小五郎の声に変換する何らかの統計モデルが含まれてるんじゃないかな?
少し混乱していたのだが、テキストを入力すると合成音が出てくるいわゆるTTS(Text-to-Speech)とは少し違う。TTSで入力するのはテキストだが、声質変換で入力するのは音声になる。そのため、TTSで必要となる自然言語処理は声質変換では行わない。純粋に音声信号処理の問題のようだ。
先のチュートリアル記事ではJulia(2015/1/13)というプログラミング言語を使っている。このプロジェクトはPythonで音声信号処理(2011/5/14)の一環としてやっているため言語はPythonを使っていきたい。
大ざっぱなロードマップを書いておこう。
ロードマップ(これ)- 統計的じゃない声質変換(音声の分析合成について)
- 音声データのダウンロード
- SPTKによるメルケプストラムの抽出と可視化
- Pythonのdtwライブラリの使い方
- パラレルデータの作成
- scikit-learnのGMMライブラリの使い方
- 声質変換モデルの学習
- GMMによるメルケプストラムの変換
- MLSAフィルタによる音声の再合成
- 音声分析合成システムWORLDの使い方
- WORLDを使った声質変換
基本的に先のチュートリアル記事をなぞる形で進める予定。声質変換の統計モデルとしてメジャーな混合ガウスモデル(GMM)を使う方法を実験してみたい。GMMは前に実装した(2010/5/21)が今回は機械学習のPythonライブラリとして有名なscikit-learnを使ってみる予定。
先のチュートリアルではWORLDという音声分析合成システムが使われているが、今回は前に使ったことがあるSPTK(2012/7/1)という音声信号処理ツールを使っていく。WORLDの方ができあがる音声の品質が優れているようだがSPTKのほうが手軽そうだったので。余力があったらSPTKとWORLDで比較してみたい。
追記(2016/2/25)
- Pythonで実装している人を見つけた。すごい情報量!⇛SunPro C89 特設ページ