/* GStreamer ReplayGain volume adjustment
 *
 * Copyright (C) 2007 Rene Stadler <mail@renestadler.de>
 * 
 * gstrgvolume.c: Element to apply ReplayGain volume adjustment
 *
 * 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-rgvolume
 * @see_also: #GstRgLimiter, #GstRgAnalysis
 *
 * This element applies volume changes to streams as lined out in the proposed
 * <ulink url="http://replaygain.org">ReplayGain standard</ulink>.  It
 * interprets the ReplayGain meta data tags and carries out the adjustment (by
 * using a volume element internally).  The relevant tags are:
 * <itemizedlist>
 * <listitem>#GST_TAG_TRACK_GAIN</listitem>
 * <listitem>#GST_TAG_TRACK_PEAK</listitem>
 * <listitem>#GST_TAG_ALBUM_GAIN</listitem>
 * <listitem>#GST_TAG_ALBUM_PEAK</listitem>
 * <listitem>#GST_TAG_REFERENCE_LEVEL</listitem>
 * </itemizedlist>
 * The information carried by these tags must have been calculated beforehand by
 * performing the ReplayGain analysis.  This is implemented by the <link
 * linkend="GstRgAnalysis">rganalysis</link> element.
 * 
 * The signal compression/limiting recommendations outlined in the proposed
 * standard are not implemented by this element.  This has to be handled by
 * separate elements because applications might want to have additional filters
 * between the volume adjustment and the limiting stage.  A basic limiter is
 * included with this plugin: The <link linkend="GstRgLimiter">rglimiter</link>
 * element applies -6 dB hard limiting as mentioned in the ReplayGain standard.
 * 
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 filesrc location=filename.ext ! decodebin ! audioconvert \
 *     ! rgvolume ! audioconvert ! audioresample ! alsasink
 * ]| Playback of a file
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
#include <gst/audio/audio.h>
#include <math.h>

#include "gstrgvolume.h"
#include "replaygain.h"

GST_DEBUG_CATEGORY_STATIC (gst_rg_volume_debug);
#define GST_CAT_DEFAULT gst_rg_volume_debug

enum
{
  PROP_0,
  PROP_ALBUM_MODE,
  PROP_HEADROOM,
  PROP_PRE_AMP,
  PROP_FALLBACK_GAIN,
  PROP_TARGET_GAIN,
  PROP_RESULT_GAIN
};

#define DEFAULT_ALBUM_MODE TRUE
#define DEFAULT_HEADROOM 0.0
#define DEFAULT_PRE_AMP 0.0
#define DEFAULT_FALLBACK_GAIN 0.0

#define DB_TO_LINEAR(x) pow (10., (x) / 20.)
#define LINEAR_TO_DB(x) (20. * log10 (x))

#define GAIN_FORMAT "+.02f dB"
#define PEAK_FORMAT ".06f"

#define VALID_GAIN(x) ((x) > -60.00 && (x) < 60.00)
#define VALID_PEAK(x) ((x) > 0.)

/* Same template caps as GstVolume, for I don't like having just ANY caps. */

#define FORMAT "{ "GST_AUDIO_NE(F32)","GST_AUDIO_NE(S16)" }"

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) " FORMAT ", "
        "layout = (string) { interleaved, non-interleaved }, "
        "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]"));

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) " FORMAT ", "
        "layout = (string) { interleaved, non-interleaved }, "
        "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]"));

#define gst_rg_volume_parent_class parent_class
G_DEFINE_TYPE (GstRgVolume, gst_rg_volume, GST_TYPE_BIN);

static void gst_rg_volume_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_rg_volume_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_rg_volume_dispose (GObject * object);

static GstStateChangeReturn gst_rg_volume_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_rg_volume_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static GstEvent *gst_rg_volume_tag_event (GstRgVolume * self, GstEvent * event);
static void gst_rg_volume_reset (GstRgVolume * self);
static void gst_rg_volume_update_gain (GstRgVolume * self);
static inline void gst_rg_volume_determine_gain (GstRgVolume * self,
    gdouble * target_gain, gdouble * result_gain);

