CICフィルタでサンプルレート変換
by K.I
2017/01/16〜2017/01/26
Index
- プログラムでCICフィルタの記事で、微分・積分器を組み合わせたCICフィルタプログラムを作成、
- その特性を調べてみたので、今度はサンプルレートコンバータを試してみようと思う。
- サンプルレートコンバータは、デジタルオーディオで良く使われる回路で、
- 例えば、CDは44.1kHzのサンプルレートだが、DVDは48kHzのサンプリングレートになっている
- これを、相互に変換する際に使われる
- 何で統一しないんだってことなんだけど、
- ひとつには簡単にコピー出来ない様に、というつまらない理由らしい
- まぁそれだけが理由ではないと思うけれど。
- いずれにせよ、サンプルレート変換は、デジタル処理として面白そうなので、
- CICフィルタの、微分・積分回路とアップダウンサンプラは、 CICフィルタの記事で作ったものを使っている。
- lcomb,lintg,lups,ldwsは、それを単に、longに拡張しただけのもの。
[top]
- まずは、自分なりにCICフィルタでサンプルレート変換する方法を試してみる
- 48kHz→44.1kHzのサンプルレートコンバータの場合
- 48000 → 2^7 x 3 x 5^3
- 44100 → 2^2 x 3^2 x 5^2 x 7^2
- 3 x 7^2 を掛けて、2^5 x 5 で割れば良い
- つまり、147倍アップサンプリングして、160倍ダウンサンプリングすれば良いことになる
- それなら、アップサンプリング147倍だけなら、いけるかな
% idds 1000 48000 | comb 1 | comb 1 | comb 1 | iups 147 | intg | intg | intg | tail -14700 | gp_wav > src_test2w.png
% idds 1000 48000 | comb 1 | comb 1 | comb 1 | iups 147 | intg | intg | intg | fftw | gp_fftl > src_test2.png
- CICフィルタの記事で作ったプログラムのバッファの型はint、つまり4byte長だから、
- -2147483648〜2147483647 なので、本当にギリギリだった
- これだと、ダウンサンプリングは無理なのは当たり前か。
- でも、バッファを倍にすれば、ギリギリ行けるということかもしれない。
- ということで、バッファ変数をlong、8byte長(64bit)にした、lcomb,lintg,lups,ldwsを作成
% idds 1000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg | lintg \
| lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | tail -100 | gp_wav > src_cicw.png
% idds 1000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg | lintg \
| lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | fftw | gp_fftl > src_cic.png
- なんとか、ギリギリ動いたようだ。
- 但し、実際の音声信号は、〜20kHzぐらいなので、1kHzはかなり低い周波数になる
% idds 10000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | tail -100 | gp_wav > src_cic10kw.png
% idds 10000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | fftw | gp_fftl > src_cic10k.png
- ちょっとだけ波形が歪み始めているが、まぁOKのようだ
% idds 15000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | tail -100 | gp_wav > src_cic15kw.png
% idds 15000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | fftw | gp_fftl > src_cic15k.png
- 波形にうねりがみられる。15kHzのレベルも落ちてきているし、
- 周波数特性で見ると、11k,18k辺りになにか出ている。。
% idds 15000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg | tail -1000 | gp_wav > src_cic15kw2.png
% idds 15000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg | fftw | gp_fftl > src_cic15k2.png
→元の波形はスッキリしている(本当は元波形のサンプリングは荒いんだけど)
- 単体でみると分かり辛いが、見較べてみると、アップサンプリング後の波形は歪んでいることがわかる
- 波形の山が左右対称じゃない。波形の上の方は太く、下の方は細めにみえる
- この周波数特性では、ダウンサンプリングで間引いた時に、変な周波数を拾ってしまうのも頷ける
% idds 20000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | tail -100 | gp_wav > src_cic20kw.png
% idds 20000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | fftw | gp_fftl > src_cic20k.png
- 波形のうねりが酷い。20kHzのレベルもかなり落ちているし、
- この16k辺りの信号はかなり強い。20k近くにも何かある
- 20kHzでも、アップサンプリング後だけ、見てみよう
% idds 20000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg | tail -2000 | gp_wav > src_cic20kw2.png
% idds 20000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg | fftw | gp_fftl > src_cic20k2.png
- 周波数特性は酷いけれど、15kHzと意外と変わらないが、波形は明らかに歪んでいる
- やはり、ダウンサンプリングで間引いた時に、変な周波数を拾ってしまうのも頷けるし、
- 周波数が高くなった時、ノイズになる周波数の数が増えるというより、特定の周波数のレベルが大きくなるのかな?
% white 48000 20000 | imul 100 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | tail -100 | gp_wav > src_cicwtw.png
% white 48000 20000 | imul 100 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | fftw | gp_fftl > src_cicwt.png
- これだけ見ると、高域のレベルはかなり落ちているが、ナイキスト周波数以上はキレイにカットされているように見える。
- でも、単体の正弦波を入れたときの挙動からみると、余計な周波数も発生3して波形は歪んでいるので、
- ホワイトノイズの特性をみても、それだけではわからないこともあるってことか。。
1コマンドが長くなるので、途中で改行を入れている。(改行がある場合は、\を付けている)
2といっても、元波形のサンプリング周波数は荒いので、見やすいようにサンプリングを10倍にしている。
3高域のカットオフは、実際はもっと緩やかなはず。多分、発生した余計な周波数で、こんな風に見えるんじゃないかな。
[top]
- サンプルレートコンバータは、音のデータを扱うことが多いので、やっぱり音を聞いてみたい。
- ということで、Waveに変換して、さらにMP3に変換4したもので音を聞いてみる
% idds 1000 48000 | imul 0.8 > idds1000.dat
% txt2wav -48000 idds1000.dat
% lame idds1000.wav idds1000.mp3
- CICサンプルレート変換後は、1kHz/44.1ks
% idds 1000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | imul 0.00000000001 > idds1000cic.dat
% txt2wav -44100 idds1000cic.dat
% lame --preset studio idds1000cic.wav idds1000cic.mp3
% idds 10000 48000 | imul 0.8 > idds10000.dat
% txt2wav -48000 idds10000.dat
% lame idds10000.wav idds10000.mp3
- CICサンプルレート変換後で、10kHz/44.1ks
% idds 10000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | imul 0.00000000001 > idds10000cic.dat
% txt2wav -44100 idds10000cic.dat
% lame --preset studio idds10000cic.wav idds10000cic.mp3
- これも、区別が付かないなぁ。まぁ、波形が少し歪んでるだけだからね。
% idds 15000 48000 | imul 0.8 > idds15000.dat
% txt2wav -48000 idds15000.dat
% lame idds15000.wav idds15000.mp3
- CICサンプルレート変換後が、15kHz/44.1ks
% idds 15000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | imul 0.00000000001 > idds15000cic.dat
% txt2wav -44100 idds15000cic.dat
% lame --preset studio idds15000cic.wav idds15000cic.mp3
- あれ、聞こえない5。
- でも変換後は、雑音がある所為か、なんか違う感じではある
- ということは、元データが、20kHz/48ksで、
% idds 20000 48000 | imul 0.8 > idds20000.dat
% txt2wav -48000 idds20000.dat
% lame --preset studio idds20000.wav idds20000.mp3
- CICサンプルレート変換後が、20kHz/44.1ksでも
% idds 20000 48000 | lcomb 1 | lcomb 1 | lcomb 1 | lups 147 | lintg | lintg | lintg \
| lintg | lintg | lintg | ldws 160 | lcomb 1 | lcomb 1 | lcomb 1 | imul 0.00000000001 > idds20000cic.dat
% txt2wav -44100 idds20000cic.dat
% lame --preset studio idds20000cic.wav idds20000cic.mp3
- やっぱり、聞こえないか。。かなり劣化してるはずなんだけど。わからん。。。
- DOVA-SYNDROMEというサイトは、基本的に改変も認めてる6らしい
- 各音源の権利は、あくまで作曲者にあるので、作曲者の利用条件もちゃんと確認する必要がある
- MP3フォーマットなので、Windowsのサウンド編集アプリ Audacityを使って、
- まず、ステレオ→モノラル変換、
- 48ks/sに設定して、WAVフォーマットで保存した(saadekakeyo.wav)
- Audacityは、スペクトラム解析も出来るので、変換前後のスペクトルの変化も見ることが出来る
- サンプルレート変換前(saadekakeyo.wav、48ks/s)
- サンプルレート変換後(saadekakeyo2.wav、44.1ks/s)
- 元々、MP3だったものなので、そもそも高音がカットされていることもあるとは思うけど、
- スペクトル解析では、高音がかなり削られていることが、はっきり分かる。
- まぁ、でも変換前の -84dB以上の部分だけ見れば、それほど変化は無い。
4IEのAudio要素は、WAV再生できないので。。
5あくまで、自分には聞こえないということ。。
6自分で作った曲として使ったりしない限りは。利用規約を確認して下さい。
7まぁ、アプリやツール使えば、一瞬なんだけど。。。
8耳が良い人には、簡単に聞き分けられるのかもしれない。
[top]
- CICフィルタだけによる、サンプルレート変換は、低音部はちゃんと再現されており、
- でも、高音では波形に歪みがあるし、
- 実際の曲データを変換してみた結果からも、高音がかなり失われていることが分かる
- これは耳で聞けば、はっきり分かると思っていたが、全然分からなかった。。
- 自分は区別つかないけど、他の人が簡単に区別つくのならショックだなぁ。。
- まぁ、CICフィルタによるサンプルレート変換は簡単な構成で出来るが、
- 周波数特性をみると、特に高音の劣化はハッキリ分かる。
- CICフィルタだけだと、特性の弄りようが無いので、実用に使うにはちょっと難しい感じだ。
- やはりもっと急峻な特性を持たせられる、FIRフィルタとかを使わないとダメなんだろう。
- でも、自分のポンコツの耳だと、意外にこれぐらいでも大丈夫なのかもしれない
- おまけで、DDSで作った正弦波データで、どの周波数まで聞こえるか試してみた。
- ちなみに、自分が聞こえるのは、14kHzまででした。。
- 聞こえなくても、聞こえる人には五月蝿いので、音量には気をつけて!
- ヘッドホンとかで聞くと、耳を傷めるかもしれないです
- 1kHz
- 2kHz
- 3kHz
- 4kHz
- 5kHz
- 6kHz
- 7kHz
- 8kHz
- 9kHz
- 10kHz
- 11kHz
- 12kHz
- 13kHz
- 14kHz
- 15kHz
- 16kHz
- 17kHz
- 18kHz
- 19kHz
- 20kHz
- 但し、自分の環境で、本当にちゃんと音が出ているのか、最初に確認した方が良いです
- ちなみに、自分の環境では、モニターについてるスピーカだと、17kHz以上はそもそも音が出ていなかった。
- 仕方ないので、USB-Audio出力にしたら、とりあえず20kHzまで出るようになった
- だから、聞こえないからって諦めないで、まず、ちゃんと音が出ているか確認しましょう
- この高い音は、モスキート音とか呼ばれていて、若い人は普通に聞こえるらしい10。。
- 実は最初、17kHz以上の音が出ていないことに、全く気がつかなかった。
- Androidや、iPhoneのツールが、全然反応しないので、やっと気がついた
- WAVファイルを再生しても、やはり出ていないので、
- モニタのスピーカ11に問題があると分かって、USB-Audio出力にした
- それでWAVファイルの音は出るようになったが、自分の作ったMP3は、やはり17kHz以上はダメ。
- 調べてみると、MP3のエンコーダは、ビットレートが128kbpsぐらいが標準で、
- 普通は、16kHz前後でLPFを掛けてからエンコードしているらしい
- lameも、デフォルトのビットレートは128kbpsになっているようだ。
- -bでビットレートを指定できるらしいが、lame --preset help で確認すると、
- --preset studio とすれば、ビットレートを256kbpsにしてくれるらしい12
- それで、16kHz以上は、全部 --preset studio オプションをつけて変換し直した
- 記事内の、MP3生成も必要な箇所は、同様に変更したので、ちゃんと20kHzぐらいまで、出るようになってるはず
- ツールで、どこまで聞こえるか確かめなかったら、全然気がつかないままだったな〜。
9でも無料ではないけど。なんで自分は持ってるんだろう。昔、買ったんだっけ?
10まぁ、どのみち自分には聞こえません。全然、聞こえませんとも。。
11というか、自分のPCのサウンド出力の問題か。
12じゃ、-bオプションは何なんだということだけど、それ以外にも何かしてくれるのかな?
[top]
[プログラムの部屋に戻る]
⇒ Disqusの広告がうるさすぎるので基本は非表示にしました