/* GStreamer
 * Copyright (C) <2017> Carlos Rafael Giani <dv at pseudoterminal 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.
 */


/**
 * SECTION:element-openmptdec
 * @see_also: #GstOpenMptDec
 *
 * openmpdec decodes module music formats, such as S3M, MOD, XM, IT.
 * It uses the <ulink url="https://lib.openmpt.org">OpenMPT library</ulink>
 * for this purpose. It can be autoplugged and therefore works with decodebin.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 filesrc location=media/example.it ! openmptdec ! audioconvert ! audioresample ! autoaudiosink
 * ]|
 * </refsect2>
 */


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

#include <gst/gst.h>

#include "gstopenmptdec.h"

#ifndef OPENMPT_API_VERSION_AT_LEAST
#define OPENMPT_API_VERSION_AT_LEAST(x, y, z) (FALSE)
#endif

GST_DEBUG_CATEGORY_STATIC (openmptdec_debug);
#define GST_CAT_DEFAULT openmptdec_debug


enum
{
  PROP_0,
  PROP_MASTER_GAIN,
  PROP_STEREO_SEPARATION,
  PROP_FILTER_LENGTH,
  PROP_VOLUME_RAMPING,
  PROP_OUTPUT_BUFFER_SIZE
};


#define DEFAULT_MASTER_GAIN 0
#define DEFAULT_STEREO_SEPARATION 100
#define DEFAULT_FILTER_LENGTH 0
#define DEFAULT_VOLUME_RAMPING -1
#define DEFAULT_OUTPUT_BUFFER_SIZE 1024

#define DEFAULT_SAMPLE_FORMAT GST_AUDIO_FORMAT_F32
#define DEFAULT_SAMPLE_RATE 48000
#define DEFAULT_NUM_CHANNELS 2



static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-mod, "
        "type = (string) { 669, asylum-amf, dsmi-amf, extreme-ams, velvet-ams, "
        "dbm, digi, dmf, dsm, far, gdm, imf, it, j2b, mdl, med, mod, mt2, mtm, "
        "okt, psm, ptm, s3m, stm, ult, xm }")
    );

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) { " GST_AUDIO_NE (S16) ", " GST_AUDIO_NE (F32) " }, "
        "layout = (string) interleaved, "
        "rate = (int) [ 1, 192000 ], " "channels = (int) { 1, 2, 4 } ")
    );



G_DEFINE_TYPE (GstOpenMptDec, gst_openmpt_dec,
    GST_TYPE_NONSTREAM_AUDIO_DECODER);



static void gst_openmpt_dec_finalize (GObject * object);

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

static gboolean gst_openmpt_dec_seek (GstNonstreamAudioDecoder * dec,
    GstClockTime * new_position);
static GstClockTime gst_openmpt_dec_tell (GstNonstreamAudioDecoder * dec);

static void gst_openmpt_dec_log_func (char const *message, void *user);
static void gst_openmpt_dec_add_metadata_to_tag_list (GstOpenMptDec *
    openmpt_dec, GstTagList * tags, char const *key, gchar const *tag);
static gboolean gst_openmpt_dec_load_from_buffer (GstNonstreamAudioDecoder *
    dec, GstBuffer * source_data, guint initial_subsong,
    GstNonstreamAudioSubsongMode initial_subsong_mode,
    GstClockTime * initial_position,
    GstNonstreamAudioOutputMode * initial_output_mode,
    gint * initial_num_loops);

static GstTagList *gst_openmpt_dec_get_main_tags (GstNonstreamAudioDecoder *
    dec);

static gboolean gst_openmpt_dec_set_current_subsong (GstNonstreamAudioDecoder *
    dec, guint subsong, GstClockTime * initial_position);
static guint gst_openmpt_dec_get_current_subsong (GstNonstreamAudioDecoder *
    dec);

static guint gst_openmpt_dec_get_num_subsongs (GstNonstreamAudioDecoder * dec);
static GstClockTime
gst_openmpt_dec_get_subsong_duration (GstNonstreamAudioDecoder * dec,
    guint subsong);
static GstTagList *gst_openmpt_dec_get_subsong_tags (GstNonstreamAudioDecoder *
    dec, guint subsong);
