From 8b7bf5ac764bfdb1ef526f3d31935eb013083dc0 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Sun, 14 Apr 2019 17:27:45 +1000 Subject: [PATCH 1/6] Add Haiku MediaKit support --- CMakeLists.txt | 19 +++++ cmake_admin/report.cmake | 6 ++ src/CMakeLists.txt | 5 ++ src/config.cmake | 3 + src/drivers/fluid_adriver.c | 10 +++ src/drivers/fluid_adriver.h | 7 ++ src/drivers/fluid_haiku.cpp | 140 ++++++++++++++++++++++++++++++++++++ src/synth/fluid_synth.c | 21 ++++++ src/utils/fluid_sys.h | 2 +- 9 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 src/drivers/fluid_haiku.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 75b8862a..831f29c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,7 @@ option ( enable-dsound "compile DirectSound support (if it is available)" on ) option ( enable-wasapi "compile Windows WASAPI support (if it is available)" on ) option ( enable-waveout "compile Windows WaveOut support (if it is available)" on ) option ( enable-winmidi "compile Windows MIDI support (if it is available)" on ) +option ( enable-haiku "compile Haiku MediaKit audio support (if it is available)" on ) option ( enable-sdl2 "compile SDL2 audio support (if it is available)" off ) option ( enable-pulseaudio "compile PulseAudio support (if it is available)" on ) option ( enable-pipewire "compile PipeWire support (if it is available)" on ) @@ -186,8 +187,10 @@ endif () include ( CMakePrintHelpers ) # for cmake_print_properties() and cmake_print_variables() include ( TestInline ) include ( TestVLA ) +if ( NOT HAIKU ) include ( TestBigEndian ) test_big_endian ( WORDS_BIGENDIAN ) +endif ( NOT HAIKU ) unset ( LIBFLUID_CPPFLAGS CACHE ) unset ( LIBFLUID_LIBS CACHE ) @@ -249,6 +252,11 @@ if ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_C endif (CMAKE_C_COMPILER_ID STREQUAL "Intel" ) endif ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "Intel" ) +# Haiku +if ( HAIKU ) +set ( CMAKE_CXX_FLAGS "-fpermissive") +endif ( HAIKU ) + # Windows unset ( WINDOWS_LIBS CACHE ) unset ( DSOUND_SUPPORT CACHE ) @@ -395,6 +403,12 @@ if ( CMAKE_SYSTEM MATCHES "SunOS" ) set ( LIBFLUID_LIBS "${LIBFLUID_LIBS};nsl;socket" ) endif ( CMAKE_SYSTEM MATCHES "SunOS" ) +# Haiku +if ( CMAKE_SYSTEM MATCHES "Haiku" ) + set ( FLUID_LIBS "${FLUID_LIBS};network;bsd;be;media" ) + set ( LIBFLUID_LIBS "${LIBFLUID_LIBS};network;bsd;be;media" ) +endif ( CMAKE_SYSTEM MATCHES "Haiku" ) + # Apple Mac OSX unset ( COREAUDIO_SUPPORT CACHE ) unset ( COREAUDIO_LIBS CACHE ) @@ -708,6 +722,11 @@ if ( enable-readline ) endif ( Readline_FOUND ) endif ( enable-readline ) +unset ( HAIKU_SUPPORT CACHE ) +if ( enable-haiku ) + set ( HAIKU_SUPPORT 1 ) +endif ( enable-haiku ) + unset ( AUFILE_SUPPORT CACHE ) if ( enable-aufile ) set ( AUFILE_SUPPORT 1 ) diff --git a/cmake_admin/report.cmake b/cmake_admin/report.cmake index e2fe5055..391cdd78 100644 --- a/cmake_admin/report.cmake +++ b/cmake_admin/report.cmake @@ -154,6 +154,12 @@ else ( DBUS_SUPPORT ) set ( MISC_REPORT "${MISC_REPORT} D-Bus: no\n" ) endif ( DBUS_SUPPORT ) +if ( HAIKU_SUPPORT ) + message ( "Haiku MediaKit support: yes" ) +else ( HAIKU_SUPPORT ) + message ( "Haiku MediaKit support: no" ) +endif ( HAIKU_SUPPORT ) + if ( LADSPA_SUPPORT ) set ( MISC_REPORT "${MISC_REPORT} LADSPA support: yes\n" ) else ( LADSPA_SUPPORT ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0275227b..68265ffb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -73,6 +73,10 @@ if ( SDL2_SUPPORT ) set ( fluid_sdl2_SOURCES drivers/fluid_sdl2.c ) endif ( SDL2_SUPPORT ) +if ( HAIKU_SUPPORT ) + set ( fluid_haiku_SOURCES drivers/fluid_haiku.cpp ) +endif ( HAIKU_SUPPORT ) + if ( OSS_SUPPORT ) set ( fluid_oss_SOURCES drivers/fluid_oss.c ) endif ( OSS_SUPPORT ) @@ -239,6 +243,7 @@ add_library ( libfluidsynth-OBJ OBJECT ${fluid_wasapi_SOURCES} ${fluid_waveout_SOURCES} ${fluid_winmidi_SOURCES} + ${fluid_haiku_SOURCES} ${fluid_sdl2_SOURCES} ${fluid_libinstpatch_SOURCES} ${libfluidsynth_SOURCES} diff --git a/src/config.cmake b/src/config.cmake index d98a86f9..13bde4d5 100644 --- a/src/config.cmake +++ b/src/config.cmake @@ -208,6 +208,9 @@ /* Define to enable SDL2 audio driver */ #cmakedefine SDL2_SUPPORT @SDL2_SUPPORT@ +/* Define to enable Haiku MediaKit audio driver */ +#cmakedefine HAIKU_SUPPORT @HAIKU_SUPPORT@ + /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS @STDC_HEADERS@ diff --git a/src/drivers/fluid_adriver.c b/src/drivers/fluid_adriver.c index f56d636b..9e8bedf9 100644 --- a/src/drivers/fluid_adriver.c +++ b/src/drivers/fluid_adriver.c @@ -110,6 +110,16 @@ static const fluid_audriver_definition_t fluid_audio_drivers[] = }, #endif +#if HAIKU_SUPPORT + { + "mediakit", + new_fluid_haiku_audio_driver, + NULL, + delete_fluid_haiku_audio_driver, + fluid_haiku_audio_driver_settings + }, +#endif + #if COREAUDIO_SUPPORT { "coreaudio", diff --git a/src/drivers/fluid_adriver.h b/src/drivers/fluid_adriver.h index a3651905..8caaf1fe 100644 --- a/src/drivers/fluid_adriver.h +++ b/src/drivers/fluid_adriver.h @@ -61,6 +61,13 @@ void delete_fluid_alsa_audio_driver(fluid_audio_driver_t *p); void fluid_alsa_audio_driver_settings(fluid_settings_t *settings); #endif +#if HAIKU_SUPPORT +fluid_audio_driver_t *new_fluid_haiku_audio_driver(fluid_settings_t *settings, + fluid_synth_t *synth); +void delete_fluid_haiku_audio_driver(fluid_audio_driver_t *p); +void fluid_haiku_audio_driver_settings(fluid_settings_t *settings); +#endif + #if OSS_SUPPORT fluid_audio_driver_t *new_fluid_oss_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth); diff --git a/src/drivers/fluid_haiku.cpp b/src/drivers/fluid_haiku.cpp new file mode 100644 index 00000000..4d86529a --- /dev/null +++ b/src/drivers/fluid_haiku.cpp @@ -0,0 +1,140 @@ +/* Haiku MediaKit Driver for FluidSynth + * + * Copyright (C) 2019 Gerasim Troeglazov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + + +#include +#include + +extern "C" { +#include "fluid_synth.h" +#include "fluid_adriver.h" +#include "fluid_settings.h" +} + +typedef struct +{ + fluid_audio_driver_t driver; + + fluid_synth_t *synth; + fluid_audio_callback_t write_ptr; + + int frame_size; + + BSoundPlayer *m_player; + +} fluid_haiku_audio_driver_t; + + +static void playerProc(void *cookie, void *buffer, size_t len, const media_raw_audio_format &format) +{ + fluid_haiku_audio_driver_t *dev = (fluid_haiku_audio_driver_t *)cookie; + len /= dev->frame_size; + dev->write_ptr(dev->synth, len, buffer, 0, 2, buffer, 1, 2); +} + +void fluid_haiku_audio_driver_settings(fluid_settings_t *settings) +{ + fluid_settings_register_str(settings, "audio.haiku.device", "default", 0); + fluid_settings_add_option(settings, "audio.haiku.device", "default"); +} + +fluid_audio_driver_t * +new_fluid_haiku_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth) +{ + fluid_haiku_audio_driver_t *dev = NULL; + fluid_audio_callback_t write_ptr; + + double sample_rate; + int period_size; + int periods; + int sample_size; + + char *device; + const char *dev_name; + + fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate); + fluid_settings_getint(settings, "audio.periods", &periods); + fluid_settings_getint(settings, "audio.period-size", &period_size); + + if(period_size < 1024) { + period_size = 1024; + } else { + if((period_size & (period_size - 1)) != 0) { + FLUID_LOG(FLUID_ERR, "\"audio.period-size\" must be a power of 2"); + return NULL; + } + } + + if(fluid_settings_str_equal(settings, "audio.sample-format", "16bits")) + { + FLUID_LOG(FLUID_DBG, "Selected 16 bit sample format"); + sample_size = sizeof(short); + write_ptr = fluid_synth_write_s16; + } else { + FLUID_LOG(FLUID_ERR, "Unhandled sample format"); + return NULL; + } + + dev = FLUID_NEW(fluid_haiku_audio_driver_t); + if(dev == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return NULL; + } + FLUID_MEMSET(dev, 0, sizeof(fluid_haiku_audio_driver_t)); + + dev->synth = synth; + dev->frame_size = 2 * sample_size; + dev->write_ptr = write_ptr; + + media_raw_audio_format mediaKitFormat = { + (float)sample_rate, + (uint32)2, + media_raw_audio_format::B_AUDIO_SHORT, + B_MEDIA_LITTLE_ENDIAN, + (uint32)periods * period_size * dev->frame_size + }; + + dev->m_player = new BSoundPlayer(&mediaKitFormat, "FluidSynth", playerProc, NULL, (void*)dev); + + if(dev->m_player->InitCheck() != B_OK) { + delete dev->m_player; + dev->m_player = NULL; + delete_fluid_haiku_audio_driver(&dev->driver); + return NULL; + } + + dev->m_player->SetHasData(true); + dev->m_player->Start(); + + return (fluid_audio_driver_t *) dev; +} + + +void delete_fluid_haiku_audio_driver(fluid_audio_driver_t *d) +{ + fluid_haiku_audio_driver_t *dev = (fluid_haiku_audio_driver_t *) d; + if (dev->m_player != NULL) { + dev->m_player->SetHasData(false); + dev->m_player->Stop(); + delete dev->m_player; + dev->m_player = NULL; + } + FLUID_FREE(dev); +} diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 82cfac4c..a97efbf5 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -27,6 +27,10 @@ #include "fluid_defsfont.h" #include "fluid_instpatch.h" +#ifdef __HAIKU__ +#include +#endif + #ifdef TRAP_ON_FPE #define _GNU_SOURCE #include @@ -218,8 +222,25 @@ void fluid_synth_settings(fluid_settings_t *settings) fluid_settings_register_int(settings, "synth.lock-memory", 1, 0, 1, FLUID_HINT_TOGGLED); fluid_settings_register_str(settings, "midi.portname", "", 0); +#ifdef __HAIKU__ + char midiSettings[PATH_MAX] = ""; + if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, midiSettings, sizeof(midiSettings)) == B_OK) { + strcat(midiSettings, "/Media/midi_settings"); + if( access( midiSettings, F_OK ) != -1 ) { + FILE *inFile = fopen(midiSettings, "rt"); + if (inFile) { + char sf2file[PATH_MAX]; + if (fscanf(inFile, "# Midi\n\tsoundfont \"%[^\"]\"", sf2file)) { + fluid_settings_register_str(settings, "synth.default-soundfont", sf2file, 0); + } + fclose(inFile); + } + } + } +#else #ifdef DEFAULT_SOUNDFONT fluid_settings_register_str(settings, "synth.default-soundfont", DEFAULT_SOUNDFONT, 0); +#endif #endif fluid_settings_register_int(settings, "synth.polyphony", 256, 1, 65535, 0); diff --git a/src/utils/fluid_sys.h b/src/utils/fluid_sys.h index f491254d..30805fd2 100644 --- a/src/utils/fluid_sys.h +++ b/src/utils/fluid_sys.h @@ -738,7 +738,7 @@ enum sample data. */ -#if defined(HAVE_SYS_MMAN_H) && !defined(__OS2__) +#if defined(HAVE_SYS_MMAN_H) && !defined(__OS2__) && !defined(__HAIKU__) #define fluid_mlock(_p,_n) mlock(_p, _n) #define fluid_munlock(_p,_n) munlock(_p,_n) #else -- 2.45.2 From f73f4f574674b2c534b4ffc611b8e864419e09ff Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 17 Mar 2022 14:08:23 +0600 Subject: [PATCH 2/6] Get rid of excessive realtime audio output latency --- src/drivers/fluid_haiku.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/drivers/fluid_haiku.cpp b/src/drivers/fluid_haiku.cpp index 4d86529a..e68653f5 100644 --- a/src/drivers/fluid_haiku.cpp +++ b/src/drivers/fluid_haiku.cpp @@ -73,16 +73,13 @@ new_fluid_haiku_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth) fluid_settings_getint(settings, "audio.periods", &periods); fluid_settings_getint(settings, "audio.period-size", &period_size); - if(period_size < 1024) { - period_size = 1024; - } else { - if((period_size & (period_size - 1)) != 0) { - FLUID_LOG(FLUID_ERR, "\"audio.period-size\" must be a power of 2"); - return NULL; - } + if(fluid_settings_str_equal(settings, "audio.sample-format", "float")) + { + FLUID_LOG(FLUID_DBG, "Selected 32 bit sample format"); + sample_size = sizeof(float); + write_ptr = fluid_synth_write_float; } - - if(fluid_settings_str_equal(settings, "audio.sample-format", "16bits")) + else if(fluid_settings_str_equal(settings, "audio.sample-format", "16bits")) { FLUID_LOG(FLUID_DBG, "Selected 16 bit sample format"); sample_size = sizeof(short); @@ -106,7 +103,7 @@ new_fluid_haiku_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth) media_raw_audio_format mediaKitFormat = { (float)sample_rate, (uint32)2, - media_raw_audio_format::B_AUDIO_SHORT, + sample_size == sizeof(float) ? media_raw_audio_format::B_AUDIO_FLOAT : media_raw_audio_format::B_AUDIO_SHORT, B_MEDIA_LITTLE_ENDIAN, (uint32)periods * period_size * dev->frame_size }; -- 2.45.2 From faebc01901f2471d0ee10085ede0c57e98bd5180 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 17 Mar 2022 14:09:10 +0600 Subject: [PATCH 3/6] Add Haiku MidiKit2 MIDI backend --- CMakeLists.txt | 9 ++ src/CMakeLists.txt | 5 + src/config.cmake | 3 + src/drivers/fluid_mdriver.c | 8 ++ src/drivers/fluid_mdriver.h | 9 ++ src/drivers/fluid_midikit2.cpp | 162 +++++++++++++++++++++++++++++++++ 6 files changed, 196 insertions(+) create mode 100644 src/drivers/fluid_midikit2.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 831f29c6..8bacb7b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,7 @@ option ( enable-wasapi "compile Windows WASAPI support (if it is available)" on option ( enable-waveout "compile Windows WaveOut support (if it is available)" on ) option ( enable-winmidi "compile Windows MIDI support (if it is available)" on ) option ( enable-haiku "compile Haiku MediaKit audio support (if it is available)" on ) +option ( enable-midikit2 "compile Haiku MidiKit2 MIDI support (if it is available)" on ) option ( enable-sdl2 "compile SDL2 audio support (if it is available)" off ) option ( enable-pulseaudio "compile PulseAudio support (if it is available)" on ) option ( enable-pipewire "compile PipeWire support (if it is available)" on ) @@ -407,6 +408,9 @@ endif ( CMAKE_SYSTEM MATCHES "SunOS" ) if ( CMAKE_SYSTEM MATCHES "Haiku" ) set ( FLUID_LIBS "${FLUID_LIBS};network;bsd;be;media" ) set ( LIBFLUID_LIBS "${LIBFLUID_LIBS};network;bsd;be;media" ) + if ( enable-midikit2 ) + set( LIBFLUID_LIBS "midi2" ${LIBFLUID_LIBS} ) + endif ( enable-midikit2 ) endif ( CMAKE_SYSTEM MATCHES "Haiku" ) # Apple Mac OSX @@ -723,10 +727,15 @@ if ( enable-readline ) endif ( enable-readline ) unset ( HAIKU_SUPPORT CACHE ) +unset ( MIDIKIT2_SUPPORT CACHE ) if ( enable-haiku ) set ( HAIKU_SUPPORT 1 ) endif ( enable-haiku ) +if ( enable-midikit2 ) + set ( MIDIKIT2_SUPPORT 1 ) +endif ( enable-midikit2 ) + unset ( AUFILE_SUPPORT CACHE ) if ( enable-aufile ) set ( AUFILE_SUPPORT 1 ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 68265ffb..ddabc28f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -77,6 +77,10 @@ if ( HAIKU_SUPPORT ) set ( fluid_haiku_SOURCES drivers/fluid_haiku.cpp ) endif ( HAIKU_SUPPORT ) +if ( MIDIKIT2_SUPPORT ) + set ( fluid_midikit2_SOURCES drivers/fluid_midikit2.cpp ) +endif ( MIDIKIT2_SUPPORT ) + if ( OSS_SUPPORT ) set ( fluid_oss_SOURCES drivers/fluid_oss.c ) endif ( OSS_SUPPORT ) @@ -244,6 +248,7 @@ add_library ( libfluidsynth-OBJ OBJECT ${fluid_waveout_SOURCES} ${fluid_winmidi_SOURCES} ${fluid_haiku_SOURCES} + ${fluid_midikit2_SOURCES} ${fluid_sdl2_SOURCES} ${fluid_libinstpatch_SOURCES} ${libfluidsynth_SOURCES} diff --git a/src/config.cmake b/src/config.cmake index 13bde4d5..1b182d0d 100644 --- a/src/config.cmake +++ b/src/config.cmake @@ -211,6 +211,9 @@ /* Define to enable Haiku MediaKit audio driver */ #cmakedefine HAIKU_SUPPORT @HAIKU_SUPPORT@ +/* Define to enable Haiku MidiKit2 MIDI driver */ +#cmakedefine MIDIKIT2_SUPPORT @MIDIKIT2_SUPPORT@ + /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS @STDC_HEADERS@ diff --git a/src/drivers/fluid_mdriver.c b/src/drivers/fluid_mdriver.c index 973aef58..33b07eb4 100644 --- a/src/drivers/fluid_mdriver.c +++ b/src/drivers/fluid_mdriver.c @@ -84,6 +84,14 @@ static const fluid_mdriver_definition_t fluid_midi_drivers[] = NULL }, #endif +#if MIDIKIT2_SUPPORT + { + "midikit2", + new_fluid_midikit2_driver, + delete_fluid_midikit2_driver, + fluid_midikit2_driver_settings + }, +#endif #if COREMIDI_SUPPORT { "coremidi", diff --git a/src/drivers/fluid_mdriver.h b/src/drivers/fluid_mdriver.h index 76b8b7b0..7a2d701e 100644 --- a/src/drivers/fluid_mdriver.h +++ b/src/drivers/fluid_mdriver.h @@ -88,6 +88,15 @@ fluid_midi_driver_t *new_fluid_midishare_midi_driver(fluid_settings_t *settings, void delete_fluid_midishare_midi_driver(fluid_midi_driver_t *p); #endif +/* definitions for the MidiKit2 driver */ +#if MIDIKIT2_SUPPORT +fluid_midi_driver_t *new_fluid_midikit2_driver(fluid_settings_t *settings, + handle_midi_event_func_t handler, + void *event_handler_data); +void delete_fluid_midikit2_driver(fluid_midi_driver_t *p); +void fluid_midikit2_driver_settings(fluid_settings_t *settings); +#endif + /* definitions for the CoreMidi driver */ #if COREMIDI_SUPPORT fluid_midi_driver_t *new_fluid_coremidi_driver(fluid_settings_t *settings, diff --git a/src/drivers/fluid_midikit2.cpp b/src/drivers/fluid_midikit2.cpp new file mode 100644 index 00000000..c65ab471 --- /dev/null +++ b/src/drivers/fluid_midikit2.cpp @@ -0,0 +1,162 @@ +/* Haiku MidiKit2 Driver for FluidSynth + * + * Copyright (C) 2022 Cacodemon345 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + +/* Parts of code taken from the CoreMIDI driver. */ +#include + +extern "C" { +#include "fluid_midi.h" +#include "fluid_mdriver.h" +#include "fluid_settings.h" +} + +#include +#include +#include +#include +#include + +typedef struct +{ + fluid_midi_driver_t driver; + fluid_midi_parser_t* parser; + + BMidiLocalConsumer *m_consumer; + int autoconn_inputs; +} fluid_midikit2_driver_t; + +class fluid_midikit2_input : public BMidiLocalConsumer +{ + void Data(uchar *data, size_t length, bool atomic, bigtime_t time) override + { + if (atomic && callback) + { + fluid_midi_event_t *event = NULL; + snooze_until(time, B_SYSTEM_TIMEBASE); + for (int i = 0; i < length; i++) + { + event = fluid_midi_parser_parse(callback->parser, data[i]); + } + if (event) + { + callback->driver.handler(callback->driver.data, event); + } + } + } +public: + fluid_midikit2_driver_t* callback; +}; + +void fluid_midikit2_driver_settings(fluid_settings_t *settings) +{ + fluid_settings_register_str(settings, "midi.midikit2.id", "pid", 0); +} + +static void fluid_coremidi_autoconnect(fluid_midikit2_driver_t *dev) +{ + int32 id = 0; + BMidiProducer* producer = NULL; + while ((producer = BMidiRoster::NextProducer(&id)) != NULL) + { + producer->Connect(dev->m_consumer); + producer->Release(); + } +} + +fluid_midi_driver_t* +new_fluid_midikit2_driver(fluid_settings_t *settings, handle_midi_event_func_t handler, void *data) +{ + fluid_midikit2_driver_t* driver = NULL; + char* id = NULL; + char clientid[128]; + + memset(clientid, 0, sizeof(clientid)); + driver = FLUID_MALLOC(sizeof(fluid_midikit2_driver_t)); + + if(driver == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return NULL; + } + + driver->driver.handler = handler; + driver->driver.data = data; + + driver->parser = new_fluid_midi_parser(); + + if(driver->parser == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + FLUID_FREE(driver); + return NULL; + } + + fluid_settings_dupstr(settings, "midi.midikit2.id", &id); + if(id != NULL) + { + if(FLUID_STRCMP(id, "pid") == 0) + { + FLUID_SNPRINTF(clientid, sizeof(clientid), "FluidSynth virtual port (%d)", getpid()); + } + else + { + FLUID_SNPRINTF(clientid, sizeof(clientid), "FluidSynth virtual port (%s)", id); + } + + FLUID_FREE(id); /* -- free id string */ + } + else strncpy(clientid, "FluidSynth virtual port", sizeof(clientid)); + + driver->m_consumer = new fluid_midikit2_input; + if(!driver->m_consumer->IsValid()) + { + FLUID_LOG(FLUID_ERR, "Failed to create the MIDI consumer"); + driver->m_consumer->Release(); + delete_fluid_midi_parser(driver->parser); + FLUID_FREE(driver); + return NULL; + } + + ((fluid_midikit2_input*)driver->m_consumer)->callback = driver; + driver->m_consumer->SetName(clientid); + driver->m_consumer->Register(); + fluid_settings_getint(settings, "midi.autoconnect", &driver->autoconn_inputs); + + if (driver->autoconn_inputs) + { + fluid_coremidi_autoconnect(driver); + } + + return (fluid_midi_driver_t *)driver; +} + +void +delete_fluid_midikit2_driver(fluid_midi_driver_t *p) +{ + fluid_return_if_fail(p != NULL); + if (p) + { + fluid_midikit2_driver_t* driver = (fluid_midikit2_driver_t*)p; + driver->m_consumer->Unregister(); + driver->m_consumer->Release(); + delete_fluid_midi_parser(driver->parser); + FLUID_FREE(driver); + } +} -- 2.45.2 From 7f2a52e8ffe9092514f827db50be1299fb5c8025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 16 Feb 2025 00:15:33 +0100 Subject: [PATCH 4/6] CMake: Report Haiku audio & MIDI --- cmake_admin/report.cmake | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cmake_admin/report.cmake b/cmake_admin/report.cmake index 391cdd78..e2271ea0 100644 --- a/cmake_admin/report.cmake +++ b/cmake_admin/report.cmake @@ -26,6 +26,18 @@ else ( DSOUND_SUPPORT ) set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} DSound: no\n" ) endif ( DSOUND_SUPPORT ) +if ( HAIKU_SUPPORT ) + set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} Haiku: yes\n" ) +else ( HAIKU_SUPPORT ) + set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} Haiku: no\n" ) +endif ( HAIKU_SUPPORT ) + +if ( MIDIKIT2_SUPPORT ) + set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} Haiku MidiKit2: yes\n" ) +else ( MIDIKIT2_SUPPORT ) + set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} Haiku MidiKit2: no\n" ) +endif ( MIDIKIT2_SUPPORT ) + if ( JACK_SUPPORT ) set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} JACK: yes\n" ) else ( JACK_SUPPORT ) -- 2.45.2 From 73f122436cd8df64568c14dc4ef74728f3c7037c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 16 Feb 2025 00:37:24 +0100 Subject: [PATCH 5/6] Haiku: no need for and C++2011 --- src/drivers/fluid_midikit2.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/drivers/fluid_midikit2.cpp b/src/drivers/fluid_midikit2.cpp index c65ab471..5989bcbe 100644 --- a/src/drivers/fluid_midikit2.cpp +++ b/src/drivers/fluid_midikit2.cpp @@ -19,7 +19,6 @@ */ /* Parts of code taken from the CoreMIDI driver. */ -#include extern "C" { #include "fluid_midi.h" -- 2.45.2 From 1881c2b3fdf5af115c644b930e98c4a03784e23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 16 Feb 2025 01:34:40 +0100 Subject: [PATCH 6/6] CMake: properly check for Haiku headers --- CMakeLists.txt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8bacb7b1..16cf76dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -729,11 +729,23 @@ endif ( enable-readline ) unset ( HAIKU_SUPPORT CACHE ) unset ( MIDIKIT2_SUPPORT CACHE ) if ( enable-haiku ) - set ( HAIKU_SUPPORT 1 ) + check_include_file_cxx("MediaKit.h" HAVE_MEDIAKIT_H) + check_include_file_cxx("SupportKit.h" HAVE_SUPPORTKIT_H) + if ( HAVE_MEDIAKIT_H AND HAVE_SUPPORTKIT_H ) + set ( HAIKU_SUPPORT TRUE ) + else ( HAVE_MEDIAKIT_H AND HAVE_SUPPORTKIT_H ) + set ( HAIKU_SUPPORT FALSE ) + endif ( HAVE_MEDIAKIT_H AND HAVE_SUPPORTKIT_H ) endif ( enable-haiku ) if ( enable-midikit2 ) - set ( MIDIKIT2_SUPPORT 1 ) + check_include_file_cxx("Midi2Defs.h" HAVE_MIDI2DEFS_H) + check_include_file_cxx("MidiRoster.h" HAVE_MIDIROSTER_H) + if ( HAVE_MIDI2DEFS_H AND HAVE_MIDIROSTER_H ) + set ( MIDIKIT2_SUPPORT TRUE ) + else ( HAVE_MIDI2DEFS_H AND HAVE_MIDIROSTER_H ) + set ( MIDIKIT2_SUPPORT FALSE ) + endif ( HAVE_MIDI2DEFS_H AND HAVE_MIDIROSTER_H ) endif ( enable-midikit2 ) unset ( AUFILE_SUPPORT CACHE ) -- 2.45.2