diff --git a/CMakeLists.txt b/CMakeLists.txt index d4956b199..5fa7825ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,107 @@ # CMake based build system. Pedro Lopez-Cabanillas +if ( ANDROID ) +enable_language(C) +cmake_minimum_required(VERSION 3.4.1) + +set(fluidsynth_sources + src/midi/fluid_midi.c + src/midi/fluid_midi_router.c + src/midi/fluid_seq.c + src/midi/fluid_seqbind.c + src/rvoice/fluid_adsr_env.c + src/rvoice/fluid_chorus.c + src/rvoice/fluid_iir_filter.c + src/rvoice/fluid_lfo.c + src/rvoice/fluid_rev.c + src/rvoice/fluid_rvoice.c + src/rvoice/fluid_rvoice_dsp.c + src/rvoice/fluid_rvoice_event.c + src/rvoice/fluid_rvoice_mixer.c + src/sfloader/fluid_defsfont.c + src/sfloader/fluid_sfont.c + src/sfloader/fluid_sffile.c + src/sfloader/fluid_samplecache.c + src/synth/fluid_chan.c + src/synth/fluid_event.c + src/synth/fluid_gen.c + src/synth/fluid_mod.c + src/synth/fluid_synth.c + src/synth/fluid_tuning.c + src/synth/fluid_voice.c + src/synth/fluid_synth_monopoly.c + src/utils/fluid_conv.c + src/utils/fluid_hash.c + src/utils/fluid_list.c + src/utils/fluid_ringbuffer.c + src/utils/fluid_settings.c + src/bindings/fluid_filerenderer.c + src/utils/fluid_sys.c + android/src/bindings/fluid_cmd.c + src/drivers/fluid_adriver.c + src/drivers/fluid_mdriver.c +) + +set ( public_main_HEADER + ${CMAKE_BINARY_DIR}/include/fluidsynth.h +) + +configure_file ( include/fluidsynth.cmake + ${public_main_HEADER} ) + +add_library(fluidsynth SHARED ${fluidsynth_sources}) + +if(ANDROID_ABI STREQUAL "armeabi-v7a") + target_compile_options(fluidsynth PRIVATE -DWITH_FLOAT) +endif() +if(ANDROID_ABI STREQUAL "x86") + target_compile_options(fluidsynth PRIVATE -DWITH_FLOAT) +endif() + +# Specify directories which the compiler should look for headers +target_include_directories(fluidsynth PRIVATE + android android/include + include + src + src/synth + src/midi + src/rvoice + src/sfloader + src/utils + src/bindings + src/drivers + ${CMAKE_BINARY_DIR}/include + ${CMAKE_BINARY_DIR} + ) + +target_include_directories(fluidsynth INTERFACE + android android/include + include + ${CMAKE_BINARY_DIR}/include + ) + +target_compile_options(fluidsynth PRIVATE -std=gnu11 + PRIVATE -Wall + PRIVATE -DHAVE_CONFIG_H + PRIVATE -Wno-unused-variable + PRIVATE -Wno-error=format + PRIVATE "$<$:-Werror>") # Only include -Werror when building debug config + +# ******* Auto Generated Lookup Tables ****** + +include(ExternalProject) +ExternalProject_Add(gentables + DOWNLOAD_COMMAND "" + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/gentables + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/gentables + INSTALL_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/src/gentables/make_tables.exe "${CMAKE_BINARY_DIR}/" + CMAKE_GENERATOR "Unix Makefiles" + ) +add_dependencies(fluidsynth gentables) + +else ( ANDROID ) + cmake_minimum_required ( VERSION 3.1.0 ) # because of CMAKE_C_STANDARD project ( FluidSynth C ) set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_admin ) @@ -808,3 +909,5 @@ set ( CPACK_PACKAGE_NAME ${PACKAGE} ) set ( CPACK_STRIP_FILES ON ) include ( CPack ) + +endif ( ANDROID ) diff --git a/android/config.h b/android/config.h new file mode 100644 index 000000000..7a4417d4d --- /dev/null +++ b/android/config.h @@ -0,0 +1,228 @@ +#ifndef CONFIG_H +#define CONFIG_H + +/* Define to enable ALSA driver */ +/* #undef ALSA_SUPPORT */ + +/* Define to activate sound output to files */ +/* #undef AUFILE_SUPPORT */ + +/* whether or not we are supporting CoreAudio */ +/* #undef COREAUDIO_SUPPORT */ + +/* whether or not we are supporting CoreMIDI */ +/* #undef COREMIDI_SUPPORT */ + +/* whether or not we are supporting DART */ +/* #undef DART_SUPPORT */ + +/* Define if building for Mac OS X Darwin */ +/* #undef DARWIN */ + +/* Define if D-Bus support is enabled */ +/* #undef DBUS_SUPPORT */ + +/* Define to enable FPE checks */ +/* #undef FPE_CHECK */ + +/* Define to 1 if you have the header file. */ +/*#undef HAVE_ARPA_INET_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* whether or not we are supporting ladcca */ +/* #undef HAVE_LADCCA */ + +/* whether or not we are supporting lash */ +/* #undef HAVE_LASH */ + +/* Define to 1 if you have the `dl' library (-ldl). */ +/* #undef HAVE_LIBDL */ + +/* Define to 1 if you have the `MidiShare' library (-lMidiShare). */ +/* #undef HAVE_LIBMIDISHARE */ + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD TRUE + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MACHINE_SOUNDCARD_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MATH_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MIDISHARE_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PTHREAD_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDARG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MMAN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOUNDCARD_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define to enable JACK driver */ +/* #undef JACK_SUPPORT */ + +/* Include the LADSPA Fx unit */ +/* #undef LADSPA */ + +/* libsndfile has ogg vorbis support */ +/* #undef LIBSNDFILE_HASVORBIS */ + +/* Define to enable libsndfile support */ +/* #undef LIBSNDFILE_SUPPORT */ + +/* Define to enable MidiShare driver */ +/* #undef MIDISHARE_SUPPORT */ + +/* Define if using the MinGW32 environment */ +/* #undef MINGW32 */ + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Define to enable OSS driver */ +/* #undef OSS_SUPPORT */ + +/* Name of package */ +#define PACKAGE "fluidsynth" + +/* Define to the address where bug reports for this package should be sent. */ +/* #undef PACKAGE_BUGREPORT */ + +/* Define to the full name of this package. */ +/* #undef PACKAGE_NAME */ + +/* Define to the full name and version of this package. */ +/* #undef PACKAGE_STRING */ + +/* Define to the one symbol short name of this package. */ +/* #undef PACKAGE_TARNAME */ + +/* Define to the version of this package. */ +/* #undef PACKAGE_VERSION */ + +/* Define to enable PortAudio driver */ +/* #undef PORTAUDIO_SUPPORT */ + +/* Define to enable PulseAudio driver */ +/* #undef PULSE_SUPPORT */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to enable SIGFPE assertions */ +/* #undef TRAP_ON_FPE */ + +/* Version number of package */ +#define VERSION "2.1.0" + +/* Define to do all DSP in single floating point precision */ +/* #undef WITH_FLOAT */ + +#define HAVE_SINF 1 +#define HAVE_COSF 1 +#define HAVE_FABSF 1 +#define HAVE_POWF 1 +#define HAVE_SQRTF 1 +#define HAVE_LOGF 1 + +/* Define to profile the DSP code */ +/* #undef WITH_PROFILING */ + +/* Define to use the readline library for line editing */ +/* #undef WITH_READLINE */ + +/* Define if the compiler supports VLA */ +#define SUPPORTS_VLA + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +#endif /* CONFIG_H */ diff --git a/android/include/fluidsynth/version.h b/android/include/fluidsynth/version.h new file mode 100644 index 000000000..52a328372 --- /dev/null +++ b/android/include/fluidsynth/version.h @@ -0,0 +1,47 @@ +/* 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 + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + +#ifndef _FLUIDSYNTH_VERSION_H +#define _FLUIDSYNTH_VERSION_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file version.h + * @brief Library version functions and defines + */ + +#define FLUIDSYNTH_VERSION "2.1.0" /**< String constant of libfluidsynth version. */ +#define FLUIDSYNTH_VERSION_MAJOR 2 /**< libfluidsynth major version integer constant. */ +#define FLUIDSYNTH_VERSION_MINOR 1 /**< libfluidsynth minor version integer constant. */ +#define FLUIDSYNTH_VERSION_MICRO 0 /**< libfluidsynth micro version integer constant. */ + +FLUIDSYNTH_API void fluid_version(int *major, int *minor, int *micro); +FLUIDSYNTH_API char* fluid_version_str(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* _FLUIDSYNTH_VERSION_H */ diff --git a/android/src/bindings/fluid_cmd.c b/android/src/bindings/fluid_cmd.c new file mode 100644 index 000000000..280ce98af --- /dev/null +++ b/android/src/bindings/fluid_cmd.c @@ -0,0 +1,8 @@ +#include "fluid_synth.h" +#include "fluid_settings.h" + +void fluid_shell_settings(fluid_settings_t* settings) +{ + // NOOP +} + \ No newline at end of file diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index 7c5f567df..1f4db6f4e 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -103,7 +103,7 @@ int fluid_is_midifile(const char *filename) { return retcode; } - + if(FLUID_FREAD(&id, sizeof(id), 1, fp) != 1) { break; diff --git a/src/rvoice/fluid_adsr_env.h b/src/rvoice/fluid_adsr_env.h index 9ed652d0b..802cbfe2c 100644 --- a/src/rvoice/fluid_adsr_env.h +++ b/src/rvoice/fluid_adsr_env.h @@ -137,7 +137,7 @@ fluid_adsr_env_set_val(fluid_adsr_env_t *env, fluid_real_t val) static FLUID_INLINE fluid_adsr_env_section_t fluid_adsr_env_get_section(fluid_adsr_env_t *env) { - return env->section; + return (fluid_adsr_env_section_t)env->section; } static FLUID_INLINE void diff --git a/src/rvoice/fluid_rvoice_event.h b/src/rvoice/fluid_rvoice_event.h index 870d7a4ca..59f0df3cb 100644 --- a/src/rvoice/fluid_rvoice_event.h +++ b/src/rvoice/fluid_rvoice_event.h @@ -86,7 +86,7 @@ fluid_rvoice_eventhandler_get_finished_voice(fluid_rvoice_eventhandler_t *handle result = * (fluid_rvoice_t **) result; fluid_ringbuffer_next_outptr(handler->finished_voices); - return result; + return (fluid_rvoice_t *)result; } diff --git a/src/sfloader/fluid_sfont.c b/src/sfloader/fluid_sfont.c index fb0b75aca..3e02c0bae 100644 --- a/src/sfloader/fluid_sfont.c +++ b/src/sfloader/fluid_sfont.c @@ -31,7 +31,6 @@ void *default_fopen(const char *path) { FLUID_LOG(FLUID_ERR, "fluid_sfloader_load(): Failed to open '%s': %s", path, msg); } - return handle; } diff --git a/src/utils/fluid_atomic.h b/src/utils/fluid_atomic.h new file mode 100644 index 000000000..c5bb397f0 --- /dev/null +++ b/src/utils/fluid_atomic.h @@ -0,0 +1,69 @@ + +#ifndef _FLUID_ATOMIC_H +#define _FLUID_ATOMIC_H + +#include + +#ifndef STATIC_ASSERT +#if __STDC_VERSION__ >= 201112L +#define STATIC_ASSERT _Static_assert +#else +#define STATIC_ASSERT(expr, msg) typedef char __static_assertion_ ## __COUNTER__[(expr) ? 1 : -1] +#endif +#endif //STATIC_ASSERT + +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + +#define fluid_atomic_int_add(atomic, val) __extension__ ({ \ + STATIC_ASSERT(sizeof((atomic)->value) == sizeof(int), \ + "Atomic must be the size of an int"); \ + __sync_fetch_and_add(&(atomic)->value, (val));}) + +#define fluid_atomic_int_get(atomic) __extension__ ({ \ + STATIC_ASSERT(sizeof((atomic)->value) == sizeof(int), \ + "Atomic must be the size of an int"); \ + __sync_synchronize(); \ + (atomic)->value;}) + +#define fluid_atomic_int_set(atomic, newval) __extension__ ({ \ + STATIC_ASSERT(sizeof((atomic)->value) == sizeof(int), \ + "Atomic must be the size of an int"); \ + (atomic)->value = (newval); \ + __sync_synchronize();}) + +#define fluid_atomic_int_inc(atomic) __extension__ ({ \ + STATIC_ASSERT(sizeof((atomic)->value) == sizeof(int), \ + "Atomic must be the size of an int"); \ + __sync_synchronize(); \ + __sync_fetch_and_add(&(atomic)->value, 1);}) + +#define fluid_atomic_int_compare_and_exchange(atomic, oldval, newval) __extension__ ({ \ + STATIC_ASSERT(sizeof((atomic)->value) == sizeof(int), \ + "Atomic must be the size of an int"); \ + __sync_bool_compare_and_swap(&(atomic)->value, (oldval), (newval));}) + +#define fluid_atomic_int_exchange_and_add(atomic, add) __extension__ ({ \ + STATIC_ASSERT(sizeof((atomic)->value) == sizeof(int), \ + "Atomic must be the size of an int"); \ + __sync_synchronize(); \ + __sync_fetch_and_add(&(atomic)->value, add);}) + +#define fluid_atomic_float_get(atomic) __extension__ ({ \ + STATIC_ASSERT(sizeof((atomic)->value) == sizeof(float), \ + "Atomic must be the size of a float"); \ + __sync_synchronize(); \ + (atomic)->value;}) + +#define fluid_atomic_float_set(atomic, val) __extension__ ({ \ + STATIC_ASSERT(sizeof((atomic)->value) == sizeof(float), \ + "Atomic must be the size of a float"); \ + (atomic)->value = (val); \ + __sync_synchronize();}) + +#else + +#error "GCC builtins missings for atomic operations" + +#endif + +#endif /* _FLUID_ATOMIC_H */ diff --git a/src/utils/fluid_sys.c b/src/utils/fluid_sys.c index 5ef5676cf..ead58e7e7 100644 --- a/src/utils/fluid_sys.c +++ b/src/utils/fluid_sys.c @@ -179,12 +179,12 @@ fluid_log(int level, const char *fmt, ...) if(fun != NULL) { char errbuf[1024]; - + va_list args; va_start(args, fmt); FLUID_VSNPRINTF(errbuf, sizeof(errbuf), fmt, args); va_end(args); - + (*fun)(level, errbuf, fluid_log_user_data[level]); } } @@ -308,7 +308,7 @@ char *fluid_strtok(char **str, char *delim) */ void fluid_msleep(unsigned int msecs) { - g_usleep(msecs * 1000); + usleep(msecs * 1000); } /** @@ -341,40 +341,11 @@ unsigned int fluid_curtime(void) double fluid_utime(void) { - double utime; - -#if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 28 - /* use high precision monotonic clock if available (g_monotonic_time(). - * For Winfdows, if this clock is actually implemented as low prec. clock - * (i.e. in case glib is too old), high precision performance counter are - * used instead. - * see: https://bugzilla.gnome.org/show_bug.cgi?id=783340 - */ -#if defined(WITH_PROFILING) && defined(WIN32) &&\ - /* glib < 2.53.3 */\ - (GLIB_MINOR_VERSION <= 53 && (GLIB_MINOR_VERSION < 53 || GLIB_MICRO_VERSION < 3)) - /* use high precision performance counter. */ - static LARGE_INTEGER freq_cache = {0, 0}; /* Performance Frequency */ - LARGE_INTEGER perf_cpt; - - if(! freq_cache.QuadPart) - { - QueryPerformanceFrequency(&freq_cache); /* Frequency value */ - } + struct timespec timeval; - QueryPerformanceCounter(&perf_cpt); /* Counter value */ - utime = perf_cpt.QuadPart * 1000000.0 / freq_cache.QuadPart; /* time in micros */ -#else - utime = g_get_monotonic_time(); -#endif -#else - /* fallback to less precise clock */ - GTimeVal timeval; - g_get_current_time(&timeval); - utime = (timeval.tv_sec * 1000000.0 + timeval.tv_usec); -#endif + clock_gettime(CLOCK_REALTIME, &timeval); - return utime; + return (timeval.tv_sec * 1000000.0 + timeval.tv_nsec / 1000.0); } @@ -940,8 +911,8 @@ new_fluid_cond(void) #endif -static gpointer -fluid_thread_high_prio(gpointer data) +static fluid_thread_return_t +fluid_thread_high_prio (void *data) { fluid_thread_info_t *info = data; @@ -950,9 +921,8 @@ fluid_thread_high_prio(gpointer data) info->func(info->data); FLUID_FREE(info); - return NULL; + return FLUID_THREAD_RETURN_VALUE; } - /** * Create a new thread. * @param func Function to execute in new thread context @@ -965,72 +935,39 @@ fluid_thread_high_prio(gpointer data) fluid_thread_t * new_fluid_thread(const char *name, fluid_thread_func_t func, void *data, int prio_level, int detach) { - GThread *thread; - fluid_thread_info_t *info = NULL; - GError *err = NULL; - - g_return_val_if_fail(func != NULL, NULL); - -#if OLD_GLIB_THREAD_API - - /* Make sure g_thread_init has been called. - * FIXME - Probably not a good idea in a shared library, - * but what can we do *and* remain backwards compatible? */ - if(!g_thread_supported()) - { - g_thread_init(NULL); - } - -#endif - - if(prio_level > 0) - { - info = FLUID_NEW(fluid_thread_info_t); + fluid_thread_t *thread; + fluid_thread_info_t *info; - if(!info) - { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } + fluid_return_val_if_fail (func != NULL, NULL); - info->func = func; - info->data = data; - info->prio_level = prio_level; -#if NEW_GLIB_THREAD_API - thread = g_thread_try_new(name, fluid_thread_high_prio, info, &err); -#else - thread = g_thread_create(fluid_thread_high_prio, info, detach == FALSE, &err); -#endif - } + thread = FLUID_NEW(fluid_thread_t); + if (prio_level > 0) { + info = FLUID_NEW (fluid_thread_info_t); - else - { -#if NEW_GLIB_THREAD_API - thread = g_thread_try_new(name, (GThreadFunc)func, data, &err); -#else - thread = g_thread_create((GThreadFunc)func, data, detach == FALSE, &err); -#endif + if (!info) { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return NULL; } - if(!thread) - { - FLUID_LOG(FLUID_ERR, "Failed to create the thread: %s", - fluid_gerror_message(err)); - g_clear_error(&err); - FLUID_FREE(info); - return NULL; - } + info->func = func; + info->data = data; + info->prio_level = prio_level; + data = info; + func = fluid_thread_high_prio; + } -#if NEW_GLIB_THREAD_API + pthread_create(thread, NULL, func, data); - if(detach) - { - g_thread_unref(thread); // Release thread reference, if caller wants to detach - } + if (!thread) { + FLUID_LOG(FLUID_ERR, "Failed to create the thread"); + return NULL; + } -#endif + if (detach) { + pthread_detach(*thread); + } - return thread; + return thread; } /** @@ -1051,7 +988,7 @@ delete_fluid_thread(fluid_thread_t *thread) int fluid_thread_join(fluid_thread_t *thread) { - g_thread_join(thread); + pthread_join(*thread, NULL); return FLUID_OK; } @@ -1641,9 +1578,9 @@ FILE* fluid_file_open(const char* path, const char** errMsg) static const char ErrExist[] = "File does not exist."; static const char ErrRegular[] = "File is not regular, refusing to open it."; static const char ErrNull[] = "File does not exists or insufficient permissions to open it."; - + FILE* handle = NULL; - +#ifndef ANDROID if(!g_file_test(path, G_FILE_TEST_EXISTS)) { if(errMsg != NULL) @@ -1658,13 +1595,15 @@ FILE* fluid_file_open(const char* path, const char** errMsg) *errMsg = ErrRegular; } } - else if((handle = FLUID_FOPEN(path, "rb")) == NULL) + else +#endif + if((handle = FLUID_FOPEN(path, "rb")) == NULL) { if(errMsg != NULL) { *errMsg = ErrNull; } } - + return handle; } diff --git a/src/utils/fluid_sys.h b/src/utils/fluid_sys.h index 5dae87800..b65583dbd 100644 --- a/src/utils/fluid_sys.h +++ b/src/utils/fluid_sys.h @@ -112,21 +112,10 @@ /** Integer types */ #if HAVE_STDINT_H #include +#endif -#else - -/* Assume GLIB types */ -typedef gint8 int8_t; -typedef guint8 uint8_t; -typedef gint16 int16_t; -typedef guint16 uint16_t; -typedef gint32 int32_t; -typedef guint32 uint32_t; -typedef gint64 int64_t; -typedef guint64 uint64_t; -typedef guintptr uintptr_t; -typedef gintptr intptr_t; - +#if HAVE_PTHREAD_H +#include #endif #if defined(WIN32) && HAVE_WINDOWS_H @@ -157,16 +146,6 @@ typedef gintptr intptr_t; #include #endif -#include - -/** - * Macro used for safely accessing a message from a GError and using a default - * message if it is NULL. - * @param err Pointer to a GError to access the message field of. - * @return Message string - */ -#define fluid_gerror_message(err) ((err) ? err->message : "No error details") - #define FLUID_INLINE inline @@ -177,17 +156,17 @@ typedef gintptr intptr_t; #define FLUID_INT_TO_POINTER(x) ((void *)(intptr_t)(x)) /* Endian detection */ -#define FLUID_IS_BIG_ENDIAN (G_BYTE_ORDER == G_BIG_ENDIAN) +#define FLUID_IS_BIG_ENDIAN false -#define FLUID_LE32TOH(x) GINT32_FROM_LE(x) -#define FLUID_LE16TOH(x) GINT16_FROM_LE(x) +#define FLUID_LE32TOH(x) le32toh(x) +#define FLUID_LE16TOH(x) le16toh(x) #if FLUID_IS_BIG_ENDIAN #define FLUID_FOURCC(_a, _b, _c, _d) \ (uint32_t)(((uint32_t)(_a) << 24) | ((uint32_t)(_b) << 16) | ((uint32_t)(_c) << 8) | (uint32_t)(_d)) #else #define FLUID_FOURCC(_a, _b, _c, _d) \ - (uint32_t)(((uint32_t)(_d) << 24) | ((uint32_t)(_c) << 16) | ((uint32_t)(_b) << 8) | (uint32_t)(_a)) + (uint32_t)(((uint32_t)(_d) << 24) | ((uint32_t)(_c) << 16) | ((uint32_t)(_b) << 8) | (uint32_t)(_a)) #endif /* @@ -231,194 +210,88 @@ void delete_fluid_timer(fluid_timer_t *timer); int fluid_timer_join(fluid_timer_t *timer); int fluid_timer_stop(fluid_timer_t *timer); -// Macros to use for pre-processor if statements to test which Glib thread API we have (pre or post 2.32) -#define NEW_GLIB_THREAD_API (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 32)) -#define OLD_GLIB_THREAD_API (GLIB_MAJOR_VERSION < 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 32)) - /* Muteces */ -#if NEW_GLIB_THREAD_API - -/* glib 2.32 and newer */ +static FLUID_INLINE void +fluid_pthread_mutex_init(pthread_mutex_t *m, int kind) +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, kind); + pthread_mutex_init(m, &attr); +} /* Regular mutex */ -typedef GMutex fluid_mutex_t; -#define FLUID_MUTEX_INIT { 0 } -#define fluid_mutex_init(_m) g_mutex_init (&(_m)) -#define fluid_mutex_destroy(_m) g_mutex_clear (&(_m)) -#define fluid_mutex_lock(_m) g_mutex_lock(&(_m)) -#define fluid_mutex_unlock(_m) g_mutex_unlock(&(_m)) +typedef pthread_mutex_t fluid_mutex_t; +#define FLUID_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER +#define fluid_mutex_init(_m) pthread_mutex_init (&(_m), NULL) +#define fluid_mutex_destroy(_m) pthread_mutex_destroy(&(_m)) +#define fluid_mutex_lock(_m) pthread_mutex_lock(&(_m)) +#define fluid_mutex_unlock(_m) pthread_mutex_unlock(&(_m)) /* Recursive lock capable mutex */ -typedef GRecMutex fluid_rec_mutex_t; -#define fluid_rec_mutex_init(_m) g_rec_mutex_init(&(_m)) -#define fluid_rec_mutex_destroy(_m) g_rec_mutex_clear(&(_m)) -#define fluid_rec_mutex_lock(_m) g_rec_mutex_lock(&(_m)) -#define fluid_rec_mutex_unlock(_m) g_rec_mutex_unlock(&(_m)) +typedef pthread_mutex_t fluid_rec_mutex_t; +#define fluid_rec_mutex_init(_m) fluid_pthread_mutex_init(&(_m), PTHREAD_MUTEX_RECURSIVE) +#define fluid_rec_mutex_destroy(_m) pthread_mutex_destroy(&(_m)) +#define fluid_rec_mutex_lock(_m) pthread_mutex_lock(&(_m)) +#define fluid_rec_mutex_unlock(_m) pthread_mutex_unlock(&(_m)) /* Dynamically allocated mutex suitable for fluid_cond_t use */ -typedef GMutex fluid_cond_mutex_t; -#define fluid_cond_mutex_lock(m) g_mutex_lock(m) -#define fluid_cond_mutex_unlock(m) g_mutex_unlock(m) +typedef pthread_mutex_t fluid_cond_mutex_t; +#define fluid_cond_mutex_init(m) pthread_mutex_init(m, NULL) +#define fluid_cond_mutex_destroy(m) pthread_mutex_destroy(m) +#define fluid_cond_mutex_lock(m) pthread_mutex_lock(m) +#define fluid_cond_mutex_unlock(m) pthread_mutex_unlock(m) static FLUID_INLINE fluid_cond_mutex_t * new_fluid_cond_mutex(void) { - GMutex *mutex; - mutex = g_new(GMutex, 1); - g_mutex_init(mutex); - return (mutex); + fluid_cond_mutex_t *mutex; + mutex = (fluid_cond_mutex_t *)malloc(sizeof(fluid_cond_mutex_t)); + fluid_cond_mutex_init(mutex); + return mutex; } static FLUID_INLINE void delete_fluid_cond_mutex(fluid_cond_mutex_t *m) { fluid_return_if_fail(m != NULL); - g_mutex_clear(m); - g_free(m); + fluid_cond_mutex_destroy(m); + free(m); } /* Thread condition signaling */ -typedef GCond fluid_cond_t; -#define fluid_cond_signal(cond) g_cond_signal(cond) -#define fluid_cond_broadcast(cond) g_cond_broadcast(cond) -#define fluid_cond_wait(cond, mutex) g_cond_wait(cond, mutex) +typedef pthread_cond_t fluid_cond_t; +#define fluid_cond_init(cond) pthread_cond_init(cond, NULL) +#define fluid_cond_destroy(cond) pthread_cond_destroy(cond) +#define fluid_cond_signal(cond) pthread_cond_signal(cond) +#define fluid_cond_broadcast(cond) pthread_cond_broadcast(cond) +#define fluid_cond_wait(cond, mutex) pthread_cond_wait(cond, mutex) static FLUID_INLINE fluid_cond_t * new_fluid_cond(void) { - GCond *cond; - cond = g_new(GCond, 1); - g_cond_init(cond); - return (cond); + fluid_cond_t *cond; + cond = (fluid_cond_t *)malloc(sizeof(fluid_cond_t)); + fluid_cond_init(cond); + return cond; } static FLUID_INLINE void delete_fluid_cond(fluid_cond_t *cond) { fluid_return_if_fail(cond != NULL); - g_cond_clear(cond); - g_free(cond); + fluid_cond_destroy(cond); + free(cond); } /* Thread private data */ -typedef GPrivate fluid_private_t; -#define fluid_private_init(_priv) memset (&_priv, 0, sizeof (_priv)) +typedef pthread_key_t fluid_private_t; +#define fluid_private_init(_priv) pthread_key_create(&_priv, NULL) #define fluid_private_free(_priv) -#define fluid_private_get(_priv) g_private_get(&(_priv)) -#define fluid_private_set(_priv, _data) g_private_set(&(_priv), _data) - -#else - -/* glib prior to 2.32 */ - -/* Regular mutex */ -typedef GStaticMutex fluid_mutex_t; -#define FLUID_MUTEX_INIT G_STATIC_MUTEX_INIT -#define fluid_mutex_destroy(_m) g_static_mutex_free(&(_m)) -#define fluid_mutex_lock(_m) g_static_mutex_lock(&(_m)) -#define fluid_mutex_unlock(_m) g_static_mutex_unlock(&(_m)) - -#define fluid_mutex_init(_m) do { \ - if (!g_thread_supported ()) g_thread_init (NULL); \ - g_static_mutex_init (&(_m)); \ -} while(0) - -/* Recursive lock capable mutex */ -typedef GStaticRecMutex fluid_rec_mutex_t; -#define fluid_rec_mutex_destroy(_m) g_static_rec_mutex_free(&(_m)) -#define fluid_rec_mutex_lock(_m) g_static_rec_mutex_lock(&(_m)) -#define fluid_rec_mutex_unlock(_m) g_static_rec_mutex_unlock(&(_m)) - -#define fluid_rec_mutex_init(_m) do { \ - if (!g_thread_supported ()) g_thread_init (NULL); \ - g_static_rec_mutex_init (&(_m)); \ -} while(0) - -/* Dynamically allocated mutex suitable for fluid_cond_t use */ -typedef GMutex fluid_cond_mutex_t; -#define delete_fluid_cond_mutex(m) g_mutex_free(m) -#define fluid_cond_mutex_lock(m) g_mutex_lock(m) -#define fluid_cond_mutex_unlock(m) g_mutex_unlock(m) - -static FLUID_INLINE fluid_cond_mutex_t * -new_fluid_cond_mutex(void) -{ - if(!g_thread_supported()) - { - g_thread_init(NULL); - } - - return g_mutex_new(); -} - -/* Thread condition signaling */ -typedef GCond fluid_cond_t; -fluid_cond_t *new_fluid_cond(void); -#define delete_fluid_cond(cond) g_cond_free(cond) -#define fluid_cond_signal(cond) g_cond_signal(cond) -#define fluid_cond_broadcast(cond) g_cond_broadcast(cond) -#define fluid_cond_wait(cond, mutex) g_cond_wait(cond, mutex) - -/* Thread private data */ -typedef GStaticPrivate fluid_private_t; -#define fluid_private_get(_priv) g_static_private_get(&(_priv)) -#define fluid_private_set(_priv, _data) g_static_private_set(&(_priv), _data, NULL) -#define fluid_private_free(_priv) g_static_private_free(&(_priv)) - -#define fluid_private_init(_priv) do { \ - if (!g_thread_supported ()) g_thread_init (NULL); \ - g_static_private_init (&(_priv)); \ -} while(0) - -#endif - - -/* Atomic operations */ - -#define fluid_atomic_int_inc(_pi) g_atomic_int_inc(_pi) -#define fluid_atomic_int_get(_pi) g_atomic_int_get(_pi) -#define fluid_atomic_int_set(_pi, _val) g_atomic_int_set(_pi, _val) -#define fluid_atomic_int_dec_and_test(_pi) g_atomic_int_dec_and_test(_pi) -#define fluid_atomic_int_compare_and_exchange(_pi, _old, _new) \ - g_atomic_int_compare_and_exchange(_pi, _old, _new) - -#if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 30) -#define fluid_atomic_int_exchange_and_add(_pi, _add) \ - g_atomic_int_add(_pi, _add) -#define fluid_atomic_int_add(_pi, _add) \ - g_atomic_int_add(_pi, _add) -#else -#define fluid_atomic_int_exchange_and_add(_pi, _add) \ - g_atomic_int_exchange_and_add(_pi, _add) -#define fluid_atomic_int_add(_pi, _add) \ - g_atomic_int_exchange_and_add(_pi, _add) -#endif - -#define fluid_atomic_pointer_get(_pp) g_atomic_pointer_get(_pp) -#define fluid_atomic_pointer_set(_pp, val) g_atomic_pointer_set(_pp, val) -#define fluid_atomic_pointer_compare_and_exchange(_pp, _old, _new) \ - g_atomic_pointer_compare_and_exchange(_pp, _old, _new) - -static FLUID_INLINE void -fluid_atomic_float_set(volatile float *fptr, float val) -{ - int32_t ival; - memcpy(&ival, &val, 4); - fluid_atomic_int_set((volatile int *)fptr, ival); -} - -static FLUID_INLINE float -fluid_atomic_float_get(volatile float *fptr) -{ - int32_t ival; - float fval; - ival = fluid_atomic_int_get((volatile int *)fptr); - memcpy(&fval, &ival, 4); - return fval; -} - +#define fluid_private_get(_priv) pthread_getspecific((_priv)) +#define fluid_private_set(_priv, _data) pthread_setspecific((_priv), (_data)) /* Threads */ @@ -427,12 +300,12 @@ typedef void *fluid_thread_return_t; /* static return value for thread functions which requires a return value */ #define FLUID_THREAD_RETURN_VALUE (NULL) -typedef GThread fluid_thread_t; +typedef pthread_t fluid_thread_t; typedef fluid_thread_return_t (*fluid_thread_func_t)(void *data); -#define FLUID_THREAD_ID_NULL NULL /* A NULL "ID" value */ -#define fluid_thread_id_t GThread * /* Data type for a thread ID */ -#define fluid_thread_get_id() g_thread_self() /* Get unique "ID" for current thread */ +#define FLUID_THREAD_ID_NULL NULL /* A NULL "ID" value */ +#define fluid_thread_id_t pthread_t /* Data type for a thread ID */ +#define fluid_thread_get_id() pthread_self() /* Get unique "ID" for current thread */ fluid_thread_t *new_fluid_thread(const char *name, fluid_thread_func_t func, void *data, int prio_level, int detach); @@ -440,18 +313,9 @@ void delete_fluid_thread(fluid_thread_t *thread); void fluid_thread_self_set_prio(int prio_level); int fluid_thread_join(fluid_thread_t *thread); -/* Dynamic Module Loading, currently only used by LADSPA subsystem */ -#ifdef LADSPA - -typedef GModule fluid_module_t; - -#define fluid_module_open(_name) g_module_open((_name), G_MODULE_BIND_LOCAL) -#define fluid_module_close(_mod) g_module_close(_mod) -#define fluid_module_error() g_module_error() -#define fluid_module_name(_mod) g_module_name(_mod) -#define fluid_module_symbol(_mod, _name, _ptr) g_module_symbol((_mod), (_name), (_ptr)) +/* Atomic operations */ -#endif /* LADSPA */ +#include "fluid_atomic.h" /* Sockets and I/O */ @@ -477,24 +341,8 @@ fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock); fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock); /* File access */ -#define fluid_stat(_filename, _statbuf) g_stat((_filename), (_statbuf)) -#if !GLIB_CHECK_VERSION(2, 26, 0) - /* GStatBuf has not been introduced yet, manually typedef to what they had at that time: - * https://github.com/GNOME/glib/blob/e7763678b56e3be073cc55d707a6e92fc2055ee0/glib/gstdio.h#L98-L115 - */ - #if defined(WIN32) || HAVE_WINDOWS_H // somehow reliably mock G_OS_WIN32?? - // Any effort from our side to reliably mock GStatBuf on Windows is in vain. E.g. glib-2.16 is broken as it uses struct stat rather than struct _stat32 on Win x86. - // Disable it (the user has been warned by cmake). - #undef fluid_stat - #define fluid_stat(_filename, _statbuf) (-1) - typedef struct _fluid_stat_buf_t{int st_mtime;} fluid_stat_buf_t; - #else - /* posix, OS/2, etc. */ - typedef struct stat fluid_stat_buf_t; - #endif -#else -typedef GStatBuf fluid_stat_buf_t; -#endif +typedef struct stat fluid_stat_buf_t; +#define fluid_stat(_filename, _statbuf) stat((_filename), (_statbuf)) FILE* fluid_file_open(const char* filename, const char** errMsg); diff --git a/src/utils/fluidsynth_priv.h b/src/utils/fluidsynth_priv.h index 0626baced..fd42e344b 100644 --- a/src/utils/fluidsynth_priv.h +++ b/src/utils/fluidsynth_priv.h @@ -20,7 +20,7 @@ /* * @file fluidsynth_priv.h - * + * * lightweight part of fluid_sys.h, containing forward declarations of fluidsynth's private types and private macros * * include this one file in fluidsynth's private header files @@ -29,9 +29,9 @@ #ifndef _FLUIDSYNTH_PRIV_H #define _FLUIDSYNTH_PRIV_H -#include - +#if HAVE_CONFIG_H #include "config.h" +#endif #if HAVE_STDLIB_H #include // malloc, free @@ -68,12 +68,20 @@ typedef double fluid_real_t; _type* _name = g_newa(_type, (_len)) #endif +#define TRUE 1 +#define FALSE 0 -/** Atomic types */ -typedef int fluid_atomic_int_t; -typedef unsigned int fluid_atomic_uint_t; -typedef float fluid_atomic_float_t; +/** Atomic types */ +typedef struct { + volatile int value; +} fluid_atomic_int_t; +typedef struct { + volatile unsigned value; +} fluid_atomic_uint_t; +typedef struct { + volatile float value; +} fluid_atomic_float_t; /*************************************************************** * @@ -275,14 +283,15 @@ do { strncpy(_dst,_src,_n); \ #define FLUID_LOG fluid_log #endif -#if defined(DEBUG) && !defined(NDEBUG) -#define FLUID_ASSERT(a) g_assert(a) +#ifdef DEBUG +#include +#define FLUID_ASSERT(a) assert(a) #else #define FLUID_ASSERT(a) #endif -#define FLUID_LIKELY G_LIKELY -#define FLUID_UNLIKELY G_UNLIKELY +#define FLUID_LIKELY(x) __builtin_expect(!!(x), 1) +#define FLUID_UNLIKELY(x) __builtin_expect(!!(x), 0) /* Misc */ #if defined(__INTEL_COMPILER)