サンプリングレートの変換(リサンプル)
左図をクリックすると、ブラウザ上で実行します。
以下の変換をします。
1.サンプリングレート(リサンプル)
2.ビット長
3.ステレオ - モノラル
音声データは、サンプリングによってデジタル化されているので、必ずサンプリングレートを持っています。
このサンプリングレートを変換する必要性はあまりないと思います。
考えられるのはAudio CDにオーサリングする場合ぐらいです。
サンプリングレートとサンプル数(ファイルの大きさ)は比例します。
デジタルでリサンプルする方法は、間引きや挿入でサンプル数を変えることになります。
ダウンサンプリングの場合は、ナイキスト周波数が小さくなるので、表現できなくなる高い周波数成分を除去した上で間引きを行います。
変換のアルゴリズムは、「内挿、間引きによるレート変換」に記した、R言語のresample()によっています。
ただし、フィルタは通常のFIRフィルタを使いました。(R言語のresample()では、fftfilt()が使われている。)
FIRフィルタならレジスタを保持すれば、分割して処理しても結果が同じになることが保証できると考えました。
以下のようにして、ダウンサンプリングの結果を見て見ました。
WAVファイルは、以下のようにして作成しました。
- source("WavIO_R.R");# 1度だけ実行
- # サンプリングレート32KHz
- # 左チャネルに4KHz、10KHz
- # 右チャネルに6KHz、12KHz
- # 10ms 分
- t <- seq(0,by=1/32000,length.out=320)
- s4 <- sin(2*pi*4000*t)
- s6 <- sin(2*pi*6000*t)
- s10 <- sin(2*pi*10000*t)
- s12 <- sin(2*pi*12000*t)
- # 合成して出力
- w <- rep(640)
- odd <- seq(1,by=2,length.out=320)
- even <- seq(2,by=2,length.out=320)
- w[odd] <- (s4+s10)/2 * 32767 # 左チャネル
- w[even] <- (s6+s12)/2 * 32767 # 左チャネル
- wav16write("32k4_10-6_12.wav",w,2,32000)
サンプリングレートを、32KHz から 16Hz に変換してみます。
「音の実験」にこのファイルを貼り付け、「ファイル変換」「リサンプル」で変換しました。
出力は、16KHzなので、8KHz以上の周波数は表現できません。
この影響を見ました。
32KHzサンプリング |
|
フィルタを通さない場合は、以下のようになります。
ダウンサンプリング時のフィルタの効果を波形で見ると、以下のようになります。
入力は 4KHz と 10KHz の正弦波です。サンプリングレートを32KHzから16KHzにすると、ナイキスト周波数を超える 10KHzの正弦波は表現できません。
フィルタを通さないと周波数のピークが2つできています。ナイキスト周波数を超える周波数成分が、ナイキスト周波数以下の存在しない周波数成分と解釈されるようになります。
フィルタを通すと 10KHz はカットされます。振幅で見ても周期性が確認できます。
また、パワーが小さくなっています。
フィルタを通さない場合もパワーがいくらか小さくなっています。
間引くことと平滑化で失われるパワーは、補正の必要がありそうですが、行いませんでした。
最終的にマキシマイズするなどするなら、補正は冗長です。
図を描いたR言語のスクリプト。
- s <- wav16read("32k4_10-6_12.wav")
- L <- s$pcm[seq(1,by=2,length.out=320)] / 32768
- R <- s$pcm[seq(2,by=2,length.out=320)] / 32768
- L_F <- abs(fft(L))[1:160]
- R_F <- abs(fft(R))[1:160]
- KHz <- seq(0,by=16/160,length.out=160)
- par(mfrow=c(2,2),mar=c(3,3,3,2),mgp = c(1.5,0.5,0))
- plot(L[1:50],type="l")
- title(main="左の振幅")
- plot(KHz,L_F,type="l");
- title(main="左の周波数")
- plot(R[1:50],type="l",col="blue")
- title(main="右の振幅")
- plot(KHz,R_F,type="l",col="blue");
- title(main="右の周波数")
|