N.Yamazaki's blog

主に音声合成について思ったことを書いてみようと思います。
<< CentOS i386(32bit)でC++11を使う | main | サンプリング周波数変換(リサンプリング)技術 - 応用編 >>
サンプリング周波数変換(リサンプリング)技術 - 基本編

Keyword: サンプリング周波数変換、リサンプリング、サンプリングレート変換、アルゴリズム・方法

 

サンプリング周波数変換とは、オーディオデータなどのデジタル信号を、異なるサンプリング周波数の信号に変換する処理のことです。例えば、CD規格の44.1 kHzのデータをDVDの48kHzへ変換するときに使用します。

 

■原理



ここで、サンプリング周波数 fiからfoへの変換を考えます。fiとfoは単純な整数比である必要はありません。
Wikiでは、fiとfoの最小公倍数を求め、ゼロ値の内挿によるアップサンプリングを行い、LPFを通し、間引きする といった方法が示されています。しかし、以下の方法を使えば任意のサンプリング周波数にダイレクトに(ワンパスで)変換できます。

 

サンプリング周波数 fiからfoへ変換するということは、入力サンプルのfi/foおきに入力サンプルの補間値を求めることといいかえることができます。

 

ここで、
 Xn:入力信号のn番目の値
 Ym:出力信号のm番目の値
 X'(t):入力信号の時刻tの補間値(tは実数)
とすると、

formula

 

ここで、m x fi / foを、整数部(n)と小数部(dn)に分ける。

fomrmula

 

このとき、Ymは次式で求められます

formula

 

ここで、

sinc_func

 

 

upsampling

 

 

downsampling

 

 

■解説



繰り返しになりますが、サンプリング周波数 fiからfoへ変換するということは、入力サンプルのfi/foおきに入力サンプルの補間値を求めることです。

 

ただ、ここでの補間は、見かけの滑らかさとは違うことに注意が必要です。直線補間やスプライン補間などは折り返し雑音(エイリアシング)が酷くて実際には使えません。サンプリング周波数変換では式(1.1)と式(1.2)のようにsinc関数というもので補間します。

sinc関数の周波数特性は矩形特性で、カットオフ周波数がナイキスト周波数(fs/2)で急峻に減衰する理想のLPF特性です。

 

sinc関数の周波数特性

sinc_spec

 

ところで、sinc関数ってとても美しい式だと思いませんか。矩形の周波数特性の応答波形を、こんなシンプルな式で表現できます。しかも、いきなり原点が0で割るという、おちゃめな部分もあります。私がこれまでデジタル信号処理に携わってた中で一番お気に入りの関数です。

 

閑話休題。
式(1.1)と式(1.2)は、FIRデジタルフィルタの畳みこみ演算と似ています。違いはフィルタの係数列が固定ではなく、dnによって出力サンプル点毎に変化(シフト)する点です。これにより、フィルタをかけながら入力サンプル間の途中の値を求めているのです。

 

アップサンプリングとダウンサンプリングで式が異なるのは、sinc関数のカットオフ周波数(fc)を、アップサンプリングの場合は入力側のナイキスト周波数(fi/2)、ダウンサンプリングの場合は出力側のナイキスト周波数(fo/2)に合わせるためです。ダウンサンプリングの場合は、sinc関数がfiとfoの比によって横に伸長されたイメージです。

 

ここで、もうお気づきかもしれませんが、sinc関数は無限長のため、このままでは実装できません。なんらかの方法で有限長にする必要があります。

 

sinc関数はxが大きくなるにつれ振幅が次第に減少していく関数なので、適当な時点で打ち切ればよさそうですが、この部分はもう少しテクニックがあります。次回は応用編として、sinc関数を有限長にする方法について書こうと思います。

 

 

■おまけ(実践)


 

ここにWAVフォーマットのファイル in.wavがあるとします(このサンプリング周波数は任意です)。
これを、各種のコマンドプログラムで、44.1KHzのサンプリング周波数のout.wavに変換してみます。

 

FFmpegの場合
> ffmpeg -i in.wav -ar 44100 -y out.wav

 

SoXの場合
> sox in.wav -D out.wav rate 44100

 

AqResampleの場合
> AqResampleCmd in.wav 44100 out.wav

 

なお、最近のFFmpegはSoXのリサンプリングエンジンlibsoxrを内包しています。
以下のように"-af aresample=resampler=soxr"を指定することでlibsoxrを使用できます。

 

> ffmpeg -i in.wav  -af aresample=resampler=soxr -ar 44100 out.wav

 

基本的に、各プログラムの変換結果の違いは、使用している補間の関数(フィルタ係数)の違いとなります。


■リンク


 

| 音声合成一般 | 11:44 | - | - |
PROFILE
Follow
CATEGORIES
LATEST ENTRIES
SEARCH THIS SITE