static gboolean gst_openmpt_dec_set_subsong_mode (GstNonstreamAudioDecoder *
    dec, GstNonstreamAudioSubsongMode mode, GstClockTime * initial_position);

static gboolean gst_openmpt_dec_set_num_loops (GstNonstreamAudioDecoder * dec,
    gint num_loops);
static gint gst_openmpt_dec_get_num_loops (GstNonstreamAudioDecoder * dec);

static guint
gst_openmpt_dec_get_supported_output_modes (GstNonstreamAudioDecoder * dec);
static gboolean gst_openmpt_dec_decode (GstNonstreamAudioDecoder * dec,
    GstBuffer ** buffer, guint * num_samples);

static gboolean gst_openmpt_dec_select_subsong (GstOpenMptDec *
    openmpt_dec, GstNonstreamAudioSubsongMode subsong_mode,
    gint openmpt_subsong);


void
gst_openmpt_dec_class_init (GstOpenMptDecClass * klass)
{
  GObjectClass *object_class;
  GstElementClass *element_class;
  GstNonstreamAudioDecoderClass *dec_class;

  GST_DEBUG_CATEGORY_INIT (openmptdec_debug, "openmptdec", 0,
      "OpenMPT-based module music decoder");

  object_class = G_OBJECT_CLASS (klass);
  element_class = GST_ELEMENT_CLASS (klass);
  dec_class = GST_NONSTREAM_AUDIO_DECODER_CLASS (klass);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_template));

  object_class->finalize = GST_DEBUG_FUNCPTR (gst_openmpt_dec_finalize);
  object_class->set_property = GST_DEBUG_FUNCPTR (gst_openmpt_dec_set_property);
  object_class->get_property = GST_DEBUG_FUNCPTR (gst_openmpt_dec_get_property);

  dec_class->seek = GST_DEBUG_FUNCPTR (gst_openmpt_dec_seek);
  dec_class->tell = GST_DEBUG_FUNCPTR (gst_openmpt_dec_tell);
  dec_class->load_from_buffer =
      GST_DEBUG_FUNCPTR (gst_openmpt_dec_load_from_buffer);
  dec_class->get_main_tags = GST_DEBUG_FUNCPTR (gst_openmpt_dec_get_main_tags);
  dec_class->set_num_loops = GST_DEBUG_FUNCPTR (gst_openmpt_dec_set_num_loops);
  dec_class->get_num_loops = GST_DEBUG_FUNCPTR (gst_openmpt_dec_get_num_loops);
  dec_class->get_supported_output_modes =
      GST_DEBUG_FUNCPTR (gst_openmpt_dec_get_supported_output_modes);
  dec_class->decode = GST_DEBUG_FUNCPTR (gst_openmpt_dec_decode);
  dec_class->set_current_subsong =
      GST_DEBUG_FUNCPTR (gst_openmpt_dec_set_current_subsong);
  dec_class->get_current_subsong =
      GST_DEBUG_FUNCPTR (gst_openmpt_dec_get_current_subsong);
  dec_class->get_num_subsongs =
      GST_DEBUG_FUNCPTR (gst_openmpt_dec_get_num_subsongs);
  dec_class->get_subsong_duration =
      GST_DEBUG_FUNCPTR (gst_openmpt_dec_get_subsong_duration);
  dec_class->get_subsong_tags =
      GST_DEBUG_FUNCPTR (gst_openmpt_dec_get_subsong_tags);
  dec_class->set_subsong_mode =
      GST_DEBUG_FUNCPTR (gst_openmpt_dec_set_subsong_mode);

  gst_element_class_set_static_metadata (element_class,
      "OpenMPT-based module music decoder",
      "Codec/Decoder/Audio",
      "Decoders module files (MOD/S3M/XM/IT/MTM/...) using OpenMPT",
      "Carlos Rafael Giani <dv@pseudoterminal.org>");

  g_object_class_install_property (object_class,
      PROP_MASTER_GAIN,
      g_param_spec_int ("master-gain",
          "Master gain",
          "Gain to apply to the playback, in millibel",
          -G_MAXINT, G_MAXINT,
          DEFAULT_MASTER_GAIN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_STEREO_SEPARATION,
      g_param_spec_int ("stereo-separation",
          "Stereo separation",
          "Degree of separation for stereo channels, in percent",
          0, 400,
          DEFAULT_STEREO_SEPARATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_FILTER_LENGTH,
      g_param_spec_int ("filter-length",
          "Filter length",
          "Length of interpolation filter to use for the samples (0 = internal default)",
          0, 8,
          DEFAULT_FILTER_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_VOLUME_RAMPING,
      g_param_spec_int ("volume-ramping",
          "Volume ramping",
          "Volume ramping strength; higher value -> slower ramping (-1 = internal default)",
          -1, 10,
          DEFAULT_VOLUME_RAMPING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  /* 4*4 => quad output with F32 samples; this ensures that no overflow can happen */
  g_object_class_install_property (object_class,
      PROP_OUTPUT_BUFFER_SIZE,
      g_param_spec_uint ("output-buffer-size",
          "Output buffer size",
          "Size of each output buffer, in samples (actual size can be smaller "
          "than this during flush or EOS)",
          1, G_MAXUINT / (4 * 4),
          DEFAULT_OUTPUT_BUFFER_SIZE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
}


void
gst_openmpt_dec_init (GstOpenMptDec * openmpt_dec)
{
  openmpt_dec->mod = NULL;

  openmpt_dec->cur_subsong = 0;
  openmpt_dec->num_subsongs = 0;
  openmpt_dec->subsong_durations = NULL;

  openmpt_dec->num_loops = 0;

  openmpt_dec->master_gain = DEFAULT_MASTER_GAIN;
  openmpt_dec->stereo_separation = DEFAULT_STEREO_SEPARATION;
  openmpt_dec->filter_length = DEFAULT_FILTER_LENGTH;
  openmpt_dec->volume_ramping = DEFAULT_VOLUME_RAMPING;

  openmpt_dec->output_buffer_size = DEFAULT_OUTPUT_BUFFER_SIZE;

  openmpt_dec->main_tags = NULL;

  openmpt_dec->sample_format = DEFAULT_SAMPLE_FORMAT;
  openmpt_dec->sample_rate = DEFAULT_SAMPLE_RATE;
  openmpt_dec->num_channels = DEFAULT_NUM_CHANNELS;
}


static void
gst_openmpt_dec_finalize (GObject * object)
{
  GstOpenMptDec *openmpt_dec;

  g_return_if_fail (GST_IS_OPENMPT_DEC (object));
  openmpt_dec = GST_OPENMPT_DEC (object);

  if (openmpt_dec->main_tags != NULL)
    gst_tag_list_unref (openmpt_dec->main_tags);

  if (openmpt_dec->mod != NULL)
    openmpt_module_destroy (openmpt_dec->mod);

  g_free (openmpt_dec->subsong_durations);

  G_OBJECT_CLASS (gst_openmpt_dec_parent_class)->finalize (object);
}


static void
gst_openmpt_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstNonstreamAudioDecoder *dec;
  GstOpenMptDec *openmpt_dec;

  dec = GST_NONSTREAM_AUDIO_DECODER (object);
  openmpt_dec = GST_OPENMPT_DEC (object);

  switch (prop_id) {
    case PROP_MASTER_GAIN:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      openmpt_dec->master_gain = g_value_get_int (value);
      if (openmpt_dec->mod != NULL)
        openmpt_module_set_render_param (openmpt_dec->mod,
            OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL,
            openmpt_dec->master_gain);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      break;
    }

    case PROP_STEREO_SEPARATION:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      openmpt_dec->stereo_separation = g_value_get_int (value);
      if (openmpt_dec->mod != NULL)
        openmpt_module_set_render_param (openmpt_dec->mod,
            OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT,
            openmpt_dec->stereo_separation);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      break;
    }

    case PROP_FILTER_LENGTH:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      openmpt_dec->filter_length = g_value_get_int (value);
      if (openmpt_dec->mod != NULL)
        openmpt_module_set_render_param (openmpt_dec->mod,
            OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH,
            openmpt_dec->filter_length);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      break;
    }

    case PROP_VOLUME_RAMPING:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      openmpt_dec->volume_ramping = g_value_get_int (value);
      if (openmpt_dec->mod != NULL)
        openmpt_module_set_render_param (openmpt_dec->mod,
            OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH,
            openmpt_dec->volume_ramping);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      break;
    }

    case PROP_OUTPUT_BUFFER_SIZE:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      openmpt_dec->output_buffer_size = g_value_get_uint (value);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      break;
    }

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static void
gst_openmpt_dec_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (object);

  switch (prop_id) {
    case PROP_MASTER_GAIN:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      g_value_set_int (value, openmpt_dec->master_gain);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;
    }

    case PROP_STEREO_SEPARATION:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      g_value_set_int (value, openmpt_dec->stereo_separation);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;
    }

    case PROP_FILTER_LENGTH:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      g_value_set_int (value, openmpt_dec->filter_length);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;
    }

    case PROP_VOLUME_RAMPING:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      g_value_set_int (value, openmpt_dec->volume_ramping);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;
    }

    case PROP_OUTPUT_BUFFER_SIZE:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      g_value_set_uint (value, openmpt_dec->output_buffer_size);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;
    }

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static gboolean
gst_openmpt_dec_seek (GstNonstreamAudioDecoder * dec,
    GstClockTime * new_position)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  g_return_val_if_fail (openmpt_dec->mod != NULL, FALSE);

  openmpt_module_set_position_seconds (openmpt_dec->mod,
      (double) (*new_position) / GST_SECOND);
  *new_position = gst_openmpt_dec_tell (dec);

  return TRUE;
}


