实时音频输入的每分钟节拍数

时间:2008-09-17 02:51:14

标签: c# audio signal-processing

我想编写一个简单的C#应用​​程序来监听线路输入音频并给出每分钟的当前(好的,滚动平均)节拍。

我见过this gamedev article,这绝对没有帮助。我经历了并尝试实施他正在做的事情,但它只是没有用。

我知道必须有大量的解决方案,因为很多DJ软件都能做到这一点,但我没有找到任何开源库或自己做的指示。

8 个答案:

答案 0 :(得分:26)

使用滑动窗口FFT计算功率谱: 拿1024个样本:

double[] signal = stream.Take(1024);

将其输入FFT算法:

double[] real = new double[signal.Length];
double[] imag = new double[signal.Length);
FFT(signal, out real, out imag);

你会得到一个真实的部分和想象的部分。不要扔掉想象中的部分。对想象中的实际部分做同样的事情。虽然假想部分与真实部分是pi / 2异相,但它仍然包含50%的频谱信息。

编辑:

计算功率而不是振幅,这样当声音很大时你会有一个很高的数字,而当它很安静时它会接近零:

for (i=0; i < real.Length; i++) real[i] = real[i] * real[i];

同样对于想象部分。

for (i=0; i < imag.Length; i++) imag[i] = imag[i] * imag[i];

现在您拥有最后1024个样本的功率谱。频谱的第一部分是低频,频谱的最后部分是高频 频率。

如果你想在流行音乐中找到BPM,你应该专注于低音。您可以通过对功率谱的下半部分求和来获得低音强度。使用哪些数字取决于采样频率:

double bassIntensity = 0;
for (i=8; i < 96; i++) bassIntensity += real[i];

现在再次执行相同操作,但在计算新光谱之前将窗口移动256个样本。现在,您最终计算出每256个样本的bassIntensity。

这是您的BPM分析的一个很好的输入。当低音安静时你没有节拍,当它很响时你就会有节拍。

祝你好运!

答案 1 :(得分:15)

有一个名为Dancing Monkeys的出色项目,它在程序上从音乐中产生DDR舞步。它所做的大部分工作都基于(必然是非常准确的)节拍分析,他们的项目文章详细描述了各种节拍检测算法及其对任务的适用性。它们包括对每种算法的原始论文的引用。他们还为他们的解决方案发布了matlab代码。我相信你可以找到你需要的东西。

这里全部可用:http://monket.net/dancing-monkeys-v2/Main_Page

答案 2 :(得分:8)

不是我知道如何实现这一点,但从音频工程的角度来看,你需要先过滤。低音鼓点击将是第一个检查。低通滤波器可以为您提供低于200Hz的任何信号,可以为您提供非常清晰的低音鼓图像。也可能需要一个门来清除其他谐振器低的其他仪器的杂波。

接下来的检查将是网罗点击。你必须得到这个EQ。来自小军鼓的“裂缝”距离记忆大约1.5kHz,但你需要明确地控制它。

接下来的挑战是制定一个时髦的节拍算法。你会如何以编程方式找到1?我想你会跟踪以前的节拍,并使用匹配某些东西或其他东西的模式。所以,你可能需要几个小节才能准确找到节拍。然后有时间问题,如4 / 4,3 / 4,6 / 8,哇,我无法想象准确地做到这一点需要什么!我相信音频硬件/软件公司值得花一些钱。

答案 3 :(得分:6)

这绝不是一个容易的问题。我会尽量给你一个概述。

您可以做的事情如下:

  1. 计算信号的平均(均方根)响度,例如5毫秒。 (之前从未这样做过,我不知道块大小会是多少。)
  2. 使用FFT算法对“阻塞”信号进行傅里叶变换。
  3. 在变换后的信号中找到具有最大幅度的分量。
  4. 傅立叶变换基本上是计算信号中存在的所有频率的强度的方法。如果你对“阻塞”信号这样做,那么节拍的频率有望成为最强的。

    也许您需要首先应用过滤器,以专注于通常包含有关BPM的最多信息的特定频率(如低音)。

答案 4 :(得分:5)

我发现这个库似乎有一个非常可靠的实现,用于检测每分钟节拍数http://soundtouchdotnet.codeplex.com/

它基于http://www.surina.net/soundtouch/index.html,用于很多DJ项目http://www.surina.net/soundtouch/applications.html

答案 5 :(得分:1)

首先,Hallgrim正在制作的不是功率谱密度函数。任何信号中的统计周期都可以通过自相关函数得出。自相关信号的傅里叶变换是功率谱密度。除了0 Hz以外,PSD中的主导峰值将对应于信号中的有效周期(以Hz为单位)......

答案 6 :(得分:0)

简单的方法是让用户按节拍的节拍点击一个按钮,然后计算点击次数除以时间。

答案 7 :(得分:0)

我建议您查看BASS音频库和BASS.NET包装器。它有一个内置的BPMCounter类。

有关此特定功能的详细信息,请访问: http://bass.radio42.com/help/html/0833aa5a-3be9-037c-66f2-9adfd42a8512.htm