/*
 * midiparse - midi parser plugin for gstreamer
 *
 * Copyright 2013 Wim Taymans <wim.taymans@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-midiparse
 * @see_also: fluiddec
 *
 * This element parses midi-files into midi events. You would need a midi
 * renderer such as fluidsynth to convert the events into raw samples.
 *
 * <refsect2>
 * <title>Example pipeline</title>
 * |[
 * gst-launch-1.0 filesrc location=song.mid ! midiparse ! fluiddec ! pulsesink
 * ]| This example pipeline will parse the midi and render to raw audio which is
 * played via pulseaudio.
 * </refsect2>
 */

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

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

#include "midiparse.h"

GST_DEBUG_CATEGORY_STATIC (gst_midi_parse_debug);
#define GST_CAT_DEFAULT gst_midi_parse_debug

enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  PROP_0,
  /* FILL ME */
};

#define DEFAULT_TEMPO   500000  /* 120 BPM is the default */

typedef struct
{
  guint8 *data;
  guint size;
  guint offset;

  guint8 running_status;
  guint64 pulse;
  gboolean eot;

} GstMidiTrack;

typedef GstFlowReturn (*GstMidiPushFunc) (GstMidiParse * parse,
    GstMidiTrack * track, guint8 event, guint8 * data, guint length,
    gpointer user_data);

static void gst_midi_parse_finalize (GObject * object);

static gboolean gst_midi_parse_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_midi_parse_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static GstStateChangeReturn gst_midi_parse_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_midi_parse_activate (GstPad * pad, GstObject * parent);
static gboolean gst_midi_parse_activatemode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active);

static void gst_midi_parse_loop (GstPad * sinkpad);
static GstFlowReturn gst_midi_parse_chain (GstPad * sinkpad, GstObject * parent,
    GstBuffer * buffer);

static gboolean gst_midi_parse_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);

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

static void reset_track (GstMidiTrack * track, GstMidiParse * midiparse);

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

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-midi-event"));

#define parent_class gst_midi_parse_parent_class
G_DEFINE_TYPE (GstMidiParse, gst_midi_parse, GST_TYPE_ELEMENT);

/* initialize the plugin's class */
static void
gst_midi_parse_class_init (GstMidiParseClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

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

  gobject_class->finalize = gst_midi_parse_finalize;
  gobject_class->set_property = gst_midi_parse_set_property;
  gobject_class->get_property = gst_midi_parse_get_property;

  gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
  gst_element_class_add_static_pad_template (gstelement_class, &sink_factory);
  gst_element_class_set_static_metadata (gstelement_class, "MidiParse",
      "Codec/Demuxer/Audio",
      "Midi Parser Element", "Wim Taymans <wim.taymans@gmail.com>");

  GST_DEBUG_CATEGORY_INIT (gst_midi_parse_debug, "midiparse",
      0, "MIDI parser plugin");

  gstelement_class->change_state = gst_midi_parse_change_state;
}

/* initialize the new element
 * instantiate pads and add them to element
 * set functions
 * initialize structure
 */
static void
gst_midi_parse_init (GstMidiParse * filter)
{
  filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");

  gst_pad_set_activatemode_function (filter->sinkpad,
      gst_midi_parse_activatemode);
  gst_pad_set_activate_function (filter->sinkpad, gst_midi_parse_activate);
  gst_pad_set_event_function (filter->sinkpad, gst_midi_parse_sink_event);
  gst_pad_set_chain_function (filter->sinkpad, gst_midi_parse_chain);
  gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);

  filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");

  gst_pad_set_query_function (filter->srcpad, gst_midi_parse_src_query);
  gst_pad_set_event_function (filter->srcpad, gst_midi_parse_src_event);
  gst_pad_use_fixed_caps (filter->srcpad);

  gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);

  gst_segment_init (&filter->segment, GST_FORMAT_TIME);

  filter->adapter = gst_adapter_new ();

  filter->have_group_id = FALSE;
  filter->group_id = G_MAXUINT;
}

