librosa.clicks 返回的错误信号

问题描述

我正在尝试使用 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]

这是另一种我不太了解的行为。如果我是正确的,那么增加采样率或减少跳跃长度应该可以最大限度地减少问题,但我想获得完美的节拍器计时,因为这对我正在构建的应用程序至关重要。

解决方法

我将点击作为 wav 文件导入到音频编辑器中,发现它在 1-2 个样本内是准确的。

起始检测算法并不完美,并且非常依赖于信号的瞬态。

我已经根据 onset_samples 绘制了波形图,即使在鸟瞰图中,您也可以看出开始时间并不一致。

onset vs waveform

底线:点击没问题。其发病检测已关闭。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...