... this way, fluidsynth can be used as output of a midi sequencer. ok?
-- Alexandre Index: Makefile =================================================================== RCS file: /cvs/ports/audio/fluidsynth/Makefile,v retrieving revision 1.5 diff -u -p -r1.5 Makefile --- Makefile 6 Mar 2009 21:24:52 -0000 1.5 +++ Makefile 18 May 2009 15:47:29 -0000 @@ -2,7 +2,7 @@ COMMENT = SoundFont2 software synthesizer DISTNAME = fluidsynth-1.0.8 -PKGNAME = ${DISTNAME}p2 +PKGNAME = ${DISTNAME}p3 SHARED_LIBS = fluidsynth 0.0 Index: files/fluid_libsndio.c =================================================================== RCS file: /cvs/ports/audio/fluidsynth/files/fluid_libsndio.c,v retrieving revision 1.1 diff -u -p -r1.1 fluid_libsndio.c --- files/fluid_libsndio.c 26 Dec 2008 08:45:12 -0000 1.1 +++ files/fluid_libsndio.c 18 May 2009 15:47:29 -0000 @@ -23,6 +23,8 @@ #include "fluid_synth.h" #include "fluid_adriver.h" +#include "fluid_midi.h" +#include "fluid_mdriver.h" #include "fluid_settings.h" #if LIBSNDIO_SUPPORT @@ -56,6 +58,14 @@ typedef struct { float* buffers[2]; } fluid_libsndio_audio_driver_t; +typedef struct { + fluid_midi_driver_t driver; + struct mio_hdl *hdl; + pthread_t thread; + int status; + fluid_midi_parser_t *parser; +} fluid_libsndio_midi_driver_t; + int delete_fluid_libsndio_audio_driver(fluid_audio_driver_t* p); /* local utilities */ @@ -368,5 +378,153 @@ fluid_libsndio_audio_run2(void* d) return 0; /* not reached */ } +void fluid_libsndio_midi_driver_settings(fluid_settings_t* settings) +{ + fluid_settings_register_str(settings, "midi.libsndio.device", NULL, 0, NULL, NULL); +} + +int +delete_fluid_libsndio_midi_driver(fluid_midi_driver_t *addr) +{ + int err; + fluid_libsndio_midi_driver_t *dev = (fluid_libsndio_midi_driver_t *)addr; + + if (dev == NULL) { + return FLUID_OK; + } + dev->status = FLUID_MIDI_DONE; + + /* cancel the thread and wait for it before cleaning up */ + if (dev->thread) { + err = pthread_cancel(dev->thread); + if (err) { + FLUID_LOG(FLUID_ERR, "Failed to cancel the midi thread"); + return FLUID_FAILED; + } + if (pthread_join(dev->thread, NULL)) { + FLUID_LOG(FLUID_ERR, "Failed to join the midi thread"); + return FLUID_FAILED; + } + } + if (dev->hdl != NULL) { + mio_close(dev->hdl); + } + if (dev->parser != NULL) { + delete_fluid_midi_parser(dev->parser); + } + FLUID_FREE(dev); + return FLUID_OK; +} + +void * +fluid_libsndio_midi_run(void *addr) +{ + int n, i; + fluid_midi_event_t* evt; + fluid_libsndio_midi_driver_t *dev = (fluid_libsndio_midi_driver_t *)addr; +#define MIDI_BUFLEN (3125 / 10) + unsigned char buffer[MIDI_BUFLEN]; + + /* make sure the other threads can cancel this thread any time */ + if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) { + FLUID_LOG(FLUID_ERR, "Failed to set the cancel state of the midi thread"); + pthread_exit(NULL); + } + if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { + FLUID_LOG(FLUID_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 = FLUID_MIDI_LISTENING; + + while (dev->status == FLUID_MIDI_LISTENING) { + + /* read new data */ + n = mio_read(dev->hdl, buffer, MIDI_BUFLEN); + if (n == 0 && mio_eof(dev->hdl)) { + fprintf(stderr, "cant read midi device\n"); + FLUID_LOG(FLUID_ERR, "Failed to read the midi input"); + dev->status = FLUID_MIDI_DONE; + } + + /* let the parser convert the data into events */ + for (i = 0; i < n; i++) { + evt = fluid_midi_parser_parse(dev->parser, buffer[i]); + if (evt != NULL) { + /* send the event to the next link in the chain */ + (*dev->driver.handler)(dev->driver.data, evt); + } + } + } + pthread_exit(NULL); +} + +int +fluid_libsndio_midi_driver_status(fluid_midi_driver_t *addr) +{ + fluid_libsndio_midi_driver_t *dev = (fluid_libsndio_midi_driver_t *)addr; + return dev->status; +} + + +fluid_midi_driver_t * +new_fluid_libsndio_midi_driver(fluid_settings_t *settings, + handle_midi_event_func_t handler, void *data) +{ + int err; + fluid_libsndio_midi_driver_t *dev; + char *device; + + /* not much use doing anything */ + if (handler == NULL) { + FLUID_LOG(FLUID_ERR, "Invalid argument"); + return NULL; + } + + /* allocate the device */ + dev = FLUID_NEW(fluid_libsndio_midi_driver_t); + if (dev == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return NULL; + } + FLUID_MEMSET(dev, 0, sizeof(fluid_libsndio_midi_driver_t)); + dev->hdl = NULL; + + dev->driver.handler = handler; + dev->driver.data = data; + + /* allocate one event to store the input data */ + dev->parser = new_fluid_midi_parser(); + if (dev->parser == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory"); + goto error_recovery; + } + + /* get the device name. if none is specified, use the default device. */ + if (!fluid_settings_getstr(settings, "midi.libsndio.device", &device)) { + device = NULL; + } + + /* open the default hardware device. only use midi in. */ + dev->hdl = mio_open(device, MIO_IN, 0); + if (dev->hdl == NULL) { + fprintf(stderr, "%s: couldn't open midi device\n"); + goto error_recovery; + } + + dev->status = FLUID_MIDI_READY; + + err = pthread_create(&dev->thread, NULL, fluid_libsndio_midi_run, (void *)dev); + if (err) { + FLUID_LOG(FLUID_PANIC, "Couldn't create the midi thread."); + goto error_recovery; + } + return (fluid_midi_driver_t *) dev; + + error_recovery: + delete_fluid_libsndio_midi_driver((fluid_midi_driver_t *)dev); + return NULL; +} #endif /*#if LIBSNDIO_SUPPORT */ Index: patches/patch-src_fluid_mdriver_c =================================================================== RCS file: /cvs/ports/audio/fluidsynth/patches/patch-src_fluid_mdriver_c,v retrieving revision 1.1 diff -u -p -r1.1 patch-src_fluid_mdriver_c --- patches/patch-src_fluid_mdriver_c 26 Dec 2008 08:45:12 -0000 1.1 +++ patches/patch-src_fluid_mdriver_c 18 May 2009 15:47:29 -0000 @@ -1,9 +1,18 @@ -$OpenBSD: patch-src_fluid_mdriver_c,v 1.1 2008/12/26 08:45:12 jakemsr Exp $ ---- src/fluid_mdriver.c.orig Sat Dec 20 17:42:12 2008 -+++ src/fluid_mdriver.c Sat Dec 20 17:43:01 2008 -@@ -38,13 +38,13 @@ void fluid_alsa_seq_driver_settings(fluid_settings_t* +--- src/fluid_mdriver.c.orig Sat Aug 18 23:53:17 2007 ++++ src/fluid_mdriver.c Mon May 18 16:34:43 2009 +@@ -37,14 +37,23 @@ int delete_fluid_alsa_seq_driver(fluid_midi_driver_t* + void fluid_alsa_seq_driver_settings(fluid_settings_t* settings); #endif ++/* LIBSNDIO */ ++#if LIBSNDIO_SUPPORT ++fluid_midi_driver_t* new_fluid_libsndio_midi_driver(fluid_settings_t* settings, ++ handle_midi_event_func_t handler, ++ void* event_handler_data); ++int delete_fluid_libsndio_midi_driver(fluid_midi_driver_t* p); ++void fluid_libsndio_midi_driver_settings(fluid_settings_t* settings); ++#endif ++ /* OSS */ -#if OSS_SUPPORT +/* #if OSS_SUPPORT */ @@ -17,7 +26,7 @@ $OpenBSD: patch-src_fluid_mdriver_c,v 1. /* Windows MIDI service */ #if WINMIDI_SUPPORT -@@ -78,12 +78,12 @@ struct fluid_mdriver_definition_t { +@@ -78,12 +87,12 @@ struct fluid_mdriver_definition_t { struct fluid_mdriver_definition_t fluid_midi_drivers[] = { @@ -32,3 +41,35 @@ $OpenBSD: patch-src_fluid_mdriver_c,v 1. #if ALSA_SUPPORT { "alsa_raw", new_fluid_alsa_rawmidi_driver, +@@ -94,6 +103,12 @@ struct fluid_mdriver_definition_t fluid_midi_drivers[] + delete_fluid_alsa_seq_driver, + fluid_alsa_seq_driver_settings }, + #endif ++#if LIBSNDIO_SUPPORT ++ { "libsndio", ++ new_fluid_libsndio_midi_driver, ++ delete_fluid_libsndio_midi_driver, ++ fluid_libsndio_midi_driver_settings }, ++#endif + #if WINMIDI_SUPPORT + { "winmidi", + new_fluid_winmidi_driver, +@@ -118,6 +133,8 @@ void fluid_midi_driver_settings(fluid_settings_t* sett + /* Set the default driver */ + #if ALSA_SUPPORT + fluid_settings_register_str(settings, "midi.driver", "alsa_seq", 0, NULL, NULL); ++#elif LIBSNDIO_SUPPORT ++ fluid_settings_register_str(settings, "midi.driver", "libsndio", 0, NULL, NULL); + #elif OSS_SUPPORT + fluid_settings_register_str(settings, "midi.driver", "oss", 0, NULL, NULL); + #elif WINMIDI_SUPPORT +@@ -132,6 +149,9 @@ void fluid_midi_driver_settings(fluid_settings_t* sett + #if ALSA_SUPPORT + fluid_settings_add_option(settings, "midi.driver", "alsa_seq"); + fluid_settings_add_option(settings, "midi.driver", "alsa_raw"); ++#endif ++#if LIBSNDIO_SUPPORT ++ fluid_settings_add_option(settings, "midi.driver", "libsndio"); + #endif + #if OSS_SUPPORT + fluid_settings_add_option(settings, "midi.driver", "oss");