00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <math.h>
00022
00023 #include "fluid_synth.h"
00024 #include "fluid_sys.h"
00025 #include "fluid_chan.h"
00026 #include "fluid_tuning.h"
00027 #include "fluid_settings.h"
00028 #include "fluid_sfont.h"
00029
00030 #ifdef TRAP_ON_FPE
00031 #define _GNU_SOURCE
00032 #include <fenv.h>
00033
00034
00035 extern int feenableexcept (int excepts);
00036 #endif
00037
00038
00039 fluid_sfloader_t* new_fluid_defsfloader(void);
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 int fluid_synth_program_select2(fluid_synth_t* synth,
00050 int chan,
00051 char* sfont_name,
00052 unsigned int bank_num,
00053 unsigned int preset_num);
00054
00055 fluid_sfont_t* fluid_synth_get_sfont_by_name(fluid_synth_t* synth, char *name);
00056
00057 int fluid_synth_set_gen2(fluid_synth_t* synth, int chan,
00058 int param, float value,
00059 int absolute, int normalized);
00060
00061
00062
00063
00064
00065
00066
00067
00068 static int fluid_synth_initialized = 0;
00069 static void fluid_synth_init(void);
00070 static void init_dither(void);
00071
00072
00073
00074
00075
00076
00077
00078
00079 fluid_mod_t default_vel2att_mod;
00080 fluid_mod_t default_vel2filter_mod;
00081 fluid_mod_t default_at2viblfo_mod;
00082 fluid_mod_t default_mod2viblfo_mod;
00083 fluid_mod_t default_att_mod;
00084 fluid_mod_t default_pan_mod;
00085 fluid_mod_t default_expr_mod;
00086 fluid_mod_t default_reverb_mod;
00087 fluid_mod_t default_chorus_mod;
00088 fluid_mod_t default_pitch_bend_mod;
00089
00090
00091 static fluid_revmodel_presets_t revmodel_preset[] = {
00092
00093 { "Test 1", 0.2f, 0.0f, 0.5f, 0.9f },
00094 { "Test 2", 0.4f, 0.2f, 0.5f, 0.8f },
00095 { "Test 3", 0.6f, 0.4f, 0.5f, 0.7f },
00096 { "Test 4", 0.8f, 0.7f, 0.5f, 0.6f },
00097 { "Test 5", 0.8f, 1.0f, 0.5f, 0.5f },
00098 { NULL, 0.0f, 0.0f, 0.0f, 0.0f }
00099 };
00100
00101
00102
00103
00104
00105
00106
00107
00108 void fluid_synth_settings(fluid_settings_t* settings)
00109 {
00110 fluid_settings_register_str(settings, "synth.verbose", "no", 0, NULL, NULL);
00111 fluid_settings_register_str(settings, "synth.dump", "no", 0, NULL, NULL);
00112 fluid_settings_register_str(settings, "synth.reverb.active", "yes", 0, NULL, NULL);
00113 fluid_settings_register_str(settings, "synth.chorus.active", "yes", 0, NULL, NULL);
00114 fluid_settings_register_str(settings, "synth.ladspa.active", "no", 0, NULL, NULL);
00115
00116 fluid_settings_register_int(settings, "synth.polyphony",
00117 256, 16, 4096, 0, NULL, NULL);
00118 fluid_settings_register_int(settings, "synth.midi-channels",
00119 16, 16, 256, 0, NULL, NULL);
00120 fluid_settings_register_num(settings, "synth.gain",
00121 0.2f, 0.0f, 10.0f,
00122 0, NULL, NULL);
00123 fluid_settings_register_int(settings, "synth.audio-channels",
00124 1, 1, 256, 0, NULL, NULL);
00125 fluid_settings_register_int(settings, "synth.audio-groups",
00126 1, 1, 256, 0, NULL, NULL);
00127 fluid_settings_register_int(settings, "synth.effects-channels",
00128 2, 2, 2, 0, NULL, NULL);
00129 fluid_settings_register_num(settings, "synth.sample-rate",
00130 44100.0f, 22050.0f, 96000.0f,
00131 0, NULL, NULL);
00132 }
00133
00134
00135
00136
00137 void fluid_version(int *major, int *minor, int *micro)
00138 {
00139 *major = FLUIDSYNTH_VERSION_MAJOR;
00140 *minor = FLUIDSYNTH_VERSION_MINOR;
00141 *micro = FLUIDSYNTH_VERSION_MICRO;
00142 }
00143
00144
00145
00146
00147 char* fluid_version_str(void)
00148 {
00149 return FLUIDSYNTH_VERSION;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158 static void
00159 fluid_synth_init()
00160 {
00161 fluid_synth_initialized++;
00162
00163 #ifdef TRAP_ON_FPE
00164
00165 feenableexcept (FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);
00166 #endif
00167
00168 fluid_conversion_config();
00169
00170 fluid_dsp_float_config();
00171
00172 fluid_sys_config();
00173
00174 init_dither();
00175
00176
00177
00178 fluid_mod_set_source1(&default_vel2att_mod,
00179 FLUID_MOD_VELOCITY,
00180 FLUID_MOD_GC
00181 | FLUID_MOD_CONCAVE
00182 | FLUID_MOD_UNIPOLAR
00183 | FLUID_MOD_NEGATIVE
00184 );
00185 fluid_mod_set_source2(&default_vel2att_mod, 0, 0);
00186 fluid_mod_set_dest(&default_vel2att_mod, GEN_ATTENUATION);
00187 fluid_mod_set_amount(&default_vel2att_mod, 960.0);
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 fluid_mod_set_source1(&default_vel2filter_mod, FLUID_MOD_VELOCITY,
00199 FLUID_MOD_GC
00200 | FLUID_MOD_LINEAR
00201 | FLUID_MOD_UNIPOLAR
00202 | FLUID_MOD_NEGATIVE
00203 );
00204 fluid_mod_set_source2(&default_vel2filter_mod, FLUID_MOD_VELOCITY,
00205 FLUID_MOD_GC
00206 | FLUID_MOD_SWITCH
00207 | FLUID_MOD_UNIPOLAR
00208
00209 | FLUID_MOD_POSITIVE
00210 );
00211 fluid_mod_set_dest(&default_vel2filter_mod, GEN_FILTERFC);
00212 fluid_mod_set_amount(&default_vel2filter_mod, -2400);
00213
00214
00215
00216
00217 fluid_mod_set_source1(&default_at2viblfo_mod, FLUID_MOD_CHANNELPRESSURE,
00218 FLUID_MOD_GC
00219 | FLUID_MOD_LINEAR
00220 | FLUID_MOD_UNIPOLAR
00221 | FLUID_MOD_POSITIVE
00222 );
00223 fluid_mod_set_source2(&default_at2viblfo_mod, 0,0);
00224 fluid_mod_set_dest(&default_at2viblfo_mod, GEN_VIBLFOTOPITCH);
00225 fluid_mod_set_amount(&default_at2viblfo_mod, 50);
00226
00227
00228
00229
00230 fluid_mod_set_source1(&default_mod2viblfo_mod, 1,
00231 FLUID_MOD_CC
00232 | FLUID_MOD_LINEAR
00233 | FLUID_MOD_UNIPOLAR
00234 | FLUID_MOD_POSITIVE
00235 );
00236 fluid_mod_set_source2(&default_mod2viblfo_mod, 0,0);
00237 fluid_mod_set_dest(&default_mod2viblfo_mod, GEN_VIBLFOTOPITCH);
00238 fluid_mod_set_amount(&default_mod2viblfo_mod, 50);
00239
00240
00241
00242
00243 fluid_mod_set_source1(&default_att_mod, 7,
00244 FLUID_MOD_CC
00245 | FLUID_MOD_CONCAVE
00246 | FLUID_MOD_UNIPOLAR
00247 | FLUID_MOD_NEGATIVE
00248 );
00249 fluid_mod_set_source2(&default_att_mod, 0, 0);
00250 fluid_mod_set_dest(&default_att_mod, GEN_ATTENUATION);
00251 fluid_mod_set_amount(&default_att_mod, 960.0);
00252
00253
00254
00255
00256 fluid_mod_set_source1(&default_pan_mod, 10,
00257 FLUID_MOD_CC
00258 | FLUID_MOD_LINEAR
00259 | FLUID_MOD_BIPOLAR
00260 | FLUID_MOD_POSITIVE
00261 );
00262 fluid_mod_set_source2(&default_pan_mod, 0, 0);
00263 fluid_mod_set_dest(&default_pan_mod, GEN_PAN);
00264
00265
00266
00267 fluid_mod_set_amount(&default_pan_mod, 500.0);
00268
00269
00270
00271 fluid_mod_set_source1(&default_expr_mod, 11,
00272 FLUID_MOD_CC
00273 | FLUID_MOD_CONCAVE
00274 | FLUID_MOD_UNIPOLAR
00275 | FLUID_MOD_NEGATIVE
00276 );
00277 fluid_mod_set_source2(&default_expr_mod, 0, 0);
00278 fluid_mod_set_dest(&default_expr_mod, GEN_ATTENUATION);
00279 fluid_mod_set_amount(&default_expr_mod, 960.0);
00280
00281
00282
00283
00284 fluid_mod_set_source1(&default_reverb_mod, 91,
00285 FLUID_MOD_CC
00286 | FLUID_MOD_LINEAR
00287 | FLUID_MOD_UNIPOLAR
00288 | FLUID_MOD_POSITIVE
00289 );
00290 fluid_mod_set_source2(&default_reverb_mod, 0, 0);
00291 fluid_mod_set_dest(&default_reverb_mod, GEN_REVERBSEND);
00292 fluid_mod_set_amount(&default_reverb_mod, 200);
00293
00294
00295
00296
00297 fluid_mod_set_source1(&default_chorus_mod, 93,
00298 FLUID_MOD_CC
00299 | FLUID_MOD_LINEAR
00300 | FLUID_MOD_UNIPOLAR
00301 | FLUID_MOD_POSITIVE
00302 );
00303 fluid_mod_set_source2(&default_chorus_mod, 0, 0);
00304 fluid_mod_set_dest(&default_chorus_mod, GEN_CHORUSSEND);
00305 fluid_mod_set_amount(&default_chorus_mod, 200);
00306
00307
00308
00309
00310 fluid_mod_set_source1(&default_pitch_bend_mod, FLUID_MOD_PITCHWHEEL,
00311 FLUID_MOD_GC
00312 | FLUID_MOD_LINEAR
00313 | FLUID_MOD_BIPOLAR
00314 | FLUID_MOD_POSITIVE
00315 );
00316 fluid_mod_set_source2(&default_pitch_bend_mod, FLUID_MOD_PITCHWHEELSENS,
00317 FLUID_MOD_GC
00318 | FLUID_MOD_LINEAR
00319 | FLUID_MOD_UNIPOLAR
00320 | FLUID_MOD_POSITIVE
00321 );
00322 fluid_mod_set_dest(&default_pitch_bend_mod, GEN_PITCH);
00323 fluid_mod_set_amount(&default_pitch_bend_mod, 12700.0);
00324 }
00325
00326
00327 int fluid_synth_verify_settings(fluid_settings_t *settings)
00328 {
00329 return 0;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 fluid_synth_t*
00341 new_fluid_synth(fluid_settings_t *settings)
00342 {
00343 int i;
00344 fluid_synth_t* synth;
00345 fluid_sfloader_t* loader;
00346
00347
00348 if (fluid_synth_initialized == 0) {
00349 fluid_synth_init();
00350 }
00351
00352 fluid_synth_verify_settings(settings);
00353
00354
00355 synth = FLUID_NEW(fluid_synth_t);
00356 if (synth == NULL) {
00357 FLUID_LOG(FLUID_ERR, "Out of memory");
00358 return NULL;
00359 }
00360 FLUID_MEMSET(synth, 0, sizeof(fluid_synth_t));
00361
00362 fluid_mutex_init(synth->busy);
00363
00364 synth->settings = settings;
00365
00366 synth->with_reverb = fluid_settings_str_equal(settings, "synth.reverb.active", "yes");
00367 synth->with_chorus = fluid_settings_str_equal(settings, "synth.chorus.active", "yes");
00368 synth->verbose = fluid_settings_str_equal(settings, "synth.verbose", "yes");
00369 synth->dump = fluid_settings_str_equal(settings, "synth.dump", "yes");
00370
00371 fluid_settings_getint(settings, "synth.polyphony", &synth->polyphony);
00372 fluid_settings_getnum(settings, "synth.sample-rate", &synth->sample_rate);
00373 fluid_settings_getint(settings, "synth.midi-channels", &synth->midi_channels);
00374 fluid_settings_getint(settings, "synth.audio-channels", &synth->audio_channels);
00375 fluid_settings_getint(settings, "synth.audio-groups", &synth->audio_groups);
00376 fluid_settings_getint(settings, "synth.effects-channels", &synth->effects_channels);
00377 fluid_settings_getnum(settings, "synth.gain", &synth->gain);
00378
00379
00380 fluid_settings_register_num(settings, "synth.gain",
00381 0.2f, 0.0f, 10.0f, 0,
00382 (fluid_num_update_t) fluid_synth_update_gain, synth);
00383 fluid_settings_register_int(settings, "synth.polyphony",
00384 synth->polyphony, 16, 4096, 0,
00385 (fluid_int_update_t) fluid_synth_update_polyphony,
00386 synth);
00387
00388
00389
00390 if (synth->midi_channels % 16 != 0) {
00391 int n = synth->midi_channels / 16;
00392 synth->midi_channels = (n + 1) * 16;
00393 fluid_settings_setint(settings, "synth.midi-channels", synth->midi_channels);
00394 FLUID_LOG(FLUID_WARN, "Requested number of MIDI channels is not a multiple of 16. "
00395 "I'll increase the number of channels to the next multiple.");
00396 }
00397
00398 if (synth->audio_channels < 1) {
00399 FLUID_LOG(FLUID_WARN, "Requested number of audio channels is smaller than 1. "
00400 "Changing this setting to 1.");
00401 synth->audio_channels = 1;
00402 } else if (synth->audio_channels > 128) {
00403 FLUID_LOG(FLUID_WARN, "Requested number of audio channels is too big (%d). "
00404 "Limiting this setting to 128.", synth->audio_channels);
00405 synth->audio_channels = 128;
00406 }
00407
00408 if (synth->audio_groups < 1) {
00409 FLUID_LOG(FLUID_WARN, "Requested number of audio groups is smaller than 1. "
00410 "Changing this setting to 1.");
00411 synth->audio_groups = 1;
00412 } else if (synth->audio_groups > 128) {
00413 FLUID_LOG(FLUID_WARN, "Requested number of audio groups is too big (%d). "
00414 "Limiting this setting to 128.", synth->audio_groups);
00415 synth->audio_groups = 128;
00416 }
00417
00418 if (synth->effects_channels != 2) {
00419 FLUID_LOG(FLUID_WARN, "Invalid number of effects channels (%d)."
00420 "Setting effects channels to 2.", synth->effects_channels);
00421 synth->effects_channels = 2;
00422 }
00423
00424
00425
00426
00427
00428 synth->nbuf = synth->audio_channels;
00429 if (synth->audio_groups > synth->nbuf) {
00430 synth->nbuf = synth->audio_groups;
00431 }
00432
00433 #ifdef LADSPA
00434
00435 synth->LADSPA_FxUnit = new_fluid_LADSPA_FxUnit(synth);
00436 #endif
00437
00438
00439 synth->state = FLUID_SYNTH_PLAYING;
00440 synth->sfont = NULL;
00441 synth->noteid = 0;
00442 synth->ticks = 0;
00443 synth->tuning = NULL;
00444
00445
00446 loader = new_fluid_defsfloader();
00447
00448 if (loader == NULL) {
00449 FLUID_LOG(FLUID_WARN, "Failed to create the default SoundFont loader");
00450 } else {
00451 fluid_synth_add_sfloader(synth, loader);
00452 }
00453
00454
00455 synth->channel = FLUID_ARRAY(fluid_channel_t*, synth->midi_channels);
00456 if (synth->channel == NULL) {
00457 FLUID_LOG(FLUID_ERR, "Out of memory");
00458 goto error_recovery;
00459 }
00460 for (i = 0; i < synth->midi_channels; i++) {
00461 synth->channel[i] = new_fluid_channel(synth, i);
00462 if (synth->channel[i] == NULL) {
00463 goto error_recovery;
00464 }
00465 }
00466
00467
00468 synth->nvoice = synth->polyphony;
00469 synth->voice = FLUID_ARRAY(fluid_voice_t*, synth->nvoice);
00470 if (synth->voice == NULL) {
00471 goto error_recovery;
00472 }
00473 for (i = 0; i < synth->nvoice; i++) {
00474 synth->voice[i] = new_fluid_voice(synth->sample_rate);
00475 if (synth->voice[i] == NULL) {
00476 goto error_recovery;
00477 }
00478 }
00479
00480
00481 synth->left_buf = NULL;
00482 synth->right_buf = NULL;
00483 synth->fx_left_buf = NULL;
00484 synth->fx_right_buf = NULL;
00485
00486
00487
00488 synth->left_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf);
00489 synth->right_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf);
00490
00491 if ((synth->left_buf == NULL) || (synth->right_buf == NULL)) {
00492 FLUID_LOG(FLUID_ERR, "Out of memory");
00493 goto error_recovery;
00494 }
00495
00496 FLUID_MEMSET(synth->left_buf, 0, synth->nbuf * sizeof(fluid_real_t*));
00497 FLUID_MEMSET(synth->right_buf, 0, synth->nbuf * sizeof(fluid_real_t*));
00498
00499 for (i = 0; i < synth->nbuf; i++) {
00500
00501 synth->left_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE);
00502 synth->right_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE);
00503
00504 if ((synth->left_buf[i] == NULL) || (synth->right_buf[i] == NULL)) {
00505 FLUID_LOG(FLUID_ERR, "Out of memory");
00506 goto error_recovery;
00507 }
00508 }
00509
00510
00511
00512 synth->fx_left_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels);
00513 synth->fx_right_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels);
00514
00515 if ((synth->fx_left_buf == NULL) || (synth->fx_right_buf == NULL)) {
00516 FLUID_LOG(FLUID_ERR, "Out of memory");
00517 goto error_recovery;
00518 }
00519
00520 FLUID_MEMSET(synth->fx_left_buf, 0, 2 * sizeof(fluid_real_t*));
00521 FLUID_MEMSET(synth->fx_right_buf, 0, 2 * sizeof(fluid_real_t*));
00522
00523 for (i = 0; i < synth->effects_channels; i++) {
00524 synth->fx_left_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE);
00525 synth->fx_right_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE);
00526
00527 if ((synth->fx_left_buf[i] == NULL) || (synth->fx_right_buf[i] == NULL)) {
00528 FLUID_LOG(FLUID_ERR, "Out of memory");
00529 goto error_recovery;
00530 }
00531 }
00532
00533
00534 synth->cur = FLUID_BUFSIZE;
00535 synth->dither_index = 0;
00536
00537
00538 synth->reverb = new_fluid_revmodel();
00539 if (synth->reverb == NULL) {
00540 FLUID_LOG(FLUID_ERR, "Out of memory");
00541 goto error_recovery;
00542 }
00543
00544 fluid_synth_set_reverb(synth,
00545 FLUID_REVERB_DEFAULT_ROOMSIZE,
00546 FLUID_REVERB_DEFAULT_DAMP,
00547 FLUID_REVERB_DEFAULT_WIDTH,
00548 FLUID_REVERB_DEFAULT_LEVEL);
00549
00550
00551 synth->chorus = new_fluid_chorus(synth->sample_rate);
00552 if (synth->chorus == NULL) {
00553 FLUID_LOG(FLUID_ERR, "Out of memory");
00554 goto error_recovery;
00555 }
00556
00557
00558 synth->start = fluid_curtime();
00559
00560 return synth;
00561
00562 error_recovery:
00563 delete_fluid_synth(synth);
00564 return NULL;
00565 }
00566
00567
00568
00569
00570 int
00571 delete_fluid_synth(fluid_synth_t* synth)
00572 {
00573 int i, k;
00574 fluid_list_t *list;
00575 fluid_sfont_t* sfont;
00576 fluid_bank_offset_t* bank_offset;
00577 fluid_sfloader_t* loader;
00578
00579 if (synth == NULL) {
00580 return FLUID_OK;
00581 }
00582
00583 fluid_profiling_print();
00584
00585 synth->state = FLUID_SYNTH_STOPPED;
00586
00587
00588 if (synth->voice != NULL) {
00589 for (i = 0; i < synth->nvoice; i++) {
00590 if (synth->voice[i] && fluid_voice_is_playing (synth->voice[i]))
00591 fluid_voice_off (synth->voice[i]);
00592 }
00593 }
00594
00595
00596 for (list = synth->sfont; list; list = fluid_list_next(list)) {
00597 sfont = (fluid_sfont_t*) fluid_list_get(list);
00598 delete_fluid_sfont(sfont);
00599 }
00600
00601 delete_fluid_list(synth->sfont);
00602
00603
00604 for (list = synth->bank_offsets; list; list = fluid_list_next(list)) {
00605 bank_offset = (fluid_bank_offset_t*) fluid_list_get(list);
00606 FLUID_FREE(bank_offset);
00607 }
00608
00609 delete_fluid_list(synth->bank_offsets);
00610
00611
00612
00613
00614 for (list = synth->loaders; list; list = fluid_list_next(list)) {
00615 loader = (fluid_sfloader_t*) fluid_list_get(list);
00616 fluid_sfloader_delete(loader);
00617 }
00618
00619 delete_fluid_list(synth->loaders);
00620
00621
00622 if (synth->channel != NULL) {
00623 for (i = 0; i < synth->midi_channels; i++) {
00624 if (synth->channel[i] != NULL) {
00625 delete_fluid_channel(synth->channel[i]);
00626 }
00627 }
00628 FLUID_FREE(synth->channel);
00629 }
00630
00631 if (synth->voice != NULL) {
00632 for (i = 0; i < synth->nvoice; i++) {
00633 if (synth->voice[i] != NULL) {
00634 delete_fluid_voice(synth->voice[i]);
00635 }
00636 }
00637 FLUID_FREE(synth->voice);
00638 }
00639
00640
00641 if (synth->left_buf != NULL) {
00642 for (i = 0; i < synth->nbuf; i++) {
00643 if (synth->left_buf[i] != NULL) {
00644 FLUID_FREE(synth->left_buf[i]);
00645 }
00646 }
00647 FLUID_FREE(synth->left_buf);
00648 }
00649
00650 if (synth->right_buf != NULL) {
00651 for (i = 0; i < synth->nbuf; i++) {
00652 if (synth->right_buf[i] != NULL) {
00653 FLUID_FREE(synth->right_buf[i]);
00654 }
00655 }
00656 FLUID_FREE(synth->right_buf);
00657 }
00658
00659 if (synth->fx_left_buf != NULL) {
00660 for (i = 0; i < 2; i++) {
00661 if (synth->fx_left_buf[i] != NULL) {
00662 FLUID_FREE(synth->fx_left_buf[i]);
00663 }
00664 }
00665 FLUID_FREE(synth->fx_left_buf);
00666 }
00667
00668 if (synth->fx_right_buf != NULL) {
00669 for (i = 0; i < 2; i++) {
00670 if (synth->fx_right_buf[i] != NULL) {
00671 FLUID_FREE(synth->fx_right_buf[i]);
00672 }
00673 }
00674 FLUID_FREE(synth->fx_right_buf);
00675 }
00676
00677
00678 if (synth->reverb != NULL) {
00679 delete_fluid_revmodel(synth->reverb);
00680 }
00681
00682
00683 if (synth->chorus != NULL) {
00684 delete_fluid_chorus(synth->chorus);
00685 }
00686
00687
00688 if (synth->tuning != NULL) {
00689 for (i = 0; i < 128; i++) {
00690 if (synth->tuning[i] != NULL) {
00691 for (k = 0; k < 128; k++) {
00692 if (synth->tuning[i][k] != NULL) {
00693 FLUID_FREE(synth->tuning[i][k]);
00694 }
00695 }
00696 FLUID_FREE(synth->tuning[i]);
00697 }
00698 }
00699 FLUID_FREE(synth->tuning);
00700 }
00701
00702 #ifdef LADSPA
00703
00704 fluid_LADSPA_shutdown(synth->LADSPA_FxUnit);
00705 FLUID_FREE(synth->LADSPA_FxUnit);
00706 #endif
00707
00708 fluid_mutex_destroy(synth->busy);
00709
00710 FLUID_FREE(synth);
00711
00712 return FLUID_OK;
00713 }
00714
00715
00716
00717
00718
00719
00720
00721 char*
00722 fluid_synth_error(fluid_synth_t* synth)
00723 {
00724 return fluid_error();
00725 }
00726
00727
00728
00729
00730 int
00731 fluid_synth_noteon(fluid_synth_t* synth, int chan, int key, int vel)
00732 {
00733 fluid_channel_t* channel;
00734 int r = FLUID_FAILED;
00735
00736
00737 if ((chan < 0) || (chan >= synth->midi_channels)) {
00738 FLUID_LOG(FLUID_WARN, "Channel out of range");
00739 return FLUID_FAILED;
00740 }
00741
00742
00743 if (vel == 0) {
00744 return fluid_synth_noteoff(synth, chan, key);
00745 }
00746
00747 channel = synth->channel[chan];
00748
00749
00750 if (channel->preset == NULL) {
00751 if (synth->verbose) {
00752 FLUID_LOG(FLUID_INFO, "noteon\t%d\t%d\t%d\t%05d\t%.3f\t%.3f\t%.3f\t%d\t%s",
00753 chan, key, vel, 0,
00754 (float) synth->ticks / 44100.0f,
00755 (fluid_curtime() - synth->start) / 1000.0f,
00756 0.0f, 0, "channel has no preset");
00757 }
00758 return FLUID_FAILED;
00759 }
00760
00761
00762
00763 fluid_synth_release_voice_on_same_note(synth, chan, key);
00764
00765 return fluid_synth_start(synth, synth->noteid++, channel->preset, 0, chan, key, vel);
00766 }
00767
00768
00769
00770
00771 int
00772 fluid_synth_noteoff(fluid_synth_t* synth, int chan, int key)
00773 {
00774 int i;
00775 fluid_voice_t* voice;
00776 int status = FLUID_FAILED;
00777
00778
00779
00780 for (i = 0; i < synth->polyphony; i++) {
00781 voice = synth->voice[i];
00782 if (_ON(voice) && (voice->chan == chan) && (voice->key == key)) {
00783 if (synth->verbose) {
00784 int used_voices = 0;
00785 int k;
00786 for (k = 0; k < synth->polyphony; k++) {
00787 if (!_AVAILABLE(synth->voice[k])) {
00788 used_voices++;
00789 }
00790 }
00791 FLUID_LOG(FLUID_INFO, "noteoff\t%d\t%d\t%d\t%05d\t%.3f\t%.3f\t%.3f\t%d",
00792 voice->chan, voice->key, 0, voice->id,
00793 (float) (voice->start_time + voice->ticks) / 44100.0f,
00794 (fluid_curtime() - synth->start) / 1000.0f,
00795 (float) voice->ticks / 44100.0f,
00796 used_voices);
00797 }
00798 fluid_voice_noteoff(voice);
00799 status = FLUID_OK;
00800 }
00801 }
00802 return status;
00803 }
00804
00805
00806
00807
00808 int
00809 fluid_synth_damp_voices(fluid_synth_t* synth, int chan)
00810 {
00811 int i;
00812 fluid_voice_t* voice;
00813
00814
00815
00816
00817 for (i = 0; i < synth->polyphony; i++) {
00818 voice = synth->voice[i];
00819 if ((voice->chan == chan) && _SUSTAINED(voice)) {
00820
00821 fluid_voice_noteoff(voice);
00822 }
00823 }
00824
00825 return FLUID_OK;
00826 }
00827
00828
00829
00830
00831 int
00832 fluid_synth_cc(fluid_synth_t* synth, int chan, int num, int val)
00833 {
00834
00835
00836
00837
00838 if ((chan < 0) || (chan >= synth->midi_channels)) {
00839 FLUID_LOG(FLUID_WARN, "Channel out of range");
00840 return FLUID_FAILED;
00841 }
00842 if ((num < 0) || (num >= 128)) {
00843 FLUID_LOG(FLUID_WARN, "Ctrl out of range");
00844 return FLUID_FAILED;
00845 }
00846 if ((val < 0) || (val >= 128)) {
00847 FLUID_LOG(FLUID_WARN, "Value out of range");
00848 return FLUID_FAILED;
00849 }
00850
00851 if (synth->verbose) {
00852 FLUID_LOG(FLUID_INFO, "cc\t%d\t%d\t%d", chan, num, val);
00853 }
00854
00855
00856 fluid_channel_cc(synth->channel[chan], num, val);
00857
00858 return FLUID_OK;
00859 }
00860
00861
00862
00863
00864 int
00865 fluid_synth_get_cc(fluid_synth_t* synth, int chan, int num, int* pval)
00866 {
00867
00868 if ((chan < 0) || (chan >= synth->midi_channels)) {
00869 FLUID_LOG(FLUID_WARN, "Channel out of range");
00870 return FLUID_FAILED;
00871 }
00872 if ((num < 0) || (num >= 128)) {
00873 FLUID_LOG(FLUID_WARN, "Ctrl out of range");
00874 return FLUID_FAILED;
00875 }
00876
00877 *pval = synth->channel[chan]->cc[num];
00878 return FLUID_OK;
00879 }
00880
00881
00882
00883
00884
00885
00886 int
00887 fluid_synth_all_notes_off(fluid_synth_t* synth, int chan)
00888 {
00889 int i;
00890 fluid_voice_t* voice;
00891
00892 for (i = 0; i < synth->polyphony; i++) {
00893 voice = synth->voice[i];
00894 if (_PLAYING(voice) && (voice->chan == chan)) {
00895 fluid_voice_noteoff(voice);
00896 }
00897 }
00898 return FLUID_OK;
00899 }
00900
00901
00902
00903
00904
00905
00906 int
00907 fluid_synth_all_sounds_off(fluid_synth_t* synth, int chan)
00908 {
00909 int i;
00910 fluid_voice_t* voice;
00911
00912 for (i = 0; i < synth->polyphony; i++) {
00913 voice = synth->voice[i];
00914 if (_PLAYING(voice) && (voice->chan == chan)) {
00915 fluid_voice_off(voice);
00916 }
00917 }
00918 return FLUID_OK;
00919 }
00920
00921
00922
00923
00924
00925
00926
00927 int
00928 fluid_synth_system_reset(fluid_synth_t* synth)
00929 {
00930 int i;
00931 fluid_voice_t* voice;
00932
00933 for (i = 0; i < synth->polyphony; i++) {
00934 voice = synth->voice[i];
00935 if (_PLAYING(voice)) {
00936 fluid_voice_off(voice);
00937 }
00938 }
00939
00940 for (i = 0; i < synth->midi_channels; i++) {
00941 fluid_channel_reset(synth->channel[i]);
00942 }
00943
00944 fluid_chorus_reset(synth->chorus);
00945 fluid_revmodel_reset(synth->reverb);
00946
00947 return FLUID_OK;
00948 }
00949
00950
00951
00952
00953
00954
00955
00956 int
00957 fluid_synth_modulate_voices(fluid_synth_t* synth, int chan, int is_cc, int ctrl)
00958 {
00959 int i;
00960 fluid_voice_t* voice;
00961
00962
00963
00964
00965 for (i = 0; i < synth->polyphony; i++) {
00966 voice = synth->voice[i];
00967 if (voice->chan == chan) {
00968 fluid_voice_modulate(voice, is_cc, ctrl);
00969 }
00970 }
00971 return FLUID_OK;
00972 }
00973
00974
00975
00976
00977
00978
00979
00980
00981 int
00982 fluid_synth_modulate_voices_all(fluid_synth_t* synth, int chan)
00983 {
00984 int i;
00985 fluid_voice_t* voice;
00986
00987
00988
00989
00990 for (i = 0; i < synth->polyphony; i++) {
00991 voice = synth->voice[i];
00992 if (voice->chan == chan) {
00993 fluid_voice_modulate_all(voice);
00994 }
00995 }
00996 return FLUID_OK;
00997 }
00998
00999
01000
01001
01002 int
01003 fluid_synth_pitch_bend(fluid_synth_t* synth, int chan, int val)
01004 {
01005
01006
01007
01008
01009
01010 if ((chan < 0) || (chan >= synth->midi_channels)) {
01011 FLUID_LOG(FLUID_WARN, "Channel out of range");
01012 return FLUID_FAILED;
01013 }
01014
01015 if (synth->verbose) {
01016 FLUID_LOG(FLUID_INFO, "pitchb\t%d\t%d", chan, val);
01017 }
01018
01019
01020 fluid_channel_pitch_bend(synth->channel[chan], val);
01021
01022 return FLUID_OK;
01023 }
01024
01025
01026
01027
01028 int
01029 fluid_synth_get_pitch_bend(fluid_synth_t* synth, int chan, int* ppitch_bend)
01030 {
01031
01032 if ((chan < 0) || (chan >= synth->midi_channels)) {
01033 FLUID_LOG(FLUID_WARN, "Channel out of range");
01034 return FLUID_FAILED;
01035 }
01036
01037 *ppitch_bend = synth->channel[chan]->pitch_bend;
01038 return FLUID_OK;
01039 }
01040
01041
01042
01043
01044 int
01045 fluid_synth_pitch_wheel_sens(fluid_synth_t* synth, int chan, int val)
01046 {
01047
01048
01049 if ((chan < 0) || (chan >= synth->midi_channels)) {
01050 FLUID_LOG(FLUID_WARN, "Channel out of range");
01051 return FLUID_FAILED;
01052 }
01053
01054 if (synth->verbose) {
01055 FLUID_LOG(FLUID_INFO, "pitchsens\t%d\t%d", chan, val);
01056 }
01057
01058
01059 fluid_channel_pitch_wheel_sens(synth->channel[chan], val);
01060
01061 return FLUID_OK;
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072 int
01073 fluid_synth_get_pitch_wheel_sens(fluid_synth_t* synth, int chan, int* pval)
01074 {
01075
01076
01077 if ((chan < 0) || (chan >= synth->midi_channels)) {
01078 FLUID_LOG(FLUID_WARN, "Channel out of range");
01079 return FLUID_FAILED;
01080 }
01081
01082
01083 *pval = synth->channel[chan]->pitch_wheel_sensitivity;
01084
01085 return FLUID_OK;
01086 }
01087
01088
01089
01090
01091 fluid_preset_t*
01092 fluid_synth_get_preset(fluid_synth_t* synth, unsigned int sfontnum,
01093 unsigned int banknum, unsigned int prognum)
01094 {
01095 fluid_preset_t* preset = NULL;
01096 fluid_sfont_t* sfont = NULL;
01097 fluid_list_t* list = synth->sfont;
01098 int offset;
01099
01100 sfont = fluid_synth_get_sfont_by_id(synth, sfontnum);
01101
01102 if (sfont != NULL) {
01103 offset = fluid_synth_get_bank_offset(synth, sfontnum);
01104 preset = fluid_sfont_get_preset(sfont, banknum - offset, prognum);
01105 if (preset != NULL) {
01106 return preset;
01107 }
01108 }
01109 return NULL;
01110 }
01111
01112
01113
01114
01115 fluid_preset_t*
01116 fluid_synth_get_preset2(fluid_synth_t* synth, char* sfont_name,
01117 unsigned int banknum, unsigned int prognum)
01118 {
01119 fluid_preset_t* preset = NULL;
01120 fluid_sfont_t* sfont = NULL;
01121 int offset;
01122
01123 sfont = fluid_synth_get_sfont_by_name(synth, sfont_name);
01124
01125 if (sfont != NULL) {
01126 offset = fluid_synth_get_bank_offset(synth, fluid_sfont_get_id(sfont));
01127 preset = fluid_sfont_get_preset(sfont, banknum - offset, prognum);
01128 if (preset != NULL) {
01129 return preset;
01130 }
01131 }
01132 return NULL;
01133 }
01134
01135 fluid_preset_t* fluid_synth_find_preset(fluid_synth_t* synth,
01136 unsigned int banknum,
01137 unsigned int prognum)
01138 {
01139 fluid_preset_t* preset = NULL;
01140 fluid_sfont_t* sfont = NULL;
01141 fluid_list_t* list = synth->sfont;
01142 int offset;
01143
01144 while (list) {
01145
01146 sfont = (fluid_sfont_t*) fluid_list_get(list);
01147 offset = fluid_synth_get_bank_offset(synth, fluid_sfont_get_id(sfont));
01148 preset = fluid_sfont_get_preset(sfont, banknum - offset, prognum);
01149
01150 if (preset != NULL) {
01151 preset->sfont = sfont;
01152 return preset;
01153 }
01154
01155 list = fluid_list_next(list);
01156
01157 }
01158 return NULL;
01159 }
01160
01161
01162
01163
01164
01165 int
01166 fluid_synth_program_change(fluid_synth_t* synth, int chan, int prognum)
01167 {
01168 fluid_preset_t* preset = NULL;
01169 fluid_channel_t* channel;
01170 unsigned int banknum;
01171 unsigned int sfont_id;
01172
01173
01174
01175
01176 if ((prognum >= 0) && (prognum < FLUID_NUM_PROGRAMS) &&
01177 (chan >= 0) && (chan < synth->midi_channels)) {
01178
01179 channel = synth->channel[chan];
01180 banknum = fluid_channel_get_banknum(channel);
01181
01182
01183 fluid_channel_set_prognum(channel, prognum);
01184
01185 if (synth->verbose) {
01186 FLUID_LOG(FLUID_INFO, "prog\t%d\t%d\t%d", chan, banknum, prognum);
01187 }
01188
01189
01190
01191 if (channel->channum == 9) {
01192
01193
01194 preset = fluid_synth_find_preset(synth, banknum | DRUM_INST_MASK, prognum);
01195
01196
01197 if (preset == NULL) {
01198 preset = fluid_synth_find_preset(synth, banknum, prognum);
01199 }
01200
01201 } else {
01202 preset = fluid_synth_find_preset(synth, banknum, prognum);
01203 }
01204
01205 sfont_id = preset? fluid_sfont_get_id(preset->sfont) : 0;
01206 fluid_channel_set_sfontnum(channel, sfont_id);
01207 fluid_channel_set_preset(channel, preset);
01208
01209 return FLUID_OK;
01210 }
01211
01212 FLUID_LOG(FLUID_ERR, "Index out of range (chan=%d, prog=%d)", chan, prognum);
01213 return FLUID_FAILED;
01214 }
01215
01216
01217
01218
01219 int fluid_synth_bank_select(fluid_synth_t* synth, int chan, unsigned int bank)
01220 {
01221 if ((chan >= 0) && (chan < synth->midi_channels)) {
01222 fluid_channel_set_banknum(synth->channel[chan], bank);
01223 return FLUID_OK;
01224 }
01225 return FLUID_FAILED;
01226 }
01227
01228
01229
01230
01231
01232 int fluid_synth_sfont_select(fluid_synth_t* synth, int chan, unsigned int sfont_id)
01233 {
01234 if ((chan >= 0) && (chan < synth->midi_channels)) {
01235 fluid_channel_set_sfontnum(synth->channel[chan], sfont_id);
01236 return FLUID_OK;
01237 }
01238 return FLUID_FAILED;
01239 }
01240
01241
01242
01243
01244 int
01245 fluid_synth_get_program(fluid_synth_t* synth, int chan,
01246 unsigned int* sfont_id, unsigned int* bank_num, unsigned int* preset_num)
01247 {
01248 fluid_channel_t* channel;
01249 if ((chan >= 0) && (chan < synth->midi_channels)) {
01250 channel = synth->channel[chan];
01251 *sfont_id = fluid_channel_get_sfontnum(channel);
01252 *bank_num = fluid_channel_get_banknum(channel);
01253 *preset_num = fluid_channel_get_prognum(channel);
01254 return FLUID_OK;
01255 }
01256 return FLUID_FAILED;
01257 }
01258
01259
01260
01261
01262 int fluid_synth_program_select(fluid_synth_t* synth,
01263 int chan,
01264 unsigned int sfont_id,
01265 unsigned int bank_num,
01266 unsigned int preset_num)
01267 {
01268 fluid_preset_t* preset = NULL;
01269 fluid_channel_t* channel;
01270
01271 if ((chan < 0) || (chan >= synth->midi_channels)) {
01272 FLUID_LOG(FLUID_ERR, "Channel number out of range (chan=%d)", chan);
01273 return FLUID_FAILED;
01274 }
01275 channel = synth->channel[chan];
01276
01277 preset = fluid_synth_get_preset(synth, sfont_id, bank_num, preset_num);
01278 if (preset == NULL) {
01279 FLUID_LOG(FLUID_ERR,
01280 "There is no preset with bank number %d and preset number %d in SoundFont %d",
01281 bank_num, preset_num, sfont_id);
01282 return FLUID_FAILED;
01283 }
01284
01285
01286 fluid_channel_set_sfontnum(channel, sfont_id);
01287 fluid_channel_set_banknum(channel, bank_num);
01288 fluid_channel_set_prognum(channel, preset_num);
01289
01290 fluid_channel_set_preset(channel, preset);
01291
01292 return FLUID_OK;
01293 }
01294
01295
01296
01297
01298 int fluid_synth_program_select2(fluid_synth_t* synth,
01299 int chan,
01300 char* sfont_name,
01301 unsigned int bank_num,
01302 unsigned int preset_num)
01303 {
01304 fluid_preset_t* preset = NULL;
01305 fluid_channel_t* channel;
01306 fluid_sfont_t* sfont = NULL;
01307 int offset;
01308
01309 if ((chan < 0) || (chan >= synth->midi_channels)) {
01310 FLUID_LOG(FLUID_ERR, "Channel number out of range (chan=%d)", chan);
01311 return FLUID_FAILED;
01312 }
01313 channel = synth->channel[chan];
01314
01315 sfont = fluid_synth_get_sfont_by_name(synth, sfont_name);
01316 if (sfont == NULL) {
01317 FLUID_LOG(FLUID_ERR, "Could not find SoundFont %s", sfont_name);
01318 return FLUID_FAILED;
01319 }
01320
01321 offset = fluid_synth_get_bank_offset(synth, fluid_sfont_get_id(sfont));
01322 preset = fluid_sfont_get_preset(sfont, bank_num - offset, preset_num);
01323 if (preset == NULL) {
01324 FLUID_LOG(FLUID_ERR,
01325 "There is no preset with bank number %d and preset number %d in SoundFont %s",
01326 bank_num, preset_num, sfont_name);
01327 return FLUID_FAILED;
01328 }
01329
01330
01331 fluid_channel_set_sfontnum(channel, fluid_sfont_get_id(sfont));
01332 fluid_channel_set_banknum(channel, bank_num);
01333 fluid_channel_set_prognum(channel, preset_num);
01334
01335 fluid_channel_set_preset(channel, preset);
01336
01337 return FLUID_OK;
01338 }
01339
01340
01341
01342
01343 void fluid_synth_update_presets(fluid_synth_t* synth)
01344 {
01345 int chan;
01346 fluid_channel_t* channel;
01347
01348 for (chan = 0; chan < synth->midi_channels; chan++) {
01349 channel = synth->channel[chan];
01350 fluid_channel_set_preset(channel,
01351 fluid_synth_get_preset(synth,
01352 fluid_channel_get_sfontnum(channel),
01353 fluid_channel_get_banknum(channel),
01354 fluid_channel_get_prognum(channel)));
01355 }
01356 }
01357
01358
01359
01360
01361
01362 int fluid_synth_update_gain(fluid_synth_t* synth, char* name, double value)
01363 {
01364 fluid_synth_set_gain(synth, (float) value);
01365 return 0;
01366 }
01367
01368
01369
01370
01371 void fluid_synth_set_gain(fluid_synth_t* synth, float gain)
01372 {
01373 int i;
01374
01375 fluid_clip(gain, 0.0f, 10.0f);
01376 synth->gain = gain;
01377
01378 for (i = 0; i < synth->polyphony; i++) {
01379 fluid_voice_t* voice = synth->voice[i];
01380 if (_PLAYING(voice)) {
01381 fluid_voice_set_gain(voice, gain);
01382 }
01383 }
01384 }
01385
01386
01387
01388
01389 float fluid_synth_get_gain(fluid_synth_t* synth)
01390 {
01391 return synth->gain;
01392 }
01393
01394
01395
01396
01397 int fluid_synth_update_polyphony(fluid_synth_t* synth, char* name, int value)
01398 {
01399 fluid_synth_set_polyphony(synth, value);
01400 return 0;
01401 }
01402
01403
01404
01405
01406 int fluid_synth_set_polyphony(fluid_synth_t* synth, int polyphony)
01407 {
01408 int i;
01409
01410 if (polyphony < 1 || polyphony > synth->nvoice) {
01411 return FLUID_FAILED;
01412 }
01413
01414
01415 for (i = polyphony; i < synth->nvoice; i++) {
01416 fluid_voice_t* voice = synth->voice[i];
01417 if (_PLAYING(voice)) {
01418 fluid_voice_off(voice);
01419 }
01420 }
01421
01422 synth->polyphony = polyphony;
01423
01424 return FLUID_OK;
01425 }
01426
01427
01428
01429
01430 int fluid_synth_get_polyphony(fluid_synth_t* synth)
01431 {
01432 return synth->polyphony;
01433 }
01434
01435
01436
01437
01438 int fluid_synth_get_internal_bufsize(fluid_synth_t* synth)
01439 {
01440 return FLUID_BUFSIZE;
01441 }
01442
01443
01444
01445
01446
01447
01448
01449 int
01450 fluid_synth_program_reset(fluid_synth_t* synth)
01451 {
01452 int i;
01453
01454 for (i = 0; i < synth->midi_channels; i++){
01455 fluid_synth_program_change(synth, i, fluid_channel_get_prognum(synth->channel[i]));
01456 }
01457 return FLUID_OK;
01458 }
01459
01460
01461
01462
01463 int fluid_synth_set_reverb_preset(fluid_synth_t* synth, int num)
01464 {
01465 int i = 0;
01466 while (revmodel_preset[i].name != NULL) {
01467 if (i == num) {
01468 fluid_revmodel_setroomsize(synth->reverb, revmodel_preset[i].roomsize);
01469 fluid_revmodel_setdamp(synth->reverb, revmodel_preset[i].damp);
01470 fluid_revmodel_setwidth(synth->reverb, revmodel_preset[i].width);
01471 fluid_revmodel_setlevel(synth->reverb, revmodel_preset[i].level);
01472 return FLUID_OK;
01473 }
01474 i++;
01475 }
01476 return FLUID_FAILED;
01477 }
01478
01479
01480
01481
01482 void fluid_synth_set_reverb(fluid_synth_t* synth, double roomsize, double damping,
01483 double width, double level)
01484 {
01485
01486
01487
01488 fluid_revmodel_setroomsize(synth->reverb, roomsize);
01489 fluid_revmodel_setdamp(synth->reverb, damping);
01490 fluid_revmodel_setwidth(synth->reverb, width);
01491 fluid_revmodel_setlevel(synth->reverb, level);
01492 }
01493
01494
01495
01496
01497 void fluid_synth_set_chorus(fluid_synth_t* synth, int nr, double level,
01498 double speed, double depth_ms, int type)
01499 {
01500
01501
01502
01503 fluid_chorus_set_nr(synth->chorus, nr);
01504 fluid_chorus_set_level(synth->chorus, (fluid_real_t)level);
01505 fluid_chorus_set_speed_Hz(synth->chorus, (fluid_real_t)speed);
01506 fluid_chorus_set_depth_ms(synth->chorus, (fluid_real_t)depth_ms);
01507 fluid_chorus_set_type(synth->chorus, type);
01508 fluid_chorus_update(synth->chorus);
01509 }
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563 int
01564 fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
01565 float** left, float** right,
01566 float** fx_left, float** fx_right)
01567 {
01568 fluid_real_t** left_in = synth->left_buf;
01569 fluid_real_t** right_in = synth->right_buf;
01570 fluid_real_t** fx_left_in = synth->fx_left_buf;
01571 fluid_real_t** fx_right_in = synth->fx_right_buf;
01572 double time = fluid_utime();
01573 int i, num, available, count, bytes;
01574
01575
01576 if (synth->state != FLUID_SYNTH_PLAYING) {
01577 return 0;
01578 }
01579
01580
01581 count = 0;
01582 num = synth->cur;
01583 if (synth->cur < FLUID_BUFSIZE) {
01584 available = FLUID_BUFSIZE - synth->cur;
01585
01586 num = (available > len)? len : available;
01587 bytes = num * sizeof(float);
01588
01589 for (i = 0; i < synth->audio_channels; i++) {
01590 FLUID_MEMCPY(left[i], left_in[i] + synth->cur, bytes);
01591 FLUID_MEMCPY(right[i], right_in[i] + synth->cur, bytes);
01592 }
01593 for (i = 0; i < synth->effects_channels; i++) {
01594 FLUID_MEMCPY(fx_left[i], fx_left_in[i] + synth->cur, bytes);
01595 FLUID_MEMCPY(fx_right[i], fx_right_in[i] + synth->cur, bytes);
01596 }
01597 count += num;
01598 num += synth->cur;
01599 }
01600
01601
01602 while (count < len) {
01603 fluid_synth_one_block(synth, 1);
01604
01605 num = (FLUID_BUFSIZE > len - count)? len - count : FLUID_BUFSIZE;
01606 bytes = num * sizeof(float);
01607
01608 for (i = 0; i < synth->audio_channels; i++) {
01609 FLUID_MEMCPY(left[i] + count, left_in[i], bytes);
01610 FLUID_MEMCPY(right[i] + count, right_in[i], bytes);
01611 }
01612 for (i = 0; i < synth->effects_channels; i++) {
01613 FLUID_MEMCPY(fx_left[i] + count, fx_left_in[i], bytes);
01614 FLUID_MEMCPY(fx_right[i] + count, fx_right_in[i], bytes);
01615 }
01616
01617 count += num;
01618 }
01619
01620 synth->cur = num;
01621
01622 time = fluid_utime() - time;
01623 synth->cpu_load = 0.5 * (synth->cpu_load +
01624 time * synth->sample_rate / len / 10000.0);
01625
01626
01627
01628 return 0;
01629 }
01630
01631 int fluid_synth_process(fluid_synth_t* synth, int len,
01632 int nin, float** in,
01633 int nout, float** out)
01634 {
01635 return fluid_synth_write_float(synth, len, out[0], 0, 1, out[1], 0, 1);
01636 }
01637
01638
01639
01640
01641
01642 int
01643 fluid_synth_write_float(fluid_synth_t* synth, int len,
01644 void* lout, int loff, int lincr,
01645 void* rout, int roff, int rincr)
01646 {
01647 int i, j, k, l;
01648 float* left_out = (float*) lout;
01649 float* right_out = (float*) rout;
01650 fluid_real_t* left_in = synth->left_buf[0];
01651 fluid_real_t* right_in = synth->right_buf[0];
01652 double time = fluid_utime();
01653
01654
01655 if (synth->state != FLUID_SYNTH_PLAYING) {
01656 return 0;
01657 }
01658
01659 l = synth->cur;
01660
01661 for (i = 0, j = loff, k = roff; i < len; i++, l++, j += lincr, k += rincr) {
01662
01663 if (l == FLUID_BUFSIZE) {
01664 fluid_synth_one_block(synth, 0);
01665 l = 0;
01666 }
01667
01668 left_out[j] = (float) left_in[l];
01669 right_out[k] = (float) right_in[l];
01670 }
01671
01672 synth->cur = l;
01673
01674 time = fluid_utime() - time;
01675 synth->cpu_load = 0.5 * (synth->cpu_load +
01676 time * synth->sample_rate / len / 10000.0);
01677
01678
01679
01680 return 0;
01681 }
01682
01683 #define DITHER_SIZE 48000
01684 #define DITHER_CHANNELS 2
01685
01686 static float rand_table[DITHER_CHANNELS][DITHER_SIZE];
01687
01688 static void init_dither(void)
01689 {
01690 float d, dp;
01691 int c, i;
01692
01693 for (c = 0; c < DITHER_CHANNELS; c++) {
01694 dp = 0;
01695 for (i = 0; i < DITHER_SIZE-1; i++) {
01696 d = rand() / (float)RAND_MAX - 0.5f;
01697 rand_table[c][i] = d - dp;
01698 dp = d;
01699 }
01700 rand_table[c][DITHER_SIZE-1] = 0 - dp;
01701 }
01702 }
01703
01704
01705 static inline int
01706 roundi (float x)
01707 {
01708 if (x >= 0.0f)
01709 return (int)(x+0.5f);
01710 else
01711 return (int)(x-0.5f);
01712 }
01713
01714
01715
01716
01717 int
01718 fluid_synth_write_s16(fluid_synth_t* synth, int len,
01719 void* lout, int loff, int lincr,
01720 void* rout, int roff, int rincr)
01721 {
01722 int i, j, k, cur;
01723 signed short* left_out = (signed short*) lout;
01724 signed short* right_out = (signed short*) rout;
01725 fluid_real_t* left_in = synth->left_buf[0];
01726 fluid_real_t* right_in = synth->right_buf[0];
01727 double prof_ref = fluid_profile_ref();
01728 fluid_real_t left_sample;
01729 fluid_real_t right_sample;
01730 double time = fluid_utime();
01731 int di = synth->dither_index;
01732 double prof_ref_on_block;
01733
01734
01735 if (synth->state != FLUID_SYNTH_PLAYING) {
01736 return 0;
01737 }
01738
01739 cur = synth->cur;
01740
01741 for (i = 0, j = loff, k = roff; i < len; i++, cur++, j += lincr, k += rincr) {
01742
01743
01744 if (cur == FLUID_BUFSIZE) {
01745 prof_ref_on_block = fluid_profile_ref();
01746
01747 fluid_synth_one_block(synth, 0);
01748 cur = 0;
01749
01750 fluid_profile(FLUID_PROF_ONE_BLOCK, prof_ref_on_block);
01751 }
01752
01753 left_sample = roundi (left_in[cur] * 32766.0f + rand_table[0][di]);
01754 right_sample = roundi (right_in[cur] * 32766.0f + rand_table[1][di]);
01755
01756 di++;
01757 if (di >= DITHER_SIZE) di = 0;
01758
01759
01760 if (left_sample > 32767.0f) left_sample = 32767.0f;
01761 if (left_sample < -32768.0f) left_sample = -32768.0f;
01762 if (right_sample > 32767.0f) right_sample = 32767.0f;
01763 if (right_sample < -32768.0f) right_sample = -32768.0f;
01764
01765 left_out[j] = (signed short) left_sample;
01766 right_out[k] = (signed short) right_sample;
01767 }
01768
01769 synth->cur = cur;
01770 synth->dither_index = di;
01771
01772 fluid_profile(FLUID_PROF_WRITE_S16, prof_ref);
01773
01774
01775 time = fluid_utime() - time;
01776 synth->cpu_load = 0.5 * (synth->cpu_load +
01777 time * synth->sample_rate / len / 10000.0);
01778
01779
01780
01781 return 0;
01782 }
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792 void
01793 fluid_synth_dither_s16(int *dither_index, int len, float* lin, float* rin,
01794 void* lout, int loff, int lincr,
01795 void* rout, int roff, int rincr)
01796 {
01797 int i, j, k;
01798 signed short* left_out = (signed short*) lout;
01799 signed short* right_out = (signed short*) rout;
01800 double prof_ref = fluid_profile_ref();
01801 fluid_real_t left_sample;
01802 fluid_real_t right_sample;
01803 int di = *dither_index;
01804
01805 for (i = 0, j = loff, k = roff; i < len; i++, j += lincr, k += rincr) {
01806
01807 left_sample = roundi (lin[i] * 32766.0f + rand_table[0][di]);
01808 right_sample = roundi (rin[i] * 32766.0f + rand_table[1][di]);
01809
01810 di++;
01811 if (di >= DITHER_SIZE) di = 0;
01812
01813
01814 if (left_sample > 32767.0f) left_sample = 32767.0f;
01815 if (left_sample < -32768.0f) left_sample = -32768.0f;
01816 if (right_sample > 32767.0f) right_sample = 32767.0f;
01817 if (right_sample < -32768.0f) right_sample = -32768.0f;
01818
01819 left_out[j] = (signed short) left_sample;
01820 right_out[k] = (signed short) right_sample;
01821 }
01822
01823 *dither_index = di;
01824
01825 fluid_profile(FLUID_PROF_WRITE_S16, prof_ref);
01826 }
01827
01828
01829
01830
01831 int
01832 fluid_synth_one_block(fluid_synth_t* synth, int do_not_mix_fx_to_out)
01833 {
01834 int i, auchan;
01835 fluid_voice_t* voice;
01836 fluid_real_t* left_buf;
01837 fluid_real_t* right_buf;
01838 fluid_real_t* reverb_buf;
01839 fluid_real_t* chorus_buf;
01840 int byte_size = FLUID_BUFSIZE * sizeof(fluid_real_t);
01841 double prof_ref = fluid_profile_ref();
01842
01843
01844
01845 fluid_check_fpe("??? Just starting up ???");
01846
01847
01848 for (i = 0; i < synth->nbuf; i++) {
01849 FLUID_MEMSET(synth->left_buf[i], 0, byte_size);
01850 FLUID_MEMSET(synth->right_buf[i], 0, byte_size);
01851 }
01852
01853 for (i = 0; i < synth->effects_channels; i++) {
01854 FLUID_MEMSET(synth->fx_left_buf[i], 0, byte_size);
01855 FLUID_MEMSET(synth->fx_right_buf[i], 0, byte_size);
01856 }
01857
01858
01859
01860
01861
01862 reverb_buf = synth->with_reverb ? synth->fx_left_buf[0] : NULL;
01863 chorus_buf = synth->with_chorus ? synth->fx_left_buf[1] : NULL;
01864
01865 fluid_profile(FLUID_PROF_ONE_BLOCK_CLEAR, prof_ref);
01866
01867
01868 for (i = 0; i < synth->polyphony; i++) {
01869 voice = synth->voice[i];
01870
01871 if (_PLAYING(voice)) {
01872 double prof_ref_voice = fluid_profile_ref();
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886 auchan = fluid_channel_get_num(fluid_voice_get_channel(voice));
01887 auchan %= synth->audio_groups;
01888 left_buf = synth->left_buf[auchan];
01889 right_buf = synth->right_buf[auchan];
01890
01891 fluid_voice_write(voice, left_buf, right_buf, reverb_buf, chorus_buf);
01892
01893 fluid_profile(FLUID_PROF_ONE_BLOCK_VOICE, prof_ref_voice);
01894 }
01895 }
01896
01897 fluid_check_fpe("Synthesis processes");
01898
01899 fluid_profile(FLUID_PROF_ONE_BLOCK_VOICES, prof_ref);
01900
01901
01902
01903
01904
01905 if (do_not_mix_fx_to_out) {
01906
01907
01908 if (reverb_buf) {
01909 fluid_revmodel_processreplace(synth->reverb, reverb_buf,
01910 synth->fx_left_buf[0], synth->fx_right_buf[0]);
01911 fluid_check_fpe("Reverb");
01912 }
01913
01914 fluid_profile(FLUID_PROF_ONE_BLOCK_REVERB, prof_ref);
01915
01916
01917 if (chorus_buf) {
01918 fluid_chorus_processreplace(synth->chorus, chorus_buf,
01919 synth->fx_left_buf[1], synth->fx_right_buf[1]);
01920 fluid_check_fpe("Chorus");
01921 }
01922
01923 } else {
01924
01925
01926 if (reverb_buf) {
01927 fluid_revmodel_processmix(synth->reverb, reverb_buf,
01928 synth->left_buf[0], synth->right_buf[0]);
01929 fluid_check_fpe("Reverb");
01930 }
01931
01932 fluid_profile(FLUID_PROF_ONE_BLOCK_REVERB, prof_ref);
01933
01934
01935 if (chorus_buf) {
01936 fluid_chorus_processmix(synth->chorus, chorus_buf,
01937 synth->left_buf[0], synth->right_buf[0]);
01938 fluid_check_fpe("Chorus");
01939 }
01940 }
01941
01942 fluid_profile(FLUID_PROF_ONE_BLOCK_CHORUS, prof_ref);
01943
01944 #ifdef LADSPA
01945
01946 fluid_LADSPA_run(synth->LADSPA_FxUnit, synth->left_buf, synth->right_buf, synth->fx_left_buf, synth->fx_right_buf);
01947 fluid_check_fpe("LADSPA");
01948 #endif
01949
01950 synth->ticks += FLUID_BUFSIZE;
01951
01952
01953 #if 0
01954 {float num=1;while (num != 0){num*=0.5;};};
01955 #endif
01956 fluid_check_fpe("??? Remainder of synth_one_block ???");
01957
01958
01959
01960 return 0;
01961 }
01962
01963
01964
01965
01966
01967
01968
01969
01970 fluid_voice_t*
01971 fluid_synth_free_voice_by_kill(fluid_synth_t* synth)
01972 {
01973 int i;
01974 fluid_real_t best_prio = 999999.;
01975 fluid_real_t this_voice_prio;
01976 fluid_voice_t* voice;
01977 int best_voice_index=-1;
01978
01979
01980
01981
01982 for (i = 0; i < synth->polyphony; i++) {
01983
01984 voice = synth->voice[i];
01985
01986
01987 if (_AVAILABLE(voice)) {
01988 return voice;
01989 }
01990
01991
01992
01993 this_voice_prio = 10000.;
01994
01995
01996
01997
01998
01999
02000
02001 if (voice->chan == 9){
02002 this_voice_prio += 4000;
02003
02004 } else if (_RELEASED(voice)){
02005
02006
02007
02008 this_voice_prio -= 2000.;
02009 }
02010
02011 if (_SUSTAINED(voice)){
02012
02013
02014
02015
02016
02017
02018 this_voice_prio -= 1000;
02019 }
02020
02021
02022
02023
02024
02025
02026
02027 this_voice_prio -= (synth->noteid - fluid_voice_get_id(voice));
02028
02029
02030 if (voice->volenv_section != FLUID_VOICE_ENVATTACK){
02031 this_voice_prio += voice->volenv_val * 1000.;
02032 }
02033
02034
02035 if (this_voice_prio < best_prio)
02036 best_voice_index = i,
02037 best_prio = this_voice_prio;
02038 }
02039
02040 if (best_voice_index < 0) {
02041 return NULL;
02042 }
02043
02044 voice = synth->voice[best_voice_index];
02045 fluid_voice_off(voice);
02046
02047 return voice;
02048 }
02049
02050
02051
02052
02053 fluid_voice_t*
02054 fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan, int key, int vel)
02055 {
02056 int i, k;
02057 fluid_voice_t* voice = NULL;
02058 fluid_channel_t* channel = NULL;
02059
02060
02061
02062
02063
02064 for (i = 0; i < synth->polyphony; i++) {
02065 if (_AVAILABLE(synth->voice[i])) {
02066 voice = synth->voice[i];
02067 break;
02068 }
02069 }
02070
02071
02072 if (voice == NULL) {
02073 voice = fluid_synth_free_voice_by_kill(synth);
02074 }
02075
02076 if (voice == NULL) {
02077 FLUID_LOG(FLUID_WARN, "Failed to allocate a synthesis process. (chan=%d,key=%d)", chan, key);
02078 return NULL;
02079 }
02080
02081 if (synth->verbose) {
02082 k = 0;
02083 for (i = 0; i < synth->polyphony; i++) {
02084 if (!_AVAILABLE(synth->voice[i])) {
02085 k++;
02086 }
02087 }
02088
02089 FLUID_LOG(FLUID_INFO, "noteon\t%d\t%d\t%d\t%05d\t%.3f\t%.3f\t%.3f\t%d",
02090 chan, key, vel, synth->storeid,
02091 (float) synth->ticks / 44100.0f,
02092 (fluid_curtime() - synth->start) / 1000.0f,
02093 0.0f,
02094 k);
02095 }
02096
02097 if (chan >= 0) {
02098 channel = synth->channel[chan];
02099 }
02100
02101 if (fluid_voice_init(voice, sample, channel, key, vel,
02102 synth->storeid, synth->ticks, synth->gain) != FLUID_OK) {
02103 FLUID_LOG(FLUID_WARN, "Failed to initialize voice");
02104 return NULL;
02105 }
02106
02107
02108 fluid_voice_add_mod(voice, &default_vel2att_mod, FLUID_VOICE_DEFAULT);
02109 fluid_voice_add_mod(voice, &default_vel2filter_mod, FLUID_VOICE_DEFAULT);
02110 fluid_voice_add_mod(voice, &default_at2viblfo_mod, FLUID_VOICE_DEFAULT);
02111 fluid_voice_add_mod(voice, &default_mod2viblfo_mod, FLUID_VOICE_DEFAULT);
02112 fluid_voice_add_mod(voice, &default_att_mod, FLUID_VOICE_DEFAULT);
02113 fluid_voice_add_mod(voice, &default_pan_mod, FLUID_VOICE_DEFAULT);
02114 fluid_voice_add_mod(voice, &default_expr_mod, FLUID_VOICE_DEFAULT);
02115 fluid_voice_add_mod(voice, &default_reverb_mod, FLUID_VOICE_DEFAULT);
02116 fluid_voice_add_mod(voice, &default_chorus_mod, FLUID_VOICE_DEFAULT);
02117 fluid_voice_add_mod(voice, &default_pitch_bend_mod, FLUID_VOICE_DEFAULT);
02118
02119 return voice;
02120 }
02121
02122
02123
02124
02125 void fluid_synth_kill_by_exclusive_class(fluid_synth_t* synth, fluid_voice_t* new_voice)
02126 {
02137 int i;
02138 int excl_class = _GEN(new_voice,GEN_EXCLUSIVECLASS);
02139
02140
02141
02142
02143
02144 if (excl_class == 0) {
02145 return;
02146 }
02147
02148
02149
02150
02151
02152 for (i = 0; i < synth->polyphony; i++) {
02153 fluid_voice_t* existing_voice = synth->voice[i];
02154
02155
02156 if (!_PLAYING(existing_voice)) {
02157 continue;
02158 }
02159
02160
02161
02162 if (existing_voice->chan != new_voice->chan) {
02163 continue;
02164 }
02165
02166
02167 if ((int)_GEN(existing_voice, GEN_EXCLUSIVECLASS) != excl_class) {
02168 continue;
02169 }
02170
02171
02172
02173 if (fluid_voice_get_id(existing_voice) == fluid_voice_get_id(new_voice)) {
02174 continue;
02175 }
02176
02177
02178
02179
02180 fluid_voice_kill_excl(existing_voice);
02181 };
02182 };
02183
02184
02185
02186
02187 void fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t* voice)
02188 {
02189
02190
02191
02192
02193
02194
02195 fluid_synth_kill_by_exclusive_class(synth, voice);
02196
02197
02198
02199 fluid_voice_start(voice);
02200 }
02201
02202
02203
02204
02205 void fluid_synth_add_sfloader(fluid_synth_t* synth, fluid_sfloader_t* loader)
02206 {
02207 synth->loaders = fluid_list_prepend(synth->loaders, loader);
02208 }
02209
02210
02211
02212
02213
02214 int
02215 fluid_synth_sfload(fluid_synth_t* synth, const char* filename, int reset_presets)
02216 {
02217 fluid_sfont_t* sfont;
02218 fluid_list_t* list;
02219 fluid_sfloader_t* loader;
02220
02221 #if defined(MACOS9)
02222 fluid_synth_sfunload_macos9(synth);
02223 #endif
02224
02225 if (filename == NULL) {
02226 FLUID_LOG(FLUID_ERR, "Invalid filename");
02227 return FLUID_FAILED;
02228 }
02229
02230 for (list = synth->loaders; list; list = fluid_list_next(list)) {
02231 loader = (fluid_sfloader_t*) fluid_list_get(list);
02232
02233 sfont = fluid_sfloader_load(loader, filename);
02234
02235 if (sfont != NULL) {
02236
02237 sfont->id = ++synth->sfont_id;
02238
02239
02240 synth->sfont = fluid_list_prepend(synth->sfont, sfont);
02241
02242
02243 if (reset_presets) {
02244 fluid_synth_program_reset(synth);
02245 }
02246
02247 return (int) sfont->id;
02248 }
02249 }
02250
02251 FLUID_LOG(FLUID_ERR, "Failed to load SoundFont \"%s\"", filename);
02252 return -1;
02253 }
02254
02255
02256
02257
02258 static int fluid_synth_sfunload_callback(void* data, unsigned int msec)
02259 {
02260 fluid_sfont_t* sfont = (fluid_sfont_t*) data;
02261 int r = delete_fluid_sfont(sfont);
02262 if (r == 0) {
02263 FLUID_LOG(FLUID_DBG,"Unloaded SoundFont");
02264 }
02265 return r != 0;
02266 }
02267
02268
02269
02270
02271 void fluid_synth_sfunload_macos9(fluid_synth_t* synth)
02272 {
02273 #if defined(MACOS9)
02274 fluid_list_t *list, *next;
02275 fluid_sfont_t* sfont;
02276
02277 list = synth->unloading;
02278 while (list) {
02279 next = fluid_list_next(list);
02280 sfont = (fluid_sfont_t*) fluid_list_get(list);
02281 if (delete_fluid_sfont(sfont) == 0) {
02282 synth->unloading = fluid_list_remove(synth->unloading, sfont);
02283 }
02284 list = next;
02285 }
02286 #endif
02287 }
02288
02289
02290
02291
02292 int
02293 fluid_synth_sfunload(fluid_synth_t* synth, unsigned int id, int reset_presets)
02294 {
02295 fluid_sfont_t* sfont = fluid_synth_get_sfont_by_id(synth, id);
02296
02297 #if defined(MACOS9)
02298 fluid_synth_sfunload_macos9(synth);
02299 #endif
02300
02301 if (!sfont) {
02302 FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", id);
02303 return FLUID_FAILED;
02304 }
02305
02306
02307 synth->sfont = fluid_list_remove(synth->sfont, sfont);
02308
02309
02310 if (reset_presets) {
02311 fluid_synth_program_reset(synth);
02312 } else {
02313 fluid_synth_update_presets(synth);
02314 }
02315
02316 if (delete_fluid_sfont(sfont) != 0) {
02317 #if defined(MACOS9)
02318 synth->unloading = fluid_list_prepend(synth->unloading, sfont);
02319 #else
02320
02321 new_fluid_timer(100, fluid_synth_sfunload_callback, sfont, 1, 1);
02322 #endif
02323 }
02324
02325 return FLUID_OK;
02326 }
02327
02328
02329
02330
02331 int fluid_synth_sfreload(fluid_synth_t* synth, unsigned int id)
02332 {
02333 char filename[1024];
02334 fluid_sfont_t* sfont;
02335 int index = 0;
02336 fluid_list_t *list;
02337 fluid_sfloader_t* loader;
02338
02339
02340 sfont = fluid_synth_get_sfont_by_id(synth, id);
02341 if (!sfont) {
02342 FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", id);
02343 return FLUID_FAILED;
02344 }
02345
02346
02347 list = synth->sfont;
02348 while (list) {
02349 if (sfont == (fluid_sfont_t*) fluid_list_get(list)) {
02350 break;
02351 }
02352 list = fluid_list_next(list);
02353 index++;
02354 }
02355
02356
02357 FLUID_STRCPY(filename, fluid_sfont_get_name(sfont));
02358
02359 if (fluid_synth_sfunload(synth, id, 0) != FLUID_OK) {
02360 return FLUID_FAILED;
02361 }
02362
02363 for (list = synth->loaders; list; list = fluid_list_next(list)) {
02364 loader = (fluid_sfloader_t*) fluid_list_get(list);
02365
02366 sfont = fluid_sfloader_load(loader, filename);
02367
02368 if (sfont != NULL) {
02369
02370 sfont->id = id;
02371
02372
02373 synth->sfont = fluid_list_insert_at(synth->sfont, index, sfont);
02374
02375
02376 fluid_synth_update_presets(synth);
02377
02378 return sfont->id;
02379 }
02380 }
02381
02382 FLUID_LOG(FLUID_ERR, "Failed to load SoundFont \"%s\"", filename);
02383 return -1;
02384 }
02385
02386
02387
02388
02389
02390 int fluid_synth_add_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont)
02391 {
02392 sfont->id = ++synth->sfont_id;
02393
02394
02395 synth->sfont = fluid_list_prepend(synth->sfont, sfont);
02396
02397
02398 fluid_synth_program_reset(synth);
02399
02400 return sfont->id;
02401 }
02402
02403
02404
02405
02406
02407 void fluid_synth_remove_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont)
02408 {
02409 int sfont_id = fluid_sfont_get_id(sfont);
02410
02411 synth->sfont = fluid_list_remove(synth->sfont, sfont);
02412
02413
02414 fluid_synth_remove_bank_offset(synth, sfont_id);
02415
02416
02417 fluid_synth_program_reset(synth);
02418 }
02419
02420
02421
02422
02423
02424
02425 int
02426 fluid_synth_sfcount(fluid_synth_t* synth)
02427 {
02428 return fluid_list_size(synth->sfont);
02429 }
02430
02431
02432
02433
02434
02435 fluid_sfont_t*
02436 fluid_synth_get_sfont(fluid_synth_t* synth, unsigned int num)
02437 {
02438 return (fluid_sfont_t*) fluid_list_get(fluid_list_nth(synth->sfont, num));
02439 }
02440
02441
02442
02443
02444 fluid_sfont_t* fluid_synth_get_sfont_by_id(fluid_synth_t* synth, unsigned int id)
02445 {
02446 fluid_list_t* list = synth->sfont;
02447 fluid_sfont_t* sfont;
02448
02449 while (list) {
02450 sfont = (fluid_sfont_t*) fluid_list_get(list);
02451 if (fluid_sfont_get_id(sfont) == id) {
02452 return sfont;
02453 }
02454 list = fluid_list_next(list);
02455 }
02456 return NULL;
02457 }
02458
02459
02460
02461
02462 fluid_sfont_t* fluid_synth_get_sfont_by_name(fluid_synth_t* synth, char *name)
02463 {
02464 fluid_list_t* list = synth->sfont;
02465 fluid_sfont_t* sfont;
02466
02467 while (list) {
02468 sfont = (fluid_sfont_t*) fluid_list_get(list);
02469 if (FLUID_STRCMP(fluid_sfont_get_name(sfont), name) == 0) {
02470 return sfont;
02471 }
02472 list = fluid_list_next(list);
02473 }
02474 return NULL;
02475 }
02476
02477
02478
02479
02480 fluid_preset_t*
02481 fluid_synth_get_channel_preset(fluid_synth_t* synth, int chan)
02482 {
02483 if ((chan >= 0) && (chan < synth->midi_channels)) {
02484 return fluid_channel_get_preset(synth->channel[chan]);
02485 }
02486
02487 return NULL;
02488 }
02489
02490
02491
02492
02493 void
02494 fluid_synth_get_voicelist(fluid_synth_t* synth, fluid_voice_t* buf[], int bufsize, int ID)
02495 {
02496 int i;
02497 int count = 0;
02498 for (i = 0; i < synth->polyphony; i++) {
02499 fluid_voice_t* voice = synth->voice[i];
02500 if (count >= bufsize) {
02501 return;
02502 }
02503
02504 if (_PLAYING(voice) && ((int)voice->id == ID || ID < 0)) {
02505 buf[count++] = voice;
02506 }
02507 }
02508 if (count >= bufsize) {
02509 return;
02510 }
02511 buf[count++] = NULL;
02512 }
02513
02514
02515
02516 void fluid_synth_set_reverb_on(fluid_synth_t* synth, int on)
02517 {
02518 synth->with_reverb = on;
02519 }
02520
02521
02522
02523 void fluid_synth_set_chorus_on(fluid_synth_t* synth, int on)
02524 {
02525 synth->with_chorus = on;
02526 }
02527
02528
02529
02530 int fluid_synth_get_chorus_nr(fluid_synth_t* synth)
02531 {
02532 return fluid_chorus_get_nr(synth->chorus);
02533 }
02534
02535 double fluid_synth_get_chorus_level(fluid_synth_t* synth)
02536 {
02537 return (double)fluid_chorus_get_level(synth->chorus);
02538 }
02539
02540 double fluid_synth_get_chorus_speed_Hz(fluid_synth_t* synth)
02541 {
02542 return (double)fluid_chorus_get_speed_Hz(synth->chorus);
02543 }
02544
02545 double fluid_synth_get_chorus_depth_ms(fluid_synth_t* synth)
02546 {
02547 return (double)fluid_chorus_get_depth_ms(synth->chorus);
02548 }
02549
02550 int fluid_synth_get_chorus_type(fluid_synth_t* synth)
02551 {
02552 return fluid_chorus_get_type(synth->chorus);
02553 }
02554
02555
02556
02557 double fluid_synth_get_reverb_roomsize(fluid_synth_t* synth)
02558 {
02559 return (double)fluid_revmodel_getroomsize(synth->reverb);
02560 }
02561
02562 double fluid_synth_get_reverb_damp(fluid_synth_t* synth)
02563 {
02564 return (double) fluid_revmodel_getdamp(synth->reverb);
02565 }
02566
02567 double fluid_synth_get_reverb_level(fluid_synth_t* synth)
02568 {
02569 return (double) fluid_revmodel_getlevel(synth->reverb);
02570 }
02571
02572 double fluid_synth_get_reverb_width(fluid_synth_t* synth)
02573 {
02574 return (double) fluid_revmodel_getwidth(synth->reverb);
02575 }
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587 void fluid_synth_release_voice_on_same_note(fluid_synth_t* synth, int chan, int key){
02588 int i;
02589 fluid_voice_t* voice;
02590
02591
02592
02593
02594 for (i = 0; i < synth->polyphony; i++) {
02595 voice = synth->voice[i];
02596 if (_PLAYING(voice)
02597 && (voice->chan == chan)
02598 && (voice->key == key)
02599 && (fluid_voice_get_id(voice) != synth->noteid)) {
02600 fluid_voice_noteoff(voice);
02601 }
02602 }
02603 }
02604
02605
02606
02607
02608
02609 int fluid_synth_set_interp_method(fluid_synth_t* synth, int chan, int interp_method){
02610 int i;
02611 for (i = 0; i < synth->midi_channels; i++) {
02612 if (synth->channel[i] == NULL){
02613 FLUID_LOG(FLUID_ERR, "Channels don't exist (yet)!");
02614 return FLUID_FAILED;
02615 };
02616 if (chan < 0 || fluid_channel_get_num(synth->channel[i]) == chan){
02617 fluid_channel_set_interp_method(synth->channel[i], interp_method);
02618 };
02619 };
02620 return FLUID_OK;
02621 };
02622
02623
02624
02625
02626 int
02627 fluid_synth_count_midi_channels(fluid_synth_t* synth)
02628 {
02629 return synth->midi_channels;
02630 }
02631
02632
02633
02634
02635 int
02636 fluid_synth_count_audio_channels(fluid_synth_t* synth)
02637 {
02638 return synth->audio_channels;
02639 }
02640
02641
02642
02643
02644 int
02645 fluid_synth_count_audio_groups(fluid_synth_t* synth)
02646 {
02647 return synth->audio_groups;
02648 }
02649
02650
02651
02652
02653 int
02654 fluid_synth_count_effects_channels(fluid_synth_t* synth)
02655 {
02656 return synth->effects_channels;
02657 }
02658
02659 double fluid_synth_get_cpu_load(fluid_synth_t* synth)
02660 {
02661 return synth->cpu_load;
02662 }
02663
02664 static fluid_tuning_t*
02665 fluid_synth_get_tuning(fluid_synth_t* synth, int bank, int prog)
02666 {
02667 if ((bank < 0) || (bank >= 128)) {
02668 FLUID_LOG(FLUID_WARN, "Bank number out of range");
02669 return NULL;
02670 }
02671 if ((prog < 0) || (prog >= 128)) {
02672 FLUID_LOG(FLUID_WARN, "Program number out of range");
02673 return NULL;
02674 }
02675 if ((synth->tuning == NULL) ||
02676 (synth->tuning[bank] == NULL) ||
02677 (synth->tuning[bank][prog] == NULL)) {
02678 FLUID_LOG(FLUID_WARN, "No tuning at bank %d, prog %d", bank, prog);
02679 return NULL;
02680 }
02681 return synth->tuning[bank][prog];
02682 }
02683
02684 static fluid_tuning_t*
02685 fluid_synth_create_tuning(fluid_synth_t* synth, int bank, int prog, char* name)
02686 {
02687 if ((bank < 0) || (bank >= 128)) {
02688 FLUID_LOG(FLUID_WARN, "Bank number out of range");
02689 return NULL;
02690 }
02691 if ((prog < 0) || (prog >= 128)) {
02692 FLUID_LOG(FLUID_WARN, "Program number out of range");
02693 return NULL;
02694 }
02695 if (synth->tuning == NULL) {
02696 synth->tuning = FLUID_ARRAY(fluid_tuning_t**, 128);
02697 if (synth->tuning == NULL) {
02698 FLUID_LOG(FLUID_PANIC, "Out of memory");
02699 return NULL;
02700 }
02701 FLUID_MEMSET(synth->tuning, 0, 128 * sizeof(fluid_tuning_t**));
02702 }
02703
02704 if (synth->tuning[bank] == NULL) {
02705 synth->tuning[bank] = FLUID_ARRAY(fluid_tuning_t*, 128);
02706 if (synth->tuning[bank] == NULL) {
02707 FLUID_LOG(FLUID_PANIC, "Out of memory");
02708 return NULL;
02709 }
02710 FLUID_MEMSET(synth->tuning[bank], 0, 128 * sizeof(fluid_tuning_t*));
02711 }
02712
02713 if (synth->tuning[bank][prog] == NULL) {
02714 synth->tuning[bank][prog] = new_fluid_tuning(name, bank, prog);
02715 if (synth->tuning[bank][prog] == NULL) {
02716 return NULL;
02717 }
02718 }
02719
02720 if ((fluid_tuning_get_name(synth->tuning[bank][prog]) == NULL)
02721 || (FLUID_STRCMP(fluid_tuning_get_name(synth->tuning[bank][prog]), name) != 0)) {
02722 fluid_tuning_set_name(synth->tuning[bank][prog], name);
02723 }
02724
02725 return synth->tuning[bank][prog];
02726 }
02727
02728 int fluid_synth_create_key_tuning(fluid_synth_t* synth,
02729 int bank, int prog,
02730 char* name, double* pitch)
02731 {
02732 fluid_tuning_t* tuning = fluid_synth_create_tuning(synth, bank, prog, name);
02733 if (tuning == NULL) {
02734 return FLUID_FAILED;
02735 }
02736 if (pitch) {
02737 fluid_tuning_set_all(tuning, pitch);
02738 }
02739 return FLUID_OK;
02740 }
02741
02742
02743 int fluid_synth_create_octave_tuning(fluid_synth_t* synth,
02744 int bank, int prog,
02745 char* name, double* pitch)
02746 {
02747 fluid_tuning_t* tuning = fluid_synth_create_tuning(synth, bank, prog, name);
02748 if (tuning == NULL) {
02749 return FLUID_FAILED;
02750 }
02751 fluid_tuning_set_octave(tuning, pitch);
02752 return FLUID_OK;
02753 }
02754
02755 int fluid_synth_tune_notes(fluid_synth_t* synth, int bank, int prog,
02756 int len, int *key, double* pitch, int apply)
02757 {
02758 fluid_tuning_t* tuning = fluid_synth_get_tuning(synth, bank, prog);
02759 int i;
02760
02761 if (tuning == NULL) {
02762 return FLUID_FAILED;
02763 }
02764
02765 for (i = 0; i < len; i++) {
02766 fluid_tuning_set_pitch(tuning, key[i], pitch[i]);
02767 }
02768
02769 return FLUID_OK;
02770 }
02771
02772 int fluid_synth_select_tuning(fluid_synth_t* synth, int chan,
02773 int bank, int prog)
02774 {
02775 fluid_tuning_t* tuning = fluid_synth_get_tuning(synth, bank, prog);
02776
02777 if (tuning == NULL) {
02778 return FLUID_FAILED;
02779 }
02780 if ((chan < 0) || (chan >= synth->midi_channels)) {
02781 FLUID_LOG(FLUID_WARN, "Channel out of range");
02782 return FLUID_FAILED;
02783 }
02784
02785 fluid_channel_set_tuning(synth->channel[chan], synth->tuning[bank][prog]);
02786
02787 return FLUID_OK;
02788 }
02789
02790 int fluid_synth_reset_tuning(fluid_synth_t* synth, int chan)
02791 {
02792 if ((chan < 0) || (chan >= synth->midi_channels)) {
02793 FLUID_LOG(FLUID_WARN, "Channel out of range");
02794 return FLUID_FAILED;
02795 }
02796
02797 fluid_channel_set_tuning(synth->channel[chan], NULL);
02798
02799 return FLUID_OK;
02800 }
02801
02802 void fluid_synth_tuning_iteration_start(fluid_synth_t* synth)
02803 {
02804 synth->cur_tuning = NULL;
02805 }
02806
02807 int fluid_synth_tuning_iteration_next(fluid_synth_t* synth, int* bank, int* prog)
02808 {
02809 int b = 0, p = 0;
02810
02811 if (synth->tuning == NULL) {
02812 return 0;
02813 }
02814
02815 if (synth->cur_tuning != NULL) {
02816
02817 b = fluid_tuning_get_bank(synth->cur_tuning);
02818 p = 1 + fluid_tuning_get_prog(synth->cur_tuning);
02819 if (p >= 128) {
02820 p = 0;
02821 b++;
02822 }
02823 }
02824
02825 while (b < 128) {
02826 if (synth->tuning[b] != NULL) {
02827 while (p < 128) {
02828 if (synth->tuning[b][p] != NULL) {
02829 synth->cur_tuning = synth->tuning[b][p];
02830 *bank = b;
02831 *prog = p;
02832 return 1;
02833 }
02834 p++;
02835 }
02836 }
02837 p = 0;
02838 b++;
02839 }
02840
02841 return 0;
02842 }
02843
02844 int fluid_synth_tuning_dump(fluid_synth_t* synth, int bank, int prog,
02845 char* name, int len, double* pitch)
02846 {
02847 fluid_tuning_t* tuning = fluid_synth_get_tuning(synth, bank, prog);
02848
02849 if (tuning == NULL) {
02850 return FLUID_FAILED;
02851 }
02852
02853 if (name) {
02854 snprintf(name, len - 1, "%s", fluid_tuning_get_name(tuning));
02855 name[len - 1] = 0;
02856 }
02857 if (pitch) {
02858 FLUID_MEMCPY(pitch, fluid_tuning_get_all(tuning), 128 * sizeof(double));
02859 }
02860
02861 return FLUID_OK;
02862 }
02863
02864 fluid_settings_t* fluid_synth_get_settings(fluid_synth_t* synth)
02865 {
02866 return synth->settings;
02867 }
02868
02869 int fluid_synth_setstr(fluid_synth_t* synth, char* name, char* str)
02870 {
02871 return fluid_settings_setstr(synth->settings, name, str);
02872 }
02873
02874 int fluid_synth_getstr(fluid_synth_t* synth, char* name, char** str)
02875 {
02876 return fluid_settings_getstr(synth->settings, name, str);
02877 }
02878
02879 int fluid_synth_setnum(fluid_synth_t* synth, char* name, double val)
02880 {
02881 return fluid_settings_setnum(synth->settings, name, val);
02882 }
02883
02884 int fluid_synth_getnum(fluid_synth_t* synth, char* name, double* val)
02885 {
02886 return fluid_settings_getnum(synth->settings, name, val);
02887 }
02888
02889 int fluid_synth_setint(fluid_synth_t* synth, char* name, int val)
02890 {
02891 return fluid_settings_setint(synth->settings, name, val);
02892 }
02893
02894 int fluid_synth_getint(fluid_synth_t* synth, char* name, int* val)
02895 {
02896 return fluid_settings_getint(synth->settings, name, val);
02897 }
02898
02899 int
02900 fluid_synth_set_gen(fluid_synth_t* synth, int chan, int param, float value)
02901 {
02902 int i;
02903 fluid_voice_t* voice;
02904
02905 if ((chan < 0) || (chan >= synth->midi_channels)) {
02906 FLUID_LOG(FLUID_WARN, "Channel out of range");
02907 return FLUID_FAILED;
02908 }
02909
02910 if ((param < 0) || (param >= GEN_LAST)) {
02911 FLUID_LOG(FLUID_WARN, "Parameter number out of range");
02912 return FLUID_FAILED;
02913 }
02914
02915 fluid_channel_set_gen(synth->channel[chan], param, value, 0);
02916
02917 for (i = 0; i < synth->polyphony; i++) {
02918 voice = synth->voice[i];
02919 if (voice->chan == chan) {
02920 fluid_voice_set_param(voice, param, value, 0);
02921 }
02922 }
02923
02924 return FLUID_OK;
02925 }
02926
02950 int
02951 fluid_synth_set_gen2(fluid_synth_t* synth, int chan, int param,
02952 float value, int absolute, int normalized)
02953 {
02954 int i;
02955 fluid_voice_t* voice;
02956 float v;
02957
02958 if ((chan < 0) || (chan >= synth->midi_channels)) {
02959 FLUID_LOG(FLUID_WARN, "Channel out of range");
02960 return FLUID_FAILED;
02961 }
02962
02963 if ((param < 0) || (param >= GEN_LAST)) {
02964 FLUID_LOG(FLUID_WARN, "Parameter number out of range");
02965 return FLUID_FAILED;
02966 }
02967
02968 v = (normalized)? fluid_gen_scale(param, value) : value;
02969
02970 fluid_channel_set_gen(synth->channel[chan], param, v, absolute);
02971
02972 for (i = 0; i < synth->polyphony; i++) {
02973 voice = synth->voice[i];
02974 if (voice->chan == chan) {
02975 fluid_voice_set_param(voice, param, v, absolute);
02976 }
02977 }
02978
02979 return FLUID_OK;
02980 }
02981
02982 float fluid_synth_get_gen(fluid_synth_t* synth, int chan, int param)
02983 {
02984 if ((chan < 0) || (chan >= synth->midi_channels)) {
02985 FLUID_LOG(FLUID_WARN, "Channel out of range");
02986 return 0.0;
02987 }
02988
02989 if ((param < 0) || (param >= GEN_LAST)) {
02990 FLUID_LOG(FLUID_WARN, "Parameter number out of range");
02991 return 0.0;
02992 }
02993
02994 return fluid_channel_get_gen(synth->channel[chan], param);
02995 }
02996
02997
02998
02999
03000 void fluid_synth_set_midi_router(fluid_synth_t* synth, fluid_midi_router_t* router){
03001 synth->midi_router=router;
03002 };
03003
03004
03005
03006
03007
03008 int fluid_synth_handle_midi_event(void* data, fluid_midi_event_t* event)
03009 {
03010 fluid_synth_t* synth = (fluid_synth_t*) data;
03011 int type = fluid_midi_event_get_type(event);
03012 int chan = fluid_midi_event_get_channel(event);
03013
03014 switch(type) {
03015 case NOTE_ON:
03016 return fluid_synth_noteon(synth, chan,
03017 fluid_midi_event_get_key(event),
03018 fluid_midi_event_get_velocity(event));
03019
03020 case NOTE_OFF:
03021 return fluid_synth_noteoff(synth, chan, fluid_midi_event_get_key(event));
03022
03023 case CONTROL_CHANGE:
03024 return fluid_synth_cc(synth, chan,
03025 fluid_midi_event_get_control(event),
03026 fluid_midi_event_get_value(event));
03027
03028 case PROGRAM_CHANGE:
03029 return fluid_synth_program_change(synth, chan, fluid_midi_event_get_program(event));
03030
03031 case PITCH_BEND:
03032 return fluid_synth_pitch_bend(synth, chan, fluid_midi_event_get_pitch(event));
03033
03034 case MIDI_SYSTEM_RESET:
03035 return fluid_synth_system_reset(synth);
03036 }
03037 return FLUID_FAILED;
03038 }
03039
03040
03041 int fluid_synth_start(fluid_synth_t* synth, unsigned int id, fluid_preset_t* preset,
03042 int audio_chan, int midi_chan, int key, int vel)
03043 {
03044 int r;
03045
03046
03047 if ((midi_chan < 0) || (midi_chan >= synth->midi_channels)) {
03048 FLUID_LOG(FLUID_WARN, "Channel out of range");
03049 return FLUID_FAILED;
03050 }
03051
03052 if ((key < 0) || (key >= 128)) {
03053 FLUID_LOG(FLUID_WARN, "Key out of range");
03054 return FLUID_FAILED;
03055 }
03056
03057 if ((vel <= 0) || (vel >= 128)) {
03058 FLUID_LOG(FLUID_WARN, "Velocity out of range");
03059 return FLUID_FAILED;
03060 }
03061
03062 fluid_mutex_lock(synth->busy);
03063
03064 synth->storeid = id;
03065 r = fluid_preset_noteon(preset, synth, midi_chan, key, vel);
03066
03067 fluid_mutex_unlock(synth->busy);
03068
03069 return r;
03070 }
03071
03072 int fluid_synth_stop(fluid_synth_t* synth, unsigned int id)
03073 {
03074 int i;
03075 fluid_voice_t* voice;
03076 int status = FLUID_FAILED;
03077 int count = 0;
03078
03079 for (i = 0; i < synth->polyphony; i++) {
03080
03081 voice = synth->voice[i];
03082
03083 if (_ON(voice) && (fluid_voice_get_id(voice) == id)) {
03084 count++;
03085 fluid_voice_noteoff(voice);
03086 status = FLUID_OK;
03087 }
03088 }
03089
03090 return status;
03091 }
03092
03093 fluid_bank_offset_t*
03094 fluid_synth_get_bank_offset0(fluid_synth_t* synth, int sfont_id)
03095 {
03096 fluid_list_t* list = synth->bank_offsets;
03097 fluid_bank_offset_t* offset;
03098
03099 while (list) {
03100
03101 offset = (fluid_bank_offset_t*) fluid_list_get(list);
03102 if (offset->sfont_id == sfont_id) {
03103 return offset;
03104 }
03105
03106 list = fluid_list_next(list);
03107 }
03108
03109 return NULL;
03110 }
03111
03112 int
03113 fluid_synth_set_bank_offset(fluid_synth_t* synth, int sfont_id, int offset)
03114 {
03115 fluid_bank_offset_t* bank_offset;
03116
03117 bank_offset = fluid_synth_get_bank_offset0(synth, sfont_id);
03118
03119 if (bank_offset == NULL) {
03120 bank_offset = FLUID_NEW(fluid_bank_offset_t);
03121 if (bank_offset == NULL) {
03122 return -1;
03123 }
03124 bank_offset->sfont_id = sfont_id;
03125 bank_offset->offset = offset;
03126 synth->bank_offsets = fluid_list_prepend(synth->bank_offsets, bank_offset);
03127 } else {
03128 bank_offset->offset = offset;
03129 }
03130
03131 return 0;
03132 }
03133
03134 int
03135 fluid_synth_get_bank_offset(fluid_synth_t* synth, int sfont_id)
03136 {
03137 fluid_bank_offset_t* bank_offset;
03138
03139 bank_offset = fluid_synth_get_bank_offset0(synth, sfont_id);
03140 return (bank_offset == NULL)? 0 : bank_offset->offset;
03141 }
03142
03143 void
03144 fluid_synth_remove_bank_offset(fluid_synth_t* synth, int sfont_id)
03145 {
03146 fluid_bank_offset_t* bank_offset;
03147
03148 bank_offset = fluid_synth_get_bank_offset0(synth, sfont_id);
03149 if (bank_offset != NULL) {
03150 synth->bank_offsets = fluid_list_remove(synth->bank_offsets, bank_offset);
03151 }
03152 }