/* GStreamer
 * Copyright (C) <2016> 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-wildmididec
 * @see_also: #GstWildmidiDec
 *
 * wildmididec decodes MIDI files.
 * It uses <ulink url="https://www.mindwerks.net/projects/wildmidi/">WildMidi</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.mid ! wildmididec ! audioconvert ! audioresample ! autoaudiosink
 * ]|
 * </refsect2>
 */


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

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

#include <gst/gst.h>
#include <glib/gstdio.h>

#ifdef G_OS_WIN32

#ifndef R_OK
#define R_OK 4                  /* Test for read permission */
#endif

#else
#include <unistd.h>
#endif

#include "gstwildmididec.h"


GST_DEBUG_CATEGORY_STATIC (wildmididec_debug);
#define GST_CAT_DEFAULT wildmididec_debug


/* This is hardcoded because the sample rate is set once,
 * globally, in WildMidi_Init() */
#define WILDMIDI_SAMPLE_RATE 44100
/* WildMidi always outputs stereo data */
#define WILDMIDI_NUM_CHANNELS 2

#ifndef WILDMIDI_CFG
#define WILDMIDI_CFG "/etc/timidity.cfg"
#endif

#define DEFAULT_LOG_VOLUME_SCALE     TRUE
#define DEFAULT_ENHANCED_RESAMPLING  TRUE
#define DEFAULT_REVERB               FALSE
#define DEFAULT_OUTPUT_BUFFER_SIZE   1024


enum
{
  PROP_0,
  PROP_LOG_VOLUME_SCALE,
  PROP_ENHANCED_RESAMPLING,
  PROP_REVERB,
  PROP_OUTPUT_BUFFER_SIZE
};



static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/midi; audio/riff-midi")
    );

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) ", "
        "layout = (string) interleaved, "
        "rate = (int) " G_STRINGIFY (WILDMIDI_SAMPLE_RATE) ", "
        "channels = (int) " G_STRINGIFY (WILDMIDI_NUM_CHANNELS)
    )
    );



G_DEFINE_TYPE (GstWildmidiDec, gst_wildmidi_dec,
    GST_TYPE_NONSTREAM_AUDIO_DECODER);



static void gst_wildmidi_dec_finalize (GObject * object);

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

static gboolean gst_wildmidi_dec_seek (GstNonstreamAudioDecoder * dec,
    GstClockTime * new_position);
static GstClockTime gst_wildmidi_dec_tell (GstNonstreamAudioDecoder * dec);

static gboolean gst_wildmidi_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 guint gst_wildmidi_dec_get_current_subsong (GstNonstreamAudioDecoder *
    dec);

static guint gst_wildmidi_dec_get_num_subsongs (GstNonstreamAudioDecoder * dec);
static GstClockTime
gst_wildmidi_dec_get_subsong_duration (GstNonstreamAudioDecoder * dec,
    guint subsong);

static guint
gst_wildmidi_dec_get_supported_output_modes (GstNonstreamAudioDecoder * dec);
static gboolean gst_wildmidi_dec_decode (GstNonstreamAudioDecoder * dec,
    GstBuffer ** buffer, guint * num_samples);

static void gst_wildmidi_dec_update_options (GstWildmidiDec * wildmidi_dec);



static GMutex load_mutex;
static unsigned long init_refcount = 0;
static volatile gint wildmidi_initialized = 0;