static GstClockTime
gst_openmpt_dec_tell (GstNonstreamAudioDecoder * dec)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  g_return_val_if_fail (openmpt_dec->mod != NULL, GST_CLOCK_TIME_NONE);

  return (GstClockTime) (openmpt_module_get_position_seconds (openmpt_dec->mod)
      * GST_SECOND);
}


static void
gst_openmpt_dec_log_func (char const *message, void *user)
{
  GST_LOG_OBJECT (GST_OBJECT (user), "%s", message);
}


static void
gst_openmpt_dec_add_metadata_to_tag_list (GstOpenMptDec * openmpt_dec,
    GstTagList * tags, char const *key, gchar const *tag)
{
  char const *metadata = openmpt_module_get_metadata (openmpt_dec->mod, key);

  if (metadata && *metadata) {
    GST_DEBUG_OBJECT (openmpt_dec,
        "adding metadata \"%s\" with key \"%s\" to tag list as tag \"%s\"",
        metadata, key, tag);

    if (g_strcmp0 (tag, GST_TAG_DATE_TIME) == 0) {
      /* Special handling for date-time tags - interpret the
       * metadata string as an iso8601 string and convert it
       * to a GstDateTime value, since this is the data type
       * that GST_TAG_DATE_TIME expects. */

      GstDateTime *date_time = gst_date_time_new_from_iso8601_string (metadata);
      if (date_time) {
        GST_DEBUG_OBJECT (openmpt_dec,
            "successfully created date-time object out of iso8601 string");
        gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, tag, date_time, NULL);
        gst_date_time_unref (date_time);
      } else
        GST_WARNING_OBJECT (openmpt_dec,
            "could not create date-time object out of iso8601 string - not adding metadata to tags");
    } else {
      /* Default handling - just insert the metadata string as-is */
      gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, tag, metadata, NULL);
    }
  } else
    GST_DEBUG_OBJECT (openmpt_dec,
        "attempted to add metadata with key \"%s\" to tag list as tag \"%s\", but none exists",
        key, tag);

  if (metadata)
    openmpt_free_string (metadata);
}