static void
gst_midi_parse_finalize (GObject * object)
{
  GstMidiParse *midiparse;

  midiparse = GST_MIDI_PARSE (object);

  g_object_unref (midiparse->adapter);
  g_free (midiparse->data);

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

static gboolean
gst_midi_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean res = TRUE;
  GstMidiParse *midiparse = GST_MIDI_PARSE (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
      gst_query_set_duration (query, GST_FORMAT_TIME,
          midiparse->segment.duration);
      break;
    case GST_QUERY_POSITION:
      gst_query_set_position (query, GST_FORMAT_TIME,
          midiparse->segment.position);
      break;
    case GST_QUERY_FORMATS:
      gst_query_set_formats (query, 1, GST_FORMAT_TIME);
      break;
    case GST_QUERY_SEGMENT:{
      GstFormat format;
      gint64 start, stop;

      format = midiparse->segment.format;

      start =
          gst_segment_to_stream_time (&midiparse->segment, format,
          midiparse->segment.start);
      if ((stop = midiparse->segment.stop) == -1)
        stop = midiparse->segment.duration;
      else
        stop = gst_segment_to_stream_time (&midiparse->segment, format, stop);

      gst_query_set_segment (query, midiparse->segment.rate, format, start,
          stop);
      res = TRUE;
      break;
    }
    case GST_QUERY_SEEKING:
      gst_query_set_seeking (query, midiparse->segment.format,
          FALSE, 0, midiparse->segment.duration);
      break;
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

  return res;
}

static gboolean
gst_midi_parse_do_seek (GstMidiParse * midiparse, GstSegment * segment)
{
  /* if seeking backwards, start from 0 else we just let things run and
   * have it clip downstream */
  GST_DEBUG_OBJECT (midiparse, "seeking back to 0");
  segment->position = 0;
  g_list_foreach (midiparse->tracks, (GFunc) reset_track, midiparse);
  midiparse->pulse = 0;

  return TRUE;
}

static gboolean
gst_midi_parse_perform_seek (GstMidiParse * midiparse, GstEvent * event)
{
  gboolean res = TRUE, tres;
  gdouble rate;
  GstFormat seek_format;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  gboolean flush;
  gboolean update;
  GstSegment seeksegment;
  guint32 seqnum;
  GstEvent *tevent;

  GST_DEBUG_OBJECT (midiparse, "doing seek: %" GST_PTR_FORMAT, event);

  if (event) {
    gst_event_parse_seek (event, &rate, &seek_format, &flags,
        &start_type, &start, &stop_type, &stop);

    if (seek_format != GST_FORMAT_TIME)
      goto invalid_format;

    flush = flags & GST_SEEK_FLAG_FLUSH;
    seqnum = gst_event_get_seqnum (event);
  } else {
    flush = FALSE;
    /* get next seqnum */
    seqnum = gst_util_seqnum_next ();
  }

  /* send flush start */
  if (flush) {
    tevent = gst_event_new_flush_start ();
    gst_event_set_seqnum (tevent, seqnum);
    gst_pad_push_event (midiparse->srcpad, tevent);
  } else
    gst_pad_pause_task (midiparse->srcpad);

  /* grab streaming lock, this should eventually be possible, either
   * because the task is paused, our streaming thread stopped
   * or because our peer is flushing. */
  GST_PAD_STREAM_LOCK (midiparse->sinkpad);
  if (G_UNLIKELY (midiparse->seqnum == seqnum)) {
    /* we have seen this event before, issue a warning for now */
    GST_WARNING_OBJECT (midiparse, "duplicate event found %" G_GUINT32_FORMAT,
        seqnum);
  } else {
    midiparse->seqnum = seqnum;
    GST_DEBUG_OBJECT (midiparse, "seek with seqnum %" G_GUINT32_FORMAT, seqnum);
  }

  /* Copy the current segment info into the temp segment that we can actually
   * attempt the seek with. We only update the real segment if the seek succeeds. */
  memcpy (&seeksegment, &midiparse->segment, sizeof (GstSegment));

  /* now configure the final seek segment */
  if (event) {
    gst_segment_do_seek (&seeksegment, rate, seek_format, flags,
        start_type, start, stop_type, stop, &update);
  }

  /* Else, no seek event passed, so we're just (re)starting the
     current segment. */
  GST_DEBUG_OBJECT (midiparse, "segment configured from %" G_GINT64_FORMAT
      " to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
      seeksegment.start, seeksegment.stop, seeksegment.position);

  /* do the seek, segment.position contains the new position. */
  res = gst_midi_parse_do_seek (midiparse, &seeksegment);

  /* and prepare to continue streaming */
  if (flush) {
    tevent = gst_event_new_flush_stop (TRUE);
    gst_event_set_seqnum (tevent, seqnum);
    /* send flush stop, peer will accept data and events again. We
     * are not yet providing data as we still have the STREAM_LOCK. */
    gst_pad_push_event (midiparse->srcpad, tevent);
  }

  /* if the seek was successful, we update our real segment and push
   * out the new segment. */
  if (res) {
    GST_OBJECT_LOCK (midiparse);
    memcpy (&midiparse->segment, &seeksegment, sizeof (GstSegment));
    GST_OBJECT_UNLOCK (midiparse);

    if (seeksegment.flags & GST_SEGMENT_FLAG_SEGMENT) {
      GstMessage *message;

      message = gst_message_new_segment_start (GST_OBJECT (midiparse),
          seeksegment.format, seeksegment.position);
      gst_message_set_seqnum (message, seqnum);

      gst_element_post_message (GST_ELEMENT (midiparse), message);
    }
    /* for deriving a stop position for the playback segment from the seek
     * segment, we must take the duration when the stop is not set */
    if ((stop = seeksegment.stop) == -1)
      stop = seeksegment.duration;

    midiparse->segment_pending = TRUE;
    midiparse->discont = TRUE;
  }

  /* and restart the task in case it got paused explicitly or by
   * the FLUSH_START event we pushed out. */
  tres =
      gst_pad_start_task (midiparse->sinkpad,
      (GstTaskFunction) gst_midi_parse_loop, midiparse->sinkpad, NULL);
  if (res && !tres)
    res = FALSE;

  /* and release the lock again so we can continue streaming */
  GST_PAD_STREAM_UNLOCK (midiparse->sinkpad);

  return res;

  /* ERROR */
invalid_format:
  {
    GST_DEBUG_OBJECT (midiparse, "Unsupported seek format %s",
        gst_format_get_name (seek_format));
    return FALSE;
  }
}

static gboolean
gst_midi_parse_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = FALSE;
  GstMidiParse *midiparse = GST_MIDI_PARSE (parent);

  GST_DEBUG_OBJECT (pad, "%s event received", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      res = gst_midi_parse_perform_seek (midiparse, event);
      break;
    default:
      break;
  }
  gst_event_unref (event);

  return res;
}

