Basic CoreMIDI driver (Mac OSX). Ticket #18

This commit is contained in:
Pedro Lopez-Cabanillas 2009-01-08 22:47:55 +00:00
parent 291810dfe1
commit 8c31f07f81
7 changed files with 203 additions and 4 deletions

View file

@ -1,12 +1,18 @@
#!/bin/sh
# Add flags for aclocal if needed (Mac OSX)
ACLOCAL_PATH=""
uname -s | grep -q Darwin
if [ $? -eq 0 ]; then
ACLOCAL_FLAGS=-I/sw/share/aclocal
fi
# Some poor souls have linux distributions, that don't install pkg-config by default.
#pkg-config --version does actually nothing, but it will fail and give 'sort of' an error message...
pkg-config --version > /dev/null \
&& aclocal \
&& aclocal $ACLOCAL_FLAGS \
&& libtoolize -f \
&& autoheader \
&& autoconf \
&& automake -a

View file

@ -245,6 +245,24 @@ fi
AM_CONDITIONAL(COREAUDIO_SUPPORT, test "$COREAUDIO_SUPPORT" = "1")
AC_SUBST(COREAUDIO_LIBS)
dnl
dnl - Check support for CoreMIDI
dnl
AC_CHECK_HEADER(CoreMIDI/MIDIServices.h, COREMIDI_FOUND="yes",
COREMIDI_FOUND="no")
AC_ARG_ENABLE(coremidi, AS_HELP_STRING([--disable-coremidi],
[disable CoreMIDI support (default=auto)]),
enable_coremidi=$enableval, enable_coremidi="yes")
COREMIDI_SUPPORT=0
if test "$enable_coremidi" = "yes" -a "$COREMIDI_FOUND" = "yes"; then
AC_DEFINE(COREMIDI_SUPPORT, 1, [whether or not we are supporting CoreMIDI])
COREMIDI_SUPPORT=1
COREMIDI_LIBS="-Wl,-framework,CoreMIDI"
fi
AM_CONDITIONAL(COREMIDI_SUPPORT, test "$COREMIDI_SUPPORT" = "1")
AC_SUBST(COREMIDI_LIBS)
dnl
dnl Check for readline support (Josh Green 2003-06-10)
dnl
@ -386,6 +404,12 @@ else
echo "CoreAudio: no"
fi
if test "${COREMIDI_SUPPORT}" = "1"; then
echo "CoreMIDI: yes"
else
echo "CoreMIDI: no"
fi
if test "${ENABLE_LADSPA}" = "yes"; then
echo "LADSPA support: yes"
else

View file

@ -13,6 +13,10 @@ if COREAUDIO_SUPPORT
fluid_coreaudio = fluid_coreaudio.c
endif
if COREMIDI_SUPPORT
fluid_coremidi = fluid_coremidi.c
endif
if JACK_SUPPORT
fluid_jack = fluid_jack.c
endif
@ -48,6 +52,7 @@ bin_PROGRAMS = fluidsynth
libfluidsynth_la_SOURCES = \
$(fluid_alsa) \
$(fluid_coreaudio) \
$(fluid_coremidi) \
$(fluid_jack) \
$(fluid_lash) \
$(fluid_oss) \
@ -113,7 +118,8 @@ INCLUDES = -I$(top_srcdir)/include $(LASH_CFLAGS) $(LADCCA_CFLAGS) \
$(READLINE_CFLAGS) $(JACK_CFLAGS) $(ALSA_CFLAGS) $(PULSE_CFLAGS)
libfluidsynth_la_LIBADD = $(LIBFLUID_LIBS) $(LASH_LIBS) $(LADCCA_LIBS) \
$(READLINE_LIBS) $(COREAUDIO_LIBS) $(JACK_LIBS) $(ALSA_LIBS) $(PULSE_LIBS)
$(READLINE_LIBS) $(COREAUDIO_LIBS) $(COREMIDI_LIBS) $(JACK_LIBS) \
$(ALSA_LIBS) $(PULSE_LIBS)
libfluidsynth_la_LDFLAGS = \
-version-info @LT_VERSION_INFO@ \
-export-dynamic $(LIBFLUID_LDFLAGS)

View file

@ -13,6 +13,7 @@
#define MIDISHARE_SUPPORT 1
#define MIDISHARE_DRIVER 1
#define PORTAUDIO_SUPPORT 1
#define PORTMIDI_SUPPORT 1
#define __Types__
/* define to support DARWIN */

View file

