N.Yamazaki's blog

主に音声合成について思ったことを書いてみようと思います。
<< サンプリング周波数変換(リサンプリング)技術 - 基本編 | main | ESP32で音声合成(AquesTalk pico for ESP32) >>
サンプリング周波数変換(リサンプリング)技術 - 応用編

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

 

前記事(基本編)では、sinc関数を使ったサンプリング周波数の変換方法を紹介しました。
ただ、sinc関数は無限長(時間軸上で-∞から∞までの長さ)のため、そのままでは実装できません。今回は、これを有限長にする時のいくつかのテクニックを紹介します。


 

■sinc関数に窓関数をかけて有限長にする


sinc関数は、xが大きくなるにつれて次第に振幅が小さくなる関数なので、まずは適当な長さで打ち切った場合を考えてみます。

 

図1は打ち切る長さ(LW)を128、32、8と変えたときの周波数特性です。

長さを短くするほど、sinc関数の本来の周波数特性(理想のLPF)からずれていきます。遷移域(通過域から阻止域に向かう途中の徐々に減衰する部分)は短くするほど広くなり、阻止域の大きさは、短くするほど大きくなっているのがわかります。

 

図1 打ち切り長さによるsinc関数の特性の変化

 

阻止域の大きさ(サイドローブのゲイン)が大きいと、アップサンプリングの場合はナイキスト周波数で折り返した位置にエイリアシング(折り返し雑音)が現れます。ダウンサンプリングの場合は阻止域にあった信号が変換後に帯域内にエイリアシングとして出現します。これらのエイリアシングを少なくするためには、阻止域のゲインを小さくする必要があります。

 

遷移域の幅が大きいとナイキスト周波数付近の信号成分によるエイリアシングが現れます。通常、これは阻止域のより大きなエイリアシングが現れるので注意が必要です。このエイリアシングを少なくするためには、遷移域の幅を狭くする必要があります。

 

リサンプリング処理は上記2つのポイントを考慮して設計します。この2つを同時に満たすには窓長を長くします。ほかに方法はありません。しかし、窓長を長くすると、処理量の増加、遅延、プリエコーという問題が生じます。これについては後述します。

 

ところで、固定の長さでsinc関数を打ち切るというのは、sinc関数に矩形の窓関数をかけることと等価です。

矩形窓の代わりにブラックマン窓をかけた場合は図2のようになります。矩形窓と比べると、阻止域のゲインがより小さく、遷移域の幅はより広くなっていることが分かります。

このように窓関数によって特性のバランスを変えることができます。

 


図2. ブラックマン窓をかけた場合

 


■窓関数の選び方


世の中には多種の窓関数があります。Wikiの窓関数の説明では20種類以上の窓関数が示されています。なぜこんなにたくさんの種類があるのでしょうか。


窓関数には、阻止域のゲインは大きいけれど遷移幅は狭い、あるいは、阻止域のゲインは小さいけど遷移幅は広いなどがあり、いずれの窓関数もそれぞれ一長一短で、また、その周波数特性のカーブも微妙に異なります。
そのため、サンプリング周波数変換においては入力信号の特性や変換に要求される精度によって窓関数を選択することがあります。

 

例えば、入力信号に高域(ナイキスト周波数付近)の信号成分が多く重要視される場合は、阻止域が大きくても遷移域が狭いものが望ましく、24bitデータなど全帯域のエイリアシングを少なくする場合はその逆の阻止域のゲインが小さい窓関数を選択します。

 

また、阻止域のゲインも窓関数に応じて傾きが異なるため、これも選択の基準にすることもあります。

 

表1. 代表的な窓関数の遷移域幅と阻止域ゲイン
窓の種類 阻止域の大きさ 遷移域の幅
矩形         -13db 1(これを基準)
Hanning         -32db  2
Hamming         -41db  2
Kaiser         -46db(β=6.3) 2.2

 

 

■fcを下げる


