对音频信号进行切片以检测音调

2024-09-29 23:19:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我用Librosa来转录单声道吉他音频信号。在

我认为,这将是一个很好的开端,根据发作时间对信号进行“切片”,以便在正确的时间检测音符的变化。在

Librosa提供了一个function,它在开始时间之前检测局部极小值。我检查了那些时间,它们是正确的。在

这是原始信号的波形和最小值的时间。在

[ 266240  552960  840704 1161728 1427968 1735680 1994752]

waveform

演奏的旋律是E4,F4,F#4…,B4。在

因此,理想的结果应该是:330Hz,350Hz,…,493Hz(近似值)。在

如您所见,minima数组中的时间表示音符播放前的时间。在

然而,对于切片信号(10-12秒,每片只有一个音符),我的频率检测方法的效果非常差。我很困惑,因为我在代码中看不到任何错误:

^{pr2}$

其中freq_from函数直接取自here。在

我认为这些方法的精确度很差,但我得到了一些疯狂的结果。具体来说,freq_from_hps返回:

1.33818658287
1.2078047577
0.802142642257
0.531096911977
0.987532329094
0.559638134414
0.953497587952
0.628980979055

这些值应该是8个相应切片的8个音高(以赫兹为单位)。在

freq_from_fft返回相似的值,而freq_from_autocorr返回一些更“正常”的值,但也有一些接近10000Hz的随机值:

242.748000585
10650.0394232
275.25299319
145.552578747
154.725859019
7828.70876515
174.180627765
183.731497068

这是整个信号的频谱图:

wholespectrogram

例如,这是切片1的光谱图(E4注): spectrograme4

如您所见,切片已正确完成。然而,有几个问题。首先,在光谱图中有一个倍频程的问题。我本来以为会有问题的。然而,我从上面提到的3种方法得到的结果却很奇怪。在

这是我的信号处理理解问题还是代码问题?在


Tags: 方法代码from信号时间切片function光谱
1条回答
网友
1楼 · 发布于 2024-09-29 23:19:56

Is this an issue with my signal processing understanding or my code?

你的代码在我看来不错。在

你想要检测的频率是你音调的基频(这个问题也被称为“f0估计”)。在

所以在使用freq_from_fft之类的东西之前,我会对信号进行带通滤波,以消除垃圾瞬态和低频噪声信号中的那些,但与你的问题无关的东西。在

想想,你的基频在哪个范围内。对于E2(82赫兹)到F6(1397赫兹)的原声吉他。这意味着您可以去掉低于~80赫兹和高于~1400赫兹的任何东西(关于带通示例,请参见here)。过滤之后,进行峰值检测以找到音调(假设基频实际上具有最多的能量)。在

另一个策略可能是,忽略每个切片的第一个X样本,因为它们往往是撞击的,本质上不是和声的,无论如何也不会给你太多信息。所以,你的切片,只需看看最后90%的样本。在

总之,对于f0或基频估计有大量的工作要做。一个好的起点是ISMIR论文。在

最后,但并非最不重要的是,Librosa的piptrack函数可以满足您的需要。在

相关问题 更多 >

    热门问题