static gboolean
gst_midi_parse_activate (GstPad * sinkpad, GstObject * parent)
{
  GstQuery *query;
  gboolean pull_mode;

  query = gst_query_new_scheduling ();

  if (!gst_pad_peer_query (sinkpad, query)) {
    gst_query_unref (query);
    goto activate_push;
  }

  pull_mode = gst_query_has_scheduling_mode_with_flags (query,
      GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
  gst_query_unref (query);

  if (!pull_mode)
    goto activate_push;

  GST_DEBUG_OBJECT (sinkpad, "activating pull");
  return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);

activate_push:
  {
    GST_DEBUG_OBJECT (sinkpad, "activating push");
    return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
  }
}

static gboolean
gst_midi_parse_activatemode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;

  switch (mode) {
    case GST_PAD_MODE_PUSH:
      res = TRUE;
      break;
    case GST_PAD_MODE_PULL:
      if (active) {
        res = gst_pad_start_task (pad, (GstTaskFunction) gst_midi_parse_loop,
            pad, NULL);
      } else {
        res = gst_pad_stop_task (pad);
      }
      break;
    default:
      res = FALSE;
      break;
  }
  return res;
}

static gboolean
parse_MThd (GstMidiParse * midiparse, guint8 * data, guint size)
{
  guint16 format, ntracks, division;
  gboolean multitrack;

  format = GST_READ_UINT16_BE (data);
  switch (format) {
    case 0:
      multitrack = FALSE;
      break;
    case 1:
      multitrack = TRUE;
      break;
    default:
    case 2:
      goto invalid_format;
  }
  ntracks = GST_READ_UINT16_BE (data + 2);
  if (ntracks > 1 && !multitrack)
    goto invalid_tracks;

  division = GST_READ_UINT16_BE (data + 4);
  if (division & 0x8000)
    goto invalid_division;

  GST_DEBUG_OBJECT (midiparse, "format %u, tracks %u, division %u",
      format, ntracks, division);

  midiparse->ntracks = ntracks;
  midiparse->division = division;

  return TRUE;

invalid_format:
  {
    GST_ERROR_OBJECT (midiparse, "unsupported midi format %u", format);
    return FALSE;
  }
invalid_tracks:
  {
    GST_ERROR_OBJECT (midiparse, "invalid number of tracks %u for format %u",
        ntracks, format);
    return FALSE;
  }
invalid_division:
  {
    GST_ERROR_OBJECT (midiparse, "unsupported division");
    return FALSE;
  }
}

static guint
parse_varlen (GstMidiParse * midiparse, guint8 * data, guint size,
    gint32 * result)
{
  gint32 res;
  gint i;

  res = 0;
  for (i = 0; i < 4; i++) {
    if (size == 0)
      return 0;

    res = (res << 7) | ((data[i]) & 0x7f);
    if ((data[i] & 0x80) == 0) {
      *result = res;
      return i + 1;
    }
  }
  return 0;
}