static gchar *
gst_wildmidi_get_config_path (void)
{
  /* This code is adapted from the original wildmidi
   * gst-plugins-bad decoder element */

  gchar *path = g_strdup (g_getenv ("WILDMIDI_CFG"));

  GST_DEBUG
      ("trying configuration path \"%s\" from WILDMIDI_CFG environment variable",
      GST_STR_NULL (path));
  if (path && (g_access (path, R_OK) == -1)) {
    g_free (path);
    path = NULL;
  }

  if (path == NULL) {
    path =
        g_build_path (G_DIR_SEPARATOR_S, g_get_home_dir (), ".wildmidirc",
        NULL);
    GST_DEBUG ("trying configuration path \"%s\"", path);
    if (path && (g_access (path, R_OK) == -1)) {
      g_free (path);
      path = NULL;
    }
  }

  if (path == NULL) {
    path =
        g_build_path (G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S "etc",
        "wildmidi.cfg", NULL);
    GST_DEBUG ("trying configuration path \"%s\"", path);
    if (path && (g_access (path, R_OK) == -1)) {
      g_free (path);
      path = NULL;
    }
  }

  if (path == NULL) {
    path =
        g_build_path (G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S "etc", "wildmidi",
        "wildmidi.cfg", NULL);
    GST_DEBUG ("trying configuration path \"%s\"", path);
    if (path && (g_access (path, R_OK) == -1)) {
      g_free (path);
      path = NULL;
    }
  }

  if (path == NULL) {
    path = g_strdup (WILDMIDI_CFG);
    GST_DEBUG ("trying default configuration path \"%s\"", path);
    if (path && (g_access (path, R_OK) == -1)) {
      g_free (path);
      path = NULL;
    }
  }

  if (path == NULL) {
    path =
        g_build_path (G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S "etc",
        "timidity.cfg", NULL);
    GST_DEBUG ("trying TiMidity configuration path \"%s\"", path);
    if (path && (g_access (path, R_OK) == -1)) {
      g_free (path);
      path = NULL;
    }
  }

  if (path == NULL) {
    path =
        g_build_path (G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S "etc", "timidity",
        "timidity.cfg", NULL);
    GST_DEBUG ("trying TiMidity configuration path \"%s\"", path);
    if (path && (g_access (path, R_OK) == -1)) {
      g_free (path);
      path = NULL;
    }
  }

  return path;
}


static void
gst_wildmidi_init_library (void)
{
  GST_DEBUG ("WildMidi init instance counter: %lu", init_refcount);

  g_mutex_lock (&load_mutex);

  if (init_refcount != 0) {
    ++init_refcount;
  } else {
    gchar *config_path = gst_wildmidi_get_config_path ();
    if (config_path != NULL) {
      int ret = WildMidi_Init (config_path, WILDMIDI_SAMPLE_RATE, 0);
      g_free (config_path);

      if (ret == 0) {
        GST_DEBUG ("WildMidi initialized, version string: %s",
            WildMidi_GetString (WM_GS_VERSION));
        ++init_refcount;
        g_atomic_int_set (&wildmidi_initialized, 1);
      } else {
        GST_ERROR ("initializing WildMidi failed");
        g_atomic_int_set (&wildmidi_initialized, 0);
      }
    } else {
      GST_ERROR ("no config file, can't initialise");
      g_atomic_int_set (&wildmidi_initialized, 0);
    }
  }

  g_mutex_unlock (&load_mutex);
}


static void
gst_wildmidi_shutdown_library (void)
{
  GST_DEBUG ("WildMidi init instance counter: %lu", init_refcount);

  g_mutex_lock (&load_mutex);

  if (init_refcount != 0) {
    --init_refcount;
    if (init_refcount == 0) {
      WildMidi_Shutdown ();
      GST_DEBUG ("WildMidi shut down");
      g_atomic_int_set (&wildmidi_initialized, 0);
    }
  }

  g_mutex_unlock (&load_mutex);
}