static gboolean
gst_openmpt_dec_load_from_buffer (GstNonstreamAudioDecoder * dec,
    GstBuffer * source_data, guint initial_subsong,
    GstNonstreamAudioSubsongMode initial_subsong_mode,
    GstClockTime * initial_position,
    GstNonstreamAudioOutputMode * initial_output_mode, gint * initial_num_loops)
{
  GstMapInfo map;
  GstOpenMptDec *openmpt_dec;

  openmpt_dec = GST_OPENMPT_DEC (dec);

  /* First, determine the sample rate, channel count, and sample format to use */
  openmpt_dec->sample_format = DEFAULT_SAMPLE_FORMAT;
  openmpt_dec->sample_rate = DEFAULT_SAMPLE_RATE;
  openmpt_dec->num_channels = DEFAULT_NUM_CHANNELS;
  gst_nonstream_audio_decoder_get_downstream_info (dec,
      &(openmpt_dec->sample_format), &(openmpt_dec->sample_rate),
      &(openmpt_dec->num_channels));

  /* Set output format */
  if (!gst_nonstream_audio_decoder_set_output_format_simple (dec,
          openmpt_dec->sample_rate,
          openmpt_dec->sample_format, openmpt_dec->num_channels))
    return FALSE;

  /* Pass the module data to OpenMPT for loading */
  gst_buffer_map (source_data, &map, GST_MAP_READ);
#if OPENMPT_API_VERSION_AT_LEAST(0,3,0)
  openmpt_dec->mod =
      openmpt_module_create_from_memory2 (map.data, map.size,
      gst_openmpt_dec_log_func, dec, NULL, NULL, NULL, NULL, NULL);
#else
  openmpt_dec->mod =
      openmpt_module_create_from_memory (map.data, map.size,
      gst_openmpt_dec_log_func, dec, NULL);
#endif
  gst_buffer_unmap (source_data, &map);

  if (openmpt_dec->mod == NULL) {
    GST_ERROR_OBJECT (dec, "loading module failed");
    return FALSE;
  }

  /* Copy subsong states */
  openmpt_dec->cur_subsong = initial_subsong;
  openmpt_dec->cur_subsong_mode = initial_subsong_mode;

  /* Query the number of subsongs available for logging and for checking
   * the initial subsong index */
  openmpt_dec->num_subsongs =
      openmpt_module_get_num_subsongs (openmpt_dec->mod);
  if (G_UNLIKELY (initial_subsong >= openmpt_dec->num_subsongs)) {
    GST_WARNING_OBJECT (openmpt_dec,
        "initial subsong %u out of bounds (there are %u subsongs) - setting it to 0",
        initial_subsong, openmpt_dec->num_subsongs);
    initial_subsong = 0;
  }
  GST_INFO_OBJECT (openmpt_dec, "%d subsong(s) available",
      openmpt_dec->num_subsongs);

  /* Query the OpenMPT default subsong (can be -1)
   * The default subsong is the one that is initially selected, so we
   * need to query it here, *before* any openmpt_module_select_subsong()
   * calls are done */
  {
    gchar const *subsong_cstr =
        openmpt_module_ctl_get (openmpt_dec->mod, "subsong");
    gchar *endptr;

    if (subsong_cstr != NULL) {
      openmpt_dec->default_openmpt_subsong =
          g_ascii_strtoll (subsong_cstr, &endptr, 10);
      if (subsong_cstr == endptr) {
        GST_WARNING_OBJECT (openmpt_dec,
            "could not convert ctl string \"%s\" to subsong index - using default OpenMPT index -1 instead",
            subsong_cstr);
        openmpt_dec->default_openmpt_subsong = -1;
      } else
        GST_DEBUG_OBJECT (openmpt_dec, "default OpenMPT subsong index is %d",
            openmpt_dec->default_openmpt_subsong);

      openmpt_free_string (subsong_cstr);
    } else {
      GST_INFO_OBJECT (openmpt_dec,
          "could not get subsong ctl string - using default OpenMPT index -1 instead");
      openmpt_dec->default_openmpt_subsong = -1;
    }
  }

  /* Seek to initial position */
  if (*initial_position != 0) {
    openmpt_module_set_position_seconds (openmpt_dec->mod,
        (double) (*initial_position) / GST_SECOND);
    *initial_position =
        (GstClockTime) (openmpt_module_get_position_seconds (openmpt_dec->mod) *
        GST_SECOND);
  }

  /* LOOPING output mode is not supported */
  *initial_output_mode = GST_NONSTREAM_AUDIO_OUTPUT_MODE_STEADY;

  /* Query the durations of each subsong (if any exist) */
  if (openmpt_dec->num_subsongs > 0) {
    guint i;

    openmpt_dec->subsong_durations =
        g_try_malloc (openmpt_dec->num_subsongs * sizeof (double));
    if (openmpt_dec->subsong_durations == NULL) {
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      GST_ELEMENT_ERROR (openmpt_dec, RESOURCE, NO_SPACE_LEFT,
          ("could not allocate memory for subsong duration array"), (NULL));
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      return FALSE;
    }

    for (i = 0; i < openmpt_dec->num_subsongs; ++i) {
      openmpt_module_select_subsong (openmpt_dec->mod, i);
      openmpt_dec->subsong_durations[i] =
          openmpt_module_get_duration_seconds (openmpt_dec->mod);
    }
  }

  /* Select the initial subsong */
  gst_openmpt_dec_select_subsong (openmpt_dec, initial_subsong_mode,
      initial_subsong);

  /* Set the number of loops, and query the actual number
   * that was chosen by OpenMPT */
  {
    int32_t actual_repeat_count;
    openmpt_module_set_repeat_count (openmpt_dec->mod, *initial_num_loops);
    actual_repeat_count = openmpt_module_get_repeat_count (openmpt_dec->mod);

    if (actual_repeat_count != *initial_num_loops) {
      GST_DEBUG_OBJECT (openmpt_dec,
          "requested num-loops value %d differs from actual value %d",
          *initial_num_loops, actual_repeat_count);
      *initial_num_loops = actual_repeat_count;
    }
  }

  /* Set render parameters (adjustable via properties) */
  openmpt_module_set_render_param (openmpt_dec->mod,
      OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL, openmpt_dec->master_gain);
  openmpt_module_set_render_param (openmpt_dec->mod,
      OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT,
      openmpt_dec->stereo_separation);
  openmpt_module_set_render_param (openmpt_dec->mod,
      OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH,
      openmpt_dec->filter_length);
  openmpt_module_set_render_param (openmpt_dec->mod,
      OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH,
      openmpt_dec->volume_ramping);

  /* Log the available metadata keys, and produce a
   * tag list if any keys are available */
  {
    char const *metadata_keys =
        openmpt_module_get_metadata_keys (openmpt_dec->mod);
    if (metadata_keys != NULL) {
      GstTagList *tags = gst_tag_list_new_empty ();

      GST_DEBUG_OBJECT (dec, "metadata keys: [%s]", metadata_keys);
      openmpt_free_string (metadata_keys);

      gst_openmpt_dec_add_metadata_to_tag_list (openmpt_dec, tags, "title",
          GST_TAG_TITLE);
      gst_openmpt_dec_add_metadata_to_tag_list (openmpt_dec, tags, "artist",
          GST_TAG_ARTIST);
      gst_openmpt_dec_add_metadata_to_tag_list (openmpt_dec, tags, "message",
          GST_TAG_COMMENT);
      gst_openmpt_dec_add_metadata_to_tag_list (openmpt_dec, tags, "tracker",
          GST_TAG_APPLICATION_NAME);
      gst_openmpt_dec_add_metadata_to_tag_list (openmpt_dec, tags, "type_long",
          GST_TAG_CODEC);
      gst_openmpt_dec_add_metadata_to_tag_list (openmpt_dec, tags, "date",
          GST_TAG_DATE_TIME);
      gst_openmpt_dec_add_metadata_to_tag_list (openmpt_dec, tags,
          "container_long", GST_TAG_CONTAINER_FORMAT);

      openmpt_dec->main_tags = tags;
    } else {
      GST_DEBUG_OBJECT (dec,
          "no metadata keys found - not producing a tag list");
    }
  }

  /* Log any warnings that were produced by OpenMPT while loading */
  {
    char const *warnings =
        openmpt_module_get_metadata (openmpt_dec->mod, "warnings");
    if (warnings) {
      if (*warnings)
        GST_WARNING_OBJECT (openmpt_dec, "reported warnings during loading: %s",
            warnings);
      openmpt_free_string (warnings);
    }
  }

  return TRUE;
}