static GstFlowReturn
handle_meta_event (GstMidiParse * midiparse, GstMidiTrack * track, guint8 event)
{
  guint8 type;
  guint8 *data;
  gchar *bytes;
  guint size, consumed;
  gint32 length;

  track->offset += 1;

  data = track->data + track->offset;
  size = track->size - track->offset;

  if (size < 1)
    goto short_file;

  type = data[0];

  consumed = parse_varlen (midiparse, data + 1, size - 1, &length);
  if (consumed == 0)
    goto short_file;

  data += consumed + 1;
  size -= consumed + 1;

  if (size < length)
    goto short_file;

  GST_DEBUG_OBJECT (midiparse, "handle meta event type 0x%02x, length %u",
      type, length);

  bytes = g_strndup ((const gchar *) data, length);

  switch (type) {
    case 0x01:
      GST_DEBUG_OBJECT (midiparse, "Text: %s", bytes);
      break;
    case 0x02:
      GST_DEBUG_OBJECT (midiparse, "Copyright: %s", bytes);
      break;
    case 0x03:
      GST_DEBUG_OBJECT (midiparse, "Track Name: %s", bytes);
      break;
    case 0x04:
      GST_DEBUG_OBJECT (midiparse, "Instrument: %s", bytes);
      break;
    case 0x05:
      GST_DEBUG_OBJECT (midiparse, "Lyric: %s", bytes);
      break;
    case 0x06:
      GST_DEBUG_OBJECT (midiparse, "Marker: %s", bytes);
      break;
    case 0x07:
      GST_DEBUG_OBJECT (midiparse, "Cue point: %s", bytes);
      break;
    case 0x08:
      GST_DEBUG_OBJECT (midiparse, "Patch name: %s", bytes);
      break;
    case 0x09:
      GST_DEBUG_OBJECT (midiparse, "MIDI port: %s", bytes);
      break;
    case 0x2f:
      GST_DEBUG_OBJECT (midiparse, "End of track");
      break;
    case 0x51:
    {
      guint32 uspqn = (data[0] << 16) | (data[1] << 8) | data[2];
      midiparse->tempo = (uspqn ? uspqn : DEFAULT_TEMPO);
      GST_DEBUG_OBJECT (midiparse, "tempo %u", midiparse->tempo);
      break;
    }
    case 0x54:
      GST_DEBUG_OBJECT (midiparse, "SMPTE offset");
      break;
    case 0x58:
      GST_DEBUG_OBJECT (midiparse, "Time signature");
      break;
    case 0x59:
      GST_DEBUG_OBJECT (midiparse, "Key signature");
      break;
    case 0x7f:
      GST_DEBUG_OBJECT (midiparse, "Proprietary event");
      break;
    default:
      GST_DEBUG_OBJECT (midiparse, "unknown event 0x%02x length %d", type,
          length);
      break;
  }
  g_free (bytes);

  track->offset += consumed + length + 1;

  return GST_FLOW_OK;

  /* ERRORS */
short_file:
  {
    GST_DEBUG_OBJECT (midiparse, "not enough data");
    return GST_FLOW_ERROR;
  }
}

static GstFlowReturn
handle_sysex_event (GstMidiParse * midiparse, GstMidiTrack * track,
    guint8 event, GstMidiPushFunc pushfunc, gpointer user_data)
{
  GstFlowReturn ret;
  guint8 *data;
  guint size, consumed;
  gint32 length;

  track->offset += 1;

  data = track->data + track->offset;
  size = track->size - track->offset;

  consumed = parse_varlen (midiparse, data, size, &length);
  if (consumed == 0)
    goto short_file;

  data += consumed;
  size -= consumed;

  if (size < length)
    goto short_file;

  GST_DEBUG_OBJECT (midiparse, "handle sysex event 0x%02x, length %u",
      event, length);

  if (pushfunc)
    ret = pushfunc (midiparse, track, event, data, length, user_data);
  else
    ret = GST_FLOW_OK;

  track->offset += consumed + length;

  return ret;

  /* ERRORS */
short_file:
  {
    GST_DEBUG_OBJECT (midiparse, "not enough data");
    return GST_FLOW_ERROR;
  }
}


static guint8
event_from_status (GstMidiParse * midiparse, GstMidiTrack * track,
    guint8 status)
{
  if ((status & 0x80) == 0) {
    if ((track->running_status & 0x80) == 0)
      return 0;

    return track->running_status;
  } else {
    return status;
  }
}

static gboolean
update_track_position (GstMidiParse * midiparse, GstMidiTrack * track)
{
  gint32 delta_time;
  guint8 *data;
  guint size, consumed;

  if (track->offset >= track->size)
    goto eot;

  data = track->data + track->offset;
  size = track->size - track->offset;

  consumed = parse_varlen (midiparse, data, size, &delta_time);
  if (consumed == 0)
    goto eot;

  track->pulse += delta_time;
  track->offset += consumed;

  GST_LOG_OBJECT (midiparse, "updated track to pulse %" G_GUINT64_FORMAT,
      track->pulse);

  return TRUE;

  /* ERRORS */
eot:
  {
    GST_DEBUG_OBJECT (midiparse, "track ended");
    track->eot = TRUE;
    return FALSE;
  }
}

static GstFlowReturn
handle_next_event (GstMidiParse * midiparse, GstMidiTrack * track,
    GstMidiPushFunc pushfunc, gpointer user_data)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint8 status, event;
  guint length;
  guint8 *data;

  data = &track->data[track->offset];

  status = data[0];
  event = event_from_status (midiparse, track, status);

  GST_LOG_OBJECT (midiparse, "track %p, status 0x%02x, event 0x%02x", track,
      status, event);

  switch (event & 0xf0) {
    case 0xf0:
      switch (event) {
        case 0xff:
          ret = handle_meta_event (midiparse, track, event);
          break;
        case 0xf0:
        case 0xf7:
          ret =
              handle_sysex_event (midiparse, track, event, pushfunc, user_data);
          break;
        default:
          goto unhandled_event;
      }
      length = 0;
      break;
    case 0xc0:
    case 0xd0:
      length = 1;
      break;
    case 0x80:
    case 0x90:
    case 0xa0:
    case 0xb0:
    case 0xe0:
      length = 2;
      break;
    default:
      goto undefined_status;
  }
  if (length > 0) {
    if (status & 0x80) {
      if (pushfunc)
        ret = pushfunc (midiparse, track, event, data + 1, length, user_data);
      track->offset += length + 1;
    } else {
      if (pushfunc)
        ret = pushfunc (midiparse, track, event, data, length + 1, user_data);
      track->offset += length;
    }
  }

  if (ret == GST_FLOW_OK) {
    if (event < 0xF8)
      track->running_status = event;

    update_track_position (midiparse, track);
  }
  return ret;

  /* ERRORS */
undefined_status:
  {
    GST_ERROR_OBJECT (midiparse, "Undefined status and invalid running status");
    return GST_FLOW_ERROR;
  }
unhandled_event:
  {
    /* we don't know the size so we can't continue parsing */
    GST_ERROR_OBJECT (midiparse, "unhandled event 0x%08x", event);
    return GST_FLOW_ERROR;
  }
}

static void
reset_track (GstMidiTrack * track, GstMidiParse * midiparse)
{
  GST_DEBUG_OBJECT (midiparse, "reset track");
  track->offset = 0;
  track->pulse = 0;
  track->eot = FALSE;
  track->running_status = 0xff;
  update_track_position (midiparse, track);
}

static gboolean
parse_MTrk (GstMidiParse * midiparse, guint8 * data, guint size)
{
  GstMidiTrack *track;
  GstClockTime duration;

  /* ignore excess tracks */
  if (midiparse->track_count >= midiparse->ntracks)
    return TRUE;

  track = g_slice_new (GstMidiTrack);
  track->data = data;
  track->size = size;
  reset_track (track, midiparse);

  midiparse->tracks = g_list_append (midiparse->tracks, track);
  midiparse->track_count++;

  /* now loop over all events and calculate the duration */
  while (!track->eot) {
    handle_next_event (midiparse, track, NULL, NULL);
  }

  duration = gst_util_uint64_scale (track->pulse,
      1000 * midiparse->tempo, midiparse->division);

  GST_DEBUG_OBJECT (midiparse, "duration %" GST_TIME_FORMAT,
      GST_TIME_ARGS (duration));

  if (duration > midiparse->segment.duration)
    midiparse->segment.duration = duration;

  reset_track (track, midiparse);

  return TRUE;
}

