问题描述
我正在尝试使用 librosa.clicks 编写一个简单的节拍器
import librosa
import numpy as np
bpm = 200
exercise_duration = 10
sr = 22050
seconds_per_beat = 60/bpm
beats_number = round(bpm/ (60/exercise_duration))
metronome_clicks = [0]
for i in range(beats_number - 1):
metronome_clicks.append(seconds_per_beat + metronome_clicks[i])
click = librosa.clicks(times=metronome_clicks,sr=sr,length=22050 * exercise_duration,click_duration=0.1)
hop_length = 512
onset_samples = librosa.onset.onset_detect(y=click,units='samples',hop_length=hop_length)
onset_diff = np.diff(onset_samples)
print(onset_samples)
print(onset_diff)
在测试 librosa.clicks 的结果时,我注意到一个明显的不准确 - 我机器上 np.diff 的打印结果如下所示:
[6144 6656 6656 6656 6656 6656 6656 6656 6656 6656 6656 6656 6656 6144
6656 6656 6656 6656 6656 6656 6656 6656 6656 6656 6656 6144 6656 6656
6656 6656 6656]
这基本上意味着 23 毫秒的延迟。我还注意到样本中的延迟量 = 512,如果我将 hop_length 调整为 256,那么延迟是 256 个样本,所以它似乎与跳跃长度以某种方式相关 - 但说实话,我没有真的知道怎么做,有什么方法可以解决这个问题。此外,当您将 bpm 调整为 60 时,结果会很好:
[22016 22016 22016 22016 22016 22016 22016 22016]
但并不完美,因为 60bpm 应该等于 1 秒,这应该会给我们 22050 个样本。在 120 bpm 中,它看起来像这样:
[11264 10752 11264 10752 11264 10752 11264 10752 11264 11264 10752 11264
10752 11264 10752 11264 10752 11264]
这是另一种我不太了解的行为。如果我是正确的,那么增加采样率或减少跳跃长度应该可以最大限度地减少问题,但我想获得完美的节拍器计时,因为这对我正在构建的应用程序至关重要。