/* GStreamer ReplayGain analysis
 *
 * Copyright (C) 2006 Rene Stadler <mail@renestadler.de>
 * 
 * gstrganalysis.c: Element that performs the ReplayGain analysis
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

/**
 * SECTION:element-rganalysis
 * @see_also: #GstRgVolume
 *
 * This element analyzes raw audio sample data in accordance with the proposed
 * <ulink url="http://replaygain.org">ReplayGain standard</ulink> for
 * calculating the ideal replay gain for music tracks and albums.  The element
 * is designed as a pass-through filter that never modifies any data.  As it
 * receives an EOS event, it finalizes the ongoing analysis and generates a tag
 * list containing the results.  It is sent downstream with a tag event and
 * posted on the message bus with a tag message.  The EOS event is forwarded as
 * normal afterwards.  Result tag lists at least contain the tags
 * #GST_TAG_TRACK_GAIN, #GST_TAG_TRACK_PEAK and #GST_TAG_REFERENCE_LEVEL.
 * 
 * Because the generated metadata tags become available at the end of streams,
 * downstream muxer and encoder elements are normally unable to save them in
 * their output since they generally save metadata in the file header.
 * Therefore, it is often necessary that applications read the results in a bus
 * event handler for the tag message.  Obtaining the values this way is always
 * needed for <link linkend="GstRgAnalysis--num-tracks">album processing</link>
 * since the album gain and peak values need to be associated with all tracks of
 * an album, not just the last one.
 * 
 * <refsect2>
 * <title>Example launch lines</title>
 * |[
 * gst-launch-1.0 -t audiotestsrc wave=sine num-buffers=512 ! rganalysis ! fakesink
 * ]| Analyze a simple test waveform
 * |[
 * gst-launch-1.0 -t filesrc location=filename.ext ! decodebin \
 *     ! audioconvert ! audioresample ! rganalysis ! fakesink
 * ]| Analyze a given file
 * |[
 * gst-launch-1.0 -t gnomevfssrc location=http://replaygain.hydrogenaudio.org/ref_pink.wav \
 *     ! wavparse ! rganalysis ! fakesink
 * ]| Analyze the pink noise reference file
 * <para>
 * The above launch line yields a result gain of +6 dB (instead of the expected
 * +0 dB).  This is not in error, refer to the #GstRgAnalysis:reference-level
 * property documentation for more information.
 * </para>
 * </refsect2>
 * <refsect2>
 * <title>Acknowledgements</title>
 * <para>
 * This element is based on code used in the <ulink
 * url="http://sjeng.org/vorbisgain.html">vorbisgain</ulink> program and many
 * others.  The relevant parts are copyrighted by David Robinson, Glen Sawyer
 * and Frank Klemm.
 * </para>
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/audio/audio.h>

#include "gstrganalysis.h"
#include "replaygain.h"

GST_DEBUG_CATEGORY_STATIC (gst_rg_analysis_debug);
#define GST_CAT_DEFAULT gst_rg_analysis_debug

/* Default property value. */
#define FORCED_DEFAULT TRUE
#define DEFAULT_MESSAGE FALSE

enum
{
  PROP_0,
  PROP_NUM_TRACKS,
  PROP_FORCED,
  PROP_REFERENCE_LEVEL,
  PROP_MESSAGE
};

/* The ReplayGain algorithm is intended for use with mono and stereo
 * audio.  The used implementation has filter coefficients for the
 * "usual" sample rates in the 8000 to 48000 Hz range. */
#define REPLAY_GAIN_CAPS "audio/x-raw," \
  "format = (string) { "GST_AUDIO_NE(F32)","GST_AUDIO_NE(S16)" }, "     \
  "layout = (string) interleaved, "                                     \
  "channels = (int) 1, "                                                \
  "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, "     \
  "44100, 48000 }; "                                                    \
  "audio/x-raw,"                                                        \
  "format = (string) { "GST_AUDIO_NE(F32)","GST_AUDIO_NE(S16)" }, "     \
  "layout = (string) interleaved, "                                     \
  "channels = (int) 2, "                                                \
  "channel-mask = (bitmask) 0x3, "                                      \
  "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, "     \
  "44100, 48000 }"

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (REPLAY_GAIN_CAPS));

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (REPLAY_GAIN_CAPS));

