wav2midi 方針・設計
音声波形のパワースペクトルの抽出
音声波形 の周波数成分ーつまりパワースペクトル はフーリエ変換を用いて求めることができる。
ここで、対象となる音声波形 はサンプリング周期 により一定間隔で標本化された離散値となる。そのため、離散フーリエ変換(Discrete Fourier Transform―DFT)を用いる。
まず、 をある区間 で 個標本化したときの の標本化列 は以下のようになる 。
そして、 のパワースペクトル は離散フーリエ変換より以下のように求められる。
ここで、 はサンプリング周期 で 個標本化されているので、取りうる周波数 および角周波数 は標本点 を使って以下のようになる 。
よって、 は、パワースペクトル列 となり、以下のようになる。
高速フーリエ変換(Fast Fourier Transform―FFT)
DFTでは計算量が となり計算量が膨大になるため、実際に実装する際は FFT を用いる。これで計算量が となり大幅に減らすことができる。
まず、 回転因子 というものを導入する。
すると、 は以下のようになる。
ここで、回転因子 は以下の関係が成り立つ。
つぎに、 が偶数である場合に、 を が偶数の場合と奇数の場合にわけ、それぞれ ごとに分割する。
ここで、数列 および を考える。
、 および回転因子 の性質により とすると および はそれぞれ以下のようになる。
これより、 および それぞれが、離散フーリエ変換の式になっているので、あとはこれを再帰的に分割していく。
この一連の演算の結果の数列を とすると以下のような式になる。
よって、 は以下のようになる。
参考
- 離散フーリエ変換、逆離散フーリエ変換 - Qiita
- フーリエ解析 2: C++ で高速フーリエ変換 (FFT) - ロコリンの雑記
- 離散フーリエ変換入門
- fft
- みる きく 考える 進む: C++で超シンプルなFFTの実装
- 高速フーリエ変換 (FFT) - ゆるふわブログ
- Tech Tips: サルでも分かるFFT(3)
- 基礎からの周波数分析(9) ― 「高速フーリエ変換(FFT)」
音階の周波数
音階は1オクターブごとに12個存在し、隣り合う音階の周波数の比率が一定である。すなわち音階の周波数は等比数列となる。また、1オクターブごとに周波数が2倍となるため、音階の周波数の公比 は以下のようになる。
また、最初の音階 の周波数は である。そのため、初項 は以下のようになる。
よって、 および より 番目の音階の周波数―すなわち一般項 は以下のようになる。
さて、ここでピアノの鍵盤は88鍵存在するので各鍵盤 の周波数 および音階 は以下のようになる 。
参考
パワースペクトルから音階の抽出
パワースペクトルのピーク(基音)を抽出することにより求めることができる。
まず、基音はパワースペクトル列 で最大の大きさを持つはずなので、最大値 抽出する。
次に、 の 以上の大きさを持つスペクトル列を基音 と定義すると以下のようになる。
これより基音の周波数 は以下のようになる。
ここで、式 を について解くと以下のようになる。
ここで、 を音階の周波数以外の一般の周波数 について考える。つまり、 、 とすると上式は以下のようになる。
ただし、音階 は整数である必要があるので 、上式を四捨五入してもっとも近い整数に丸める。そのため以下のようになる。
及び、 より、音声波形 の音階 は以下のようになる。
本記事では、自然数 は を含む。