static GstTagList *
gst_openmpt_dec_get_main_tags (GstNonstreamAudioDecoder * dec)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  return gst_tag_list_ref (openmpt_dec->main_tags);
}


static gboolean
gst_openmpt_dec_set_current_subsong (GstNonstreamAudioDecoder * dec,
    guint subsong, GstClockTime * initial_position)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  g_return_val_if_fail (openmpt_dec->mod != NULL, FALSE);

  if (gst_openmpt_dec_select_subsong (openmpt_dec,
          openmpt_dec->cur_subsong_mode, subsong)) {
    GST_DEBUG_OBJECT (openmpt_dec,
        "selected subsong %u and switching subsong mode to SINGLE", subsong);
    openmpt_dec->cur_subsong_mode = GST_NONSTREAM_AUDIO_SUBSONG_MODE_SINGLE;
    openmpt_dec->cur_subsong = subsong;
    *initial_position = 0;
    return TRUE;
  } else {
    GST_ERROR_OBJECT (openmpt_dec, "could not select subsong %u", subsong);
    return FALSE;
  }
}


static guint
gst_openmpt_dec_get_current_subsong (GstNonstreamAudioDecoder * dec)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  return openmpt_dec->cur_subsong;
}


static guint
gst_openmpt_dec_get_num_subsongs (GstNonstreamAudioDecoder * dec)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  return openmpt_dec->num_subsongs;
}


