43

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

我看过这篇 gamedev 文章,这绝对没有帮助。我经历并试图实施他正在做的事情,但它只是没有用。

我知道必须有大量的解决方案来解决这个问题,因为很多 DJ 软件都可以做到,但我没有找到任何开源库或自己做的说明。

4

8 回答 8

27

使用滑动窗口 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 分析来说是一个很好的输入。当低音很安静时,你没有节拍,当它响亮时,你有节拍。

祝你好运!

于 2008-09-17T10:06:17.153 回答
15

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

这一切都在这里: http: //monket.net/dancing-monkeys-v2/Main_Page

于 2008-09-17T09:30:33.947 回答
8

并不是说我知道如何实现这一点,而是从音频工程的角度来看,您需要先进行过滤。低音鼓击打将是第一个检查。一个低通滤波器可以为您提供低于 200Hz 的任何内容,应该可以为您提供非常清晰的低音鼓画面。可能还需要一个门来清除来自其他具有如此低谐波的乐器的杂波。

接下来要检查的是军鼓命中。你必须均衡这个。军鼓发出的“裂纹”大约是记忆中的 1.5kHz,但你肯定需要对它进行门控。

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

于 2008-09-17T03:04:18.120 回答
6

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

您可以执行以下操作:

  1. 计算信号在 5 毫秒内的平均(均方根)响度。(以前从未这样做过,我不知道一个好的块大小是多少。)
  2. 使用 FFT 算法对“阻塞”信号进行傅里叶变换。
  3. 找到变换后信号中幅度最大的分量。

傅里叶变换基本上是一种计算信号中所有频率强度的方法。如果您对“阻塞”信号执行此操作,则节拍的频率有望成为最强的频率。

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

于 2008-09-17T02:57:55.437 回答
6

我发现这个库似乎有一个非常可靠的实现来检测Beats per Minutehttps://github.com/owoudenberg/soundtouch.net

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

于 2012-04-26T23:19:55.163 回答
1

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

于 2010-11-18T20:45:35.897 回答
0

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

于 2009-03-20T21:44:14.710 回答
0

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

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

于 2015-03-08T10:46:10.560 回答