level

Level analyses incoming audio buffers and, if the message property is TRUE, generates an element message named level: after each interval of time given by the interval property. The message's structure contains these fields:

  • GstClockTime timestamp: the timestamp of the buffer that triggered the message.
  • GstClockTime stream-time: the stream time of the buffer.
  • GstClockTime running-time: the running_time of the buffer.
  • GstClockTime duration: the duration of the buffer.
  • GstClockTime endtime: the end time of the buffer that triggered the message as stream time (this is deprecated, as it can be calculated from stream-time + duration)
  • GValueArray of gdouble peak: the peak power level in dB for each channel
  • GValueArray of gdouble decay: the decaying peak power level in dB for each channel The decaying peak level follows the peak level, but starts dropping if no new peak is reached after the time given by the peak-ttl. When the decaying peak level drops, it does so at the decay rate as specified by the peak-falloff.
  • GValueArray of gdouble rms: the Root Mean Square (or average power) level in dB for each channel

Example application

/* GStreamer
 * Copyright (C) 2000,2001,2002,2003,2005
 *           Thomas Vander Stichele <thomas at apestaart dot org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <string.h>
#include <math.h>

#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include <gst/gst.h>

static gboolean
message_handler (GstBus * bus, GstMessage * message, gpointer data)
{

  if (message->type == GST_MESSAGE_ELEMENT) {
    const GstStructure *s = gst_message_get_structure (message);
    const gchar *name = gst_structure_get_name (s);

    if (strcmp (name, "level") == 0) {
      gint channels;
      GstClockTime endtime;
      gdouble rms_dB, peak_dB, decay_dB;
      gdouble rms;
      const GValue *array_val;
      const GValue *value;
      GValueArray *rms_arr, *peak_arr, *decay_arr;
      gint i;

      if (!gst_structure_get_clock_time (s, "endtime", &endtime))
        g_warning ("Could not parse endtime");

      /* the values are packed into GValueArrays with the value per channel */
      array_val = gst_structure_get_value (s, "rms");
      rms_arr = (GValueArray *) g_value_get_boxed (array_val);

      array_val = gst_structure_get_value (s, "peak");
      peak_arr = (GValueArray *) g_value_get_boxed (array_val);

      array_val = gst_structure_get_value (s, "decay");
      decay_arr = (GValueArray *) g_value_get_boxed (array_val);

      /* we can get the number of channels as the length of any of the value
       * arrays */
      channels = rms_arr->n_values;
      g_print ("endtime: %" GST_TIME_FORMAT ", channels: %d\n",
          GST_TIME_ARGS (endtime), channels);
      for (i = 0; i < channels; ++i) {

        g_print ("channel %d\n", i);
        value = g_value_array_get_nth (rms_arr, i);
        rms_dB = g_value_get_double (value);

        value = g_value_array_get_nth (peak_arr, i);
        peak_dB = g_value_get_double (value);

        value = g_value_array_get_nth (decay_arr, i);
        decay_dB = g_value_get_double (value);
        g_print ("    RMS: %f dB, peak: %f dB, decay: %f dB\n",
            rms_dB, peak_dB, decay_dB);

        /* converting from dB to normal gives us a value between 0.0 and 1.0 */
        rms = pow (10, rms_dB / 20);
        g_print ("    normalized rms value: %f\n", rms);
      }
    }
  }
  /* we handled the message we want, and ignored the ones we didn't want.
   * so the core can unref the message for us */
  return TRUE;
}

int
main (int argc, char *argv[])
{
  GstElement *audiotestsrc, *audioconvert, *level, *fakesink;
  GstElement *pipeline;
  GstCaps *caps;
  GstBus *bus;
  guint watch_id;
  GMainLoop *loop;

  gst_init (&argc, &argv);

  caps = gst_caps_from_string ("audio/x-raw,channels=2");

  pipeline = gst_pipeline_new (NULL);
  g_assert (pipeline);
  audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
  g_assert (audiotestsrc);
  audioconvert = gst_element_factory_make ("audioconvert", NULL);
  g_assert (audioconvert);
  level = gst_element_factory_make ("level", NULL);
  g_assert (level);
  fakesink = gst_element_factory_make ("fakesink", NULL);
  g_assert (fakesink);

  gst_bin_add_many (GST_BIN (pipeline), audiotestsrc, audioconvert, level,
      fakesink, NULL);
  if (!gst_element_link (audiotestsrc, audioconvert))
    g_error ("Failed to link audiotestsrc and audioconvert");
  if (!gst_element_link_filtered (audioconvert, level, caps))
    g_error ("Failed to link audioconvert and level");
  if (!gst_element_link (level, fakesink))
    g_error ("Failed to link level and fakesink");

  /* make sure we'll get messages */
  g_object_set (G_OBJECT (level), "post-messages", TRUE, NULL);
  /* run synced and not as fast as we can */
  g_object_set (G_OBJECT (fakesink), "sync", TRUE, NULL);

  bus = gst_element_get_bus (pipeline);
  watch_id = gst_bus_add_watch (bus, message_handler, NULL);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* we need to run a GLib main loop to get the messages */
  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (loop);

  g_source_remove (watch_id);
  g_main_loop_unref (loop);
  return 0;
}

Hierarchy

GObject
    ╰──GInitiallyUnowned
        ╰──GstObject
            ╰──GstElement
                ╰──GstBaseTransform
                    ╰──level

Factory details

Authors: – Thomas Vander Stichele

Classification:Filter/Analyzer/Audio

Rank – none

Plugin – level

Package – GStreamer Good Plug-ins

Pad Templates

sink

audio/x-raw:
         format: { S8, S16LE, S32LE, F32LE, F64LE }
         layout: interleaved
           rate: [ 1, 2147483647 ]
       channels: [ 1, 2147483647 ]

Presencealways

Directionsink

Object typeGstPad


src

audio/x-raw:
         format: { S8, S16LE, S32LE, F32LE, F64LE }
         layout: interleaved
           rate: [ 1, 2147483647 ]
       channels: [ 1, 2147483647 ]

Presencealways

Directionsrc

Object typeGstPad


Properties

audio-level-meta

“audio-level-meta” gboolean

If TRUE, generate or update GstAudioLevelMeta on output buffers.

Flags : Read / Write

Default value : false

Since : 1.20


interval

“interval” guint64

Interval of time between message posts (in nanoseconds)

Flags : Read / Write

Default value : 100000000


message

“message” gboolean

Post messages on the bus with level information.

Flags : Read / Write

Default value : true

deprecated :

use the post-messages property


peak-falloff

“peak-falloff” gdouble

Decay rate of decay peak after TTL (in dB/sec)

Flags : Read / Write

Default value : 10


peak-ttl

“peak-ttl” guint64

Time To Live of decay peak before it falls back (in nanoseconds)

Flags : Read / Write

Default value : 300000000


post-messages

“post-messages” gboolean

Post messages on the bus with level information.

Flags : Read / Write

Default value : true

Since : 1.1.0


The results of the search are