リサンプリング処理は、遮断周波数(fc)をナイキスト周波数としたLPFフィルタリングと考えることができます。
そこで、fcをナイキスト周波数よりわずかに下げて遷移域を全体的に低域側にずらせば、遷移域のエイリアシングを少なくすることができます。


    sinc(x) ⇒ sinc(rx)  r:ナイキスト周波数に対するfcの割合

 

図3. fcを90%にしたときの周波数特性


デメリットは、ナイキスト周波数付近の信号レベルが小さくなります。例えば、fcを90%にした場合、fi48K fc24k*0.9=21.6KHz 21.6KHzの信号ゲインが3db小さくなります。

 

このテクニックは、入力ソースの信号にナイキスト周波数付近の信号成分が小さかったり無視できる場合に有効です。もっとも、この帯域を無視できるのであれば、それ以上高い周波数の折り返し雑音があっても無視してよいのではという考え方もできますが...。

 


■最小位相化


エイリアシングを少なくするには窓長を長くする必要がありますが、窓長を長くすると今度は遅延やプリエコーの問題が生じます。

 

遅延は通信や放送などのリアルタイムの変換が求められるときに問題となります。窓関数の長さをtwとすると、時刻tの変換値を得るには入力のt+tw/2までの値を使います。したがって、理論上tw/2(窓長の半分)の時間の遅延が生じ、窓長が長いほどその影響が大きくなります。

 

プリエコーとは、遅延と同様に、時刻tの変換値は入力のt+tw/2までの値を使うため、未来の信号の影響が先立って現れる現象をいいます。特に無音の後にアタックの強い信号が来るときに目立ちます。これも窓長が長いほど影響が大きくなり、例えば、窓長が4msのリサンプル処理にパルス状の信号を与えた場合、その2ms前から振幅が始まります。

 

この遅延やプリエコーは、"最小位相化"によって(理論上)なくすことができます。
これまで示した窓かけsinc関数は、すべて左右対称の時間波形です。これは線形位相(またはリニア位相)と呼ばれ、フーリエ変換したときの位相がすべて0になります。
これに対して、最小位相は時間波形では時刻0を中心に片側だけの波形となります。これは因果的な応答特性です。これにより時刻tの変換値を過去の入力値だけから求めることができ、遅延やプリエコーが無くなります。

 


図4.線形位相と最小位相化の時間特性


最小位相化は、窓かけsinc関数をケプストラムに変換後、時系列の片側を0で埋め、元の時間領域に戻すことで得られます。最小位相化を行っても周波数の振幅特性は変わりません。変化するのは位相だけです。

 

ちなみに、すべての位相がゼロなのが最小位相ではなく線形位相というのはややこしいですね。最小位相は本来は群遅延が最小という意味です。

 

リサンプリングにおける線形位相と最小位相の特徴をまとめると次のようになります。

 

●ゼロ位相:左右対称
・変換後の位相が変化しない
・遅延やプリエコーがある


●最小位相:片側のみ
・原理的な遅延が無い
・位相が変化する(波形の形が変化する)
・ゼロ位相より窓長を短くできる


SoXは、オプションの指定で最小位相を用いることができます。SoXのサイトには、オプション毎のさまざまな窓長や位相のサンプルが示されています。このなかで、-vsM -vM -vMa オプションが最小位相です。

 


■各種リサンプラーの実際のパラメータ


各リサンプラーで、44.1KHz⇒96KHzにリサンプリングするときのパラメータを調べてみました。

 

表2.各種Resamplerの分析パラメータ例
窓長 窓の種類 fc     処理量(参考値)
FFmpeg 32 Kaiser(beta=9) 1.0 1(これを基準)
SoX  156 Kaiser(beta=14) 0.96 2.6
AqResample  16 一般化ハミング  1.0 0.5

 

