gpt4 book ai didi

c# - 帮助实现这个节拍检测算法?

转载 作者:太空狗 更新时间:2023-10-29 23:34:09 24 4
gpt4 key购买 nike

我最近尝试实现在这里找到的节拍检测代码,即 Derivation 和 Combfilter 算法 #1::http://archive.gamedev.net/reference/programming/features/beatdetection/page2.asp

我不太确定我是否成功实现了它,因为我没有得到好的结果。我想知道是否有人成功地实现了这个,或者只是针对那些想要提供一般帮助的好人。这是我的实现:

//Cycle through Tempo's (60 to 200) incrementing each time by 10
for (int i = (int)mintempo; i <= maxtempo; i += 10)
{
//Clear variables to be used
curtempo = i;
fftPulse.Clear();
offset = 0;
energy = 0;
short[] prevBuffer = null;

//Calculate ti
ti = (60 / curtempo) * 44100;
ti = Math.Round(ti, 0);

//Generate pulse train
for (int j = 0; j < pulseTrain.Length; j++)
{
if ((j % ti) == 0)
pulseTrain[j] = short.MaxValue;
else
pulseTrain[j] = 0;
}

//Compute FFT of the pulseTrain array
while (offset < pulseTrain.Length)
{
//Generate block samples (1024 is my blocksize)
short[] fftPulseBuffer = new short[po.blocksize / 2];

//Store samples from pulseTrain in a 1024 block buffer for passing to the FFT algorithm
index = 0;
for (int j = offset; j < (offset + (po.blocksize / 2)) && j < pulseTrain.Length; j++)
{
fftPulseBuffer[index] = pulseTrain[j];
index++;
}

//Initialize prevBuffer, which contains samples from the previous block, used in conjunction with the current block for the FFT
if (prevBuffer == null)
prevBuffer = new short[po.blocksize / 2];

//Calculate the FFT using the current and previous blocks
fftPulse.Add(CalculateFFT(fftPulseBuffer,prevBuffer));

//Set prevBuffer and increment to next block start position
prevBuffer = fftPulseBuffer;
offset += (po.blocksize / 2);
}

//Calculate energy
for (int j = 0; j < intendomainarr.Count; j++)
{
double[] signalarr = intendomainarr[j];
double[] pulsearr = fftPulse[j];
for (int x = 0; x < signalarr.Length; x++)
{
energy += Math.Abs(signalarr[x] * pulsearr[x]);
}
}

//Get current best tempo match
if (energy > maxenergy)
{
chosentempo = curtempo;
maxenergy = energy;
}
}

我得到的结果总是很高,通常在 190 到 200BPM 左右,但事实并非如此,因为我的 .wav 文件的速度仅在 60-120BPM 之间。

请注意,我使用的是 .WAV 文件(44.1Khz,16 位,单声道),因此对某些公式进行了一些修改(即计算能量)以仅适用于一个 channel 。我想确认我的实现是否有任何差异?我不担心 FFT 部分,因为我为此使用了一个库。

非常感谢!

最佳答案

绘制能量与频率的关系图。

我认为您会发现谐波与基本信号具有几乎相同的能量,如果实际频率落在频率区间的中间位置,则二次谐波的峰值被采样并且很容易将两个样本击败到频率区间的任一侧真实频率。

您需要稍微惩罚较高的频率以克服这种影响。


请注意,虽然 C# 不是实时实现此类算法或批量处理的不合理选择,但它对于算法开发和调整来说是可怕的。我建议使用 MatLab(或免费的克隆 Octave)来获得正确的算法,并且只有在它处理某些测试用例时,才将代码转换为 C#(或 C++)。

关于c# - 帮助实现这个节拍检测算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6563135/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com