void
gst_wildmidi_dec_class_init (GstWildmidiDecClass * klass)
{
  GObjectClass *object_class;
  GstElementClass *element_class;
  GstNonstreamAudioDecoderClass *dec_class;

  GST_DEBUG_CATEGORY_INIT (wildmididec_debug, "wildmididec", 0,
      "WildMidi-based MIDI 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_wildmidi_dec_finalize);
  object_class->set_property =
      GST_DEBUG_FUNCPTR (gst_wildmidi_dec_set_property);
  object_class->get_property =
      GST_DEBUG_FUNCPTR (gst_wildmidi_dec_get_property);

  dec_class->tell = GST_DEBUG_FUNCPTR (gst_wildmidi_dec_tell);
  dec_class->seek = GST_DEBUG_FUNCPTR (gst_wildmidi_dec_seek);
  dec_class->load_from_buffer =
      GST_DEBUG_FUNCPTR (gst_wildmidi_dec_load_from_buffer);
  dec_class->get_current_subsong =
      GST_DEBUG_FUNCPTR (gst_wildmidi_dec_get_current_subsong);
  dec_class->get_num_subsongs =
      GST_DEBUG_FUNCPTR (gst_wildmidi_dec_get_num_subsongs);
  dec_class->get_subsong_duration =
      GST_DEBUG_FUNCPTR (gst_wildmidi_dec_get_subsong_duration);
  dec_class->get_supported_output_modes =
      GST_DEBUG_FUNCPTR (gst_wildmidi_dec_get_supported_output_modes);
  dec_class->decode = GST_DEBUG_FUNCPTR (gst_wildmidi_dec_decode);

  gst_element_class_set_static_metadata (element_class,
      "WildMidi-based MIDI music decoder",
      "Codec/Decoder/Audio",
      "Decodes MIDI music using WildMidi",
      "Carlos Rafael Giani <dv@pseudoterminal.org>");

  g_object_class_install_property (object_class,
      PROP_LOG_VOLUME_SCALE,
      g_param_spec_boolean ("log-volume-scale",
          "Logarithmic volume scale",
          "Use a logarithmic volume scale if set to TRUE, or a linear scale if set to FALSE",
          DEFAULT_LOG_VOLUME_SCALE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_ENHANCED_RESAMPLING,
      g_param_spec_boolean ("enhanced-resampling",
          "Enhanced resampling",
          "Use enhanced resampling if set to TRUE, or linear interpolation if set to FALSE",
          DEFAULT_ENHANCED_RESAMPLING,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_REVERB,
      g_param_spec_boolean ("reverb",
          "Reverb",
          "Whether or not to enable the WildMidi 8 reflection reverb engine to add more depth to the sound",
          DEFAULT_REVERB, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  /* 2*2 => stereo output with S16 samples; the division 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 / (2 * 2),
          DEFAULT_OUTPUT_BUFFER_SIZE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
}


void
gst_wildmidi_dec_init (GstWildmidiDec * wildmidi_dec)
{
  wildmidi_dec->song = NULL;

  wildmidi_dec->log_volume_scale = DEFAULT_LOG_VOLUME_SCALE;
  wildmidi_dec->enhanced_resampling = DEFAULT_ENHANCED_RESAMPLING;
  wildmidi_dec->reverb = DEFAULT_REVERB;
  wildmidi_dec->output_buffer_size = DEFAULT_OUTPUT_BUFFER_SIZE;

  gst_wildmidi_init_library ();
}


static void
gst_wildmidi_dec_finalize (GObject * object)
{
  GstWildmidiDec *wildmidi_dec = GST_WILDMIDI_DEC (object);

  if (wildmidi_dec->song != NULL)
    WildMidi_Close (wildmidi_dec->song);

  gst_wildmidi_shutdown_library ();

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


static void
gst_wildmidi_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstWildmidiDec *wildmidi_dec;

  wildmidi_dec = GST_WILDMIDI_DEC (object);

  switch (prop_id) {
    case PROP_LOG_VOLUME_SCALE:
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      wildmidi_dec->log_volume_scale = g_value_get_boolean (value);
      gst_wildmidi_dec_update_options (wildmidi_dec);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;

    case PROP_ENHANCED_RESAMPLING:
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      wildmidi_dec->enhanced_resampling = g_value_get_boolean (value);
      gst_wildmidi_dec_update_options (wildmidi_dec);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;

    case PROP_REVERB:
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      wildmidi_dec->reverb = g_value_get_boolean (value);
      gst_wildmidi_dec_update_options (wildmidi_dec);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;

    case PROP_OUTPUT_BUFFER_SIZE:
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      wildmidi_dec->output_buffer_size = g_value_get_uint (value);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;

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


static void
gst_wildmidi_dec_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstWildmidiDec *wildmidi_dec = GST_WILDMIDI_DEC (object);

  switch (prop_id) {
    case PROP_LOG_VOLUME_SCALE:
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      g_value_set_boolean (value, wildmidi_dec->log_volume_scale);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;

    case PROP_ENHANCED_RESAMPLING:
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      g_value_set_boolean (value, wildmidi_dec->enhanced_resampling);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (object);
      break;

    case PROP_REVERB:
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (object);
      g_value_set_boolean (value, wildmidi_dec->reverb);
      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, wildmidi_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_wildmidi_dec_seek (GstNonstreamAudioDecoder * dec,
    GstClockTime * new_position)
{
  GstWildmidiDec *wildmidi_dec = GST_WILDMIDI_DEC (dec);
  unsigned long int sample_pos =
      gst_util_uint64_scale_int (*new_position, WILDMIDI_SAMPLE_RATE,
      GST_SECOND);

  if (G_UNLIKELY (wildmidi_dec->song == NULL))
    return FALSE;

  WildMidi_FastSeek (wildmidi_dec->song, &sample_pos);

  *new_position =
      gst_util_uint64_scale_int (sample_pos, GST_SECOND, WILDMIDI_SAMPLE_RATE);
  return TRUE;
}


static GstClockTime
gst_wildmidi_dec_tell (GstNonstreamAudioDecoder * dec)
{
  GstWildmidiDec *wildmidi_dec = GST_WILDMIDI_DEC (dec);
  struct _WM_Info *info;

  if (G_UNLIKELY (wildmidi_dec->song == NULL))
    return GST_CLOCK_TIME_NONE;

  info = WildMidi_GetInfo (wildmidi_dec->song);
  return gst_util_uint64_scale_int (info->current_sample, GST_SECOND,
      WILDMIDI_SAMPLE_RATE);
}


static gboolean
gst_wildmidi_dec_load_from_buffer (GstNonstreamAudioDecoder * dec,
    GstBuffer * source_data, G_GNUC_UNUSED guint initial_subsong,
    G_GNUC_UNUSED GstNonstreamAudioSubsongMode initial_subsong_mode,
    GstClockTime * initial_position,
    GstNonstreamAudioOutputMode * initial_output_mode,
    G_GNUC_UNUSED gint * initial_num_loops)
{
  GstWildmidiDec *wildmidi_dec = GST_WILDMIDI_DEC (dec);
  GstMapInfo buffer_map;


  if (g_atomic_int_get (&wildmidi_initialized) == 0) {
    GST_ERROR_OBJECT (wildmidi_dec,
        "Could not start loading: WildMidi is not initialized");
    return FALSE;
  }


  /* Set output format */
  if (!gst_nonstream_audio_decoder_set_output_format_simple (dec,
          WILDMIDI_SAMPLE_RATE, GST_AUDIO_FORMAT_S16, WILDMIDI_NUM_CHANNELS))
    return FALSE;


  /* Load MIDI */
  gst_buffer_map (source_data, &buffer_map, GST_MAP_READ);
  wildmidi_dec->song = WildMidi_OpenBuffer (buffer_map.data, buffer_map.size);
  gst_buffer_unmap (source_data, &buffer_map);

  if (wildmidi_dec->song == NULL) {
    GST_ERROR_OBJECT (wildmidi_dec, "Could not load MIDI tune");
    return FALSE;
  }

  gst_wildmidi_dec_update_options (wildmidi_dec);


  /* Seek to initial position */
  if (*initial_position != 0) {
    unsigned long int sample_pos =
        gst_util_uint64_scale_int (*initial_position, WILDMIDI_SAMPLE_RATE,
        GST_SECOND);
    WildMidi_FastSeek (wildmidi_dec->song, &sample_pos);
    *initial_position =
        gst_util_uint64_scale_int (sample_pos, GST_SECOND,
        WILDMIDI_SAMPLE_RATE);
  }


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


  return TRUE;
}


static guint
gst_wildmidi_dec_get_current_subsong (G_GNUC_UNUSED GstNonstreamAudioDecoder *
    dec)
{
  return 0;
}


static guint
gst_wildmidi_dec_get_num_subsongs (G_GNUC_UNUSED GstNonstreamAudioDecoder * dec)
{
  return 1;
}


static GstClockTime
gst_wildmidi_dec_get_subsong_duration (GstNonstreamAudioDecoder * dec,
    G_GNUC_UNUSED guint subsong)
{
  GstWildmidiDec *wildmidi_dec = GST_WILDMIDI_DEC (dec);
  struct _WM_Info *info;

  if (G_UNLIKELY (wildmidi_dec->song == NULL))
    return GST_CLOCK_TIME_NONE;

  info = WildMidi_GetInfo (wildmidi_dec->song);
  return gst_util_uint64_scale_int (info->approx_total_samples, GST_SECOND,
      WILDMIDI_SAMPLE_RATE);
}


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


static gboolean
gst_wildmidi_dec_decode (GstNonstreamAudioDecoder * dec, GstBuffer ** buffer,
    guint * num_samples)
{
  GstWildmidiDec *wildmidi_dec = GST_WILDMIDI_DEC (dec);
  GstMapInfo info;
  GstBuffer *outbuf;
  gsize outbuf_size;
  int decoded_size_in_bytes;

  if (G_UNLIKELY (wildmidi_dec->song == NULL))
    return FALSE;

  /* Allocate output buffer
   * Multiply by 2 to accomodate for the sample size (16 bit = 2 byte) */
  outbuf_size = wildmidi_dec->output_buffer_size * 2 * WILDMIDI_NUM_CHANNELS;
  outbuf =
      gst_nonstream_audio_decoder_allocate_output_buffer (dec, outbuf_size);
  if (G_UNLIKELY (outbuf == NULL))
    return FALSE;

  /* The actual decoding */
  gst_buffer_map (outbuf, &info, GST_MAP_WRITE);
  decoded_size_in_bytes =
      WildMidi_GetOutput (wildmidi_dec->song, (int8_t *) (info.data),
      info.size);
  gst_buffer_unmap (outbuf, &info);

  if (decoded_size_in_bytes == 0) {
    gst_buffer_unref (outbuf);
    return FALSE;
  }

  *buffer = outbuf;
  *num_samples = decoded_size_in_bytes / 2 / WILDMIDI_NUM_CHANNELS;

  return TRUE;
}


static void
gst_wildmidi_dec_update_options (GstWildmidiDec * wildmidi_dec)
{
  unsigned short int options = 0;

  if (wildmidi_dec->song == NULL)
    return;

  if (wildmidi_dec->log_volume_scale)
    options |= WM_MO_LOG_VOLUME;
  if (wildmidi_dec->enhanced_resampling)
    options |= WM_MO_ENHANCED_RESAMPLING;
  if (wildmidi_dec->reverb)
    options |= WM_MO_REVERB;

  WildMidi_SetOption (wildmidi_dec->song,
      WM_MO_LOG_VOLUME | WM_MO_ENHANCED_RESAMPLING | WM_MO_REVERB, options);
}


static gboolean
plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "wildmididec", GST_RANK_MARGINAL,
      gst_wildmidi_dec_get_type ());
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    wildmidi,
    "WildMidi-based MIDI playback plugin",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
