aubio 是否有办法检测一段音频中缺少音调元素的部分——只有节奏?我测试了一首开始时有 16 秒节奏的音乐,但所有的 aubiopitch 和 aubionotes 算法似乎都能在节奏部分检测到音调。能否以某种方式对其进行调整以区分音调和非音调起始?或者有没有相关的图书馆可以做到这一点?
2 回答
过去几天一直很忙-但今天开始研究这个...
我想这需要一段时间才能完善,但我想我会给你一些想法和一些我已经开始着手攻击这个问题的代码!
首先,伪代码是设计初始方法的好方法。
1/ 用于import matplotlib.pyplot as plt
对音频进行频谱分析,并绘制各种 fft 和音频信号。
2/import numpy as np
用于基本的类数组结构处理。
(我知道这不仅仅是伪代码,但是嘿:-)
3/plt.specgram
创建音频的频谱图。除了它创建的图像(可用于开始手动解构您的音频文件)之外,它还返回 4 个结构。
例如
ffts,freqs,times,img = plt.specgram(signal,Fs=44100)
ffts
是一个二维数组,其中列是ffts
时间段(行)的(快速傅立叶变换)。
普通香草specgram
分析了 256 个样本的时间段,每次向前步进 128 个样本。
这以相当快的速度提供了一个非常低分辨率的频率阵列。
由于音符在以或多或少 10 赫兹播放时合并为一个声音,我决定使用这些specgram
选项将音频分成 4096 个样本长度(大约 10 赫兹),每 2048 个样本向前步进(即每秒 20 次)。
这提供了不错的频率分辨率,相隔 20 秒的时间段比人们感知单个音符的速度要快。
这意味着调用specgram
如下:
plt.specgram(signal,Fs=44100,NFFT=4096,noverlap=2048,mode='magnitude')
(注意模式 - 这似乎给了我 0 - 0.1 之间的幅度:我有一个问题,fft
没有给我与音频信号相同比例的幅度(你可能已经看到我发布的问题)。但我们在这里。 ..
4/接下来我决定去除ffts
返回的噪音。这意味着我们可以专注于freqs
适当的幅度,并将始终存在的噪声归零ffts
(根据我的经验)。
这是(是)我的功能:
def gate(signal,minAmplitude):
return np.array([int((((a-minAmplitude)+abs(a-minAmplitude))/2) > 0) * a for a in signal])
看起来有点疯狂——我相信一个合适的数学家可以想出更有效的东西——但这是我能发明的最好的东西。它将幅度小于 的任何频率归零minAmplitude
。
ffts
这是从返回的调用它的相关代码,plt.specgram
如下所示,我的函数涉及更多,因为它是类的一部分,并且具有它引用的其他函数 - 但这应该足够了:
def fft_noise_gate(minAmplitude=0.001,check=True):
'''
zero the amplitudes of frequencies
with amplitudes below minAmplitude
across self.ffts
check - plot middle fft just because!
'''
nffts = ffts.shape[1]
gated_ffts = []
for f in range(nffts):
fft = ffts[...,f]
# Anyone got a more efficient noise gate formula? Best I could think up!
fft_gated = gate(fft,minAmplitude)
gated_ffts.append(fft_gated)
ffts = np.array(gated_ffts)
if check:
# plot middle fft just to see!
plt.plot(ffts[int(nffts/2)])
plt.show(block=False)
return ffts
这应该给你一个开始我仍在努力,当我有进一步的时候会回复你 - 但如果你有任何想法,请分享它们。
无论如何,我的策略是:
1/ 找到峰值(即任何声音的开始),然后 2/ 寻找同时上升和下降的频率范围(即组成一个声音)。
和
3/ 将它们区分为单独的乐器(更具体地说是声源),并绘制它们的时间和幅度以创建您的分析(乐谱)。
希望你玩得开心——我知道我是。
正如我所说的任何想法......
问候
托尼
使用频谱分析仪检测具有高幅度的部分。如果您进行编程 - 您可以获取每个部分并对存在的频率(和幅度)进行平均,以让您了解创建该幅度峰值所涉及的仪器。
希望对您有所帮助-如果您使用的是python,我可以为您提供一些如何编程的指示!?
问候
托尼