Pythonで音声処理(3)ピー音の周波数を変更してみる

IT

前回の記事では、Pythonを利用して、作成した正弦波の音声をFFT処理し、周波数のグラフ化までを行いました。

今回の記事では、周波数データに変換したピー音の周波数を変更し、元の波形に戻すとどうなるか実験してみます。

その前に、前回の記事で出力したFFTのデータをもう一度良く見て見るために、少しプログラムを変えてグラフ出力します。具体的には20行目に下記変更を加えて、データ全体をグラフに表します。

【変更前】plt.plot(freq[1:int(N/2)], Amp[1:int(N/2)])

【変更後】plt.plot(F.imag[1:N])

実行して得られた周波数領域のグラフが以下になります。

図1 440Hzの周波数グラフ

続いて、7行目に下記変更を加えて周波数を変更します。

【変更前】f0 = 440

【変更後】f0 = 880

実行して得られた周波数領域のグラフは以下になります。

図2 880Hzの周波数グラフ

図1 440Hzの周波数グラフと図2 880Hzの周波数グラフの違いを確認してみましょう。

図2のほうが縦棒が中央に寄っていることがわかると思います。

これは周波数が上がれば、周波数領域のデータが中央に寄ることを意味しています。

この結果を元に、440Hzの音声データをFFTし、周波数データを中央に寄せて、逆FFTで元の音声データに戻してみます。

プログラム全体は下記となります。

少し長くなりましたので、周波数変更処理の部分は関数として定義(7行目から46行目)しています。

48行目から86行目がメイン処理になります。

メイン処理はやっていることは単純なので、流れのみ説明します。

1.440Hzの正弦波を作成し、グラフ化しています。

2.440HzのデータをFFTし、周波数データに変換しています。

3.周波数データを新たに定義したshift_freqという関数を使って440Hzプラスします。

4.変更した周波数データに対して、逆FFT処理をかけて元の波形に戻し、グラフ化します。

5.元に戻したデータをWaveファイルとして出力しています。

続いて、shift_freqの処理について解説していきます。

7行目で、「shift_freq」という関数を定義しています。引数として、FFTの実行結果、シフトする周波数、サンプリング周波数、音声の長さ(秒)を定義しています。シフトする周波数はプラスでもマイナスでも構いません。今回のメイン処理ではわかりやすいように440Hzプラスし、880Hzにしています。

8行目で、サンプリング周波数に音声の長さ(秒)を乗算して、信号データの総数Nを算出しています。

9行目では、シフトする周波数に音声の長さ(秒)を乗算して、実際にシフトする量を算出しています。

10行目から27行目で、周波数をプラス方向にシフトする場合の処理を定義しています。

13行目から19行目のループでは、データの中央部から左方向に向かって値を見ていき、シフト分先(si)にある値を現在(i)の位置にシフトします。シフト分先(si)がマイナスになったら、現在(i)の位置に0を入れます。

21行目から27行目のループでは、データの中央部から右方向に向かって値を見ていき、シフト分先(si)にある値を現在(i)の位置にシフトします。こちらもシフト分先(si)が総数Nを超えたら、現在(i)の位置に0を入れます。

28行目から45行目の処理は、周波数をマイナス方向にシフトする場合の処理を定義しています。

処理内容の説明はプラス方向と同様のため割愛します。

最後の46行目でシフトしたFを戻り値としてメイン処理に渡して関数処理は完了します。

本プログラムを実行して得られた波形画像は以下になります。

図3 作成した440Hzの波形
図4 周波数領域で周波数を440Hz追加して戻した880Hzの波形

図3が作成した440Hzの波形で、図4が、440Hzの波形をFFTして440Hzシフトし880Hzとして、波形データに戻したものです。周波数を上げたので波形が細かくなっているのがわかります。

音声でも確認してみましょう。音量にご注意ください。

音声1 作成した440Hzの正弦波
音声2 周波数を440Hz追加して戻した880Hzの正弦波

プー音からピー音になりましたね。

周波数領域のデータをシフトすることで、周波数を変更できることが確認できました。

次の記事では、作成した波形ではなく、実際の音声を利用して処理してみたいと思います。

コメント

タイトルとURLをコピーしました