
音の高さと再生速度1.FFTと逆変換R言語を使って試して見ます。確かに完全に戻ります。 > s <- sin( seq(0,by=2*pi/16,length.out=16) ) > f <- fft( s )/16 > r <- fft( f, inverse=TRUE ) > s [1] 0.000000e+00 3.826834e-01 7.071068e-01 9.238795e-01 1.000000e+00 [6] 9.238795e-01 7.071068e-01 3.826834e-01 1.224606e-16 -3.826834e-01 [11] -7.071068e-01 -9.238795e-01 -1.000000e+00 -9.238795e-01 -7.071068e-01 [16] -3.826834e-01 > Re(r) [1] 0.000000e+00 3.826834e-01 7.071068e-01 9.238795e-01 1.000000e+00 [6] 9.238795e-01 7.071068e-01 3.826834e-01 1.224606e-16 -3.826834e-01 [11] -7.071068e-01 -9.238795e-01 -1.000000e+00 -9.238795e-01 -7.071068e-01 [16] -3.826834e-01 16分割した1周期のサイン波のFFTの結果を逆変換すると元のサイン波に戻ります。この例では、FFTの結果をサンプル数16で割っています。 > c <- seq(0,by=0,length.out=16) > c[2] <- complex(re=0,im=-0.5) > c[16] <- complex(re=0,im=0.5) > c [1] 0+0.0i 0-0.5i 0+0.0i 0+0.0i 0+0.0i 0+0.0i 0+0.0i 0+0.0i 0+0.0i 0+0.0i [11] 0+0.0i 0+0.0i 0+0.0i 0+0.0i 0+0.0i 0+0.5i > r2 <- fft( c, inverse=TRUE ) > Re(r2) [1] 0.0000000 0.3826834 0.7071068 0.9238795 1.0000000 0.9238795 [7] 0.7071068 0.3826834 0.0000000 -0.3826834 -0.7071068 -0.9238795 [13] -1.0000000 -0.9238795 -0.7071068 -0.3826834 FFTを行うサンプルの範囲で、1周期の信号成分の大きさは、先頭から2つ目(0,1なら1)に反映します。その共役数が最後に入ります。 位相を2π/16ずつずらしながら、16サンプルで1周期のサイン波を作って、FFTを行って、[2]の実部、虚部をプロットして見ました。(「R言語」「サンプル」にスクリプトを保存しました。)
同じもの( サンプル中で、1周期のFFTの結果のうち、1周期の分に相当する[2]の部分)を、実部、虚部でプロットして見ました。
2.FFTとその逆変換で再生速度を変えてみるやって見たのですが、あまり上手くいきません。リアルタイムに、マイク入力をゆっくり再生するプログラムを作ったのですが、ぶつぶつとノイズが入ります。上手く行かない訳を考えて見ます。 2.1.意図したこと 44100Hzでサンプリングします。これを、22050Hzで再生することで「ゆっくり再生」を実現します。これだけだと、周波数も低くなってしまうので、FFT、逆変換で周波数を2倍にします。 これを作っては見たのですが、ぶつぶつとノイズが入ります。プログラムの間違いを除去するために、WAVファイルを変換する単純なプログラムを使って検討することにしました。 2.2.検証用WAVファイル16000Hz、モノラルで録音された文章読み上げのサンプルです。これを、8000Hzでサンプリングしたものとして出力します。出力サイズは変わりません。本来、約8000HzまでFFTで検出するわけですが、4000Hzまでになります。 2.3.周波数を2倍にするC#でのプログラム用に作った、私のFFTは、サンプル数の半分の値しか返しません。したがって、この半分で考えます。 これを逆変換して、入力と同じものになるのを確認しました。
2.4.上手く行かない理由
2.4.1.期待したことFFT -> 結果をシフト -> 逆変換
---------------------------------------------------------
2.4.2.実際は最初は、FFTを計算するサンプル数を、512程度にしていて、気が付きませんでした。4096にしたら、同じ音節を繰り返していることが分かりました。 FFTは、サイン波、コサイン波を合成して、元の振幅波形を近似していると言う大元を考えれば当然で、近似に使用した、サイン波、コサイン波の周期を半分にしたのですから、合成波形も半分になってしまいます。残りの半分は、同じ波形の合成が続くのですから、同じものが繰り返されるわけです。 「ぶつぶつ」は、つなぎ目で不整合かとも思いましたが、FFT区間内での特性が一様でないことに原因があるようです。 下の「入力データ(4096)」は、FFTの入力となったPCM(振幅)データです。 FFT -> 結果をシフト -> 逆変換 「周波数2倍処理後の逆変換結果(4096)」のデータの先頭と中央の10個を見て見ます。 > cc<-scan("tmp.txt") また、差をプロットすると左図になりました。 > diff <- cc[1:2048]-cc[2049:4096]
2.5.どうすれば良いか
音素より短い時間でFFTを行い、そのデータを2回出力する方法が考えられます。 しかし、これを良く考えて見ると、FFTを使う必要がないようです。 PCMデータを1つ飛びに取ることは、サンプリングレートを半分にして、サンプリングしたのと同じことです。 図、「サンプリングレート半分(偶数x2)」は、「上手く行かない理由」の入力に対して、この処理をした結果のPCMデータです。
3.わかったこと
|

