level

## level level — RMS/Peak/Decaying Peak Level messager for audio/raw |

## Synopsis

    struct              GstLevel;

## Object Hierarchy

      GObject
       +----GInitiallyUnowned
             +----GstObject
                   +----GstElement
                         +----GstBaseTransform
                               +----GstLevel

## Properties

      "interval"                 guint64               : Read / Write
      "message"                  gboolean              : Read / Write
      "peak-falloff"             gdouble               : Read / Write
      "peak-ttl"                 guint64               : Read / Write

## Description

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 the time to live. When the decaying peak level drops, it does so at the decay rate as specified by the the peak falloff rate.

- GValueArray of gdouble `"rms"`: the Root Mean Square (or average power) level in dB for each channel

### Example application

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    /* 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., 59 Temple Place - Suite 330,
     * Boston, MA 02111-1307, 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 *arr;

          gint i;

          if (!gst_structure_get_clock_time (s, "endtime", &endtime))
            g_warning ("Could not parse endtime");
          /* we can get the number of channels as the length of any of the value
           * lists */
          array_val = gst_structure_get_value (s, "rms");
          arr = (GValueArray *) g_value_get_boxed (array_val);
          channels = 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);
            array_val = gst_structure_get_value (s, "rms");
            arr = (GValueArray *) g_value_get_boxed (array_val);
            value = g_value_array_get_nth (arr, i);
            rms_dB = g_value_get_double (value);
            array_val = gst_structure_get_value (s, "peak");
            arr = (GValueArray *) g_value_get_boxed (array_val);
            value = g_value_array_get_nth (arr, i);
            peak_dB = g_value_get_double (value);
            array_val = gst_structure_get_value (s, "decay");
            arr = (GValueArray *) g_value_get_boxed (array_val);
            value = g_value_array_get_nth (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), "message", 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;
    }

## Synopsis

### Element Information

plugin | level
author | Thomas Vander Stichele <thomas at apestaart dot org>
class | Filter/Analyzer/Audio

### Element Pads

name | sink
direction | sink
presence | always
details | audio/x-raw, format=(string){ S8, S16LE, S32LEF32LE, F64LE }, layout=(string)interleaved, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]

name | src
direction | source
presence | always
details | audio/x-raw, format=(string){ S8, S16LE, S32LEF32LE, F64LE }, layout=(string)interleaved, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]

## Details

### struct GstLevel

    struct GstLevel;

Opaque data structure.

## Property Details

### The `"interval"` property

      "interval"                 guint64               : Read / Write

Interval of time between message posts (in nanoseconds).

Allowed values: >= 1

Default value: 100000000

### The `"message"` property

      "message"                  gboolean              : Read / Write

Post a level message for each passed interval.

Default value: TRUE

### The `"peak-falloff"` property

      "peak-falloff"             gdouble               : Read / Write

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

Allowed values: >= 0

Default value: 10

### The `"peak-ttl"` property

      "peak-ttl"                 guint64               : Read / Write

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

Default value: 300000000