static GstClockTime
gst_openmpt_dec_get_subsong_duration (GstNonstreamAudioDecoder * dec,
    guint subsong)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  return (GstClockTime) (openmpt_dec->subsong_durations[subsong] * GST_SECOND);
}


static GstTagList *
gst_openmpt_dec_get_subsong_tags (GstNonstreamAudioDecoder * dec, guint subsong)
{
  GstOpenMptDec *openmpt_dec;
  char const *name;

  openmpt_dec = GST_OPENMPT_DEC (dec);

  name = openmpt_module_get_subsong_name (openmpt_dec->mod, subsong);
  if (name != NULL) {
    GstTagList *tags = NULL;

    if (*name) {
      tags = gst_tag_list_new_empty ();
      gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, "title", name, NULL);
    }

    openmpt_free_string (name);

    return tags;
  } else
    return NULL;
}


static gboolean
gst_openmpt_dec_set_subsong_mode (GstNonstreamAudioDecoder * dec,
    GstNonstreamAudioSubsongMode mode, GstClockTime * initial_position)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  g_return_val_if_fail (openmpt_dec->mod != NULL, FALSE);

  if (gst_openmpt_dec_select_subsong (openmpt_dec, mode,
          openmpt_dec->cur_subsong)) {
    GST_DEBUG_OBJECT (openmpt_dec, "set subsong mode");
    openmpt_dec->cur_subsong_mode = mode;
    *initial_position = 0;
    return TRUE;
  } else {
    GST_ERROR_OBJECT (openmpt_dec, "could not set subsong mode");
    return FALSE;
  }
}


