/* 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");
      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);
    }
  }
}
