Pythonでお手軽音声処理(2) サンプリング周波数の話

シェアする

  • このエントリーをはてなブックマークに追加

こんにちは。ふるやん(@furuya1223)です。

Python音声処理シリーズ第2弾です。

前回は、音声ファイルの入出力と簡単なデータ加工を行いました。

今回は、サンプリング周波数についての解説と実験をしてみます。

前回載せ忘れていましたが、C言語で音声処理を行うこちらの書籍は、音声ファイルの扱い方や信号処理理論に関する解説がたくさん書かれており、プログラム例もあるのでオススメです。

私が所属する研究室の最初のゼミでも使用しました。

長々と読みたくない人のためのまとめ

サンプリング周波数「1秒あたりいくつデータがあるか」のこと。単位は Hz。

音声データの長さをサンプリング周波数で割ると音声の長さ(秒)が分かる。

多くの音声データは符号付き16bit整数で表される。つまり、-32768〜32767 の範囲の値で表される。

コンピュータで扱う音声は、サンプリング周波数の半分の周波数より高い音声を表現できない。この事実を「サンプリング定理」という。

「サンプリング周波数の半分の周波数」を「ナイキスト周波数」という。

人間の聞こえる音の高さは20kHz程度が限界と言われるので、その倍程度の 44.1kHz がサンプリング周波数としてよく利用される。

サンプリング周波数として多いのは 48kHz、44.1kHz、16kHz、8kHz ぐらい。

サンプリング周波数とは

現実世界で聞こえる音声は、連続的な波ですが、コンピュータでは離散的な値しか扱えません。

そのため、音声データは現実世界の音声を離散化したものになります。

音声の離散化には2つの処理があります。

時間に対する離散化

音の波は常に変化しますが、コンピュータでは全ての時刻における波の値を持つことができません。そんなことをするとデータ量が無限大になってしまいます。

そのため、一定時間ごとの波の値を記録します。この処理を「サンプリング(標本化)」といいます。

この時間間隔を「サンプリング周期」といいます。単位は 秒 です。
サンプリング周期の逆数を「サンプリング周波数」といいます。単位は Hz です。

サンプリング周波数が16000Hz (16kHz) のとき、音声データは「1/16000秒ごとの値」を表します。

したがって、3秒の音声を16kHzのサンプリング周波数でサンプリングすれば、データの長さは 16000×3=48000 となります。

逆に、データ長が48000であれば、音声の長さは 48000/16000=3秒 となります。

サンプリング周波数の値は、scipy.io.wavfile.read() の出力で得られます。

rate, data = scipy.io.wavfile.read('sample.wav') と書いたときに、rate に入るのがサンプリング周波数の値です。

音声を読み込み、サンプリング周波数を半分に変えて保存してみると、次のように変化します。

原音声

サンプリング周波数を半分にしたもの

1/2倍速で再生したようになっていますね。その通りの処理です。サンプリング周期が2倍になったので、時間方向に2倍に引き延ばされたのです。

サンプリング周波数だけを変更すると、1秒あたりのデータ数が変化するので、音声の長さが変化します。

音を変えずにサンプリング周波数を変えたい場合(ダウンサンプリングやアップサンプリングと呼ばれる処理)は少し工夫しないといけません。(いずれ触れると思います)

サンプリング周波数を変化させるプログラムはこちら(GitHub)です。

値に対する離散化

音声波形のある一瞬の値は、本来は連続値ですが、コンピュータで扱うために飛び飛びの値にします。

これを「量子化」といいます。

身長を測るときに、「173.6cm」と測定されても、実際にはもっと細かい桁(小数第二位、第三位……)がありますよね。でも、測定器の精度や記述欄の問題から、桁数が制限された近似値になっています。これと同じです。

多くの場合、65536段階(=2^16段階)に量子化されます。このとき、音声データは符号付き16bit整数で表されます。

まあこんだけ細かく表現したら大丈夫でしょ、という雰囲気ですかね。

サンプル音声のビットレートを16bitから8bitに変更してみました。

原音声(ビットレート16bit)

ビットレート8bit

ものすごく違いが分かりにくいですが、よーく聞くと、8bitの方には「サー」というようなノイズが乗っているように聞こえる気がします。

もっと極端に、8bitのまま解像度を1/4に変えた(256段階から64段階に変えた)音声を用意しました。

音質がかなり悪いですね。

ビットレートを変更するプログラムはこちら(GitHub)です。

サンプリング定理

連続時間の波を飛び飛びの時刻でサンプリングすると、ある周波数より高い波を表現できなくなってしまいます

「ある周波数」とは、「サンプリング周波数の半分の周波数」になります。この周波数を「ナイキスト周波数」といいます。(ナイキスト:Nyquist は人名です)

例えば、サンプリング周波数が16kHzのときは、ナイキスト周波数は8kHzになります。16kHzサンプリングの音声は8kHzより高い音を含むことができません。

人間の聞こえる音の高さ(可聴域)20Hz~20kHz 程度と言われているので、これらの音さえ含められれば十分と考えられます。

そのため、音楽ではサンプリング周波数は 44.1kHz が多く利用されます。このとき、22.05Hz の音まで含められます。なんでこんな中途半端な値なのかは知りません。なぜでしょう。

ちょっと良い音声だと、48kHzサンプリングのものもあります。キリが良い。

音声処理では、16kHzサンプリングなども用いられます。データサイズが小さい方が良いのでね。

電話では、伝送時間のことを考えて、8kHzサンプリングが用いられたりするそうです。この場合、4kHzの音までしか表現できませんが、発話を聞き取るには十分ということでしょう。

最近では、ハイレゾ音声といって、192kHzサンプリングなどの高サンプリングレートの音声も見かけますね。「可聴域外の音が含まれているかどうかが感覚に影響を与えるらしい」とか「可聴域内の音についての精度も上がる」という理由で、完全に無駄というわけではないようです。私は詳しくないですが。

サンプリング定理のふわっとした解説

時間的に飛び飛びの信号で波を表現すると、こんな感じになります。

灰色の点線は、サンプリングするタイミングを表しています。

点線の間隔はサンプリング周期(=サンプリング周波数の逆数)です。

丸の高さが波の値を表しています。

限界まで細かい波を表現したい場合はどうなるでしょうか。たぶんこうなると思います。

めっちゃ細かい。波っぽくない気もするけど、波です。

これより細かい波は作れなさそうですよね。作れません。

この波は、1周期(山から山まで)が2サンプルになっています。

つまり、周期は 2×サンプリング周期 = 2×1/サンプリング周波数(秒) となります。

したがって、周波数はその逆数の サンプリング周波数/2 (Hz) になります。これがナイキスト周波数です。

まとめ

冒頭に載せているのでそっち見てください(適当)

次回は音声波形の表示をしようと思います。

やっぱり可視化するのは大事ですからね。

スポンサーリンク
レクタングル(大)
レクタングル(大)

シェアする

  • このエントリーをはてなブックマークに追加

フォローする