Я взял данные амплитуды из 10-секундного клипа mp3. Затем я выполнил быстрое преобразование Фурье, чтобы получить данные для клипа в частотной области (показано на первом рисунке). Теперь я хотел бы определить, на каких частотах расположены пики.
Я начал со сглаживания данных, что можно увидеть ниже на синем и красном графиках. Я создал порог, по которому пики должны быть превышены, чтобы их можно было учитывать. Это горизонтальная синяя линия на третьем графике ниже. Как видно, мой код обнаружения пиков работал до некоторой степени.
Проблема, с которой я столкнулся сейчас, очевидна на последнем графике, показанном ниже. Мой код находит максимумы, которые являются локальными максимумами как часть общего пика. Мне нужен способ отфильтровать эти локальные максимумы, чтобы для каждого пика я получал только один маркер. то есть для пика, показанного ниже, мне нужен маркер только на абсолютном пике, а не на каждом второстепенном пике на этом пути.
Мой код обнаружения пика показан ниже:
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: Еще немного кода, чтобы показать, что я делаю в отношении БПФ и сглаживания:
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)
fft = np.fft.rfft(song)
- person Nick Camps   schedule 31.07.2013