#define gst_rg_analysis_parent_class parent_class
G_DEFINE_TYPE (GstRgAnalysis, gst_rg_analysis, GST_TYPE_BASE_TRANSFORM);

static void gst_rg_analysis_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_rg_analysis_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_rg_analysis_start (GstBaseTransform * base);
static gboolean gst_rg_analysis_set_caps (GstBaseTransform * base,
    GstCaps * incaps, GstCaps * outcaps);
static GstFlowReturn gst_rg_analysis_transform_ip (GstBaseTransform * base,
    GstBuffer * buf);
static gboolean gst_rg_analysis_sink_event (GstBaseTransform * base,
    GstEvent * event);
static gboolean gst_rg_analysis_stop (GstBaseTransform * base);

static void gst_rg_analysis_handle_tags (GstRgAnalysis * filter,
    const GstTagList * tag_list);
static void gst_rg_analysis_handle_eos (GstRgAnalysis * filter);
static gboolean gst_rg_analysis_track_result (GstRgAnalysis * filter,
    GstTagList ** tag_list);
static gboolean gst_rg_analysis_album_result (GstRgAnalysis * filter,
    GstTagList ** tag_list);

static void
gst_rg_analysis_class_init (GstRgAnalysisClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstBaseTransformClass *trans_class;

  gobject_class = (GObjectClass *) klass;
  element_class = (GstElementClass *) klass;

  gobject_class->set_property = gst_rg_analysis_set_property;
  gobject_class->get_property = gst_rg_analysis_get_property;

  /**
   * GstRgAnalysis:num-tracks:
   *
   * Number of remaining album tracks.
   * 
   * Analyzing several streams sequentially and assigning them a common result
   * gain is known as "album processing".  If this gain is used during playback
   * (by switching to "album mode"), all tracks of an album receive the same
   * amplification.  This keeps the relative volume levels between the tracks
   * intact.  To enable this, set this property to the number of streams that
   * will be processed as album tracks.
   *
   * Every time an EOS event is received, the value of this property is
   * decremented by one.  As it reaches zero, it is assumed that the last track
   * of the album finished.  The tag list for the final stream will contain the
   * additional tags #GST_TAG_ALBUM_GAIN and #GST_TAG_ALBUM_PEAK.  All other
   * streams just get the two track tags posted because the values for the album
   * tags are not known before all tracks are analyzed.  Applications need to
   * ensure that the album gain and peak values are also associated with the
   * other tracks when storing the results.
   *
   * If the total number of album tracks is unknown beforehand, just ensure that
   * the value is greater than 1 before each track starts.  Then before the end
   * of the last track, set it to the value 1.
   *
   * To perform album processing, the element has to preserve data between
   * streams.  This cannot survive a state change to the NULL or READY state.
   * If you change your pipeline's state to NULL or READY between tracks, lock
   * the element's state using gst_element_set_locked_state() when it is in
   * PAUSED or PLAYING.
   */
  g_object_class_install_property (gobject_class, PROP_NUM_TRACKS,
      g_param_spec_int ("num-tracks", "Number of album tracks",
          "Number of remaining album tracks", 0, G_MAXINT, 0,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRgAnalysis:forced:
   *
   * Whether to analyze streams even when ReplayGain tags exist.
   *
   * For assisting transcoder/converter applications, the element can silently
   * skip the processing of streams that already contain the necessary tags.
   * Data will flow as usual but the element will not consume CPU time and will
   * not generate result tags.  To enable possible skipping, set this property
   * to #FALSE.
   *
   * If used in conjunction with <link linkend="GstRgAnalysis--num-tracks">album
   * processing</link>, the element will skip the number of remaining album
   * tracks if a full set of tags is found for the first track.  If a subsequent
   * track of the album is missing tags, processing cannot start again.  If this
   * is undesired, the application has to scan all files beforehand and enable
   * forcing of processing if needed.
   */
  g_object_class_install_property (gobject_class, PROP_FORCED,
      g_param_spec_boolean ("forced", "Forced",
          "Analyze even if ReplayGain tags exist",
          FORCED_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRgAnalysis:reference-level:
   *
   * Reference level [dB].
   *
   * Analyzing the ReplayGain pink noise reference waveform computes a result of
   * +6 dB instead of the expected 0 dB.  This is because the default reference
   * level is 89 dB.  To obtain values as lined out in the original proposal of
   * ReplayGain, set this property to 83.
   *
   * Almost all software uses 89 dB as a reference however, and this value has
   * become the new official value.  That is to say, while the change has been
   * acclaimed by the author of the ReplayGain proposal, the <ulink
   * url="http://replaygain.org">webpage</ulink> is still outdated at the time
   * of this writing.
   *
   * The value was changed because the original proposal recommends a default
   * pre-amp value of +6 dB for playback.  This seemed a bit odd, as it means
   * that the algorithm has the general tendency to produce adjustment values
   * that are 6 dB too low.  Bumping the reference level by 6 dB compensated for
   * this.
   *
   * The problem of the reference level being ambiguous for lack of concise
   * standardization is to be solved by adopting the #GST_TAG_REFERENCE_LEVEL
   * tag, which allows to store the used value alongside the gain values.
   */
  g_object_class_install_property (gobject_class, PROP_REFERENCE_LEVEL,
      g_param_spec_double ("reference-level", "Reference level",
          "Reference level [dB]", 0.0, 150., RG_REFERENCE_LEVEL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MESSAGE,
      g_param_spec_boolean ("message", "Message",
          "Post statics messages",
          DEFAULT_MESSAGE,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));

  trans_class = (GstBaseTransformClass *) klass;
  trans_class->start = GST_DEBUG_FUNCPTR (gst_rg_analysis_start);
  trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_rg_analysis_set_caps);
  trans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_rg_analysis_transform_ip);
  trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_rg_analysis_sink_event);
  trans_class->stop = GST_DEBUG_FUNCPTR (gst_rg_analysis_stop);
  trans_class->passthrough_on_same_caps = TRUE;

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_factory));
  gst_element_class_set_static_metadata (element_class, "ReplayGain analysis",
      "Filter/Analyzer/Audio",
      "Perform the ReplayGain analysis",
      "Ren\xc3\xa9 Stadler <mail@renestadler.de>");

  GST_DEBUG_CATEGORY_INIT (gst_rg_analysis_debug, "rganalysis", 0,
      "ReplayGain analysis element");
}

