2010-01-14

音声の均一化

どうすれば何万ファイルもある音声ファイルの音量を均一化できるだろうか。今手元にあるそれらのファイルは、録音レベル(録音環境に起因する音量レベル)がそれぞれ大きく異なる。一つのファイルに収録されているのは数秒から十数秒の一人台詞。ただ、全く録音レベルがバラバラなのではなく、近いファイル名のものは近い録音レベルであることが多い。

ピークレベルや実効値(RMS)で正規化(ノーマライズ)するという方法は使えない。例えば「ふぅ……」みたいなため息は音量が極端に小さい。これを普通の台詞の音量と揃えると、耳元で「ふぅ……」と言われてるような大きな音になってしまう。逆に普通の台詞を「ふぅ……」へ合わせたら、とても小さな遠くで喋っているような音になってしまう。

録音レベルがある程度の範囲に収まっているのであれば、コンプレッサをかけてから増幅すればおおよそ問題無く揃う。しかしそれにも限度があって、録音レベルに何倍もの開きがあるようだとコンプレッサの影響で大きい方のファイルの音質がかなり悪くなってしまう。

問題の原因は、音量の違いが録音レベルに起因するのか、それとも喋り方・喋る内容に起因するのかを判別できないところにある。あるファイルのRMS値が小さかった場合、それがその日の体調やマイクとの距離や録音機材の設定によるものなのか、それとも意図的に小さく喋ったものであるのかは容易には判別できそうもない。それなりに高度な解析が必要になると思われる。

しかし希望はある。今手元にある音声ファイルの音量は、全くランダムというわけではない。数百から千程度は一度に同じ状況で収録しているので、それらのファイルの中で大きく録音レベルが変わることはほとんど無い。

状況を確認するために、音声ファイルごとの音量(RMS)を出力するプログラムをC++で作成した。wave_rms.cppはカレントディレクトリ以下にある.wavファイルの有音部分のRMSを求め、標準出力へ出力する。

手元のファイルのうち、頭の数千をこのプログラムにかけ、結果をグラフ化したのが以下。横軸がファイル名、縦軸が音量[db]である。

音声ファイル(横)と音量(縦)のグラフ(調整前):

20100114_voice_levels.jpg

ファイル名先頭のアルファベットは喋っている人の違いと思っていただきたい。

bの人の途中からガクンと音量が上がっていることが分かる。bの後半、c、dはほぼ同じくらいの録音レベル。e、f、iになるとまた下がる。fはe、iに比べてあまり音量差が無く、それほど小さくならないことも分かる。

結局、この録音レベルが異なる領域ごとに個別の設定で音量を整えることで、均一化させることにした。

以下は調整後との比較。

音声ファイル(横)と音量(縦)のグラフ(調整後):

20100114_voice_levels2.jpg

てきとー。