メモ置き場

個人的備忘録(物理、機械学習、プログラミング...etc)

デジタル波形について

仕事で音声処理をする機会があったので基本的な知識をまとめておく。

信号の種類

  • アナログ信号:手を叩いて実際に我々の耳に入ってくる音(連続値)
  • デジタル信号:手を叩いてマイクで集音しコンピュータ上で処理ができる音(離散値)

アナログ信号は連続値を取りますが、デジタル信号はアナログ信号をデジタル化(0と1で表す)したものであるので離散値を取ります。
波形のグラフはx軸に時間、縦軸にy幅をそれぞれ表します。
よく見るウニョウニョとした波の図です。

デジタル化

音のデジタル化は次の3つのステップを踏むようです。

  • 標本化(サップリング):時間軸の刻み幅(細かさ)を決める
  • 量子化:振幅の刻み幅を決める
  • 符号化

・参考
https://www.infraexpert.com/study/telephony2.html http://www.soraotona.net/weblog/?p=319

標本化(サンプリング、サンプリングレート)についてはこちらの説明が分かりやすいです。 http://www.aichi-c.ed.jp/contents/joho/contents/jissyuu/049/sound.files/oto.htm

以下は個人的な解釈、理解、要約です。
音の高さ(周波数)は1秒間の振動数で決まります。
振動数とは波形がx軸と交わる回数のことです。
よりx軸と多く交わっている波形の方が高い音になります。
サンプリングレートが低い場合は波形のx軸の刻み幅を大きくなってしまいます。
この場合、x軸と交わった回数を調べる精度が荒くなってしまうため、実際の信号の持つ周波数よりも低い周波数しか捉えることができなくなってしまいます。
ゆえにサンプリングレートを高くした方が高周波数の音を捉えることができ、実際の信号に近い音をデジタル化できるようです。

サンプリングレートを8kHzに設定すると1秒間に1/8000秒ごとの振幅データが得られます。
1秒の音源の場合のデータ数は8000個、2秒の場合は16000個になります。
逆にデータ数をサンプリングレートで割れば音源の再生時間が分かりますね。

サンプリング定理(Shannon-染谷の定理)によりサンプリングした音をアナログ信号に戻す場合の周波数は、サンプリングレートの0.5倍までしか復元できないようです。
8kHzでサンプリングした音をアナログ信号に復元すると4kHzになってしまいます。
なので最高周波数の2倍以上の周波数でサンプリングする必要があるようです。
(2点だけ波形の谷と山を観測できれば少なくとも1点はx軸と交わっているので、2倍以上のサンプリングをすれば良い的なロジックだったと思います。)

python上で音源の加工をする時はLibROSA(https://librosa.github.io/librosa/)というモジュールが便利です。
短時間フーリエ変換を行い簡単にスペクトログラムを得ることもできます。

音源はこちらのfanfare.wavを使用しました。 http://www.ne.jp/asahi/music/myuu/wave/wave.htm

%matplotlib inline
import matplotlib.pyplot as plt
import librosa
import librosa.display
sr = 44100
music, sr_ = librosa.load("fanfare.wav", sr=sr)
print("play time : {} [sec]".format(len(music) / sr))
librosa.display.waveplot(music, sr=sr)
  • 結果

play time : 11.679637188208616 [sec]

f:id:butch416:20190202225534p:plain

librosa.loadlibrosa.display.waveplotのsr(sampling rate)のデフォルト値が22050なので注意してください。
何も指定しない場合はsr=22050になるので波形のx軸の上限が実際の再生時間とは異なる値になってしまいます。

IPython上で音源を再生したい場合はIPython.displayを使用します。
https://musicinformationretrieval.com/ipython_audio.html

import IPython.display as ipd
ipd.Audio(music, rate=sr)