spectrum

The Spectrum element analyzes the frequency spectrum of an audio signal. If the post-messages property is TRUE, it sends analysis results as element messages named spectrum after each interval of time given by the interval property.

The message's structure contains some combination of 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)
  • A GST_TYPE_LIST value of gfloat magnitude: the level for each frequency band in dB. All values below the value of the threshold property will be set to the threshold. Only present if the message-magnitude property is TRUE.
  • A GST_TYPE_LIST of gfloat phase: The phase for each frequency band. The value is between -pi and pi. Only present if the message-phase property is TRUE.

If multi-channel property is set to true. magnitude and phase fields will be each a nested GST_TYPE_ARRAY value. The first dimension are the channels and the second dimension are the values.

Example application

/* GStreamer
 * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
 * Copyright (C) 2008 Jan Schmidt <jan.schmidt@sun.com>
 *
 * 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gst/gst.h>

static guint spect_bands = 20;

#define AUDIOFREQ 32000

/* receive spectral data from element message */
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);
    GstClockTime endtime;

    if (strcmp (name, "spectrum") == 0) {
      const GValue *magnitudes;
      const GValue *phases;
      const GValue *mag, *phase;
      gdouble freq;
      guint i;

      if (!gst_structure_get_clock_time (s, "endtime", &endtime))
        endtime = GST_CLOCK_TIME_NONE;

      g_print ("New spectrum message, endtime %" GST_TIME_FORMAT "\n",
          GST_TIME_ARGS (endtime));

      magnitudes = gst_structure_get_value (s, "magnitude");
      phases = gst_structure_get_value (s, "phase");

      for (i = 0; i < spect_bands; ++i) {
        freq = (gdouble) ((AUDIOFREQ / 2) * i + AUDIOFREQ / 4) / spect_bands;
        mag = gst_value_list_get_value (magnitudes, i);
        phase = gst_value_list_get_value (phases, i);

        if (mag != NULL && phase != NULL) {
          g_print ("band %d (freq %g): magnitude %f dB phase %f\n", i, freq,
              g_value_get_float (mag), g_value_get_float (phase));
        }
      }
      g_print ("\n");
    }
  }
  return TRUE;
}

int
main (int argc, char *argv[])
{
  GstElement *bin;
  GstElement *src, *audioconvert, *spectrum, *sink;
  GstBus *bus;
  GstCaps *caps;
  GMainLoop *loop;

  gst_init (&argc, &argv);

  bin = gst_pipeline_new ("bin");

  src = gst_element_factory_make ("audiotestsrc", "src");
  g_object_set (G_OBJECT (src), "wave", 0, "freq", 6000.0, NULL);
  audioconvert = gst_element_factory_make ("audioconvert", NULL);
  g_assert (audioconvert);

  spectrum = gst_element_factory_make ("spectrum", "spectrum");
  g_object_set (G_OBJECT (spectrum), "bands", spect_bands, "threshold", -80,
      "post-messages", TRUE, "message-phase", TRUE, NULL);

  sink = gst_element_factory_make ("fakesink", "sink");
  g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);

  gst_bin_add_many (GST_BIN (bin), src, audioconvert, spectrum, sink, NULL);

  caps = gst_caps_new_simple ("audio/x-raw",
      "rate", G_TYPE_INT, AUDIOFREQ, NULL);

  if (!gst_element_link (src, audioconvert) ||
      !gst_element_link_filtered (audioconvert, spectrum, caps) ||
      !gst_element_link (spectrum, sink)) {
    fprintf (stderr, "can't link elements\n");
    exit (1);
  }
  gst_caps_unref (caps);

  bus = gst_element_get_bus (bin);
  gst_bus_add_watch (bus, message_handler, NULL);
  gst_object_unref (bus);

  gst_element_set_state (bin, 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);

  gst_element_set_state (bin, GST_STATE_NULL);

  gst_object_unref (bin);

  return 0;
}

Hierarchy

GObject
    ╰──GInitiallyUnowned
        ╰──GstObject
            ╰──GstElement
                ╰──GstBaseTransform
                    ╰──GstAudioFilter
                        ╰──spectrum

Factory details

Authors: – Erik Walthinsen , Stefan Kost , Sebastian Dröge

Classification:Filter/Analyzer/Audio

Rank – none

Plugin – gstspectrum

Package – GStreamer Good Plug-ins git

Pad Templates

sink

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

Presencealways

Directionsink


src

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

Presencealways

Directionsrc


Properties

bands

“bands” guint *

Number of frequency bands

Flags : Read / Write

Default value : 128


interval

“interval” guint64 *

Interval of time between message posts (in nanoseconds)

Flags : Read / Write

Default value : 100000000


message-magnitude

“message-magnitude” gboolean *

Whether to add a 'magnitude' field to the structure of any 'spectrum' element messages posted on the bus

Flags : Read / Write

Default value : true


message-phase

“message-phase” gboolean *

Whether to add a 'phase' field to the structure of any 'spectrum' element messages posted on the bus

Flags : Read / Write

Default value : false


multi-channel

“multi-channel” gboolean *

Send separate results for each channel

Flags : Read / Write

Default value : false


name

“name” gchararray *

The name of the object

Flags : Read / Write / Construct

Default value : NULL


parent

“parent” GstObject *

The parent of the object

Flags : Read / Write


post-messages

“post-messages” gboolean *

Whether to post a 'spectrum' element message on the bus for each passed interval

Flags : Read / Write

Default value : true


qos

“qos” gboolean *

Handle Quality-of-Service events

Flags : Read / Write

Default value : false


threshold

“threshold” gint *

dB threshold for result. All lower values will be set to this

Flags : Read / Write

Default value : -60


The results of the search are