我正在用 C 开发一个插件,它使用 gstreamer-1.0 检测音频峰值。我对音频编程一无所知,到目前为止,我的插件只能检测声音脉冲(如果没有音频,什么也不会发生,如果有声音,我会打印能量)。
这是我的(非常简单的)算法的示例代码。
gfloat energy_of_sample(guint8 array[], int num_elements, gfloat *p)
{
gfloat energy=0.f;
for(int i=0 ; i<num_elements ; i++)
{
energy += array[i]*array[i]/4096;
if (*p < (array[i]*array[i]/4096)) *p = array[i]*array[i]/4096;
}
return energy/num_elements;
}
static void
audio_process(GstBPMdetect *filter, GstBuffer *music)
{
GstMapInfo info;
gint threshold = 6;
// gets the information of the buffer and put it in "info"
gst_buffer_map (music, &info, GST_MAP_READ);
// calculate the average of the buffer data
gfloat energy = 0;
gfloat peak = 0;
energy = energy_of_sample(info.data, info.size, &peak);
if (energy >= threshold )g_print("energy : %f , peak : %f \n", energy,peak);
}
例如,如果音频源只是简单的拍手声或底鼓声,我的插件就能很好地检测到音频峰值。但是当音频源是一首歌时,我的插件会不断检测声音脉冲(总是超过阈值)。
我针对该问题的解决方案是添加一个低通滤波器,这样就只会检测到低音。通过这样做,我削减了歌曲中仅包含高频的每个部分,这不是我想要的(不适用于高频节拍)。
所以我的问题是:有没有人知道如何在不削减高频的情况下检测节拍(音频脉冲)?谢谢大家,希望我的问题很清楚!
最佳答案
您应该测量能量而不是峰值。有一种计算能量的好方法。使用统计中的方差公式。您需要计算 20 - 50 毫秒间隔内所有点的总和的平方和。使用方差公式可以得到能量。公式在这里 http://staff.icdi.wvu.edu/djhstats/variance1.JPG
作为替代方案,您可以使用优秀插件集中现有的插件级别。
关于c - 使用 gstreamer 插件检测音频峰值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23942853/