ref: b60dd4ae028d987b1e9bdbd6b71e62f529465109
parent: b16b90048ff3e3f9578514de3dace12f631822b5
author: Paul Brossier <piem@altern.org>
date: Mon Dec 6 13:51:31 EST 2004
moved midi functions to ext/
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = src examples doc sounds swig python plugins
+SUBDIRS = src ext examples doc sounds swig python plugins
EXTRA_DIST = bootstrap VERSION
DISTCLEANFILES = autom4te.cache
--- a/Makefile.in
+++ b/Makefile.in
@@ -151,7 +151,7 @@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
-SUBDIRS = src examples doc sounds swig python plugins
+SUBDIRS = src ext examples doc sounds swig python plugins
EXTRA_DIST = bootstrap VERSION
DISTCLEANFILES = autom4te.cache
subdir = .
--- a/configure
+++ b/configure
@@ -21053,7 +21053,7 @@
- ac_config_files="$ac_config_files Makefile src/Makefile examples/Makefile sounds/Makefile doc/Makefile python/Makefile python/aubio/Makefile plugins/Makefile plugins/audacity/Makefile plugins/audacity/plug-ins/Makefile plugins/wavesurfer/Makefile plugins/puredata/Makefile swig/Makefile"
+ ac_config_files="$ac_config_files Makefile src/Makefile ext/Makefile examples/Makefile sounds/Makefile doc/Makefile python/Makefile python/aubio/Makefile plugins/Makefile plugins/audacity/Makefile plugins/audacity/plug-ins/Makefile plugins/wavesurfer/Makefile plugins/puredata/Makefile swig/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -21613,6 +21613,7 @@
"aubio.pc" ) CONFIG_FILES="$CONFIG_FILES aubio.pc" ;;
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "ext/Makefile" ) CONFIG_FILES="$CONFIG_FILES ext/Makefile" ;;
"examples/Makefile" ) CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
"sounds/Makefile" ) CONFIG_FILES="$CONFIG_FILES sounds/Makefile" ;;
"doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
--- a/configure.ac
+++ b/configure.ac
@@ -150,6 +150,7 @@
AC_OUTPUT([
Makefile
src/Makefile
+ ext/Makefile
examples/Makefile
sounds/Makefile
doc/Makefile
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,9 +1,8 @@
-
#SUBDIRS=onsets
# global flags
-AM_CFLAGS = -I../src @LADCCA_CFLAGS@
-AM_LDFLAGS = -L../src @LADCCA_LIBS@ -laubio
+AM_CFLAGS = -I../src -I../ext @LADCCA_CFLAGS@
+AM_LDFLAGS = -L../src -L../ext @LADCCA_LIBS@ -laubioext -laubio
#AM_SOURCES = utils.c
# add your programs to this list
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -155,8 +155,8 @@
target_alias = @target_alias@
# global flags
-AM_CFLAGS = -I../src @LADCCA_CFLAGS@
-AM_LDFLAGS = -L../src @LADCCA_LIBS@ -laubio
+AM_CFLAGS = -I../src -I../ext @LADCCA_CFLAGS@
+AM_LDFLAGS = -L../src -L../ext @LADCCA_LIBS@ -laubioext -laubio
#AM_SOURCES = utils.c
# add your programs to this list
--- a/examples/aubionotes.c
+++ b/examples/aubionotes.c
@@ -23,6 +23,7 @@
#include <unistd.h>
#include <math.h> // how do i do a floorf with a mask again ?
#include "aubio.h"
+#include "aubioext.h"
#include "utils.h"
/* settings */
--- a/examples/aubionotesmedian.c
+++ b/examples/aubionotesmedian.c
@@ -22,6 +22,7 @@
#include <getopt.h>
#include <unistd.h>
#include "aubio.h"
+#include "aubioext.h"
#include "utils.h"
#include <math.h> //required for FLOORF :(
--- /dev/null
+++ b/ext/midi/list.c
@@ -1,0 +1,256 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* Modified by the GLib Team and others 1997-1999. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "aubio_priv.h"
+#include "list.h"
+
+
+
+aubio_list_t*
+new_aubio_list(void)
+{
+ aubio_list_t* list;
+ list = AUBIO_NEW(aubio_list_t);
+ list->data = NULL;
+ list->next = NULL;
+ return list;
+}
+
+void
+del_aubio_list(aubio_list_t *list)
+{
+ aubio_list_t *next;
+ while (list) {
+ next = list->next;
+ AUBIO_FREE(list);
+ list = next;
+ }
+}
+
+void
+del_aubio_list1(aubio_list_t *list)
+{
+ if (list) {
+ AUBIO_FREE(list);
+ }
+}
+
+aubio_list_t*
+aubio_list_append(aubio_list_t *list, void* data)
+{
+ aubio_list_t *new_list;
+ aubio_list_t *last;
+
+ new_list = new_aubio_list();
+ new_list->data = data;
+
+ if (list)
+ {
+ last = aubio_list_last(list);
+ /* g_assert (last != NULL); */
+ last->next = new_list;
+
+ return list;
+ }
+ else
+ return new_list;
+}
+
+aubio_list_t*
+aubio_list_prepend(aubio_list_t *list, void* data)
+{
+ aubio_list_t *new_list;
+
+ new_list = new_aubio_list();
+ new_list->data = data;
+ new_list->next = list;
+
+ return new_list;
+}
+
+aubio_list_t*
+aubio_list_nth(aubio_list_t *list, int n)
+{
+ while ((n-- > 0) && list) {
+ list = list->next;
+ }
+
+ return list;
+}
+
+aubio_list_t*
+aubio_list_remove(aubio_list_t *list, void* data)
+{
+ aubio_list_t *tmp;
+ aubio_list_t *prev;
+
+ prev = NULL;
+ tmp = list;
+
+ while (tmp) {
+ if (tmp->data == data) {
+ if (prev) {
+ prev->next = tmp->next;
+ }
+ if (list == tmp) {
+ list = list->next;
+ }
+ tmp->next = NULL;
+ del_aubio_list(tmp);
+
+ break;
+ }
+
+ prev = tmp;
+ tmp = tmp->next;
+ }
+
+ return list;
+}
+
+aubio_list_t*
+aubio_list_remove_link(aubio_list_t *list, aubio_list_t *link)
+{
+ aubio_list_t *tmp;
+ aubio_list_t *prev;
+
+ prev = NULL;
+ tmp = list;
+
+ while (tmp) {
+ if (tmp == link) {
+ if (prev) {
+ prev->next = tmp->next;
+ }
+ if (list == tmp) {
+ list = list->next;
+ }
+ tmp->next = NULL;
+ break;
+ }
+
+ prev = tmp;
+ tmp = tmp->next;
+ }
+
+ return list;
+}
+
+static aubio_list_t*
+aubio_list_sort_merge(aubio_list_t *l1, aubio_list_t *l2, aubio_compare_func_t compare_func)
+{
+ aubio_list_t list, *l;
+
+ l = &list;
+
+ while (l1 && l2) {
+ if (compare_func(l1->data,l2->data) < 0) {
+ l = l->next = l1;
+ l1 = l1->next;
+ } else {
+ l = l->next = l2;
+ l2 = l2->next;
+ }
+ }
+ l->next= l1 ? l1 : l2;
+
+ return list.next;
+}
+
+aubio_list_t*
+aubio_list_sort(aubio_list_t *list, aubio_compare_func_t compare_func)
+{
+ aubio_list_t *l1, *l2;
+
+ if (!list) {
+ return NULL;
+ }
+ if (!list->next) {
+ return list;
+ }
+
+ l1 = list;
+ l2 = list->next;
+
+ while ((l2 = l2->next) != NULL) {
+ if ((l2 = l2->next) == NULL)
+ break;
+ l1=l1->next;
+ }
+ l2 = l1->next;
+ l1->next = NULL;
+
+ return aubio_list_sort_merge(aubio_list_sort(list, compare_func),
+ aubio_list_sort(l2, compare_func),
+ compare_func);
+}
+
+
+aubio_list_t*
+aubio_list_last(aubio_list_t *list)
+{
+ if (list) {
+ while (list->next)
+ list = list->next;
+ }
+
+ return list;
+}
+
+int
+aubio_list_size(aubio_list_t *list)
+{
+ int n = 0;
+ while (list) {
+ n++;
+ list = list->next;
+ }
+ return n;
+}
+
+aubio_list_t* aubio_list_insert_at(aubio_list_t *list, int n, void* data)
+{
+ aubio_list_t *new_list;
+ aubio_list_t *cur;
+ aubio_list_t *prev = NULL;
+
+ new_list = new_aubio_list();
+ new_list->data = data;
+
+ cur = list;
+ while ((n-- > 0) && cur) {
+ prev = cur;
+ cur = cur->next;
+ }
+
+ new_list->next = cur;
+
+ if (prev) {
+ prev->next = new_list;
+ return list;
+ } else {
+ return new_list;
+ }
+}
--- /dev/null
+++ b/ext/midi/list.h
@@ -1,0 +1,63 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * \file
+ * list of objects
+ *
+ * implement common list structure and its various functions
+ *
+ * adapted for audio by Paul Brossier
+ *
+ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef _AUBIO_LIST_H
+#define _AUBIO_LIST_H
+
+typedef struct _aubio_list_t aubio_list_t;
+
+struct _aubio_list_t
+{
+ void* data;
+ aubio_list_t *next;
+};
+
+typedef int (*aubio_compare_func_t)(void* a, void* b);
+
+aubio_list_t* new_aubio_list(void);
+void del_aubio_list(aubio_list_t *list);
+void del_aubio_list1(aubio_list_t *list);
+aubio_list_t* aubio_list_sort(aubio_list_t *list, aubio_compare_func_t compare_func);
+aubio_list_t* aubio_list_append(aubio_list_t *list, void* data);
+aubio_list_t* aubio_list_prepend(aubio_list_t *list, void* data);
+aubio_list_t* aubio_list_remove(aubio_list_t *list, void* data);
+aubio_list_t* aubio_list_remove_link(aubio_list_t *list, aubio_list_t *llink);
+aubio_list_t* aubio_list_nth(aubio_list_t *list, int n);
+aubio_list_t* aubio_list_last(aubio_list_t *list);
+aubio_list_t* aubio_list_insert_at(aubio_list_t *list, int n, void* data);
+int aubio_list_size(aubio_list_t *list);
+
+#define aubio_list_next(slist) ((slist) ? (((aubio_list_t *)(slist))->next) : NULL)
+#define aubio_list_get(slist) ((slist) ? ((slist)->data) : NULL)
+
+#endif /* _AUBIO_LIST_H */
--- /dev/null
+++ b/ext/midi/midi.c
@@ -1,0 +1,32 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+#include "aubio_priv.h"
+#include "midi.h"
+#include "midi_event.h"
+#include "midi_track.h"
+#include "midi_player.h"
+
+/* all outgoing user messages are stored in a global text buffer */
+#define MIDI_MESSAGE_LENGTH 1024
+char midi_message_buffer[MIDI_MESSAGE_LENGTH];
+
--- /dev/null
+++ b/ext/midi/midi.h
@@ -1,0 +1,190 @@
+/*
+ *
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from fluidsynth, peter hanappe and others,
+ * adapted for aubio by paul brossier,
+ */
+
+
+/** \file
+ * midi header
+ *
+ * contains all (?) possible known midi messages.
+ *
+ * this file originally taken from fluidsynth, Peter Hanappe and others,
+ * adapted for aubio by Paul Brossier,
+ */
+
+#ifndef _AUBIO_MIDI_H
+#define _AUBIO_MIDI_H
+
+//typedef struct _aubio_midi_driver_t aubio_midi_driver_t;
+
+//int aubio_midi_send_event(aubio_synth_t* synth, aubio_player_t* player, aubio_midi_event_t* evt);
+
+//int aubio_midi_router_send_event(aubio_midi_router_t* router, aubio_midi_event_t* event);
+
+
+/***************************************************************
+ *
+ * CONSTANTS & ENUM
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum aubio_midi_event_type {
+ /* channel messages */
+ NOTE_OFF = 0x80,
+ NOTE_ON = 0x90,
+ KEY_PRESSURE = 0xa0,
+ CONTROL_CHANGE = 0xb0,
+ PROGRAM_CHANGE = 0xc0,
+ CHANNEL_PRESSURE = 0xd0,
+ PITCH_BEND = 0xe0,
+ /* system exclusive */
+ MIDI_SYSEX = 0xf0,
+ /* system common - never in midi files */
+ MIDI_TIME_CODE = 0xf1,
+ MIDI_SONG_POSITION = 0xf2,
+ MIDI_SONG_SELECT = 0xf3,
+ MIDI_TUNE_REQUEST = 0xf6,
+ MIDI_EOX = 0xf7,
+ /* system real-time - never in midi files */
+ MIDI_SYNC = 0xf8,
+ MIDI_TICK = 0xf9,
+ MIDI_START = 0xfa,
+ MIDI_CONTINUE = 0xfb,
+ MIDI_STOP = 0xfc,
+ MIDI_ACTIVE_SENSING = 0xfe,
+ MIDI_SYSTEM_RESET = 0xff,
+ /* meta event - for midi files only */
+ MIDI_META_EVENT = 0xff
+};
+
+enum aubio_midi_control_change {
+ BANK_SELECT_MSB = 0x00,
+ MODULATION_MSB = 0x01,
+ BREATH_MSB = 0x02,
+ FOOT_MSB = 0x04,
+ PORTAMENTO_TIME_MSB = 0x05,
+ DATA_ENTRY_MSB = 0x06,
+ VOLUME_MSB = 0x07,
+ BALANCE_MSB = 0x08,
+ PAN_MSB = 0x0A,
+ EXPRESSION_MSB = 0x0B,
+ EFFECTS1_MSB = 0x0C,
+ EFFECTS2_MSB = 0x0D,
+ GPC1_MSB = 0x10, /* general purpose controller */
+ GPC2_MSB = 0x11,
+ GPC3_MSB = 0x12,
+ GPC4_MSB = 0x13,
+ BANK_SELECT_LSB = 0x20,
+ MODULATION_WHEEL_LSB = 0x21,
+ BREATH_LSB = 0x22,
+ FOOT_LSB = 0x24,
+ PORTAMENTO_TIME_LSB = 0x25,
+ DATA_ENTRY_LSB = 0x26,
+ VOLUME_LSB = 0x27,
+ BALANCE_LSB = 0x28,
+ PAN_LSB = 0x2A,
+ EXPRESSION_LSB = 0x2B,
+ EFFECTS1_LSB = 0x2C,
+ EFFECTS2_LSB = 0x2D,
+ GPC1_LSB = 0x30,
+ GPC2_LSB = 0x31,
+ GPC3_LSB = 0x32,
+ GPC4_LSB = 0x33,
+ SUSTAIN_SWITCH = 0x40,
+ PORTAMENTO_SWITCH = 0x41,
+ SOSTENUTO_SWITCH = 0x42,
+ SOFT_PEDAL_SWITCH = 0x43,
+ LEGATO_SWITCH = 0x45,
+ HOLD2_SWITCH = 0x45,
+ SOUND_CTRL1 = 0x46,
+ SOUND_CTRL2 = 0x47,
+ SOUND_CTRL3 = 0x48,
+ SOUND_CTRL4 = 0x49,
+ SOUND_CTRL5 = 0x4A,
+ SOUND_CTRL6 = 0x4B,
+ SOUND_CTRL7 = 0x4C,
+ SOUND_CTRL8 = 0x4D,
+ SOUND_CTRL9 = 0x4E,
+ SOUND_CTRL10 = 0x4F,
+ GPC5 = 0x50,
+ GPC6 = 0x51,
+ GPC7 = 0x52,
+ GPC8 = 0x53,
+ PORTAMENTO_CTRL = 0x54,
+ EFFECTS_DEPTH1 = 0x5B,
+ EFFECTS_DEPTH2 = 0x5C,
+ EFFECTS_DEPTH3 = 0x5D,
+ EFFECTS_DEPTH4 = 0x5E,
+ EFFECTS_DEPTH5 = 0x5F,
+ DATA_ENTRY_INCR = 0x60,
+ DATA_ENTRY_DECR = 0x61,
+ NRPN_LSB = 0x62,
+ NRPN_MSB = 0x63,
+ RPN_LSB = 0x64,
+ RPN_MSB = 0x65,
+ ALL_SOUND_OFF = 0x78,
+ ALL_CTRL_OFF = 0x79,
+ LOCAL_CONTROL = 0x7A,
+ ALL_NOTES_OFF = 0x7B,
+ OMNI_OFF = 0x7C,
+ OMNI_ON = 0x7D,
+ POLY_OFF = 0x7E,
+ POLY_ON = 0x7F
+};
+
+enum midi_meta_event {
+ MIDI_COPYRIGHT = 0x02,
+ MIDI_TRACK_NAME = 0x03,
+ MIDI_INST_NAME = 0x04,
+ MIDI_LYRIC = 0x05,
+ MIDI_MARKER = 0x06,
+ MIDI_CUE_POINT = 0x07,
+ MIDI_EOT = 0x2f,
+ MIDI_SET_TEMPO = 0x51,
+ MIDI_SMPTE_OFFSET = 0x54,
+ MIDI_TIME_SIGNATURE = 0x58,
+ MIDI_KEY_SIGNATURE = 0x59,
+ MIDI_SEQUENCER_EVENT = 0x7f
+};
+
+enum aubio_player_status
+{
+ AUBIO_MIDI_PLAYER_READY,
+ AUBIO_MIDI_PLAYER_PLAYING,
+ AUBIO_MIDI_PLAYER_DONE
+};
+
+enum aubio_driver_status
+{
+ AUBIO_MIDI_READY,
+ AUBIO_MIDI_LISTENING,
+ AUBIO_MIDI_DONE
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AUBIO_MIDI_H */
--- /dev/null
+++ b/ext/midi/midi_alsa_raw.c
@@ -1,0 +1,308 @@
+/*
+ * Copyright 2004 Paul Brossier
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from Fluidsynth, Peter Hanappe and others. */
+
+/** \file
+ * Midi driver for the Advanced Linux Sound Architecture
+ */
+
+
+#include "aubio_priv.h"
+#include "midi.h"
+#include "midi_event.h"
+#include "midi_parser.h"
+#include "midi_driver.h"
+
+#if ALSA_SUPPORT
+
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#include <alsa/asoundlib.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/poll.h>
+/* #include <errno.h> //perror is in stdio.h */
+
+#include "config.h"
+
+#define AUBIO_ALSA_DEFAULT_MIDI_DEVICE "default"
+
+/** \bug double define? */
+#define AUBIO_ALSA_BUFFER_LENGTH 512
+
+/* SCHED_FIFO priorities for ALSA threads (see pthread_attr_setschedparam) */
+#define ALSA_RAWMIDI_SCHED_PRIORITY 90
+#define ALSA_SEQ_SCHED_PRIORITY 90
+
+/** aubio_midi_alsa_raw_driver_t */
+typedef struct {
+ aubio_midi_driver_t driver;
+ snd_rawmidi_t *rawmidi_in;
+ snd_rawmidi_t *rawmidi_out;
+ struct pollfd *pfd;
+ int npfd;
+ pthread_t thread;
+ int status;
+ unsigned char buffer[AUBIO_ALSA_BUFFER_LENGTH];
+ aubio_midi_parser_t* parser;
+} aubio_midi_alsa_raw_driver_t;
+
+aubio_midi_driver_t* new_aubio_midi_alsa_raw_driver(//aubio_settings_t* settings,
+ handle_midi_event_func_t handler,
+ void* event_handler_data);
+int del_aubio_midi_alsa_raw_driver(aubio_midi_driver_t* p);
+static void* aubio_midi_alsa_raw_run(void* d);
+
+
+/**************************************************************
+ *
+ * Alsa MIDI driver
+ *
+ */
+
+//void aubio_midi_alsa_raw_driver_settings(aubio_settings_t* settings)
+//{
+// aubio_settings_register_str(settings, "midi.alsa.device", "default", 0, NULL, NULL);
+//}
+
+/** new_aubio_midi_alsa_raw_driver */
+aubio_midi_driver_t* new_aubio_midi_alsa_raw_driver(
+ //aubio_settings_t* settings,
+ handle_midi_event_func_t handler,
+ void* data)
+{
+ int i, err;
+ aubio_midi_alsa_raw_driver_t* dev;
+ pthread_attr_t attr;
+ int sched = SCHED_FIFO;
+ struct sched_param priority;
+ int count;
+ struct pollfd *pfd = NULL;
+ char* device = NULL;
+
+ /* not much use doing anything */
+ if (handler == NULL) {
+ AUBIO_ERR("Invalid argument");
+ return NULL;
+ }
+
+ /* allocate the device */
+ dev = AUBIO_NEW(aubio_midi_alsa_raw_driver_t);
+ if (dev == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return NULL;
+ }
+ AUBIO_MEMSET(dev, 0, sizeof(aubio_midi_alsa_raw_driver_t));
+
+ dev->driver.handler = handler;
+ dev->driver.data = data;
+
+ /* allocate one event to store the input data */
+ dev->parser = new_aubio_midi_parser();
+ if (dev->parser == NULL) {
+ AUBIO_ERR( "Out of memory");
+ goto error_recovery;
+ }
+
+ /* get the device name. if none is specified, use the default device. */
+ //aubio_settings_getstr(settings, "midi.alsa.device", &device);
+ if (device == NULL) {
+ device = "default";
+ }
+
+ /* open the hardware device. only use midi in. */
+ if ((err = snd_rawmidi_open(&dev->rawmidi_in, NULL, device, SND_RAWMIDI_NONBLOCK)) < 0) {
+ //if ((err = snd_rawmidi_open(&dev->rawmidi_in, &dev->rawmidi_out, device, SND_RAWMIDI_NONBLOCK)) < 0) {
+ AUBIO_ERR( "Error opening ALSA raw MIDI IN port");
+ goto error_recovery;
+ }
+
+ /* get # of MIDI file descriptors */
+ count = snd_rawmidi_poll_descriptors_count(dev->rawmidi_in);
+ if (count > 0) { /* make sure there are some */
+ pfd = AUBIO_MALLOC(sizeof (struct pollfd) * count);
+ dev->pfd = AUBIO_MALLOC(sizeof (struct pollfd) * count);
+ /* grab file descriptor POLL info structures */
+ count = snd_rawmidi_poll_descriptors(dev->rawmidi_in, pfd, count);
+ }
+
+ /* copy the input FDs */
+ for (i = 0; i < count; i++) { /* loop over file descriptors */
+ if (pfd[i].events & POLLIN) { /* use only the input FDs */
+ dev->pfd[dev->npfd].fd = pfd[i].fd;
+ dev->pfd[dev->npfd].events = POLLIN;
+ dev->pfd[dev->npfd].revents = 0;
+ dev->npfd++;
+ }
+ }
+ AUBIO_FREE(pfd);
+
+
+
+ dev->status = AUBIO_MIDI_READY;
+
+ /* create the midi thread */
+ if (pthread_attr_init(&attr)) {
+ AUBIO_ERR( "Couldn't initialize midi thread attributes");
+ goto error_recovery;
+ }
+
+ /* Was: "use fifo scheduling. if it fails, use default scheduling." */
+ /* Now normal scheduling is used by default for the MIDI thread. The reason is,
+ * that fluidsynth works better with low latencies under heavy load, if only the
+ * audio thread is prioritized.
+ * With MIDI at ordinary priority, that could result in individual notes being played
+ * a bit late. On the other hand, if the audio thread is delayed, an audible dropout
+ * is the result.
+ * To reproduce this: Edirol UA-1 USB-MIDI interface, four buffers
+ * with 45 samples each (roughly 4 ms latency), ravewave soundfont. -MN
+ */
+
+ /* Not so sure anymore. We're losing MIDI data, if we can't keep up with
+ * the speed it is generated. */
+ /* AUBIO_MSG("Note: High-priority scheduling for the MIDI thread was intentionally disabled.");
+ sched=SCHED_OTHER;*/
+
+ while (1) {
+ err = pthread_attr_setschedpolicy(&attr, sched);
+ if (err) {
+ //AUBIO_LOG(AUBIO_WARN, "Couldn't set high priority scheduling for the MIDI input");
+ AUBIO_MSG( "Couldn't set high priority scheduling for the MIDI input");
+ if (sched == SCHED_FIFO) {
+ sched = SCHED_OTHER;
+ continue;
+ } else {
+ AUBIO_ERR( "Couldn't set scheduling policy.");
+ goto error_recovery;
+ }
+ }
+
+ /* SCHED_FIFO will not be active without setting the priority */
+ priority.sched_priority = (sched == SCHED_FIFO) ?
+ ALSA_RAWMIDI_SCHED_PRIORITY : 0;
+ pthread_attr_setschedparam (&attr, &priority);
+ err = pthread_create(&dev->thread, &attr, aubio_midi_alsa_raw_run, (void*) dev);
+ if (err) {
+ AUBIO_MSG( "Couldn't set high priority scheduling for the MIDI input");
+ if (sched == SCHED_FIFO) {
+ sched = SCHED_OTHER;
+ continue;
+ } else {
+ AUBIO_ERR( "Couldn't create the midi thread.");
+ goto error_recovery;
+ }
+ }
+ break;
+ }
+ return (aubio_midi_driver_t*) dev;
+
+error_recovery:
+ del_aubio_midi_alsa_raw_driver((aubio_midi_driver_t*) dev);
+ return NULL;
+
+}
+
+/** del_aubio_midi_alsa_raw_driver */
+int del_aubio_midi_alsa_raw_driver(aubio_midi_driver_t* p)
+{
+ aubio_midi_alsa_raw_driver_t* dev;
+
+ dev = (aubio_midi_alsa_raw_driver_t*) p;
+ if (dev == NULL) {
+ return AUBIO_OK;
+ }
+
+ dev->status = AUBIO_MIDI_DONE;
+
+ /* cancel the thread and wait for it before cleaning up */
+ if (dev->thread) {
+ if (pthread_cancel(dev->thread)) {
+ AUBIO_ERR( "Failed to cancel the midi thread");
+ return AUBIO_FAIL;
+ }
+ if (pthread_join(dev->thread, NULL)) {
+ AUBIO_ERR( "Failed to join the midi thread");
+ return AUBIO_FAIL;
+ }
+ }
+ if (dev->rawmidi_in) {
+ snd_rawmidi_drain(dev->rawmidi_in);
+ snd_rawmidi_close(dev->rawmidi_in);
+ }
+ if (dev->rawmidi_out) {
+ snd_rawmidi_drain(dev->rawmidi_out);
+ snd_rawmidi_close(dev->rawmidi_in);
+ }
+ if (dev->parser != NULL) {
+ del_aubio_midi_parser(dev->parser);
+ }
+ AUBIO_FREE(dev);
+ return AUBIO_OK;
+}
+
+/** aubio_midi_alsa_raw_run */
+void * aubio_midi_alsa_raw_run(void* d)
+{
+ int n, i;
+ aubio_midi_event_t* evt;
+ aubio_midi_alsa_raw_driver_t* dev = (aubio_midi_alsa_raw_driver_t*) d;
+
+ /* make sure the other threads can cancel this thread any time */
+ if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) {
+ AUBIO_ERR( "Failed to set the cancel state of the midi thread");
+ pthread_exit(NULL);
+ }
+ if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
+ AUBIO_ERR( "Failed to set the cancel state of the midi thread");
+ pthread_exit(NULL);
+ }
+
+ /* go into a loop until someone tells us to stop */
+ dev->status = AUBIO_MIDI_LISTENING;
+ while (dev->status == AUBIO_MIDI_LISTENING) {
+
+ /* is there something to read? */
+ /* use a 100 milliseconds timeout */
+ n = poll(dev->pfd, dev->npfd, 100);
+ if (n < 0) {
+ perror("poll");
+ } else if (n > 0) {
+
+ /* read new data */
+ n = snd_rawmidi_read(dev->rawmidi_in, dev->buffer,
+ AUBIO_ALSA_BUFFER_LENGTH);
+ if ((n < 0) && (n != -EAGAIN)) {
+ AUBIO_ERR( "Failed to read the midi input");
+ dev->status = AUBIO_MIDI_DONE;
+ }
+
+ /* let the parser convert the data into events */
+ for (i = 0; i < n; i++) {
+ evt = aubio_midi_parser_parse(dev->parser, dev->buffer[i]);
+ if (evt != NULL) {
+ (*dev->driver.handler)(dev->driver.data, evt);
+ }
+ }
+ };
+ }
+ pthread_exit(NULL);
+}
+
+#endif /* #if ALSA_SUPPORT */
--- /dev/null
+++ b/ext/midi/midi_alsa_seq.c
@@ -1,0 +1,419 @@
+/*
+ * Copyright 2004 Paul Brossier
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from Fluidsynth, Peter Hanappe and others. */
+
+/** \file
+ * Midi driver for the Advanced Linux Sound Architecture (sequencer mode)
+ */
+
+
+#include "aubio_priv.h"
+#include "midi.h"
+#include "midi_event.h"
+#include "midi_parser.h"
+#include "midi_driver.h"
+#include "config.h"
+
+#if ALSA_SUPPORT
+
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#include <alsa/asoundlib.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/poll.h>
+/* #include <errno.h> //perror is in stdio.h */
+
+#define AUBIO_ALSA_DEFAULT_SEQ_DEVICE "default"
+
+#define AUBIO_ALSA_BUFFER_LENGTH 512
+
+/* SCHED_FIFO priorities for ALSA threads (see pthread_attr_setschedparam) */
+#define ALSA_RAWMIDI_SCHED_PRIORITY 90
+#define ALSA_SEQ_SCHED_PRIORITY 90
+
+
+/** aubio_alsa_seq_driver_t */
+typedef struct {
+ aubio_midi_driver_t driver;
+ snd_seq_t *seq_handle;
+ int seq_port;
+ struct pollfd *pfd;
+ int npfd;
+ pthread_t thread;
+ int status;
+} aubio_alsa_seq_driver_t;
+
+aubio_midi_driver_t* new_aubio_alsa_seq_driver(//aubio_settings_t* settings,
+ handle_midi_event_func_t handler,
+ void* data);
+int del_aubio_alsa_seq_driver(aubio_midi_driver_t* p);
+static void* aubio_alsa_seq_run(void* d);
+
+//void aubio_alsa_seq_driver_settings(aubio_settings_t* settings)
+//{
+// aubio_settings_register_str(settings, "midi.alsa_seq.device", "default", 0, NULL, NULL);
+// aubio_settings_register_str(settings, "midi.alsa_seq.id", "pid", 0, NULL, NULL);
+//}
+
+/** new_aubio_alsa_seq_driver */
+aubio_midi_driver_t* new_aubio_alsa_seq_driver(//aubio_settings_t* settings,
+ handle_midi_event_func_t handler, void* data)
+{
+ int i, err;
+ aubio_alsa_seq_driver_t* dev; /**< object to return */
+ pthread_attr_t attr; /**< sequencer thread */
+ int sched = SCHED_FIFO; /**< default scheduling policy */
+ struct sched_param priority; /**< scheduling priority settings */
+ int count; /**< number of MIDI file descriptors */
+ struct pollfd *pfd = NULL; /**< poll file descriptor array (copied in dev->pfd) */
+ char* device = NULL; /**< the device name */
+ char* id = NULL;
+ char full_id[64];
+ char full_name[64];
+
+ /* not much use doing anything */
+ if (handler == NULL) {
+ AUBIO_ERR( "Invalid argument");
+ return NULL;
+ }
+
+ /* allocate the device */
+ dev = AUBIO_NEW(aubio_alsa_seq_driver_t);
+ if (dev == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return NULL;
+ }
+ AUBIO_MEMSET(dev, 0, sizeof(aubio_alsa_seq_driver_t));
+ dev->seq_port = -1;
+ dev->driver.data = data;
+ dev->driver.handler = handler;
+
+ /* get the device name. if none is specified, use the default device. */
+ //aubio_settings_getstr(settings, "midi.alsa_seq.device", &device);
+ if (device == NULL) {
+ device = "default";
+ }
+
+ /* open the sequencer INPUT only, non-blocking */
+ //if ((err = snd_seq_open(&dev->seq_handle, device, SND_SEQ_OPEN_INPUT,
+ if ((err = snd_seq_open(&dev->seq_handle, device, SND_SEQ_OPEN_DUPLEX,
+ SND_SEQ_NONBLOCK)) < 0) {
+ AUBIO_ERR( "Error opening ALSA sequencer");
+ goto error_recovery;
+ }
+
+ /* tell the ladcca server our client id */
+#ifdef LADCCA_SUPPORT
+ {
+ int enable_ladcca = 1;
+ //aubio_settings_getint (settings, "ladcca.enable", &enable_ladcca);
+ if (enable_ladcca)
+ cca_alsa_client_id (aubio_cca_client, snd_seq_client_id (dev->seq_handle));
+ }
+#endif /* LADCCA_SUPPORT */
+
+ /* get # of MIDI file descriptors */
+ count = snd_seq_poll_descriptors_count(dev->seq_handle, POLLIN);
+ if (count > 0) { /* make sure there are some */
+ pfd = AUBIO_MALLOC(sizeof (struct pollfd) * count);
+ dev->pfd = AUBIO_MALLOC(sizeof (struct pollfd) * count);
+ /* grab file descriptor POLL info structures */
+ count = snd_seq_poll_descriptors(dev->seq_handle, pfd, count, POLLIN);
+ }
+
+ for (i = 0; i < count; i++) { /* loop over file descriptors */
+ /* copy the input FDs */
+ if (pfd[i].events & POLLIN) { /* use only the input FDs */
+ dev->pfd[dev->npfd].fd = pfd[i].fd;
+ dev->pfd[dev->npfd].events = POLLIN;
+ dev->pfd[dev->npfd].revents = 0;
+ dev->npfd++;
+ }
+ }
+ AUBIO_FREE(pfd);
+
+ //aubio_settings_getstr(settings, "midi.alsa_seq.id", &id);
+
+ if (id != NULL) {
+ if (AUBIO_STRCMP(id, "pid") == 0) {
+ snprintf(full_id, 64, "aubio (%d)", getpid());
+ snprintf(full_name, 64, "aubio_port (%d)", getpid());
+ } else {
+ snprintf(full_id, 64, "aubio (%s)", id);
+ snprintf(full_name, 64, "aubio_port (%s)", id);
+ }
+ } else {
+ snprintf(full_id, 64, "aubio");
+ snprintf(full_name, 64, "aubio_port");
+ }
+
+ /* set the client name */
+ snd_seq_set_client_name (dev->seq_handle, full_id);
+
+ if ((dev->seq_port = snd_seq_create_simple_port (dev->seq_handle,
+ full_name,
+ SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE |
+ SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ |
+ SND_SEQ_PORT_CAP_DUPLEX,
+ SND_SEQ_PORT_TYPE_APPLICATION)) < 0)
+ {
+ AUBIO_ERR( "Error creating ALSA sequencer port");
+ goto error_recovery;
+ }
+
+ dev->status = AUBIO_MIDI_READY;
+
+ /* create the midi thread */
+ if (pthread_attr_init(&attr)) {
+ AUBIO_ERR( "Couldn't initialize midi thread attributes");
+ goto error_recovery;
+ }
+
+ /* use fifo scheduling. if it fails, use default scheduling. */
+ while (1) {
+ err = pthread_attr_setschedpolicy(&attr, sched);
+ if (err) {
+ AUBIO_MSG( "Couldn't set high priority scheduling for the MIDI input");
+ if (sched == SCHED_FIFO) {
+ sched = SCHED_OTHER;
+ continue;
+ } else {
+ AUBIO_ERR( "Couldn't set scheduling policy.");
+ goto error_recovery;
+ }
+ }
+
+ /* SCHED_FIFO will not be active without setting the priority */
+ priority.sched_priority = (sched == SCHED_FIFO) ? ALSA_SEQ_SCHED_PRIORITY : 0;
+ pthread_attr_setschedparam (&attr, &priority);
+
+ err = pthread_create(&dev->thread, &attr, aubio_alsa_seq_run, (void*) dev);
+ if (err) {
+ AUBIO_ERR( "Couldn't set high priority scheduling for the MIDI input");
+ if (sched == SCHED_FIFO) {
+ sched = SCHED_OTHER;
+ continue;
+ } else {
+ //AUBIO_LOG(AUBIO_PANIC, "Couldn't create the midi thread.");
+ AUBIO_ERR( "Couldn't create the midi thread.");
+ goto error_recovery;
+ }
+ }
+ break;
+ }
+ return (aubio_midi_driver_t*) dev;
+
+
+error_recovery:
+ del_aubio_alsa_seq_driver((aubio_midi_driver_t*) dev);
+ return NULL;
+}
+
+/** del_aubio_alsa_seq_driver */
+int del_aubio_alsa_seq_driver(aubio_midi_driver_t* p)
+{
+ aubio_alsa_seq_driver_t* dev;
+
+ dev = (aubio_alsa_seq_driver_t*) p;
+ if (dev == NULL) {
+ return AUBIO_OK;
+ }
+
+ dev->status = AUBIO_MIDI_DONE;
+
+ /* cancel the thread and wait for it before cleaning up */
+ if (dev->thread) {
+ if (pthread_cancel(dev->thread)) {
+ AUBIO_ERR( "Failed to cancel the midi thread");
+ return AUBIO_FAIL;
+ }
+ if (pthread_join(dev->thread, NULL)) {
+ AUBIO_ERR( "Failed to join the midi thread");
+ return AUBIO_FAIL;
+ }
+ }
+ if (dev->seq_port >= 0) {
+ snd_seq_delete_simple_port (dev->seq_handle, dev->seq_port);
+ }
+ if (dev->seq_handle) {
+ snd_seq_drain_output(dev->seq_handle);
+ snd_seq_close(dev->seq_handle);
+ }
+ AUBIO_FREE(dev);
+ return AUBIO_OK;
+}
+
+/** aubio_alsa_seq_run */
+void* aubio_alsa_seq_run(void* d)
+{
+ int n;//, i;
+ snd_seq_event_t *seq_ev;
+ aubio_midi_event_t evt;
+ aubio_alsa_seq_driver_t* dev = (aubio_alsa_seq_driver_t*) d;
+
+ /* make sure the other threads can cancel this thread any time */
+ if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) {
+ AUBIO_ERR( "Failed to set the cancel state of the midi thread");
+ pthread_exit(NULL);
+ }
+ if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
+ AUBIO_ERR( "Failed to set the cancel state of the midi thread");
+ pthread_exit(NULL);
+ }
+
+ /* go into a loop until someone tells us to stop */
+ dev->status = AUBIO_MIDI_LISTENING;
+ while (dev->status == AUBIO_MIDI_LISTENING) {
+
+ /* is there something to read? */
+ n = poll(dev->pfd, dev->npfd, 1); /* use a 1 milliseconds timeout */
+ if (n < 0) {
+ perror("poll");
+ } else if (n > 0) {
+
+ /* read new events from the midi input port */
+ while ((n = snd_seq_event_input(dev->seq_handle, &seq_ev)) >= 0)
+ {
+ switch (seq_ev->type)
+ {
+ case SND_SEQ_EVENT_NOTEON:
+ evt.type = NOTE_ON;
+ evt.channel = seq_ev->data.note.channel;
+ evt.param1 = seq_ev->data.note.note;
+ evt.param2 = seq_ev->data.note.velocity;
+ break;
+ case SND_SEQ_EVENT_NOTEOFF:
+ evt.type = NOTE_OFF;
+ evt.channel = seq_ev->data.note.channel;
+ evt.param1 = seq_ev->data.note.note;
+ evt.param2 = seq_ev->data.note.velocity;
+ break;
+ case SND_SEQ_EVENT_KEYPRESS:
+ evt.type = KEY_PRESSURE;
+ evt.channel = seq_ev->data.note.channel;
+ evt.param1 = seq_ev->data.note.note;
+ evt.param2 = seq_ev->data.note.velocity;
+ break;
+ case SND_SEQ_EVENT_CONTROLLER:
+ evt.type = CONTROL_CHANGE;
+ evt.channel = seq_ev->data.control.channel;
+ evt.param1 = seq_ev->data.control.param;
+ evt.param2 = seq_ev->data.control.value;
+ break;
+ case SND_SEQ_EVENT_PITCHBEND:
+ evt.type = PITCH_BEND;
+ evt.channel = seq_ev->data.control.channel;
+ /* ALSA pitch bend is -8192 - 8191, we adjust it here */
+ evt.param1 = seq_ev->data.control.value + 8192;
+ break;
+ case SND_SEQ_EVENT_PGMCHANGE:
+ evt.type = PROGRAM_CHANGE;
+ evt.channel = seq_ev->data.control.channel;
+ evt.param1 = seq_ev->data.control.value;
+ break;
+ case SND_SEQ_EVENT_CHANPRESS:
+ evt.type = CHANNEL_PRESSURE;
+ evt.channel = seq_ev->data.control.channel;
+ evt.param1 = seq_ev->data.control.value;
+ break;
+ default:
+ continue; /* unhandled event, next loop iteration */
+ }
+
+ /* send the events to the next link in the chain */
+ (*dev->driver.handler)(dev->driver.data, &evt);
+
+ /* dump input on output */
+ //snd_seq_ev_set_source(new_ev, dev->seq_port);
+ //snd_seq_ev_set_dest(seq_ev,dev->seq_handle,dev->seq_client);
+ //snd_seq_ev_set_subs(new_ev);
+ //snd_seq_ev_set_direct(new_ev);
+ //snd_seq_event_output(dev->seq_handle, new_ev);
+ //snd_seq_drain_output(dev->seq_handle);
+
+ }
+ }
+
+ if ((n < 0) && (n != -EAGAIN)) {
+ AUBIO_ERR( "Error occured while reading ALSA sequencer events");
+ dev->status = AUBIO_MIDI_DONE;
+ }
+
+// /* added by piem to handle new data to output */
+// while (/* get new data, but from where ??? (n = snd_seq_event_output(dev->seq_handle, seq_ev)) >= 0*/ )
+// {
+// /* dump input on output */
+// snd_seq_ev_set_source(new_ev, dev->seq_port);
+// //snd_seq_ev_set_dest(seq_ev,dev->seq_handle,dev->seq_client);
+// snd_seq_ev_set_subs(new_ev);
+// snd_seq_ev_set_direct(new_ev);
+// snd_seq_event_output(dev->seq_handle, new_ev);
+// snd_seq_drain_output(dev->seq_handle);
+// }
+
+ }
+ pthread_exit(NULL);
+}
+
+
+snd_seq_event_t ev;
+
+void aubio_midi_direct_output(aubio_midi_driver_t * d, aubio_midi_event_t * event)
+{
+ aubio_alsa_seq_driver_t* dev = (aubio_alsa_seq_driver_t*) d;
+ /*
+ if (pthread_join(dev->thread, NULL)) {
+ AUBIO_ERR( "Failed to join the midi thread");
+ }
+ */
+ switch(event->type)
+ {
+ case NOTE_ON:
+ ev.type = SND_SEQ_EVENT_NOTEON;
+ ev.data.note.channel = event->channel;
+ ev.data.note.note = event->param1;
+ ev.data.note.velocity = event->param2;
+ //AUBIO_ERR( "NOTE_ON %d\n", event->param1);
+ break;
+ case NOTE_OFF:
+ ev.type = SND_SEQ_EVENT_NOTEOFF;
+ ev.data.note.channel = event->channel;
+ ev.data.note.note = event->param1;
+ ev.data.note.velocity = event->param2;
+ //AUBIO_ERR( "NOTE_OFF %d\n", event->param1);
+ break;
+ default:
+ break;
+ }
+ if (ev.type == SND_SEQ_EVENT_NOTEOFF || ev.type == SND_SEQ_EVENT_NOTEON ) {
+ snd_seq_ev_set_subs(&ev);
+ snd_seq_ev_set_direct(&ev);
+ snd_seq_ev_set_source(&ev, dev->seq_port);
+ snd_seq_event_output_direct(dev->seq_handle, &ev);
+ }
+ /*
+ if (pthread_detach(dev->thread)) {
+ AUBIO_ERR( "Failed to leave the midi thread");
+ }
+ */
+}
+
+#endif /* #if ALSA_SUPPORT */
--- /dev/null
+++ b/ext/midi/midi_driver.c
@@ -1,0 +1,195 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+/* This file originally tajke from
+ * FluidSynth - A Software Synthesizer
+ *
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+#include "aubio_priv.h"
+#include "midi_event.h"
+#include "midi_driver.h"
+//#include "settings.h"
+
+/*
+ * aubio_mdriver_definition
+ */
+struct aubio_mdriver_definition_t {
+ char* name;
+ aubio_midi_driver_t* (*new)(
+ //aubio_settings_t* settings,
+ handle_midi_event_func_t event_handler,
+ void* event_handler_data);
+ int (*free)(aubio_midi_driver_t* p);
+ void (*settings)(aubio_settings_t* settings);
+};
+
+
+/* ALSA */
+#if ALSA_SUPPORT
+aubio_midi_driver_t* new_aubio_midi_alsa_raw_driver(
+ //aubio_settings_t* settings,
+ handle_midi_event_func_t handler,
+ void* event_handler_data);
+int del_aubio_midi_alsa_raw_driver(aubio_midi_driver_t* p);
+void aubio_midi_alsa_raw_driver_settings(aubio_settings_t* settings);
+
+aubio_midi_driver_t* new_aubio_alsa_seq_driver(
+ //aubio_settings_t* settings,
+ handle_midi_event_func_t handler,
+ void* event_handler_data);
+int del_aubio_alsa_seq_driver(aubio_midi_driver_t* p);
+void aubio_alsa_seq_driver_settings(aubio_settings_t* settings);
+#endif
+
+/* OSS */
+#if OSS_SUPPORT
+aubio_midi_driver_t* new_aubio_oss_midi_driver(aubio_settings_t* settings,
+ handle_midi_event_func_t handler,
+ void* event_handler_data);
+int del_aubio_oss_midi_driver(aubio_midi_driver_t* p);
+//void aubio_oss_midi_driver_settings(aubio_settings_t* settings);
+#endif
+
+/* Windows MIDI service */
+#if WINMIDI_SUPPORT
+aubio_midi_driver_t* new_aubio_winmidi_driver(aubio_settings_t* settings,
+ handle_midi_event_func_t handler,
+ void* event_handler_data);
+int del_aubio_winmidi_driver(aubio_midi_driver_t* p);
+#endif
+
+/* definitions for the MidiShare driver */
+#if MIDISHARE_SUPPORT
+aubio_midi_driver_t* new_aubio_midishare_midi_driver(aubio_settings_t* settings,
+ handle_midi_event_func_t handler,
+ void* event_handler_data);
+int del_aubio_midishare_midi_driver(aubio_midi_driver_t* p);
+#endif
+
+
+struct aubio_mdriver_definition_t aubio_midi_drivers[] = {
+#if OSS_SUPPORT
+ { "oss",
+ new_aubio_oss_midi_driver,
+ del_aubio_oss_midi_driver,
+ aubio_oss_midi_driver_settings },
+#endif
+#if ALSA_SUPPORT
+ { "alsa_raw",
+ new_aubio_midi_alsa_raw_driver,
+ del_aubio_midi_alsa_raw_driver,
+ NULL /*aubio_midi_alsa_raw_driver_settings*/ },
+ { "alsa_seq",
+ new_aubio_alsa_seq_driver,
+ del_aubio_alsa_seq_driver,
+ NULL /*aubio_alsa_seq_driver_settings*/ },
+#endif
+#if WINMIDI_SUPPORT
+ { "winmidi",
+ new_aubio_winmidi_driver,
+ del_aubio_winmidi_driver,
+ NULL },
+#endif
+#if MIDISHARE_SUPPORT
+ { "midishare",
+ new_aubio_midishare_midi_driver,
+ del_aubio_midishare_midi_driver,
+ NULL },
+#endif
+ { NULL, NULL, NULL, NULL }
+};
+
+
+void aubio_midi_driver_settings(aubio_settings_t* settings)
+{
+ int i;
+
+#if 0
+ /* Set the default driver */
+#if ALSA_SUPPORT
+ aubio_settings_register_str(settings, "midi.driver", "alsa_seq", 0, NULL, NULL);
+#elif OSS_SUPPORT
+ aubio_settings_register_str(settings, "midi.driver", "oss", 0, NULL, NULL);
+#elif WINMIDI_SUPPORT
+ aubio_settings_register_str(settings, "midi.driver", "winmidi", 0, NULL, NULL);
+#elif MIDISHARE_SUPPORT
+ aubio_settings_register_str(settings, "midi.driver", "midishare", 0, NULL, NULL);
+#else
+ aubio_settings_register_str(settings, "midi.driver", "", 0, NULL, NULL);
+#endif
+
+ /* Add all drivers to the list of options */
+#if ALSA_SUPPORT
+ aubio_settings_add_option(settings, "midi.driver", "alsa_seq");
+ aubio_settings_add_option(settings, "midi.driver", "alsa_raw");
+#endif
+#if OSS_SUPPORT
+ aubio_settings_add_option(settings, "midi.driver", "oss");
+#endif
+#if WINMIDI_SUPPORT
+ aubio_settings_add_option(settings, "midi.driver", "winmidi");
+#endif
+#if MIDISHARE_SUPPORT
+ aubio_settings_add_option(settings, "midi.driver", "midishare");
+#endif
+
+#endif
+
+ for (i = 0; aubio_midi_drivers[i].name != NULL; i++) {
+ if (aubio_midi_drivers[i].settings != NULL) {
+ aubio_midi_drivers[i].settings(settings);
+ }
+ }
+}
+
+//aubio_midi_driver_t* new_aubio_midi_driver(aubio_settings_t* settings,
+aubio_midi_driver_t* new_aubio_midi_driver(char * name,
+ handle_midi_event_func_t handler,
+ void* event_handler_data)
+{
+ int i;
+ aubio_midi_driver_t* driver = NULL;
+ for (i = 0; aubio_midi_drivers[i].name != NULL; i++) {
+ if (AUBIO_STRCMP(name,aubio_midi_drivers[i].name) == 0){
+ //if (aubio_settings_str_equal(settings, "midi.driver", aubio_midi_drivers[i].name)) {
+ AUBIO_DBG( "Using '%s' midi driver\n", aubio_midi_drivers[i].name);
+ //driver = aubio_midi_drivers[i].new(settings, handler, event_handler_data);
+ driver = aubio_midi_drivers[i].new(/*name,*/ handler, event_handler_data);
+ if (driver) {
+ driver->name = aubio_midi_drivers[i].name;
+ }
+ return driver;
+ }
+ }
+ AUBIO_ERR("Couldn't find the requested midi driver");
+ return NULL;
+}
+
+void del_aubio_midi_driver(aubio_midi_driver_t* driver)
+{
+ int i;
+
+ for (i = 0; aubio_midi_drivers[i].name != NULL; i++) {
+ if (aubio_midi_drivers[i].name == driver->name) {
+ aubio_midi_drivers[i].free(driver);
+ return;
+ }
+ }
+}
+
--- /dev/null
+++ b/ext/midi/midi_driver.h
@@ -1,0 +1,57 @@
+/*
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file orginally taken from :
+ * FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+
+/** \file
+ * generic midi driver
+ */
+
+#ifndef _AUBIO_MDRIVER_H
+#define _AUBIO_MDRIVER_H
+
+typedef void aubio_settings_t;
+
+typedef int (*handle_midi_event_func_t)(void* data, aubio_midi_event_t* event);
+
+/** aubio_midi_driver_t */
+typedef struct _aubio_midi_driver_t aubio_midi_driver_t;
+
+struct _aubio_midi_driver_t
+{
+ char* name;
+ handle_midi_event_func_t handler;
+ void* data;
+};
+
+//aubio_midi_driver_t* new_aubio_midi_driver(aubio_settings_t* settings,
+aubio_midi_driver_t* new_aubio_midi_driver(char * name,
+ handle_midi_event_func_t handler,
+ void* event_handler_data);
+void del_aubio_midi_driver(aubio_midi_driver_t* driver);
+void aubio_midi_driver_settings(aubio_settings_t* settings);
+
+#include "config.h"
+#if JACK_SUPPORT
+void aubio_midi_direct_output(aubio_midi_driver_t * dev, aubio_midi_event_t * event);
+#endif
+
+#endif /* _AUBIO_AUDRIVER_H */
--- /dev/null
+++ b/ext/midi/midi_event.c
@@ -1,0 +1,222 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+#include "aubio_priv.h"
+#include "midi_event.h"
+#include "midi.h"
+
+/******************************************************
+ *
+ * aubio_event_t
+ */
+
+/*
+ * new_aubio_midi_event
+ */
+aubio_midi_event_t* new_aubio_midi_event()
+{
+ aubio_midi_event_t* evt;
+ evt = AUBIO_NEW(aubio_midi_event_t);
+ if (evt == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return NULL;
+ }
+ evt->dtime = 0;
+ evt->type = 0;
+ evt->channel = 0;
+ evt->param1 = 0;
+ evt->param2 = 0;
+ evt->next = NULL;
+ return evt;
+}
+
+/** del_aubio_midi_event */
+int del_aubio_midi_event(aubio_midi_event_t* evt)
+{
+ aubio_midi_event_t *temp;
+ while(evt)
+ {
+ temp = evt->next;
+ AUBIO_FREE(evt);
+ evt = temp;
+ }
+ return AUBIO_OK;
+}
+
+/*
+ * aubio_midi_event_get_type
+ */
+int aubio_midi_event_get_type(aubio_midi_event_t* evt)
+{
+ return evt->type;
+}
+
+/*
+ * aubio_midi_event_set_type
+ */
+int aubio_midi_event_set_type(aubio_midi_event_t* evt, int type)
+{
+ evt->type = type;
+ return AUBIO_OK;
+}
+
+/*
+ * aubio_midi_event_get_channel
+ */
+int aubio_midi_event_get_channel(aubio_midi_event_t* evt)
+{
+ return evt->channel;
+}
+
+/*
+ * aubio_midi_event_set_channel
+ */
+int aubio_midi_event_set_channel(aubio_midi_event_t* evt, int chan)
+{
+ evt->channel = chan;
+ return AUBIO_OK;
+}
+
+/*
+ * aubio_midi_event_get_key
+ */
+int aubio_midi_event_get_key(aubio_midi_event_t* evt)
+{
+ return evt->param1;
+}
+
+/*
+ * aubio_midi_event_set_key
+ */
+int aubio_midi_event_set_key(aubio_midi_event_t* evt, int v)
+{
+ evt->param1 = v;
+ return AUBIO_OK;
+}
+
+/*
+ * aubio_midi_event_get_velocity
+ */
+int aubio_midi_event_get_velocity(aubio_midi_event_t* evt)
+{
+ return evt->param2;
+}
+
+/*
+ * aubio_midi_event_set_velocity
+ */
+int aubio_midi_event_set_velocity(aubio_midi_event_t* evt, int v)
+{
+ evt->param2 = v;
+ return AUBIO_OK;
+}
+
+/*
+ * aubio_midi_event_get_control
+ */
+int aubio_midi_event_get_control(aubio_midi_event_t* evt)
+{
+ return evt->param1;
+}
+
+/*
+ * aubio_midi_event_set_control
+ */
+int aubio_midi_event_set_control(aubio_midi_event_t* evt, int v)
+{
+ evt->param1 = v;
+ return AUBIO_OK;
+}
+
+/*
+ * aubio_midi_event_get_value
+ */
+int aubio_midi_event_get_value(aubio_midi_event_t* evt)
+{
+ return evt->param2;
+}
+
+/*
+ * aubio_midi_event_set_value
+ */
+int aubio_midi_event_set_value(aubio_midi_event_t* evt, int v)
+{
+ evt->param2 = v;
+ return AUBIO_OK;
+}
+
+int aubio_midi_event_get_program(aubio_midi_event_t* evt)
+{
+ return evt->param1;
+}
+
+int aubio_midi_event_set_program(aubio_midi_event_t* evt, int val)
+{
+ evt->param1 = val;
+ return AUBIO_OK;
+}
+
+int aubio_midi_event_get_pitch(aubio_midi_event_t* evt)
+{
+ return evt->param1;
+}
+
+int aubio_midi_event_set_pitch(aubio_midi_event_t* evt, int val)
+{
+ evt->param1 = val;
+ return AUBIO_OK;
+}
+
+/*
+ * aubio_midi_event_get_param1
+ */
+/* int aubio_midi_event_get_param1(aubio_midi_event_t* evt) */
+/* { */
+/* return evt->param1; */
+/* } */
+
+/*
+ * aubio_midi_event_set_param1
+ */
+/* int aubio_midi_event_set_param1(aubio_midi_event_t* evt, int v) */
+/* { */
+/* evt->param1 = v; */
+/* return AUBIO_OK; */
+/* } */
+
+/*
+ * aubio_midi_event_get_param2
+ */
+/* int aubio_midi_event_get_param2(aubio_midi_event_t* evt) */
+/* { */
+/* return evt->param2; */
+/* } */
+
+/*
+ * aubio_midi_event_set_param2
+ */
+/* int aubio_midi_event_set_param2(aubio_midi_event_t* evt, int v) */
+/* { */
+/* evt->param2 = v; */
+/* return AUBIO_OK; */
+/* } */
+
--- /dev/null
+++ b/ext/midi/midi_event.h
@@ -1,0 +1,72 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+/** \file
+ * midi event structure
+ */
+
+#ifndef _AUBIO_MIDI_EVENT_H
+#define _AUBIO_MIDI_EVENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _aubio_midi_event_t aubio_midi_event_t;
+
+/*
+ * aubio_midi_event_t
+ */
+struct _aubio_midi_event_t {
+ aubio_midi_event_t* next; /**< Don't use it, it will dissappear. Used in midi tracks. */
+ unsigned int dtime; /**< Delay (ticks) between this and previous event. midi tracks. */
+ unsigned char type; /**< MIDI event type */
+ unsigned char channel; /**< MIDI channel */
+ unsigned int param1; /**< First parameter */
+ unsigned int param2; /**< Second parameter */
+};
+
+aubio_midi_event_t* new_aubio_midi_event(void);
+int del_aubio_midi_event(aubio_midi_event_t* event);
+int aubio_midi_event_set_type(aubio_midi_event_t* evt, int type);
+int aubio_midi_event_get_type(aubio_midi_event_t* evt);
+int aubio_midi_event_set_channel(aubio_midi_event_t* evt, int chan);
+int aubio_midi_event_get_channel(aubio_midi_event_t* evt);
+int aubio_midi_event_get_key(aubio_midi_event_t* evt);
+int aubio_midi_event_set_key(aubio_midi_event_t* evt, int key);
+int aubio_midi_event_get_velocity(aubio_midi_event_t* evt);
+int aubio_midi_event_set_velocity(aubio_midi_event_t* evt, int vel);
+int aubio_midi_event_get_control(aubio_midi_event_t* evt);
+int aubio_midi_event_set_control(aubio_midi_event_t* evt, int ctrl);
+int aubio_midi_event_get_value(aubio_midi_event_t* evt);
+int aubio_midi_event_set_value(aubio_midi_event_t* evt, int val);
+int aubio_midi_event_get_program(aubio_midi_event_t* evt);
+int aubio_midi_event_set_program(aubio_midi_event_t* evt, int val);
+int aubio_midi_event_get_pitch(aubio_midi_event_t* evt);
+int aubio_midi_event_set_pitch(aubio_midi_event_t* evt, int val);
+int aubio_midi_event_length(unsigned char status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif/*_AUBIO_MIDI_EVENT_H*/
--- /dev/null
+++ b/ext/midi/midi_file.c
@@ -1,0 +1,633 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ *
+ * \note fixed some track names causing segfault
+ */
+
+#include "aubio_priv.h"
+#include "midi.h"
+#include "midi_event.h"
+#include "midi_track.h"
+#include "midi_player.h"
+#include "midi_file.h"
+
+
+/** aubio_midi_file */
+struct _aubio_midi_file_t{
+ //aubio_file_t fp;
+ FILE *fp;
+ int running_status;
+ int c;
+ int type;
+ int ntracks;
+ int uses_smpte;
+ unsigned int smpte_fps;
+ unsigned int smpte_res;
+ unsigned int division; /* If uses_SMPTE == 0 then division is
+ ticks per beat (quarter-note) */
+ double tempo; /* Beats per second (SI rules =) */
+ int tracklen;
+ int trackpos;
+ int eot;
+ int varlen;
+};
+
+/***************************************************************
+ *
+ * MIDIFILE
+ */
+
+/** new_aubio_midi_file */
+aubio_midi_file_t * new_aubio_midi_file(char* filename)
+{
+ aubio_midi_file_t* mf;
+
+ mf = AUBIO_NEW(aubio_midi_file_t);
+ if (mf == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return NULL;
+ }
+ AUBIO_MEMSET(mf, 0, sizeof(aubio_midi_file_t));
+
+ mf->c = -1;
+ mf->running_status = -1;
+ mf->fp = AUBIO_FOPEN(filename, "rb");
+
+ if (mf->fp == NULL) {
+ AUBIO_ERR( "Couldn't open the MIDI file !\n");
+ AUBIO_FREE(mf);
+ return NULL;
+ }
+
+ if (aubio_midi_file_read_mthd(mf) != AUBIO_OK) {
+ AUBIO_FREE(mf);
+ return NULL;
+ }
+ return mf;
+}
+
+/** del_aubio_midi_file */
+void del_aubio_midi_file(aubio_midi_file_t* mf)
+{
+ if (mf == NULL) {
+ return;
+ }
+ if (mf->fp != NULL) {
+ AUBIO_FCLOSE(mf->fp);
+ }
+ AUBIO_FREE(mf);
+ return;
+}
+
+/** aubio_midi_file_getc */
+int aubio_midi_file_getc(aubio_midi_file_t* mf)
+{
+ unsigned char c;
+ int n;
+ if (mf->c >= 0) {
+ c = mf->c;
+ mf->c = -1;
+ } else {
+ n = AUBIO_FREAD(&c, 1, 1, mf->fp);
+ mf->trackpos++;
+ }
+ return (int) c;
+}
+
+/** aubio_midi_file_push */
+int aubio_midi_file_push(aubio_midi_file_t* mf, int c)
+{
+ mf->c = c;
+ return AUBIO_OK;
+}
+
+/** aubio_midi_file_read */
+int aubio_midi_file_read(aubio_midi_file_t* mf, void* buf, int len)
+{
+ int num = AUBIO_FREAD(buf, 1, len, mf->fp);
+ mf->trackpos += num;
+#if DEBUG
+ if (num != len) {
+ AUBIO_DBG( "Coulnd't read the requested number of bytes");
+ }
+#endif
+ return (num != len)? AUBIO_FAIL : AUBIO_OK;
+}
+
+/** aubio_midi_file_skip */
+int aubio_midi_file_skip(aubio_midi_file_t* mf, int skip)
+{
+ int err = AUBIO_FSEEK(mf->fp, skip, SEEK_CUR);
+ if (err) {
+ AUBIO_ERR( "FAIL to seek position in file");
+ return AUBIO_FAIL;
+ }
+ return AUBIO_OK;
+}
+
+/** aubio_midi_file_read_mthd */
+int aubio_midi_file_read_mthd(aubio_midi_file_t* mf)
+{
+ char mthd[15];
+ if (aubio_midi_file_read(mf, mthd, 14) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+ if ((AUBIO_STRNCMP(mthd, "MThd", 4) != 0) || (mthd[7] != 6) || (mthd[9] > 2)) {
+ AUBIO_ERR( "Doesn't look like a MIDI file: invalid MThd header");
+ return AUBIO_FAIL;
+ }
+ mf->type = mthd[9];
+ mf->ntracks = (unsigned) mthd[11];
+ mf->ntracks += (unsigned int) (mthd[10]) << 16;
+ /** \bug: smpte timing not yet implemented */
+ if((int)(mthd[12]) < 0){
+ /*if((mthd[12]) < 0){*/
+ mf->uses_smpte = 1;
+ mf->smpte_fps = -mthd[12];
+ mf->smpte_res = (unsigned) mthd[13];
+ AUBIO_ERR( "File uses SMPTE timing -- Not implemented yet");
+ return AUBIO_FAIL;
+ } else {
+ mf->uses_smpte = 0;
+ mf->division = (mthd[12] << 8) | (mthd[13] & 0xff);
+ }
+ return AUBIO_OK;
+}
+
+/** aubio_midi_file_load_tracks */
+int aubio_midi_file_load_tracks(aubio_midi_file_t* mf, aubio_midi_player_t* player)
+{
+ int i;
+ for (i = 0; i < mf->ntracks; i++) {
+ if (aubio_midi_file_read_track(mf, player, i) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+ }
+ return AUBIO_OK;
+}
+
+/** aubio_midi_file_read_tracklen */
+int aubio_midi_file_read_tracklen(aubio_midi_file_t* mf)
+{
+ unsigned char length[5];
+ if (aubio_midi_file_read(mf, length, 4) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+ mf->tracklen = aubio_getlength(length);
+ mf->trackpos = 0;
+ mf->eot = 0;
+ return AUBIO_OK;
+}
+
+/** aubio_midi_file_eot */
+int aubio_midi_file_eot(aubio_midi_file_t* mf)
+{
+#if DEBUG
+ if (mf->trackpos > mf->tracklen) {
+ printf("track overrun: %d > %d\n", mf->trackpos, mf->tracklen);
+ }
+#endif
+ return mf->eot || (mf->trackpos >= mf->tracklen);
+}
+
+/** aubio_midi_file_read_track */
+int aubio_midi_file_read_track(aubio_midi_file_t* mf, aubio_midi_player_t* player, int num)
+{
+ aubio_track_t* track;
+ unsigned char id[5], length[5];
+ int found_track = 0;
+ int skip;
+
+ AUBIO_DBG("Loading track %d\n",num);
+ if (aubio_midi_file_read(mf, id, 4) != AUBIO_OK) {
+ AUBIO_DBG("Failed loading track %d\n",num);
+ return AUBIO_FAIL;
+ }
+
+ id[4]='\0';
+
+ while (!found_track){
+
+ if (aubio_isasciistring((char*) id) == 0) {
+ AUBIO_ERR( "An non-ascii track header found, currupt file");
+ return AUBIO_FAIL;
+
+ } else if (strcmp((char*) id, "MTrk") == 0) {
+
+ found_track = 1;
+
+ if (aubio_midi_file_read_tracklen(mf) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+
+ track = new_aubio_track(num);
+ if (track == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return AUBIO_FAIL;
+ }
+
+ while (!aubio_midi_file_eot(mf)) {
+ if (aubio_midi_file_read_event(mf, track) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+ }
+
+ aubio_midi_player_add_track(player, track);
+ } else {
+ found_track = 0;
+ if (aubio_midi_file_read(mf, length, 4) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+ skip = aubio_getlength(length);
+ /* fseek(mf->fp, skip, SEEK_CUR); */
+ if (aubio_midi_file_skip(mf, skip) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+ }
+ }
+
+ if (feof(mf->fp)) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+ AUBIO_DBG("Loaded track %d\n",num);
+ return AUBIO_OK;
+}
+
+/** aubio_midi_file_read_varlen */
+int aubio_midi_file_read_varlen(aubio_midi_file_t* mf)
+{
+ int i;
+ int c;
+ mf->varlen = 0;
+ for (i = 0;;i++) {
+ if (i == 4) {
+ AUBIO_ERR( "Invalid variable length number");
+ return AUBIO_FAIL;
+ }
+ c = aubio_midi_file_getc(mf);
+ if (c < 0) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+ if (c & 0x80){
+ mf->varlen |= (int) (c & 0x7F);
+ mf->varlen <<= 7;
+ } else {
+ mf->varlen += c;
+ break;
+ }
+ }
+ return AUBIO_OK;
+}
+
+/** aubio_midi_file_read_event */
+int aubio_midi_file_read_event(aubio_midi_file_t* mf, aubio_track_t* track)
+{
+ int dtime;
+ int status;
+ int type;
+ int tempo;
+ unsigned char* metadata = NULL;
+ unsigned char* dyn_buf = NULL;
+ unsigned char static_buf[256];
+ int nominator, denominator, clocks, notes, sf, mi;
+ aubio_midi_event_t* evt;
+ int channel = 0;
+ int param1 = 0;
+ int param2 = 0;
+
+
+ /* read the delta-time of the event */
+ if (aubio_midi_file_read_varlen(mf) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+ dtime = mf->varlen;
+
+ /* read the status byte */
+ status = aubio_midi_file_getc(mf);
+ if (status < 0) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+
+ /* not a valid status byte: use the running status instead */
+ if ((status & 0x80) == 0) {
+ if ((mf->running_status & 0x80) == 0) {
+ AUBIO_ERR( "Undefined status and invalid running status");
+ return AUBIO_FAIL;
+ }
+ aubio_midi_file_push(mf, status);
+ status = mf->running_status;
+ }
+
+ /* check what message we have */
+ if (status & 0x80) {
+ mf->running_status = status;
+
+ if ((status == MIDI_SYSEX) || (status == MIDI_EOX)) { /* system exclusif */
+ /** \bug Sysex messages are not handled yet */
+ /* read the length of the message */
+ if (aubio_midi_file_read_varlen(mf) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+
+ if (mf->varlen < 255) {
+ metadata = &static_buf[0];
+ } else {
+ AUBIO_DBG( "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
+ dyn_buf = AUBIO_MALLOC(mf->varlen + 1);
+ if (dyn_buf == NULL) {
+ //AUBIO_LOG(AUBIO_PANIC, "Out of memory");
+ AUBIO_ERR("Out of memory");
+ return AUBIO_FAIL;
+ }
+ metadata = dyn_buf;
+ }
+
+ /* read the data of the message */
+ if (mf->varlen) {
+
+ if (aubio_midi_file_read(mf, metadata, mf->varlen) != AUBIO_OK) {
+ if (dyn_buf) {
+ AUBIO_FREE(dyn_buf);
+ }
+ return AUBIO_FAIL;
+ }
+
+ if (dyn_buf) {
+ AUBIO_DBG( "%s: %d: free metadata", __FILE__, __LINE__);
+ AUBIO_FREE(dyn_buf);
+ }
+ }
+
+ return AUBIO_OK;
+
+ } else if (status == MIDI_META_EVENT) { /* meta events */
+
+ int result = AUBIO_OK;
+
+ /* get the type of the meta message */
+ type = aubio_midi_file_getc(mf);
+ if (type < 0) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+
+ /* get the length of the data part */
+ if (aubio_midi_file_read_varlen(mf) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+
+ if (mf->varlen) {
+
+ if (mf->varlen < 255) {
+ metadata = &static_buf[0];
+ } else {
+ AUBIO_DBG( "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
+ dyn_buf = AUBIO_MALLOC(mf->varlen + 1);
+ if (dyn_buf == NULL) {
+ AUBIO_ERR("Out of memory");
+ return AUBIO_FAIL;
+ }
+ metadata = dyn_buf;
+ }
+
+ /* read the data */
+ if (aubio_midi_file_read(mf, metadata, mf->varlen) != AUBIO_OK) {
+ if (dyn_buf) {
+ AUBIO_FREE(dyn_buf);
+ }
+ return AUBIO_FAIL;
+ }
+ }
+
+ /* handle meta data */
+ switch (type) {
+
+ case MIDI_COPYRIGHT:
+ metadata[mf->varlen] = 0;
+ break;
+
+ case MIDI_TRACK_NAME:
+ if (metadata != NULL) /* avoids crashes on empty tracks */
+ metadata[mf->varlen] = 0;
+ aubio_track_set_name(track, (char*) metadata);
+ break;
+
+ case MIDI_INST_NAME:
+ metadata[mf->varlen] = 0;
+ break;
+
+ case MIDI_LYRIC:
+ break;
+
+ case MIDI_MARKER:
+ break;
+
+ case MIDI_CUE_POINT:
+ break; /* don't care much for text events */
+
+ case MIDI_EOT:
+ if (mf->varlen != 0) {
+ AUBIO_ERR("Invalid length for EndOfTrack event");
+ result = AUBIO_FAIL;
+ break;
+ }
+ mf->eot = 1;
+ break;
+
+ case MIDI_SET_TEMPO:
+ if (mf->varlen != 3) {
+ AUBIO_ERR("Invalid length for SetTempo meta event");
+ result = AUBIO_FAIL;
+ break;
+ }
+ tempo = (metadata[0] << 16) + (metadata[1] << 8) + metadata[2];
+ evt = new_aubio_midi_event();
+ if (evt == NULL) {
+ AUBIO_ERR( "Out of memory");
+ result = AUBIO_FAIL;
+ break;
+ }
+ evt->dtime = dtime;
+ evt->type = MIDI_SET_TEMPO;
+ evt->channel = 0;
+ evt->param1 = tempo;
+ evt->param2 = 0;
+ aubio_track_add_event(track, evt);
+ break;
+
+ case MIDI_SMPTE_OFFSET:
+ if (mf->varlen != 5) {
+ AUBIO_ERR("Invalid length for SMPTE Offset meta event");
+ result = AUBIO_FAIL;
+ break;
+ }
+ break; /* we don't use smtp */
+
+ case MIDI_TIME_SIGNATURE:
+ if (mf->varlen != 4) {
+ AUBIO_ERR("Invalid length for TimeSignature meta event");
+ result = AUBIO_FAIL;
+ break;
+ }
+ nominator = metadata[0];
+ denominator = pow(2.0, (double) metadata[1]);
+ clocks = metadata[2];
+ notes = metadata[3];
+
+ AUBIO_DBG("signature=%d/%d, metronome=%d, 32nd-notes=%d\n",
+ nominator, denominator, clocks, notes);
+
+ break;
+
+ case MIDI_KEY_SIGNATURE:
+ if (mf->varlen != 2) {
+ AUBIO_ERR( "Invalid length for KeySignature meta event");
+ result = AUBIO_FAIL;
+ break;
+ }
+ sf = metadata[0];
+ mi = metadata[1];
+ break;
+
+ case MIDI_SEQUENCER_EVENT:
+ AUBIO_DBG("Sequencer event ignored\n");
+ break;
+
+ default:
+ break;
+ }
+
+ if (dyn_buf) {
+ AUBIO_DBG( "%s: %d: free metadata", __FILE__, __LINE__);
+ AUBIO_FREE(dyn_buf);
+ }
+
+ return result;
+
+ } else { /* channel messages */
+
+ type = status & 0xf0;
+ channel = status & 0x0f;
+
+ /* all channel message have at least 1 byte of associated data */
+ if ((param1 = aubio_midi_file_getc(mf)) < 0) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+
+ switch (type) {
+
+ case NOTE_ON:
+ if ((param2 = aubio_midi_file_getc(mf)) < 0) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+ break;
+
+ case NOTE_OFF:
+ if ((param2 = aubio_midi_file_getc(mf)) < 0) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+ break;
+
+ case KEY_PRESSURE:
+ if ((param2 = aubio_midi_file_getc(mf)) < 0) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+ break;
+
+ case CONTROL_CHANGE:
+ if ((param2 = aubio_midi_file_getc(mf)) < 0) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+ break;
+
+ case PROGRAM_CHANGE:
+ break;
+
+ case CHANNEL_PRESSURE:
+ break;
+
+ case PITCH_BEND:
+ if ((param2 = aubio_midi_file_getc(mf)) < 0) {
+ AUBIO_ERR( "Unexpected end of file");
+ return AUBIO_FAIL;
+ }
+
+ param1 = ((param2 & 0x7f) << 7) | (param1 & 0x7f);
+ param2 = 0;
+ break;
+
+ default:
+ /* Can't possibly happen !? */
+ AUBIO_ERR( "Unrecognized MIDI event");
+ return AUBIO_FAIL;
+ }
+ evt = new_aubio_midi_event();
+ if (evt == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return AUBIO_FAIL;
+ }
+ evt->dtime = dtime;
+ evt->type = type;
+ evt->channel = channel;
+ evt->param1 = param1;
+ evt->param2 = param2;
+ aubio_track_add_event(track, evt);
+ }
+ }
+ return AUBIO_OK;
+}
+
+/** aubio_midi_file_get_division */
+int aubio_midi_file_get_division(aubio_midi_file_t* midifile)
+{
+ return midifile->division;
+}
+
+
+/** aubio_isasciistring */
+int aubio_isasciistring(char* s)
+{
+ int i;
+ int len = (int) AUBIO_STRLEN(s);
+ for (i = 0; i < len; i++) {
+ if (!aubio_isascii(s[i])) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/** aubio_getlength */
+long aubio_getlength(unsigned char *s)
+{
+ long i = 0;
+ i = s[3] | (s[2]<<8) | (s[1]<<16) | (s[0]<<24);
+ return i;
+}
+
--- /dev/null
+++ b/ext/midi/midi_file.h
@@ -1,0 +1,62 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+/** \file
+ * midi file reader
+ */
+
+#ifndef _AUBIO_MIDI_FILE_H
+#define _AUBIO_MIDI_FILE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _aubio_midi_file_t aubio_midi_file_t;
+
+
+aubio_midi_file_t* new_aubio_midi_file(char* filename);
+void del_aubio_midi_file(aubio_midi_file_t* mf);
+int aubio_midi_file_read_mthd(aubio_midi_file_t* midifile);
+int aubio_midi_file_load_tracks(aubio_midi_file_t* midifile, aubio_midi_player_t* player);
+int aubio_midi_file_read_track(aubio_midi_file_t* mf, aubio_midi_player_t* player, int num);
+int aubio_midi_file_read_event(aubio_midi_file_t* mf, aubio_track_t* track);
+int aubio_midi_file_read_varlen(aubio_midi_file_t* mf);
+int aubio_midi_file_getc(aubio_midi_file_t* mf);
+int aubio_midi_file_push(aubio_midi_file_t* mf, int c);
+int aubio_midi_file_read(aubio_midi_file_t* mf, void* buf, int len);
+int aubio_midi_file_skip(aubio_midi_file_t* mf, int len);
+int aubio_midi_file_read_tracklen(aubio_midi_file_t* mf);
+int aubio_midi_file_eot(aubio_midi_file_t* mf);
+int aubio_midi_file_get_division(aubio_midi_file_t* midifile);
+
+
+/* From ctype.h */
+#define aubio_isascii(c) (((c) & ~0x7f) == 0)
+int aubio_isasciistring(char* s);
+long aubio_getlength(unsigned char *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_AUBIO_MIDI_FILE_H*/
--- /dev/null
+++ b/ext/midi/midi_parser.c
@@ -1,0 +1,221 @@
+/*
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* This file orginally taken from, Fluidsynth, Peter Hanappe */
+
+#include "aubio_priv.h"
+#include "midi.h"
+#include "midi_event.h"
+#include "midi_parser.h"
+
+/** aubio_midi_parser_t */
+struct _aubio_midi_parser_t {
+ unsigned char status; /**< Identifies the type of event, that is
+ currently received ('Noteon', 'Pitch Bend'
+ etc). */
+ unsigned char channel; /**< The channel of the event that is received
+ (in case of a channel event) */
+ unsigned int nr_bytes; /**< How many bytes have been read for the
+ current event? */
+ unsigned int nr_bytes_total;/**< How many bytes does the current event
+ type include? */
+ unsigned short p[AUBIO_MIDI_PARSER_MAX_PAR]; /**< The parameters */
+
+ aubio_midi_event_t event; /**< The event, that is returned to the
+ MIDI driver. */
+};
+
+/** new_aubio_midi_parser */
+aubio_midi_parser_t* new_aubio_midi_parser()
+{
+ aubio_midi_parser_t* parser;
+ parser = AUBIO_NEW(aubio_midi_parser_t);
+ if (parser == NULL) {
+ AUBIO_ERR("Out of memory");
+ return NULL;
+ }
+ /* As long as the status is 0, the parser won't do anything -> no need to
+ * initialize all the fields. */
+ parser->status = 0;
+ return parser;
+}
+
+/** del_aubio_midi_parser */
+int del_aubio_midi_parser(aubio_midi_parser_t* parser)
+{
+ AUBIO_FREE(parser);
+ return AUBIO_OK;
+}
+
+/** aubio_midi_parser_parse
+ *
+ * The MIDI byte stream is fed into the parser, one byte at a time.
+ * As soon as the parser has recognized an event, it will return it.
+ * Otherwise it returns NULL.
+ */
+aubio_midi_event_t* aubio_midi_parser_parse(aubio_midi_parser_t* parser,
+ unsigned char c)
+{
+ /*********************************************************************/
+ /* 'Process' system real-time messages */
+ /*********************************************************************/
+ /* There are not too many real-time messages that are of interest here.
+ * They can occur anywhere, even in the middle of a noteon message!
+ * Real-time range: 0xF8 .. 0xFF
+ * Note: Real-time does not affect (running) status.
+ */
+ if (c >= 0xF8){
+ if (c == MIDI_SYSTEM_RESET){
+ parser->event.type = c;
+ parser->status = 0; /* clear the status */
+ return &parser->event;
+ };
+ return NULL;
+ };
+
+ /*********************************************************************/
+ /* 'Process' system common messages (again, just skip them) */
+ /*********************************************************************/
+ /* There are no system common messages that are of interest here.
+ * System common range: 0xF0 .. 0xF7
+ */
+
+ if (c > 0xF0){
+ /* MIDI specs say: To ignore a non-real-time message, just discard all data
+ * up to the next status byte. And our parser will ignore data that is
+ * received without a valid status.
+ * Note: system common cancels running status. */
+ parser->status = 0;
+ return NULL;
+ };
+
+ /*********************************************************************/
+ /* Process voice category messages: */
+ /*********************************************************************/
+ /* Now that we have handled realtime and system common messages, only
+ * voice messages are left.
+ * Only a status byte has bit # 7 set.
+ * So no matter the status of the parser (in case we have lost sync),
+ * as soon as a byte >= 0x80 comes in, we are dealing with a status byte
+ * and start a new event.
+ */
+
+ if (c & 0x80){
+ parser->channel = c & 0x0F;
+ parser->status = c & 0xF0;
+ /* The event consumes x bytes of data... (subtract 1 for the status
+ * byte) */
+ parser->nr_bytes_total=aubio_midi_event_length(parser->status)-1;
+ /* of which we have read 0 at this time. */
+ parser->nr_bytes = 0;
+ return NULL;
+ };
+
+ /*********************************************************************/
+ /* Process data */
+ /*********************************************************************/
+ /* If we made it this far, then the received char belongs to the data
+ * of the last event. */
+ if (parser->status == 0){
+ /* We are not interested in the event currently received.
+ * Discard the data. */
+ return NULL;
+ };
+
+ /* Store the first couple of bytes */
+ if (parser->nr_bytes < AUBIO_MIDI_PARSER_MAX_PAR){
+ parser->p[parser->nr_bytes]=c;
+ };
+ parser->nr_bytes++;
+
+ /* Do we still need more data to get this event complete? */
+ if (parser->nr_bytes < parser->nr_bytes_total){
+ return NULL;
+ };
+
+ /*********************************************************************/
+ /* Send the event */
+ /*********************************************************************/
+ /* The event is ready-to-go. About 'running status':
+ *
+ * The MIDI protocol has a built-in compression mechanism. If several similar
+ * events are sent in-a-row, for example note-ons, then the event type is
+ * only sent once. For this case, the last event type (status) is remembered.
+ * We simply keep the status as it is, just reset the parameter counter. If
+ * another status byte comes in, it will overwrite the status.
+ */
+ parser->event.type = parser->status;
+ parser->event.channel = parser->channel;
+ parser->nr_bytes = 0; /* Related to running status! */
+ switch (parser->status){
+ case NOTE_OFF:
+ case NOTE_ON:
+ case KEY_PRESSURE:
+ case CONTROL_CHANGE:
+ case PROGRAM_CHANGE:
+ case CHANNEL_PRESSURE:
+ parser->event.param1 = parser->p[0]; /* For example key number */
+ parser->event.param2 = parser->p[1]; /* For example velocity */
+ break;
+ case PITCH_BEND:
+ /* Pitch-bend is transmitted with 14-bit precision. */
+ /* Note: '|' does here the same as '+' (no common bits),
+ * but might be faster */
+ parser->event.param1 = ((parser->p[1] << 7) | parser->p[0]);
+ break;
+ default:
+ /* Unlikely */
+ return NULL;
+ };
+ return &parser->event;
+};
+
+
+
+/* Taken from Nagano Daisuke's USB-MIDI driver */
+static int remains_f0f6[] = {
+ 0, /* 0xF0 */
+ 2, /* 0XF1 */
+ 3, /* 0XF2 */
+ 2, /* 0XF3 */
+ 2, /* 0XF4 (Undefined by MIDI Spec, and subject to change) */
+ 2, /* 0XF5 (Undefined by MIDI Spec, and subject to change) */
+ 1 /* 0XF6 */
+};
+
+static int remains_80e0[] = {
+ 3, /* 0x8X Note Off */
+ 3, /* 0x9X Note On */
+ 3, /* 0xAX Poly-key pressure */
+ 3, /* 0xBX Control Change */
+ 2, /* 0xCX Program Change */
+ 2, /* 0xDX Channel pressure */
+ 3 /* 0xEX PitchBend Change */
+};
+
+/** Returns the length of the MIDI message starting with c.
+ *
+ * Taken from Nagano Daisuke's USB-MIDI driver */
+int aubio_midi_event_length(unsigned char event){
+ if ( event < 0xf0 ) {
+ return remains_80e0[((event-0x80)>>4)&0x0f];
+ } else if ( event < 0xf7 ) {
+ return remains_f0f6[event-0xf0];
+ } else {
+ return 1;
+ }
+}
--- /dev/null
+++ b/ext/midi/midi_parser.h
@@ -1,0 +1,49 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+
+/** \file
+ * midi parser
+ */
+
+#ifndef _AUBIO_MIDI_PARSER_H
+#define _AUBIO_MIDI_PARSER_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* How many parameters may a MIDI event have? */
+#define AUBIO_MIDI_PARSER_MAX_PAR 3
+
+typedef struct _aubio_midi_parser_t aubio_midi_parser_t;
+
+aubio_midi_parser_t* new_aubio_midi_parser(void);
+int del_aubio_midi_parser(aubio_midi_parser_t* parser);
+aubio_midi_event_t* aubio_midi_parser_parse(aubio_midi_parser_t* parser, unsigned char c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_AUBIO_MIDI_PARSER_H*/
--- /dev/null
+++ b/ext/midi/midi_player.c
@@ -1,0 +1,492 @@
+/*
+ * Copyright (C) 2003 Peter Hanappe and others.
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * modified by Paul Brossier for aubio
+ */
+
+/**
+ *
+ * \bug timer still broken
+ * (should use alsa seq anyway) (fixed?) realtime playing is slower than
+ * it should. moved msec_passed and deltatime to microseconds (usec)
+ * (rounding were causing the drift) the new offline version is not quite
+ * exact yet.
+ *
+ * \bug the player does not seem to understand a ``reprise'' in a file
+ */
+
+#include "aubio_priv.h"
+#include "list.h"
+#include "timer.h"
+#include "midi.h"
+#include "midi_event.h"
+#include "midi_track.h"
+#include "midi_player.h"
+#include "midi_file.h"
+
+
+/** aubio_midi_player */
+struct _aubio_midi_player_t {
+ aubio_track_t *track[AUBIO_MIDI_PLAYER_MAX_TRACKS];
+ aubio_timer_t* timer;
+ sint_t status;
+ sint_t loop;
+ sint_t ntracks;
+ aubio_list_t* playlist;
+ char* current_file;
+ char send_program_change;/**< should we ignore the program changes? */
+ sint_t ticks_passed; /**< number of midi ticks that have passed */
+ sint_t usec_passed; /**< number of microseconds that have passed */
+ sint_t miditempo; /**< as indicated by midi settempo: n 24th of a
+ * usec per midi-clock. bravo! */
+ lsmp_t deltatime; /**< microseconds per midi tick. depends on
+ * set-tempo */
+ uint_t division; /**< the number of ticks per beat (quarter-note)
+ * in the file*/
+ //aubio_synth_t* synth;
+};
+
+/******************************************************
+ *
+ * aubio_midi_player
+ */
+/** new_aubio_midi_player */
+aubio_midi_player_t* new_aubio_midi_player()
+ //aubio_midi_player_t* new_aubio_midi_player(aubio_synth_t* synth)
+{
+ sint_t i;
+ aubio_midi_player_t* player;
+ player = AUBIO_NEW(aubio_midi_player_t);
+ if (player == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return NULL;
+ }
+ player->status = AUBIO_MIDI_PLAYER_READY;
+ player->loop = 0;
+ player->ntracks = 0;
+ for (i = 0; i < AUBIO_MIDI_PLAYER_MAX_TRACKS; i++) {
+ player->track[i] = NULL;
+ }
+ //player->synth = synth;
+ player->timer = NULL;
+ player->playlist = NULL;
+ player->current_file = NULL;
+ player->division = 0;
+ player->send_program_change = 1;
+ player->ticks_passed = 0;
+ player->usec_passed = 0;
+ player->miditempo = 480000;
+ player->deltatime = 4000.0;
+ return player;
+}
+
+/** delete_aubio_midi_player */
+sint_t del_aubio_midi_player(aubio_midi_player_t* player)
+{
+ if (player == NULL) {
+ return AUBIO_OK;
+ }
+ aubio_midi_player_stop(player);
+ aubio_midi_player_reset(player);
+ AUBIO_FREE(player);
+ return AUBIO_OK;
+}
+
+/** aubio_midi_player_reset */
+sint_t aubio_midi_player_reset(aubio_midi_player_t* player)
+{
+ sint_t i;
+
+ for (i = 0; i < AUBIO_MIDI_PLAYER_MAX_TRACKS; i++) {
+ if (player->track[i] != NULL) {
+ del_aubio_track(player->track[i]);
+ player->track[i] = NULL;
+ }
+ }
+ player->current_file = NULL;
+ player->status = AUBIO_MIDI_PLAYER_READY;
+ player->loop = 0;
+ player->ntracks = 0;
+ player->division = 0;
+ player->send_program_change = 1;
+ player->ticks_passed = 0;
+ player->usec_passed = 0;
+ player->miditempo = 480000;
+ player->deltatime = 4000.0;
+ return 0;
+}
+
+/** aubio_midi_player_add_track */
+sint_t aubio_midi_player_add_track(aubio_midi_player_t* player, aubio_track_t* track)
+{
+ if (player->ntracks < AUBIO_MIDI_PLAYER_MAX_TRACKS) {
+ player->track[player->ntracks++] = track;
+ return AUBIO_OK;
+ } else {
+ return AUBIO_FAIL;
+ }
+}
+
+/** aubio_midi_player_count_tracks */
+sint_t aubio_midi_player_count_tracks(aubio_midi_player_t* player)
+{
+ return player->ntracks;
+}
+
+/** aubio_midi_player_get_track */
+aubio_track_t* aubio_midi_player_get_track(aubio_midi_player_t* player, sint_t i)
+{
+ if ((i >= 0) && (i < AUBIO_MIDI_PLAYER_MAX_TRACKS)) {
+ return player->track[i];
+ } else {
+ return NULL;
+ }
+}
+
+/** aubio_midi_player_get_track */
+sint_t aubio_midi_player_add(aubio_midi_player_t* player, char* midifile)
+{
+ char *s = AUBIO_STRDUP(midifile);
+ player->playlist = aubio_list_append(player->playlist, s);
+ return 0;
+}
+
+/** aubio_midi_player_load */
+sint_t aubio_midi_player_load(aubio_midi_player_t* player, char *filename)
+{
+ aubio_midi_file_t* midifile;
+
+ midifile = new_aubio_midi_file(filename);
+ if (midifile == NULL) {
+ return AUBIO_FAIL;
+ }
+ player->division = aubio_midi_file_get_division(midifile);
+
+ AUBIO_DBG("quarter note division=%d\n", player->division);
+
+ if (aubio_midi_file_load_tracks(midifile, player) != AUBIO_OK){
+ return AUBIO_FAIL;
+ }
+
+ AUBIO_DBG("Tracks loaded\n");
+
+ del_aubio_midi_file(midifile);
+ return AUBIO_OK;
+}
+
+/** aubio_midi_player_callback */
+sint_t aubio_midi_player_callback(void* data, uint_t usec)
+{
+ sint_t i;
+ uint_t ticks;
+ uint_t delta_ticks;
+ sint_t status = AUBIO_MIDI_PLAYER_DONE;
+ aubio_midi_player_t* player;
+ //aubio_synth_t* synth;
+ player = (aubio_midi_player_t*) data;
+ //synth = player->synth;
+
+ /* Load the next file if necessary */
+ while (player->current_file == NULL) {
+
+ if (player->playlist == NULL) {
+ return 0;
+ }
+
+ aubio_midi_player_reset(player);
+
+ player->current_file = aubio_list_get(player->playlist);
+ player->playlist = aubio_list_next(player->playlist);
+
+ //AUBIO_DBG( "%s: %d: Loading midifile %s", __FILE__, __LINE__, player->current_file);
+ AUBIO_DBG("Loading midifile %s\n", player->current_file);
+
+ if (aubio_midi_player_load(player, player->current_file) == AUBIO_OK) {
+
+ player->ticks_passed = 0;
+ player->usec_passed = 0;
+
+ for (i = 0; i < player->ntracks; i++) {
+ if (player->track[i] != NULL) {
+ aubio_track_reset(player->track[i]);
+ }
+ }
+
+ } else {
+ player->current_file = NULL;
+ }
+ }
+
+ delta_ticks = (uint_t) ((lsmp_t)(usec - player->usec_passed) / player->deltatime);
+ ticks = player->ticks_passed + delta_ticks;
+
+ for (i = 0; i < player->ntracks; i++) {
+ if (!aubio_track_eot(player->track[i])) {
+ status = AUBIO_MIDI_PLAYER_PLAYING;
+ if (aubio_track_send_events(player->track[i], /*synth,*/ player, ticks) != AUBIO_OK) {
+ /* */
+ }
+ }
+ }
+
+ player->status = status;
+ player->ticks_passed = ticks;
+ player->usec_passed = usec;
+
+ if (player->status == AUBIO_MIDI_PLAYER_DONE) {
+ player->current_file = NULL;
+ }
+
+ return 1;
+}
+
+/** aubio_midi_player_play */
+sint_t aubio_midi_player_play(aubio_midi_player_t* player)
+{
+ AUBIO_DBG("Starting midi player\n");
+ if (player->status == AUBIO_MIDI_PLAYER_PLAYING) {
+ AUBIO_DBG("Midi player already playing\n");
+ return AUBIO_OK;
+ }
+
+ if (player->playlist == NULL) {
+ AUBIO_DBG("No playlist\n");
+ return AUBIO_FAIL;
+ }
+
+ player->status = AUBIO_MIDI_PLAYER_PLAYING;
+
+ /** \bug timer is still in millisec, should be moved to microseconds,
+ * and replaced in favor of the alsa sequencer api */
+ player->timer = new_aubio_timer((sint_t) player->deltatime * 1.e-3, aubio_midi_player_callback,
+ (void*) player, 1, 0);
+ if (player->timer == NULL) {
+ AUBIO_DBG("Failed creating timer for midi player.\n");
+ return AUBIO_FAIL;
+ }
+ if (player->current_file == NULL) {
+ AUBIO_DBG("No more file.\n");
+ delete_aubio_timer(player->timer);
+ return AUBIO_FAIL;
+ }
+
+ return AUBIO_OK;
+}
+
+/** aubio_midi_player_play_offline */
+sint_t aubio_midi_player_play_offline(aubio_midi_player_t* player)
+{
+ uint_t usec = 0; /* start looking n ms in advance */
+ AUBIO_DBG("Starting midi player\n");
+ if (player->status == AUBIO_MIDI_PLAYER_PLAYING) {
+ AUBIO_DBG("Midi player already playing\n");
+ return AUBIO_OK;
+ }
+
+ if (player->playlist == NULL) {
+ AUBIO_DBG("No playlist\n");
+ return AUBIO_FAIL;
+ }
+
+ //AUBIO_DBG("Starting callback.\n");
+ player->status = AUBIO_MIDI_PLAYER_PLAYING;
+
+ /* no timer, no thread ! */
+ while(aubio_midi_player_callback((void *)player,usec))
+ {
+ /* step at least one microsecond forward */
+ usec += 1 + player->deltatime;
+ if (player->status == AUBIO_MIDI_PLAYER_DONE)
+ break;
+ }
+ //AUBIO_DBG("End of callback.\n");
+
+ if (player->current_file == NULL) {
+ AUBIO_DBG("No more file.\n");
+ return AUBIO_FAIL;
+ }
+ return AUBIO_OK;
+}
+/** aubio_midi_player_stop */
+sint_t aubio_midi_player_stop(aubio_midi_player_t* player)
+{
+ if (player->timer != NULL) {
+ delete_aubio_timer(player->timer);
+ }
+ player->status = AUBIO_MIDI_PLAYER_DONE;
+ player->timer = NULL;
+ return AUBIO_OK;
+}
+
+/** aubio_midi_player_set_loop */
+sint_t aubio_midi_player_set_loop(aubio_midi_player_t* player, sint_t loop)
+{
+ player->loop = loop;
+ return AUBIO_OK;
+}
+
+/** aubio_midi_player_set_midi_tempo */
+sint_t aubio_midi_player_set_midi_tempo(aubio_midi_player_t* player, sint_t tempo)
+{
+ player->miditempo = tempo;
+ //player->deltatime = (lsmp_t) tempo / player->division * 1.e-3; /* in milliseconds */
+ player->deltatime = (lsmp_t) tempo / player->division; /* in microseconds */
+
+ AUBIO_DBG("Tempo Change: %d tempo=%f tick time=%f msec\n",
+ // player->usec_passed, 60.*1.e6/tempo, player->deltatime);
+ player->usec_passed, 60.*1.e6/tempo, 1e-3*player->deltatime);
+
+ return AUBIO_OK;
+}
+
+/** aubio_midi_player_set_bpm */
+sint_t aubio_midi_player_set_bpm(aubio_midi_player_t* player, sint_t bpm)
+{
+ return aubio_midi_player_set_midi_tempo(player, (sint_t)((lsmp_t) 60 * 1e6 / bpm));
+}
+
+/** aubio_midi_player_join */
+sint_t aubio_midi_player_join(aubio_midi_player_t* player)
+{
+ return player->timer? aubio_timer_join(player->timer) : AUBIO_OK;
+}
+
+/** aubio_track_send_events */
+sint_t aubio_track_send_events(aubio_track_t* track,
+ // aubio_synth_t* synth,
+ aubio_midi_player_t* player,
+ uint_t ticks)
+{
+ sint_t status = AUBIO_OK;
+ aubio_midi_event_t* event;
+
+ while (1) {
+
+ event = track->cur;
+ if (event == NULL) {
+ return status;
+ }
+ /* prsint_t each midi tick */
+ /*
+ AUBIO_DBG("track=%d\tticks=%u\ttrack=%u\tdtime=%u\tnext=%u\n",
+ track->num,
+ ticks,
+ track->ticks,
+ event->dtime,
+ track->ticks + event->dtime);
+ */
+
+ if (track->ticks + event->dtime > ticks) {
+ return status;
+ }
+
+ track->ticks += event->dtime;
+ status = aubio_midi_send_event(/*synth, */player, event);
+ aubio_track_next_event(track);
+
+ }
+ return status;
+}
+
+
+/**
+ * aubio_midi_send_event
+ *
+ * This is a utility function that doesn't really belong to any class or
+ * structure. It is called by aubio_midi_track and aubio_midi_device.
+ *
+ * \note This could be moved to a callback function defined in the main programs
+ */
+//sint_t aubio_midi_send_event(aubio_synth_t* synth, aubio_player_t* player, aubio_midi_event_t* event)
+sint_t aubio_midi_send_event(aubio_midi_player_t* player, aubio_midi_event_t* event)
+{
+ /* current time in seconds */
+ //smpl_t print_time = player->msec_passed * 1e-3;
+ smpl_t print_time = player->usec_passed * 1e-6;
+ switch (event->type) {
+ case NOTE_ON:
+ AUBIO_MSG("Time=%f, chan=%d, pitch=%d vol=%d \n",
+ print_time, event->channel, event->param1, event->param2);
+ /*if (aubio_synth_noteon(synth, event->channel, event->param1, event->param2) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }*/
+ break;
+ case NOTE_OFF:
+ AUBIO_MSG("Time=%f, chan=%d, pitch=%d, vol=0\n",
+ print_time, event->channel, event->param1);
+ /*if (aubio_synth_noteoff(synth, event->channel, event->param1) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }*/
+ break;
+ case CONTROL_CHANGE:
+ AUBIO_MSG("Time=%f Parameter, chan=%d c1=%d c2=%d\n",
+ print_time, event->channel, event->param1, event->param2);
+ /*if (aubio_synth_cc(synth, event->channel, event->param1, event->param2) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }*/
+ break;
+ case MIDI_SET_TEMPO:
+ if (player != NULL) {
+ if (aubio_midi_player_set_midi_tempo(player, event->param1) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+ }
+ break;
+ case PROGRAM_CHANGE:
+ AUBIO_MSG("Time=%f Program, chan=%d program=%d\n",
+ print_time, event->channel, event->param1);
+ /*if (aubio_synth_program_change(synth, event->channel, event->param1) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }*/
+ break;
+ case PITCH_BEND:
+ AUBIO_MSG("Time=%f Pitchbend, chan=%d msb=%d lsb=%d \n",
+ print_time, event->channel, event->param1, event->param2);
+ /*if (aubio_synth_pitch_bend(synth, event->channel, event->param1) != AUBIO_OK) {
+ return AUBIO_FAIL;
+ }
+ break;*/
+ default:
+ break;
+ }
+ return AUBIO_OK;
+}
+
+
+/**
+ * aubio_midi_receive_event
+ *
+ * \note This could be moved to a callback function defined in the main programs
+ */
+sint_t aubio_midi_receive_event(aubio_midi_player_t* player, aubio_midi_event_t* event)
+{
+ /* current time in seconds */
+ //smpl_t print_time = player->msec_passed * 1e-3;
+ //smpl_t print_time = player->usec_passed * 1e-6;
+ switch (event->type) {
+ case NOTE_ON:
+ break;
+ case NOTE_OFF:
+ break;
+ default:
+ break;
+ }
+ return AUBIO_OK;
+}
--- /dev/null
+++ b/ext/midi/midi_player.h
@@ -1,0 +1,69 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+/** \file
+ * midi player
+ */
+
+
+#ifndef _AUBIO_MIDI_PLAYER_H
+#define _AUBIO_MIDI_PLAYER_H
+
+#define AUBIO_MIDI_PLAYER_MAX_TRACKS 128
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _aubio_midi_player_t aubio_midi_player_t;
+
+
+aubio_midi_player_t* new_aubio_midi_player(void);
+sint_t del_aubio_midi_player(aubio_midi_player_t* player);
+sint_t aubio_midi_player_reset(aubio_midi_player_t* player);
+sint_t aubio_midi_player_add_track(aubio_midi_player_t* player, aubio_track_t* track);
+sint_t aubio_midi_player_count_tracks(aubio_midi_player_t* player);
+aubio_track_t* aubio_midi_player_get_track(aubio_midi_player_t* player, sint_t i);
+sint_t aubio_midi_player_add(aubio_midi_player_t* player, char* midifile);
+sint_t aubio_midi_player_load(aubio_midi_player_t* player, char *filename);
+sint_t aubio_midi_player_callback(void* data, uint_t msec);
+sint_t aubio_midi_player_play(aubio_midi_player_t* player);
+sint_t aubio_midi_player_play_offline(aubio_midi_player_t* player);
+sint_t aubio_midi_player_stop(aubio_midi_player_t* player);
+sint_t aubio_midi_player_set_loop(aubio_midi_player_t* player, sint_t loop);
+sint_t aubio_midi_player_set_midi_tempo(aubio_midi_player_t* player, sint_t tempo);
+sint_t aubio_midi_player_set_bpm(aubio_midi_player_t* player, sint_t bpm);
+sint_t aubio_midi_player_join(aubio_midi_player_t* player);
+
+sint_t aubio_track_send_events(aubio_track_t* track,
+/* aubio_synth_t* synth, */
+ aubio_midi_player_t* player,
+ uint_t ticks);
+
+sint_t aubio_midi_send_event(aubio_midi_player_t* player, aubio_midi_event_t* event);
+sint_t aubio_midi_receive_event(aubio_midi_player_t* player, aubio_midi_event_t* event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AUBIO_MIDI_PLAYER_H*/
--- /dev/null
+++ b/ext/midi/midi_track.c
@@ -1,0 +1,162 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+
+#include "aubio_priv.h"
+#include "midi.h"
+#include "midi_event.h"
+#include "midi_track.h"
+#include "midi_player.h"
+
+
+/** new_aubio_track */
+aubio_track_t* new_aubio_track(int num)
+{
+ aubio_track_t* track;
+ track = AUBIO_NEW(aubio_track_t);
+ if (track == NULL) {
+ return NULL;
+ }
+ track->name = NULL;
+ track->num = num;
+ track->first = NULL;
+ track->cur = NULL;
+ track->last = NULL;
+ track->ticks = 0;
+ return track;
+}
+
+/** del_aubio_track */
+int del_aubio_track(aubio_track_t* track)
+{
+ if (track->name != NULL) {
+ AUBIO_FREE(track->name);
+ }
+ if (track->first != NULL) {
+ del_aubio_midi_event(track->first);
+ }
+ AUBIO_FREE(track);
+ return AUBIO_OK;
+}
+
+/** aubio_track_set_name */
+int aubio_track_set_name(aubio_track_t* track, char* name)
+{
+ int len;
+ if (track->name != NULL) {
+ AUBIO_FREE(track->name);
+ }
+ if (name == NULL) {
+ track->name = NULL;
+ return AUBIO_OK;
+ }
+ len = AUBIO_STRLEN(name);
+ track->name = AUBIO_MALLOC(len + 1);
+ if (track->name == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return AUBIO_FAIL;
+ }
+ AUBIO_STRCPY(track->name, name);
+ return AUBIO_OK;
+}
+
+/** aubio_track_get_name */
+char* aubio_track_get_name(aubio_track_t* track)
+{
+ return track->name;
+}
+
+/** aubio_track_get_duration */
+int aubio_track_get_duration(aubio_track_t* track)
+ {
+ int time = 0;
+ aubio_midi_event_t* evt = track->first;
+ while (evt != NULL) {
+ time += evt->dtime;
+ evt = evt->next;
+ }
+ return time;
+}
+
+/** aubio_track_count_events */
+int aubio_track_count_events(aubio_track_t* track, int* on, int* off)
+{
+ aubio_midi_event_t* evt = track->first;
+ while (evt != NULL) {
+ if (evt->type == NOTE_ON) {
+ (*on)++;
+ } else if (evt->type == NOTE_OFF) {
+ (*off)++;
+ }
+ evt = evt->next;
+ }
+ return AUBIO_OK;
+}
+
+/*
+ * aubio_track_add_event
+ */
+int aubio_track_add_event(aubio_track_t* track, aubio_midi_event_t* evt)
+{
+ evt->next = NULL;
+ if (track->first == NULL) {
+ track->first = evt;
+ track->cur = evt;
+ track->last = evt;
+ } else {
+ track->last->next = evt;
+ track->last = evt;
+ }
+ return AUBIO_OK;
+}
+
+/*
+ * aubio_track_first_event
+ */
+aubio_midi_event_t* aubio_track_first_event(aubio_track_t* track)
+{
+ track->cur = track->first;
+ return track->cur;
+}
+
+/*
+ * aubio_track_next_event
+ */
+aubio_midi_event_t* aubio_track_next_event(aubio_track_t* track)
+{
+ if (track->cur != NULL) {
+ track->cur = track->cur->next;
+ }
+ return track->cur;
+}
+
+/*
+ * aubio_track_reset
+ */
+ int
+aubio_track_reset(aubio_track_t* track)
+{
+ track->ticks = 0;
+ track->cur = track->first;
+ return AUBIO_OK;
+}
+
--- /dev/null
+++ b/ext/midi/midi_track.h
@@ -1,0 +1,67 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+#ifndef _AUBIO_MIDI_TRACK_H
+#define _AUBIO_MIDI_TRACK_H
+
+/** \file
+ * midi track structure
+ *
+ * \bug need public declaration ?
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** aubio_track_t */
+struct _aubio_track_t {
+ char* name;
+ int num;
+ aubio_midi_event_t *first;
+ aubio_midi_event_t *cur;
+ aubio_midi_event_t *last;
+ unsigned int ticks;
+};
+
+typedef struct _aubio_track_t aubio_track_t;
+
+aubio_track_t* new_aubio_track(int num);
+int del_aubio_track(aubio_track_t* track);
+int aubio_track_set_name(aubio_track_t* track, char* name);
+char* aubio_track_get_name(aubio_track_t* track);
+int aubio_track_add_event(aubio_track_t* track, aubio_midi_event_t* evt);
+aubio_midi_event_t* aubio_track_first_event(aubio_track_t* track);
+aubio_midi_event_t* aubio_track_next_event(aubio_track_t* track);
+int aubio_track_get_duration(aubio_track_t* track);
+int aubio_track_reset(aubio_track_t* track);
+int aubio_track_count_events(aubio_track_t* track, int* on, int* off);
+
+
+#define aubio_track_eot(track) ((track)->cur == NULL)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_AUBIO_MIDI_TRACK_H*/
--- /dev/null
+++ b/ext/midi/timer.c
@@ -1,0 +1,551 @@
+/*
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+/* this file originally taken from FluidSynth - A Software Synthesizer
+ * Copyright (C) 2003 Peter Hanappe and others.
+ */
+
+#include "aubio_priv.h"
+#include "timer.h"
+
+#if defined(WIN32)
+
+/*=============================================================*/
+/* */
+/* Win32 */
+/* */
+/*=============================================================*/
+
+/***************************************************************
+ *
+ * Timer
+ *
+ */
+#include <windef.h>
+
+#if 0
+#include <winbase.h>
+
+struct _aubio_timer_t
+{
+ long msec;
+ aubio_timer_callback_t callback;
+ void* data;
+ HANDLE thread;
+ DWORD thread_id;
+ int cont;
+ int auto_destroy;
+};
+
+static int aubio_timer_count = 0;
+DWORD WINAPI aubio_timer_run(LPVOID data);
+
+aubio_timer_t*
+new_aubio_timer(int msec, aubio_timer_callback_t callback, void* data,
+ int new_thread, int auto_destroy)
+{
+ aubio_timer_t* timer = AUBIO_NEW(aubio_timer_t);
+ if (timer == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return NULL;
+ }
+
+ timer->cont = 1;
+ timer->msec = msec;
+ timer->callback = callback;
+ timer->data = data;
+ timer->thread = 0;
+ timer->auto_destroy = auto_destroy;
+
+ if (new_thread) {
+ timer->thread = CreateThread(NULL, 0, aubio_timer_run, (LPVOID) timer, 0, &timer->thread_id);
+ if (timer->thread == NULL) {
+ AUBIO_ERR( "Couldn't create timer thread");
+ AUBIO_FREE(timer);
+ return NULL;
+ }
+ SetThreadPriority(timer->thread, THREAD_PRIORITY_TIME_CRITICAL);
+ } else {
+ aubio_timer_run((LPVOID) timer);
+ }
+ return timer;
+}
+
+DWORD WINAPI
+aubio_timer_run(LPVOID data)
+{
+ int count = 0;
+ int cont = 1;
+ long start;
+ long delay;
+ aubio_timer_t* timer;
+ timer = (aubio_timer_t*) data;
+
+ if ((timer == NULL) || (timer->callback == NULL)) {
+ return 0;
+ }
+
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+
+ /* keep track of the start time for absolute positioning */
+ start = aubio_curtime();
+
+ while (cont) {
+
+ /* do whatever we have to do */
+ cont = (*timer->callback)(timer->data, aubio_curtime() - start);
+
+ count++;
+
+ /* to avoid incremental time errors, I calculate the delay between
+ two callbacks bringing in the "absolute" time (count *
+ timer->msec) */
+ delay = (count * timer->msec) - (aubio_curtime() - start);
+ if (delay > 0) {
+ Sleep(delay);
+ }
+
+ cont &= timer->cont;
+ }
+
+ AUBIO_DBG( "Timer thread finished");
+
+ if (timer->auto_destroy) {
+ AUBIO_FREE(timer);
+ }
+
+ ExitThread(0);
+ return 0;
+}
+
+int
+delete_aubio_timer(aubio_timer_t* timer)
+{
+ timer->cont = 0;
+ aubio_timer_join(timer);
+ AUBIO_FREE(timer);
+ return AUBIO_OK;
+}
+
+int
+aubio_timer_join(aubio_timer_t* timer)
+{
+ DWORD wait_result;
+ if (timer->thread == 0) {
+ return AUBIO_OK;
+ }
+ wait_result = WaitForSingleObject(timer->thread, INFINITE);
+ return (wait_result == WAIT_OBJECT_0)? AUBIO_OK : AUBIO_FAIL;
+}
+/***************************************************************
+ *
+ * Time
+ */
+
+double rdtsc(void);
+double aubio_estimate_cpu_frequency(void);
+
+static double aubio_cpu_frequency = -1.0;
+
+void aubio_time_config(void)
+{
+ if (aubio_cpu_frequency < 0.0) {
+ aubio_cpu_frequency = aubio_estimate_cpu_frequency() / 1000000.0;
+ }
+}
+
+double aubio_utime(void)
+{
+ return (rdtsc() / aubio_cpu_frequency);
+}
+
+double rdtsc(void)
+{
+ LARGE_INTEGER t;
+ QueryPerformanceCounter(&t);
+ return (double) t.QuadPart;
+}
+
+double aubio_estimate_cpu_frequency(void)
+{
+#if 0
+ LONGLONG start, stop, ticks;
+ unsigned int before, after, delta;
+ double freq;
+
+ start = rdtsc();
+ stop = start;
+ before = aubio_curtime();
+ after = before;
+
+ while (1) {
+ if (after - before > 1000) {
+ break;
+ }
+ after = aubio_curtime();
+ stop = rdtsc();
+ }
+
+ delta = after - before;
+ ticks = stop - start;
+
+ freq = 1000 * ticks / delta;
+
+ return freq;
+
+#else
+ unsigned int before, after;
+ LARGE_INTEGER start, stop;
+
+ before = aubio_curtime();
+ QueryPerformanceCounter(&start);
+
+ Sleep(1000);
+
+ after = aubio_curtime();
+ QueryPerformanceCounter(&stop);
+
+ return (double) 1000 * (stop.QuadPart - start.QuadPart) / (after - before);
+#endif
+}
+
+#endif
+
+
+#elif defined(MACOS9)
+/*=============================================================*/
+/* */
+/* MacOS 9 */
+/* */
+/*=============================================================*/
+
+
+/***************************************************************
+ *
+ * Timer
+ */
+
+struct _aubio_timer_t
+{
+ TMTask myTmTask;
+ long msec;
+ unsigned int start;
+ unsigned int count;
+ int isInstalled;
+ aubio_timer_callback_t callback;
+ void* data;
+ int auto_destroy;
+};
+
+static TimerUPP myTimerUPP;
+
+void
+_timerCallback(aubio_timer_t *timer)
+{
+ int cont;
+ cont = (*timer->callback)(timer->data, aubio_curtime() - timer->start);
+ if (cont) {
+ PrimeTime((QElemPtr)timer, timer->msec);
+ } else {
+ timer->isInstalled = 0;
+ }
+ timer->count++;
+}
+
+aubio_timer_t*
+new_aubio_timer(int msec, aubio_timer_callback_t callback, void* data,
+ int new_thread, int auto_destroy)
+{
+ aubio_timer_t* timer = AUBIO_NEW(aubio_timer_t);
+ if (timer == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return NULL;
+ }
+
+ if (!myTimerUPP)
+ myTimerUPP = NewTimerProc(_timerCallback);
+
+ /* setup tmtask */
+ timer->myTmTask.tmAddr = myTimerUPP;
+ timer->myTmTask.qLink = NULL;
+ timer->myTmTask.qType = 0;
+ timer->myTmTask.tmCount = 0L;
+ timer->myTmTask.tmWakeUp = 0L;
+ timer->myTmTask.tmReserved = 0L;
+
+ timer->callback = callback;
+
+ timer->msec = msec;
+ timer->data = data;
+ timer->start = aubio_curtime();
+ timer->isInstalled = 1;
+ timer->count = 0;
+ timer->auto_destroy = auto_destroy;
+
+ InsXTime((QElemPtr)timer);
+ PrimeTime((QElemPtr)timer, msec);
+
+ return timer;
+}
+
+int
+delete_aubio_timer(aubio_timer_t* timer)
+{
+ if (timer->isInstalled) {
+ RmvTime((QElemPtr)timer);
+ }
+ AUBIO_FREE(timer);
+ return AUBIO_OK;
+}
+
+int
+aubio_timer_join(aubio_timer_t* timer)
+{
+ if (timer->isInstalled) {
+ int count = timer->count;
+ /* wait until count has incremented */
+ while (count == timer->count) {}
+ }
+ return AUBIO_OK;
+}
+
+/***************************************************************
+ *
+ * Time
+ */
+#define kTwoPower32 (4294967296.0) /* 2^32 */
+
+void aubio_time_config(void)
+{
+}
+
+unsigned int aubio_curtime()
+{
+ /* could be optimized by not going though a double */
+ UnsignedWide uS;
+ double mSf;
+ unsigned int ms;
+
+ Microseconds(&uS);
+
+ mSf = ((((double) uS.hi) * kTwoPower32) + uS.lo)/1000.0f;
+
+ ms = mSf;
+
+ return (ms);
+}
+
+
+
+#else
+
+/*=============================================================*/
+/* */
+/* POSIX */
+/* */
+/*=============================================================*/
+
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+
+/***************************************************************
+ *
+ * Timer
+ */
+
+struct _aubio_timer_t
+{
+ long msec;
+ aubio_timer_callback_t callback;
+ void* data;
+ pthread_t thread;
+ int cont;
+ int auto_destroy;
+};
+
+void*
+aubio_timer_start(void *data)
+{
+ int count = 0;
+ int cont = 1;
+ long start;
+ long delay;
+ aubio_timer_t* timer;
+ timer = (aubio_timer_t*) data;
+
+ /* keep track of the start time for absolute positioning */
+ start = aubio_curtime();
+
+ while (cont) {
+
+ /* do whatever we have to do */
+ cont = (*timer->callback)(timer->data, aubio_curtime() - start);
+
+ count++;
+
+ /* to avoid incremental time errors, calculate the delay between
+ two callbacks bringing in the "absolute" time (count *
+ timer->msec) */
+ delay = (count * timer->msec) - (aubio_curtime() - start);
+ if (delay > 0) {
+ usleep(delay * 1000);
+ }
+
+ cont &= timer->cont;
+ }
+
+ AUBIO_DBG( "Timer thread finished");
+ if (timer->thread != 0) {
+ pthread_exit(NULL);
+ }
+
+ if (timer->auto_destroy) {
+ AUBIO_FREE(timer);
+ }
+
+ return NULL;
+}
+
+aubio_timer_t*
+new_aubio_timer(int msec, aubio_timer_callback_t callback, void* data,
+ int new_thread, int auto_destroy)
+{
+ aubio_timer_t* timer = AUBIO_NEW(aubio_timer_t);
+ if (timer == NULL) {
+ AUBIO_ERR( "Out of memory");
+ return NULL;
+ }
+ timer->msec = msec;
+ timer->callback = callback;
+ timer->data = data;
+ timer->cont = 1;
+ timer->thread = 0;
+ timer->auto_destroy = auto_destroy;
+
+ if (new_thread) {
+ if (pthread_create(&timer->thread, NULL, aubio_timer_start, (void*) timer)) {
+ AUBIO_ERR( "Failed to create the timer thread");
+ AUBIO_FREE(timer);
+ return NULL;
+ }
+ } else {
+ aubio_timer_start((void*) timer);
+ }
+ return timer;
+}
+
+int
+delete_aubio_timer(aubio_timer_t* timer)
+{
+ timer->cont = 0;
+ aubio_timer_join(timer);
+ AUBIO_DBG( "Deleted player thread\n");
+ AUBIO_FREE(timer);
+ return AUBIO_OK;
+}
+
+int
+aubio_timer_join(aubio_timer_t* timer)
+{
+ int err = 0;
+
+ if (timer->thread != 0) {
+ err = pthread_join(timer->thread, NULL);
+ } else
+ AUBIO_DBG( "Joined player thread\n");
+ return (err == 0)? AUBIO_OK : AUBIO_FAIL;
+}
+
+
+/***************************************************************
+ *
+ * Time
+ */
+
+static double aubio_cpu_frequency = -1.0;
+
+double rdtsc(void);
+double aubio_estimate_cpu_frequency(void);
+
+void aubio_time_config(void)
+{
+ if (aubio_cpu_frequency < 0.0) {
+ aubio_cpu_frequency = aubio_estimate_cpu_frequency() / 1000000.0;
+ }
+}
+
+unsigned int aubio_curtime()
+{
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ return now.tv_sec * 1000 + now.tv_usec / 1000;
+}
+
+double aubio_utime(void)
+{
+ return (rdtsc() / aubio_cpu_frequency);
+}
+
+#if !defined(__i386__)
+
+double rdtsc(void)
+{
+ return 0.0;
+}
+
+double aubio_estimate_cpu_frequency(void)
+{
+ return 1.0;
+}
+
+#else
+
+double rdtsc(void)
+{
+ unsigned int a, b;
+
+ __asm__ ("rdtsc" : "=a" (a), "=d" (b));
+ return (double)b * (double)0x10000 * (double)0x10000 + a;
+}
+
+double aubio_estimate_cpu_frequency(void)
+{
+ double start, stop;
+ unsigned int a0, b0, a1, b1;
+ unsigned int before, after;
+
+ before = aubio_curtime();
+ __asm__ ("rdtsc" : "=a" (a0), "=d" (b0));
+
+ sleep(1);
+
+ after = aubio_curtime();
+ __asm__ ("rdtsc" : "=a" (a1), "=d" (b1));
+
+
+ start = (double)b0 * (double)0x10000 * (double)0x10000 + a0;
+ stop = (double)b1 * (double)0x10000 * (double)0x10000 + a1;
+
+ return 1000 * (stop - start) / (after - before);
+}
+
+#endif
+
+#endif
--- /dev/null
+++ b/ext/midi/timer.h
@@ -1,0 +1,34 @@
+
+#if defined(WIN32)
+#define aubio_curtime() GetTickCount()
+
+double aubio_utime(void);
+
+#elif defined(MACOS9)
+#include <OSUtils.h>
+#include <Timer.h>
+
+unsigned int aubio_curtime();
+#define aubio_utime() 0.0
+
+#else
+
+unsigned int aubio_curtime(void);
+double aubio_utime(void);
+
+#endif
+
+/* if the callback function returns 1 the timer will continue; if it
+ returns 0 it will stop */
+typedef int (*aubio_timer_callback_t)(void* data, unsigned int msec);
+
+typedef struct _aubio_timer_t aubio_timer_t;
+
+aubio_timer_t* new_aubio_timer(int msec, aubio_timer_callback_t callback,
+ void* data, int new_thread, int auto_destroy);
+
+int delete_aubio_timer(aubio_timer_t* timer);
+int aubio_timer_join(aubio_timer_t* timer);
+int aubio_timer_stop(aubio_timer_t* timer);
+void * aubio_timer_start(void * data);
+void aubio_time_config(void);
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,16 +19,7 @@
pitchdetection.h \
pitchmcomb.h \
pitchyin.h \
- filter.h \
- midi.h \
- list.h \
- timer.h \
- midi_file.h \
- midi_driver.h \
- midi_event.h \
- midi_track.h \
- midi_player.h \
- midi_parser.h
+ filter.h
lib_LTLIBRARIES = libaubio.la
libaubio_la_SOURCES = aubio.h \
@@ -66,27 +57,7 @@
pitchyin.c \
pitchyin.h \
filter.c \
- filter.h \
- midi.c \
- midi.h \
- list.c \
- list.h \
- timer.c \
- timer.h \
- midi_alsa_seq.c \
- midi_alsa_raw.c \
- midi_file.c \
- midi_file.h \
- midi_event.c \
- midi_event.h \
- midi_track.c \
- midi_track.h \
- midi_player.c \
- midi_player.h \
- midi_parser.c \
- midi_parser.h \
- midi_driver.h \
- midi_driver.c
+ filter.h
-AM_CFLAGS = @SNDLIB_CFLAGS@ @JACK_CFLAGS@ @FFTWLIB_CFLAGS@ @SAMPLERATE_CFLAGS@ @ALSA_CFLAGS@ @LADCCA_CFLAGS@
-libaubio_la_LIBADD = @SNDLIB_LIBS@ @JACK_LIBS@ @FFTWLIB_LIBS@ @SAMPLERATE_LIBS@ @ALSA_LIBS@ @LADCCA_LIBS@ @LTLIBOBJS@
+AM_CFLAGS = @SNDLIB_CFLAGS@ @JACK_CFLAGS@ @FFTWLIB_CFLAGS@ @SAMPLERATE_CFLAGS@ @LADCCA_CFLAGS@
+libaubio_la_LIBADD = @SNDLIB_LIBS@ @JACK_LIBS@ @FFTWLIB_LIBS@ @SAMPLERATE_LIBS@ @LADCCA_LIBS@ @LTLIBOBJS@
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -172,16 +172,7 @@
pitchdetection.h \
pitchmcomb.h \
pitchyin.h \
- filter.h \
- midi.h \
- list.h \
- timer.h \
- midi_file.h \
- midi_driver.h \
- midi_event.h \
- midi_track.h \
- midi_player.h \
- midi_parser.h
+ filter.h
lib_LTLIBRARIES = libaubio.la
@@ -220,31 +211,11 @@
pitchyin.c \
pitchyin.h \
filter.c \
- filter.h \
- midi.c \
- midi.h \
- list.c \
- list.h \
- timer.c \
- timer.h \
- midi_alsa_seq.c \
- midi_alsa_raw.c \
- midi_file.c \
- midi_file.h \
- midi_event.c \
- midi_event.h \
- midi_track.c \
- midi_track.h \
- midi_player.c \
- midi_player.h \
- midi_parser.c \
- midi_parser.h \
- midi_driver.h \
- midi_driver.c
+ filter.h
-AM_CFLAGS = @SNDLIB_CFLAGS@ @JACK_CFLAGS@ @FFTWLIB_CFLAGS@ @SAMPLERATE_CFLAGS@ @ALSA_CFLAGS@ @LADCCA_CFLAGS@
-libaubio_la_LIBADD = @SNDLIB_LIBS@ @JACK_LIBS@ @FFTWLIB_LIBS@ @SAMPLERATE_LIBS@ @ALSA_LIBS@ @LADCCA_LIBS@ @LTLIBOBJS@
+AM_CFLAGS = @SNDLIB_CFLAGS@ @JACK_CFLAGS@ @FFTWLIB_CFLAGS@ @SAMPLERATE_CFLAGS@ @LADCCA_CFLAGS@
+libaubio_la_LIBADD = @SNDLIB_LIBS@ @JACK_LIBS@ @FFTWLIB_LIBS@ @SAMPLERATE_LIBS@ @LADCCA_LIBS@ @LTLIBOBJS@
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -257,9 +228,7 @@
am_libaubio_la_OBJECTS = jackio.lo phasevoc.lo sndfileio.lo mathutils.lo \
fft.lo sample.lo hist.lo scale.lo resample.lo onsetdetection.lo \
tss.lo peakpick.lo biquad.lo pitchdetection.lo pitchmcomb.lo \
- pitchyin.lo filter.lo midi.lo list.lo timer.lo midi_alsa_seq.lo \
- midi_alsa_raw.lo midi_file.lo midi_event.lo midi_track.lo \
- midi_player.lo midi_parser.lo midi_driver.lo
+ pitchyin.lo filter.lo
libaubio_la_OBJECTS = $(am_libaubio_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
@@ -267,16 +236,7 @@
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/biquad.Plo ./$(DEPDIR)/fft.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/filter.Plo ./$(DEPDIR)/hist.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/jackio.Plo ./$(DEPDIR)/list.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/mathutils.Plo ./$(DEPDIR)/midi.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/midi_alsa_raw.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/midi_alsa_seq.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/midi_driver.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/midi_event.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/midi_file.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/midi_parser.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/midi_player.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/midi_track.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/jackio.Plo ./$(DEPDIR)/mathutils.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/onsetdetection.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/peakpick.Plo ./$(DEPDIR)/phasevoc.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/pitchdetection.Plo \
@@ -283,7 +243,7 @@
@AMDEP_TRUE@ ./$(DEPDIR)/pitchmcomb.Plo ./$(DEPDIR)/pitchyin.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/resample.Plo ./$(DEPDIR)/sample.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/scale.Plo ./$(DEPDIR)/sndfileio.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/timer.Plo ./$(DEPDIR)/tss.Plo
+@AMDEP_TRUE@ ./$(DEPDIR)/tss.Plo
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
@@ -367,17 +327,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jackio.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mathutils.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi_alsa_raw.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi_alsa_seq.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi_driver.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi_event.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi_file.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi_parser.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi_player.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi_track.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onsetdetection.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peakpick.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phasevoc.Plo@am__quote@
@@ -388,7 +338,6 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sample.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scale.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sndfileio.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tss.Plo@am__quote@
.c.o:
--- a/src/aubio.h
+++ b/src/aubio.h
@@ -19,46 +19,16 @@
/** @mainpage
*
- * \section whatis All starts here ...
+ * \section whatis Introduction
*
- * Aubio (note i need another name for this program) is a small library
- * for audio and control processing. The aim of this project is educative
- * (for me, and all the others who might want to use it). The main purpose of
- * aubio is to experiment with some bleeding-edge algorithms in a real time
- * context. This library targets at being light and portable, and relatively
- * fast.
+ * Aubio is a library for audio labelling: it provides function for pitch
+ * estimation and onset detection. See the README file for more
+ * information.
*
- * aubio is implemented as a library of C units and functions. You can create
- * all the C objects you need in your processing function, process those
- * objects from a main callback function, and delete them when done. This
- * simple but efficient way makes it easy to write a small wrapper, for
- * instance in the python language. (actually, GUIs should probably be build
- * with python itself). Writing LADSPA, jmax, pd, or any other like audio
- * plugins should be feasible too.
- *
- * Aubio provides various tools, some of them are listed below. I added the
- * names of the original authors and references to corresponding articles
- * are in the corresponding source file.
- *
- * - various maths tools
- * - phase vocoder
- * - up/downsampling
- * - filtering (n pole/zero pairs)
- * - onset detection functions
- * - onset peak picking
- * - multicomb-filtering pitch detection
- * - transient/steady-state separation
- * - audio and midi devices abstractions (callback)
- * - audio and midi files abstractions (various access modes)
- *
- * The midi support is kindly borrowed from the powerful Fluidsynth, written
- * by Peter Hanappe.
- *
- * See the README file for more information.
- *
* \section bugs bugs and todo
*
- * This software is under development. It needs debugging and optimisations.
+ * This software is under development. It needs debugging and
+ * optimisations.
*
* See <a href='bug.html'>bugs</a> and <a href='todo.html'>todo</a> lists.
*
@@ -108,14 +78,6 @@
#include "pitchdetection.h"
#include "pitchmcomb.h"
#include "pitchyin.h"
-
-#include "midi.h"
-#include "midi_event.h"
-#include "midi_track.h"
-#include "midi_player.h"
-#include "midi_parser.h"
-#include "midi_file.h"
-#include "midi_driver.h"
#ifdef __cplusplus
} /* extern "C" */
--- a/src/list.c
+++ /dev/null
@@ -1,256 +1,0 @@
-/* GLIB - Library of useful routines for C programming
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* Modified by the GLib Team and others 1997-1999. See the AUTHORS
- * file for a list of people on the GLib Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GLib at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#include "aubio_priv.h"
-#include "list.h"
-
-
-
-aubio_list_t*
-new_aubio_list(void)
-{
- aubio_list_t* list;
- list = AUBIO_NEW(aubio_list_t);
- list->data = NULL;
- list->next = NULL;
- return list;
-}
-
-void
-del_aubio_list(aubio_list_t *list)
-{
- aubio_list_t *next;
- while (list) {
- next = list->next;
- AUBIO_FREE(list);
- list = next;
- }
-}
-
-void
-del_aubio_list1(aubio_list_t *list)
-{
- if (list) {
- AUBIO_FREE(list);
- }
-}
-
-aubio_list_t*
-aubio_list_append(aubio_list_t *list, void* data)
-{
- aubio_list_t *new_list;
- aubio_list_t *last;
-
- new_list = new_aubio_list();
- new_list->data = data;
-
- if (list)
- {
- last = aubio_list_last(list);
- /* g_assert (last != NULL); */
- last->next = new_list;
-
- return list;
- }
- else
- return new_list;
-}
-
-aubio_list_t*
-aubio_list_prepend(aubio_list_t *list, void* data)
-{
- aubio_list_t *new_list;
-
- new_list = new_aubio_list();
- new_list->data = data;
- new_list->next = list;
-
- return new_list;
-}
-
-aubio_list_t*
-aubio_list_nth(aubio_list_t *list, int n)
-{
- while ((n-- > 0) && list) {
- list = list->next;
- }
-
- return list;
-}
-
-aubio_list_t*
-aubio_list_remove(aubio_list_t *list, void* data)
-{
- aubio_list_t *tmp;
- aubio_list_t *prev;
-
- prev = NULL;
- tmp = list;
-
- while (tmp) {
- if (tmp->data == data) {
- if (prev) {
- prev->next = tmp->next;
- }
- if (list == tmp) {
- list = list->next;
- }
- tmp->next = NULL;
- del_aubio_list(tmp);
-
- break;
- }
-
- prev = tmp;
- tmp = tmp->next;
- }
-
- return list;
-}
-
-aubio_list_t*
-aubio_list_remove_link(aubio_list_t *list, aubio_list_t *link)
-{
- aubio_list_t *tmp;
- aubio_list_t *prev;
-
- prev = NULL;
- tmp = list;
-
- while (tmp) {
- if (tmp == link) {
- if (prev) {
- prev->next = tmp->next;
- }
- if (list == tmp) {
- list = list->next;
- }
- tmp->next = NULL;
- break;
- }
-
- prev = tmp;
- tmp = tmp->next;
- }
-
- return list;
-}
-
-static aubio_list_t*
-aubio_list_sort_merge(aubio_list_t *l1, aubio_list_t *l2, aubio_compare_func_t compare_func)
-{
- aubio_list_t list, *l;
-
- l = &list;
-
- while (l1 && l2) {
- if (compare_func(l1->data,l2->data) < 0) {
- l = l->next = l1;
- l1 = l1->next;
- } else {
- l = l->next = l2;
- l2 = l2->next;
- }
- }
- l->next= l1 ? l1 : l2;
-
- return list.next;
-}
-
-aubio_list_t*
-aubio_list_sort(aubio_list_t *list, aubio_compare_func_t compare_func)
-{
- aubio_list_t *l1, *l2;
-
- if (!list) {
- return NULL;
- }
- if (!list->next) {
- return list;
- }
-
- l1 = list;
- l2 = list->next;
-
- while ((l2 = l2->next) != NULL) {
- if ((l2 = l2->next) == NULL)
- break;
- l1=l1->next;
- }
- l2 = l1->next;
- l1->next = NULL;
-
- return aubio_list_sort_merge(aubio_list_sort(list, compare_func),
- aubio_list_sort(l2, compare_func),
- compare_func);
-}
-
-
-aubio_list_t*
-aubio_list_last(aubio_list_t *list)
-{
- if (list) {
- while (list->next)
- list = list->next;
- }
-
- return list;
-}
-
-int
-aubio_list_size(aubio_list_t *list)
-{
- int n = 0;
- while (list) {
- n++;
- list = list->next;
- }
- return n;
-}
-
-aubio_list_t* aubio_list_insert_at(aubio_list_t *list, int n, void* data)
-{
- aubio_list_t *new_list;
- aubio_list_t *cur;
- aubio_list_t *prev = NULL;
-
- new_list = new_aubio_list();
- new_list->data = data;
-
- cur = list;
- while ((n-- > 0) && cur) {
- prev = cur;
- cur = cur->next;
- }
-
- new_list->next = cur;
-
- if (prev) {
- prev->next = new_list;
- return list;
- } else {
- return new_list;
- }
-}
--- a/src/list.h
+++ /dev/null
@@ -1,63 +1,0 @@
-/* GLIB - Library of useful routines for C programming
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * \file
- * list of objects
- *
- * implement common list structure and its various functions
- *
- * adapted for audio by Paul Brossier
- *
- * Modified by the GLib Team and others 1997-1999. See the AUTHORS
- * file for a list of people on the GLib Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GLib at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#ifndef _AUBIO_LIST_H
-#define _AUBIO_LIST_H
-
-typedef struct _aubio_list_t aubio_list_t;
-
-struct _aubio_list_t
-{
- void* data;
- aubio_list_t *next;
-};
-
-typedef int (*aubio_compare_func_t)(void* a, void* b);
-
-aubio_list_t* new_aubio_list(void);
-void del_aubio_list(aubio_list_t *list);
-void del_aubio_list1(aubio_list_t *list);
-aubio_list_t* aubio_list_sort(aubio_list_t *list, aubio_compare_func_t compare_func);
-aubio_list_t* aubio_list_append(aubio_list_t *list, void* data);
-aubio_list_t* aubio_list_prepend(aubio_list_t *list, void* data);
-aubio_list_t* aubio_list_remove(aubio_list_t *list, void* data);
-aubio_list_t* aubio_list_remove_link(aubio_list_t *list, aubio_list_t *llink);
-aubio_list_t* aubio_list_nth(aubio_list_t *list, int n);
-aubio_list_t* aubio_list_last(aubio_list_t *list);
-aubio_list_t* aubio_list_insert_at(aubio_list_t *list, int n, void* data);
-int aubio_list_size(aubio_list_t *list);
-
-#define aubio_list_next(slist) ((slist) ? (((aubio_list_t *)(slist))->next) : NULL)
-#define aubio_list_get(slist) ((slist) ? ((slist)->data) : NULL)
-
-#endif /* _AUBIO_LIST_H */
--- a/src/midi.c
+++ /dev/null
@@ -1,32 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-#include "aubio_priv.h"
-#include "midi.h"
-#include "midi_event.h"
-#include "midi_track.h"
-#include "midi_player.h"
-
-/* all outgoing user messages are stored in a global text buffer */
-#define MIDI_MESSAGE_LENGTH 1024
-char midi_message_buffer[MIDI_MESSAGE_LENGTH];
-
--- a/src/midi.h
+++ /dev/null
@@ -1,190 +1,0 @@
-/*
- *
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from fluidsynth, peter hanappe and others,
- * adapted for aubio by paul brossier,
- */
-
-
-/** \file
- * midi header
- *
- * contains all (?) possible known midi messages.
- *
- * this file originally taken from fluidsynth, Peter Hanappe and others,
- * adapted for aubio by Paul Brossier,
- */
-
-#ifndef _AUBIO_MIDI_H
-#define _AUBIO_MIDI_H
-
-//typedef struct _aubio_midi_driver_t aubio_midi_driver_t;
-
-//int aubio_midi_send_event(aubio_synth_t* synth, aubio_player_t* player, aubio_midi_event_t* evt);
-
-//int aubio_midi_router_send_event(aubio_midi_router_t* router, aubio_midi_event_t* event);
-
-
-/***************************************************************
- *
- * CONSTANTS & ENUM
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum aubio_midi_event_type {
- /* channel messages */
- NOTE_OFF = 0x80,
- NOTE_ON = 0x90,
- KEY_PRESSURE = 0xa0,
- CONTROL_CHANGE = 0xb0,
- PROGRAM_CHANGE = 0xc0,
- CHANNEL_PRESSURE = 0xd0,
- PITCH_BEND = 0xe0,
- /* system exclusive */
- MIDI_SYSEX = 0xf0,
- /* system common - never in midi files */
- MIDI_TIME_CODE = 0xf1,
- MIDI_SONG_POSITION = 0xf2,
- MIDI_SONG_SELECT = 0xf3,
- MIDI_TUNE_REQUEST = 0xf6,
- MIDI_EOX = 0xf7,
- /* system real-time - never in midi files */
- MIDI_SYNC = 0xf8,
- MIDI_TICK = 0xf9,
- MIDI_START = 0xfa,
- MIDI_CONTINUE = 0xfb,
- MIDI_STOP = 0xfc,
- MIDI_ACTIVE_SENSING = 0xfe,
- MIDI_SYSTEM_RESET = 0xff,
- /* meta event - for midi files only */
- MIDI_META_EVENT = 0xff
-};
-
-enum aubio_midi_control_change {
- BANK_SELECT_MSB = 0x00,
- MODULATION_MSB = 0x01,
- BREATH_MSB = 0x02,
- FOOT_MSB = 0x04,
- PORTAMENTO_TIME_MSB = 0x05,
- DATA_ENTRY_MSB = 0x06,
- VOLUME_MSB = 0x07,
- BALANCE_MSB = 0x08,
- PAN_MSB = 0x0A,
- EXPRESSION_MSB = 0x0B,
- EFFECTS1_MSB = 0x0C,
- EFFECTS2_MSB = 0x0D,
- GPC1_MSB = 0x10, /* general purpose controller */
- GPC2_MSB = 0x11,
- GPC3_MSB = 0x12,
- GPC4_MSB = 0x13,
- BANK_SELECT_LSB = 0x20,
- MODULATION_WHEEL_LSB = 0x21,
- BREATH_LSB = 0x22,
- FOOT_LSB = 0x24,
- PORTAMENTO_TIME_LSB = 0x25,
- DATA_ENTRY_LSB = 0x26,
- VOLUME_LSB = 0x27,
- BALANCE_LSB = 0x28,
- PAN_LSB = 0x2A,
- EXPRESSION_LSB = 0x2B,
- EFFECTS1_LSB = 0x2C,
- EFFECTS2_LSB = 0x2D,
- GPC1_LSB = 0x30,
- GPC2_LSB = 0x31,
- GPC3_LSB = 0x32,
- GPC4_LSB = 0x33,
- SUSTAIN_SWITCH = 0x40,
- PORTAMENTO_SWITCH = 0x41,
- SOSTENUTO_SWITCH = 0x42,
- SOFT_PEDAL_SWITCH = 0x43,
- LEGATO_SWITCH = 0x45,
- HOLD2_SWITCH = 0x45,
- SOUND_CTRL1 = 0x46,
- SOUND_CTRL2 = 0x47,
- SOUND_CTRL3 = 0x48,
- SOUND_CTRL4 = 0x49,
- SOUND_CTRL5 = 0x4A,
- SOUND_CTRL6 = 0x4B,
- SOUND_CTRL7 = 0x4C,
- SOUND_CTRL8 = 0x4D,
- SOUND_CTRL9 = 0x4E,
- SOUND_CTRL10 = 0x4F,
- GPC5 = 0x50,
- GPC6 = 0x51,
- GPC7 = 0x52,
- GPC8 = 0x53,
- PORTAMENTO_CTRL = 0x54,
- EFFECTS_DEPTH1 = 0x5B,
- EFFECTS_DEPTH2 = 0x5C,
- EFFECTS_DEPTH3 = 0x5D,
- EFFECTS_DEPTH4 = 0x5E,
- EFFECTS_DEPTH5 = 0x5F,
- DATA_ENTRY_INCR = 0x60,
- DATA_ENTRY_DECR = 0x61,
- NRPN_LSB = 0x62,
- NRPN_MSB = 0x63,
- RPN_LSB = 0x64,
- RPN_MSB = 0x65,
- ALL_SOUND_OFF = 0x78,
- ALL_CTRL_OFF = 0x79,
- LOCAL_CONTROL = 0x7A,
- ALL_NOTES_OFF = 0x7B,
- OMNI_OFF = 0x7C,
- OMNI_ON = 0x7D,
- POLY_OFF = 0x7E,
- POLY_ON = 0x7F
-};
-
-enum midi_meta_event {
- MIDI_COPYRIGHT = 0x02,
- MIDI_TRACK_NAME = 0x03,
- MIDI_INST_NAME = 0x04,
- MIDI_LYRIC = 0x05,
- MIDI_MARKER = 0x06,
- MIDI_CUE_POINT = 0x07,
- MIDI_EOT = 0x2f,
- MIDI_SET_TEMPO = 0x51,
- MIDI_SMPTE_OFFSET = 0x54,
- MIDI_TIME_SIGNATURE = 0x58,
- MIDI_KEY_SIGNATURE = 0x59,
- MIDI_SEQUENCER_EVENT = 0x7f
-};
-
-enum aubio_player_status
-{
- AUBIO_MIDI_PLAYER_READY,
- AUBIO_MIDI_PLAYER_PLAYING,
- AUBIO_MIDI_PLAYER_DONE
-};
-
-enum aubio_driver_status
-{
- AUBIO_MIDI_READY,
- AUBIO_MIDI_LISTENING,
- AUBIO_MIDI_DONE
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _AUBIO_MIDI_H */
--- a/src/midi_alsa_raw.c
+++ /dev/null
@@ -1,308 +1,0 @@
-/*
- * Copyright 2004 Paul Brossier
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from Fluidsynth, Peter Hanappe and others. */
-
-/** \file
- * Midi driver for the Advanced Linux Sound Architecture
- */
-
-
-#include "aubio_priv.h"
-#include "midi.h"
-#include "midi_event.h"
-#include "midi_parser.h"
-#include "midi_driver.h"
-
-#if ALSA_SUPPORT
-
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#include <alsa/asoundlib.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/poll.h>
-/* #include <errno.h> //perror is in stdio.h */
-
-#include "config.h"
-
-#define AUBIO_ALSA_DEFAULT_MIDI_DEVICE "default"
-
-/** \bug double define? */
-#define AUBIO_ALSA_BUFFER_LENGTH 512
-
-/* SCHED_FIFO priorities for ALSA threads (see pthread_attr_setschedparam) */
-#define ALSA_RAWMIDI_SCHED_PRIORITY 90
-#define ALSA_SEQ_SCHED_PRIORITY 90
-
-/** aubio_midi_alsa_raw_driver_t */
-typedef struct {
- aubio_midi_driver_t driver;
- snd_rawmidi_t *rawmidi_in;
- snd_rawmidi_t *rawmidi_out;
- struct pollfd *pfd;
- int npfd;
- pthread_t thread;
- int status;
- unsigned char buffer[AUBIO_ALSA_BUFFER_LENGTH];
- aubio_midi_parser_t* parser;
-} aubio_midi_alsa_raw_driver_t;
-
-aubio_midi_driver_t* new_aubio_midi_alsa_raw_driver(//aubio_settings_t* settings,
- handle_midi_event_func_t handler,
- void* event_handler_data);
-int del_aubio_midi_alsa_raw_driver(aubio_midi_driver_t* p);
-static void* aubio_midi_alsa_raw_run(void* d);
-
-
-/**************************************************************
- *
- * Alsa MIDI driver
- *
- */
-
-//void aubio_midi_alsa_raw_driver_settings(aubio_settings_t* settings)
-//{
-// aubio_settings_register_str(settings, "midi.alsa.device", "default", 0, NULL, NULL);
-//}
-
-/** new_aubio_midi_alsa_raw_driver */
-aubio_midi_driver_t* new_aubio_midi_alsa_raw_driver(
- //aubio_settings_t* settings,
- handle_midi_event_func_t handler,
- void* data)
-{
- int i, err;
- aubio_midi_alsa_raw_driver_t* dev;
- pthread_attr_t attr;
- int sched = SCHED_FIFO;
- struct sched_param priority;
- int count;
- struct pollfd *pfd = NULL;
- char* device = NULL;
-
- /* not much use doing anything */
- if (handler == NULL) {
- AUBIO_ERR("Invalid argument");
- return NULL;
- }
-
- /* allocate the device */
- dev = AUBIO_NEW(aubio_midi_alsa_raw_driver_t);
- if (dev == NULL) {
- AUBIO_ERR( "Out of memory");
- return NULL;
- }
- AUBIO_MEMSET(dev, 0, sizeof(aubio_midi_alsa_raw_driver_t));
-
- dev->driver.handler = handler;
- dev->driver.data = data;
-
- /* allocate one event to store the input data */
- dev->parser = new_aubio_midi_parser();
- if (dev->parser == NULL) {
- AUBIO_ERR( "Out of memory");
- goto error_recovery;
- }
-
- /* get the device name. if none is specified, use the default device. */
- //aubio_settings_getstr(settings, "midi.alsa.device", &device);
- if (device == NULL) {
- device = "default";
- }
-
- /* open the hardware device. only use midi in. */
- if ((err = snd_rawmidi_open(&dev->rawmidi_in, NULL, device, SND_RAWMIDI_NONBLOCK)) < 0) {
- //if ((err = snd_rawmidi_open(&dev->rawmidi_in, &dev->rawmidi_out, device, SND_RAWMIDI_NONBLOCK)) < 0) {
- AUBIO_ERR( "Error opening ALSA raw MIDI IN port");
- goto error_recovery;
- }
-
- /* get # of MIDI file descriptors */
- count = snd_rawmidi_poll_descriptors_count(dev->rawmidi_in);
- if (count > 0) { /* make sure there are some */
- pfd = AUBIO_MALLOC(sizeof (struct pollfd) * count);
- dev->pfd = AUBIO_MALLOC(sizeof (struct pollfd) * count);
- /* grab file descriptor POLL info structures */
- count = snd_rawmidi_poll_descriptors(dev->rawmidi_in, pfd, count);
- }
-
- /* copy the input FDs */
- for (i = 0; i < count; i++) { /* loop over file descriptors */
- if (pfd[i].events & POLLIN) { /* use only the input FDs */
- dev->pfd[dev->npfd].fd = pfd[i].fd;
- dev->pfd[dev->npfd].events = POLLIN;
- dev->pfd[dev->npfd].revents = 0;
- dev->npfd++;
- }
- }
- AUBIO_FREE(pfd);
-
-
-
- dev->status = AUBIO_MIDI_READY;
-
- /* create the midi thread */
- if (pthread_attr_init(&attr)) {
- AUBIO_ERR( "Couldn't initialize midi thread attributes");
- goto error_recovery;
- }
-
- /* Was: "use fifo scheduling. if it fails, use default scheduling." */
- /* Now normal scheduling is used by default for the MIDI thread. The reason is,
- * that fluidsynth works better with low latencies under heavy load, if only the
- * audio thread is prioritized.
- * With MIDI at ordinary priority, that could result in individual notes being played
- * a bit late. On the other hand, if the audio thread is delayed, an audible dropout
- * is the result.
- * To reproduce this: Edirol UA-1 USB-MIDI interface, four buffers
- * with 45 samples each (roughly 4 ms latency), ravewave soundfont. -MN
- */
-
- /* Not so sure anymore. We're losing MIDI data, if we can't keep up with
- * the speed it is generated. */
- /* AUBIO_MSG("Note: High-priority scheduling for the MIDI thread was intentionally disabled.");
- sched=SCHED_OTHER;*/
-
- while (1) {
- err = pthread_attr_setschedpolicy(&attr, sched);
- if (err) {
- //AUBIO_LOG(AUBIO_WARN, "Couldn't set high priority scheduling for the MIDI input");
- AUBIO_MSG( "Couldn't set high priority scheduling for the MIDI input");
- if (sched == SCHED_FIFO) {
- sched = SCHED_OTHER;
- continue;
- } else {
- AUBIO_ERR( "Couldn't set scheduling policy.");
- goto error_recovery;
- }
- }
-
- /* SCHED_FIFO will not be active without setting the priority */
- priority.sched_priority = (sched == SCHED_FIFO) ?
- ALSA_RAWMIDI_SCHED_PRIORITY : 0;
- pthread_attr_setschedparam (&attr, &priority);
- err = pthread_create(&dev->thread, &attr, aubio_midi_alsa_raw_run, (void*) dev);
- if (err) {
- AUBIO_MSG( "Couldn't set high priority scheduling for the MIDI input");
- if (sched == SCHED_FIFO) {
- sched = SCHED_OTHER;
- continue;
- } else {
- AUBIO_ERR( "Couldn't create the midi thread.");
- goto error_recovery;
- }
- }
- break;
- }
- return (aubio_midi_driver_t*) dev;
-
-error_recovery:
- del_aubio_midi_alsa_raw_driver((aubio_midi_driver_t*) dev);
- return NULL;
-
-}
-
-/** del_aubio_midi_alsa_raw_driver */
-int del_aubio_midi_alsa_raw_driver(aubio_midi_driver_t* p)
-{
- aubio_midi_alsa_raw_driver_t* dev;
-
- dev = (aubio_midi_alsa_raw_driver_t*) p;
- if (dev == NULL) {
- return AUBIO_OK;
- }
-
- dev->status = AUBIO_MIDI_DONE;
-
- /* cancel the thread and wait for it before cleaning up */
- if (dev->thread) {
- if (pthread_cancel(dev->thread)) {
- AUBIO_ERR( "Failed to cancel the midi thread");
- return AUBIO_FAIL;
- }
- if (pthread_join(dev->thread, NULL)) {
- AUBIO_ERR( "Failed to join the midi thread");
- return AUBIO_FAIL;
- }
- }
- if (dev->rawmidi_in) {
- snd_rawmidi_drain(dev->rawmidi_in);
- snd_rawmidi_close(dev->rawmidi_in);
- }
- if (dev->rawmidi_out) {
- snd_rawmidi_drain(dev->rawmidi_out);
- snd_rawmidi_close(dev->rawmidi_in);
- }
- if (dev->parser != NULL) {
- del_aubio_midi_parser(dev->parser);
- }
- AUBIO_FREE(dev);
- return AUBIO_OK;
-}
-
-/** aubio_midi_alsa_raw_run */
-void * aubio_midi_alsa_raw_run(void* d)
-{
- int n, i;
- aubio_midi_event_t* evt;
- aubio_midi_alsa_raw_driver_t* dev = (aubio_midi_alsa_raw_driver_t*) d;
-
- /* make sure the other threads can cancel this thread any time */
- if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) {
- AUBIO_ERR( "Failed to set the cancel state of the midi thread");
- pthread_exit(NULL);
- }
- if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
- AUBIO_ERR( "Failed to set the cancel state of the midi thread");
- pthread_exit(NULL);
- }
-
- /* go into a loop until someone tells us to stop */
- dev->status = AUBIO_MIDI_LISTENING;
- while (dev->status == AUBIO_MIDI_LISTENING) {
-
- /* is there something to read? */
- /* use a 100 milliseconds timeout */
- n = poll(dev->pfd, dev->npfd, 100);
- if (n < 0) {
- perror("poll");
- } else if (n > 0) {
-
- /* read new data */
- n = snd_rawmidi_read(dev->rawmidi_in, dev->buffer,
- AUBIO_ALSA_BUFFER_LENGTH);
- if ((n < 0) && (n != -EAGAIN)) {
- AUBIO_ERR( "Failed to read the midi input");
- dev->status = AUBIO_MIDI_DONE;
- }
-
- /* let the parser convert the data into events */
- for (i = 0; i < n; i++) {
- evt = aubio_midi_parser_parse(dev->parser, dev->buffer[i]);
- if (evt != NULL) {
- (*dev->driver.handler)(dev->driver.data, evt);
- }
- }
- };
- }
- pthread_exit(NULL);
-}
-
-#endif /* #if ALSA_SUPPORT */
--- a/src/midi_alsa_seq.c
+++ /dev/null
@@ -1,419 +1,0 @@
-/*
- * Copyright 2004 Paul Brossier
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from Fluidsynth, Peter Hanappe and others. */
-
-/** \file
- * Midi driver for the Advanced Linux Sound Architecture (sequencer mode)
- */
-
-
-#include "aubio_priv.h"
-#include "midi.h"
-#include "midi_event.h"
-#include "midi_parser.h"
-#include "midi_driver.h"
-#include "config.h"
-
-#if ALSA_SUPPORT
-
-#define ALSA_PCM_NEW_HW_PARAMS_API
-#include <alsa/asoundlib.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/poll.h>
-/* #include <errno.h> //perror is in stdio.h */
-
-#define AUBIO_ALSA_DEFAULT_SEQ_DEVICE "default"
-
-#define AUBIO_ALSA_BUFFER_LENGTH 512
-
-/* SCHED_FIFO priorities for ALSA threads (see pthread_attr_setschedparam) */
-#define ALSA_RAWMIDI_SCHED_PRIORITY 90
-#define ALSA_SEQ_SCHED_PRIORITY 90
-
-
-/** aubio_alsa_seq_driver_t */
-typedef struct {
- aubio_midi_driver_t driver;
- snd_seq_t *seq_handle;
- int seq_port;
- struct pollfd *pfd;
- int npfd;
- pthread_t thread;
- int status;
-} aubio_alsa_seq_driver_t;
-
-aubio_midi_driver_t* new_aubio_alsa_seq_driver(//aubio_settings_t* settings,
- handle_midi_event_func_t handler,
- void* data);
-int del_aubio_alsa_seq_driver(aubio_midi_driver_t* p);
-static void* aubio_alsa_seq_run(void* d);
-
-//void aubio_alsa_seq_driver_settings(aubio_settings_t* settings)
-//{
-// aubio_settings_register_str(settings, "midi.alsa_seq.device", "default", 0, NULL, NULL);
-// aubio_settings_register_str(settings, "midi.alsa_seq.id", "pid", 0, NULL, NULL);
-//}
-
-/** new_aubio_alsa_seq_driver */
-aubio_midi_driver_t* new_aubio_alsa_seq_driver(//aubio_settings_t* settings,
- handle_midi_event_func_t handler, void* data)
-{
- int i, err;
- aubio_alsa_seq_driver_t* dev; /**< object to return */
- pthread_attr_t attr; /**< sequencer thread */
- int sched = SCHED_FIFO; /**< default scheduling policy */
- struct sched_param priority; /**< scheduling priority settings */
- int count; /**< number of MIDI file descriptors */
- struct pollfd *pfd = NULL; /**< poll file descriptor array (copied in dev->pfd) */
- char* device = NULL; /**< the device name */
- char* id = NULL;
- char full_id[64];
- char full_name[64];
-
- /* not much use doing anything */
- if (handler == NULL) {
- AUBIO_ERR( "Invalid argument");
- return NULL;
- }
-
- /* allocate the device */
- dev = AUBIO_NEW(aubio_alsa_seq_driver_t);
- if (dev == NULL) {
- AUBIO_ERR( "Out of memory");
- return NULL;
- }
- AUBIO_MEMSET(dev, 0, sizeof(aubio_alsa_seq_driver_t));
- dev->seq_port = -1;
- dev->driver.data = data;
- dev->driver.handler = handler;
-
- /* get the device name. if none is specified, use the default device. */
- //aubio_settings_getstr(settings, "midi.alsa_seq.device", &device);
- if (device == NULL) {
- device = "default";
- }
-
- /* open the sequencer INPUT only, non-blocking */
- //if ((err = snd_seq_open(&dev->seq_handle, device, SND_SEQ_OPEN_INPUT,
- if ((err = snd_seq_open(&dev->seq_handle, device, SND_SEQ_OPEN_DUPLEX,
- SND_SEQ_NONBLOCK)) < 0) {
- AUBIO_ERR( "Error opening ALSA sequencer");
- goto error_recovery;
- }
-
- /* tell the ladcca server our client id */
-#ifdef LADCCA_SUPPORT
- {
- int enable_ladcca = 1;
- //aubio_settings_getint (settings, "ladcca.enable", &enable_ladcca);
- if (enable_ladcca)
- cca_alsa_client_id (aubio_cca_client, snd_seq_client_id (dev->seq_handle));
- }
-#endif /* LADCCA_SUPPORT */
-
- /* get # of MIDI file descriptors */
- count = snd_seq_poll_descriptors_count(dev->seq_handle, POLLIN);
- if (count > 0) { /* make sure there are some */
- pfd = AUBIO_MALLOC(sizeof (struct pollfd) * count);
- dev->pfd = AUBIO_MALLOC(sizeof (struct pollfd) * count);
- /* grab file descriptor POLL info structures */
- count = snd_seq_poll_descriptors(dev->seq_handle, pfd, count, POLLIN);
- }
-
- for (i = 0; i < count; i++) { /* loop over file descriptors */
- /* copy the input FDs */
- if (pfd[i].events & POLLIN) { /* use only the input FDs */
- dev->pfd[dev->npfd].fd = pfd[i].fd;
- dev->pfd[dev->npfd].events = POLLIN;
- dev->pfd[dev->npfd].revents = 0;
- dev->npfd++;
- }
- }
- AUBIO_FREE(pfd);
-
- //aubio_settings_getstr(settings, "midi.alsa_seq.id", &id);
-
- if (id != NULL) {
- if (AUBIO_STRCMP(id, "pid") == 0) {
- snprintf(full_id, 64, "aubio (%d)", getpid());
- snprintf(full_name, 64, "aubio_port (%d)", getpid());
- } else {
- snprintf(full_id, 64, "aubio (%s)", id);
- snprintf(full_name, 64, "aubio_port (%s)", id);
- }
- } else {
- snprintf(full_id, 64, "aubio");
- snprintf(full_name, 64, "aubio_port");
- }
-
- /* set the client name */
- snd_seq_set_client_name (dev->seq_handle, full_id);
-
- if ((dev->seq_port = snd_seq_create_simple_port (dev->seq_handle,
- full_name,
- SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE |
- SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ |
- SND_SEQ_PORT_CAP_DUPLEX,
- SND_SEQ_PORT_TYPE_APPLICATION)) < 0)
- {
- AUBIO_ERR( "Error creating ALSA sequencer port");
- goto error_recovery;
- }
-
- dev->status = AUBIO_MIDI_READY;
-
- /* create the midi thread */
- if (pthread_attr_init(&attr)) {
- AUBIO_ERR( "Couldn't initialize midi thread attributes");
- goto error_recovery;
- }
-
- /* use fifo scheduling. if it fails, use default scheduling. */
- while (1) {
- err = pthread_attr_setschedpolicy(&attr, sched);
- if (err) {
- AUBIO_MSG( "Couldn't set high priority scheduling for the MIDI input");
- if (sched == SCHED_FIFO) {
- sched = SCHED_OTHER;
- continue;
- } else {
- AUBIO_ERR( "Couldn't set scheduling policy.");
- goto error_recovery;
- }
- }
-
- /* SCHED_FIFO will not be active without setting the priority */
- priority.sched_priority = (sched == SCHED_FIFO) ? ALSA_SEQ_SCHED_PRIORITY : 0;
- pthread_attr_setschedparam (&attr, &priority);
-
- err = pthread_create(&dev->thread, &attr, aubio_alsa_seq_run, (void*) dev);
- if (err) {
- AUBIO_ERR( "Couldn't set high priority scheduling for the MIDI input");
- if (sched == SCHED_FIFO) {
- sched = SCHED_OTHER;
- continue;
- } else {
- //AUBIO_LOG(AUBIO_PANIC, "Couldn't create the midi thread.");
- AUBIO_ERR( "Couldn't create the midi thread.");
- goto error_recovery;
- }
- }
- break;
- }
- return (aubio_midi_driver_t*) dev;
-
-
-error_recovery:
- del_aubio_alsa_seq_driver((aubio_midi_driver_t*) dev);
- return NULL;
-}
-
-/** del_aubio_alsa_seq_driver */
-int del_aubio_alsa_seq_driver(aubio_midi_driver_t* p)
-{
- aubio_alsa_seq_driver_t* dev;
-
- dev = (aubio_alsa_seq_driver_t*) p;
- if (dev == NULL) {
- return AUBIO_OK;
- }
-
- dev->status = AUBIO_MIDI_DONE;
-
- /* cancel the thread and wait for it before cleaning up */
- if (dev->thread) {
- if (pthread_cancel(dev->thread)) {
- AUBIO_ERR( "Failed to cancel the midi thread");
- return AUBIO_FAIL;
- }
- if (pthread_join(dev->thread, NULL)) {
- AUBIO_ERR( "Failed to join the midi thread");
- return AUBIO_FAIL;
- }
- }
- if (dev->seq_port >= 0) {
- snd_seq_delete_simple_port (dev->seq_handle, dev->seq_port);
- }
- if (dev->seq_handle) {
- snd_seq_drain_output(dev->seq_handle);
- snd_seq_close(dev->seq_handle);
- }
- AUBIO_FREE(dev);
- return AUBIO_OK;
-}
-
-/** aubio_alsa_seq_run */
-void* aubio_alsa_seq_run(void* d)
-{
- int n;//, i;
- snd_seq_event_t *seq_ev;
- aubio_midi_event_t evt;
- aubio_alsa_seq_driver_t* dev = (aubio_alsa_seq_driver_t*) d;
-
- /* make sure the other threads can cancel this thread any time */
- if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) {
- AUBIO_ERR( "Failed to set the cancel state of the midi thread");
- pthread_exit(NULL);
- }
- if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
- AUBIO_ERR( "Failed to set the cancel state of the midi thread");
- pthread_exit(NULL);
- }
-
- /* go into a loop until someone tells us to stop */
- dev->status = AUBIO_MIDI_LISTENING;
- while (dev->status == AUBIO_MIDI_LISTENING) {
-
- /* is there something to read? */
- n = poll(dev->pfd, dev->npfd, 1); /* use a 1 milliseconds timeout */
- if (n < 0) {
- perror("poll");
- } else if (n > 0) {
-
- /* read new events from the midi input port */
- while ((n = snd_seq_event_input(dev->seq_handle, &seq_ev)) >= 0)
- {
- switch (seq_ev->type)
- {
- case SND_SEQ_EVENT_NOTEON:
- evt.type = NOTE_ON;
- evt.channel = seq_ev->data.note.channel;
- evt.param1 = seq_ev->data.note.note;
- evt.param2 = seq_ev->data.note.velocity;
- break;
- case SND_SEQ_EVENT_NOTEOFF:
- evt.type = NOTE_OFF;
- evt.channel = seq_ev->data.note.channel;
- evt.param1 = seq_ev->data.note.note;
- evt.param2 = seq_ev->data.note.velocity;
- break;
- case SND_SEQ_EVENT_KEYPRESS:
- evt.type = KEY_PRESSURE;
- evt.channel = seq_ev->data.note.channel;
- evt.param1 = seq_ev->data.note.note;
- evt.param2 = seq_ev->data.note.velocity;
- break;
- case SND_SEQ_EVENT_CONTROLLER:
- evt.type = CONTROL_CHANGE;
- evt.channel = seq_ev->data.control.channel;
- evt.param1 = seq_ev->data.control.param;
- evt.param2 = seq_ev->data.control.value;
- break;
- case SND_SEQ_EVENT_PITCHBEND:
- evt.type = PITCH_BEND;
- evt.channel = seq_ev->data.control.channel;
- /* ALSA pitch bend is -8192 - 8191, we adjust it here */
- evt.param1 = seq_ev->data.control.value + 8192;
- break;
- case SND_SEQ_EVENT_PGMCHANGE:
- evt.type = PROGRAM_CHANGE;
- evt.channel = seq_ev->data.control.channel;
- evt.param1 = seq_ev->data.control.value;
- break;
- case SND_SEQ_EVENT_CHANPRESS:
- evt.type = CHANNEL_PRESSURE;
- evt.channel = seq_ev->data.control.channel;
- evt.param1 = seq_ev->data.control.value;
- break;
- default:
- continue; /* unhandled event, next loop iteration */
- }
-
- /* send the events to the next link in the chain */
- (*dev->driver.handler)(dev->driver.data, &evt);
-
- /* dump input on output */
- //snd_seq_ev_set_source(new_ev, dev->seq_port);
- //snd_seq_ev_set_dest(seq_ev,dev->seq_handle,dev->seq_client);
- //snd_seq_ev_set_subs(new_ev);
- //snd_seq_ev_set_direct(new_ev);
- //snd_seq_event_output(dev->seq_handle, new_ev);
- //snd_seq_drain_output(dev->seq_handle);
-
- }
- }
-
- if ((n < 0) && (n != -EAGAIN)) {
- AUBIO_ERR( "Error occured while reading ALSA sequencer events");
- dev->status = AUBIO_MIDI_DONE;
- }
-
-// /* added by piem to handle new data to output */
-// while (/* get new data, but from where ??? (n = snd_seq_event_output(dev->seq_handle, seq_ev)) >= 0*/ )
-// {
-// /* dump input on output */
-// snd_seq_ev_set_source(new_ev, dev->seq_port);
-// //snd_seq_ev_set_dest(seq_ev,dev->seq_handle,dev->seq_client);
-// snd_seq_ev_set_subs(new_ev);
-// snd_seq_ev_set_direct(new_ev);
-// snd_seq_event_output(dev->seq_handle, new_ev);
-// snd_seq_drain_output(dev->seq_handle);
-// }
-
- }
- pthread_exit(NULL);
-}
-
-
-snd_seq_event_t ev;
-
-void aubio_midi_direct_output(aubio_midi_driver_t * d, aubio_midi_event_t * event)
-{
- aubio_alsa_seq_driver_t* dev = (aubio_alsa_seq_driver_t*) d;
- /*
- if (pthread_join(dev->thread, NULL)) {
- AUBIO_ERR( "Failed to join the midi thread");
- }
- */
- switch(event->type)
- {
- case NOTE_ON:
- ev.type = SND_SEQ_EVENT_NOTEON;
- ev.data.note.channel = event->channel;
- ev.data.note.note = event->param1;
- ev.data.note.velocity = event->param2;
- //AUBIO_ERR( "NOTE_ON %d\n", event->param1);
- break;
- case NOTE_OFF:
- ev.type = SND_SEQ_EVENT_NOTEOFF;
- ev.data.note.channel = event->channel;
- ev.data.note.note = event->param1;
- ev.data.note.velocity = event->param2;
- //AUBIO_ERR( "NOTE_OFF %d\n", event->param1);
- break;
- default:
- break;
- }
- if (ev.type == SND_SEQ_EVENT_NOTEOFF || ev.type == SND_SEQ_EVENT_NOTEON ) {
- snd_seq_ev_set_subs(&ev);
- snd_seq_ev_set_direct(&ev);
- snd_seq_ev_set_source(&ev, dev->seq_port);
- snd_seq_event_output_direct(dev->seq_handle, &ev);
- }
- /*
- if (pthread_detach(dev->thread)) {
- AUBIO_ERR( "Failed to leave the midi thread");
- }
- */
-}
-
-#endif /* #if ALSA_SUPPORT */
--- a/src/midi_driver.c
+++ /dev/null
@@ -1,195 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-/* This file originally tajke from
- * FluidSynth - A Software Synthesizer
- *
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-#include "aubio_priv.h"
-#include "midi_event.h"
-#include "midi_driver.h"
-//#include "settings.h"
-
-/*
- * aubio_mdriver_definition
- */
-struct aubio_mdriver_definition_t {
- char* name;
- aubio_midi_driver_t* (*new)(
- //aubio_settings_t* settings,
- handle_midi_event_func_t event_handler,
- void* event_handler_data);
- int (*free)(aubio_midi_driver_t* p);
- void (*settings)(aubio_settings_t* settings);
-};
-
-
-/* ALSA */
-#if ALSA_SUPPORT
-aubio_midi_driver_t* new_aubio_midi_alsa_raw_driver(
- //aubio_settings_t* settings,
- handle_midi_event_func_t handler,
- void* event_handler_data);
-int del_aubio_midi_alsa_raw_driver(aubio_midi_driver_t* p);
-void aubio_midi_alsa_raw_driver_settings(aubio_settings_t* settings);
-
-aubio_midi_driver_t* new_aubio_alsa_seq_driver(
- //aubio_settings_t* settings,
- handle_midi_event_func_t handler,
- void* event_handler_data);
-int del_aubio_alsa_seq_driver(aubio_midi_driver_t* p);
-void aubio_alsa_seq_driver_settings(aubio_settings_t* settings);
-#endif
-
-/* OSS */
-#if OSS_SUPPORT
-aubio_midi_driver_t* new_aubio_oss_midi_driver(aubio_settings_t* settings,
- handle_midi_event_func_t handler,
- void* event_handler_data);
-int del_aubio_oss_midi_driver(aubio_midi_driver_t* p);
-//void aubio_oss_midi_driver_settings(aubio_settings_t* settings);
-#endif
-
-/* Windows MIDI service */
-#if WINMIDI_SUPPORT
-aubio_midi_driver_t* new_aubio_winmidi_driver(aubio_settings_t* settings,
- handle_midi_event_func_t handler,
- void* event_handler_data);
-int del_aubio_winmidi_driver(aubio_midi_driver_t* p);
-#endif
-
-/* definitions for the MidiShare driver */
-#if MIDISHARE_SUPPORT
-aubio_midi_driver_t* new_aubio_midishare_midi_driver(aubio_settings_t* settings,
- handle_midi_event_func_t handler,
- void* event_handler_data);
-int del_aubio_midishare_midi_driver(aubio_midi_driver_t* p);
-#endif
-
-
-struct aubio_mdriver_definition_t aubio_midi_drivers[] = {
-#if OSS_SUPPORT
- { "oss",
- new_aubio_oss_midi_driver,
- del_aubio_oss_midi_driver,
- aubio_oss_midi_driver_settings },
-#endif
-#if ALSA_SUPPORT
- { "alsa_raw",
- new_aubio_midi_alsa_raw_driver,
- del_aubio_midi_alsa_raw_driver,
- NULL /*aubio_midi_alsa_raw_driver_settings*/ },
- { "alsa_seq",
- new_aubio_alsa_seq_driver,
- del_aubio_alsa_seq_driver,
- NULL /*aubio_alsa_seq_driver_settings*/ },
-#endif
-#if WINMIDI_SUPPORT
- { "winmidi",
- new_aubio_winmidi_driver,
- del_aubio_winmidi_driver,
- NULL },
-#endif
-#if MIDISHARE_SUPPORT
- { "midishare",
- new_aubio_midishare_midi_driver,
- del_aubio_midishare_midi_driver,
- NULL },
-#endif
- { NULL, NULL, NULL, NULL }
-};
-
-
-void aubio_midi_driver_settings(aubio_settings_t* settings)
-{
- int i;
-
-#if 0
- /* Set the default driver */
-#if ALSA_SUPPORT
- aubio_settings_register_str(settings, "midi.driver", "alsa_seq", 0, NULL, NULL);
-#elif OSS_SUPPORT
- aubio_settings_register_str(settings, "midi.driver", "oss", 0, NULL, NULL);
-#elif WINMIDI_SUPPORT
- aubio_settings_register_str(settings, "midi.driver", "winmidi", 0, NULL, NULL);
-#elif MIDISHARE_SUPPORT
- aubio_settings_register_str(settings, "midi.driver", "midishare", 0, NULL, NULL);
-#else
- aubio_settings_register_str(settings, "midi.driver", "", 0, NULL, NULL);
-#endif
-
- /* Add all drivers to the list of options */
-#if ALSA_SUPPORT
- aubio_settings_add_option(settings, "midi.driver", "alsa_seq");
- aubio_settings_add_option(settings, "midi.driver", "alsa_raw");
-#endif
-#if OSS_SUPPORT
- aubio_settings_add_option(settings, "midi.driver", "oss");
-#endif
-#if WINMIDI_SUPPORT
- aubio_settings_add_option(settings, "midi.driver", "winmidi");
-#endif
-#if MIDISHARE_SUPPORT
- aubio_settings_add_option(settings, "midi.driver", "midishare");
-#endif
-
-#endif
-
- for (i = 0; aubio_midi_drivers[i].name != NULL; i++) {
- if (aubio_midi_drivers[i].settings != NULL) {
- aubio_midi_drivers[i].settings(settings);
- }
- }
-}
-
-//aubio_midi_driver_t* new_aubio_midi_driver(aubio_settings_t* settings,
-aubio_midi_driver_t* new_aubio_midi_driver(char * name,
- handle_midi_event_func_t handler,
- void* event_handler_data)
-{
- int i;
- aubio_midi_driver_t* driver = NULL;
- for (i = 0; aubio_midi_drivers[i].name != NULL; i++) {
- if (AUBIO_STRCMP(name,aubio_midi_drivers[i].name) == 0){
- //if (aubio_settings_str_equal(settings, "midi.driver", aubio_midi_drivers[i].name)) {
- AUBIO_DBG( "Using '%s' midi driver\n", aubio_midi_drivers[i].name);
- //driver = aubio_midi_drivers[i].new(settings, handler, event_handler_data);
- driver = aubio_midi_drivers[i].new(/*name,*/ handler, event_handler_data);
- if (driver) {
- driver->name = aubio_midi_drivers[i].name;
- }
- return driver;
- }
- }
- AUBIO_ERR("Couldn't find the requested midi driver");
- return NULL;
-}
-
-void del_aubio_midi_driver(aubio_midi_driver_t* driver)
-{
- int i;
-
- for (i = 0; aubio_midi_drivers[i].name != NULL; i++) {
- if (aubio_midi_drivers[i].name == driver->name) {
- aubio_midi_drivers[i].free(driver);
- return;
- }
- }
-}
-
--- a/src/midi_driver.h
+++ /dev/null
@@ -1,57 +1,0 @@
-/*
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file orginally taken from :
- * FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-
-/** \file
- * generic midi driver
- */
-
-#ifndef _AUBIO_MDRIVER_H
-#define _AUBIO_MDRIVER_H
-
-typedef void aubio_settings_t;
-
-typedef int (*handle_midi_event_func_t)(void* data, aubio_midi_event_t* event);
-
-/** aubio_midi_driver_t */
-typedef struct _aubio_midi_driver_t aubio_midi_driver_t;
-
-struct _aubio_midi_driver_t
-{
- char* name;
- handle_midi_event_func_t handler;
- void* data;
-};
-
-//aubio_midi_driver_t* new_aubio_midi_driver(aubio_settings_t* settings,
-aubio_midi_driver_t* new_aubio_midi_driver(char * name,
- handle_midi_event_func_t handler,
- void* event_handler_data);
-void del_aubio_midi_driver(aubio_midi_driver_t* driver);
-void aubio_midi_driver_settings(aubio_settings_t* settings);
-
-#include "config.h"
-#if JACK_SUPPORT
-void aubio_midi_direct_output(aubio_midi_driver_t * dev, aubio_midi_event_t * event);
-#endif
-
-#endif /* _AUBIO_AUDRIVER_H */
--- a/src/midi_event.c
+++ /dev/null
@@ -1,222 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-#include "aubio_priv.h"
-#include "midi_event.h"
-#include "midi.h"
-
-/******************************************************
- *
- * aubio_event_t
- */
-
-/*
- * new_aubio_midi_event
- */
-aubio_midi_event_t* new_aubio_midi_event()
-{
- aubio_midi_event_t* evt;
- evt = AUBIO_NEW(aubio_midi_event_t);
- if (evt == NULL) {
- AUBIO_ERR( "Out of memory");
- return NULL;
- }
- evt->dtime = 0;
- evt->type = 0;
- evt->channel = 0;
- evt->param1 = 0;
- evt->param2 = 0;
- evt->next = NULL;
- return evt;
-}
-
-/** del_aubio_midi_event */
-int del_aubio_midi_event(aubio_midi_event_t* evt)
-{
- aubio_midi_event_t *temp;
- while(evt)
- {
- temp = evt->next;
- AUBIO_FREE(evt);
- evt = temp;
- }
- return AUBIO_OK;
-}
-
-/*
- * aubio_midi_event_get_type
- */
-int aubio_midi_event_get_type(aubio_midi_event_t* evt)
-{
- return evt->type;
-}
-
-/*
- * aubio_midi_event_set_type
- */
-int aubio_midi_event_set_type(aubio_midi_event_t* evt, int type)
-{
- evt->type = type;
- return AUBIO_OK;
-}
-
-/*
- * aubio_midi_event_get_channel
- */
-int aubio_midi_event_get_channel(aubio_midi_event_t* evt)
-{
- return evt->channel;
-}
-
-/*
- * aubio_midi_event_set_channel
- */
-int aubio_midi_event_set_channel(aubio_midi_event_t* evt, int chan)
-{
- evt->channel = chan;
- return AUBIO_OK;
-}
-
-/*
- * aubio_midi_event_get_key
- */
-int aubio_midi_event_get_key(aubio_midi_event_t* evt)
-{
- return evt->param1;
-}
-
-/*
- * aubio_midi_event_set_key
- */
-int aubio_midi_event_set_key(aubio_midi_event_t* evt, int v)
-{
- evt->param1 = v;
- return AUBIO_OK;
-}
-
-/*
- * aubio_midi_event_get_velocity
- */
-int aubio_midi_event_get_velocity(aubio_midi_event_t* evt)
-{
- return evt->param2;
-}
-
-/*
- * aubio_midi_event_set_velocity
- */
-int aubio_midi_event_set_velocity(aubio_midi_event_t* evt, int v)
-{
- evt->param2 = v;
- return AUBIO_OK;
-}
-
-/*
- * aubio_midi_event_get_control
- */
-int aubio_midi_event_get_control(aubio_midi_event_t* evt)
-{
- return evt->param1;
-}
-
-/*
- * aubio_midi_event_set_control
- */
-int aubio_midi_event_set_control(aubio_midi_event_t* evt, int v)
-{
- evt->param1 = v;
- return AUBIO_OK;
-}
-
-/*
- * aubio_midi_event_get_value
- */
-int aubio_midi_event_get_value(aubio_midi_event_t* evt)
-{
- return evt->param2;
-}
-
-/*
- * aubio_midi_event_set_value
- */
-int aubio_midi_event_set_value(aubio_midi_event_t* evt, int v)
-{
- evt->param2 = v;
- return AUBIO_OK;
-}
-
-int aubio_midi_event_get_program(aubio_midi_event_t* evt)
-{
- return evt->param1;
-}
-
-int aubio_midi_event_set_program(aubio_midi_event_t* evt, int val)
-{
- evt->param1 = val;
- return AUBIO_OK;
-}
-
-int aubio_midi_event_get_pitch(aubio_midi_event_t* evt)
-{
- return evt->param1;
-}
-
-int aubio_midi_event_set_pitch(aubio_midi_event_t* evt, int val)
-{
- evt->param1 = val;
- return AUBIO_OK;
-}
-
-/*
- * aubio_midi_event_get_param1
- */
-/* int aubio_midi_event_get_param1(aubio_midi_event_t* evt) */
-/* { */
-/* return evt->param1; */
-/* } */
-
-/*
- * aubio_midi_event_set_param1
- */
-/* int aubio_midi_event_set_param1(aubio_midi_event_t* evt, int v) */
-/* { */
-/* evt->param1 = v; */
-/* return AUBIO_OK; */
-/* } */
-
-/*
- * aubio_midi_event_get_param2
- */
-/* int aubio_midi_event_get_param2(aubio_midi_event_t* evt) */
-/* { */
-/* return evt->param2; */
-/* } */
-
-/*
- * aubio_midi_event_set_param2
- */
-/* int aubio_midi_event_set_param2(aubio_midi_event_t* evt, int v) */
-/* { */
-/* evt->param2 = v; */
-/* return AUBIO_OK; */
-/* } */
-
--- a/src/midi_event.h
+++ /dev/null
@@ -1,72 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-/** \file
- * midi event structure
- */
-
-#ifndef _AUBIO_MIDI_EVENT_H
-#define _AUBIO_MIDI_EVENT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _aubio_midi_event_t aubio_midi_event_t;
-
-/*
- * aubio_midi_event_t
- */
-struct _aubio_midi_event_t {
- aubio_midi_event_t* next; /**< Don't use it, it will dissappear. Used in midi tracks. */
- unsigned int dtime; /**< Delay (ticks) between this and previous event. midi tracks. */
- unsigned char type; /**< MIDI event type */
- unsigned char channel; /**< MIDI channel */
- unsigned int param1; /**< First parameter */
- unsigned int param2; /**< Second parameter */
-};
-
-aubio_midi_event_t* new_aubio_midi_event(void);
-int del_aubio_midi_event(aubio_midi_event_t* event);
-int aubio_midi_event_set_type(aubio_midi_event_t* evt, int type);
-int aubio_midi_event_get_type(aubio_midi_event_t* evt);
-int aubio_midi_event_set_channel(aubio_midi_event_t* evt, int chan);
-int aubio_midi_event_get_channel(aubio_midi_event_t* evt);
-int aubio_midi_event_get_key(aubio_midi_event_t* evt);
-int aubio_midi_event_set_key(aubio_midi_event_t* evt, int key);
-int aubio_midi_event_get_velocity(aubio_midi_event_t* evt);
-int aubio_midi_event_set_velocity(aubio_midi_event_t* evt, int vel);
-int aubio_midi_event_get_control(aubio_midi_event_t* evt);
-int aubio_midi_event_set_control(aubio_midi_event_t* evt, int ctrl);
-int aubio_midi_event_get_value(aubio_midi_event_t* evt);
-int aubio_midi_event_set_value(aubio_midi_event_t* evt, int val);
-int aubio_midi_event_get_program(aubio_midi_event_t* evt);
-int aubio_midi_event_set_program(aubio_midi_event_t* evt, int val);
-int aubio_midi_event_get_pitch(aubio_midi_event_t* evt);
-int aubio_midi_event_set_pitch(aubio_midi_event_t* evt, int val);
-int aubio_midi_event_length(unsigned char status);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif/*_AUBIO_MIDI_EVENT_H*/
--- a/src/midi_file.c
+++ /dev/null
@@ -1,633 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- *
- * \note fixed some track names causing segfault
- */
-
-#include "aubio_priv.h"
-#include "midi.h"
-#include "midi_event.h"
-#include "midi_track.h"
-#include "midi_player.h"
-#include "midi_file.h"
-
-
-/** aubio_midi_file */
-struct _aubio_midi_file_t{
- //aubio_file_t fp;
- FILE *fp;
- int running_status;
- int c;
- int type;
- int ntracks;
- int uses_smpte;
- unsigned int smpte_fps;
- unsigned int smpte_res;
- unsigned int division; /* If uses_SMPTE == 0 then division is
- ticks per beat (quarter-note) */
- double tempo; /* Beats per second (SI rules =) */
- int tracklen;
- int trackpos;
- int eot;
- int varlen;
-};
-
-/***************************************************************
- *
- * MIDIFILE
- */
-
-/** new_aubio_midi_file */
-aubio_midi_file_t * new_aubio_midi_file(char* filename)
-{
- aubio_midi_file_t* mf;
-
- mf = AUBIO_NEW(aubio_midi_file_t);
- if (mf == NULL) {
- AUBIO_ERR( "Out of memory");
- return NULL;
- }
- AUBIO_MEMSET(mf, 0, sizeof(aubio_midi_file_t));
-
- mf->c = -1;
- mf->running_status = -1;
- mf->fp = AUBIO_FOPEN(filename, "rb");
-
- if (mf->fp == NULL) {
- AUBIO_ERR( "Couldn't open the MIDI file !\n");
- AUBIO_FREE(mf);
- return NULL;
- }
-
- if (aubio_midi_file_read_mthd(mf) != AUBIO_OK) {
- AUBIO_FREE(mf);
- return NULL;
- }
- return mf;
-}
-
-/** del_aubio_midi_file */
-void del_aubio_midi_file(aubio_midi_file_t* mf)
-{
- if (mf == NULL) {
- return;
- }
- if (mf->fp != NULL) {
- AUBIO_FCLOSE(mf->fp);
- }
- AUBIO_FREE(mf);
- return;
-}
-
-/** aubio_midi_file_getc */
-int aubio_midi_file_getc(aubio_midi_file_t* mf)
-{
- unsigned char c;
- int n;
- if (mf->c >= 0) {
- c = mf->c;
- mf->c = -1;
- } else {
- n = AUBIO_FREAD(&c, 1, 1, mf->fp);
- mf->trackpos++;
- }
- return (int) c;
-}
-
-/** aubio_midi_file_push */
-int aubio_midi_file_push(aubio_midi_file_t* mf, int c)
-{
- mf->c = c;
- return AUBIO_OK;
-}
-
-/** aubio_midi_file_read */
-int aubio_midi_file_read(aubio_midi_file_t* mf, void* buf, int len)
-{
- int num = AUBIO_FREAD(buf, 1, len, mf->fp);
- mf->trackpos += num;
-#if DEBUG
- if (num != len) {
- AUBIO_DBG( "Coulnd't read the requested number of bytes");
- }
-#endif
- return (num != len)? AUBIO_FAIL : AUBIO_OK;
-}
-
-/** aubio_midi_file_skip */
-int aubio_midi_file_skip(aubio_midi_file_t* mf, int skip)
-{
- int err = AUBIO_FSEEK(mf->fp, skip, SEEK_CUR);
- if (err) {
- AUBIO_ERR( "FAIL to seek position in file");
- return AUBIO_FAIL;
- }
- return AUBIO_OK;
-}
-
-/** aubio_midi_file_read_mthd */
-int aubio_midi_file_read_mthd(aubio_midi_file_t* mf)
-{
- char mthd[15];
- if (aubio_midi_file_read(mf, mthd, 14) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
- if ((AUBIO_STRNCMP(mthd, "MThd", 4) != 0) || (mthd[7] != 6) || (mthd[9] > 2)) {
- AUBIO_ERR( "Doesn't look like a MIDI file: invalid MThd header");
- return AUBIO_FAIL;
- }
- mf->type = mthd[9];
- mf->ntracks = (unsigned) mthd[11];
- mf->ntracks += (unsigned int) (mthd[10]) << 16;
- /** \bug: smpte timing not yet implemented */
- if((int)(mthd[12]) < 0){
- /*if((mthd[12]) < 0){*/
- mf->uses_smpte = 1;
- mf->smpte_fps = -mthd[12];
- mf->smpte_res = (unsigned) mthd[13];
- AUBIO_ERR( "File uses SMPTE timing -- Not implemented yet");
- return AUBIO_FAIL;
- } else {
- mf->uses_smpte = 0;
- mf->division = (mthd[12] << 8) | (mthd[13] & 0xff);
- }
- return AUBIO_OK;
-}
-
-/** aubio_midi_file_load_tracks */
-int aubio_midi_file_load_tracks(aubio_midi_file_t* mf, aubio_midi_player_t* player)
-{
- int i;
- for (i = 0; i < mf->ntracks; i++) {
- if (aubio_midi_file_read_track(mf, player, i) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
- }
- return AUBIO_OK;
-}
-
-/** aubio_midi_file_read_tracklen */
-int aubio_midi_file_read_tracklen(aubio_midi_file_t* mf)
-{
- unsigned char length[5];
- if (aubio_midi_file_read(mf, length, 4) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
- mf->tracklen = aubio_getlength(length);
- mf->trackpos = 0;
- mf->eot = 0;
- return AUBIO_OK;
-}
-
-/** aubio_midi_file_eot */
-int aubio_midi_file_eot(aubio_midi_file_t* mf)
-{
-#if DEBUG
- if (mf->trackpos > mf->tracklen) {
- printf("track overrun: %d > %d\n", mf->trackpos, mf->tracklen);
- }
-#endif
- return mf->eot || (mf->trackpos >= mf->tracklen);
-}
-
-/** aubio_midi_file_read_track */
-int aubio_midi_file_read_track(aubio_midi_file_t* mf, aubio_midi_player_t* player, int num)
-{
- aubio_track_t* track;
- unsigned char id[5], length[5];
- int found_track = 0;
- int skip;
-
- AUBIO_DBG("Loading track %d\n",num);
- if (aubio_midi_file_read(mf, id, 4) != AUBIO_OK) {
- AUBIO_DBG("Failed loading track %d\n",num);
- return AUBIO_FAIL;
- }
-
- id[4]='\0';
-
- while (!found_track){
-
- if (aubio_isasciistring((char*) id) == 0) {
- AUBIO_ERR( "An non-ascii track header found, currupt file");
- return AUBIO_FAIL;
-
- } else if (strcmp((char*) id, "MTrk") == 0) {
-
- found_track = 1;
-
- if (aubio_midi_file_read_tracklen(mf) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
-
- track = new_aubio_track(num);
- if (track == NULL) {
- AUBIO_ERR( "Out of memory");
- return AUBIO_FAIL;
- }
-
- while (!aubio_midi_file_eot(mf)) {
- if (aubio_midi_file_read_event(mf, track) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
- }
-
- aubio_midi_player_add_track(player, track);
- } else {
- found_track = 0;
- if (aubio_midi_file_read(mf, length, 4) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
- skip = aubio_getlength(length);
- /* fseek(mf->fp, skip, SEEK_CUR); */
- if (aubio_midi_file_skip(mf, skip) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
- }
- }
-
- if (feof(mf->fp)) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
- AUBIO_DBG("Loaded track %d\n",num);
- return AUBIO_OK;
-}
-
-/** aubio_midi_file_read_varlen */
-int aubio_midi_file_read_varlen(aubio_midi_file_t* mf)
-{
- int i;
- int c;
- mf->varlen = 0;
- for (i = 0;;i++) {
- if (i == 4) {
- AUBIO_ERR( "Invalid variable length number");
- return AUBIO_FAIL;
- }
- c = aubio_midi_file_getc(mf);
- if (c < 0) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
- if (c & 0x80){
- mf->varlen |= (int) (c & 0x7F);
- mf->varlen <<= 7;
- } else {
- mf->varlen += c;
- break;
- }
- }
- return AUBIO_OK;
-}
-
-/** aubio_midi_file_read_event */
-int aubio_midi_file_read_event(aubio_midi_file_t* mf, aubio_track_t* track)
-{
- int dtime;
- int status;
- int type;
- int tempo;
- unsigned char* metadata = NULL;
- unsigned char* dyn_buf = NULL;
- unsigned char static_buf[256];
- int nominator, denominator, clocks, notes, sf, mi;
- aubio_midi_event_t* evt;
- int channel = 0;
- int param1 = 0;
- int param2 = 0;
-
-
- /* read the delta-time of the event */
- if (aubio_midi_file_read_varlen(mf) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
- dtime = mf->varlen;
-
- /* read the status byte */
- status = aubio_midi_file_getc(mf);
- if (status < 0) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
-
- /* not a valid status byte: use the running status instead */
- if ((status & 0x80) == 0) {
- if ((mf->running_status & 0x80) == 0) {
- AUBIO_ERR( "Undefined status and invalid running status");
- return AUBIO_FAIL;
- }
- aubio_midi_file_push(mf, status);
- status = mf->running_status;
- }
-
- /* check what message we have */
- if (status & 0x80) {
- mf->running_status = status;
-
- if ((status == MIDI_SYSEX) || (status == MIDI_EOX)) { /* system exclusif */
- /** \bug Sysex messages are not handled yet */
- /* read the length of the message */
- if (aubio_midi_file_read_varlen(mf) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
-
- if (mf->varlen < 255) {
- metadata = &static_buf[0];
- } else {
- AUBIO_DBG( "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
- dyn_buf = AUBIO_MALLOC(mf->varlen + 1);
- if (dyn_buf == NULL) {
- //AUBIO_LOG(AUBIO_PANIC, "Out of memory");
- AUBIO_ERR("Out of memory");
- return AUBIO_FAIL;
- }
- metadata = dyn_buf;
- }
-
- /* read the data of the message */
- if (mf->varlen) {
-
- if (aubio_midi_file_read(mf, metadata, mf->varlen) != AUBIO_OK) {
- if (dyn_buf) {
- AUBIO_FREE(dyn_buf);
- }
- return AUBIO_FAIL;
- }
-
- if (dyn_buf) {
- AUBIO_DBG( "%s: %d: free metadata", __FILE__, __LINE__);
- AUBIO_FREE(dyn_buf);
- }
- }
-
- return AUBIO_OK;
-
- } else if (status == MIDI_META_EVENT) { /* meta events */
-
- int result = AUBIO_OK;
-
- /* get the type of the meta message */
- type = aubio_midi_file_getc(mf);
- if (type < 0) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
-
- /* get the length of the data part */
- if (aubio_midi_file_read_varlen(mf) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
-
- if (mf->varlen) {
-
- if (mf->varlen < 255) {
- metadata = &static_buf[0];
- } else {
- AUBIO_DBG( "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
- dyn_buf = AUBIO_MALLOC(mf->varlen + 1);
- if (dyn_buf == NULL) {
- AUBIO_ERR("Out of memory");
- return AUBIO_FAIL;
- }
- metadata = dyn_buf;
- }
-
- /* read the data */
- if (aubio_midi_file_read(mf, metadata, mf->varlen) != AUBIO_OK) {
- if (dyn_buf) {
- AUBIO_FREE(dyn_buf);
- }
- return AUBIO_FAIL;
- }
- }
-
- /* handle meta data */
- switch (type) {
-
- case MIDI_COPYRIGHT:
- metadata[mf->varlen] = 0;
- break;
-
- case MIDI_TRACK_NAME:
- if (metadata != NULL) /* avoids crashes on empty tracks */
- metadata[mf->varlen] = 0;
- aubio_track_set_name(track, (char*) metadata);
- break;
-
- case MIDI_INST_NAME:
- metadata[mf->varlen] = 0;
- break;
-
- case MIDI_LYRIC:
- break;
-
- case MIDI_MARKER:
- break;
-
- case MIDI_CUE_POINT:
- break; /* don't care much for text events */
-
- case MIDI_EOT:
- if (mf->varlen != 0) {
- AUBIO_ERR("Invalid length for EndOfTrack event");
- result = AUBIO_FAIL;
- break;
- }
- mf->eot = 1;
- break;
-
- case MIDI_SET_TEMPO:
- if (mf->varlen != 3) {
- AUBIO_ERR("Invalid length for SetTempo meta event");
- result = AUBIO_FAIL;
- break;
- }
- tempo = (metadata[0] << 16) + (metadata[1] << 8) + metadata[2];
- evt = new_aubio_midi_event();
- if (evt == NULL) {
- AUBIO_ERR( "Out of memory");
- result = AUBIO_FAIL;
- break;
- }
- evt->dtime = dtime;
- evt->type = MIDI_SET_TEMPO;
- evt->channel = 0;
- evt->param1 = tempo;
- evt->param2 = 0;
- aubio_track_add_event(track, evt);
- break;
-
- case MIDI_SMPTE_OFFSET:
- if (mf->varlen != 5) {
- AUBIO_ERR("Invalid length for SMPTE Offset meta event");
- result = AUBIO_FAIL;
- break;
- }
- break; /* we don't use smtp */
-
- case MIDI_TIME_SIGNATURE:
- if (mf->varlen != 4) {
- AUBIO_ERR("Invalid length for TimeSignature meta event");
- result = AUBIO_FAIL;
- break;
- }
- nominator = metadata[0];
- denominator = pow(2.0, (double) metadata[1]);
- clocks = metadata[2];
- notes = metadata[3];
-
- AUBIO_DBG("signature=%d/%d, metronome=%d, 32nd-notes=%d\n",
- nominator, denominator, clocks, notes);
-
- break;
-
- case MIDI_KEY_SIGNATURE:
- if (mf->varlen != 2) {
- AUBIO_ERR( "Invalid length for KeySignature meta event");
- result = AUBIO_FAIL;
- break;
- }
- sf = metadata[0];
- mi = metadata[1];
- break;
-
- case MIDI_SEQUENCER_EVENT:
- AUBIO_DBG("Sequencer event ignored\n");
- break;
-
- default:
- break;
- }
-
- if (dyn_buf) {
- AUBIO_DBG( "%s: %d: free metadata", __FILE__, __LINE__);
- AUBIO_FREE(dyn_buf);
- }
-
- return result;
-
- } else { /* channel messages */
-
- type = status & 0xf0;
- channel = status & 0x0f;
-
- /* all channel message have at least 1 byte of associated data */
- if ((param1 = aubio_midi_file_getc(mf)) < 0) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
-
- switch (type) {
-
- case NOTE_ON:
- if ((param2 = aubio_midi_file_getc(mf)) < 0) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
- break;
-
- case NOTE_OFF:
- if ((param2 = aubio_midi_file_getc(mf)) < 0) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
- break;
-
- case KEY_PRESSURE:
- if ((param2 = aubio_midi_file_getc(mf)) < 0) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
- break;
-
- case CONTROL_CHANGE:
- if ((param2 = aubio_midi_file_getc(mf)) < 0) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
- break;
-
- case PROGRAM_CHANGE:
- break;
-
- case CHANNEL_PRESSURE:
- break;
-
- case PITCH_BEND:
- if ((param2 = aubio_midi_file_getc(mf)) < 0) {
- AUBIO_ERR( "Unexpected end of file");
- return AUBIO_FAIL;
- }
-
- param1 = ((param2 & 0x7f) << 7) | (param1 & 0x7f);
- param2 = 0;
- break;
-
- default:
- /* Can't possibly happen !? */
- AUBIO_ERR( "Unrecognized MIDI event");
- return AUBIO_FAIL;
- }
- evt = new_aubio_midi_event();
- if (evt == NULL) {
- AUBIO_ERR( "Out of memory");
- return AUBIO_FAIL;
- }
- evt->dtime = dtime;
- evt->type = type;
- evt->channel = channel;
- evt->param1 = param1;
- evt->param2 = param2;
- aubio_track_add_event(track, evt);
- }
- }
- return AUBIO_OK;
-}
-
-/** aubio_midi_file_get_division */
-int aubio_midi_file_get_division(aubio_midi_file_t* midifile)
-{
- return midifile->division;
-}
-
-
-/** aubio_isasciistring */
-int aubio_isasciistring(char* s)
-{
- int i;
- int len = (int) AUBIO_STRLEN(s);
- for (i = 0; i < len; i++) {
- if (!aubio_isascii(s[i])) {
- return 0;
- }
- }
- return 1;
-}
-
-/** aubio_getlength */
-long aubio_getlength(unsigned char *s)
-{
- long i = 0;
- i = s[3] | (s[2]<<8) | (s[1]<<16) | (s[0]<<24);
- return i;
-}
-
--- a/src/midi_file.h
+++ /dev/null
@@ -1,62 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-/** \file
- * midi file reader
- */
-
-#ifndef _AUBIO_MIDI_FILE_H
-#define _AUBIO_MIDI_FILE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _aubio_midi_file_t aubio_midi_file_t;
-
-
-aubio_midi_file_t* new_aubio_midi_file(char* filename);
-void del_aubio_midi_file(aubio_midi_file_t* mf);
-int aubio_midi_file_read_mthd(aubio_midi_file_t* midifile);
-int aubio_midi_file_load_tracks(aubio_midi_file_t* midifile, aubio_midi_player_t* player);
-int aubio_midi_file_read_track(aubio_midi_file_t* mf, aubio_midi_player_t* player, int num);
-int aubio_midi_file_read_event(aubio_midi_file_t* mf, aubio_track_t* track);
-int aubio_midi_file_read_varlen(aubio_midi_file_t* mf);
-int aubio_midi_file_getc(aubio_midi_file_t* mf);
-int aubio_midi_file_push(aubio_midi_file_t* mf, int c);
-int aubio_midi_file_read(aubio_midi_file_t* mf, void* buf, int len);
-int aubio_midi_file_skip(aubio_midi_file_t* mf, int len);
-int aubio_midi_file_read_tracklen(aubio_midi_file_t* mf);
-int aubio_midi_file_eot(aubio_midi_file_t* mf);
-int aubio_midi_file_get_division(aubio_midi_file_t* midifile);
-
-
-/* From ctype.h */
-#define aubio_isascii(c) (((c) & ~0x7f) == 0)
-int aubio_isasciistring(char* s);
-long aubio_getlength(unsigned char *s);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_AUBIO_MIDI_FILE_H*/
--- a/src/midi_parser.c
+++ /dev/null
@@ -1,221 +1,0 @@
-/*
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* This file orginally taken from, Fluidsynth, Peter Hanappe */
-
-#include "aubio_priv.h"
-#include "midi.h"
-#include "midi_event.h"
-#include "midi_parser.h"
-
-/** aubio_midi_parser_t */
-struct _aubio_midi_parser_t {
- unsigned char status; /**< Identifies the type of event, that is
- currently received ('Noteon', 'Pitch Bend'
- etc). */
- unsigned char channel; /**< The channel of the event that is received
- (in case of a channel event) */
- unsigned int nr_bytes; /**< How many bytes have been read for the
- current event? */
- unsigned int nr_bytes_total;/**< How many bytes does the current event
- type include? */
- unsigned short p[AUBIO_MIDI_PARSER_MAX_PAR]; /**< The parameters */
-
- aubio_midi_event_t event; /**< The event, that is returned to the
- MIDI driver. */
-};
-
-/** new_aubio_midi_parser */
-aubio_midi_parser_t* new_aubio_midi_parser()
-{
- aubio_midi_parser_t* parser;
- parser = AUBIO_NEW(aubio_midi_parser_t);
- if (parser == NULL) {
- AUBIO_ERR("Out of memory");
- return NULL;
- }
- /* As long as the status is 0, the parser won't do anything -> no need to
- * initialize all the fields. */
- parser->status = 0;
- return parser;
-}
-
-/** del_aubio_midi_parser */
-int del_aubio_midi_parser(aubio_midi_parser_t* parser)
-{
- AUBIO_FREE(parser);
- return AUBIO_OK;
-}
-
-/** aubio_midi_parser_parse
- *
- * The MIDI byte stream is fed into the parser, one byte at a time.
- * As soon as the parser has recognized an event, it will return it.
- * Otherwise it returns NULL.
- */
-aubio_midi_event_t* aubio_midi_parser_parse(aubio_midi_parser_t* parser,
- unsigned char c)
-{
- /*********************************************************************/
- /* 'Process' system real-time messages */
- /*********************************************************************/
- /* There are not too many real-time messages that are of interest here.
- * They can occur anywhere, even in the middle of a noteon message!
- * Real-time range: 0xF8 .. 0xFF
- * Note: Real-time does not affect (running) status.
- */
- if (c >= 0xF8){
- if (c == MIDI_SYSTEM_RESET){
- parser->event.type = c;
- parser->status = 0; /* clear the status */
- return &parser->event;
- };
- return NULL;
- };
-
- /*********************************************************************/
- /* 'Process' system common messages (again, just skip them) */
- /*********************************************************************/
- /* There are no system common messages that are of interest here.
- * System common range: 0xF0 .. 0xF7
- */
-
- if (c > 0xF0){
- /* MIDI specs say: To ignore a non-real-time message, just discard all data
- * up to the next status byte. And our parser will ignore data that is
- * received without a valid status.
- * Note: system common cancels running status. */
- parser->status = 0;
- return NULL;
- };
-
- /*********************************************************************/
- /* Process voice category messages: */
- /*********************************************************************/
- /* Now that we have handled realtime and system common messages, only
- * voice messages are left.
- * Only a status byte has bit # 7 set.
- * So no matter the status of the parser (in case we have lost sync),
- * as soon as a byte >= 0x80 comes in, we are dealing with a status byte
- * and start a new event.
- */
-
- if (c & 0x80){
- parser->channel = c & 0x0F;
- parser->status = c & 0xF0;
- /* The event consumes x bytes of data... (subtract 1 for the status
- * byte) */
- parser->nr_bytes_total=aubio_midi_event_length(parser->status)-1;
- /* of which we have read 0 at this time. */
- parser->nr_bytes = 0;
- return NULL;
- };
-
- /*********************************************************************/
- /* Process data */
- /*********************************************************************/
- /* If we made it this far, then the received char belongs to the data
- * of the last event. */
- if (parser->status == 0){
- /* We are not interested in the event currently received.
- * Discard the data. */
- return NULL;
- };
-
- /* Store the first couple of bytes */
- if (parser->nr_bytes < AUBIO_MIDI_PARSER_MAX_PAR){
- parser->p[parser->nr_bytes]=c;
- };
- parser->nr_bytes++;
-
- /* Do we still need more data to get this event complete? */
- if (parser->nr_bytes < parser->nr_bytes_total){
- return NULL;
- };
-
- /*********************************************************************/
- /* Send the event */
- /*********************************************************************/
- /* The event is ready-to-go. About 'running status':
- *
- * The MIDI protocol has a built-in compression mechanism. If several similar
- * events are sent in-a-row, for example note-ons, then the event type is
- * only sent once. For this case, the last event type (status) is remembered.
- * We simply keep the status as it is, just reset the parameter counter. If
- * another status byte comes in, it will overwrite the status.
- */
- parser->event.type = parser->status;
- parser->event.channel = parser->channel;
- parser->nr_bytes = 0; /* Related to running status! */
- switch (parser->status){
- case NOTE_OFF:
- case NOTE_ON:
- case KEY_PRESSURE:
- case CONTROL_CHANGE:
- case PROGRAM_CHANGE:
- case CHANNEL_PRESSURE:
- parser->event.param1 = parser->p[0]; /* For example key number */
- parser->event.param2 = parser->p[1]; /* For example velocity */
- break;
- case PITCH_BEND:
- /* Pitch-bend is transmitted with 14-bit precision. */
- /* Note: '|' does here the same as '+' (no common bits),
- * but might be faster */
- parser->event.param1 = ((parser->p[1] << 7) | parser->p[0]);
- break;
- default:
- /* Unlikely */
- return NULL;
- };
- return &parser->event;
-};
-
-
-
-/* Taken from Nagano Daisuke's USB-MIDI driver */
-static int remains_f0f6[] = {
- 0, /* 0xF0 */
- 2, /* 0XF1 */
- 3, /* 0XF2 */
- 2, /* 0XF3 */
- 2, /* 0XF4 (Undefined by MIDI Spec, and subject to change) */
- 2, /* 0XF5 (Undefined by MIDI Spec, and subject to change) */
- 1 /* 0XF6 */
-};
-
-static int remains_80e0[] = {
- 3, /* 0x8X Note Off */
- 3, /* 0x9X Note On */
- 3, /* 0xAX Poly-key pressure */
- 3, /* 0xBX Control Change */
- 2, /* 0xCX Program Change */
- 2, /* 0xDX Channel pressure */
- 3 /* 0xEX PitchBend Change */
-};
-
-/** Returns the length of the MIDI message starting with c.
- *
- * Taken from Nagano Daisuke's USB-MIDI driver */
-int aubio_midi_event_length(unsigned char event){
- if ( event < 0xf0 ) {
- return remains_80e0[((event-0x80)>>4)&0x0f];
- } else if ( event < 0xf7 ) {
- return remains_f0f6[event-0xf0];
- } else {
- return 1;
- }
-}
--- a/src/midi_parser.h
+++ /dev/null
@@ -1,49 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-
-/** \file
- * midi parser
- */
-
-#ifndef _AUBIO_MIDI_PARSER_H
-#define _AUBIO_MIDI_PARSER_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* How many parameters may a MIDI event have? */
-#define AUBIO_MIDI_PARSER_MAX_PAR 3
-
-typedef struct _aubio_midi_parser_t aubio_midi_parser_t;
-
-aubio_midi_parser_t* new_aubio_midi_parser(void);
-int del_aubio_midi_parser(aubio_midi_parser_t* parser);
-aubio_midi_event_t* aubio_midi_parser_parse(aubio_midi_parser_t* parser, unsigned char c);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_AUBIO_MIDI_PARSER_H*/
--- a/src/midi_player.c
+++ /dev/null
@@ -1,492 +1,0 @@
-/*
- * Copyright (C) 2003 Peter Hanappe and others.
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * modified by Paul Brossier for aubio
- */
-
-/**
- *
- * \bug timer still broken
- * (should use alsa seq anyway) (fixed?) realtime playing is slower than
- * it should. moved msec_passed and deltatime to microseconds (usec)
- * (rounding were causing the drift) the new offline version is not quite
- * exact yet.
- *
- * \bug the player does not seem to understand a ``reprise'' in a file
- */
-
-#include "aubio_priv.h"
-#include "list.h"
-#include "timer.h"
-#include "midi.h"
-#include "midi_event.h"
-#include "midi_track.h"
-#include "midi_player.h"
-#include "midi_file.h"
-
-
-/** aubio_midi_player */
-struct _aubio_midi_player_t {
- aubio_track_t *track[AUBIO_MIDI_PLAYER_MAX_TRACKS];
- aubio_timer_t* timer;
- sint_t status;
- sint_t loop;
- sint_t ntracks;
- aubio_list_t* playlist;
- char* current_file;
- char send_program_change;/**< should we ignore the program changes? */
- sint_t ticks_passed; /**< number of midi ticks that have passed */
- sint_t usec_passed; /**< number of microseconds that have passed */
- sint_t miditempo; /**< as indicated by midi settempo: n 24th of a
- * usec per midi-clock. bravo! */
- lsmp_t deltatime; /**< microseconds per midi tick. depends on
- * set-tempo */
- uint_t division; /**< the number of ticks per beat (quarter-note)
- * in the file*/
- //aubio_synth_t* synth;
-};
-
-/******************************************************
- *
- * aubio_midi_player
- */
-/** new_aubio_midi_player */
-aubio_midi_player_t* new_aubio_midi_player()
- //aubio_midi_player_t* new_aubio_midi_player(aubio_synth_t* synth)
-{
- sint_t i;
- aubio_midi_player_t* player;
- player = AUBIO_NEW(aubio_midi_player_t);
- if (player == NULL) {
- AUBIO_ERR( "Out of memory");
- return NULL;
- }
- player->status = AUBIO_MIDI_PLAYER_READY;
- player->loop = 0;
- player->ntracks = 0;
- for (i = 0; i < AUBIO_MIDI_PLAYER_MAX_TRACKS; i++) {
- player->track[i] = NULL;
- }
- //player->synth = synth;
- player->timer = NULL;
- player->playlist = NULL;
- player->current_file = NULL;
- player->division = 0;
- player->send_program_change = 1;
- player->ticks_passed = 0;
- player->usec_passed = 0;
- player->miditempo = 480000;
- player->deltatime = 4000.0;
- return player;
-}
-
-/** delete_aubio_midi_player */
-sint_t del_aubio_midi_player(aubio_midi_player_t* player)
-{
- if (player == NULL) {
- return AUBIO_OK;
- }
- aubio_midi_player_stop(player);
- aubio_midi_player_reset(player);
- AUBIO_FREE(player);
- return AUBIO_OK;
-}
-
-/** aubio_midi_player_reset */
-sint_t aubio_midi_player_reset(aubio_midi_player_t* player)
-{
- sint_t i;
-
- for (i = 0; i < AUBIO_MIDI_PLAYER_MAX_TRACKS; i++) {
- if (player->track[i] != NULL) {
- del_aubio_track(player->track[i]);
- player->track[i] = NULL;
- }
- }
- player->current_file = NULL;
- player->status = AUBIO_MIDI_PLAYER_READY;
- player->loop = 0;
- player->ntracks = 0;
- player->division = 0;
- player->send_program_change = 1;
- player->ticks_passed = 0;
- player->usec_passed = 0;
- player->miditempo = 480000;
- player->deltatime = 4000.0;
- return 0;
-}
-
-/** aubio_midi_player_add_track */
-sint_t aubio_midi_player_add_track(aubio_midi_player_t* player, aubio_track_t* track)
-{
- if (player->ntracks < AUBIO_MIDI_PLAYER_MAX_TRACKS) {
- player->track[player->ntracks++] = track;
- return AUBIO_OK;
- } else {
- return AUBIO_FAIL;
- }
-}
-
-/** aubio_midi_player_count_tracks */
-sint_t aubio_midi_player_count_tracks(aubio_midi_player_t* player)
-{
- return player->ntracks;
-}
-
-/** aubio_midi_player_get_track */
-aubio_track_t* aubio_midi_player_get_track(aubio_midi_player_t* player, sint_t i)
-{
- if ((i >= 0) && (i < AUBIO_MIDI_PLAYER_MAX_TRACKS)) {
- return player->track[i];
- } else {
- return NULL;
- }
-}
-
-/** aubio_midi_player_get_track */
-sint_t aubio_midi_player_add(aubio_midi_player_t* player, char* midifile)
-{
- char *s = AUBIO_STRDUP(midifile);
- player->playlist = aubio_list_append(player->playlist, s);
- return 0;
-}
-
-/** aubio_midi_player_load */
-sint_t aubio_midi_player_load(aubio_midi_player_t* player, char *filename)
-{
- aubio_midi_file_t* midifile;
-
- midifile = new_aubio_midi_file(filename);
- if (midifile == NULL) {
- return AUBIO_FAIL;
- }
- player->division = aubio_midi_file_get_division(midifile);
-
- AUBIO_DBG("quarter note division=%d\n", player->division);
-
- if (aubio_midi_file_load_tracks(midifile, player) != AUBIO_OK){
- return AUBIO_FAIL;
- }
-
- AUBIO_DBG("Tracks loaded\n");
-
- del_aubio_midi_file(midifile);
- return AUBIO_OK;
-}
-
-/** aubio_midi_player_callback */
-sint_t aubio_midi_player_callback(void* data, uint_t usec)
-{
- sint_t i;
- uint_t ticks;
- uint_t delta_ticks;
- sint_t status = AUBIO_MIDI_PLAYER_DONE;
- aubio_midi_player_t* player;
- //aubio_synth_t* synth;
- player = (aubio_midi_player_t*) data;
- //synth = player->synth;
-
- /* Load the next file if necessary */
- while (player->current_file == NULL) {
-
- if (player->playlist == NULL) {
- return 0;
- }
-
- aubio_midi_player_reset(player);
-
- player->current_file = aubio_list_get(player->playlist);
- player->playlist = aubio_list_next(player->playlist);
-
- //AUBIO_DBG( "%s: %d: Loading midifile %s", __FILE__, __LINE__, player->current_file);
- AUBIO_DBG("Loading midifile %s\n", player->current_file);
-
- if (aubio_midi_player_load(player, player->current_file) == AUBIO_OK) {
-
- player->ticks_passed = 0;
- player->usec_passed = 0;
-
- for (i = 0; i < player->ntracks; i++) {
- if (player->track[i] != NULL) {
- aubio_track_reset(player->track[i]);
- }
- }
-
- } else {
- player->current_file = NULL;
- }
- }
-
- delta_ticks = (uint_t) ((lsmp_t)(usec - player->usec_passed) / player->deltatime);
- ticks = player->ticks_passed + delta_ticks;
-
- for (i = 0; i < player->ntracks; i++) {
- if (!aubio_track_eot(player->track[i])) {
- status = AUBIO_MIDI_PLAYER_PLAYING;
- if (aubio_track_send_events(player->track[i], /*synth,*/ player, ticks) != AUBIO_OK) {
- /* */
- }
- }
- }
-
- player->status = status;
- player->ticks_passed = ticks;
- player->usec_passed = usec;
-
- if (player->status == AUBIO_MIDI_PLAYER_DONE) {
- player->current_file = NULL;
- }
-
- return 1;
-}
-
-/** aubio_midi_player_play */
-sint_t aubio_midi_player_play(aubio_midi_player_t* player)
-{
- AUBIO_DBG("Starting midi player\n");
- if (player->status == AUBIO_MIDI_PLAYER_PLAYING) {
- AUBIO_DBG("Midi player already playing\n");
- return AUBIO_OK;
- }
-
- if (player->playlist == NULL) {
- AUBIO_DBG("No playlist\n");
- return AUBIO_FAIL;
- }
-
- player->status = AUBIO_MIDI_PLAYER_PLAYING;
-
- /** \bug timer is still in millisec, should be moved to microseconds,
- * and replaced in favor of the alsa sequencer api */
- player->timer = new_aubio_timer((sint_t) player->deltatime * 1.e-3, aubio_midi_player_callback,
- (void*) player, 1, 0);
- if (player->timer == NULL) {
- AUBIO_DBG("Failed creating timer for midi player.\n");
- return AUBIO_FAIL;
- }
- if (player->current_file == NULL) {
- AUBIO_DBG("No more file.\n");
- delete_aubio_timer(player->timer);
- return AUBIO_FAIL;
- }
-
- return AUBIO_OK;
-}
-
-/** aubio_midi_player_play_offline */
-sint_t aubio_midi_player_play_offline(aubio_midi_player_t* player)
-{
- uint_t usec = 0; /* start looking n ms in advance */
- AUBIO_DBG("Starting midi player\n");
- if (player->status == AUBIO_MIDI_PLAYER_PLAYING) {
- AUBIO_DBG("Midi player already playing\n");
- return AUBIO_OK;
- }
-
- if (player->playlist == NULL) {
- AUBIO_DBG("No playlist\n");
- return AUBIO_FAIL;
- }
-
- //AUBIO_DBG("Starting callback.\n");
- player->status = AUBIO_MIDI_PLAYER_PLAYING;
-
- /* no timer, no thread ! */
- while(aubio_midi_player_callback((void *)player,usec))
- {
- /* step at least one microsecond forward */
- usec += 1 + player->deltatime;
- if (player->status == AUBIO_MIDI_PLAYER_DONE)
- break;
- }
- //AUBIO_DBG("End of callback.\n");
-
- if (player->current_file == NULL) {
- AUBIO_DBG("No more file.\n");
- return AUBIO_FAIL;
- }
- return AUBIO_OK;
-}
-/** aubio_midi_player_stop */
-sint_t aubio_midi_player_stop(aubio_midi_player_t* player)
-{
- if (player->timer != NULL) {
- delete_aubio_timer(player->timer);
- }
- player->status = AUBIO_MIDI_PLAYER_DONE;
- player->timer = NULL;
- return AUBIO_OK;
-}
-
-/** aubio_midi_player_set_loop */
-sint_t aubio_midi_player_set_loop(aubio_midi_player_t* player, sint_t loop)
-{
- player->loop = loop;
- return AUBIO_OK;
-}
-
-/** aubio_midi_player_set_midi_tempo */
-sint_t aubio_midi_player_set_midi_tempo(aubio_midi_player_t* player, sint_t tempo)
-{
- player->miditempo = tempo;
- //player->deltatime = (lsmp_t) tempo / player->division * 1.e-3; /* in milliseconds */
- player->deltatime = (lsmp_t) tempo / player->division; /* in microseconds */
-
- AUBIO_DBG("Tempo Change: %d tempo=%f tick time=%f msec\n",
- // player->usec_passed, 60.*1.e6/tempo, player->deltatime);
- player->usec_passed, 60.*1.e6/tempo, 1e-3*player->deltatime);
-
- return AUBIO_OK;
-}
-
-/** aubio_midi_player_set_bpm */
-sint_t aubio_midi_player_set_bpm(aubio_midi_player_t* player, sint_t bpm)
-{
- return aubio_midi_player_set_midi_tempo(player, (sint_t)((lsmp_t) 60 * 1e6 / bpm));
-}
-
-/** aubio_midi_player_join */
-sint_t aubio_midi_player_join(aubio_midi_player_t* player)
-{
- return player->timer? aubio_timer_join(player->timer) : AUBIO_OK;
-}
-
-/** aubio_track_send_events */
-sint_t aubio_track_send_events(aubio_track_t* track,
- // aubio_synth_t* synth,
- aubio_midi_player_t* player,
- uint_t ticks)
-{
- sint_t status = AUBIO_OK;
- aubio_midi_event_t* event;
-
- while (1) {
-
- event = track->cur;
- if (event == NULL) {
- return status;
- }
- /* prsint_t each midi tick */
- /*
- AUBIO_DBG("track=%d\tticks=%u\ttrack=%u\tdtime=%u\tnext=%u\n",
- track->num,
- ticks,
- track->ticks,
- event->dtime,
- track->ticks + event->dtime);
- */
-
- if (track->ticks + event->dtime > ticks) {
- return status;
- }
-
- track->ticks += event->dtime;
- status = aubio_midi_send_event(/*synth, */player, event);
- aubio_track_next_event(track);
-
- }
- return status;
-}
-
-
-/**
- * aubio_midi_send_event
- *
- * This is a utility function that doesn't really belong to any class or
- * structure. It is called by aubio_midi_track and aubio_midi_device.
- *
- * \note This could be moved to a callback function defined in the main programs
- */
-//sint_t aubio_midi_send_event(aubio_synth_t* synth, aubio_player_t* player, aubio_midi_event_t* event)
-sint_t aubio_midi_send_event(aubio_midi_player_t* player, aubio_midi_event_t* event)
-{
- /* current time in seconds */
- //smpl_t print_time = player->msec_passed * 1e-3;
- smpl_t print_time = player->usec_passed * 1e-6;
- switch (event->type) {
- case NOTE_ON:
- AUBIO_MSG("Time=%f, chan=%d, pitch=%d vol=%d \n",
- print_time, event->channel, event->param1, event->param2);
- /*if (aubio_synth_noteon(synth, event->channel, event->param1, event->param2) != AUBIO_OK) {
- return AUBIO_FAIL;
- }*/
- break;
- case NOTE_OFF:
- AUBIO_MSG("Time=%f, chan=%d, pitch=%d, vol=0\n",
- print_time, event->channel, event->param1);
- /*if (aubio_synth_noteoff(synth, event->channel, event->param1) != AUBIO_OK) {
- return AUBIO_FAIL;
- }*/
- break;
- case CONTROL_CHANGE:
- AUBIO_MSG("Time=%f Parameter, chan=%d c1=%d c2=%d\n",
- print_time, event->channel, event->param1, event->param2);
- /*if (aubio_synth_cc(synth, event->channel, event->param1, event->param2) != AUBIO_OK) {
- return AUBIO_FAIL;
- }*/
- break;
- case MIDI_SET_TEMPO:
- if (player != NULL) {
- if (aubio_midi_player_set_midi_tempo(player, event->param1) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
- }
- break;
- case PROGRAM_CHANGE:
- AUBIO_MSG("Time=%f Program, chan=%d program=%d\n",
- print_time, event->channel, event->param1);
- /*if (aubio_synth_program_change(synth, event->channel, event->param1) != AUBIO_OK) {
- return AUBIO_FAIL;
- }*/
- break;
- case PITCH_BEND:
- AUBIO_MSG("Time=%f Pitchbend, chan=%d msb=%d lsb=%d \n",
- print_time, event->channel, event->param1, event->param2);
- /*if (aubio_synth_pitch_bend(synth, event->channel, event->param1) != AUBIO_OK) {
- return AUBIO_FAIL;
- }
- break;*/
- default:
- break;
- }
- return AUBIO_OK;
-}
-
-
-/**
- * aubio_midi_receive_event
- *
- * \note This could be moved to a callback function defined in the main programs
- */
-sint_t aubio_midi_receive_event(aubio_midi_player_t* player, aubio_midi_event_t* event)
-{
- /* current time in seconds */
- //smpl_t print_time = player->msec_passed * 1e-3;
- //smpl_t print_time = player->usec_passed * 1e-6;
- switch (event->type) {
- case NOTE_ON:
- break;
- case NOTE_OFF:
- break;
- default:
- break;
- }
- return AUBIO_OK;
-}
--- a/src/midi_player.h
+++ /dev/null
@@ -1,69 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-/** \file
- * midi player
- */
-
-
-#ifndef _AUBIO_MIDI_PLAYER_H
-#define _AUBIO_MIDI_PLAYER_H
-
-#define AUBIO_MIDI_PLAYER_MAX_TRACKS 128
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _aubio_midi_player_t aubio_midi_player_t;
-
-
-aubio_midi_player_t* new_aubio_midi_player(void);
-sint_t del_aubio_midi_player(aubio_midi_player_t* player);
-sint_t aubio_midi_player_reset(aubio_midi_player_t* player);
-sint_t aubio_midi_player_add_track(aubio_midi_player_t* player, aubio_track_t* track);
-sint_t aubio_midi_player_count_tracks(aubio_midi_player_t* player);
-aubio_track_t* aubio_midi_player_get_track(aubio_midi_player_t* player, sint_t i);
-sint_t aubio_midi_player_add(aubio_midi_player_t* player, char* midifile);
-sint_t aubio_midi_player_load(aubio_midi_player_t* player, char *filename);
-sint_t aubio_midi_player_callback(void* data, uint_t msec);
-sint_t aubio_midi_player_play(aubio_midi_player_t* player);
-sint_t aubio_midi_player_play_offline(aubio_midi_player_t* player);
-sint_t aubio_midi_player_stop(aubio_midi_player_t* player);
-sint_t aubio_midi_player_set_loop(aubio_midi_player_t* player, sint_t loop);
-sint_t aubio_midi_player_set_midi_tempo(aubio_midi_player_t* player, sint_t tempo);
-sint_t aubio_midi_player_set_bpm(aubio_midi_player_t* player, sint_t bpm);
-sint_t aubio_midi_player_join(aubio_midi_player_t* player);
-
-sint_t aubio_track_send_events(aubio_track_t* track,
-/* aubio_synth_t* synth, */
- aubio_midi_player_t* player,
- uint_t ticks);
-
-sint_t aubio_midi_send_event(aubio_midi_player_t* player, aubio_midi_event_t* event);
-sint_t aubio_midi_receive_event(aubio_midi_player_t* player, aubio_midi_event_t* event);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _AUBIO_MIDI_PLAYER_H*/
--- a/src/midi_track.c
+++ /dev/null
@@ -1,162 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-
-#include "aubio_priv.h"
-#include "midi.h"
-#include "midi_event.h"
-#include "midi_track.h"
-#include "midi_player.h"
-
-
-/** new_aubio_track */
-aubio_track_t* new_aubio_track(int num)
-{
- aubio_track_t* track;
- track = AUBIO_NEW(aubio_track_t);
- if (track == NULL) {
- return NULL;
- }
- track->name = NULL;
- track->num = num;
- track->first = NULL;
- track->cur = NULL;
- track->last = NULL;
- track->ticks = 0;
- return track;
-}
-
-/** del_aubio_track */
-int del_aubio_track(aubio_track_t* track)
-{
- if (track->name != NULL) {
- AUBIO_FREE(track->name);
- }
- if (track->first != NULL) {
- del_aubio_midi_event(track->first);
- }
- AUBIO_FREE(track);
- return AUBIO_OK;
-}
-
-/** aubio_track_set_name */
-int aubio_track_set_name(aubio_track_t* track, char* name)
-{
- int len;
- if (track->name != NULL) {
- AUBIO_FREE(track->name);
- }
- if (name == NULL) {
- track->name = NULL;
- return AUBIO_OK;
- }
- len = AUBIO_STRLEN(name);
- track->name = AUBIO_MALLOC(len + 1);
- if (track->name == NULL) {
- AUBIO_ERR( "Out of memory");
- return AUBIO_FAIL;
- }
- AUBIO_STRCPY(track->name, name);
- return AUBIO_OK;
-}
-
-/** aubio_track_get_name */
-char* aubio_track_get_name(aubio_track_t* track)
-{
- return track->name;
-}
-
-/** aubio_track_get_duration */
-int aubio_track_get_duration(aubio_track_t* track)
- {
- int time = 0;
- aubio_midi_event_t* evt = track->first;
- while (evt != NULL) {
- time += evt->dtime;
- evt = evt->next;
- }
- return time;
-}
-
-/** aubio_track_count_events */
-int aubio_track_count_events(aubio_track_t* track, int* on, int* off)
-{
- aubio_midi_event_t* evt = track->first;
- while (evt != NULL) {
- if (evt->type == NOTE_ON) {
- (*on)++;
- } else if (evt->type == NOTE_OFF) {
- (*off)++;
- }
- evt = evt->next;
- }
- return AUBIO_OK;
-}
-
-/*
- * aubio_track_add_event
- */
-int aubio_track_add_event(aubio_track_t* track, aubio_midi_event_t* evt)
-{
- evt->next = NULL;
- if (track->first == NULL) {
- track->first = evt;
- track->cur = evt;
- track->last = evt;
- } else {
- track->last->next = evt;
- track->last = evt;
- }
- return AUBIO_OK;
-}
-
-/*
- * aubio_track_first_event
- */
-aubio_midi_event_t* aubio_track_first_event(aubio_track_t* track)
-{
- track->cur = track->first;
- return track->cur;
-}
-
-/*
- * aubio_track_next_event
- */
-aubio_midi_event_t* aubio_track_next_event(aubio_track_t* track)
-{
- if (track->cur != NULL) {
- track->cur = track->cur->next;
- }
- return track->cur;
-}
-
-/*
- * aubio_track_reset
- */
- int
-aubio_track_reset(aubio_track_t* track)
-{
- track->ticks = 0;
- track->cur = track->first;
- return AUBIO_OK;
-}
-
--- a/src/midi_track.h
+++ /dev/null
@@ -1,67 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-#ifndef _AUBIO_MIDI_TRACK_H
-#define _AUBIO_MIDI_TRACK_H
-
-/** \file
- * midi track structure
- *
- * \bug need public declaration ?
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** aubio_track_t */
-struct _aubio_track_t {
- char* name;
- int num;
- aubio_midi_event_t *first;
- aubio_midi_event_t *cur;
- aubio_midi_event_t *last;
- unsigned int ticks;
-};
-
-typedef struct _aubio_track_t aubio_track_t;
-
-aubio_track_t* new_aubio_track(int num);
-int del_aubio_track(aubio_track_t* track);
-int aubio_track_set_name(aubio_track_t* track, char* name);
-char* aubio_track_get_name(aubio_track_t* track);
-int aubio_track_add_event(aubio_track_t* track, aubio_midi_event_t* evt);
-aubio_midi_event_t* aubio_track_first_event(aubio_track_t* track);
-aubio_midi_event_t* aubio_track_next_event(aubio_track_t* track);
-int aubio_track_get_duration(aubio_track_t* track);
-int aubio_track_reset(aubio_track_t* track);
-int aubio_track_count_events(aubio_track_t* track, int* on, int* off);
-
-
-#define aubio_track_eot(track) ((track)->cur == NULL)
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_AUBIO_MIDI_TRACK_H*/
--- a/src/timer.c
+++ /dev/null
@@ -1,551 +1,0 @@
-/*
- *
- * 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
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-/* this file originally taken from FluidSynth - A Software Synthesizer
- * Copyright (C) 2003 Peter Hanappe and others.
- */
-
-#include "aubio_priv.h"
-#include "timer.h"
-
-#if defined(WIN32)
-
-/*=============================================================*/
-/* */
-/* Win32 */
-/* */
-/*=============================================================*/
-
-/***************************************************************
- *
- * Timer
- *
- */
-#include <windef.h>
-
-#if 0
-#include <winbase.h>
-
-struct _aubio_timer_t
-{
- long msec;
- aubio_timer_callback_t callback;
- void* data;
- HANDLE thread;
- DWORD thread_id;
- int cont;
- int auto_destroy;
-};
-
-static int aubio_timer_count = 0;
-DWORD WINAPI aubio_timer_run(LPVOID data);
-
-aubio_timer_t*
-new_aubio_timer(int msec, aubio_timer_callback_t callback, void* data,
- int new_thread, int auto_destroy)
-{
- aubio_timer_t* timer = AUBIO_NEW(aubio_timer_t);
- if (timer == NULL) {
- AUBIO_ERR( "Out of memory");
- return NULL;
- }
-
- timer->cont = 1;
- timer->msec = msec;
- timer->callback = callback;
- timer->data = data;
- timer->thread = 0;
- timer->auto_destroy = auto_destroy;
-
- if (new_thread) {
- timer->thread = CreateThread(NULL, 0, aubio_timer_run, (LPVOID) timer, 0, &timer->thread_id);
- if (timer->thread == NULL) {
- AUBIO_ERR( "Couldn't create timer thread");
- AUBIO_FREE(timer);
- return NULL;
- }
- SetThreadPriority(timer->thread, THREAD_PRIORITY_TIME_CRITICAL);
- } else {
- aubio_timer_run((LPVOID) timer);
- }
- return timer;
-}
-
-DWORD WINAPI
-aubio_timer_run(LPVOID data)
-{
- int count = 0;
- int cont = 1;
- long start;
- long delay;
- aubio_timer_t* timer;
- timer = (aubio_timer_t*) data;
-
- if ((timer == NULL) || (timer->callback == NULL)) {
- return 0;
- }
-
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
-
- /* keep track of the start time for absolute positioning */
- start = aubio_curtime();
-
- while (cont) {
-
- /* do whatever we have to do */
- cont = (*timer->callback)(timer->data, aubio_curtime() - start);
-
- count++;
-
- /* to avoid incremental time errors, I calculate the delay between
- two callbacks bringing in the "absolute" time (count *
- timer->msec) */
- delay = (count * timer->msec) - (aubio_curtime() - start);
- if (delay > 0) {
- Sleep(delay);
- }
-
- cont &= timer->cont;
- }
-
- AUBIO_DBG( "Timer thread finished");
-
- if (timer->auto_destroy) {
- AUBIO_FREE(timer);
- }
-
- ExitThread(0);
- return 0;
-}
-
-int
-delete_aubio_timer(aubio_timer_t* timer)
-{
- timer->cont = 0;
- aubio_timer_join(timer);
- AUBIO_FREE(timer);
- return AUBIO_OK;
-}
-
-int
-aubio_timer_join(aubio_timer_t* timer)
-{
- DWORD wait_result;
- if (timer->thread == 0) {
- return AUBIO_OK;
- }
- wait_result = WaitForSingleObject(timer->thread, INFINITE);
- return (wait_result == WAIT_OBJECT_0)? AUBIO_OK : AUBIO_FAIL;
-}
-/***************************************************************
- *
- * Time
- */
-
-double rdtsc(void);
-double aubio_estimate_cpu_frequency(void);
-
-static double aubio_cpu_frequency = -1.0;
-
-void aubio_time_config(void)
-{
- if (aubio_cpu_frequency < 0.0) {
- aubio_cpu_frequency = aubio_estimate_cpu_frequency() / 1000000.0;
- }
-}
-
-double aubio_utime(void)
-{
- return (rdtsc() / aubio_cpu_frequency);
-}
-
-double rdtsc(void)
-{
- LARGE_INTEGER t;
- QueryPerformanceCounter(&t);
- return (double) t.QuadPart;
-}
-
-double aubio_estimate_cpu_frequency(void)
-{
-#if 0
- LONGLONG start, stop, ticks;
- unsigned int before, after, delta;
- double freq;
-
- start = rdtsc();
- stop = start;
- before = aubio_curtime();
- after = before;
-
- while (1) {
- if (after - before > 1000) {
- break;
- }
- after = aubio_curtime();
- stop = rdtsc();
- }
-
- delta = after - before;
- ticks = stop - start;
-
- freq = 1000 * ticks / delta;
-
- return freq;
-
-#else
- unsigned int before, after;
- LARGE_INTEGER start, stop;
-
- before = aubio_curtime();
- QueryPerformanceCounter(&start);
-
- Sleep(1000);
-
- after = aubio_curtime();
- QueryPerformanceCounter(&stop);
-
- return (double) 1000 * (stop.QuadPart - start.QuadPart) / (after - before);
-#endif
-}
-
-#endif
-
-
-#elif defined(MACOS9)
-/*=============================================================*/
-/* */
-/* MacOS 9 */
-/* */
-/*=============================================================*/
-
-
-/***************************************************************
- *
- * Timer
- */
-
-struct _aubio_timer_t
-{
- TMTask myTmTask;
- long msec;
- unsigned int start;
- unsigned int count;
- int isInstalled;
- aubio_timer_callback_t callback;
- void* data;
- int auto_destroy;
-};
-
-static TimerUPP myTimerUPP;
-
-void
-_timerCallback(aubio_timer_t *timer)
-{
- int cont;
- cont = (*timer->callback)(timer->data, aubio_curtime() - timer->start);
- if (cont) {
- PrimeTime((QElemPtr)timer, timer->msec);
- } else {
- timer->isInstalled = 0;
- }
- timer->count++;
-}
-
-aubio_timer_t*
-new_aubio_timer(int msec, aubio_timer_callback_t callback, void* data,
- int new_thread, int auto_destroy)
-{
- aubio_timer_t* timer = AUBIO_NEW(aubio_timer_t);
- if (timer == NULL) {
- AUBIO_ERR( "Out of memory");
- return NULL;
- }
-
- if (!myTimerUPP)
- myTimerUPP = NewTimerProc(_timerCallback);
-
- /* setup tmtask */
- timer->myTmTask.tmAddr = myTimerUPP;
- timer->myTmTask.qLink = NULL;
- timer->myTmTask.qType = 0;
- timer->myTmTask.tmCount = 0L;
- timer->myTmTask.tmWakeUp = 0L;
- timer->myTmTask.tmReserved = 0L;
-
- timer->callback = callback;
-
- timer->msec = msec;
- timer->data = data;
- timer->start = aubio_curtime();
- timer->isInstalled = 1;
- timer->count = 0;
- timer->auto_destroy = auto_destroy;
-
- InsXTime((QElemPtr)timer);
- PrimeTime((QElemPtr)timer, msec);
-
- return timer;
-}
-
-int
-delete_aubio_timer(aubio_timer_t* timer)
-{
- if (timer->isInstalled) {
- RmvTime((QElemPtr)timer);
- }
- AUBIO_FREE(timer);
- return AUBIO_OK;
-}
-
-int
-aubio_timer_join(aubio_timer_t* timer)
-{
- if (timer->isInstalled) {
- int count = timer->count;
- /* wait until count has incremented */
- while (count == timer->count) {}
- }
- return AUBIO_OK;
-}
-
-/***************************************************************
- *
- * Time
- */
-#define kTwoPower32 (4294967296.0) /* 2^32 */
-
-void aubio_time_config(void)
-{
-}
-
-unsigned int aubio_curtime()
-{
- /* could be optimized by not going though a double */
- UnsignedWide uS;
- double mSf;
- unsigned int ms;
-
- Microseconds(&uS);
-
- mSf = ((((double) uS.hi) * kTwoPower32) + uS.lo)/1000.0f;
-
- ms = mSf;
-
- return (ms);
-}
-
-
-
-#else
-
-/*=============================================================*/
-/* */
-/* POSIX */
-/* */
-/*=============================================================*/
-
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-
-/***************************************************************
- *
- * Timer
- */
-
-struct _aubio_timer_t
-{
- long msec;
- aubio_timer_callback_t callback;
- void* data;
- pthread_t thread;
- int cont;
- int auto_destroy;
-};
-
-void*
-aubio_timer_start(void *data)
-{
- int count = 0;
- int cont = 1;
- long start;
- long delay;
- aubio_timer_t* timer;
- timer = (aubio_timer_t*) data;
-
- /* keep track of the start time for absolute positioning */
- start = aubio_curtime();
-
- while (cont) {
-
- /* do whatever we have to do */
- cont = (*timer->callback)(timer->data, aubio_curtime() - start);
-
- count++;
-
- /* to avoid incremental time errors, calculate the delay between
- two callbacks bringing in the "absolute" time (count *
- timer->msec) */
- delay = (count * timer->msec) - (aubio_curtime() - start);
- if (delay > 0) {
- usleep(delay * 1000);
- }
-
- cont &= timer->cont;
- }
-
- AUBIO_DBG( "Timer thread finished");
- if (timer->thread != 0) {
- pthread_exit(NULL);
- }
-
- if (timer->auto_destroy) {
- AUBIO_FREE(timer);
- }
-
- return NULL;
-}
-
-aubio_timer_t*
-new_aubio_timer(int msec, aubio_timer_callback_t callback, void* data,
- int new_thread, int auto_destroy)
-{
- aubio_timer_t* timer = AUBIO_NEW(aubio_timer_t);
- if (timer == NULL) {
- AUBIO_ERR( "Out of memory");
- return NULL;
- }
- timer->msec = msec;
- timer->callback = callback;
- timer->data = data;
- timer->cont = 1;
- timer->thread = 0;
- timer->auto_destroy = auto_destroy;
-
- if (new_thread) {
- if (pthread_create(&timer->thread, NULL, aubio_timer_start, (void*) timer)) {
- AUBIO_ERR( "Failed to create the timer thread");
- AUBIO_FREE(timer);
- return NULL;
- }
- } else {
- aubio_timer_start((void*) timer);
- }
- return timer;
-}
-
-int
-delete_aubio_timer(aubio_timer_t* timer)
-{
- timer->cont = 0;
- aubio_timer_join(timer);
- AUBIO_DBG( "Deleted player thread\n");
- AUBIO_FREE(timer);
- return AUBIO_OK;
-}
-
-int
-aubio_timer_join(aubio_timer_t* timer)
-{
- int err = 0;
-
- if (timer->thread != 0) {
- err = pthread_join(timer->thread, NULL);
- } else
- AUBIO_DBG( "Joined player thread\n");
- return (err == 0)? AUBIO_OK : AUBIO_FAIL;
-}
-
-
-/***************************************************************
- *
- * Time
- */
-
-static double aubio_cpu_frequency = -1.0;
-
-double rdtsc(void);
-double aubio_estimate_cpu_frequency(void);
-
-void aubio_time_config(void)
-{
- if (aubio_cpu_frequency < 0.0) {
- aubio_cpu_frequency = aubio_estimate_cpu_frequency() / 1000000.0;
- }
-}
-
-unsigned int aubio_curtime()
-{
- struct timeval now;
- gettimeofday(&now, NULL);
- return now.tv_sec * 1000 + now.tv_usec / 1000;
-}
-
-double aubio_utime(void)
-{
- return (rdtsc() / aubio_cpu_frequency);
-}
-
-#if !defined(__i386__)
-
-double rdtsc(void)
-{
- return 0.0;
-}
-
-double aubio_estimate_cpu_frequency(void)
-{
- return 1.0;
-}
-
-#else
-
-double rdtsc(void)
-{
- unsigned int a, b;
-
- __asm__ ("rdtsc" : "=a" (a), "=d" (b));
- return (double)b * (double)0x10000 * (double)0x10000 + a;
-}
-
-double aubio_estimate_cpu_frequency(void)
-{
- double start, stop;
- unsigned int a0, b0, a1, b1;
- unsigned int before, after;
-
- before = aubio_curtime();
- __asm__ ("rdtsc" : "=a" (a0), "=d" (b0));
-
- sleep(1);
-
- after = aubio_curtime();
- __asm__ ("rdtsc" : "=a" (a1), "=d" (b1));
-
-
- start = (double)b0 * (double)0x10000 * (double)0x10000 + a0;
- stop = (double)b1 * (double)0x10000 * (double)0x10000 + a1;
-
- return 1000 * (stop - start) / (after - before);
-}
-
-#endif
-
-#endif
--- a/src/timer.h
+++ /dev/null
@@ -1,34 +1,0 @@
-
-#if defined(WIN32)
-#define aubio_curtime() GetTickCount()
-
-double aubio_utime(void);
-
-#elif defined(MACOS9)
-#include <OSUtils.h>
-#include <Timer.h>
-
-unsigned int aubio_curtime();
-#define aubio_utime() 0.0
-
-#else
-
-unsigned int aubio_curtime(void);
-double aubio_utime(void);
-
-#endif
-
-/* if the callback function returns 1 the timer will continue; if it
- returns 0 it will stop */
-typedef int (*aubio_timer_callback_t)(void* data, unsigned int msec);
-
-typedef struct _aubio_timer_t aubio_timer_t;
-
-aubio_timer_t* new_aubio_timer(int msec, aubio_timer_callback_t callback,
- void* data, int new_thread, int auto_destroy);
-
-int delete_aubio_timer(aubio_timer_t* timer);
-int aubio_timer_join(aubio_timer_t* timer);
-int aubio_timer_stop(aubio_timer_t* timer);
-void * aubio_timer_start(void * data);
-void aubio_time_config(void);