MatheuGrondin
MatheuGrondin

Reputation: 107

Detect audio peak using gstreamer plugin

I'm developing a plugin in C that detects audio peaks using gstreamer-1.0. I don't really have any knowledge about audio programming and so far, my plugin can only detect sound impulsion (if there is no audio, nothing happens, if there is sound, I print the energy).

Here is the sample code of my (really simple) algorithm.

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);
}

If the audio source is, for exemple, a simple hand clap or kick drum only, my plugin detects the audio peak just fine. But when the audio source is a song, my plugin is constantly detecting sound impulsion (always over the threshold).

My solution for that issue was to add a low-pass filter so only bass sound would be detected. By doing that, I'm cutting every part of the song containing high frequencies only and this is not what I want (will not work for high frequency beats).

So my question is : Does anyone have an idea on how to detect beats (audio impulsion) without cutting the high frequencies ? Tanks to everyone and hope that my question is clear !

Upvotes: 1

Views: 899

Answers (1)

Ro Step an ovr
Ro Step an ovr

Reputation: 51

You should measure energy not peak. There is a great method to calculate energy. Use variance formula from statistics. You need count square of sum and sum of squares for all points within an interval of 20 - 50 milliseconds. Using the variance formula you get the energy. The formula is here http://staff.icdi.wvu.edu/djhstats/variance1.JPG

As an alternative you may use the existing plugin level in the set of good plugins.

Upvotes: 2

Related Questions