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 #else
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 struct _fluid_timer_t
00654 {
00655 long msec;
00656 fluid_timer_callback_t callback;
00657 void* data;
00658 pthread_t thread;
00659 int cont;
00660 int auto_destroy;
00661 };
00662
00663 void*
00664 fluid_timer_start(void *data)
00665 {
00666 int count = 0;
00667 int cont = 1;
00668 long start;
00669 long delay;
00670 fluid_timer_t* timer;
00671 timer = (fluid_timer_t*) data;
00672
00673
00674 start = fluid_curtime();
00675
00676 while (cont) {
00677
00678
00679 cont = (*timer->callback)(timer->data, fluid_curtime() - start);
00680
00681 count++;
00682
00683
00684
00685
00686 delay = (count * timer->msec) - (fluid_curtime() - start);
00687 if (delay > 0) {
00688 usleep(delay * 1000);
00689 }
00690
00691 cont &= timer->cont;
00692 }
00693
00694 FLUID_LOG(FLUID_DBG, "Timer thread finished");
00695 if (timer->thread != 0) {
00696 pthread_exit(NULL);
00697 }
00698
00699 if (timer->auto_destroy) {
00700 FLUID_FREE(timer);
00701 }
00702
00703 return NULL;
00704 }
00705
00706 fluid_timer_t*
00707 new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data,
00708 int new_thread, int auto_destroy)
00709 {
00710 pthread_attr_t *attr = NULL;
00711 pthread_attr_t rt_attr;
00712 int sched = SCHED_FIFO;
00713 struct sched_param priority;
00714 int err;
00715
00716 fluid_timer_t* timer = FLUID_NEW(fluid_timer_t);
00717 if (timer == NULL) {
00718 FLUID_LOG(FLUID_ERR, "Out of memory");
00719 return NULL;
00720 }
00721 timer->msec = msec;
00722 timer->callback = callback;
00723 timer->data = data;
00724 timer->cont = 1;
00725 timer->thread = 0;
00726 timer->auto_destroy = auto_destroy;
00727
00728 err = pthread_attr_init(&rt_attr);
00729 if (err == 0) {
00730 err = pthread_attr_setschedpolicy(&rt_attr, SCHED_FIFO);
00731 if (err == 0) {
00732 priority.sched_priority = 10;
00733 err = pthread_attr_setschedparam(&rt_attr, &priority);
00734 if (err == 0) {
00735 attr = &rt_attr;
00736 }
00737 }
00738 }
00739
00740 if (new_thread) {
00741 err = pthread_create(&timer->thread, attr, fluid_timer_start, (void*) timer);
00742 if (err == 0) {
00743 FLUID_LOG(FLUID_DBG, "The timer thread was created with real-time priority");
00744 } else {
00745
00746 err = pthread_create(&timer->thread, NULL, fluid_timer_start, (void*) timer);
00747 if (err != 0) {
00748 FLUID_LOG(FLUID_ERR, "Failed to create the timer thread");
00749 FLUID_FREE(timer);
00750 return NULL;
00751 } else {
00752 FLUID_LOG(FLUID_DBG, "The timer thread does not have real-time priority");
00753 }
00754 }
00755 } else {
00756 fluid_timer_start((void*) timer);
00757 }
00758 return timer;
00759 }
00760
00761 int
00762 delete_fluid_timer(fluid_timer_t* timer)
00763 {
00764 timer->cont = 0;
00765 fluid_timer_join(timer);
00766 FLUID_LOG(FLUID_DBG, "Joined player thread");
00767 FLUID_FREE(timer);
00768 return FLUID_OK;
00769 }
00770
00771 int
00772 fluid_timer_join(fluid_timer_t* timer)
00773 {
00774 int err = 0;
00775
00776 if (timer->thread != 0) {
00777 err = pthread_join(timer->thread, NULL);
00778 }
00779 FLUID_LOG(FLUID_DBG, "Joined player thread");
00780 return (err == 0)? FLUID_OK : FLUID_FAILED;
00781 }
00782
00783
00784
00785
00786
00787
00788
00789 static double fluid_cpu_frequency = -1.0;
00790
00791 double rdtsc(void);
00792 double fluid_estimate_cpu_frequency(void);
00793
00794 void fluid_time_config(void)
00795 {
00796 if (fluid_cpu_frequency < 0.0) {
00797 fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0;
00798 if (fluid_cpu_frequency == 0.0) fluid_cpu_frequency = 1.0;
00799 }
00800 }
00801
00802 unsigned int fluid_curtime()
00803 {
00804 struct timeval now;
00805 gettimeofday(&now, NULL);
00806 return now.tv_sec * 1000 + now.tv_usec / 1000;
00807 }
00808
00809 double fluid_utime(void)
00810 {
00811 return (rdtsc() / fluid_cpu_frequency);
00812 }
00813
00814 #if !defined(__i386__)
00815
00816 double rdtsc(void)
00817 {
00818 return 0.0;
00819 }
00820
00821 double fluid_estimate_cpu_frequency(void)
00822 {
00823 return 1.0;
00824 }
00825
00826 #else
00827
00828 double rdtsc(void)
00829 {
00830 unsigned int a, b;
00831
00832 __asm__ ("rdtsc" : "=a" (a), "=d" (b));
00833 return (double)b * (double)0x10000 * (double)0x10000 + a;
00834 }
00835
00836 double fluid_estimate_cpu_frequency(void)
00837 {
00838 double start, stop;
00839 unsigned int a0, b0, a1, b1;
00840 unsigned int before, after;
00841
00842 before = fluid_curtime();
00843 __asm__ ("rdtsc" : "=a" (a0), "=d" (b0));
00844
00845 sleep(1);
00846
00847 after = fluid_curtime();
00848 __asm__ ("rdtsc" : "=a" (a1), "=d" (b1));
00849
00850
00851 start = (double)b0 * (double)0x10000 * (double)0x10000 + a0;
00852 stop = (double)b1 * (double)0x10000 * (double)0x10000 + a1;
00853
00854 return 1000 * (stop - start) / (after - before);
00855 }
00856 #endif
00857
00858
00859 #ifdef FPE_CHECK
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 #define _FPU_STATUS_IE 0x001
00876 #define _FPU_STATUS_DE 0x002
00877 #define _FPU_STATUS_ZE 0x004
00878 #define _FPU_STATUS_OE 0x008
00879 #define _FPU_STATUS_UE 0x010
00880 #define _FPU_STATUS_PE 0x020
00881 #define _FPU_STATUS_SF 0x040
00882 #define _FPU_STATUS_ES 0x080
00883
00884
00885
00886
00887 #define _FPU_GET_SW(sw) __asm__ ("fnstsw %0" : "=m" (*&sw))
00888
00889
00890 #define _FPU_CLR_SW() __asm__ ("fnclex" : : )
00891
00892
00893
00894
00895
00896 unsigned int fluid_check_fpe_i386(char* explanation)
00897 {
00898 unsigned int s;
00899
00900 _FPU_GET_SW(s);
00901 _FPU_CLR_SW();
00902
00903 s &= _FPU_STATUS_IE | _FPU_STATUS_DE | _FPU_STATUS_ZE | _FPU_STATUS_OE | _FPU_STATUS_UE;
00904
00905 if (s)
00906 {
00907 FLUID_LOG(FLUID_WARN, "FPE exception (before or in %s): %s%s%s%s%s", explanation,
00908 (s & _FPU_STATUS_IE) ? "Invalid operation " : "",
00909 (s & _FPU_STATUS_DE) ? "Denormal number " : "",
00910 (s & _FPU_STATUS_ZE) ? "Zero divide " : "",
00911 (s & _FPU_STATUS_OE) ? "Overflow " : "",
00912 (s & _FPU_STATUS_UE) ? "Underflow " : "");
00913 }
00914
00915 return s;
00916 }
00917
00918
00919
00920
00921 void fluid_clear_fpe_i386 (void)
00922 {
00923 _FPU_CLR_SW();
00924 }
00925
00926 #endif // ifdef FPE_CHECK
00927
00928
00929 #endif // #else (its POSIX)
00930
00931
00932
00933
00934
00935
00936
00937
00938 #if WITH_PROFILING
00939
00940 fluid_profile_data_t fluid_profile_data[] =
00941 {
00942 { FLUID_PROF_WRITE_S16, "fluid_synth_write_s16 ", 1e10, 0.0, 0.0, 0},
00943 { FLUID_PROF_ONE_BLOCK, "fluid_synth_one_block ", 1e10, 0.0, 0.0, 0},
00944 { FLUID_PROF_ONE_BLOCK_CLEAR, "fluid_synth_one_block:clear ", 1e10, 0.0, 0.0, 0},
00945 { FLUID_PROF_ONE_BLOCK_VOICE, "fluid_synth_one_block:one voice ", 1e10, 0.0, 0.0, 0},
00946 { FLUID_PROF_ONE_BLOCK_VOICES, "fluid_synth_one_block:all voices", 1e10, 0.0, 0.0, 0},
00947 { FLUID_PROF_ONE_BLOCK_REVERB, "fluid_synth_one_block:reverb ", 1e10, 0.0, 0.0, 0},
00948 { FLUID_PROF_ONE_BLOCK_CHORUS, "fluid_synth_one_block:chorus ", 1e10, 0.0, 0.0, 0},
00949 { FLUID_PROF_VOICE_NOTE, "fluid_voice:note ", 1e10, 0.0, 0.0, 0},
00950 { FLUID_PROF_VOICE_RELEASE, "fluid_voice:release ", 1e10, 0.0, 0.0, 0},
00951 { FLUID_PROF_LAST, "last", 1e100, 0.0, 0.0, 0}
00952 };
00953
00954
00955 void fluid_profiling_print(void)
00956 {
00957 int i;
00958
00959 printf("fluid_profiling_print\n");
00960
00961 FLUID_LOG(FLUID_INFO, "Estimated CPU frequency: %.0f MHz", fluid_cpu_frequency);
00962 FLUID_LOG(FLUID_INFO, "Estimated times: min/avg/max (micro seconds)");
00963
00964 for (i = 0; i < FLUID_PROF_LAST; i++) {
00965 if (fluid_profile_data[i].count > 0) {
00966 FLUID_LOG(FLUID_INFO, "%s: %.3f/%.3f/%.3f",
00967 fluid_profile_data[i].description,
00968 fluid_profile_data[i].min,
00969 fluid_profile_data[i].total / fluid_profile_data[i].count,
00970 fluid_profile_data[i].max);
00971 } else {
00972 FLUID_LOG(FLUID_DBG, "%s: no profiling available", fluid_profile_data[i].description);
00973 }
00974 }
00975 }
00976
00977
00978 #endif
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 #if defined(MACOS9)
00989
00990 fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach) { return NULL; }
00991 int delete_fluid_thread(fluid_thread_t* thread) { return 0; }
00992 int fluid_thread_join(fluid_thread_t* thread) { return 0; }
00993
00994 #elif defined(WIN32)
00995
00996 struct _fluid_thread_t {
00997 HANDLE thread;
00998 DWORD thread_id;
00999 fluid_thread_func_t func;
01000 void* data;
01001 int detached;
01002 };
01003
01004 static DWORD WINAPI fluid_thread_start(LPVOID data)
01005 {
01006 fluid_thread_t* thread = (fluid_thread_t*) data;
01007
01008 thread->func(thread->data);
01009
01010 if (thread->detached) {
01011 FLUID_FREE(thread);
01012 }
01013
01014 return 0;
01015 }
01016
01017
01018 fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach)
01019 {
01020 fluid_thread_t* thread;
01021
01022 if (func == NULL) {
01023 FLUID_LOG(FLUID_ERR, "Invalid thread function");
01024 return NULL;
01025 }
01026
01027 thread = FLUID_NEW(fluid_thread_t);
01028 if (thread == NULL) {
01029 FLUID_LOG(FLUID_ERR, "Out of memory");
01030 return NULL;
01031 }
01032
01033 thread->data = data;
01034 thread->func = func;
01035 thread->detached = detach;
01036
01037 thread->thread = CreateThread(NULL, 0, fluid_thread_start, (LPVOID) thread,
01038 0, &thread->thread_id);
01039 if (thread->thread == NULL) {
01040 FLUID_LOG(FLUID_ERR, "Couldn't create the thread");
01041 FLUID_FREE(thread);
01042 return NULL;
01043 }
01044
01045 return thread;
01046 }
01047
01048 int delete_fluid_thread(fluid_thread_t* thread)
01049 {
01050 FLUID_FREE(thread);
01051 return FLUID_OK;
01052 }
01053
01054
01055 int fluid_thread_join(fluid_thread_t* thread)
01056 {
01057 DWORD wait_result;
01058 if (thread->thread == 0) {
01059 return FLUID_OK;
01060 }
01061 wait_result = WaitForSingleObject(thread->thread, INFINITE);
01062 return (wait_result == WAIT_OBJECT_0)? FLUID_OK : FLUID_FAILED;
01063 }
01064
01065 #else
01066
01067
01068 struct _fluid_thread_t {
01069 pthread_t pthread;
01070 fluid_thread_func_t func;
01071 void* data;
01072 int detached;
01073 };
01074
01075 static void* fluid_thread_start(void *data)
01076 {
01077 fluid_thread_t* thread = (fluid_thread_t*) data;
01078
01079 thread->func(thread->data);
01080
01081 if (thread->detached) {
01082 FLUID_FREE(thread);
01083 }
01084
01085 return NULL;
01086 }
01087
01088 fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach)
01089 {
01090 fluid_thread_t* thread;
01091 pthread_attr_t attr;
01092
01093 if (func == NULL) {
01094 FLUID_LOG(FLUID_ERR, "Invalid thread function");
01095 return NULL;
01096 }
01097
01098 thread = FLUID_NEW(fluid_thread_t);
01099 if (thread == NULL) {
01100 FLUID_LOG(FLUID_ERR, "Out of memory");
01101 return NULL;
01102 }
01103
01104 thread->data = data;
01105 thread->func = func;
01106 thread->detached = detach;
01107
01108 pthread_attr_init(&attr);
01109
01110 if (detach) {
01111 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
01112 }
01113
01114 if (pthread_create(&thread->pthread, &attr, fluid_thread_start, thread)) {
01115 FLUID_LOG(FLUID_ERR, "Failed to create the thread");
01116 FLUID_FREE(thread);
01117 return NULL;
01118 }
01119
01120 return thread;
01121 }
01122
01123 int delete_fluid_thread(fluid_thread_t* thread)
01124 {
01125 FLUID_FREE(thread);
01126 return FLUID_OK;
01127 }
01128
01129 int fluid_thread_join(fluid_thread_t* thread)
01130 {
01131 int err = 0;
01132
01133 if (thread->pthread != 0) {
01134 err = pthread_join(thread->pthread, NULL);
01135 }
01136 return (err == 0)? FLUID_OK : FLUID_FAILED;
01137 }
01138
01139 #endif
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150 #if defined(MACINTOSH)
01151
01152
01153
01154 #elif defined(WIN32)
01155
01156 #if 0
01157 typedef unsigned int socklen_t;
01158
01159 #define fluid_socket_read(_S,_B,_L) recv(_S,_B,_L,0)
01160 #define fluid_socket_write(_S,_B,_L) send(_S,_B,_L,0)
01161
01162 void fluid_socket_close(fluid_socket_t sock)
01163 {
01164 int r;
01165 char buf[1024];
01166 if (sock != INVALID_SOCKET) {
01167 shutdown(sock, 0x02);
01168 while (1) {
01169 r = recv(sock, buf, 1024, 0);
01170 if ((r == 0) || (r == SOCKET_ERROR)) {
01171 break;
01172 }
01173 }
01174 closesocket(sock);
01175 }
01176 }
01177 #endif
01178
01179
01180 #else
01181 #define fluid_socket_read(_S,_B,_L) read(_S,_B,_L)
01182 #define fluid_socket_write(_S,_B,_L) write(_S,_B,_L)
01183 #define SOCKET_ERROR -1
01184
01185 void fluid_socket_close(fluid_socket_t sock)
01186 {
01187 if (sock != INVALID_SOCKET) {
01188 close(sock);
01189 }
01190 }
01191
01192 #endif
01193
01194 #if !defined(MACINTOSH) && !defined(WIN32)
01195
01196
01197 fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock)
01198 {
01199 return sock;
01200 }
01201
01202 fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock)
01203 {
01204 return sock;
01205 }
01206
01207
01208
01209 struct _fluid_server_socket_t {
01210 fluid_socket_t socket;
01211 fluid_thread_t* thread;
01212 int cont;
01213 fluid_server_func_t func;
01214 void* data;
01215 };
01216
01217
01218 static void fluid_server_socket_run(void* data)
01219 {
01220 fluid_server_socket_t* server_socket = (fluid_server_socket_t*) data;
01221 fluid_socket_t client_socket;
01222 struct sockaddr_in addr;
01223 socklen_t addrlen = sizeof(addr);
01224
01225 FLUID_LOG(FLUID_DBG, "Server listening for connections");
01226
01227 while (server_socket->cont) {
01228
01229 client_socket = accept(server_socket->socket, (struct sockaddr*) &addr, &addrlen);
01230
01231 FLUID_LOG(FLUID_DBG, "New client connection");
01232
01233 if (client_socket == INVALID_SOCKET) {
01234 if (server_socket->cont) {
01235 FLUID_LOG(FLUID_ERR, "Failed to accept connection");
01236 }
01237 server_socket->cont = 0;
01238 return;
01239 } else {
01240 int r;
01241 r = (*server_socket->func)(server_socket->data, client_socket, inet_ntoa(addr.sin_addr));
01242 if (r != 0) {
01243 fluid_socket_close(client_socket);
01244 }
01245 }
01246 }
01247
01248 FLUID_LOG(FLUID_DBG, "Server closing");
01249 }
01250
01251 fluid_server_socket_t*
01252 new_fluid_server_socket(int port, fluid_server_func_t func, void* data)
01253 {
01254 fluid_server_socket_t* server_socket;
01255 struct sockaddr_in addr;
01256 fluid_socket_t sock;
01257
01258 if (func == NULL) {
01259 FLUID_LOG(FLUID_ERR, "Invalid callback function");
01260 return NULL;
01261 }
01262
01263 sock = socket(AF_INET, SOCK_STREAM, 0);
01264 if (sock == INVALID_SOCKET) {
01265 FLUID_LOG(FLUID_ERR, "Failed to create server socket");
01266 return NULL;
01267 }
01268
01269 FLUID_MEMSET((char *)&addr, 0, sizeof(struct sockaddr_in));
01270 addr.sin_family = AF_INET;
01271 addr.sin_addr.s_addr = htonl(INADDR_ANY);
01272 addr.sin_port = htons(port);
01273
01274 if (bind(sock, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
01275 FLUID_LOG(FLUID_ERR, "Failed to bind server socket");
01276 fluid_socket_close(sock);
01277 return NULL;
01278 }
01279
01280 if (listen(sock, 10) == SOCKET_ERROR) {
01281 FLUID_LOG(FLUID_ERR, "Failed listen on server socket");
01282 fluid_socket_close(sock);
01283 return NULL;
01284 }
01285
01286 server_socket = FLUID_NEW(fluid_server_socket_t);
01287 if (server_socket == NULL) {
01288 FLUID_LOG(FLUID_ERR, "Out of memory");
01289 fluid_socket_close(sock);
01290 return NULL;
01291 }
01292
01293 server_socket->socket = sock;
01294 server_socket->func = func;
01295 server_socket->data = data;
01296 server_socket->cont = 1;
01297
01298 server_socket->thread = new_fluid_thread(fluid_server_socket_run, server_socket, 0);
01299 if (server_socket->thread == NULL) {
01300 FLUID_FREE(server_socket);
01301 fluid_socket_close(sock);
01302 return NULL;
01303 }
01304
01305 return server_socket;
01306 }
01307
01308 int delete_fluid_server_socket(fluid_server_socket_t* server_socket)
01309 {
01310 server_socket->cont = 0;
01311 if (server_socket->socket != INVALID_SOCKET) {
01312 fluid_socket_close(server_socket->socket);
01313 }
01314 if (server_socket->thread) {
01315 delete_fluid_thread(server_socket->thread);
01316 }
01317 FLUID_FREE(server_socket);
01318 return FLUID_OK;
01319 }
01320
01321 int fluid_server_socket_join(fluid_server_socket_t* server_socket)
01322 {
01323 return fluid_thread_join(server_socket->thread);
01324 }
01325
01326 #endif