2003-03-11 16:56:45 +00:00
|
|
|
/* 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.
|
2007-03-04 16:45:05 +00:00
|
|
|
*
|
2003-03-11 16:56:45 +00:00
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
This header contains a bunch of (mostly) system and machine
|
|
|
|
dependent functions:
|
|
|
|
|
|
|
|
- timers
|
|
|
|
- current time in milliseconds and microseconds
|
|
|
|
- debug logging
|
|
|
|
- profiling
|
|
|
|
- memory locking
|
|
|
|
- checking for floating point exceptions
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _FLUID_SYS_H
|
|
|
|
#define _FLUID_SYS_H
|
|
|
|
|
2009-04-27 19:13:49 +00:00
|
|
|
#include <glib.h>
|
2003-03-11 16:56:45 +00:00
|
|
|
#include "fluidsynth_priv.h"
|
|
|
|
|
|
|
|
|
2009-04-27 19:13:49 +00:00
|
|
|
/**
|
|
|
|
* 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")
|
|
|
|
|
|
|
|
|
2003-03-11 16:56:45 +00:00
|
|
|
void fluid_sys_config(void);
|
|
|
|
void fluid_log_config(void);
|
|
|
|
void fluid_time_config(void);
|
|
|
|
|
2006-12-10 16:02:04 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Utility functions
|
|
|
|
*/
|
|
|
|
char *fluid_strtok (char **str, char *delim);
|
|
|
|
|
|
|
|
|
2003-03-11 16:56:45 +00:00
|
|
|
/**
|
2007-03-04 16:45:05 +00:00
|
|
|
|
2003-03-11 16:56:45 +00:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
|
|
|
int fluid_debug(int level, char * fmt, ...);
|
|
|
|
|
|
|
|
#else
|
2007-03-04 16:45:05 +00:00
|
|
|
#define fluid_debug
|
2003-03-11 16:56:45 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2009-04-27 19:13:49 +00:00
|
|
|
#if defined(__OS2__)
|
2009-02-04 07:45:44 +00:00
|
|
|
#define INCL_DOS
|
|
|
|
#include <os2.h>
|
|
|
|
|
|
|
|
typedef int socklen_t;
|
2009-04-27 19:13:49 +00:00
|
|
|
#endif
|
2009-02-04 07:45:44 +00:00
|
|
|
|
|
|
|
unsigned int fluid_curtime(void);
|
|
|
|
double fluid_utime(void);
|
|
|
|
|
2003-03-11 16:56:45 +00:00
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
/**
|
2003-03-11 16:56:45 +00:00
|
|
|
Timers
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* 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 struct _fluid_timer_t fluid_timer_t;
|
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
fluid_timer_t* new_fluid_timer(int msec, fluid_timer_callback_t callback,
|
2009-04-27 19:13:49 +00:00
|
|
|
void* data, int new_thread, int auto_destroy);
|
2003-03-11 16:56:45 +00:00
|
|
|
|
|
|
|
int delete_fluid_timer(fluid_timer_t* timer);
|
|
|
|
int fluid_timer_join(fluid_timer_t* timer);
|
|
|
|
int fluid_timer_stop(fluid_timer_t* timer);
|
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
/**
|
2003-03-11 16:56:45 +00:00
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
Muteces
|
2003-03-11 16:56:45 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2009-04-27 19:13:49 +00:00
|
|
|
typedef GStaticMutex fluid_mutex_t;
|
|
|
|
#define fluid_mutex_init(_m) g_static_mutex_init(&(_m))
|
|
|
|
#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))
|
2003-03-11 16:56:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Threads
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2009-04-27 19:13:49 +00:00
|
|
|
typedef GThread fluid_thread_t;
|
2003-03-11 16:56:45 +00:00
|
|
|
typedef void (*fluid_thread_func_t)(void* data);
|
|
|
|
|
|
|
|
/** When detached, 'join' does not work and the thread destroys itself
|
|
|
|
when finished. */
|
|
|
|
fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach);
|
|
|
|
int delete_fluid_thread(fluid_thread_t* thread);
|
|
|
|
int fluid_thread_join(fluid_thread_t* thread);
|
|
|
|
|
|
|
|
/**
|
2009-04-27 19:13:49 +00:00
|
|
|
Sockets and I/O
|
2003-03-11 16:56:45 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2009-04-27 19:13:49 +00:00
|
|
|
fluid_istream_t fluid_get_stdin (void);
|
|
|
|
fluid_ostream_t fluid_get_stdout (void);
|
|
|
|
int fluid_istream_readline(fluid_istream_t in, char* prompt, char* buf, int len);
|
|
|
|
int fluid_ostream_printf (fluid_ostream_t out, char* format, ...);
|
2003-03-11 16:56:45 +00:00
|
|
|
|
|
|
|
/** 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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
/**
|
2003-03-11 16:56:45 +00:00
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
Profiling
|
2003-03-11 16:56:45 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
/**
|
2003-03-11 16:56:45 +00:00
|
|
|
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_S16,
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#if WITH_PROFILING
|
|
|
|
|
|
|
|
void fluid_profiling_print(void);
|
|
|
|
|
|
|
|
|
|
|
|
/** Profiling data. Keep track of min/avg/max values to execute a
|
|
|
|
piece of code. */
|
|
|
|
typedef struct _fluid_profile_data_t {
|
|
|
|
int num;
|
|
|
|
char* description;
|
|
|
|
double min, max, total;
|
|
|
|
unsigned int count;
|
|
|
|
} fluid_profile_data_t;
|
|
|
|
|
|
|
|
extern fluid_profile_data_t fluid_profile_data[];
|
|
|
|
|
|
|
|
/** Macro to obtain a time refence used for the profiling */
|
|
|
|
#define fluid_profile_ref() 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; \
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
/* No profiling */
|
|
|
|
#define fluid_profiling_print()
|
|
|
|
#define fluid_profile_ref() 0
|
|
|
|
#define fluid_profile(_num,_ref)
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
/**
|
2003-03-11 16:56:45 +00:00
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
Memory locking
|
2003-03-11 16:56:45 +00:00
|
|
|
|
|
|
|
Memory locking is used to avoid swapping of the large block of
|
|
|
|
sample data.
|
|
|
|
*/
|
|
|
|
|
2009-02-04 07:45:44 +00:00
|
|
|
#if defined(HAVE_SYS_MMAN_H) && !defined(__OS2__)
|
2003-03-11 16:56:45 +00:00
|
|
|
#define fluid_mlock(_p,_n) mlock(_p, _n)
|
|
|
|
#define fluid_munlock(_p,_n) munlock(_p,_n)
|
|
|
|
#else
|
|
|
|
#define fluid_mlock(_p,_n) 0
|
2007-03-04 16:45:05 +00:00
|
|
|
#define fluid_munlock(_p,_n)
|
2003-03-11 16:56:45 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
/**
|
2003-03-11 16:56:45 +00:00
|
|
|
|
2007-03-04 16:45:05 +00:00
|
|
|
Floating point exceptions
|
2003-03-11 16:56:45 +00:00
|
|
|
|
|
|
|
fluid_check_fpe() checks for "unnormalized numbers" and other
|
|
|
|
exceptions of the floating point processsor.
|
|
|
|
*/
|
2007-11-11 20:52:56 +00:00
|
|
|
#ifdef FPE_CHECK
|
2003-03-11 16:56:45 +00:00
|
|
|
#define fluid_check_fpe(expl) fluid_check_fpe_i386(expl)
|
2007-11-11 20:52:56 +00:00
|
|
|
#define fluid_clear_fpe() fluid_clear_fpe_i386()
|
2003-03-11 16:56:45 +00:00
|
|
|
#else
|
|
|
|
#define fluid_check_fpe(expl)
|
2007-11-11 20:52:56 +00:00
|
|
|
#define fluid_clear_fpe()
|
2003-03-11 16:56:45 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
unsigned int fluid_check_fpe_i386(char * explanation_in_case_of_fpe);
|
2007-11-11 20:52:56 +00:00
|
|
|
void fluid_clear_fpe_i386(void);
|
2003-03-11 16:56:45 +00:00
|
|
|
|
|
|
|
#endif /* _FLUID_SYS_H */
|