@ -25,6 +25,7 @@
#define WITHOUT_SERVER 1
#define COREAUDIO_SUPPORT 1
#define COREMIDI_SUPPORT 1
/* define to support the MidiShare driver */
/*

View file

@ -0,0 +1,143 @@
/* FluidSynth - A Software Synthesizer
*
* 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
*/
/* fluid_coremidi.c
*
* Driver for Mac OSX native MIDI
* Pedro Lopez-Cabanillas, Jan 2009
*/
#include "fluidsynth_priv.h"
#if COREMIDI_SUPPORT
#include "fluid_midi.h"
#include "fluid_mdriver.h"
#include <CoreServices/CoreServices.h>
#include <CoreMIDI/MIDIServices.h>
typedef struct {
fluid_midi_driver_t driver;
MIDIClientRef client;
MIDIEndpointRef endpoint;
fluid_midi_parser_t* parser;
} fluid_coremidi_driver_t;
fluid_midi_driver_t* new_fluid_coremidi_driver(fluid_settings_t* settings,
handle_midi_event_func_t handler, void* data);
int delete_fluid_coremidi_driver(fluid_midi_driver_t* p);
void fluid_coremidi_callback(const MIDIPacketList *list, void *p, void *src);
/*
* new_fluid_coremidi_driver
*/
fluid_midi_driver_t*
new_fluid_coremidi_driver(fluid_settings_t* settings, handle_midi_event_func_t handler, void* data)
{
fluid_coremidi_driver_t* dev;
MIDIClientRef client;
MIDIEndpointRef endpoint;
/* not much use doing anything */
if (handler == NULL) {
FLUID_LOG(FLUID_ERR, "Invalid argument");
return NULL;
}
dev = FLUID_MALLOC(sizeof(fluid_coremidi_driver_t));
if (dev == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
dev->client = 0;
dev->endpoint = 0;
dev->parser = 0;
dev->driver.handler = handler;
dev->driver.data = data;
dev->parser = new_fluid_midi_parser();
if (dev->parser == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
goto error_recovery;
}
OSStatus result = MIDIClientCreate( CFSTR("Fluidsynth"), NULL, NULL, &client );
if ( result != noErr ) {
FLUID_LOG(FLUID_ERR, "Failed to create the MIDI input client");
goto error_recovery;
}
dev->client = client;
result = MIDIDestinationCreate( client, CFSTR("Fluidsynth virtual port"),
fluid_coremidi_callback, (void *)dev, &endpoint );
if ( result != noErr ) {
FLUID_LOG(FLUID_ERR, "Failed to create the MIDI input port. MIDI input not available.");
goto error_recovery;
}
dev->endpoint = endpoint;
return (fluid_midi_driver_t*) dev;
error_recovery:
delete_fluid_coremidi_driver((fluid_midi_driver_t*) dev);
return NULL;
}
/*
* delete_fluid_coremidi_driver
*/
int
delete_fluid_coremidi_driver(fluid_midi_driver_t* p)
{
fluid_coremidi_driver_t* dev = (fluid_coremidi_driver_t*) p;
if (dev->client != NULL) {
MIDIClientDispose(dev->client);
}
if (dev->endpoint != NULL) {
MIDIEndpointDispose(dev->endpoint);
}
if (dev->parser != NULL) {
delete_fluid_midi_parser(dev->parser);
}
FLUID_FREE(dev);
return 0;
}
void
fluid_coremidi_callback(const MIDIPacketList *list, void *p, void *src)
{
unsigned int i, j;
fluid_midi_event_t* event;
fluid_coremidi_driver_t* dev = (fluid_coremidi_driver_t *)p;
const MIDIPacket *packet = &list->packet[0];
for ( i = 0; i < list->numPackets; ++i ) {
for ( j = 0; j < packet->length; ++j ) {
event = fluid_midi_parser_parse(dev->parser, packet->data[j]);
if (event != NULL) {
(*dev->driver.handler)(dev->driver.data, event);
}
}
packet = MIDIPacketNext(packet);
}
}
#endif /* COREMIDI_SUPPORT */

View file

@ -63,6 +63,13 @@ fluid_midi_driver_t* new_fluid_midishare_midi_driver(fluid_settings_t* settings,
int delete_fluid_midishare_midi_driver(fluid_midi_driver_t* p);
#endif
/* definitions for the CoreMidi driver */
#if COREMIDI_SUPPORT
fluid_midi_driver_t* new_fluid_coremidi_driver(fluid_settings_t* settings,
void* event_handler_data,
handle_midi_event_func_t handler);
int delete_fluid_coremidi_driver(fluid_midi_driver_t* p);
#endif
/*
@ -106,6 +113,12 @@ struct fluid_mdriver_definition_t fluid_midi_drivers[] = {
new_fluid_midishare_midi_driver,
delete_fluid_midishare_midi_driver,
NULL },
#endif
#if COREMIDI_SUPPORT
{ "coremidi",
new_fluid_coremidi_driver,
delete_fluid_coremidi_driver,
NULL },
#endif
{ NULL, NULL, NULL, NULL }
};
@ -125,6 +138,8 @@ void fluid_midi_driver_settings(fluid_settings_t* settings)
fluid_settings_register_str(settings, "midi.driver", "winmidi", 0, NULL, NULL);
#elif MIDISHARE_SUPPORT
fluid_settings_register_str(settings, "midi.driver", "midishare", 0, NULL, NULL);
#elif COREMIDI_SUPPORT
fluid_settings_register_str(settings, "midi.driver", "coremidi", 0, NULL, NULL);
#else
fluid_settings_register_str(settings, "midi.driver", "", 0, NULL, NULL);
#endif
@ -143,6 +158,9 @@ void fluid_midi_driver_settings(fluid_settings_t* settings)
#if MIDISHARE_SUPPORT
fluid_settings_add_option(settings, "midi.driver", "midishare");
#endif
#if COREMIDI_SUPPORT
fluid_settings_add_option(settings, "midi.driver", "coremidi");
#endif
for (i = 0; fluid_midi_drivers[i].name != NULL; i++) {
if (fluid_midi_drivers[i].settings != NULL) {
@ -169,7 +187,7 @@ fluid_midi_driver_t* new_fluid_midi_driver(fluid_settings_t* settings, handle_mi
FLUID_LOG(FLUID_DBG, "Using '%s' midi driver", fluid_midi_drivers[i].name);
driver = fluid_midi_drivers[i].new(settings, handler, event_handler_data);
if (driver) {
driver->name = fluid_midi_drivers[i].name;
driver->name = fluid_midi_drivers[i].name;
}
return driver;
}