Обнаружение энергии ударов с помощью Librosa, поиск первого удара каждого такта

Мне нужно найти энергию пиков с помощью Librosa, чтобы я мог обнаружить первую долю каждого такта.

Я использую Librosa для обнаружения звуковых битов в треке кликов. Это работает хорошо, но теперь я хочу обнаружить первую долю каждого такта. Я считаю, что лучший способ сделать это — определить энергию или высоту каждого удара.

В настоящее время я записываю все удары в массив. Как определить первую долю каждого такта?

def findPeaks(inputFile):
    print(">>> Finding peaks...\n")
    y, sr = librosa.load(inputFile)
    onset_env = librosa.onset.onset_strength(
        y=y, sr=sr, hop_length=512, aggregate=np.median
    )
    global inputTrackPeaks  # array of peaks
    inputTrackPeaks = librosa.util.peak_pick(onset_env, 3, 3, 3, 5, 0.5, 10)
    inputTrackPeaks = librosa.frames_to_time(inputTrackPeaks, sr=sr)
    inputTrackPeaks = inputTrackPeaks * 1000  # convert array to milliseconds
    print("Peak positions (ms): \n", inputTrackPeaks)

person Stephen Kempin    schedule 06.08.2019    source источник


Ответы (1)


Для очень простого трекера вы, вероятно, захотите использовать встроенный в librosa ритм beat. отслеживание:

import librosa

y, sr = librosa.load(librosa.util.example_audio_file())
tempo, beats = librosa.beat.beat_track(y=y, sr=sr)
# beats now contains the beat *frame positions*
# convert to timestamps like this:
beat_times = librosa.frames_to_time(beats, sr=sr)

Это дает вам битовые позиции. Но на самом деле вы запрашивали мрачную оценку. Ваша идея найти долю с наибольшей энергией хороша, но вы можете добавить некоторые дополнительные знания и усреднить соответствующие доли. Например, если вы знаете, что размер трека составляет 4/4, вы можете суммировать энергию каждой четвертой доли, а затем сделать вывод, что позиция доли с наибольшей суммой энергии является сильной долей.

Примерно так:

import librosa
import numpy as np

y, sr = librosa.load('my file.wav')
# get onset envelope
onset_env = librosa.onset.onset_strength(y, sr=sr, aggregate=np.median)
# get tempo and beats
tempo, beats = librosa.beat.beat_track(onset_envelope=onset_env, sr=sr)
# we assume 4/4 time
meter = 4
# calculate number of full measures 
measures = (len(beats) // meter)
# get onset strengths for the known beat positions
# Note: this is somewhat naive, as the main strength may be *around*
#       rather than *on* the detected beat position. 
beat_strengths = onset_env[beats]
# make sure we only consider full measures
# and convert to 2d array with indices for measure and beatpos
measure_beat_strengths = beat_strengths[:measures * meter].reshape(-1, meter)
# add up strengths per beat position
beat_pos_strength = np.sum(measure_beat_strengths, axis=0)
# find the beat position with max strength
downbeat_pos = np.argmax(beat_pos_strength)
# convert the beat positions to the same 2d measure format
full_measure_beats = beats[:measures * meter].reshape(-1, meter)
# and select the beat position we want: downbeat_pos
downbeat_frames = full_measure_beats[:, downbeat_pos]
print('Downbeat frames: {}'.format(downbeat_frames))
# print times
downbeat_times = librosa.frames_to_time(downbeat_frames, sr=sr)
print('Downbeat times in s: {}'.format(downbeat_times))

Ваш пробег с таким кодом будет варьироваться. Успех зависит от типа музыки, жанра, размера, качества обнаружения битов и т. д. Это потому, что это не тривиально. На самом деле пессимистичная оценка — это текущая тема исследования поиска музыкальной информации (MIR), и она не полностью решена. . Чтобы ознакомиться с недавним обзором расширенного автоматического отслеживания спада на основе глубокого обучения, вы можете проверить эта статья.

person Hendrik    schedule 07.08.2019
comment
Спасибо, это здорово. Однако проблема заключается в том, что не все треки кликов, которые я использую, имеют постоянный размер 4/4. У некоторых полоса всего 2/4. Я должен отметить, что сильная доля на треках щелчков, которые я использую в качестве исходного файла, имеют тон, отличный от остальных тактов. Следовательно, существует ли метод обнаружения сильной доли по высоте тона, а не по энергии? - person Stephen Kempin; 07.08.2019
comment
Если ваш трек кликов состоит только из двух разных типов шагов/кликов и ничего больше, почему бы просто (неправильно) не использовать librosa.core.piptrack, определите и классифицируйте пики на сильные или нет. Если щелчок является гармоническим, вы должны быть в состоянии измерить, какую высоту следует искать в качестве сильной доли. См. также stackoverflow.com/q/43877971/942774 и принятый ответ для выбора максимального шага. - person Hendrik; 07.08.2019