static void
gst_rg_analysis_init (GstRgAnalysis * filter)
{
  GstBaseTransform *base = GST_BASE_TRANSFORM (filter);

  gst_base_transform_set_gap_aware (base, TRUE);

  filter->num_tracks = 0;
  filter->forced = FORCED_DEFAULT;
  filter->message = DEFAULT_MESSAGE;
  filter->reference_level = RG_REFERENCE_LEVEL;

  filter->ctx = NULL;
  filter->analyze = NULL;
}

static void
gst_rg_analysis_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRgAnalysis *filter = GST_RG_ANALYSIS (object);

  GST_OBJECT_LOCK (filter);
  switch (prop_id) {
    case PROP_NUM_TRACKS:
      filter->num_tracks = g_value_get_int (value);
      break;
    case PROP_FORCED:
      filter->forced = g_value_get_boolean (value);
      break;
    case PROP_REFERENCE_LEVEL:
      filter->reference_level = g_value_get_double (value);
      break;
    case PROP_MESSAGE:
      filter->message = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  GST_OBJECT_UNLOCK (filter);
}

static void
gst_rg_analysis_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRgAnalysis *filter = GST_RG_ANALYSIS (object);

  GST_OBJECT_LOCK (filter);
  switch (prop_id) {
    case PROP_NUM_TRACKS:
      g_value_set_int (value, filter->num_tracks);
      break;
    case PROP_FORCED:
      g_value_set_boolean (value, filter->forced);
      break;
    case PROP_REFERENCE_LEVEL:
      g_value_set_double (value, filter->reference_level);
      break;
    case PROP_MESSAGE:
      g_value_set_boolean (value, filter->message);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  GST_OBJECT_UNLOCK (filter);
}