static gboolean
find_midi_chunk (GstMidiParse * midiparse, guint8 * data, guint size,
    guint * offset, guint * length)
{
  guint32 type;

  *length = 0;

  if (size < 8)
    goto short_chunk;

  type = GST_STR_FOURCC (data);

  if (type == GST_MAKE_FOURCC ('R', 'I', 'F', 'F')) {
    guint32 riff_len;

    GST_DEBUG_OBJECT (midiparse, "found RIFF");

    if (size < 12)
      goto short_chunk;

    if (GST_STR_FOURCC (data + 8) != GST_MAKE_FOURCC ('R', 'M', 'I', 'D'))
      goto invalid_format;

    riff_len = GST_READ_UINT32_LE (data + 4);

    if (size < riff_len)
      goto short_chunk;

    data += 12;
    size -= 12;
    *offset = 12;

    GST_DEBUG_OBJECT (midiparse, "found RIFF RMID of size %u", riff_len);

    while (TRUE) {
      guint32 chunk_type;
      guint32 chunk_len;

      if (riff_len < 8)
        goto short_chunk;

      chunk_type = GST_STR_FOURCC (data);
      chunk_len = GST_READ_UINT32_LE (data + 4);

      riff_len -= 8;
      if (riff_len < chunk_len)
        goto short_chunk;

      data += 8;
      size -= 8;
      *offset += 8;
      riff_len -= chunk_len;

      if (chunk_type == GST_MAKE_FOURCC ('d', 'a', 't', 'a')) {
        *length = chunk_len;
        break;
      }

      data += chunk_len;
      size -= chunk_len;
    }
  } else {
    *offset = 0;
    *length = size;
  }
  return TRUE;

  /* ERRORS */
short_chunk:
  {
    GST_LOG_OBJECT (midiparse, "not enough data %u < %u", *length + 8, size);
    return FALSE;
  }
invalid_format:
  {
    GST_ERROR_OBJECT (midiparse, "invalid format");
    return FALSE;
  }
}

static guint
gst_midi_parse_chunk (GstMidiParse * midiparse, guint8 * data, guint size)
{
  guint32 type, length = 0;

  if (size < 8)
    goto short_chunk;

  length = GST_READ_UINT32_BE (data + 4);

  GST_DEBUG_OBJECT (midiparse, "have type %c%c%c%c, length %u",
      data[0], data[1], data[2], data[3], length);

  if (size < length + 8)
    goto short_chunk;

  type = GST_STR_FOURCC (data);

  switch (type) {
    case GST_MAKE_FOURCC ('M', 'T', 'h', 'd'):
      if (!parse_MThd (midiparse, data + 8, length))
        goto invalid_format;
      break;
    case GST_MAKE_FOURCC ('M', 'T', 'r', 'k'):
      if (!parse_MTrk (midiparse, data + 8, length))
        goto invalid_format;
      break;
    default:
      GST_LOG_OBJECT (midiparse, "ignore chunk");
      break;
  }

  return length + 8;

  /* ERRORS */
short_chunk:
  {
    GST_LOG_OBJECT (midiparse, "not enough data %u < %u", size, length + 8);
    return 0;
  }
invalid_format:
  {
    GST_ERROR_OBJECT (midiparse, "invalid format");
    return 0;
  }
}

static GstFlowReturn
gst_midi_parse_parse_song (GstMidiParse * midiparse)
{
  GstCaps *outcaps;
  guint8 *data;
  guint size, offset, length;
  GstEvent *event;
  gchar *stream_id;

  GST_DEBUG_OBJECT (midiparse, "Parsing song");

  gst_segment_init (&midiparse->segment, GST_FORMAT_TIME);
  midiparse->segment.duration = 0;
  midiparse->pulse = 0;

  size = gst_adapter_available (midiparse->adapter);
  data = gst_adapter_take (midiparse->adapter, size);

  midiparse->data = data;
  midiparse->tempo = DEFAULT_TEMPO;

  if (!find_midi_chunk (midiparse, data, size, &offset, &length))
    goto invalid_format;

  while (length) {
    guint consumed;

    consumed = gst_midi_parse_chunk (midiparse, &data[offset], length);
    if (consumed == 0)
      goto short_file;

    offset += consumed;
    length -= consumed;
  }

  GST_DEBUG_OBJECT (midiparse, "song duration %" GST_TIME_FORMAT,
      GST_TIME_ARGS (midiparse->segment.duration));

  stream_id =
      gst_pad_create_stream_id (midiparse->srcpad, GST_ELEMENT_CAST (midiparse),
      NULL);
  event =
      gst_pad_get_sticky_event (midiparse->sinkpad, GST_EVENT_STREAM_START, 0);
  if (event) {
    if (gst_event_parse_group_id (event, &midiparse->group_id))
      midiparse->have_group_id = TRUE;
    else
      midiparse->have_group_id = FALSE;
    gst_event_unref (event);
  } else if (!midiparse->have_group_id) {
    midiparse->have_group_id = TRUE;
    midiparse->group_id = gst_util_group_id_next ();
  }
  event = gst_event_new_stream_start (stream_id);
  if (midiparse->have_group_id)
    gst_event_set_group_id (event, midiparse->group_id);
  gst_pad_push_event (midiparse->srcpad, event);
  g_free (stream_id);

  outcaps = gst_pad_get_pad_template_caps (midiparse->srcpad);
  gst_pad_set_caps (midiparse->srcpad, outcaps);
  gst_caps_unref (outcaps);

  midiparse->segment_pending = TRUE;
  midiparse->discont = TRUE;

  GST_DEBUG_OBJECT (midiparse, "Parsing song done");

  return GST_FLOW_OK;

  /* ERRORS */
short_file:
  {
    GST_ERROR_OBJECT (midiparse, "not enough data");
    return GST_FLOW_ERROR;
  }
invalid_format:
  {
    GST_ERROR_OBJECT (midiparse, "invalid format");
    return GST_FLOW_ERROR;
  }
}

