sound_splitを用いることで、周波数分解能と時間分解能を共に楽曲の解析に適した解像度でスペクトル解析できることがわかりました。 では、そのスペクトル情報を用いて元の波形を再現することができるのでしょうか。 単純に、分析結果からもとの波形に戻すことは簡単にできます。(分解に用いた内積を計算する際に、振幅だけでなく位相を計算しておけばよい) では、440Hzの音と300Hzの音を混合している場合に、元の440Hzの波形と300Hzの波形に分離することは可能でしょうか。
単純に考えると、440Hzに相当する解析ユニットの出力だけを抜き出せばよいように思います。 しかし、そのユニットの出力を逆位相で加えても、440Hzの成分は完全に打ち消すことができません。 解析ユニットは、0.5%の周波数幅を持っており、また先程見たようにメインローブも幅を持っていることから、440Hz周辺のいくつかのユニットに反応が見られています。 もとの混合波のある成分の正確な周波数を求めるためには、ユニット単位の解析では不十分で、周波数と位相が完全には一致しないようです。
sound_splitに、オプション--filterを与えることで、分離実験ができます。 アイデアとしては、抜き出したい部分のスペクトルの強いところが、混合波のひとつであると見なして振幅とだいたいの周波数を記録します。 そして、周波数と初期位相を少しずつずらして元の波形にぶつけ、差が一番小さくなる周波数と位相の波が含まれていると判断します。
実際の例で、分離がどのように働くかを見てみます。 440Hzの正弦波がひとつだけ鳴っている音源を解析してみます。
440Hzの正弦波です。
分離の開始点(下限周波数および開始時間)、分離するピーク、分離の終了点(上限周波数及び終了時間)を手動で与えます。
分離の条件が指定できたら、filter startボタンもしくはinverse filter startボタンで、解析を開始します。 filterは通常の分離を、inverse filterは元の波形から分離波形を引いて残りを結果として表示します。 今回はわかりやすくするため、inverse filterを使用します。
フィルタリング後の波形です。開始から1sec-2secの区間が無音になっています。
フィルタリング結果の図を見ると、指定した区間の440Hzのsin波がきれいに無くなっていることがわかります。 分離波形を引いた結果なので、分離波形は元の波形のこの区間のデータと全く一致しているということになります。
次に、300Hz、440Hz、880Hzが同時に鳴っている音源のひとつの音だけを抽出してみます。
300Hz, 440Hz, 880Hzの正弦波が3つ合成されています。
440Hzの単音の場合は、この手法でほぼ全てが抽出できることがわかります。 一方、3音が重なった音からそれぞれを抽出する場合は、おおむね抽出できるものの、完全に元の波形は再現できていません。
3音から440Hzを抽出した残りの成分について見てみると、開始部分と終了部分において振幅の検出の過渡部分で元の波形に追随できていないほか、抽出がぴったり440Hzをトラックしきれずに揺らいでいる為に成分が残存していることがわかります。
また、440Hzと300Hzが近接しているため、打ち消し波形の計算の際に他の成分を検出して揺らぎが生じています。位相と周波数の計算ロジックを改良する必要がありそうです。