今までずっと雰囲気でやってました。
`ScriptProcessor`や`AudioWorkletProcessor`をさわったことはあっても、そこで成されている処理自体を具体的に考えたことはなかった。
波形がどうとか、周波数がどうとか、PCMがどうとか、サンプリングレートがどうとか、フーリエ変換がどうとか、なんとなーくそれぞれの用語はわかってるつもりではいたが、線の理解にはなってなかった。
それをあらためて学び直したのがこの記事です。(間違ってたら教えてください)
音のデジタル化
- 音は空気の振動である
- 糸電話的なイメージ
- これはもちろんアナログ
- あの振動をデジタル化することで、プログラミングで音声処理できるようにする
- このデジタル化をPCM(Pulse Code Modulation)という
- PCMはデジタル化の方式のなかの1つで、他にもやり方はあるらしい
- WebAudioで扱える音声の生データもこのPCMデータ
- リニアPCMというやつらしい
PCMデータ
- デジタル化して得られた生データ
- 言わずもがなビット列
- 端的には時系列に並ぶ音量の配列
- プロットすると、いわゆる波形になる
- いつでもアナログにも戻せるし加工もできる
- 無限のリソースでデジタル化できればいいけど、そうもいかない
- 元の音声にどれだけ近づけられるかのパラメータとしては2つある
- サンプリングレート
- 量子化ビット数
- プロットするとき、X/Y軸がより細かいほうが、よりなめらかに波形を再現できる
- サンプリングレートは横軸の細かさ
- 量子化ビット数は縦軸の細かさ
- どれくらいの頻度で、どれくらいの詳細度でサンプリングするかという話
- 得られたPCMデータの配列の1つが、1つのオーディオサンプルとなる
サンプリングレート
- 標本化の回数
- 単位はHz
- 8000Hzならば、1秒に8000回サンプリングするということ
- サンプリングレートが大きいほど、より忠実に原音を再現できる
- ただし高すぎても実用的ではない
- 聴くのが人間なら、聞こえない音を保存する必要がないから
- なのでCDとかは44.1kHzに決まってる
量子化ビット数
- 量子化の程度
- 1サンプルの精度
- 各音量の値をどれだけ細かく表現できるか
- これも精度が高いほうが、より忠実に再現できる
- 16bitなら65536段階の細かさ
- WebAudioだと32bitで、値は実数になってる
- この振れ幅のことをダイナミックレンジという
波形とPCMデータ
- PCMデータをプロットしていくと波形のグラフができた
- Xは時間、Yは音量
- 波形はその形で音の性質が変わる
- 間隔の狭く高い波 = 高周波 = 高い音
- 間隔の広く低い波 = 低周波 = 低い音
- サンプリングレートが充分にある場合
- どんな間隔の狭さでも、余すこと無く再現できる
- つまり低周波から高周波まできっちり取れる
- 逆にレートが低い場合
- 低い頻度では間隔の狭い波を取りこぼすことになる
- なので低周波しかうまくデジタル化できない
- 波の動きが細かくなる高周波が削られるから
- つまりサンプリングレートが低いと、高音域が取れない
PCMと周波数成分
- PCMの波形は、あらゆる高さの周波数があわさった最終形
- あらゆる音の合算値である
- そしてPCMデータには音量の情報しかない
- 定数的に計算して返すと音量が変わる
- 定数的な計算であれば、波形のフォルムに変化はない(= 音質は変わらない)から
- 音質、つまりは周波数成分を変えるにはどうするのか
- 音質を変えるためには、一律ではないダイナミックな処理で、波形の形状を変化させる必要がある
- たとえばローパスフィルター(高周波数帯をカットして、低周波のみ残す)
- この場合、高周波の特徴である狭く高い波を、なだらかにできればよいということ
- そのために、直前の値と移動平均を取るなどすればよい
フーリエ変換
- フーリエ変換という処理を介すことで、PCMデータから周波数成分を抜き出せる
- 逆フーリエ変換で戻すこともできる
- なので周波数成分に変換してから処理をすることでも、音質は変えられる
- ただし変換コストがかかる
- 波形が表すのは、そのサンプルにおいてのあらゆる周波数の合算値なので
- そもそも8000Hzでサンプリングした音
- より高いレートでサンプリングしてから、8000Hz以上の周波数成分を削った音
- この2つは微妙に違うはず(後者で巻き添えになって削られる8000Hz以下の音があるかも)
というわけで
次はWebAudio APIを使って音声処理を実際にやってくところについて書きます。