使用 Librosa 检测节拍能量,找到每个小节的第一个节拍

问题描述 投票:0回答:2

我需要使用 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)
python librosa audio-analysis
2个回答
3
投票

对于一个非常简单的节拍跟踪器,您可能想使用 librosa 的内置 节拍跟踪

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)
 研究主题,尚未完全解决。有关基于高级深度学习的自动悲观跟踪的最新评论,您可能需要查看
本文

假设节奏稳定并且您知道节拍位置 您可以平均/求和节拍的起始值,按索引模 x 分组。 X可以是2到8。 发现悲观的方法是创建一些启发式方法来比较这些组,并选择其中 1 个组明显强于其他组的组。 Bin 编号将为您提供悲观的位置(小节开始),而 x 值将为您提供计量。 这就是我实际计划在我的案例中做的事情。


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.