From a198e55b318bcf4ac506a97d8c3d8ce936fca13c Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Mon, 28 Sep 2015 15:30:30 +0200 Subject: [PATCH] Revert "midi: add an ALSA MIDI sequencer source" This reverts commit cd7f4e524718a2f75467852235e4e13d64d2ac82. --- configure.ac | 12 - gst/midi/Makefile.am | 7 - gst/midi/alsamidisrc.c | 525 ----------------------------------------- gst/midi/alsamidisrc.h | 77 ------ gst/midi/midi.c | 11 +- 5 files changed, 1 insertion(+), 631 deletions(-) delete mode 100644 gst/midi/alsamidisrc.c delete mode 100644 gst/midi/alsamidisrc.h diff --git a/configure.ac b/configure.ac index af3d38dbd1..c8d3f810b0 100644 --- a/configure.ac +++ b/configure.ac @@ -1403,18 +1403,6 @@ AM_CONDITIONAL(HAVE_JPEG, test "x$HAVE_JPEG" = "xyes") dnl *** sys plug-ins *** -dnl *** alsa *** -translit(dnm, m, l) AM_CONDITIONAL(USE_ALSA, true) -AG_GST_CHECK_FEATURE(ALSA, [ALSA], alsa, [ - PKG_CHECK_MODULES(ALSA, alsa >= 0.9.1, [ - HAVE_ALSA="yes" - AC_SUBST(ALSA_CFLAGS) - AC_SUBST(ALSA_LIBS) - ], [ - AM_PATH_ALSA(0.9.1, HAVE_ALSA="yes", HAVE_ALSA="no") - ]) -]) - dnl DirectSound translit(dnm, m, l) AM_CONDITIONAL(USE_DIRECTSOUND, true) AG_GST_CHECK_FEATURE(DIRECTSOUND, [DirectSound], directsoundsrc, [ diff --git a/gst/midi/Makefile.am b/gst/midi/Makefile.am index 44ae2bf83c..55f12df326 100644 --- a/gst/midi/Makefile.am +++ b/gst/midi/Makefile.am @@ -14,10 +14,3 @@ libgstmidi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstmidi_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) noinst_HEADERS = midiparse.h - -if USE_ALSA -libgstmidi_la_SOURCES += alsamidisrc.c -libgstmidi_la_CFLAGS += $(ALSA_FLAGS) -libgstmidi_la_LIBADD += $(ALSA_LIBS) -noinst_HEADERS += alsamidisrc.h -endif diff --git a/gst/midi/alsamidisrc.c b/gst/midi/alsamidisrc.c deleted file mode 100644 index 58cd27e415..0000000000 --- a/gst/midi/alsamidisrc.c +++ /dev/null @@ -1,525 +0,0 @@ -/* GStreamer - * Copyright (C) 2014 Antonio Ospite - * - * alsamidisrc.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 - * @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-1.0 -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. - * - * |[ - * vkeybd & gst-launch-1.0 -v alsamidisrc ports=128:0 ! fluiddec ! audioconvert ! autoaudiosink - * ]| Use a software midi keyboard to play fluiddec. - * - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "alsamidisrc.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" -#define DEFAULT_POLL_TIMEOUT_MS (MIDI_TICK_PERIOD_MS / 2) - -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; - } - - 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 those 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 -create_port (GstAlsaMidiSrc * alsamidisrc) -{ - int ret; - - ret = snd_seq_create_simple_port (alsamidisrc->seq, DEFAULT_CLIENT_NAME, - SND_SEQ_PORT_CAP_WRITE | - SND_SEQ_PORT_CAP_SUBS_WRITE, - SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); - if (ret < 0) - GST_ERROR_OBJECT (alsamidisrc, "Cannot create port - %s", - 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 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 "); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&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); - gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_alsa_midi_src_create); -} - -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 GstBuffer * -prepare_buffer (GstAlsaMidiSrc * alsamidisrc, gpointer data, guint size) -{ - GstClockTime time; - gpointer local_data; - GstBuffer *buffer; - - buffer = gst_buffer_new (); - - time = alsamidisrc->tick * MIDI_TICK_PERIOD_MS * GST_MSECOND; - - GST_BUFFER_DTS (buffer) = time; - GST_BUFFER_PTS (buffer) = time; - GST_BUFFER_OFFSET (buffer) = time; - GST_BUFFER_DURATION (buffer) = MIDI_TICK_PERIOD_MS * GST_MSECOND; - - 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); - - alsamidisrc->tick += 1; - - return buffer; -} - -static void -push_buffer (GstAlsaMidiSrc * alsamidisrc, gpointer data, guint size, - GstBufferList * buffer_list) -{ - gst_buffer_list_add (buffer_list, prepare_buffer (alsamidisrc, data, size)); -} - -static void -push_tick_buffer (GstAlsaMidiSrc * alsamidisrc, GstBufferList * buffer_list) -{ - alsamidisrc->buffer[0] = MIDI_TICK; - push_buffer (alsamidisrc, alsamidisrc->buffer, 1, buffer_list); -} - -static GstFlowReturn -gst_alsa_midi_src_create (GstPushSrc * src, GstBuffer ** buf) -{ - GstAlsaMidiSrc *alsamidisrc; - GstBufferList *buffer_list; - long size_ev = 0; - int err; - int ret; - guint len; - - alsamidisrc = GST_ALSA_MIDI_SRC (src); - - buffer_list = gst_buffer_list_new (); - - snd_seq_poll_descriptors (alsamidisrc->seq, alsamidisrc->pfds, - alsamidisrc->npfds, POLLIN); - - /* - * The file descriptors are polled with a timeout _less_ than 10ms (the MIDI - * tick period) in order not to loose events because of possible overlaps - * with MIDI ticks. - * - * If the polling times out (no new events) then a MIDI-tick event gets - * generated in order to keep the pipeline alive and progressing. - * - * If new events are present, then they are decoded and queued in - * a buffer_list. One buffer per event will be queued, all with different - * timestamps (see the prepare_buffer() function); maybe this can be - * optimized but a as a proof-of-concept mechanism it works OK. - */ - ret = poll (alsamidisrc->pfds, alsamidisrc->npfds, DEFAULT_POLL_TIMEOUT_MS); - if (ret < 0) { - GST_ERROR_OBJECT (alsamidisrc, "ERROR in poll: %s", strerror (errno)); - } else if (ret == 0) { - push_tick_buffer (alsamidisrc, buffer_list); - } 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) { - 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"); - push_tick_buffer (alsamidisrc, buffer_list); - } 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, 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; - - alsamidisrc->npfds = - snd_seq_poll_descriptors_count (alsamidisrc->seq, POLLIN); - alsamidisrc->pfds = - g_try_malloc (sizeof (*alsamidisrc->pfds) * alsamidisrc->npfds); - if (alsamidisrc->pfds == NULL) - goto error_free_buffer; - - return TRUE; - -error_free_buffer: - g_free (alsamidisrc->buffer); -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); - - g_free (alsamidisrc->pfds); - g_free (alsamidisrc->buffer); - snd_midi_event_free (alsamidisrc->parser); - g_free (alsamidisrc->seq_ports); - snd_seq_close (alsamidisrc->seq); - - return TRUE; -} diff --git a/gst/midi/alsamidisrc.h b/gst/midi/alsamidisrc.h deleted file mode 100644 index 8411ad037c..0000000000 --- a/gst/midi/alsamidisrc.h +++ /dev/null @@ -1,77 +0,0 @@ -/* GStreamer - * Copyright (C) 2014 Antonio Ospite - * - * gstalsamidisrc.h: - * - * 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. - */ - -#ifndef __GST_ALSA_MIDI_SRC_H__ -#define __GST_ALSA_MIDI_SRC_H__ - -#include -#include - -#include - -G_BEGIN_DECLS -#define GST_TYPE_ALSA_MIDI_SRC \ - (gst_alsa_midi_src_get_type()) -#define GST_ALSA_MIDI_SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIDI_SRC,GstAlsaMidiSrc)) -#define GST_ALSA_MIDI_SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIDI_SRC,GstAlsaMidiSrcClass)) -#define GST_IS_ALSA_MIDI_SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_MIDI_SRC)) -#define GST_IS_ALSA_MIDI_SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIDI_SRC)) - -typedef struct _GstAlsaMidiSrc GstAlsaMidiSrc; -typedef struct _GstAlsaMidiSrcClass GstAlsaMidiSrcClass; - -/** - * GstAlsaMidiSrc: - * - * Opaque #GstAlsaMidiSrc data structure. - */ -struct _GstAlsaMidiSrc -{ - GstPushSrc element; - - gchar *ports; - - /*< private > */ - snd_seq_t *seq; - int port_count; - snd_seq_addr_t *seq_ports; - snd_midi_event_t *parser; - unsigned char *buffer; - - struct pollfd *pfds; - int npfds; - - guint64 tick; -}; - -struct _GstAlsaMidiSrcClass -{ - GstPushSrcClass parent_class; -}; - -G_GNUC_INTERNAL GType gst_alsa_midi_src_get_type (void); - -G_END_DECLS -#endif /* __GST_ALSA_MIDI_SRC_H__ */ diff --git a/gst/midi/midi.c b/gst/midi/midi.c index fda2e8f535..6171359f62 100644 --- a/gst/midi/midi.c +++ b/gst/midi/midi.c @@ -26,7 +26,6 @@ #include -#include "alsamidisrc.h" #include "midiparse.h" GST_DEBUG_CATEGORY_STATIC (midi_debug); @@ -46,22 +45,14 @@ plugin_init (GstPlugin * plugin) bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif -#ifdef HAVE_ALSA - ret = gst_element_register (plugin, "alsamidisrc", GST_RANK_PRIMARY, - GST_TYPE_ALSA_MIDI_SRC); - if (!ret) - goto out; -#endif - ret = gst_element_register (plugin, "midiparse", GST_RANK_PRIMARY, GST_TYPE_MIDI_PARSE); -out: return ret; } GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, midi, - "Generate MIDI events", + "Parse MIDI files", plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)