static gboolean
gst_openmpt_dec_set_num_loops (GstNonstreamAudioDecoder * dec, gint num_loops)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  openmpt_dec->num_loops = num_loops;

  if (openmpt_dec->mod != NULL) {
    if (openmpt_module_set_repeat_count (openmpt_dec->mod, num_loops)) {
      GST_DEBUG_OBJECT (openmpt_dec, "successfully set repeat count %d",
          num_loops);
      return TRUE;
    } else {
      GST_ERROR_OBJECT (openmpt_dec, "could not set repeat count %d",
          num_loops);
      return FALSE;
    }
  } else
    return TRUE;
}


static gint
gst_openmpt_dec_get_num_loops (GstNonstreamAudioDecoder * dec)
{
  GstOpenMptDec *openmpt_dec = GST_OPENMPT_DEC (dec);
  return openmpt_dec->num_loops;
}


static guint
gst_openmpt_dec_get_supported_output_modes (G_GNUC_UNUSED
    GstNonstreamAudioDecoder * dec)
{
  return 1u << GST_NONSTREAM_AUDIO_OUTPUT_MODE_STEADY;
}


static gboolean
gst_openmpt_dec_decode (GstNonstreamAudioDecoder * dec, GstBuffer ** buffer,
    guint * num_samples)
{
  GstOpenMptDec *openmpt_dec;
  GstBuffer *outbuf;
  GstMapInfo map;
  size_t num_read_samples;
  gsize outbuf_size;
  GstAudioFormatInfo const *fmt_info;

  openmpt_dec = GST_OPENMPT_DEC (dec);

  fmt_info = gst_audio_format_get_info (openmpt_dec->sample_format);

  /* Allocate output buffer */
  outbuf_size =
      openmpt_dec->output_buffer_size * (fmt_info->width / 8) *
      openmpt_dec->num_channels;
  outbuf =
      gst_nonstream_audio_decoder_allocate_output_buffer (dec, outbuf_size);
  if (G_UNLIKELY (outbuf == NULL))
    return FALSE;

  /* Write samples into the output buffer */

  gst_buffer_map (outbuf, &map, GST_MAP_WRITE);

  switch (openmpt_dec->sample_format) {
    case GST_AUDIO_FORMAT_S16:
    {
      int16_t *out_samples = (int16_t *) (map.data);
      switch (openmpt_dec->num_channels) {
        case 1:
          num_read_samples =
              openmpt_module_read_mono (openmpt_dec->mod,
              openmpt_dec->sample_rate, openmpt_dec->output_buffer_size,
              out_samples);
          break;
        case 2:
          num_read_samples =
              openmpt_module_read_interleaved_stereo (openmpt_dec->mod,
              openmpt_dec->sample_rate, openmpt_dec->output_buffer_size,
              out_samples);
          break;
        case 4:
          num_read_samples =
              openmpt_module_read_interleaved_quad (openmpt_dec->mod,
              openmpt_dec->sample_rate, openmpt_dec->output_buffer_size,
              out_samples);
          break;
        default:
          g_assert_not_reached ();
      }
      break;
    }
    case GST_AUDIO_FORMAT_F32:
    {
      float *out_samples = (float *) (map.data);
      switch (openmpt_dec->num_channels) {
        case 1:
          num_read_samples =
              openmpt_module_read_float_mono (openmpt_dec->mod,
              openmpt_dec->sample_rate, openmpt_dec->output_buffer_size,
              out_samples);
          break;
        case 2:
          num_read_samples =
              openmpt_module_read_interleaved_float_stereo (openmpt_dec->mod,
              openmpt_dec->sample_rate, openmpt_dec->output_buffer_size,
              out_samples);
          break;
        case 4:
          num_read_samples =
              openmpt_module_read_interleaved_float_quad (openmpt_dec->mod,
              openmpt_dec->sample_rate, openmpt_dec->output_buffer_size,
              out_samples);
          break;
        default:
          g_assert_not_reached ();
      }
      break;
    }
    default:
    {
      GST_ERROR_OBJECT (dec, "using unsupported sample format %s",
          fmt_info->name);
      g_assert_not_reached ();
    }
  }

  gst_buffer_unmap (outbuf, &map);

  if (num_read_samples == 0)
    return FALSE;

  *buffer = outbuf;
  *num_samples = num_read_samples;

  return TRUE;
}


