サンプリングレート変換の段(補間編)

以前(3年前)書いた後にある程度試していた内容ではあるのですが、
前回の内容から止まっているのも中途半端な感じがあったので続きという形で書いてみます。

前回は音声データのサンプリングレートを変換するためにフーリエ変換して逆変換する方法を取りました。
これでそれらしい結果は出たものの、かける手間と云うか計算量が多くない?という印象は残ります。

という訣で、求めたい位置の前後のサンプル数個から目的の数値を推測する補間処理を使ってサンプリングレートを変換することを試してみました。
試してみた補間方法は以下の4つ。

  • ラグランジュ補間(2次)
  • スプライン補間(Catmull-Rom)
  • スプライン補間(Centripetal Catmull-Rom)
  • ランチョス補間(Lanczos-3)

正弦波と矩形波を組み合わせた512サンプルの波形(下図グレーの線)を16サンプル単位で間引き(下図黒丸)、間引いた点の間16サンプルを補間する形で比較を行ってみました。
補間する元波形と間引き後のサンプルをプロットしたグラフ


ラグランジュ補間(2次)

3つの点を通る放物線でサンプルの間を補間しようというのがこの2次ラグランジュ補間です。
下図は求めたいサンプルの前2つと後1つの点を使って補間しました。
それぞれの2点間が放物線で繋げられます。直線でつなぐよりはそれっぽい形になりますね。
ラグランジュ補間(2次)のグラフ
範囲外の点は0として計算しているので、最初の曲線は下に凸の形になっています。
また矩形波の部分が上下にはみ出る形になりますが、これは全ての補間での共通点となります。

スプライン補間(Catmull-Rom)

3次エルミート補間とも言われているらしいです。Hermiteでエルミート。
スプラインと言えばグラフィック関連でも目にしたりするものですが、その中でもいろいろ種類があるようです。
下図はWikipediaの記述曰くCatmull–Rom splineというものを使ったものです。
求めたいサンプルの前後2点と、さらにその傾きを使って補間する方法のようです。
スプライン補間(Catmull-Rom)のグラフ
ラグランジュ補間よりも前半の一致度が高い感じがします。

ちなみにゲームでも使われやすいらしいスプライン曲線にBスプライン曲線というものがあるようですが、これは指定された点を通らない曲線ができるため音声のレート変換としては不向きそうです。

スプライン補間(Centripetal Catmull-Rom)

上記Wikipediaの記事中にさらにsee alsoとあったので、こちらも試してみました。求心的Catmull-Rom。
基本は同じで、求めたいサンプルの前後2点とさらにその前後の計4点を使って補間する方法です。
スプライン補間(Centripetal Catmull-Rom)のグラフ
上のCatmullよりもやや内側を通り、Rが大きめの曲線になります。
補間に使うαというパラメータは0.5で計算しています。

ランチョス補間(Lanczos-3)

こちらはsinc関数を使った補間となります。Lanczosでランチョス。
これもWikipediaの記事を参照して……うーん?
求めたい値の前後何サンプルを参照するかでLanczos-2とか呼ばれたりするようす。
今回は前後3サンプルずつ参照したのでおそらくLanczos-3。
ランチョス補間(Lanczos-3)のグラフ
元がsin関数だけあって前半の一致度が高いですね。その分(?)後半のはみ出具合は大きいですけれども。


以上、4つの補間を試してみました。
計算の処理負荷としては、自分で組んでみた感じだとぱっと見Lanczos-3かCatmull-Romスプラインが軽そうに見えます。計測はしていません。

補間した結果は元の関数とは別物になるので、512サンプルを640サンプルに補間して、それを512サンプルに補間しなおしたりすると最初とは似ても似つかない形になりうる点は注意が必要です。
512サンプルを整数倍の1024とかにして512に戻す分には元のデータが保持されているので問題なし。

次回はこの補間を使って実際に44100Hzの音声を48000Hzに変換してみます(長くなったので分割)。→実践編へ。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です