首页 / 知识

关于c#:实时音频输入的每分钟节拍数

2023-04-16 08:39:00

关于c#:实时音频输入的每分钟节拍数

Beats per minute from real-time audio input

我想编写一个简单的C#应用程序来监视输入音频,并为我提供每分钟的当前心跳(滚动平均值)。

我看过这篇关于gamedev的文章,那绝对没有帮助。 我经历了一下,试图实现他正在做的事情,但是那没有用。

我知道必须有很多解决方案,因为很多DJ软件都可以做到这一点,但是我自己没有找到任何开源库或说明的运气。


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

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

将其提供给FFT算法:

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

您将得到一个真实的部分和一个虚构的部分。不要丢弃虚构部分。对虚部做同样的事情。虚部确实是与实相异相的pi / 2,但它仍然包含50%的频谱信息。

编辑:

计算功率而不是振幅,以便在大声时有一个高数字,在安静时有一个接近零的数字:

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

对于虚部也是如此。

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

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

如果要在流行音乐中找到BPM,则可能应该专注于低音。您可以通过将功率谱的下部相加来获得低音强度。使用哪个数字取决于采样频率:

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

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

这对于您的BPM分析是一个很好的输入。当低音很安静时,您没有节拍,而当低音很大时,您会跳动。

祝好运!


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

此处提供所有信息:http://monket.net/dancing-monkeys-v2/Main_Page


并不是我不知道如何实现这一点,但是从音频工程的角度来看,您需要首先进行过滤。低音鼓打击将是第一个检查。低通滤波器可以为您提供大约200Hz以下的任何频率,应该可以使您清晰地了解低音鼓。可能还需要一个门来清除谐波低的其他乐器的杂波。

下一个要检查的是小军鼓。您必须均衡这一个。圈套器发出的"裂痕"距离内存约1.5kHz,但是您必须明确限制这一点。

下一个挑战将是为时髦节拍制定一种算法。您将如何以编程方式找到节拍1?我想您会跟踪以前的节拍并使用与某物或另一物匹配的模式。因此,您可能需要一些酒吧才能准确找到节拍。然后还有计时问题,例如4 / 4、3 / 4、6 / 8,哇,我无法想象要准确地做到这一点需要什么!我相信对于音频硬件/软件公司来说,这是值得的。


这绝不是一个简单的问题。我将只给您一个概述。

您可以执行以下操作:

  • 计算信号块(例如5毫秒)的平均(均方根)响度。 (以前从未做过,我不知道合适的块大小是多少。)
  • 使用FFT算法对"阻塞"信号进行傅立叶变换。
  • 在变换后的信号中找到幅度最大的分量。
  • 傅立叶变换基本上是一种计算信号中所有频率强度的方法。如果您对"阻塞"信号执行此操作,则拍子的频率有望成为最强的拍子。

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


    我找到了这个库,它似乎可以很好地实现每分钟节拍的检测。
    http://soundtouchdotnet.codeplex.com/

    它基于http://www.surina.net/soundtouch/index.html,在许多DJ项目中都使用了http://www.surina.net/soundtouch/applications.html


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


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

    可以在以下位置找到有关此特定功能的详细信息
    http://bass.radio42.com/help/html/0833aa5a-3be9-037c-66f2-9adfd42a8512.htm。


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


    实时应用程序输入音频

    最新内容

    相关内容

    猜你喜欢