summaryrefslogtreecommitdiff
path: root/libs/fluidsynth/src/fluid_sys.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/fluidsynth/src/fluid_sys.h')
-rw-r--r--libs/fluidsynth/src/fluid_sys.h453
1 files changed, 323 insertions, 130 deletions
diff --git a/libs/fluidsynth/src/fluid_sys.h b/libs/fluidsynth/src/fluid_sys.h
index 4953515692..d95f6159f2 100644
--- a/libs/fluidsynth/src/fluid_sys.h
+++ b/libs/fluidsynth/src/fluid_sys.h
@@ -3,16 +3,16 @@
* 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
+ * 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
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public
+ * 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
@@ -36,9 +36,13 @@
#ifndef _FLUID_SYS_H
#define _FLUID_SYS_H
-#include <glib.h>
#include "fluidsynth_priv.h"
+#ifdef LADSPA
+#include <gmodule.h>
+#endif
+
+#include <glib/gstdio.h>
/**
* Macro used for safely accessing a message from a GError and using a default
@@ -48,50 +52,46 @@
*/
#define fluid_gerror_message(err) ((err) ? err->message : "No error details")
-
-void fluid_sys_config(void);
-void fluid_log_config(void);
-void fluid_time_config(void);
-
-
/* Misc */
+#if defined(__INTEL_COMPILER)
+#define FLUID_RESTRICT restrict
+#elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+#define FLUID_RESTRICT __restrict__
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
+#define FLUID_RESTRICT __restrict
+#else
+#warning "Dont know how this compiler handles restrict pointers, refuse to use them."
+#define FLUID_RESTRICT
+#endif
-#define fluid_return_val_if_fail g_return_val_if_fail
-#define fluid_return_if_fail g_return_if_fail
#define FLUID_INLINE inline
#define FLUID_POINTER_TO_UINT GPOINTER_TO_UINT
#define FLUID_UINT_TO_POINTER GUINT_TO_POINTER
#define FLUID_POINTER_TO_INT GPOINTER_TO_INT
#define FLUID_INT_TO_POINTER GINT_TO_POINTER
#define FLUID_N_ELEMENTS(struct) (sizeof (struct) / sizeof (struct[0]))
+#define FLUID_MEMBER_SIZE(struct, member) ( sizeof (((struct *)0)->member) )
#define FLUID_IS_BIG_ENDIAN (G_BYTE_ORDER == G_BIG_ENDIAN)
-/*
- * Utility functions
- */
-char *fluid_strtok (char **str, char *delim);
+#define FLUID_LE32TOH(x) GINT32_FROM_LE(x)
+#define FLUID_LE16TOH(x) GINT16_FROM_LE(x)
-/**
+#define fluid_return_if_fail(cond) \
+if(cond) \
+ ; \
+else \
+ return
- Additional debugging system, separate from the log system. This
- allows to print selected debug messages of a specific subsystem.
- */
-
-extern unsigned int fluid_debug_flags;
-
-#if DEBUG
-
-enum fluid_debug_level {
- FLUID_DBG_DRIVER = 1
-};
+#define fluid_return_val_if_fail(cond, val) \
+ fluid_return_if_fail(cond) (val)
-int fluid_debug(int level, char * fmt, ...);
-#else
-#define fluid_debug
-#endif
+/*
+ * Utility functions
+ */
+char *fluid_strtok(char **str, const char *delim);
#if defined(__OS2__)
@@ -112,17 +112,17 @@ double fluid_utime(void);
/* if the callback function returns 1 the timer will continue; if it
returns 0 it will stop */
-typedef int (*fluid_timer_callback_t)(void* data, unsigned int msec);
+typedef int (*fluid_timer_callback_t)(void *data, unsigned int msec);
typedef struct _fluid_timer_t fluid_timer_t;
-fluid_timer_t* new_fluid_timer(int msec, fluid_timer_callback_t callback,
- void* data, int new_thread, int auto_destroy,
+fluid_timer_t *new_fluid_timer(int msec, fluid_timer_callback_t callback,
+ void *data, int new_thread, int auto_destroy,
int high_priority);
-int delete_fluid_timer(fluid_timer_t* timer);
-int fluid_timer_join(fluid_timer_t* timer);
-int fluid_timer_stop(fluid_timer_t* timer);
+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))
@@ -155,19 +155,20 @@ typedef GMutex fluid_cond_mutex_t;
#define fluid_cond_mutex_unlock(m) g_mutex_unlock(m)
static FLUID_INLINE fluid_cond_mutex_t *
-new_fluid_cond_mutex (void)
+new_fluid_cond_mutex(void)
{
- GMutex *mutex;
- mutex = g_new (GMutex, 1);
- g_mutex_init (mutex);
- return (mutex);
+ GMutex *mutex;
+ mutex = g_new(GMutex, 1);
+ g_mutex_init(mutex);
+ return (mutex);
}
static FLUID_INLINE void
-delete_fluid_cond_mutex (fluid_cond_mutex_t *m)
+delete_fluid_cond_mutex(fluid_cond_mutex_t *m)
{
- g_mutex_clear (m);
- g_free (m);
+ fluid_return_if_fail(m != NULL);
+ g_mutex_clear(m);
+ g_free(m);
}
/* Thread condition signaling */
@@ -177,19 +178,20 @@ typedef GCond fluid_cond_t;
#define fluid_cond_wait(cond, mutex) g_cond_wait(cond, mutex)
static FLUID_INLINE fluid_cond_t *
-new_fluid_cond (void)
+new_fluid_cond(void)
{
- GCond *cond;
- cond = g_new (GCond, 1);
- g_cond_init (cond);
- return (cond);
+ GCond *cond;
+ cond = g_new(GCond, 1);
+ g_cond_init(cond);
+ return (cond);
}
static FLUID_INLINE void
-delete_fluid_cond (fluid_cond_t *cond)
+delete_fluid_cond(fluid_cond_t *cond)
{
- g_cond_clear (cond);
- g_free (cond);
+ fluid_return_if_fail(cond != NULL);
+ g_cond_clear(cond);
+ g_free(cond);
}
/* Thread private data */
@@ -211,10 +213,10 @@ typedef GStaticMutex fluid_mutex_t;
#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) G_STMT_START { \
+#define fluid_mutex_init(_m) do { \
if (!g_thread_supported ()) g_thread_init (NULL); \
g_static_mutex_init (&(_m)); \
-} G_STMT_END;
+} while(0)
/* Recursive lock capable mutex */
typedef GStaticRecMutex fluid_rec_mutex_t;
@@ -222,10 +224,10 @@ typedef GStaticRecMutex fluid_rec_mutex_t;
#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) G_STMT_START { \
+#define fluid_rec_mutex_init(_m) do { \
if (!g_thread_supported ()) g_thread_init (NULL); \
g_static_rec_mutex_init (&(_m)); \
-} G_STMT_END;
+} while(0)
/* Dynamically allocated mutex suitable for fluid_cond_t use */
typedef GMutex fluid_cond_mutex_t;
@@ -234,15 +236,19 @@ typedef GMutex fluid_cond_mutex_t;
#define fluid_cond_mutex_unlock(m) g_mutex_unlock(m)
static FLUID_INLINE fluid_cond_mutex_t *
-new_fluid_cond_mutex (void)
+new_fluid_cond_mutex(void)
{
- if (!g_thread_supported ()) g_thread_init (NULL);
- return g_mutex_new ();
+ 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);
+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)
@@ -254,10 +260,10 @@ typedef GStaticPrivate fluid_private_t;
#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) G_STMT_START { \
+#define fluid_private_init(_priv) do { \
if (!g_thread_supported ()) g_thread_init (NULL); \
g_static_private_init (&(_priv)); \
-} G_STMT_END;
+} while(0)
#endif
@@ -265,7 +271,6 @@ typedef GStaticPrivate fluid_private_t;
/* Atomic operations */
#define fluid_atomic_int_inc(_pi) g_atomic_int_inc(_pi)
-#define fluid_atomic_int_add(_pi, _val) g_atomic_int_add(_pi, _val)
#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)
@@ -275,9 +280,13 @@ typedef GStaticPrivate fluid_private_t;
#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)
@@ -288,115 +297,276 @@ typedef GStaticPrivate fluid_private_t;
static FLUID_INLINE void
fluid_atomic_float_set(volatile float *fptr, float val)
{
- sint32 ival;
- memcpy (&ival, &val, 4);
- fluid_atomic_int_set ((volatile int *)fptr, ival);
+ 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)
{
- sint32 ival;
- float fval;
- ival = fluid_atomic_int_get ((volatile int *)fptr);
- memcpy (&fval, &ival, 4);
- return fval;
+ int32_t ival;
+ float fval;
+ ival = fluid_atomic_int_get((volatile int *)fptr);
+ memcpy(&fval, &ival, 4);
+ return fval;
}
/* Threads */
+/* other thread implementations might change this for their needs */
+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 void (*fluid_thread_func_t)(void* data);
+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 */
-fluid_thread_t* new_fluid_thread(const char *name, fluid_thread_func_t func, void *data,
+fluid_thread_t *new_fluid_thread(const char *name, fluid_thread_func_t func, void *data,
int prio_level, int detach);
-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);
+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))
+
+#endif /* LADSPA */
/* Sockets and I/O */
-fluid_istream_t fluid_get_stdin (void);
-fluid_ostream_t fluid_get_stdout (void);
-int fluid_istream_readline(fluid_istream_t in, fluid_ostream_t out, char* prompt, char* buf, int len);
-int fluid_ostream_printf (fluid_ostream_t out, char* format, ...);
+fluid_istream_t fluid_get_stdin(void);
+fluid_ostream_t fluid_get_stdout(void);
+int fluid_istream_readline(fluid_istream_t in, fluid_ostream_t out, char *prompt, char *buf, int len);
+int fluid_ostream_printf(fluid_ostream_t out, const char *format, ...);
/* The function should return 0 if no error occured, non-zero
otherwise. If the function return non-zero, the socket will be
closed by the server. */
-typedef int (*fluid_server_func_t)(void* data, fluid_socket_t client_socket, char* addr);
+typedef int (*fluid_server_func_t)(void *data, fluid_socket_t client_socket, char *addr);
-fluid_server_socket_t* new_fluid_server_socket(int port, fluid_server_func_t func, void* data);
-int delete_fluid_server_socket(fluid_server_socket_t* sock);
-int fluid_server_socket_join(fluid_server_socket_t* sock);
+fluid_server_socket_t *new_fluid_server_socket(int port, fluid_server_func_t func, void *data);
+void delete_fluid_server_socket(fluid_server_socket_t *sock);
+int fluid_server_socket_join(fluid_server_socket_t *sock);
void fluid_socket_close(fluid_socket_t sock);
fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock);
fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock);
+/* File access */
+#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??
+ #if defined (_MSC_VER) && !defined(_WIN64)
+ typedef struct _stat32 fluid_stat_buf_t;
+ #else
+ typedef struct _stat fluid_stat_buf_t;
+ #endif
+ #else
+ /* posix, OS/2, etc. */
+ typedef struct stat fluid_stat_buf_t;
+ #endif
+#else
+typedef GStatBuf fluid_stat_buf_t;
+#endif
+#define fluid_stat(_filename, _statbuf) g_stat((_filename), (_statbuf))
/* Profiling */
+#if WITH_PROFILING
+/** profiling interface beetween Profiling command shell and Audio
+ rendering API (FluidProfile_0004.pdf- 3.2.2)
+*/
+/*
+ -----------------------------------------------------------------------------
+ Shell task side | Profiling interface | Audio task side
+ -----------------------------------------------------------------------------
+ profiling | Internal | | | Audio
+ command <---> |<-- profling -->| Data |<--macros -->| <--> rendering
+ shell | API | | | API
-/**
- * Profile numbers. List all the pieces of code you want to profile
- * here. Be sure to add an entry in the fluid_profile_data table in
- * fluid_sys.c
- */
-enum {
- FLUID_PROF_WRITE,
- FLUID_PROF_ONE_BLOCK,
- FLUID_PROF_ONE_BLOCK_CLEAR,
- FLUID_PROF_ONE_BLOCK_VOICE,
- FLUID_PROF_ONE_BLOCK_VOICES,
- FLUID_PROF_ONE_BLOCK_REVERB,
- FLUID_PROF_ONE_BLOCK_CHORUS,
- FLUID_PROF_VOICE_NOTE,
- FLUID_PROF_VOICE_RELEASE,
- FLUID_PROF_LAST
-};
+*/
+/* default parameters for shell command "prof_start" in fluid_sys.c */
+#define FLUID_PROFILE_DEFAULT_BANK 0 /* default bank */
+#define FLUID_PROFILE_DEFAULT_PROG 16 /* default prog (organ) */
+#define FLUID_PROFILE_FIRST_KEY 12 /* first key generated */
+#define FLUID_PROFILE_LAST_KEY 108 /* last key generated */
+#define FLUID_PROFILE_DEFAULT_VEL 64 /* default note velocity */
+#define FLUID_PROFILE_VOICE_ATTEN -0.04f /* gain attenuation per voice (dB) */
-#if WITH_PROFILING
-void fluid_profiling_print(void);
+#define FLUID_PROFILE_DEFAULT_PRINT 0 /* default print mode */
+#define FLUID_PROFILE_DEFAULT_N_PROF 1 /* default number of measures */
+#define FLUID_PROFILE_DEFAULT_DURATION 500 /* default duration (ms) */
+
+
+extern unsigned short fluid_profile_notes; /* number of generated notes */
+extern unsigned char fluid_profile_bank; /* bank,prog preset used by */
+extern unsigned char fluid_profile_prog; /* generated notes */
+extern unsigned char fluid_profile_print; /* print mode */
+
+extern unsigned short fluid_profile_n_prof;/* number of measures */
+extern unsigned short fluid_profile_dur; /* measure duration in ms */
+extern fluid_atomic_int_t fluid_profile_lock ; /* lock between multiple shell */
+/**/
+
+/*----------------------------------------------
+ Internal profiling API (in fluid_sys.c)
+-----------------------------------------------*/
+/* Starts a profiling measure used in shell command "prof_start" */
+void fluid_profile_start_stop(unsigned int end_ticks, short clear_data);
+
+/* Returns status used in shell command "prof_start" */
+int fluid_profile_get_status(void);
+
+/* Prints profiling data used in shell command "prof_start" */
+void fluid_profiling_print_data(double sample_rate, fluid_ostream_t out);
+
+/* Returns True if profiling cancellation has been requested */
+int fluid_profile_is_cancel_req(void);
+
+/* For OS that implement <ENTER> key for profile cancellation:
+ 1) Adds #define FLUID_PROFILE_CANCEL
+ 2) Adds the necessary code inside fluid_profile_is_cancel() see fluid_sys.c
+*/
+#if defined(WIN32) /* Profile cancellation is supported for Windows */
+#define FLUID_PROFILE_CANCEL
+
+#elif defined(__OS2__) /* OS/2 specific stuff */
+/* Profile cancellation isn't yet supported for OS2 */
+#else /* POSIX stuff */
+#define FLUID_PROFILE_CANCEL /* Profile cancellation is supported for linux */
+#include <unistd.h> /* STDIN_FILENO */
+#include <sys/select.h> /* select() */
+#endif /* posix */
-/** Profiling data. Keep track of min/avg/max values to execute a
+/* logging profiling data (used on synthesizer instance deletion) */
+void fluid_profiling_print(void);
+
+/*----------------------------------------------
+ Profiling Data (in fluid_sys.c)
+-----------------------------------------------*/
+/** Profiling data. Keep track of min/avg/max values to profile a
piece of code. */
-typedef struct _fluid_profile_data_t {
- int num;
- char* description;
- double min, max, total;
- unsigned int count;
+typedef struct _fluid_profile_data_t
+{
+ const char *description; /* name of the piece of code under profiling */
+ double min, max, total; /* duration (microsecond) */
+ unsigned int count; /* total count */
+ unsigned int n_voices; /* voices number */
+ unsigned int n_samples; /* audio samples number */
} fluid_profile_data_t;
-extern fluid_profile_data_t fluid_profile_data[];
+enum
+{
+ /* commands/status (profiling interface) */
+ PROFILE_STOP, /* command to stop a profiling measure */
+ PROFILE_START, /* command to start a profile measure */
+ PROFILE_READY, /* status to signal that a profiling measure has finished
+ and ready to be printed */
+ /*- State returned by fluid_profile_get_status() -*/
+ /* between profiling commands and internal profiling API */
+ PROFILE_RUNNING, /* a profiling measure is running */
+ PROFILE_CANCELED,/* a profiling measure has been canceled */
+};
+
+/* Data interface */
+extern unsigned char fluid_profile_status ; /* command and status */
+extern unsigned int fluid_profile_end_ticks; /* ending position (in ticks) */
+extern fluid_profile_data_t fluid_profile_data[]; /* Profiling data */
-/** Macro to obtain a time refence used for the profiling */
+/*----------------------------------------------
+ Probes macros
+-----------------------------------------------*/
+/** Macro to obtain a time reference used for the profiling */
#define fluid_profile_ref() fluid_utime()
/** Macro to create a variable and assign the current reference time for profiling.
* So we don't get unused variable warnings when profiling is disabled. */
#define fluid_profile_ref_var(name) double name = fluid_utime()
-/** Macro to calculate the min/avg/max. Needs a time refence and a
- profile number. */
-#define fluid_profile(_num,_ref) { \
- double _now = fluid_utime(); \
- double _delta = _now - _ref; \
- fluid_profile_data[_num].min = _delta < fluid_profile_data[_num].min ? _delta : fluid_profile_data[_num].min; \
- fluid_profile_data[_num].max = _delta > fluid_profile_data[_num].max ? _delta : fluid_profile_data[_num].max; \
- fluid_profile_data[_num].total += _delta; \
- fluid_profile_data[_num].count++; \
- _ref = _now; \
+/**
+ * Profile identifier numbers. List all the pieces of code you want to profile
+ * here. Be sure to add an entry in the fluid_profile_data table in
+ * fluid_sys.c
+ */
+enum
+{
+ FLUID_PROF_WRITE,
+ FLUID_PROF_ONE_BLOCK,
+ FLUID_PROF_ONE_BLOCK_CLEAR,
+ FLUID_PROF_ONE_BLOCK_VOICE,
+ FLUID_PROF_ONE_BLOCK_VOICES,
+ FLUID_PROF_ONE_BLOCK_REVERB,
+ FLUID_PROF_ONE_BLOCK_CHORUS,
+ FLUID_PROF_VOICE_NOTE,
+ FLUID_PROF_VOICE_RELEASE,
+ FLUID_PROFILE_NBR /* number of profile probes */
+};
+/** Those macros are used to calculate the min/avg/max. Needs a profile number, a
+ time reference, the voices and samples number. */
+
+/* local macro : acquiere data */
+#define fluid_profile_data(_num, _ref, voices, samples)\
+{\
+ double _now = fluid_utime();\
+ double _delta = _now - _ref;\
+ fluid_profile_data[_num].min = _delta < fluid_profile_data[_num].min ?\
+ _delta : fluid_profile_data[_num].min; \
+ fluid_profile_data[_num].max = _delta > fluid_profile_data[_num].max ?\
+ _delta : fluid_profile_data[_num].max;\
+ fluid_profile_data[_num].total += _delta;\
+ fluid_profile_data[_num].count++;\
+ fluid_profile_data[_num].n_voices += voices;\
+ fluid_profile_data[_num].n_samples += samples;\
+ _ref = _now;\
}
+/** Macro to collect data, called from inner functions inside audio
+ rendering API */
+#define fluid_profile(_num, _ref, voices, samples)\
+{\
+ if ( fluid_profile_status == PROFILE_START)\
+ { /* acquires data */\
+ fluid_profile_data(_num, _ref, voices, samples)\
+ }\
+}
+
+/** Macro to collect data, called from audio rendering API (fluid_write_xxxx()).
+ This macro control profiling ending position (in ticks).
+*/
+#define fluid_profile_write(_num, _ref, voices, samples)\
+{\
+ if (fluid_profile_status == PROFILE_START)\
+ {\
+ /* acquires data first: must be done before checking that profile is
+ finished to ensure at least one valid data sample.
+ */\
+ fluid_profile_data(_num, _ref, voices, samples)\
+ if (fluid_synth_get_ticks(synth) >= fluid_profile_end_ticks)\
+ {\
+ /* profiling is finished */\
+ fluid_profile_status = PROFILE_READY;\
+ }\
+ }\
+}
#else
@@ -404,11 +574,9 @@ extern fluid_profile_data_t fluid_profile_data[];
#define fluid_profiling_print()
#define fluid_profile_ref() 0
#define fluid_profile_ref_var(name)
-#define fluid_profile(_num,_ref)
-
-#endif
-
-
+#define fluid_profile(_num,_ref,voices, samples)
+#define fluid_profile_write(_num,_ref, voices, samples)
+#endif /* WITH_PROFILING */
/**
@@ -442,7 +610,32 @@ extern fluid_profile_data_t fluid_profile_data[];
#define fluid_clear_fpe()
#endif
-unsigned int fluid_check_fpe_i386(char * explanation_in_case_of_fpe);
+unsigned int fluid_check_fpe_i386(char *explanation_in_case_of_fpe);
void fluid_clear_fpe_i386(void);
+/* System control */
+void fluid_msleep(unsigned int msecs);
+
+/**
+ * Advances the given \c ptr to the next \c alignment byte boundary.
+ * Make sure you've allocated an extra of \c alignment bytes to avoid a buffer overflow.
+ *
+ * @note \c alignment must be a power of two
+ * @return Returned pointer is guarenteed to be aligned to \c alignment boundary and in range \f[ ptr <= returned_ptr < ptr + alignment \f].
+ */
+static FLUID_INLINE void *fluid_align_ptr(const void *ptr, unsigned int alignment)
+{
+ uintptr_t ptr_int = (uintptr_t)ptr;
+ unsigned int offset = ptr_int & (alignment - 1);
+ unsigned int add = (alignment - offset) & (alignment - 1); // advance the pointer to the next alignment boundary
+ ptr_int += add;
+
+ /* assert alignment is power of two */
+ FLUID_ASSERT(!(alignment == 0) && !(alignment & (alignment - 1)));
+
+ return (void *)ptr_int;
+}
+
+#define FLUID_DEFAULT_ALIGNMENT (64U)
+
#endif /* _FLUID_SYS_H */