測定条件:

  • オプションは指定せずデフォルトでの値、
  • 窓長は入力サンプリング周期を1とした時の長さ、
  • fcはナイキスト周波数に対する比、
  • 処理量はWindows PC (CPU:Intel Haswell) で実データを変換したときの処理時間の実測(FFmpegを1に正規化)

 

処理量については、それぞれSIMDを使うなどの高速化を行っているため、動作環境によって大きく変わります。また、サンプリング周波数比によっても大きく変わり、特にSoXは比が大きい場合、急激に処理量が増える傾向があるようです。あくまでPC環境での目安にしてください。

 

インパルスレスポンスから求めたそれぞれの周波数特性は図5のようになりました(44.1KHz⇒96KHz)。

 

図5. FFmeg/SoX/AqResampleの周波数特性

SoXは遷移域の幅が狭く、ナイキスト周波数以下に収まっています。これによりナイキスト周波数付近のエイリアシングは無く理想LPFに近いことが分かります。阻止域の大きさはFFmpegより大きくなっています。窓長が長いのにこれはちょっと不思議な結果です。スイープ音を変換した場合はエイリアシングの抑制が-100db以上あったので、インパルス応答を用いた測定が適当でないのかもしれません。AqResampleは、窓長が短いため、遷移域の幅が広く、折り返し雑音がかなり目立ちます。FFmpegはその中間の特性です。

 

 

■最後に


ここまで、サンプリング周波数変換の特性について書いてきましたが、最終的なパラメータ等の選定基準は、実際に聴いてみて判断することが大切です。

 

今回3種類のResamplerを取り上げましたが、各々で変換したオーディオデータを実際に聴き比べてほしいと思います。Windows版 AqResampleは組み込み用のため処理量を優先し窓長をぎりぎりまで短くしています。数値上の特性では品質の劣化が激しそうですが、実際に聴取したらどう感じるでしょうか。

 

驚いたことに、高精度な処理でエイリアシングをなくしたものより、エイリアシングが残っているほうが、きらびやかでよりリアルに聞こえるなどという高評価が得られたことがありました。

数値だけを追い求め、人間が知覚できないレベルの品質にこだわったり、それを喧伝することについて、もっと考えるべきだと思います。
 

 

■おまけ - FFmpegの使い方(いろいろなオプション)


FFmpegでサンプリング周波数変換をするときの各種パラメータの指定方法です。

 

●窓長を指定
 filter_sizeに窓長を指定します。

>ffmpeg -i in.wav -af aresample=filter_size=64 -ar 48000 out.wav

 

●カットオフ周波数(fc)の指定
 resample_cutoffにカットオフ周波数を指定します。値は出力側のナイキスト周波数に対する比率です。

 下の例では、fc=48K/2*0.9=21.6KHzとなります。

>ffmpeg -i in.wav -af aresample=resample_cutoff=0.9 -ar 48000 out.wav

 

●Kaiser窓のβパラメータを指定
 kaiser_betaにβ値を指定します(2-16の間)。
 なお、βを変更すると窓長も変化するようです。このあたりの挙動は未確認です。

>ffmpeg -i in.wav -af aresample=kaiser_beta=12 -ar 48000 out.wav

 

●FFmpegでSoXと同等の変換を行うときの指定(44.1KHz->48KHzの場合)
 なお、以下は44.1KHz->48KHzの場合となります。
 fcは出力側のサンプリング周波数に合わせます fc=0.96*44.1/48=0.882
 また、複数のパラメータは':'で区切って指定します

>ffmpeg -i in.wav -af aresample=filter_size=156:resample_cutoff=0.882 -ar 48000 out.wav

 

●FFmpegでSoXのリサンプルエンジン(soxr)を使うときの指定
 resampler=soxr を指定します。

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

 

 

■LINK


| 音声合成一般 | 15:32 | - | - |
PROFILE
Follow
CATEGORIES
LATEST ENTRIES
SEARCH THIS SITE
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
SONY MDR-CD900ST
SONY MDR-CD900ST (JUGEMレビュー »)

普段これで開発しています。
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND