我正在使用gstreamer-1.0在C中开发一个检测音频峰值的插件。我对音频编程没有任何了解,到目前为止,我的插件只能检测声音冲击(如果没有音频,没有任何反应,如果有声音,我打印能量)。
以下是我(非常简单)算法的示例代码。
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);
}
如果音频源仅用于简单的手拍或踢鼓,我的插件就可以检测音频峰值。但是当音频源是一首歌时,我的插件会不断检测声音冲击(总是超过阈值)。
我对此问题的解决方案是添加一个低通滤波器,以便只检测到低音。通过这样做,我只剪切包含高频的歌曲的每个部分,这不是我想要的(不适用于高频节拍)。
所以我的问题是:有没有人知道如何在不削减高频的情况下检测节拍(音频冲击)?坦克给大家,希望我的问题很清楚!
答案 0 :(得分:2)
你应该测量能量而不是峰值。有一种很好的计算能量的方法。使用统计中的方差公式。您需要在20 - 50毫秒的间隔内计算所有点的总和和平方和。使用方差公式可以获得能量。公式就在这里 http://staff.icdi.wvu.edu/djhstats/variance1.JPG
作为替代方案,您可以使用好的插件集中的现有插件级别。