00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "fluid_sys.h"
00023
00024 static char fluid_errbuf[512];
00025
00026 static fluid_log_function_t fluid_log_function[LAST_LOG_LEVEL];
00027 static void* fluid_log_user_data[LAST_LOG_LEVEL];
00028 static int fluid_log_initialized = 0;
00029
00030 static char* fluid_libname = "fluidsynth";
00031
00032
00033 void fluid_sys_config()
00034 {
00035 fluid_log_config();
00036 fluid_time_config();
00037 }
00038
00039
00040 unsigned int fluid_debug_flags = 0;
00041
00042 #if DEBUG
00043
00044
00045
00046 int fluid_debug(int level, char * fmt, ...)
00047 {
00048 if (fluid_debug_flags & level) {
00049 fluid_log_function_t fun;
00050 va_list args;
00051
00052 va_start (args, fmt);
00053 vsnprintf(fluid_errbuf, sizeof (fluid_errbuf), fmt, args);
00054 va_end (args);
00055
00056 fun = fluid_log_function[FLUID_DBG];
00057 if (fun != NULL) {
00058 (*fun)(level, fluid_errbuf, fluid_log_user_data[FLUID_DBG]);
00059 }
00060 }
00061 return 0;
00062 }
00063 #endif
00064
00072 fluid_log_function_t
00073 fluid_set_log_function(int level, fluid_log_function_t fun, void* data)
00074 {
00075 fluid_log_function_t old = NULL;
00076
00077 if ((level >= 0) && (level < LAST_LOG_LEVEL)) {
00078 old = fluid_log_function[level];
00079 fluid_log_function[level] = fun;
00080 fluid_log_user_data[level] = data;
00081 }
00082 return old;
00083 }
00084
00091 void
00092 fluid_default_log_function(int level, char* message, void* data)
00093 {
00094 FILE* out;
00095
00096 #if defined(WIN32)
00097 out = stdout;
00098 #else
00099 out = stderr;
00100 #endif
00101
00102 if (fluid_log_initialized == 0) {
00103 fluid_log_config();
00104 }
00105
00106 switch (level) {
00107 case FLUID_PANIC:
00108 FLUID_FPRINTF(out, "%s: panic: %s\n", fluid_libname, message);
00109 break;
00110 case FLUID_ERR:
00111 FLUID_FPRINTF(out, "%s: error: %s\n", fluid_libname, message);
00112 break;
00113 case FLUID_WARN:
00114 FLUID_FPRINTF(out, "%s: warning: %s\n", fluid_libname, message);
00115 break;
00116 case FLUID_INFO:
00117 FLUID_FPRINTF(out, "%s: %s\n", fluid_libname, message);
00118 break;
00119 case FLUID_DBG:
00120 #if DEBUG
00121 FLUID_FPRINTF(out, "%s: debug: %s\n", fluid_libname, message);
00122 #endif
00123 break;
00124 default:
00125 FLUID_FPRINTF(out, "%s: %s\n", fluid_libname, message);
00126 break;
00127 }
00128 fflush(out);
00129 }
00130
00131
00132
00133
00134 void
00135 fluid_log_config(void)
00136 {
00137 if (fluid_log_initialized == 0) {
00138
00139 fluid_log_initialized = 1;
00140
00141 if (fluid_log_function[FLUID_PANIC] == NULL) {
00142 fluid_set_log_function(FLUID_PANIC, fluid_default_log_function, NULL);
00143 }
00144
00145 if (fluid_log_function[FLUID_ERR] == NULL) {
00146 fluid_set_log_function(FLUID_ERR, fluid_default_log_function, NULL);
00147 }
00148
00149 if (fluid_log_function[FLUID_WARN] == NULL) {
00150 fluid_set_log_function(FLUID_WARN, fluid_default_log_function, NULL);
00151 }
00152
00153 if (fluid_log_function[FLUID_INFO] == NULL) {
00154 fluid_set_log_function(FLUID_INFO, fluid_default_log_function, NULL);
00155 }
00156
00157 if (fluid_log_function[FLUID_DBG] == NULL) {
00158 fluid_set_log_function(FLUID_DBG, fluid_default_log_function, NULL);
00159 }
00160 }
00161 }
00162
00170 int
00171 fluid_log(int level, char* fmt, ...)
00172 {
00173 fluid_log_function_t fun = NULL;
00174
00175 va_list args;
00176 va_start (args, fmt);
00177 vsnprintf(fluid_errbuf, sizeof (fluid_errbuf), fmt, args);
00178 va_end (args);
00179
00180 if ((level >= 0) && (level < LAST_LOG_LEVEL)) {
00181 fun = fluid_log_function[level];
00182 if (fun != NULL) {
00183 (*fun)(level, fluid_errbuf, fluid_log_user_data[level]);
00184 }
00185 }
00186 return FLUID_FAILED;
00187 }
00188
00202 char *fluid_strtok (char **str, char *delim)
00203 {
00204 char *s, *d, *token;
00205 char c;
00206
00207 if (str == NULL || delim == NULL || !*delim)
00208 {
00209 FLUID_LOG(FLUID_ERR, "Null pointer");
00210 return NULL;
00211 }
00212
00213 s = *str;
00214 if (!s) return NULL;
00215
00216
00217 do
00218 {
00219 c = *s;
00220 if (!c)
00221 {
00222 *str = NULL;
00223 return NULL;
00224 }
00225
00226 for (d = delim; *d; d++)
00227 {
00228 if (c == *d)
00229 {
00230 s++;
00231 break;
00232 }
00233 }
00234 } while (*d);
00235
00236 token = s;
00237
00238
00239 for (s = s+1; *s; s++)
00240 {
00241 c = *s;
00242
00243 for (d = delim; *d; d++)
00244 {
00245 if (c == *d)
00246 {
00247 *s = '\0';
00248 *str = s+1;
00249 return token;
00250 }
00251 }
00252 }
00253
00254
00255 *str = NULL;
00256 return token;
00257 }
00258
00259
00260
00261
00262 char*
00263 fluid_error()
00264 {
00265 return fluid_errbuf;
00266 }
00267
00268
00269
00270
00271
00272
00273 int
00274 fluid_is_midifile(char* filename)
00275 {
00276 FILE* fp = fopen(filename, "rb");
00277 char id[4];
00278
00279 if (fp == NULL) {
00280 return 0;
00281 }
00282 if (fread((void*) id, 1, 4, fp) != 4) {
00283 fclose(fp);
00284 return 0;
00285 }
00286 fclose(fp);
00287
00288 return strncmp(id, "MThd", 4) == 0;
00289 }
00290
00291
00292
00293
00294
00295 int
00296 fluid_is_soundfont(char* filename)
00297 {
00298 FILE* fp = fopen(filename, "rb");
00299 char id[4];
00300
00301 if (fp == NULL) {
00302 return 0;
00303 }
00304 if (fread((void*) id, 1, 4, fp) != 4) {
00305 fclose(fp);
00306 return 0;
00307 }
00308 fclose(fp);
00309
00310 return strncmp(id, "RIFF", 4) == 0;
00311 }
00312
00313 #if defined(WIN32)
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 struct _fluid_timer_t
00328 {
00329 long msec;
00330 fluid_timer_callback_t callback;
00331 void* data;
00332 HANDLE thread;
00333 DWORD thread_id;
00334 int cont;
00335 int auto_destroy;
00336 };
00337
00338 static int fluid_timer_count = 0;
00339 DWORD WINAPI fluid_timer_run(LPVOID data);
00340
00341 fluid_timer_t*
00342 new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data,
00343 int new_thread, int auto_destroy)
00344 {
00345 fluid_timer_t* timer = FLUID_NEW(fluid_timer_t);
00346 if (timer == NULL) {
00347 FLUID_LOG(FLUID_ERR, "Out of memory");
00348 return NULL;
00349 }
00350
00351 timer->cont = 1;
00352 timer->msec = msec;
00353 timer->callback = callback;
00354 timer->data = data;
00355 timer->thread = 0;
00356 timer->auto_destroy = auto_destroy;
00357
00358 if (new_thread) {
00359 timer->thread = CreateThread(NULL, 0, fluid_timer_run, (LPVOID) timer, 0, &timer->thread_id);
00360 if (timer->thread == NULL) {
00361 FLUID_LOG(FLUID_ERR, "Couldn't create timer thread");
00362 FLUID_FREE(timer);
00363 return NULL;
00364 }
00365 SetThreadPriority(timer->thread, THREAD_PRIORITY_TIME_CRITICAL);
00366 } else {
00367 fluid_timer_run((LPVOID) timer);
00368 }
00369 return timer;
00370 }
00371
00372 DWORD WINAPI
00373 fluid_timer_run(LPVOID data)
00374 {
00375 int count = 0;
00376 int cont = 1;
00377 long start;
00378 long delay;
00379 fluid_timer_t* timer;
00380 timer = (fluid_timer_t*) data;
00381
00382 if ((timer == NULL) || (timer->callback == NULL)) {
00383 return 0;
00384 }
00385
00386 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
00387
00388
00389 start = fluid_curtime();
00390
00391 while (cont) {
00392
00393
00394 cont = (*timer->callback)(timer->data, fluid_curtime() - start);
00395
00396 count++;
00397
00398
00399
00400
00401 delay = (count * timer->msec) - (fluid_curtime() - start);
00402 if (delay > 0) {
00403 Sleep(delay);
00404 }
00405
00406 cont &= timer->cont;
00407 }
00408
00409 FLUID_LOG(FLUID_DBG, "Timer thread finished");
00410
00411 if (timer->auto_destroy) {
00412 FLUID_FREE(timer);
00413 }
00414
00415 ExitThread(0);
00416 return 0;
00417 }
00418
00419 int
00420 delete_fluid_timer(fluid_timer_t* timer)
00421 {
00422 timer->cont = 0;
00423 fluid_timer_join(timer);
00424 FLUID_FREE(timer);
00425 return FLUID_OK;
00426 }
00427
00428 int
00429 fluid_timer_join(fluid_timer_t* timer)
00430 {
00431 DWORD wait_result;
00432 if (timer->thread == 0) {
00433 return FLUID_OK;
00434 }
00435 wait_result = WaitForSingleObject(timer->thread, INFINITE);
00436 return (wait_result == WAIT_OBJECT_0)? FLUID_OK : FLUID_FAILED;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445 double rdtsc(void);
00446 double fluid_estimate_cpu_frequency(void);
00447
00448 static double fluid_cpu_frequency = -1.0;
00449
00450 void fluid_time_config(void)
00451 {
00452 if (fluid_cpu_frequency < 0.0) {
00453 fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0;
00454 }
00455 }
00456
00457 double fluid_utime(void)
00458 {
00459 return (rdtsc() / fluid_cpu_frequency);
00460 }
00461
00462 double rdtsc(void)
00463 {
00464 LARGE_INTEGER t;
00465 QueryPerformanceCounter(&t);
00466 return (double) t.QuadPart;
00467 }
00468
00469 double fluid_estimate_cpu_frequency(void)
00470 {
00471 #if 0
00472 LONGLONG start, stop, ticks;
00473 unsigned int before, after, delta;
00474 double freq;
00475
00476 start = rdtsc();
00477 stop = start;
00478 before = fluid_curtime();
00479 after = before;
00480
00481 while (1) {
00482 if (after - before > 1000) {
00483 break;
00484 }
00485 after = fluid_curtime();
00486 stop = rdtsc();
00487 }
00488
00489 delta = after - before;
00490 ticks = stop - start;
00491
00492 freq = 1000 * ticks / delta;
00493
00494 return freq;
00495
00496 #else
00497 unsigned int before, after;
00498 LARGE_INTEGER start, stop;
00499
00500 before = fluid_curtime();
00501 QueryPerformanceCounter(&start);
00502
00503 Sleep(1000);
00504
00505 after = fluid_curtime();
00506 QueryPerformanceCounter(&stop);
00507
00508 return (double) 1000 * (stop.QuadPart - start.QuadPart) / (after - before);
00509 #endif
00510 }
00511
00512
00513
00514 #elif defined(MACOS9)
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 struct _fluid_timer_t
00528 {
00529 TMTask myTmTask;
00530 long msec;
00531 unsigned int start;
00532 unsigned int count;
00533 int isInstalled;
00534 fluid_timer_callback_t callback;
00535 void* data;
00536 int auto_destroy;
00537 };
00538
00539 static TimerUPP myTimerUPP;
00540
00541 void
00542 _timerCallback(fluid_timer_t *timer)
00543 {
00544 int cont;
00545 cont = (*timer->callback)(timer->data, fluid_curtime() - timer->start);
00546 if (cont) {
00547 PrimeTime((QElemPtr)timer, timer->msec);
00548 } else {
00549 timer->isInstalled = 0;
00550 }
00551 timer->count++;
00552 }
00553
00554 fluid_timer_t*
00555 new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data,
00556 int new_thread, int auto_destroy)
00557 {
00558 fluid_timer_t* timer = FLUID_NEW(fluid_timer_t);
00559 if (timer == NULL) {
00560 FLUID_LOG(FLUID_ERR, "Out of memory");
00561 return NULL;
00562 }
00563
00564 if (!myTimerUPP)
00565 myTimerUPP = NewTimerProc(_timerCallback);
00566
00567
00568 timer->myTmTask.tmAddr = myTimerUPP;
00569 timer->myTmTask.qLink = NULL;
00570 timer->myTmTask.qType = 0;
00571 timer->myTmTask.tmCount = 0L;
00572 timer->myTmTask.tmWakeUp = 0L;
00573 timer->myTmTask.tmReserved = 0L;
00574
00575 timer->callback = callback;
00576
00577 timer->msec = msec;
00578 timer->data = data;
00579 timer->start = fluid_curtime();
00580 timer->isInstalled = 1;
00581 timer->count = 0;
00582 timer->auto_destroy = auto_destroy;
00583
00584 InsXTime((QElemPtr)timer);
00585 PrimeTime((QElemPtr)timer, msec);
00586
00587 return timer;
00588 }
00589
00590 int
00591 delete_fluid_timer(fluid_timer_t* timer)
00592 {
00593 if (timer->isInstalled) {
00594 RmvTime((QElemPtr)timer);
00595 }
00596 FLUID_FREE(timer);
00597 return FLUID_OK;
00598 }
00599
00600 int
00601 fluid_timer_join(fluid_timer_t* timer)
00602 {
00603 if (timer->isInstalled) {
00604 int count = timer->count;
00605
00606 while (count == timer->count) {}
00607 }
00608 return FLUID_OK;
00609 }
00610
00611
00612
00613
00614
00615 #define kTwoPower32 (4294967296.0)
00616
00617 void fluid_time_config(void)
00618 {
00619 }
00620
00621 unsigned int fluid_curtime()
00622 {
00623
00624 UnsignedWide uS;
00625 double mSf;
00626 unsigned int ms;
00627
00628 Microseconds(&uS);
00629
00630 mSf = ((((double) uS.hi) * kTwoPower32) + uS.lo)/1000.0f;
00631
00632 ms = mSf;
00633
00634 return (ms);
00635 }
00636
00637
00638
00639 #elif defined(__OS2__)
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 struct _fluid_timer_t
00653 {
00654 long msec;
00655 fluid_timer_callback_t callback;
00656 void* data;
00657 int thread_id;
00658 int cont;
00659 int auto_destroy;
00660 };
00661
00662 static int fluid_timer_count = 0;
00663 void fluid_timer_run(void *data);
00664
00665 fluid_timer_t*
00666 new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data,
00667 int new_thread, int auto_destroy)
00668 {
00669 fluid_timer_t* timer = FLUID_NEW(fluid_timer_t);
00670 if (timer == NULL) {
00671 FLUID_LOG(FLUID_ERR, "Out of memory");
00672 return NULL;
00673 }
00674
00675 timer->cont = 1;
00676 timer->msec = msec;
00677 timer->callback = callback;
00678 timer->data = data;
00679 timer->thread_id =-1;
00680 timer->auto_destroy = auto_destroy;
00681
00682 if (new_thread) {
00683 timer->thread_id = _beginthread( fluid_timer_run, NULL, 256 * 1024, ( void * )timer );
00684 if (timer->thread_id == -1) {
00685 FLUID_LOG(FLUID_ERR, "Couldn't create timer thread");
00686 FLUID_FREE(timer);
00687 return NULL;
00688 }
00689 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, timer->thread_id);
00690 } else {
00691 fluid_timer_run(( void * )timer);
00692 }
00693 return timer;
00694 }
00695
00696 void
00697 fluid_timer_run(void *data)
00698 {
00699 int count = 0;
00700 int cont = 1;
00701 long start;
00702 long delay;
00703 fluid_timer_t* timer;
00704 timer = (fluid_timer_t*) data;
00705
00706 if ((timer == NULL) || (timer->callback == NULL)) {
00707 return;
00708 }
00709
00710 DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, 0 );
00711
00712
00713 start = fluid_curtime();
00714
00715 while (cont) {
00716
00717
00718 cont = (*timer->callback)(timer->data, fluid_curtime() - start);
00719
00720 count++;
00721
00722
00723
00724
00725 delay = (count * timer->msec) - (fluid_curtime() - start);
00726 if (delay > 0) {
00727 DosSleep(delay);
00728 }
00729
00730 cont &= timer->cont;
00731 }
00732
00733 FLUID_LOG(FLUID_DBG, "Timer thread finished");
00734
00735 if (timer->auto_destroy) {
00736 FLUID_FREE(timer);
00737 }
00738
00739 return;
00740 }
00741
00742 int
00743 delete_fluid_timer(fluid_timer_t* timer)
00744 {
00745 timer->cont = 0;
00746 fluid_timer_join(timer);
00747 FLUID_FREE(timer);
00748 return FLUID_OK;
00749 }
00750
00751 int
00752 fluid_timer_join(fluid_timer_t* timer)
00753 {
00754 ULONG wait_result;
00755 if (timer->thread_id == -1) {
00756 return FLUID_OK;
00757 }
00758 wait_result = DosWaitThread(&timer->thread_id, DCWW_WAIT);
00759 return (wait_result == 0)? FLUID_OK : FLUID_FAILED;
00760 }
00761
00762
00763
00764
00765
00766
00767
00768 double rdtsc(void);
00769 double fluid_estimate_cpu_frequency(void);
00770
00771 static double fluid_cpu_frequency = -1.0;
00772
00773 void fluid_time_config(void)
00774 {
00775 if (fluid_cpu_frequency < 0.0) {
00776 fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0;
00777 }
00778 }
00779
00780 unsigned int fluid_curtime(void)
00781 {
00782 ULONG ulMS;
00783 DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &ulMS, sizeof( ULONG ));
00784 return ulMS;
00785 }
00786
00787 double fluid_utime(void)
00788 {
00789 return (rdtsc() / fluid_cpu_frequency);
00790 }
00791
00792 #define Q2ULL( q ) (*(unsigned long long *)&q)
00793
00794 double rdtsc(void)
00795 {
00796 QWORD t;
00797 DosTmrQueryTime(&t);
00798 return (double)Q2ULL(t);
00799 }
00800
00801 double fluid_estimate_cpu_frequency(void)
00802 {
00803 unsigned int before, after;
00804 QWORD start, stop;
00805
00806 before = fluid_curtime();
00807 DosTmrQueryTime(&start);
00808
00809 DosSleep(1000);
00810
00811 after = fluid_curtime();
00812 DosTmrQueryTime(&stop);
00813
00814 return (double) 1000 * (Q2ULL(stop) - Q2ULL(start)) / (after - before);
00815 }
00816
00817
00818
00819 #else
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 struct _fluid_timer_t
00834 {
00835 long msec;
00836 fluid_timer_callback_t callback;
00837 void* data;
00838 pthread_t thread;
00839 int cont;
00840 int auto_destroy;
00841 };
00842
00843 void*
00844 fluid_timer_start(void *data)
00845 {
00846 int count = 0;
00847 int cont = 1;
00848 long start;
00849 long delay;
00850 fluid_timer_t* timer;
00851 timer = (fluid_timer_t*) data;
00852
00853
00854 start = fluid_curtime();
00855
00856 while (cont) {
00857
00858
00859 cont = (*timer->callback)(timer->data, fluid_curtime() - start);
00860
00861 count++;
00862
00863
00864
00865
00866 delay = (count * timer->msec) - (fluid_curtime() - start);
00867 if (delay > 0) {
00868 usleep(delay * 1000);
00869 }
00870
00871 cont &= timer->cont;
00872 }
00873
00874 FLUID_LOG(FLUID_DBG, "Timer thread finished");
00875 if (timer->thread != 0) {
00876 pthread_exit(NULL);
00877 }
00878
00879 if (timer->auto_destroy) {
00880 FLUID_FREE(timer);
00881 }
00882
00883 return NULL;
00884 }
00885
00886 fluid_timer_t*
00887 new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data,
00888 int new_thread, int auto_destroy)
00889 {
00890 pthread_attr_t *attr = NULL;
00891 pthread_attr_t rt_attr;
00892 int sched = SCHED_FIFO;
00893 struct sched_param priority;
00894 int err;
00895
00896 fluid_timer_t* timer = FLUID_NEW(fluid_timer_t);
00897 if (timer == NULL) {
00898 FLUID_LOG(FLUID_ERR, "Out of memory");
00899 return NULL;
00900 }
00901 timer->msec = msec;
00902 timer->callback = callback;
00903 timer->data = data;
00904 timer->cont = 1;
00905 timer->thread = 0;
00906 timer->auto_destroy = auto_destroy;
00907
00908 err = pthread_attr_init(&rt_attr);
00909 if (err == 0) {
00910 err = pthread_attr_setschedpolicy(&rt_attr, SCHED_FIFO);
00911 if (err == 0) {
00912 priority.sched_priority = 10;
00913 err = pthread_attr_setschedparam(&rt_attr, &priority);
00914 if (err == 0) {
00915 attr = &rt_attr;
00916 }
00917 }
00918 }
00919
00920 if (new_thread) {
00921 err = pthread_create(&timer->thread, attr, fluid_timer_start, (void*) timer);
00922 if (err == 0) {
00923 FLUID_LOG(FLUID_DBG, "The timer thread was created with real-time priority");
00924 } else {
00925
00926 err = pthread_create(&timer->thread, NULL, fluid_timer_start, (void*) timer);
00927 if (err != 0) {
00928 FLUID_LOG(FLUID_ERR, "Failed to create the timer thread");
00929 FLUID_FREE(timer);
00930 return NULL;
00931 } else {
00932 FLUID_LOG(FLUID_DBG, "The timer thread does not have real-time priority");
00933 }
00934 }
00935 } else {
00936 fluid_timer_start((void*) timer);
00937 }
00938 return timer;
00939 }
00940
00941 int
00942 delete_fluid_timer(fluid_timer_t* timer)
00943 {
00944 timer->cont = 0;
00945 fluid_timer_join(timer);
00946 FLUID_LOG(FLUID_DBG, "Joined player thread");
00947 FLUID_FREE(timer);
00948 return FLUID_OK;
00949 }
00950
00951 int
00952 fluid_timer_join(fluid_timer_t* timer)
00953 {
00954 int err = 0;
00955
00956 if (timer->thread != 0) {
00957 err = pthread_join(timer->thread, NULL);
00958 }
00959 FLUID_LOG(FLUID_DBG, "Joined player thread");
00960 return (err == 0)? FLUID_OK : FLUID_FAILED;
00961 }
00962
00963
00964
00965
00966
00967
00968
00969 static double fluid_cpu_frequency = -1.0;
00970
00971 double rdtsc(void);
00972 double fluid_estimate_cpu_frequency(void);
00973
00974 void fluid_time_config(void)
00975 {
00976 if (fluid_cpu_frequency < 0.0) {
00977 fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0;
00978 if (fluid_cpu_frequency == 0.0) fluid_cpu_frequency = 1.0;
00979 }
00980 }
00981
00982 unsigned int fluid_curtime()
00983 {
00984 struct timeval now;
00985 gettimeofday(&now, NULL);
00986 return now.tv_sec * 1000 + now.tv_usec / 1000;
00987 }
00988
00989 double fluid_utime(void)
00990 {
00991 return (rdtsc() / fluid_cpu_frequency);
00992 }
00993
00994 #if !defined(__i386__)
00995
00996 double rdtsc(void)
00997 {
00998 return 0.0;
00999 }
01000
01001 double fluid_estimate_cpu_frequency(void)
01002 {
01003 return 1.0;
01004 }
01005
01006 #else
01007
01008 double rdtsc(void)
01009 {
01010 unsigned int a, b;
01011
01012 __asm__ ("rdtsc" : "=a" (a), "=d" (b));
01013 return (double)b * (double)0x10000 * (double)0x10000 + a;
01014 }
01015
01016 double fluid_estimate_cpu_frequency(void)
01017 {
01018 double start, stop;
01019 unsigned int a0, b0, a1, b1;
01020 unsigned int before, after;
01021
01022 before = fluid_curtime();
01023 __asm__ ("rdtsc" : "=a" (a0), "=d" (b0));
01024
01025 sleep(1);
01026
01027 after = fluid_curtime();
01028 __asm__ ("rdtsc" : "=a" (a1), "=d" (b1));
01029
01030
01031 start = (double)b0 * (double)0x10000 * (double)0x10000 + a0;
01032 stop = (double)b1 * (double)0x10000 * (double)0x10000 + a1;
01033
01034 return 1000 * (stop - start) / (after - before);
01035 }
01036 #endif
01037
01038
01039 #ifdef FPE_CHECK
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 #define _FPU_STATUS_IE 0x001
01056 #define _FPU_STATUS_DE 0x002
01057 #define _FPU_STATUS_ZE 0x004
01058 #define _FPU_STATUS_OE 0x008
01059 #define _FPU_STATUS_UE 0x010
01060 #define _FPU_STATUS_PE 0x020
01061 #define _FPU_STATUS_SF 0x040
01062 #define _FPU_STATUS_ES 0x080
01063
01064
01065
01066
01067 #define _FPU_GET_SW(sw) __asm__ ("fnstsw %0" : "=m" (*&sw))
01068
01069
01070 #define _FPU_CLR_SW() __asm__ ("fnclex" : : )
01071
01072
01073
01074
01075
01076 unsigned int fluid_check_fpe_i386(char* explanation)
01077 {
01078 unsigned int s;
01079
01080 _FPU_GET_SW(s);
01081 _FPU_CLR_SW();
01082
01083 s &= _FPU_STATUS_IE | _FPU_STATUS_DE | _FPU_STATUS_ZE | _FPU_STATUS_OE | _FPU_STATUS_UE;
01084
01085 if (s)
01086 {
01087 FLUID_LOG(FLUID_WARN, "FPE exception (before or in %s): %s%s%s%s%s", explanation,
01088 (s & _FPU_STATUS_IE) ? "Invalid operation " : "",
01089 (s & _FPU_STATUS_DE) ? "Denormal number " : "",
01090 (s & _FPU_STATUS_ZE) ? "Zero divide " : "",
01091 (s & _FPU_STATUS_OE) ? "Overflow " : "",
01092 (s & _FPU_STATUS_UE) ? "Underflow " : "");
01093 }
01094
01095 return s;
01096 }
01097
01098
01099
01100
01101 void fluid_clear_fpe_i386 (void)
01102 {
01103 _FPU_CLR_SW();
01104 }
01105
01106 #endif // ifdef FPE_CHECK
01107
01108
01109 #endif // #else (its POSIX)
01110
01111
01112
01113
01114
01115
01116
01117
01118 #if WITH_PROFILING
01119
01120 fluid_profile_data_t fluid_profile_data[] =
01121 {
01122 { FLUID_PROF_WRITE_S16, "fluid_synth_write_s16 ", 1e10, 0.0, 0.0, 0},
01123 { FLUID_PROF_ONE_BLOCK, "fluid_synth_one_block ", 1e10, 0.0, 0.0, 0},
01124 { FLUID_PROF_ONE_BLOCK_CLEAR, "fluid_synth_one_block:clear ", 1e10, 0.0, 0.0, 0},
01125 { FLUID_PROF_ONE_BLOCK_VOICE, "fluid_synth_one_block:one voice ", 1e10, 0.0, 0.0, 0},
01126 { FLUID_PROF_ONE_BLOCK_VOICES, "fluid_synth_one_block:all voices", 1e10, 0.0, 0.0, 0},
01127 { FLUID_PROF_ONE_BLOCK_REVERB, "fluid_synth_one_block:reverb ", 1e10, 0.0, 0.0, 0},
01128 { FLUID_PROF_ONE_BLOCK_CHORUS, "fluid_synth_one_block:chorus ", 1e10, 0.0, 0.0, 0},
01129 { FLUID_PROF_VOICE_NOTE, "fluid_voice:note ", 1e10, 0.0, 0.0, 0},
01130 { FLUID_PROF_VOICE_RELEASE, "fluid_voice:release ", 1e10, 0.0, 0.0, 0},
01131 { FLUID_PROF_LAST, "last", 1e100, 0.0, 0.0, 0}
01132 };
01133
01134
01135 void fluid_profiling_print(void)
01136 {
01137 int i;
01138
01139 printf("fluid_profiling_print\n");
01140
01141 FLUID_LOG(FLUID_INFO, "Estimated CPU frequency: %.0f MHz", fluid_cpu_frequency);
01142 FLUID_LOG(FLUID_INFO, "Estimated times: min/avg/max (micro seconds)");
01143
01144 for (i = 0; i < FLUID_PROF_LAST; i++) {
01145 if (fluid_profile_data[i].count > 0) {
01146 FLUID_LOG(FLUID_INFO, "%s: %.3f/%.3f/%.3f",
01147 fluid_profile_data[i].description,
01148 fluid_profile_data[i].min,
01149 fluid_profile_data[i].total / fluid_profile_data[i].count,
01150 fluid_profile_data[i].max);
01151 } else {
01152 FLUID_LOG(FLUID_DBG, "%s: no profiling available", fluid_profile_data[i].description);
01153 }
01154 }
01155 }
01156
01157
01158 #endif
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168 #if defined(MACOS9)
01169
01170 fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach) { return NULL; }
01171 int delete_fluid_thread(fluid_thread_t* thread) { return 0; }
01172 int fluid_thread_join(fluid_thread_t* thread) { return 0; }
01173
01174 #elif defined(WIN32)
01175
01176 struct _fluid_thread_t {
01177 HANDLE thread;
01178 DWORD thread_id;
01179 fluid_thread_func_t func;
01180 void* data;
01181 int detached;
01182 };
01183
01184 static DWORD WINAPI fluid_thread_start(LPVOID data)
01185 {
01186 fluid_thread_t* thread = (fluid_thread_t*) data;
01187
01188 thread->func(thread->data);
01189
01190 if (thread->detached) {
01191 FLUID_FREE(thread);
01192 }
01193
01194 return 0;
01195 }
01196
01197
01198 fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach)
01199 {
01200 fluid_thread_t* thread;
01201
01202 if (func == NULL) {
01203 FLUID_LOG(FLUID_ERR, "Invalid thread function");
01204 return NULL;
01205 }
01206
01207 thread = FLUID_NEW(fluid_thread_t);
01208 if (thread == NULL) {
01209 FLUID_LOG(FLUID_ERR, "Out of memory");
01210 return NULL;
01211 }
01212
01213 thread->data = data;
01214 thread->func = func;
01215 thread->detached = detach;
01216
01217 thread->thread = CreateThread(NULL, 0, fluid_thread_start, (LPVOID) thread,
01218 0, &thread->thread_id);
01219 if (thread->thread == NULL) {
01220 FLUID_LOG(FLUID_ERR, "Couldn't create the thread");
01221 FLUID_FREE(thread);
01222 return NULL;
01223 }
01224
01225 return thread;
01226 }
01227
01228 int delete_fluid_thread(fluid_thread_t* thread)
01229 {
01230 FLUID_FREE(thread);
01231 return FLUID_OK;
01232 }
01233
01234
01235 int fluid_thread_join(fluid_thread_t* thread)
01236 {
01237 DWORD wait_result;
01238 if (thread->thread == 0) {
01239 return FLUID_OK;
01240 }
01241 wait_result = WaitForSingleObject(thread->thread, INFINITE);
01242 return (wait_result == WAIT_OBJECT_0)? FLUID_OK : FLUID_FAILED;
01243 }
01244
01245 #elif defined(__OS2__)
01246
01247 struct _fluid_thread_t {
01248 int thread_id;
01249 fluid_thread_func_t func;
01250 void* data;
01251 int detached;
01252 };
01253
01254 static void fluid_thread_start(void *data)
01255 {
01256 fluid_thread_t* thread = (fluid_thread_t*) data;
01257
01258 thread->func(thread->data);
01259
01260 if (thread->detached) {
01261 FLUID_FREE(thread);
01262 }
01263
01264 return 0;
01265 }
01266
01267
01268 fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach)
01269 {
01270 fluid_thread_t* thread;
01271
01272 if (func == NULL) {
01273 FLUID_LOG(FLUID_ERR, "Invalid thread function");
01274 return NULL;
01275 }
01276
01277 thread = FLUID_NEW(fluid_thread_t);
01278 if (thread == NULL) {
01279 FLUID_LOG(FLUID_ERR, "Out of memory");
01280 return NULL;
01281 }
01282
01283 thread->data = data;
01284 thread->func = func;
01285 thread->detached = detach;
01286
01287 thread->thread_id = _beginthread(fluid_thread_start, NULL, 256 * 1024, (void *) thread);
01288 if (thread->thread_id == -1) {
01289 FLUID_LOG(FLUID_ERR, "Couldn't create the thread");
01290 FLUID_FREE(thread);
01291 return NULL;
01292 }
01293
01294 return thread;
01295 }
01296
01297 int delete_fluid_thread(fluid_thread_t* thread)
01298 {
01299 FLUID_FREE(thread);
01300 return FLUID_OK;
01301 }
01302
01303
01304 int fluid_thread_join(fluid_thread_t* thread)
01305 {
01306 ULONG wait_result;
01307 if (thread->thread_id == -1) {
01308 return FLUID_OK;
01309 }
01310 wait_result = DosWaitThread(&thread->thread_id, DCWW_WAIT);
01311 return (wait_result == 0)? FLUID_OK : FLUID_FAILED;
01312 }
01313
01314 #else
01315
01316
01317 struct _fluid_thread_t {
01318 pthread_t pthread;
01319 fluid_thread_func_t func;
01320 void* data;
01321 int detached;
01322 };
01323
01324 static void* fluid_thread_start(void *data)
01325 {
01326 fluid_thread_t* thread = (fluid_thread_t*) data;
01327
01328 thread->func(thread->data);
01329
01330 if (thread->detached) {
01331 FLUID_FREE(thread);
01332 }
01333
01334 return NULL;
01335 }
01336
01337 fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach)
01338 {
01339 fluid_thread_t* thread;
01340 pthread_attr_t attr;
01341
01342 if (func == NULL) {
01343 FLUID_LOG(FLUID_ERR, "Invalid thread function");
01344 return NULL;
01345 }
01346
01347 thread = FLUID_NEW(fluid_thread_t);
01348 if (thread == NULL) {
01349 FLUID_LOG(FLUID_ERR, "Out of memory");
01350 return NULL;
01351 }
01352
01353 thread->data = data;
01354 thread->func = func;
01355 thread->detached = detach;
01356
01357 pthread_attr_init(&attr);
01358
01359 if (detach) {
01360 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
01361 }
01362
01363 if (pthread_create(&thread->pthread, &attr, fluid_thread_start, thread)) {
01364 FLUID_LOG(FLUID_ERR, "Failed to create the thread");
01365 FLUID_FREE(thread);
01366 return NULL;
01367 }
01368
01369 return thread;
01370 }
01371
01372 int delete_fluid_thread(fluid_thread_t* thread)
01373 {
01374 FLUID_FREE(thread);
01375 return FLUID_OK;
01376 }
01377
01378 int fluid_thread_join(fluid_thread_t* thread)
01379 {
01380 int err = 0;
01381
01382 if (thread->pthread != 0) {
01383 err = pthread_join(thread->pthread, NULL);
01384 }
01385 return (err == 0)? FLUID_OK : FLUID_FAILED;
01386 }
01387
01388 #endif
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 #if defined(MACINTOSH)
01400
01401
01402
01403 #elif defined(WIN32)
01404
01405 #if 0
01406 typedef unsigned int socklen_t;
01407
01408 #define fluid_socket_read(_S,_B,_L) recv(_S,_B,_L,0)
01409 #define fluid_socket_write(_S,_B,_L) send(_S,_B,_L,0)
01410
01411 void fluid_socket_close(fluid_socket_t sock)
01412 {
01413 int r;
01414 char buf[1024];
01415 if (sock != INVALID_SOCKET) {
01416 shutdown(sock, 0x02);
01417 while (1) {
01418 r = recv(sock, buf, 1024, 0);
01419 if ((r == 0) || (r == SOCKET_ERROR)) {
01420 break;
01421 }
01422 }
01423 closesocket(sock);
01424 }
01425 }
01426 #endif
01427
01428
01429 #else
01430 #define fluid_socket_read(_S,_B,_L) read(_S,_B,_L)
01431 #define fluid_socket_write(_S,_B,_L) write(_S,_B,_L)
01432 #define SOCKET_ERROR -1
01433
01434 void fluid_socket_close(fluid_socket_t sock)
01435 {
01436 if (sock != INVALID_SOCKET) {
01437 close(sock);
01438 }
01439 }
01440
01441 #endif
01442
01443 #if !defined(MACINTOSH) && !defined(WIN32)
01444
01445
01446 fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock)
01447 {
01448 return sock;
01449 }
01450
01451 fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock)
01452 {
01453 return sock;
01454 }
01455
01456
01457
01458 struct _fluid_server_socket_t {
01459 fluid_socket_t socket;
01460 fluid_thread_t* thread;
01461 int cont;
01462 fluid_server_func_t func;
01463 void* data;
01464 };
01465
01466
01467 static void fluid_server_socket_run(void* data)
01468 {
01469 fluid_server_socket_t* server_socket = (fluid_server_socket_t*) data;
01470 fluid_socket_t client_socket;
01471 struct sockaddr_in addr;
01472 socklen_t addrlen = sizeof(addr);
01473
01474 FLUID_LOG(FLUID_DBG, "Server listening for connections");
01475
01476 while (server_socket->cont) {
01477
01478 client_socket = accept(server_socket->socket, (struct sockaddr*) &addr, &addrlen);
01479
01480 FLUID_LOG(FLUID_DBG, "New client connection");
01481
01482 if (client_socket == INVALID_SOCKET) {
01483 if (server_socket->cont) {
01484 FLUID_LOG(FLUID_ERR, "Failed to accept connection");
01485 }
01486 server_socket->cont = 0;
01487 return;
01488 } else {
01489 int r;
01490 r = (*server_socket->func)(server_socket->data, client_socket, inet_ntoa(addr.sin_addr));
01491 if (r != 0) {
01492 fluid_socket_close(client_socket);
01493 }
01494 }
01495 }
01496
01497 FLUID_LOG(FLUID_DBG, "Server closing");
01498 }
01499
01500 fluid_server_socket_t*
01501 new_fluid_server_socket(int port, fluid_server_func_t func, void* data)
01502 {
01503 fluid_server_socket_t* server_socket;
01504 struct sockaddr_in addr;
01505 fluid_socket_t sock;
01506
01507 if (func == NULL) {
01508 FLUID_LOG(FLUID_ERR, "Invalid callback function");
01509 return NULL;
01510 }
01511
01512 sock = socket(AF_INET, SOCK_STREAM, 0);
01513 if (sock == INVALID_SOCKET) {
01514 FLUID_LOG(FLUID_ERR, "Failed to create server socket");
01515 return NULL;
01516 }
01517
01518 FLUID_MEMSET((char *)&addr, 0, sizeof(struct sockaddr_in));
01519 addr.sin_family = AF_INET;
01520 addr.sin_addr.s_addr = htonl(INADDR_ANY);
01521 addr.sin_port = htons(port);
01522
01523 if (bind(sock, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
01524 FLUID_LOG(FLUID_ERR, "Failed to bind server socket");
01525 fluid_socket_close(sock);
01526 return NULL;
01527 }
01528
01529 if (listen(sock, 10) == SOCKET_ERROR) {
01530 FLUID_LOG(FLUID_ERR, "Failed listen on server socket");
01531 fluid_socket_close(sock);
01532 return NULL;
01533 }
01534
01535 server_socket = FLUID_NEW(fluid_server_socket_t);
01536 if (server_socket == NULL) {
01537 FLUID_LOG(FLUID_ERR, "Out of memory");
01538 fluid_socket_close(sock);
01539 return NULL;
01540 }
01541
01542 server_socket->socket = sock;
01543 server_socket->func = func;
01544 server_socket->data = data;
01545 server_socket->cont = 1;
01546
01547 server_socket->thread = new_fluid_thread(fluid_server_socket_run, server_socket, 0);
01548 if (server_socket->thread == NULL) {
01549 FLUID_FREE(server_socket);
01550 fluid_socket_close(sock);
01551 return NULL;
01552 }
01553
01554 return server_socket;
01555 }
01556
01557 int delete_fluid_server_socket(fluid_server_socket_t* server_socket)
01558 {
01559 server_socket->cont = 0;
01560 if (server_socket->socket != INVALID_SOCKET) {
01561 fluid_socket_close(server_socket->socket);
01562 }
01563 if (server_socket->thread) {
01564 delete_fluid_thread(server_socket->thread);
01565 }
01566 FLUID_FREE(server_socket);
01567 return FLUID_OK;
01568 }
01569
01570 int fluid_server_socket_join(fluid_server_socket_t* server_socket)
01571 {
01572 return fluid_thread_join(server_socket->thread);
01573 }
01574
01575 #endif