5

フーリエ変換からスペクトルを取得しました。次のように見えます: 通りすがりの警察が作成した音のスペクトログラム
ちょうど近くを警察が通過していました

色は強度を表します。
X 軸は時間です。
Y 軸は周波数で、0 が上になります。

口笛や警察のサイレンは 1 つの痕跡しか残していませんが、他の多くの音には多くの高調波周波数が含まれているようです。

EHGDAEチューニングギターのサウンドスペクトログラム エレキギターをマイクに直接差し込む(標準チューニング)

本当に悪いことは、あなたが見ることができるように、大きな強度がないということです - ほぼ等しい2-3の周波数があります.
最も重要なピークを強調するピーク検出アルゴリズムを作成しました。

    function findPeaks(data, look_range, minimal_val) {
      if(look_range==null)
        look_range = 10;
      if(minimal_val == null)
        minimal_val = 20;
      //Array of peaks            
      var peaks = [];
      //Currently the max value (that might or might not end up in peaks array)
      var max_value = 0;
      var max_value_pos = 0;
      //How many values did we check without changing the max value
      var smaller_values = 0;
      //Tmp variable for performance
      var val;
      var lastval=Math.round(data.averageValues(0,4));
      //console.log(lastval);
      for(var i=0, l=data.length; i<l; i++) {
        //Remember the value for performance and readibility
        val = data[i];

        //If last max value is larger then the current one, proceed and remember
        if(max_value>val) {
          //iterate the ammount of values that are smaller than our champion
          smaller_values++;
          //If there has been enough smaller values we take this one for confirmed peak
          if(smaller_values > look_range) {
            //Remember peak
            peaks.push(max_value_pos);
            //Reset other variables
            max_value = 0;
            max_value_pos = 0;
            smaller_values = 0;
          }
        }
        //Only take values when the difference is positive (next value is larger)
        //Also aonly take values that are larger than minimum thresold
        else if(val>lastval && val>minimal_val) {
          //Remeber this as our new champion
          max_value = val;
          max_value_pos = i;
          smaller_values = 0;
          //console.log("Max value: ", max_value);
        }           
        //Remember this value for next iteration
        lastval = val;
      }
      //Sort peaks so that the largest one is first
      peaks.sort(function(a, b) {return -data[a]+data[b];});
      //if(peaks.length>0)
      //  console.log(peaks);
      //Return array
      return peaks;
    }

アイデアは、データを調べて、 thresold より大きい値を覚えているということですminimal_val。次のlook_range値が選択した値よりも小さい場合は、ピークと見なされます。このアルゴリズムはあまりスマートではありませんが、実装は非常に簡単です。

ただし、私が予想したように、文字列の主要な周波数がどれであるかはわかりません。

ギター弦が最も強い周波数で強調表示されました
赤い点は最も強いピークを強調しています

これが実際にどのように機能するか (または機能しないか) を確認するための jsFiddleを次に示します。

4

1 に答える 1

3

弦の音のスペクトルに見られるのは、次の高調波のセットです。

f0、2*f0、3*f0、...

f0 は弦の音の基本周波数またはピッチです。

スペクトル (FFT の出力、abs 値、おそらく対数) から f0 を推定するには、最も強い成分を探すのではなく、これらすべての高調波間の距離を探す必要があります。

これを行うための非常に優れた方法の 1 つは、(abs、real) スペクトルの 2 番目の (逆) FFT です。これにより、t0 == 1/f0 で強い線が生成されます。

シーケンス fft -> abs() -> fft-1 は、ウィーナー・ヒンチンの定理により、自己相関関数(ACF)を計算することと同じです。

このアプローチの精度は、FFT (または ACF) の長さとサンプリング レートによって異なります。sinc 関数を使用して、結果のサンプリング ポイント間の「実際の」最大値を補間すると、精度を大幅に向上させることができます。

さらに良い結果を得るには、中間のスペクトルを修正することができます。ほとんどの音には、平均的なピンク色のスペクトルがあります。逆FFTの前に(逆ピンクスペクトルに従って)より高い周波数を増幅すると、ACFは「より良く」なります(より高い高調波がより考慮され、精度が向上します)。

于 2015-02-05T09:19:05.687 に答える