static GstFlowReturn
play_push_func (GstMidiParse * midiparse, GstMidiTrack * track,
    guint8 event, guint8 * data, guint length, gpointer user_data)
{
  GstBuffer *outbuf;
  GstMapInfo info;
  GstClockTime position;

  outbuf = gst_buffer_new_allocate (NULL, length + 1, NULL);

  gst_buffer_map (outbuf, &info, GST_MAP_WRITE);
  info.data[0] = event;
  if (length)
    memcpy (&info.data[1], data, length);
  gst_buffer_unmap (outbuf, &info);

  position = midiparse->segment.position;
  GST_BUFFER_PTS (outbuf) = position;
  GST_BUFFER_DTS (outbuf) = position;

  GST_DEBUG_OBJECT (midiparse, "pushing %" GST_TIME_FORMAT,
      GST_TIME_ARGS (position));

  if (midiparse->discont) {
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
    midiparse->discont = FALSE;
  }

  return gst_pad_push (midiparse->srcpad, outbuf);
}

static GstFlowReturn
gst_midi_parse_do_play (GstMidiParse * midiparse)
{
  GstFlowReturn res;
  GList *walk;
  guint64 pulse, next_pulse = G_MAXUINT64;
  GstClockTime position, next_position;
  guint64 tick;

  pulse = midiparse->pulse;
  position = midiparse->segment.position;

  if (midiparse->segment_pending) {
    gst_pad_push_event (midiparse->srcpad,
        gst_event_new_segment (&midiparse->segment));
    midiparse->segment_pending = FALSE;
  }

  GST_DEBUG_OBJECT (midiparse, "pulse %" G_GUINT64_FORMAT ", position %"
      GST_TIME_FORMAT, pulse, GST_TIME_ARGS (position));

  for (walk = midiparse->tracks; walk; walk = g_list_next (walk)) {
    GstMidiTrack *track = walk->data;

    while (!track->eot && track->pulse == pulse) {
      res = handle_next_event (midiparse, track, play_push_func, NULL);
      if (res != GST_FLOW_OK)
        goto error;
    }

    if (!track->eot && track->pulse < next_pulse)
      next_pulse = track->pulse;
  }

  if (next_pulse == G_MAXUINT64)
    goto eos;

  tick = position / (10 * GST_MSECOND);
  GST_DEBUG_OBJECT (midiparse, "current tick %" G_GUINT64_FORMAT, tick);

  next_position = gst_util_uint64_scale (next_pulse,
      1000 * midiparse->tempo, midiparse->division);
  GST_DEBUG_OBJECT (midiparse, "next position %" GST_TIME_FORMAT,
      GST_TIME_ARGS (next_position));

  /* send 10ms ticks to advance the downstream element */
  while (TRUE) {
    /* get position of next tick */
    position = ++tick * (10 * GST_MSECOND);
    GST_DEBUG_OBJECT (midiparse, "tick %" G_GUINT64_FORMAT
        ", position %" GST_TIME_FORMAT, tick, GST_TIME_ARGS (position));

    if (position >= next_position)
      break;

    midiparse->segment.position = position;
    res = play_push_func (midiparse, NULL, 0xf9, NULL, 0, NULL);
    if (res != GST_FLOW_OK)
      goto error;
  }

  midiparse->pulse = next_pulse;
  midiparse->segment.position = next_position;

  return GST_FLOW_OK;

  /* ERRORS */
eos:
  {
    GST_DEBUG_OBJECT (midiparse, "we are EOS");
    return GST_FLOW_EOS;
  }
error:
  {
    GST_DEBUG_OBJECT (midiparse, "have flow result %s",
        gst_flow_get_name (res));
    return res;
  }
}