static void
gst_rg_analysis_post_message (gpointer rganalysis, GstClockTime timestamp,
    GstClockTime duration, gdouble rglevel)
{
  GstRgAnalysis *filter = GST_RG_ANALYSIS (rganalysis);
  if (filter->message) {
    GstMessage *m;

    m = gst_message_new_element (GST_OBJECT_CAST (rganalysis),
        gst_structure_new ("rganalysis",
            "timestamp", G_TYPE_UINT64, timestamp,
            "duration", G_TYPE_UINT64, duration,
            "rglevel", G_TYPE_DOUBLE, rglevel, NULL));

    gst_element_post_message (GST_ELEMENT_CAST (rganalysis), m);
  }
}


static gboolean
gst_rg_analysis_start (GstBaseTransform * base)
{
  GstRgAnalysis *filter = GST_RG_ANALYSIS (base);

  filter->ignore_tags = FALSE;
  filter->skip = FALSE;
  filter->has_track_gain = FALSE;
  filter->has_track_peak = FALSE;
  filter->has_album_gain = FALSE;
  filter->has_album_peak = FALSE;

  filter->ctx = rg_analysis_new ();
  GST_OBJECT_LOCK (filter);
  rg_analysis_init_silence_detection (filter->ctx, gst_rg_analysis_post_message,
      filter);
  GST_OBJECT_UNLOCK (filter);
  filter->analyze = NULL;

  GST_LOG_OBJECT (filter, "started");

  return TRUE;
}

static gboolean
gst_rg_analysis_set_caps (GstBaseTransform * base, GstCaps * in_caps,
    GstCaps * out_caps)
{
  GstRgAnalysis *filter = GST_RG_ANALYSIS (base);
  GstAudioInfo info;
  gint rate, channels;

  g_return_val_if_fail (filter->ctx != NULL, FALSE);

  GST_DEBUG_OBJECT (filter,
      "set_caps in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT,
      in_caps, out_caps);

  if (!gst_audio_info_from_caps (&info, in_caps))
    goto invalid_format;

  rate = GST_AUDIO_INFO_RATE (&info);

  if (!rg_analysis_set_sample_rate (filter->ctx, rate))
    goto invalid_format;

  channels = GST_AUDIO_INFO_CHANNELS (&info);

  if (channels < 1 || channels > 2)
    goto invalid_format;

  switch (GST_AUDIO_INFO_FORMAT (&info)) {
    case GST_AUDIO_FORMAT_F32:
      /* The depth is not variable for float formats of course.  It just
       * makes the transform function nice and simple if the
       * rg_analysis_analyze_* functions have a common signature. */
      filter->depth = sizeof (gfloat) * 8;

      if (channels == 1)
        filter->analyze = rg_analysis_analyze_mono_float;
      else
        filter->analyze = rg_analysis_analyze_stereo_float;

      break;
    case GST_AUDIO_FORMAT_S16:
      filter->depth = sizeof (gint16) * 8;

      if (channels == 1)
        filter->analyze = rg_analysis_analyze_mono_int16;
      else
        filter->analyze = rg_analysis_analyze_stereo_int16;
      break;
    default:
      goto invalid_format;
  }

  return TRUE;

  /* Errors. */
invalid_format:
  {
    filter->analyze = NULL;
    GST_ELEMENT_ERROR (filter, CORE, NEGOTIATION,
        ("Invalid incoming caps: %" GST_PTR_FORMAT, in_caps), (NULL));
    return FALSE;
  }
}

