2

mp3 の 10 秒のクリップから振幅データを取得しました。次に、高速フーリエ変換を実行して、周波数領域でクリップのデータを取得しました (最初の図を参照)。ここで、ピークがどの周波数にあるかを判断したいと思います。

振幅から周波数へ

データを平滑化することから始めました。これは、下の青と赤のプロットで確認できます。考慮されるためには、ピークを超えなければならないというしきい値を作成しました。これは、下の 3 番目のプロットの青い水平線です。ご覧のとおり、ピーク検出コードはある程度機能しました。

スムージングとピーク検出

私が今抱えている問題は、以下に示す最終的なプロットで明らかです。私のコードは、全体的なピークの一部として局所的な最大値である最大値を見つけています。これらの極大値を除外して、ピークごとに 1 つのマーカーのみを取得する方法が必要です。つまり、以下に示すピークでは、途中の各マイナー ピークではなく、絶対ピークにのみマーカーが必要です。

ピーク検出拡大図

私のピーク検出コードを以下に示します。

for i, item in enumerate(xavg): #xavg contains all the smoothed data points
    if xavg[i] > threshold: #points must be above the threshold
        #if not the first or last point (so index isn't out of range)            
        if (i > 0) and (i < (len(xavg)-1)): 
            #greater than points on either side                
            if (xavg[i] > xavg[i-1]) and (xavg[i] > xavg[i+1]):  
                max_locations.append(i)

編集:私は自分の問題を十分に明確に述べていないと思います。全体的な最高点だけでなく、プロット上の 5 つほどの最高点の位置を見つけたいと考えています。私は基本的に、主な周波数をマークすることによって、クリップにオーディオ フィンガープリントを与えようとしています。

EDIT2:FFTとスムージングに関して私が何をしているのかを示すのに役立つコード:

def movingaverage(interval, window_size):
    window = np.ones(int(window_size))/float(window_size)
    return np.convolve(interval, window, 'same')

fft = np.fft.rfft(song)
xavg = movingaverage(abs(fft), 21)
4

4 に答える 4

0

現在、前のポイントと次のポイントが現在のポイントより下にある任意のポイントのリスト (max_locations) を作成しています。絶対最大値のみに関心がある場合は、次のようにすることができます。

xavg.index(max(xavg[開始位置:終了位置]))

または、コードをそのまま維持したい場合は、現在のポイントが他のポイントよりも大きいかどうかを確認してから、max_location の位置に配置することができます。

xavg[i] > xavg[max_location] の場合: max_location = i

于 2013-07-31T13:45:59.683 に答える