/* GStreamer
 * Copyright (C) 2014  Antonio Ospite <ao2@ao2.it>
 *
 * gstalsamidisrc.c: Source element for ALSA MIDI sequencer events
 *
 * 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-alsamidisrc
 * @title: alsamidisrc
 * @see_also: #GstPushSrc
 *
 * The alsamidisrc element is an element that fetches ALSA MIDI sequencer
 * events and makes them available to elements understanding
 * audio/x-midi-events in their sink pads.
 *
 * It can be used to generate notes from a MIDI input device.
 *
 * ## Example launch line
 * |[
 * gst-launch -v alsamidisrc ports=129:0 ! fluiddec ! audioconvert ! autoaudiosink
 * ]|
 *  This pipeline will listen for events from the sequencer device at port 129:0,
 * and generate notes using the fluiddec element.
 *
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "gstalsamidisrc.h"

GST_DEBUG_CATEGORY_STATIC (gst_alsa_midi_src_debug);
#define GST_CAT_DEFAULT gst_alsa_midi_src_debug

/*
 * The MIDI specification declares some status bytes undefined:
 *
 *  - 0xF4 System common - Undefined (Reserved)
 *  - 0xF5 System common - Undefined (Reserved)
 *  - 0xF9 System real-time - Undefined (Reserved)
 *  - 0xFD System real-time - Undefined (Reserved)
 *
 * See: http://www.midi.org/techspecs/midimessages.php#2
 *
 * Some other documents define status 0xf9 as a tick message with a period of
 * 10ms:
 *
 *  - http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/midispec/tick.htm
 *  - http://www.sequencer.de/synth/index.php/MIDI_Format#0xf9_-_MIDI_Tick
 *
 * Even if non-standard it looks like this convention is quite widespread.
 *
 * For instance Fluidsynth uses 0xF9 as a "midi tick" message:
 * http://sourceforge.net/p/fluidsynth/code-git/ci/master/tree/fluidsynth/src/midi/fluid_midi.h#l62
 *
 * And then so does the midiparse element in order to be compatible with
 * Fluidsynth and the fluiddec element.
 *
 * Do the same to behave like midiparse.
 */
#define MIDI_TICK 0xf9
#define MIDI_TICK_PERIOD_MS 10

/* Functions specific to the Alsa MIDI sequencer API */

#define DEFAULT_BUFSIZE 65536
#define DEFAULT_CLIENT_NAME "alsamidisrc"

