/*
 * 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: fluidsynth
 *
 * 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 ! fluidsynth ! 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_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&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_ERROR (midiparse, STREAM, FAILED,
          ("Internal data flow error."),
          ("streaming task paused, reason %s (%d)", reason, 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;
  }
}