static GstFlowReturn
gst_rg_analysis_transform_ip (GstBaseTransform * base, GstBuffer * buf)
{
  GstRgAnalysis *filter = GST_RG_ANALYSIS (base);
  GstMapInfo map;

  g_return_val_if_fail (filter->ctx != NULL, GST_FLOW_FLUSHING);
  g_return_val_if_fail (filter->analyze != NULL, GST_FLOW_NOT_NEGOTIATED);

  if (filter->skip)
    return GST_FLOW_OK;

  gst_buffer_map (buf, &map, GST_MAP_READ);
  GST_LOG_OBJECT (filter, "processing buffer of size %" G_GSIZE_FORMAT,
      map.size);

  rg_analysis_start_buffer (filter->ctx, GST_BUFFER_TIMESTAMP (buf));
  filter->analyze (filter->ctx, map.data, map.size, filter->depth);

  gst_buffer_unmap (buf, &map);

  return GST_FLOW_OK;
}

static gboolean
gst_rg_analysis_sink_event (GstBaseTransform * base, GstEvent * event)
{
  GstRgAnalysis *filter = GST_RG_ANALYSIS (base);

  g_return_val_if_fail (filter->ctx != NULL, TRUE);

  switch (GST_EVENT_TYPE (event)) {

    case GST_EVENT_EOS:
    {
      GST_LOG_OBJECT (filter, "received EOS event");

      gst_rg_analysis_handle_eos (filter);

      GST_LOG_OBJECT (filter, "passing on EOS event");

      break;
    }
    case GST_EVENT_TAG:
    {
      GstTagList *tag_list;

      /* The reference to the tag list is borrowed. */
      gst_event_parse_tag (event, &tag_list);
      gst_rg_analysis_handle_tags (filter, tag_list);

      break;
    }
    default:
      break;
  }

  return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (base, event);
}

static gboolean
gst_rg_analysis_stop (GstBaseTransform * base)
{
  GstRgAnalysis *filter = GST_RG_ANALYSIS (base);

  g_return_val_if_fail (filter->ctx != NULL, FALSE);

  rg_analysis_destroy (filter->ctx);
  filter->ctx = NULL;

  GST_LOG_OBJECT (filter, "stopped");

  return TRUE;
}

static void
gst_rg_analysis_handle_tags (GstRgAnalysis * filter,
    const GstTagList * tag_list)
{
  gboolean album_processing = (filter->num_tracks > 0);
  gdouble dummy;

  if (!album_processing)
    filter->ignore_tags = FALSE;

  if (filter->skip && album_processing) {
    GST_DEBUG_OBJECT (filter, "ignoring tag event: skipping album");
    return;
  } else if (filter->skip) {
    GST_DEBUG_OBJECT (filter, "ignoring tag event: skipping track");
    return;
  } else if (filter->ignore_tags) {
    GST_DEBUG_OBJECT (filter, "ignoring tag event: cannot skip anyways");
    return;
  }

  filter->has_track_gain |= gst_tag_list_get_double (tag_list,
      GST_TAG_TRACK_GAIN, &dummy);
  filter->has_track_peak |= gst_tag_list_get_double (tag_list,
      GST_TAG_TRACK_PEAK, &dummy);
  filter->has_album_gain |= gst_tag_list_get_double (tag_list,
      GST_TAG_ALBUM_GAIN, &dummy);
  filter->has_album_peak |= gst_tag_list_get_double (tag_list,
      GST_TAG_ALBUM_PEAK, &dummy);

  if (!(filter->has_track_gain && filter->has_track_peak)) {
    GST_DEBUG_OBJECT (filter, "track tags not complete yet");
    return;
  }

  if (album_processing && !(filter->has_album_gain && filter->has_album_peak)) {
    GST_DEBUG_OBJECT (filter, "album tags not complete yet");
    return;
  }

  if (filter->forced) {
    GST_DEBUG_OBJECT (filter,
        "existing tags are sufficient, but processing anyway (forced)");
    return;
  }

  filter->skip = TRUE;
  rg_analysis_reset (filter->ctx);

  if (!album_processing) {
    GST_DEBUG_OBJECT (filter,
        "existing tags are sufficient, will not process this track");
  } else {
    GST_DEBUG_OBJECT (filter,
        "existing tags are sufficient, will not process this album");
  }
}