static int
init_seq (GstAlsaMidiSrc * alsamidisrc)
{
  int ret;

  ret = snd_seq_open (&alsamidisrc->seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
  if (ret < 0) {
    GST_ERROR_OBJECT (alsamidisrc, "Cannot open sequencer - %s",
        snd_strerror (ret));
    goto error;
  }

  /*
   * Prevent Valgrind from reporting cached configuration as memory leaks, see:
   * http://git.alsa-project.org/?p=alsa-lib.git;a=blob;f=MEMORY-LEAK;hb=HEAD
   */
  snd_config_update_free_global ();

  ret = snd_seq_set_client_name (alsamidisrc->seq, DEFAULT_CLIENT_NAME);
  if (ret < 0) {
    GST_ERROR_OBJECT (alsamidisrc, "Cannot set client name - %s",
        snd_strerror (ret));
    goto error_seq_close;
  }

  return 0;

error_seq_close:
  snd_seq_close (alsamidisrc->seq);
error:
  return ret;
}

/* Parses one or more port addresses from the string */
static int
parse_ports (const char *arg, GstAlsaMidiSrc * alsamidisrc)
{
  gchar **ports_list;
  guint i;
  int ret = 0;

  GST_DEBUG_OBJECT (alsamidisrc, "ports: %s", arg);

  /*
   * Assume that ports are separated by commas.
   *
   * Commas are used instead of spaces because spaces are valid in client
   * names.
   */
  ports_list = g_strsplit (arg, ",", 0);

  alsamidisrc->port_count = g_strv_length (ports_list);
  alsamidisrc->seq_ports = g_try_new (snd_seq_addr_t, alsamidisrc->port_count);
  if (!alsamidisrc->seq_ports) {
    GST_ERROR_OBJECT (alsamidisrc, "Out of memory");
    ret = -ENOMEM;
    goto out_free_ports_list;
  }

  for (i = 0; i < alsamidisrc->port_count; i++) {
    gchar *port_name = ports_list[i];

    ret = snd_seq_parse_address (alsamidisrc->seq, &alsamidisrc->seq_ports[i],
        port_name);
    if (ret < 0) {
      GST_ERROR_OBJECT (alsamidisrc, "Invalid port %s - %s", port_name,
          snd_strerror (ret));
      goto error_free_seq_ports;
    }
  }

  goto out_free_ports_list;

error_free_seq_ports:
  g_free (alsamidisrc->seq_ports);
out_free_ports_list:
  g_strfreev (ports_list);
  return ret;
}

static int
start_queue_timer (GstAlsaMidiSrc * alsamidisrc)
{
  int ret;

  ret = snd_seq_start_queue (alsamidisrc->seq, alsamidisrc->queue, NULL);
  if (ret < 0) {
    GST_ERROR_OBJECT (alsamidisrc, "Timer event output error: %s\n",
        snd_strerror (ret));
    return ret;
  }

  ret = snd_seq_drain_output (alsamidisrc->seq);
  if (ret < 0)
    GST_ERROR_OBJECT (alsamidisrc, "Drain output error: %s\n",
        snd_strerror (ret));

  return ret;
}

static void
schedule_next_tick (GstAlsaMidiSrc * alsamidisrc)
{
  snd_seq_event_t ev;
  snd_seq_real_time_t time;
  int ret;

  snd_seq_ev_clear (&ev);
  snd_seq_ev_set_source (&ev, 0);
  snd_seq_ev_set_dest (&ev, snd_seq_client_id (alsamidisrc->seq), 0);

  ev.type = SND_SEQ_EVENT_TICK;

  alsamidisrc->tick += 1;
  GST_TIME_TO_TIMESPEC (alsamidisrc->tick * MIDI_TICK_PERIOD_MS * GST_MSECOND,
      time);

  snd_seq_ev_schedule_real (&ev, alsamidisrc->queue, SND_SEQ_TIME_MODE_ABS,
      &time);

  ret = snd_seq_event_output (alsamidisrc->seq, &ev);
  if (ret < 0)
    GST_ERROR_OBJECT (alsamidisrc, "Event output error: %s\n",
        snd_strerror (ret));

  ret = snd_seq_drain_output (alsamidisrc->seq);
  if (ret < 0)
    GST_ERROR_OBJECT (alsamidisrc, "Event drain error: %s\n",
        snd_strerror (ret));
}

static int
create_port (GstAlsaMidiSrc * alsamidisrc)
{
  snd_seq_port_info_t *pinfo;
  int ret;

  snd_seq_port_info_alloca (&pinfo);
  snd_seq_port_info_set_name (pinfo, DEFAULT_CLIENT_NAME);
  snd_seq_port_info_set_type (pinfo,
      SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
  snd_seq_port_info_set_capability (pinfo,
      SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE);

  ret = snd_seq_alloc_named_queue (alsamidisrc->seq, DEFAULT_CLIENT_NAME);
  if (ret < 0) {
    GST_ERROR_OBJECT (alsamidisrc, "Cannot allocate queue: %s\n",
        snd_strerror (ret));
    return ret;
  }

  /*
   * Sequencer queues are "per-system" entities, so it's important to remember
   * the queue id to make sure alsamidisrc refers to this very one in future
   * operations, and not to some other port created by another sequencer user.
   */
  alsamidisrc->queue = ret;

  snd_seq_port_info_set_timestamping (pinfo, 1);
  snd_seq_port_info_set_timestamp_real (pinfo, 1);
  snd_seq_port_info_set_timestamp_queue (pinfo, alsamidisrc->queue);

  ret = snd_seq_create_port (alsamidisrc->seq, pinfo);
  if (ret < 0) {
    GST_ERROR_OBJECT (alsamidisrc, "Cannot create port - %s",
        snd_strerror (ret));
    return ret;
  }

  /*
   * Conversely, it's not strictly necessary to remember the port id because
   * ports are per-client and alsamidisrc is only creating one port (id = 0).
   *
   * If multiple ports were to be created, the ids could be retrieved with
   * something like:
   *
   *   alsamidisrc->port = snd_seq_port_info_get_port(pinfo);
   */

  ret = start_queue_timer (alsamidisrc);
  if (ret < 0)
    GST_ERROR_OBJECT (alsamidisrc, "Cannot start timer for queue: %d - %s",
        alsamidisrc->queue, snd_strerror (ret));

  return ret;
}

static void
connect_ports (GstAlsaMidiSrc * alsamidisrc)
{
  int i;
  int ret;

  for (i = 0; i < alsamidisrc->port_count; ++i) {
    ret =
        snd_seq_connect_from (alsamidisrc->seq, 0,
        alsamidisrc->seq_ports[i].client, alsamidisrc->seq_ports[i].port);
    if (ret < 0)
      /* Issue a warning and try the other ports */
      GST_WARNING_OBJECT (alsamidisrc, "Cannot connect from port %d:%d - %s",
          alsamidisrc->seq_ports[i].client, alsamidisrc->seq_ports[i].port,
          snd_strerror (ret));
  }
}

/* GStreamer specific functions */

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

#define DEFAULT_PORTS           NULL

enum
{
  PROP_0,
  PROP_PORTS,
  PROP_LAST,
};

#define _do_init \
    GST_DEBUG_CATEGORY_INIT (gst_alsa_midi_src_debug, "alsamidisrc", 0, "alsamidisrc element");
#define gst_alsa_midi_src_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstAlsaMidiSrc, gst_alsa_midi_src, GST_TYPE_PUSH_SRC,
    _do_init);

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

static gboolean gst_alsa_midi_src_start (GstBaseSrc * basesrc);
static gboolean gst_alsa_midi_src_stop (GstBaseSrc * basesrc);
static gboolean gst_alsa_midi_src_unlock (GstBaseSrc * basesrc);
static gboolean gst_alsa_midi_src_unlock_stop (GstBaseSrc * basesrc);
static void gst_alsa_midi_src_state_changed (GstElement * element,
    GstState oldstate, GstState newstate, GstState pending);

static GstFlowReturn
gst_alsa_midi_src_create (GstPushSrc * src, GstBuffer ** buf);

static void
gst_alsa_midi_src_class_init (GstAlsaMidiSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSrcClass *gstbase_src_class;
  GstPushSrcClass *gstpush_src_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstbase_src_class = GST_BASE_SRC_CLASS (klass);
  gstpush_src_class = GST_PUSH_SRC_CLASS (klass);

  gobject_class->set_property = gst_alsa_midi_src_set_property;
  gobject_class->get_property = gst_alsa_midi_src_get_property;

  g_object_class_install_property (gobject_class, PROP_PORTS,
      g_param_spec_string ("ports", "Ports",
          "Comma separated list of sequencer ports (e.g. client:port,...)",
          DEFAULT_PORTS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_static_metadata (gstelement_class,
      "AlsaMidi Source",
      "Source",
      "Push ALSA MIDI sequencer events around", "Antonio Ospite <ao2@ao2.it>");
  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);

  gstbase_src_class->start = GST_DEBUG_FUNCPTR (gst_alsa_midi_src_start);
  gstbase_src_class->stop = GST_DEBUG_FUNCPTR (gst_alsa_midi_src_stop);
  gstbase_src_class->unlock = GST_DEBUG_FUNCPTR (gst_alsa_midi_src_unlock);
  gstbase_src_class->unlock_stop =
      GST_DEBUG_FUNCPTR (gst_alsa_midi_src_unlock_stop);
  gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_alsa_midi_src_create);
  gstelement_class->state_changed =
      GST_DEBUG_FUNCPTR (gst_alsa_midi_src_state_changed);
}

static void
gst_alsa_midi_src_init (GstAlsaMidiSrc * alsamidisrc)
{
  alsamidisrc->ports = DEFAULT_PORTS;

  gst_base_src_set_format (GST_BASE_SRC (alsamidisrc), GST_FORMAT_TIME);
  gst_base_src_set_live (GST_BASE_SRC (alsamidisrc), TRUE);
}

static void
gst_alsa_midi_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAlsaMidiSrc *src;

  src = GST_ALSA_MIDI_SRC (object);

  switch (prop_id) {
    case PROP_PORTS:
      g_free (src->ports);
      src->ports = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_alsa_midi_src_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstAlsaMidiSrc *src;

  g_return_if_fail (GST_IS_ALSA_MIDI_SRC (object));

  src = GST_ALSA_MIDI_SRC (object);

  switch (prop_id) {
    case PROP_PORTS:
      g_value_set_string (value, src->ports);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
push_buffer (GstAlsaMidiSrc * alsamidisrc, gpointer data, guint size,
    GstClockTime time, GstBufferList * buffer_list)
{
  gpointer local_data;
  GstBuffer *buffer;

  buffer = gst_buffer_new ();

  GST_BUFFER_DTS (buffer) = time;
  GST_BUFFER_PTS (buffer) = time;

  local_data = g_memdup (data, size);

  gst_buffer_append_memory (buffer,
      gst_memory_new_wrapped (0, local_data, size, 0, size, local_data,
          g_free));

  GST_MEMDUMP_OBJECT (alsamidisrc, "MIDI data:", local_data, size);

  gst_buffer_list_add (buffer_list, buffer);
}

static void
push_tick_buffer (GstAlsaMidiSrc * alsamidisrc, GstClockTime time,
    GstBufferList * buffer_list)
{
  alsamidisrc->buffer[0] = MIDI_TICK;
  push_buffer (alsamidisrc, alsamidisrc->buffer, 1, time, buffer_list);
}

static GstFlowReturn
gst_alsa_midi_src_create (GstPushSrc * src, GstBuffer ** buf)
{
  GstAlsaMidiSrc *alsamidisrc;
  GstBufferList *buffer_list;
  GstClockTime time;
  long size_ev = 0;
  int err;
  int ret;
  guint len;

  alsamidisrc = GST_ALSA_MIDI_SRC (src);

  buffer_list = gst_buffer_list_new ();

poll:
  ret = gst_poll_wait (alsamidisrc->poll, GST_CLOCK_TIME_NONE);
  if (ret <= 0) {
    if (ret < 0 && errno == EBUSY) {
      GST_INFO_OBJECT (alsamidisrc, "flushing");
      gst_buffer_list_unref (buffer_list);
      return GST_FLOW_FLUSHING;
    }
    GST_ERROR_OBJECT (alsamidisrc, "ERROR in poll: %s", strerror (errno));
  } else {
    /* There are events available */
    do {
      snd_seq_event_t *event;
      err = snd_seq_event_input (alsamidisrc->seq, &event);
      if (err < 0)
        break;                  /* Processed all events */

      if (event) {
        time = GST_TIMESPEC_TO_TIME (event->time.time) - alsamidisrc->delay;

        /*
         * Special handling is needed because decoding SND_SEQ_EVENT_TICK is
         * not supported by alsa-lib.
         */
        if (event->type == SND_SEQ_EVENT_TICK) {
          push_tick_buffer (alsamidisrc, time, buffer_list);
          schedule_next_tick (alsamidisrc);
          continue;
        }

        size_ev =
            snd_midi_event_decode (alsamidisrc->parser, alsamidisrc->buffer,
            DEFAULT_BUFSIZE, event);
        if (size_ev < 0) {
          /* ENOENT indicates an event that is not a MIDI message, silently skip it */
          if (-ENOENT == size_ev) {
            GST_WARNING_OBJECT (alsamidisrc,
                "Warning: Received non-MIDI message");
            goto poll;
          } else {
            GST_ERROR_OBJECT (alsamidisrc,
                "Error decoding event from ALSA to output: %s",
                strerror (-size_ev));
            goto error;
          }
        } else {
          push_buffer (alsamidisrc, alsamidisrc->buffer, size_ev, time,
              buffer_list);
        }
      }
    } while (err > 0);
  }

  len = gst_buffer_list_length (buffer_list);
  if (len == 0)
    goto error;

  /* Pop the _last_ buffer in the list */
  *buf = gst_buffer_copy (gst_buffer_list_get (buffer_list, len - 1));
  gst_buffer_list_remove (buffer_list, len - 1, 1);
  --len;

  /*
   * If there are no more buffers left, free the list, otherwise push all the
   * _previous_ buffers left in the list.
   *
   * The one popped above will be pushed last when this function returns.
   */
  if (len == 0)
    gst_buffer_list_unref (buffer_list);
  else
    gst_pad_push_list (GST_BASE_SRC (src)->srcpad, buffer_list);

  return GST_FLOW_OK;

error:
  gst_buffer_list_unref (buffer_list);
  return GST_FLOW_ERROR;
}

static gboolean
gst_alsa_midi_src_start (GstBaseSrc * basesrc)
{
  GstAlsaMidiSrc *alsamidisrc;
  int ret;

  alsamidisrc = GST_ALSA_MIDI_SRC (basesrc);

  alsamidisrc->tick = 0;
  alsamidisrc->port_count = 0;

  ret = init_seq (alsamidisrc);
  if (ret < 0)
    goto err;

  if (alsamidisrc->ports) {
    ret = parse_ports (alsamidisrc->ports, alsamidisrc);
    if (ret < 0)
      goto error_seq_close;
  }

  ret = create_port (alsamidisrc);
  if (ret < 0)
    goto error_free_seq_ports;

  connect_ports (alsamidisrc);

  ret = snd_seq_nonblock (alsamidisrc->seq, 1);
  if (ret < 0) {
    GST_ERROR_OBJECT (alsamidisrc, "Cannot set nonblock mode - %s",
        snd_strerror (ret));
    goto error_free_seq_ports;
  }

  snd_midi_event_new (DEFAULT_BUFSIZE, &alsamidisrc->parser);
  snd_midi_event_init (alsamidisrc->parser);
  snd_midi_event_reset_decode (alsamidisrc->parser);

  snd_midi_event_no_status (alsamidisrc->parser, 1);

  alsamidisrc->buffer = g_try_malloc (DEFAULT_BUFSIZE);
  if (alsamidisrc->buffer == NULL)
    goto error_free_parser;

  {
    struct pollfd *pfds;
    int npfds, i;

    npfds = snd_seq_poll_descriptors_count (alsamidisrc->seq, POLLIN);
    pfds = g_newa (struct pollfd, npfds);

    snd_seq_poll_descriptors (alsamidisrc->seq, pfds, npfds, POLLIN);

    alsamidisrc->poll = gst_poll_new (TRUE);
    for (i = 0; i < npfds; ++i) {
      GstPollFD fd = GST_POLL_FD_INIT;

      fd.fd = pfds[i].fd;
      gst_poll_add_fd (alsamidisrc->poll, &fd);
      gst_poll_fd_ctl_read (alsamidisrc->poll, &fd, TRUE);
      gst_poll_fd_ctl_write (alsamidisrc->poll, &fd, FALSE);
    }
  }

  return TRUE;

error_free_parser:
  snd_midi_event_free (alsamidisrc->parser);
error_free_seq_ports:
  g_free (alsamidisrc->seq_ports);
error_seq_close:
  snd_seq_close (alsamidisrc->seq);
err:
  return FALSE;
}

static gboolean
gst_alsa_midi_src_stop (GstBaseSrc * basesrc)
{
  GstAlsaMidiSrc *alsamidisrc;

  alsamidisrc = GST_ALSA_MIDI_SRC (basesrc);

  if (alsamidisrc->poll != NULL) {
    gst_poll_free (alsamidisrc->poll);
    alsamidisrc->poll = NULL;
  }
  g_free (alsamidisrc->ports);
  g_free (alsamidisrc->buffer);
  snd_midi_event_free (alsamidisrc->parser);
  g_free (alsamidisrc->seq_ports);
  snd_seq_close (alsamidisrc->seq);

  return TRUE;
}

static gboolean
gst_alsa_midi_src_unlock (GstBaseSrc * basesrc)
{
  GstAlsaMidiSrc *alsamidisrc = GST_ALSA_MIDI_SRC (basesrc);

  gst_poll_set_flushing (alsamidisrc->poll, TRUE);
  return TRUE;
}

static gboolean
gst_alsa_midi_src_unlock_stop (GstBaseSrc * basesrc)
{
  GstAlsaMidiSrc *alsamidisrc = GST_ALSA_MIDI_SRC (basesrc);

  gst_poll_set_flushing (alsamidisrc->poll, FALSE);
  return TRUE;
}

static void
gst_alsa_midi_src_state_changed (GstElement * element, GstState oldstate,
    GstState newstate, GstState pending)
{
  GstAlsaMidiSrc *alsamidisrc;

  alsamidisrc = GST_ALSA_MIDI_SRC (element);

  if (newstate == GST_STATE_PLAYING) {
    GstClockTime gst_time;
    GstClockTime base_time;
    GstClockTime running_time;
    GstClockTime queue_time;
    GstClock *clock;
    snd_seq_queue_status_t *status;

    clock = gst_element_get_clock (element);
    if (clock == NULL) {
      GST_WARNING_OBJECT (element, "No clock present");
      return;
    }
    gst_time = gst_clock_get_time (clock);
    gst_object_unref (clock);
    base_time = gst_element_get_base_time (element);
    running_time = gst_time - base_time;

    snd_seq_queue_status_malloc (&status);
    snd_seq_get_queue_status (alsamidisrc->seq, alsamidisrc->queue, status);
    queue_time =
        GST_TIMESPEC_TO_TIME (*snd_seq_queue_status_get_real_time (status));
    snd_seq_queue_status_free (status);

    /*
     * The fact that the ALSA sequencer queue started before the pipeline
     * transition to the PLAYING state ensures that the pipeline delay is
     * always positive.
     */
    alsamidisrc->delay = queue_time - running_time;

    if (alsamidisrc->tick == 0) {
      schedule_next_tick (alsamidisrc);
    }
  }
}