static gboolean
gst_midi_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstMidiParse *midiparse = GST_MIDI_PARSE (parent);

  GST_DEBUG_OBJECT (pad, "%s event received", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
      midiparse->state = GST_MIDI_PARSE_STATE_PARSE;
      /* now start the parsing task */
      res = gst_pad_start_task (midiparse->sinkpad,
          (GstTaskFunction) gst_midi_parse_loop, midiparse->sinkpad, NULL);
      /* don't forward the event */
      gst_event_unref (event);
      break;
    case GST_EVENT_CAPS:
    case GST_EVENT_STREAM_START:
    case GST_EVENT_SEGMENT:
      res = TRUE;
      gst_event_unref (event);
      break;
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }
  return res;
}

static GstFlowReturn
gst_midi_parse_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buffer)
{
  GstMidiParse *midiparse;

  midiparse = GST_MIDI_PARSE (parent);

  /* push stuff in the adapter, we will start doing something in the sink event
   * handler when we get EOS */
  gst_adapter_push (midiparse->adapter, buffer);

  return GST_FLOW_OK;
}

static void
gst_midi_parse_loop (GstPad * sinkpad)
{
  GstMidiParse *midiparse = GST_MIDI_PARSE (GST_PAD_PARENT (sinkpad));
  GstFlowReturn ret;

  switch (midiparse->state) {
    case GST_MIDI_PARSE_STATE_LOAD:
    {
      GstBuffer *buffer = NULL;

      GST_DEBUG_OBJECT (midiparse, "loading song");

      ret =
          gst_pad_pull_range (midiparse->sinkpad, midiparse->offset, -1,
          &buffer);

      if (ret == GST_FLOW_EOS) {
        GST_DEBUG_OBJECT (midiparse, "Song loaded");
        midiparse->state = GST_MIDI_PARSE_STATE_PARSE;
      } else if (ret != GST_FLOW_OK) {
        GST_ELEMENT_ERROR (midiparse, STREAM, DECODE, (NULL),
            ("Unable to read song"));
        goto pause;
      } else {
        GST_DEBUG_OBJECT (midiparse, "pushing buffer");
        gst_adapter_push (midiparse->adapter, buffer);
        midiparse->offset += gst_buffer_get_size (buffer);
      }
      break;
    }
    case GST_MIDI_PARSE_STATE_PARSE:
      ret = gst_midi_parse_parse_song (midiparse);
      if (ret != GST_FLOW_OK)
        goto pause;
      midiparse->state = GST_MIDI_PARSE_STATE_PLAY;
      break;
    case GST_MIDI_PARSE_STATE_PLAY:
      ret = gst_midi_parse_do_play (midiparse);
      if (ret != GST_FLOW_OK)
        goto pause;
      break;
    default:
      break;
  }
  return;

pause:
  {
    const gchar *reason = gst_flow_get_name (ret);
    GstEvent *event;

    GST_DEBUG_OBJECT (midiparse, "pausing task, reason %s", reason);
    gst_pad_pause_task (sinkpad);
    if (ret == GST_FLOW_EOS) {
      /* perform EOS logic */
      event = gst_event_new_eos ();
      gst_pad_push_event (midiparse->srcpad, event);
    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
      event = gst_event_new_eos ();
      /* for fatal errors we post an error message, post the error
       * first so the app knows about the error first. */
      GST_ELEMENT_FLOW_ERROR (midiparse, ret);
      gst_pad_push_event (midiparse->srcpad, event);
    }
  }
}

static void
free_track (GstMidiTrack * track, GstMidiParse * midiparse)
{
  g_slice_free (GstMidiTrack, track);
}

static void
gst_midi_parse_reset (GstMidiParse * midiparse)
{
  gst_adapter_clear (midiparse->adapter);
  g_free (midiparse->data);
  midiparse->data = NULL;
  g_list_foreach (midiparse->tracks, (GFunc) free_track, midiparse);
  g_list_free (midiparse->tracks);
  midiparse->tracks = NULL;
  midiparse->track_count = 0;
  midiparse->have_group_id = FALSE;
  midiparse->group_id = G_MAXUINT;
}

static GstStateChangeReturn
gst_midi_parse_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstMidiParse *midiparse = GST_MIDI_PARSE (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      midiparse->offset = 0;
      midiparse->state = GST_MIDI_PARSE_STATE_LOAD;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_midi_parse_reset (midiparse);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}

static void
gst_midi_parse_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_midi_parse_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