static void
gst_rg_volume_class_init (GstRgVolumeClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstBinClass *bin_class;

  gobject_class = (GObjectClass *) klass;

  gobject_class->set_property = gst_rg_volume_set_property;
  gobject_class->get_property = gst_rg_volume_get_property;
  gobject_class->dispose = gst_rg_volume_dispose;

  /**
   * GstRgVolume:album-mode:
   *
   * Whether to prefer album gain over track gain.
   *
   * If set to %TRUE, use album gain instead of track gain if both are
   * available.  This keeps the relative loudness levels of tracks from the same
   * album intact.
   *
   * If set to %FALSE, track mode is used instead.  This effectively leads to
   * more extensive normalization.
   *
   * If album mode is enabled but the album gain tag is absent in the stream,
   * the track gain is used instead.  If both gain tags are missing, the value
   * of the #GstRgVolume:fallback-gain property is used instead.
   */
  g_object_class_install_property (gobject_class, PROP_ALBUM_MODE,
      g_param_spec_boolean ("album-mode", "Album mode",
          "Prefer album over track gain", DEFAULT_ALBUM_MODE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRgVolume:headroom:
   *
   * Extra headroom [dB].  This controls the amount by which the output can
   * exceed digital full scale.
   *
   * Only set this to a value greater than 0.0 if signal compression/limiting of
   * a suitable form is applied to the output (or output is brought into the
   * correct range by some other transformation).
   *
   * This element internally uses a volume element, which also supports
   * operating on integer audio formats.  These formats do not allow exceeding
   * digital full scale.  If extra headroom is used, make sure that the raw
   * audio data format is floating point (F32).  Otherwise,
   * clipping distortion might be introduced as part of the volume adjustment
   * itself.
   */
  g_object_class_install_property (gobject_class, PROP_HEADROOM,
      g_param_spec_double ("headroom", "Headroom", "Extra headroom [dB]",
          0., 60., DEFAULT_HEADROOM,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRgVolume:pre-amp:
   *
   * Additional gain to apply globally [dB].  This controls the trade-off
   * between uniformity of normalization and utilization of available dynamic
   * range.
   *
   * Note that the default value is 0 dB because the ReplayGain reference value
   * was adjusted by +6 dB (from 83 to 89 dB).  At the time of this writing, the
   * <ulink url="http://replaygain.org">webpage</ulink> is still outdated and
   * does not reflect this change however.  Where the original proposal states
   * that a proper default pre-amp value is +6 dB, this translates to the used 0
   * dB.
   */
  g_object_class_install_property (gobject_class, PROP_PRE_AMP,
      g_param_spec_double ("pre-amp", "Pre-amp", "Extra gain [dB]",
          -60., 60., DEFAULT_PRE_AMP,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRgVolume:fallback-gain:
   *
   * Fallback gain [dB] for streams missing ReplayGain tags.
   */
  g_object_class_install_property (gobject_class, PROP_FALLBACK_GAIN,
      g_param_spec_double ("fallback-gain", "Fallback gain",
          "Gain for streams missing tags [dB]",
          -60., 60., DEFAULT_FALLBACK_GAIN,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRgVolume:result-gain:
   *
   * Applied gain [dB].  This gain is applied to processed buffer data.
   *
   * This is set to the #GstRgVolume:target-gain if amplification by that amount
   * can be applied safely. "Safely" means that the volume adjustment does not
   * inflict clipping distortion.  Should this not be the case, the result gain
   * is set to an appropriately reduced value (by applying peak normalization).
   * The proposed standard calls this "clipping prevention".
   *
   * The difference between target and result gain reflects the necessary amount
   * of reduction.  Applications can make use of this information to temporarily
   * reduce the #GstRgVolume:pre-amp for subsequent streams, as recommended by
   * the ReplayGain standard.
   *
   * Note that target and result gain differing for a great majority of streams
   * indicates a problem: What happens in this case is that most streams receive
   * peak normalization instead of amplification by the ideal replay gain.  To
   * prevent this, the #GstRgVolume:pre-amp has to be lowered and/or a limiter
   * has to be used which facilitates the use of #GstRgVolume:headroom.
   */
  g_object_class_install_property (gobject_class, PROP_RESULT_GAIN,
      g_param_spec_double ("result-gain", "Result-gain", "Applied gain [dB]",
          -120., 120., 0., G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRgVolume:target-gain:
   *
   * Applicable gain [dB].  This gain is supposed to be applied.
   *
   * Depending on the value of the #GstRgVolume:album-mode property and the
   * presence of ReplayGain tags in the stream, this is set according to one of
   * these simple formulas:
   *
   * <itemizedlist>
   * <listitem>#GstRgVolume:pre-amp + album gain of the stream</listitem>
   * <listitem>#GstRgVolume:pre-amp + track gain of the stream</listitem>
   * <listitem>#GstRgVolume:pre-amp + #GstRgVolume:fallback-gain</listitem>
   * </itemizedlist>
   */
  g_object_class_install_property (gobject_class, PROP_TARGET_GAIN,
      g_param_spec_double ("target-gain", "Target-gain",
          "Applicable gain [dB]", -120., 120., 0.,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  element_class = (GstElementClass *) klass;
  element_class->change_state = GST_DEBUG_FUNCPTR (gst_rg_volume_change_state);

  bin_class = (GstBinClass *) klass;
  /* Setting these to NULL makes gst_bin_add and _remove refuse to let anyone
   * mess with our internals. */
  bin_class->add_element = NULL;
  bin_class->remove_element = NULL;

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_template));
  gst_element_class_set_static_metadata (element_class, "ReplayGain volume",
      "Filter/Effect/Audio",
      "Apply ReplayGain volume adjustment",
      "Ren\xc3\xa9 Stadler <mail@renestadler.de>");

  GST_DEBUG_CATEGORY_INIT (gst_rg_volume_debug, "rgvolume", 0,
      "ReplayGain volume element");
}

static void
gst_rg_volume_init (GstRgVolume * self)
{
  GObjectClass *volume_class;
  GstPad *volume_pad, *ghost_pad;

  self->album_mode = DEFAULT_ALBUM_MODE;
  self->headroom = DEFAULT_HEADROOM;
  self->pre_amp = DEFAULT_PRE_AMP;
  self->fallback_gain = DEFAULT_FALLBACK_GAIN;
  self->target_gain = 0.0;
  self->result_gain = 0.0;

  self->volume_element = gst_element_factory_make ("volume", "rgvolume-volume");
  if (G_UNLIKELY (self->volume_element == NULL)) {
    GstMessage *msg;

    GST_WARNING_OBJECT (self, "could not create volume element");
    msg = gst_missing_element_message_new (GST_ELEMENT_CAST (self), "volume");
    gst_element_post_message (GST_ELEMENT_CAST (self), msg);

    /* Nothing else to do, we will refuse the state change from NULL to READY to
     * indicate that something went very wrong.  It is doubtful that someone
     * attempts changing our state though, since we end up having no pads! */
    return;
  }

  volume_class = G_OBJECT_GET_CLASS (G_OBJECT (self->volume_element));
  self->max_volume = G_PARAM_SPEC_DOUBLE
      (g_object_class_find_property (volume_class, "volume"))->maximum;

  GST_BIN_CLASS (parent_class)->add_element (GST_BIN_CAST (self),
      self->volume_element);

  volume_pad = gst_element_get_static_pad (self->volume_element, "sink");
  ghost_pad = gst_ghost_pad_new_from_template ("sink", volume_pad,
      GST_PAD_PAD_TEMPLATE (volume_pad));
  gst_object_unref (volume_pad);
  gst_pad_set_event_function (ghost_pad, gst_rg_volume_sink_event);
  gst_element_add_pad (GST_ELEMENT_CAST (self), ghost_pad);

  volume_pad = gst_element_get_static_pad (self->volume_element, "src");
  ghost_pad = gst_ghost_pad_new_from_template ("src", volume_pad,
      GST_PAD_PAD_TEMPLATE (volume_pad));
  gst_object_unref (volume_pad);
  gst_element_add_pad (GST_ELEMENT_CAST (self), ghost_pad);
}

static void
gst_rg_volume_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRgVolume *self = GST_RG_VOLUME (object);

  switch (prop_id) {
    case PROP_ALBUM_MODE:
      self->album_mode = g_value_get_boolean (value);
      break;
    case PROP_HEADROOM:
      self->headroom = g_value_get_double (value);
      break;
    case PROP_PRE_AMP:
      self->pre_amp = g_value_get_double (value);
      break;
    case PROP_FALLBACK_GAIN:
      self->fallback_gain = g_value_get_double (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  gst_rg_volume_update_gain (self);
}

static void
gst_rg_volume_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRgVolume *self = GST_RG_VOLUME (object);

  switch (prop_id) {
    case PROP_ALBUM_MODE:
      g_value_set_boolean (value, self->album_mode);
      break;
    case PROP_HEADROOM:
      g_value_set_double (value, self->headroom);
      break;
    case PROP_PRE_AMP:
      g_value_set_double (value, self->pre_amp);
      break;
    case PROP_FALLBACK_GAIN:
      g_value_set_double (value, self->fallback_gain);
      break;
    case PROP_TARGET_GAIN:
      g_value_set_double (value, self->target_gain);
      break;
    case PROP_RESULT_GAIN:
      g_value_set_double (value, self->result_gain);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rg_volume_dispose (GObject * object)
{
  GstRgVolume *self = GST_RG_VOLUME (object);

  if (self->volume_element != NULL) {
    /* Manually remove our child using the bin implementation of remove_element.
     * This is needed because we prevent gst_bin_remove from working, which the
     * parent dispose handler would use if we had any children left. */
    GST_BIN_CLASS (parent_class)->remove_element (GST_BIN_CAST (self),
        self->volume_element);
    self->volume_element = NULL;
  }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static GstStateChangeReturn
gst_rg_volume_change_state (GstElement * element, GstStateChange transition)
{
  GstRgVolume *self = GST_RG_VOLUME (element);
  GstStateChangeReturn res;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:

      if (G_UNLIKELY (self->volume_element == NULL)) {
        /* Creating our child volume element in _init failed. */
        return GST_STATE_CHANGE_FAILURE;
      }
      break;

    case GST_STATE_CHANGE_READY_TO_PAUSED:

      gst_rg_volume_reset (self);
      break;

    default:
      break;
  }

  res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  return res;
}

/* Event function for the ghost sink pad. */
static gboolean
gst_rg_volume_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstRgVolume *self;
  GstEvent *send_event = event;
  gboolean res;

  self = GST_RG_VOLUME (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:

      GST_LOG_OBJECT (self, "received tag event");

      send_event = gst_rg_volume_tag_event (self, event);

      if (send_event == NULL)
        GST_LOG_OBJECT (self, "all tags handled, dropping event");

      break;

    case GST_EVENT_EOS:

      gst_rg_volume_reset (self);
      break;

    default:
      break;
  }

  if (G_LIKELY (send_event != NULL))
    res = gst_pad_event_default (pad, parent, send_event);
  else
    res = TRUE;

  return res;
}

static GstEvent *
gst_rg_volume_tag_event (GstRgVolume * self, GstEvent * event)
{
  GstTagList *tag_list;
  gboolean has_track_gain, has_track_peak, has_album_gain, has_album_peak;
  gboolean has_ref_level;

  g_return_val_if_fail (event != NULL, NULL);
  g_return_val_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TAG, event);

  gst_event_parse_tag (event, &tag_list);

  if (gst_tag_list_is_empty (tag_list))
    return event;

  has_track_gain = gst_tag_list_get_double (tag_list, GST_TAG_TRACK_GAIN,
      &self->track_gain);
  has_track_peak = gst_tag_list_get_double (tag_list, GST_TAG_TRACK_PEAK,
      &self->track_peak);
  has_album_gain = gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_GAIN,
      &self->album_gain);
  has_album_peak = gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_PEAK,
      &self->album_peak);
  has_ref_level = gst_tag_list_get_double (tag_list, GST_TAG_REFERENCE_LEVEL,
      &self->reference_level);

  if (!has_track_gain && !has_track_peak && !has_album_gain && !has_album_peak)
    return event;

  if (has_ref_level && (has_track_gain || has_album_gain)
      && (ABS (self->reference_level - RG_REFERENCE_LEVEL) > 1.e-6)) {
    /* Log a message stating the amount of adjustment that is applied below. */
    GST_DEBUG_OBJECT (self,
        "compensating for reference level difference by %" GAIN_FORMAT,
        RG_REFERENCE_LEVEL - self->reference_level);
  }
  if (has_track_gain) {
    self->track_gain += RG_REFERENCE_LEVEL - self->reference_level;
  }
  if (has_album_gain) {
    self->album_gain += RG_REFERENCE_LEVEL - self->reference_level;
  }

  /* Ignore values that are obviously invalid. */
  if (G_UNLIKELY (has_track_gain && !VALID_GAIN (self->track_gain))) {
    GST_DEBUG_OBJECT (self,
        "ignoring bogus track gain value %" GAIN_FORMAT, self->track_gain);
    has_track_gain = FALSE;
  }
  if (G_UNLIKELY (has_track_peak && !VALID_PEAK (self->track_peak))) {
    GST_DEBUG_OBJECT (self,
        "ignoring bogus track peak value %" PEAK_FORMAT, self->track_peak);
    has_track_peak = FALSE;
  }
  if (G_UNLIKELY (has_album_gain && !VALID_GAIN (self->album_gain))) {
    GST_DEBUG_OBJECT (self,
        "ignoring bogus album gain value %" GAIN_FORMAT, self->album_gain);
    has_album_gain = FALSE;
  }
  if (G_UNLIKELY (has_album_peak && !VALID_PEAK (self->album_peak))) {
    GST_DEBUG_OBJECT (self,
        "ignoring bogus album peak value %" PEAK_FORMAT, self->album_peak);
    has_album_peak = FALSE;
  }

  /* Clamp peaks >1.0.  Float based decoders can produce spurious samples >1.0,
   * cutting these files back to 1.0 should not cause any audible distortion.
   * This is most often seen with Vorbis files. */
  if (has_track_peak && self->track_peak > 1.) {
    GST_DEBUG_OBJECT (self,
        "clamping track peak %" PEAK_FORMAT " to 1.0", self->track_peak);
    self->track_peak = 1.0;
  }
  if (has_album_peak && self->album_peak > 1.) {
    GST_DEBUG_OBJECT (self,
        "clamping album peak %" PEAK_FORMAT " to 1.0", self->album_peak);
    self->album_peak = 1.0;
  }

  self->has_track_gain |= has_track_gain;
  self->has_track_peak |= has_track_peak;
  self->has_album_gain |= has_album_gain;
  self->has_album_peak |= has_album_peak;

  tag_list = gst_tag_list_copy (tag_list);
  gst_tag_list_remove_tag (tag_list, GST_TAG_TRACK_GAIN);
  gst_tag_list_remove_tag (tag_list, GST_TAG_TRACK_PEAK);
  gst_tag_list_remove_tag (tag_list, GST_TAG_ALBUM_GAIN);
  gst_tag_list_remove_tag (tag_list, GST_TAG_ALBUM_PEAK);
  gst_tag_list_remove_tag (tag_list, GST_TAG_REFERENCE_LEVEL);

  gst_rg_volume_update_gain (self);

  gst_event_unref (event);
  if (gst_tag_list_is_empty (tag_list)) {
    gst_tag_list_unref (tag_list);
    return NULL;
  }

  return gst_event_new_tag (tag_list);
}

static void
gst_rg_volume_reset (GstRgVolume * self)
{
  self->has_track_gain = FALSE;
  self->has_track_peak = FALSE;
  self->has_album_gain = FALSE;
  self->has_album_peak = FALSE;

  self->reference_level = RG_REFERENCE_LEVEL;

  gst_rg_volume_update_gain (self);
}

static void
gst_rg_volume_update_gain (GstRgVolume * self)
{
  gdouble target_gain, result_gain, result_volume;
  gboolean target_gain_changed, result_gain_changed;

  gst_rg_volume_determine_gain (self, &target_gain, &result_gain);

  result_volume = DB_TO_LINEAR (result_gain);

  /* Ensure that the result volume is within the range that the volume element
   * can handle.  Currently, the limit is 10. (+20 dB), which should not be
   * restrictive. */
  if (G_UNLIKELY (result_volume > self->max_volume)) {
    GST_INFO_OBJECT (self,
        "cannot handle result gain of %" GAIN_FORMAT " (%0.6f), adjusting",
        result_gain, result_volume);

    result_volume = self->max_volume;
    result_gain = LINEAR_TO_DB (result_volume);
  }

  /* Direct comparison is OK in this case. */
  if (target_gain == result_gain) {
    GST_INFO_OBJECT (self,
        "result gain is %" GAIN_FORMAT " (%0.6f), matching target",
        result_gain, result_volume);
  } else {
    GST_INFO_OBJECT (self,
        "result gain is %" GAIN_FORMAT " (%0.6f), target is %" GAIN_FORMAT,
        result_gain, result_volume, target_gain);
  }

  target_gain_changed = (self->target_gain != target_gain);
  result_gain_changed = (self->result_gain != result_gain);

  self->target_gain = target_gain;
  self->result_gain = result_gain;

  g_object_set (self->volume_element, "volume", result_volume, NULL);

  if (target_gain_changed)
    g_object_notify ((GObject *) self, "target-gain");
  if (result_gain_changed)
    g_object_notify ((GObject *) self, "result-gain");
}

static inline void
gst_rg_volume_determine_gain (GstRgVolume * self, gdouble * target_gain,
    gdouble * result_gain)
{
  gdouble gain, peak;

  if (!self->has_track_gain && !self->has_album_gain) {

    GST_DEBUG_OBJECT (self, "using fallback gain");
    gain = self->fallback_gain;
    peak = 1.0;

  } else if ((self->album_mode && self->has_album_gain)
      || (!self->album_mode && !self->has_track_gain)) {

    gain = self->album_gain;
    if (G_LIKELY (self->has_album_peak)) {
      peak = self->album_peak;
    } else {
      GST_DEBUG_OBJECT (self, "album peak missing, assuming 1.0");
      peak = 1.0;
    }
    /* Falling back from track to album gain shouldn't really happen. */
    if (G_UNLIKELY (!self->album_mode))
      GST_INFO_OBJECT (self, "falling back to album gain");

  } else {
    /* !album_mode && !has_album_gain || album_mode && has_track_gain */

    gain = self->track_gain;
    if (G_LIKELY (self->has_track_peak)) {
      peak = self->track_peak;
    } else {
      GST_DEBUG_OBJECT (self, "track peak missing, assuming 1.0");
      peak = 1.0;
    }
    if (self->album_mode)
      GST_INFO_OBJECT (self, "falling back to track gain");
  }

  gain += self->pre_amp;

  *target_gain = gain;
  *result_gain = gain;

  if (LINEAR_TO_DB (peak) + gain > self->headroom) {
    *result_gain = LINEAR_TO_DB (1. / peak) + self->headroom;
  }
}