static void
gst_rg_analysis_handle_eos (GstRgAnalysis * filter)
{
  gboolean album_processing = (filter->num_tracks > 0);
  gboolean album_finished = (filter->num_tracks == 1);
  gboolean album_skipping = album_processing && filter->skip;

  filter->has_track_gain = FALSE;
  filter->has_track_peak = FALSE;

  if (album_finished) {
    filter->ignore_tags = FALSE;
    filter->skip = FALSE;
    filter->has_album_gain = FALSE;
    filter->has_album_peak = FALSE;
  } else if (!album_skipping) {
    filter->skip = FALSE;
  }

  /* We might have just fully processed a track because it has
   * incomplete tags.  If we do album processing and allow skipping
   * (not forced), prevent switching to skipping if a later track with
   * full tags comes along: */
  if (!filter->forced && album_processing && !album_finished)
    filter->ignore_tags = TRUE;

  if (!filter->skip) {
    GstTagList *tag_list = NULL;
    gboolean track_success;
    gboolean album_success = FALSE;

    track_success = gst_rg_analysis_track_result (filter, &tag_list);

    if (album_finished)
      album_success = gst_rg_analysis_album_result (filter, &tag_list);
    else if (!album_processing)
      rg_analysis_reset_album (filter->ctx);

    if (track_success || album_success) {
      GST_LOG_OBJECT (filter, "posting tag list with results");
      gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
          GST_TAG_REFERENCE_LEVEL, filter->reference_level, NULL);
      /* This steals our reference to the list: */
      gst_pad_push_event (GST_BASE_TRANSFORM_SRC_PAD (GST_BASE_TRANSFORM
              (filter)), gst_event_new_tag (gst_tag_list_ref (tag_list)));
    }
  }

  if (album_processing) {
    filter->num_tracks--;

    if (!album_finished) {
      GST_DEBUG_OBJECT (filter, "album not finished yet (num-tracks is now %u)",
          filter->num_tracks);
    } else {
      GST_DEBUG_OBJECT (filter, "album finished (num-tracks is now 0)");
    }
  }

  if (album_processing)
    g_object_notify (G_OBJECT (filter), "num-tracks");
}

static gboolean
gst_rg_analysis_track_result (GstRgAnalysis * filter, GstTagList ** tag_list)
{
  gboolean track_success;
  gdouble track_gain, track_peak;

  track_success = rg_analysis_track_result (filter->ctx, &track_gain,
      &track_peak);

  if (track_success) {
    track_gain += filter->reference_level - RG_REFERENCE_LEVEL;
    GST_INFO_OBJECT (filter, "track gain is %+.2f dB, peak %.6f", track_gain,
        track_peak);
  } else {
    GST_INFO_OBJECT (filter, "track was too short to analyze");
  }

  if (track_success) {
    if (*tag_list == NULL)
      *tag_list = gst_tag_list_new_empty ();
    gst_tag_list_add (*tag_list, GST_TAG_MERGE_APPEND,
        GST_TAG_TRACK_PEAK, track_peak, GST_TAG_TRACK_GAIN, track_gain, NULL);
  }

  return track_success;
}

static gboolean
gst_rg_analysis_album_result (GstRgAnalysis * filter, GstTagList ** tag_list)
{
  gboolean album_success;
  gdouble album_gain, album_peak;

  album_success = rg_analysis_album_result (filter->ctx, &album_gain,
      &album_peak);

  if (album_success) {
    album_gain += filter->reference_level - RG_REFERENCE_LEVEL;
    GST_INFO_OBJECT (filter, "album gain is %+.2f dB, peak %.6f", album_gain,
        album_peak);
  } else {
    GST_INFO_OBJECT (filter, "album was too short to analyze");
  }

  if (album_success) {
    if (*tag_list == NULL)
      *tag_list = gst_tag_list_new_empty ();
    gst_tag_list_add (*tag_list, GST_TAG_MERGE_APPEND,
        GST_TAG_ALBUM_PEAK, album_peak, GST_TAG_ALBUM_GAIN, album_gain, NULL);
  }

  return album_success;
}
