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)