1/* FluidSynth - A Software Synthesizer 2 * 3 * Copyright (C) 2003 Peter Hanappe and others. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public License 7 * as published by the Free Software Foundation; either version 2 of 8 * the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public 16 * License along with this library; if not, write to the Free 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 * 02111-1307, USA 19 */ 20 21 22/** 23 24 This header contains a bunch of (mostly) system and machine 25 dependent functions: 26 27 - timers 28 - current time in milliseconds and microseconds 29 - debug logging 30 - profiling 31 - memory locking 32 - checking for floating point exceptions 33 34 */ 35 36#ifndef _FLUID_SYS_H 37#define _FLUID_SYS_H 38 39#include "fluidsynth_priv.h" 40 41 42void fluid_sys_config(void); 43void fluid_log_config(void); 44void fluid_time_config(void); 45 46 47/* 48 * Utility functions 49 */ 50char *fluid_strtok (char **str, char *delim); 51 52 53/** 54 55 Additional debugging system, separate from the log system. This 56 allows to print selected debug messages of a specific subsystem. 57 58 */ 59 60extern unsigned int fluid_debug_flags; 61 62#if DEBUG 63 64enum fluid_debug_level { 65 FLUID_DBG_DRIVER = 1 66}; 67 68int fluid_debug(int level, char * fmt, ...); 69 70#else 71#define fluid_debug 72#endif 73 74 75/** fluid_curtime() returns the current time in milliseconds. This time 76 should only be used in relative time measurements. */ 77 78/** fluid_utime() returns the time in micro seconds. this time should 79 only be used to measure duration (relative times). */ 80 81#if defined(WIN32) 82#define fluid_curtime() GetTickCount() 83 84double fluid_utime(void); 85 86#elif defined(MACOS9) 87#include <OSUtils.h> 88#include <Timer.h> 89 90unsigned int fluid_curtime(); 91#define fluid_utime() 0.0 92 93#elif defined(__OS2__) 94#define INCL_DOS 95#include <os2.h> 96 97typedef int socklen_t; 98 99unsigned int fluid_curtime(void); 100double fluid_utime(void); 101 102#elif (defined(__BEOS__) || defined(__HAIKU__)) 103 104#include <OS.h> 105unsigned int fluid_curtime(void); 106double fluid_utime(void); 107 108#else 109 110unsigned int fluid_curtime(void); 111double fluid_utime(void); 112 113#endif 114 115 116 117/** 118 Timers 119 120 */ 121 122/* if the callback function returns 1 the timer will continue; if it 123 returns 0 it will stop */ 124typedef int (*fluid_timer_callback_t)(void* data, unsigned int msec); 125 126typedef struct _fluid_timer_t fluid_timer_t; 127 128fluid_timer_t* new_fluid_timer(int msec, fluid_timer_callback_t callback, 129 void* data, int new_thread, int auto_destroy); 130 131int delete_fluid_timer(fluid_timer_t* timer); 132int fluid_timer_join(fluid_timer_t* timer); 133int fluid_timer_stop(fluid_timer_t* timer); 134 135/** 136 137 Muteces 138 139*/ 140 141#if defined(MACOS9) 142typedef int fluid_mutex_t; 143#define fluid_mutex_init(_m) { (_m) = 0; } 144#define fluid_mutex_destroy(_m) 145#define fluid_mutex_lock(_m) 146#define fluid_mutex_unlock(_m) 147 148#elif defined(WIN32) 149typedef HANDLE fluid_mutex_t; 150#define fluid_mutex_init(_m) { (_m) = CreateMutex(NULL, 0, NULL); } 151#define fluid_mutex_destroy(_m) if (_m) { CloseHandle(_m); } 152#define fluid_mutex_lock(_m) WaitForSingleObject(_m, INFINITE) 153#define fluid_mutex_unlock(_m) ReleaseMutex(_m) 154 155#elif defined(__OS2__) 156typedef HMTX fluid_mutex_t; 157#define fluid_mutex_init(_m) { (_m) = 0; DosCreateMutexSem( NULL, &(_m), 0, FALSE ); } 158#define fluid_mutex_destroy(_m) if (_m) { DosCloseMutexSem(_m); } 159#define fluid_mutex_lock(_m) DosRequestMutexSem(_m, -1L) 160#define fluid_mutex_unlock(_m) DosReleaseMutexSem(_m) 161 162#else 163typedef pthread_mutex_t fluid_mutex_t; 164#define fluid_mutex_init(_m) pthread_mutex_init(&(_m), NULL) 165#define fluid_mutex_destroy(_m) pthread_mutex_destroy(&(_m)) 166#define fluid_mutex_lock(_m) pthread_mutex_lock(&(_m)) 167#define fluid_mutex_unlock(_m) pthread_mutex_unlock(&(_m)) 168#endif 169 170 171/** 172 Threads 173 174*/ 175 176typedef struct _fluid_thread_t fluid_thread_t; 177typedef void (*fluid_thread_func_t)(void* data); 178 179/** When detached, 'join' does not work and the thread destroys itself 180 when finished. */ 181fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach); 182int delete_fluid_thread(fluid_thread_t* thread); 183int fluid_thread_join(fluid_thread_t* thread); 184 185 186/** 187 Sockets 188 189*/ 190 191 192/** The function should return 0 if no error occured, non-zero 193 otherwise. If the function return non-zero, the socket will be 194 closed by the server. */ 195typedef int (*fluid_server_func_t)(void* data, fluid_socket_t client_socket, char* addr); 196 197 198fluid_server_socket_t* new_fluid_server_socket(int port, fluid_server_func_t func, void* data); 199int delete_fluid_server_socket(fluid_server_socket_t* sock); 200int fluid_server_socket_join(fluid_server_socket_t* sock); 201 202 203/** Create a new client socket. */ 204fluid_socket_t new_fluid_client_socket(char* host, int port); 205 206/** Delete the client socket. This function should only be called on 207 sockets create with 'new_fluid_client_socket'. */ 208void delete_fluid_client_socket(fluid_socket_t sock); 209 210 211void fluid_socket_close(fluid_socket_t sock); 212fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock); 213fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock); 214 215 216 217/** 218 219 Profiling 220 */ 221 222 223/** 224 Profile numbers. List all the pieces of code you want to profile 225 here. Be sure to add an entry in the fluid_profile_data table in 226 fluid_sys.c 227*/ 228enum { 229 FLUID_PROF_WRITE_S16, 230 FLUID_PROF_ONE_BLOCK, 231 FLUID_PROF_ONE_BLOCK_CLEAR, 232 FLUID_PROF_ONE_BLOCK_VOICE, 233 FLUID_PROF_ONE_BLOCK_VOICES, 234 FLUID_PROF_ONE_BLOCK_REVERB, 235 FLUID_PROF_ONE_BLOCK_CHORUS, 236 FLUID_PROF_VOICE_NOTE, 237 FLUID_PROF_VOICE_RELEASE, 238 FLUID_PROF_LAST 239}; 240 241 242#if WITH_PROFILING 243 244void fluid_profiling_print(void); 245 246 247/** Profiling data. Keep track of min/avg/max values to execute a 248 piece of code. */ 249typedef struct _fluid_profile_data_t { 250 int num; 251 char* description; 252 double min, max, total; 253 unsigned int count; 254} fluid_profile_data_t; 255 256extern fluid_profile_data_t fluid_profile_data[]; 257 258/** Macro to obtain a time refence used for the profiling */ 259#define fluid_profile_ref() fluid_utime() 260 261/** Macro to calculate the min/avg/max. Needs a time refence and a 262 profile number. */ 263#define fluid_profile(_num,_ref) { \ 264 double _now = fluid_utime(); \ 265 double _delta = _now - _ref; \ 266 fluid_profile_data[_num].min = _delta < fluid_profile_data[_num].min ? _delta : fluid_profile_data[_num].min; \ 267 fluid_profile_data[_num].max = _delta > fluid_profile_data[_num].max ? _delta : fluid_profile_data[_num].max; \ 268 fluid_profile_data[_num].total += _delta; \ 269 fluid_profile_data[_num].count++; \ 270 _ref = _now; \ 271} 272 273 274#else 275 276/* No profiling */ 277#define fluid_profiling_print() 278#define fluid_profile_ref() 0 279#define fluid_profile(_num,_ref) 280 281#endif 282 283 284 285/** 286 287 Memory locking 288 289 Memory locking is used to avoid swapping of the large block of 290 sample data. 291 */ 292 293#if defined(HAVE_SYS_MMAN_H) && !defined(__OS2__) 294#define fluid_mlock(_p,_n) mlock(_p, _n) 295#define fluid_munlock(_p,_n) munlock(_p,_n) 296#else 297#define fluid_mlock(_p,_n) 0 298#define fluid_munlock(_p,_n) 299#endif 300 301 302/** 303 304 Floating point exceptions 305 306 fluid_check_fpe() checks for "unnormalized numbers" and other 307 exceptions of the floating point processsor. 308*/ 309#ifdef FPE_CHECK 310#define fluid_check_fpe(expl) fluid_check_fpe_i386(expl) 311#define fluid_clear_fpe() fluid_clear_fpe_i386() 312#else 313#define fluid_check_fpe(expl) 314#define fluid_clear_fpe() 315#endif 316 317unsigned int fluid_check_fpe_i386(char * explanation_in_case_of_fpe); 318void fluid_clear_fpe_i386(void); 319 320#endif /* _FLUID_SYS_H */ 321