static gboolean
gst_openmpt_dec_select_subsong (GstOpenMptDec * openmpt_dec,
    GstNonstreamAudioSubsongMode subsong_mode, gint openmpt_subsong)
{
  switch (subsong_mode) {
    case GST_NONSTREAM_AUDIO_SUBSONG_MODE_SINGLE:
      GST_DEBUG_OBJECT (openmpt_dec, "setting subsong mode to SINGLE");
      return openmpt_module_select_subsong (openmpt_dec->mod, openmpt_subsong);

    case GST_NONSTREAM_AUDIO_SUBSONG_MODE_ALL:
      GST_DEBUG_OBJECT (openmpt_dec, "setting subsong mode to ALL");
      return openmpt_module_select_subsong (openmpt_dec->mod, -1);

    case GST_NONSTREAM_AUDIO_SUBSONG_MODE_DECODER_DEFAULT:
      /* NOTE: The OpenMPT documentation recommends to not bother
       * calling openmpt_module_select_subsong() if the decoder
       * default shall be used. However, the user might have switched
       * the subsong mode from SINGLE or ALL to DECODER_DEFAULT,
       * in which case we *do* have to set the default subsong index.
       * So, just set the default index here. */
      GST_DEBUG_OBJECT (openmpt_dec, "setting subsong mode to DECODER_DEFAULT");
      return openmpt_module_select_subsong (openmpt_dec->mod,
          openmpt_dec->default_openmpt_subsong);

    default:
      g_assert_not_reached ();
      return TRUE;
  }
}
