# src/fluid_synth.c

    00001 /* FluidSynth - A Software Synthesizer
    00002  *
    00003  * Copyright (C) 2003  Peter Hanappe and others.
    00004  *
    00005  * This library is free software; you can redistribute it and/or
    00006  * modify it under the terms of the GNU Library General Public License
    00007  * as published by the Free Software Foundation; either version 2 of
    00008  * the License, or (at your option) any later version.
    00009  *
    00010  * This library is distributed in the hope that it will be useful, but
    00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
    00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013  * Library General Public License for more details.
    00014  *
    00015  * You should have received a copy of the GNU Library General Public
    00016  * License along with this library; if not, write to the Free
    00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    00018  * 02111-1307, USA
    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 /* seems to not be declared in fenv.h */
    00035 extern int feenableexcept (int excepts);
    00036 #endif
    00037
    00038
    00039 fluid_sfloader_t* new_fluid_defsfloader(void);
    00040
    00041 /************************************************************************
    00042  *
    00043  * These functions were added after the v1.0 API freeze. They are not
    00044  * in synth.h. They should be added as soon as a new development
    00045  * version is started.
    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  *                         GLOBAL
    00065  */
    00066
    00067 /* has the synth module been initialized? */
    00068 static int fluid_synth_initialized = 0;
    00069 static void fluid_synth_init(void);
    00070 static void init_dither(void);
    00071
    00072 /* default modulators
    00073  * SF2.01 page 52 ff:
    00074  *
    00075  * There is a set of predefined default modulators. They have to be
    00076  * explicitly overridden by the sound font in order to turn them off.
    00077  */
    00078
    00079 fluid_mod_t default_vel2att_mod;        /* SF2.01 section 8.4.1  */
    00080 fluid_mod_t default_vel2filter_mod;     /* SF2.01 section 8.4.2  */
    00081 fluid_mod_t default_at2viblfo_mod;      /* SF2.01 section 8.4.3  */
    00082 fluid_mod_t default_mod2viblfo_mod;     /* SF2.01 section 8.4.4  */
    00083 fluid_mod_t default_att_mod;            /* SF2.01 section 8.4.5  */
    00084 fluid_mod_t default_pan_mod;            /* SF2.01 section 8.4.6  */
    00085 fluid_mod_t default_expr_mod;           /* SF2.01 section 8.4.7  */
    00086 fluid_mod_t default_reverb_mod;         /* SF2.01 section 8.4.8  */
    00087 fluid_mod_t default_chorus_mod;         /* SF2.01 section 8.4.9  */
    00088 fluid_mod_t default_pitch_bend_mod;     /* SF2.01 section 8.4.10 */
    00089
    00090 /* reverb presets */
    00091 static fluid_revmodel_presets_t revmodel_preset[] = {
    00092   /* name */    /* roomsize */ /* damp */ /* width */ /* level */
    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  *               INITIALIZATION & UTILITIES
    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  * fluid_version
    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  * fluid_version_str
    00146  */
    00147 char* fluid_version_str(void)
    00148 {
    00149   return FLUIDSYNTH_VERSION;
    00150 }
    00151
    00152
    00153 /*
    00154  * void fluid_synth_init
    00155  *
    00156  * Does all the initialization for this module.
    00157  */
    00158 static void
    00159 fluid_synth_init()
    00160 {
    00161   fluid_synth_initialized++;
    00162
    00163 #ifdef TRAP_ON_FPE
    00164   /* Turn on floating point exception traps */
    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   /* SF2.01 page 53 section 8.4.1: MIDI Note-On Velocity to Initial Attenuation */
    00178   fluid_mod_set_source1(&default_vel2att_mod, /* The modulator we are programming here */
    00179                        FLUID_MOD_VELOCITY,    /* Source. VELOCITY corresponds to 'index=2'. */
    00180                        FLUID_MOD_GC           /* Not a MIDI continuous controller */
    00181                        | FLUID_MOD_CONCAVE    /* Curve shape. Corresponds to 'type=1' */
    00182                        | FLUID_MOD_UNIPOLAR   /* Polarity. Corresponds to 'P=0' */
    00183                        | FLUID_MOD_NEGATIVE   /* Direction. Corresponds to 'D=1' */
    00184                        );
    00185   fluid_mod_set_source2(&default_vel2att_mod, 0, 0); /* No 2nd source */
    00186   fluid_mod_set_dest(&default_vel2att_mod, GEN_ATTENUATION);  /* Target: Initial attenuation */
    00187   fluid_mod_set_amount(&default_vel2att_mod, 960.0);          /* Modulation amount: 960 */
    00188
    00189
    00190
    00191   /* SF2.01 page 53 section 8.4.2: MIDI Note-On Velocity to Filter Cutoff
    00192    * Have to make a design decision here. The specs don't make any sense this way or another.
    00193    * One sound font, 'Kingston Piano', which has been praised for its quality, tries to
    00194    * override this modulator with an amount of 0 and positive polarity (instead of what
    00195    * the specs say, D=1) for the secondary source.
    00196    * So if we change the polarity to 'positive', one of the best free sound fonts works...
    00197    */
    00198   fluid_mod_set_source1(&default_vel2filter_mod, FLUID_MOD_VELOCITY, /* Index=2 */
    00199                        FLUID_MOD_GC                        /* CC=0 */
    00200                        | FLUID_MOD_LINEAR                  /* type=0 */
    00201                        | FLUID_MOD_UNIPOLAR                /* P=0 */
    00202                        | FLUID_MOD_NEGATIVE                /* D=1 */
    00203                        );
    00204   fluid_mod_set_source2(&default_vel2filter_mod, FLUID_MOD_VELOCITY, /* Index=2 */
    00205                        FLUID_MOD_GC                                 /* CC=0 */
    00206                        | FLUID_MOD_SWITCH                           /* type=3 */
    00207                        | FLUID_MOD_UNIPOLAR                         /* P=0 */
    00208                        // do not remove       | FLUID_MOD_NEGATIVE                         /* D=1 */
    00209                        | FLUID_MOD_POSITIVE                         /* D=0 */
    00210                        );
    00211   fluid_mod_set_dest(&default_vel2filter_mod, GEN_FILTERFC);        /* Target: Initial filter cutoff */
    00212   fluid_mod_set_amount(&default_vel2filter_mod, -2400);
    00213
    00214
    00215
    00216   /* SF2.01 page 53 section 8.4.3: MIDI Channel pressure to Vibrato LFO pitch depth */
    00217   fluid_mod_set_source1(&default_at2viblfo_mod, FLUID_MOD_CHANNELPRESSURE, /* Index=13 */
    00218                        FLUID_MOD_GC                        /* CC=0 */
    00219                        | FLUID_MOD_LINEAR                  /* type=0 */
    00220                        | FLUID_MOD_UNIPOLAR                /* P=0 */
    00221                        | FLUID_MOD_POSITIVE                /* D=0 */
    00222                        );
    00223   fluid_mod_set_source2(&default_at2viblfo_mod, 0,0); /* no second source */
    00224   fluid_mod_set_dest(&default_at2viblfo_mod, GEN_VIBLFOTOPITCH);        /* Target: Vib. LFO => pitch */
    00225   fluid_mod_set_amount(&default_at2viblfo_mod, 50);
    00226
    00227
    00228
    00229   /* SF2.01 page 53 section 8.4.4: Mod wheel (Controller 1) to Vibrato LFO pitch depth */
    00230   fluid_mod_set_source1(&default_mod2viblfo_mod, 1, /* Index=1 */
    00231                        FLUID_MOD_CC                        /* CC=1 */
    00232                        | FLUID_MOD_LINEAR                  /* type=0 */
    00233                        | FLUID_MOD_UNIPOLAR                /* P=0 */
    00234                        | FLUID_MOD_POSITIVE                /* D=0 */
    00235                        );
    00236   fluid_mod_set_source2(&default_mod2viblfo_mod, 0,0); /* no second source */
    00237   fluid_mod_set_dest(&default_mod2viblfo_mod, GEN_VIBLFOTOPITCH);        /* Target: Vib. LFO => pitch */
    00238   fluid_mod_set_amount(&default_mod2viblfo_mod, 50);
    00239
    00240
    00241
    00242   /* SF2.01 page 55 section 8.4.5: MIDI continuous controller 7 to initial attenuation*/
    00243   fluid_mod_set_source1(&default_att_mod, 7,                     /* index=7 */
    00244                        FLUID_MOD_CC                              /* CC=1 */
    00245                        | FLUID_MOD_CONCAVE                       /* type=1 */
    00246                        | FLUID_MOD_UNIPOLAR                      /* P=0 */
    00247                        | FLUID_MOD_NEGATIVE                      /* D=1 */
    00248                        );
    00249   fluid_mod_set_source2(&default_att_mod, 0, 0);                 /* No second source */
    00250   fluid_mod_set_dest(&default_att_mod, GEN_ATTENUATION);         /* Target: Initial attenuation */
    00251   fluid_mod_set_amount(&default_att_mod, 960.0);                 /* Amount: 960 */
    00252
    00253
    00254
    00255   /* SF2.01 page 55 section 8.4.6 MIDI continuous controller 10 to Pan Position */
    00256   fluid_mod_set_source1(&default_pan_mod, 10,                    /* index=10 */
    00257                        FLUID_MOD_CC                              /* CC=1 */
    00258                        | FLUID_MOD_LINEAR                        /* type=0 */
    00259                        | FLUID_MOD_BIPOLAR                       /* P=1 */
    00260                        | FLUID_MOD_POSITIVE                      /* D=0 */
    00261                        );
    00262   fluid_mod_set_source2(&default_pan_mod, 0, 0);                 /* No second source */
    00263   fluid_mod_set_dest(&default_pan_mod, GEN_PAN);                 /* Target: pan */
    00264   /* Amount: 500. The SF specs $8.4.6, p. 55 syas: "Amount = 1000
    00265      tenths of a percent". The center value (64) corresponds to 50%,
    00266      so it follows that amount = 50% x 1000/% = 500. */
    00267   fluid_mod_set_amount(&default_pan_mod, 500.0);
    00268
    00269
    00270   /* SF2.01 page 55 section 8.4.7: MIDI continuous controller 11 to initial attenuation*/
    00271   fluid_mod_set_source1(&default_expr_mod, 11,                     /* index=11 */
    00272                        FLUID_MOD_CC                              /* CC=1 */
    00273                        | FLUID_MOD_CONCAVE                       /* type=1 */
    00274                        | FLUID_MOD_UNIPOLAR                      /* P=0 */
    00275                        | FLUID_MOD_NEGATIVE                      /* D=1 */
    00276                        );
    00277   fluid_mod_set_source2(&default_expr_mod, 0, 0);                 /* No second source */
    00278   fluid_mod_set_dest(&default_expr_mod, GEN_ATTENUATION);         /* Target: Initial attenuation */
    00279   fluid_mod_set_amount(&default_expr_mod, 960.0);                 /* Amount: 960 */
    00280
    00281
    00282
    00283   /* SF2.01 page 55 section 8.4.8: MIDI continuous controller 91 to Reverb send */
    00284   fluid_mod_set_source1(&default_reverb_mod, 91,                 /* index=91 */
    00285                        FLUID_MOD_CC                              /* CC=1 */
    00286                        | FLUID_MOD_LINEAR                        /* type=0 */
    00287                        | FLUID_MOD_UNIPOLAR                      /* P=0 */
    00288                        | FLUID_MOD_POSITIVE                      /* D=0 */
    00289                        );
    00290   fluid_mod_set_source2(&default_reverb_mod, 0, 0);              /* No second source */
    00291   fluid_mod_set_dest(&default_reverb_mod, GEN_REVERBSEND);       /* Target: Reverb send */
    00292   fluid_mod_set_amount(&default_reverb_mod, 200);                /* Amount: 200 ('tenths of a percent') */
    00293
    00294
    00295
    00296   /* SF2.01 page 55 section 8.4.9: MIDI continuous controller 93 to Reverb send */
    00297   fluid_mod_set_source1(&default_chorus_mod, 93,                 /* index=93 */
    00298                        FLUID_MOD_CC                              /* CC=1 */
    00299                        | FLUID_MOD_LINEAR                        /* type=0 */
    00300                        | FLUID_MOD_UNIPOLAR                      /* P=0 */
    00301                        | FLUID_MOD_POSITIVE                      /* D=0 */
    00302                        );
    00303   fluid_mod_set_source2(&default_chorus_mod, 0, 0);              /* No second source */
    00304   fluid_mod_set_dest(&default_chorus_mod, GEN_CHORUSSEND);       /* Target: Chorus */
    00305   fluid_mod_set_amount(&default_chorus_mod, 200);                /* Amount: 200 ('tenths of a percent') */
    00306
    00307
    00308
    00309   /* SF2.01 page 57 section 8.4.10 MIDI Pitch Wheel to Initial Pitch ... */
    00310   fluid_mod_set_source1(&default_pitch_bend_mod, FLUID_MOD_PITCHWHEEL, /* Index=14 */
    00311                        FLUID_MOD_GC                              /* CC =0 */
    00312                        | FLUID_MOD_LINEAR                        /* type=0 */
    00313                        | FLUID_MOD_BIPOLAR                       /* P=1 */
    00314                        | FLUID_MOD_POSITIVE                      /* D=0 */
    00315                        );
    00316   fluid_mod_set_source2(&default_pitch_bend_mod, FLUID_MOD_PITCHWHEELSENS,  /* Index = 16 */
    00317                        FLUID_MOD_GC                                        /* CC=0 */
    00318                        | FLUID_MOD_LINEAR                                  /* type=0 */
    00319                        | FLUID_MOD_UNIPOLAR                                /* P=0 */
    00320                        | FLUID_MOD_POSITIVE                                /* D=0 */
    00321                        );
    00322   fluid_mod_set_dest(&default_pitch_bend_mod, GEN_PITCH);                 /* Destination: Initial pitch */
    00323   fluid_mod_set_amount(&default_pitch_bend_mod, 12700.0);                 /* Amount: 12700 cents */
    00324 }
    00325
    00326
    00327 int fluid_synth_verify_settings(fluid_settings_t *settings)
    00328 {
    00329   return 0;
    00330 }
    00331
    00332 /***************************************************************
    00333  *
    00334  *                      FLUID SYNTH
    00335  */
    00336
    00337 /*
    00338  * new_fluid_synth
    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   /* initialize all the conversion tables and other stuff */
    00348   if (fluid_synth_initialized == 0) {
    00349     fluid_synth_init();
    00350   }
    00351
    00352   fluid_synth_verify_settings(settings);
    00353
    00354   /* allocate a new synthesizer object */
    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   /* register the callbacks */
    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   /* do some basic sanity checking on the settings */
    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   /* The number of buffers is determined by the higher number of nr
    00426    * groups / nr audio channels.  If LADSPA is unused, they should be
    00427    * the same. */
    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   /* Create and initialize the Fx unit.*/
    00435   synth->LADSPA_FxUnit = new_fluid_LADSPA_FxUnit(synth);
    00436 #endif
    00437
    00438   /* as soon as the synth is created it starts playing. */
    00439   synth->state = FLUID_SYNTH_PLAYING;
    00440   synth->sfont = NULL;
    00441   synth->noteid = 0;
    00442   synth->ticks = 0;
    00443   synth->tuning = NULL;
    00444
    00445   /* allocate and add the default sfont loader */
    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   /* allocate all channel objects */
    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   /* allocate all synthesis processes */
    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   /* Allocate the sample buffers */
    00481   synth->left_buf = NULL;
    00482   synth->right_buf = NULL;
    00483   synth->fx_left_buf = NULL;
    00484   synth->fx_right_buf = NULL;
    00485
    00486   /* Left and right audio buffers */
    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   /* Effects audio buffers */
    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   /* allocate the reverb module */
    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   /* allocate the chorus module */
    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   /* FIXME */
    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  * delete_fluid_synth
    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   /* turn off all voices, needed to unload SoundFont data */
    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   /* delete all the SoundFonts */
    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   /* and the SoundFont offsets */
    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   /* delete all the SoundFont loaders */
    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   /* free all the sample buffers */
    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   /* release the reverb module */
    00678   if (synth->reverb != NULL) {
    00679     delete_fluid_revmodel(synth->reverb);
    00680   }
    00681
    00682   /* release the chorus module */
    00683   if (synth->chorus != NULL) {
    00684     delete_fluid_chorus(synth->chorus);
    00685   }
    00686
    00687   /* free the tunings, if any */
    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   /* Release the LADSPA Fx unit */
    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  * fluid_synth_error
    00717  *
    00718  * The error messages are not thread-save, yet. They are still stored
    00719  * in a global message buffer (see fluid_sys.c).
    00720  * */
    00721 char*
    00722 fluid_synth_error(fluid_synth_t* synth)
    00723 {
    00724   return fluid_error();
    00725 }
    00726
    00727 /*
    00728  * fluid_synth_noteon
    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   /* check the ranges of the arguments */
    00737   if ((chan < 0) || (chan >= synth->midi_channels)) {
    00738     FLUID_LOG(FLUID_WARN, "Channel out of range");
    00739     return FLUID_FAILED;
    00740   }
    00741
    00742   /* notes with velocity zero go to noteoff  */
    00743   if (vel == 0) {
    00744     return fluid_synth_noteoff(synth, chan, key);
    00745   }
    00746
    00747   channel = synth->channel[chan];
    00748
    00749   /* make sure this channel has a preset */
    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   /* If there is another voice process on the same channel and key,
    00762      advance it to the release phase. */
    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  * fluid_synth_noteoff
    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 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    00778 /*   fluid_mutex_unlock(synth->busy); */
    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       } /* if verbose */
    00798       fluid_voice_noteoff(voice);
    00799       status = FLUID_OK;
    00800     } /* if voice on */
    00801   } /* for all voices */
    00802   return status;
    00803 }
    00804
    00805 /*
    00806  * fluid_synth_damp_voices
    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 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    00815 /*   fluid_mutex_unlock(synth->busy); */
    00816
    00817   for (i = 0; i < synth->polyphony; i++) {
    00818     voice = synth->voice[i];
    00819     if ((voice->chan == chan) && _SUSTAINED(voice)) {
    00820 /*        printf("turned off sustained note: chan=%d, key=%d, vel=%d\n", voice->chan, voice->key, voice->vel); */
    00821       fluid_voice_noteoff(voice);
    00822     }
    00823   }
    00824
    00825   return FLUID_OK;
    00826 }
    00827
    00828 /*
    00829  * fluid_synth_cc
    00830  */
    00831 int
    00832 fluid_synth_cc(fluid_synth_t* synth, int chan, int num, int val)
    00833 {
    00834 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    00835 /*   fluid_mutex_unlock(synth->busy); */
    00836
    00837   /* check the ranges of the arguments */
    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   /* set the controller value in the channel */
    00856   fluid_channel_cc(synth->channel[chan], num, val);
    00857
    00858   return FLUID_OK;
    00859 }
    00860
    00861 /*
    00862  * fluid_synth_cc
    00863  */
    00864 int
    00865 fluid_synth_get_cc(fluid_synth_t* synth, int chan, int num, int* pval)
    00866 {
    00867   /* check the ranges of the arguments */
    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  * fluid_synth_all_notes_off
    00883  *
    00884  * put all notes on this channel into released state.
    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  * fluid_synth_all_sounds_off
    00903  *
    00904  * immediately stop all notes on this channel.
    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  * fluid_synth_system_reset
    00923  *
    00924  * Purpose:
    00925  * Respond to the MIDI command 'system reset' (0xFF, big red 'panic' button)
    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  * fluid_synth_modulate_voices
    00952  *
    00953  * tell all synthesis processes on this channel to update their
    00954  * synthesis parameters after a control change.
    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 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    00963 /*   fluid_mutex_unlock(synth->busy); */
    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  * fluid_synth_modulate_voices_all
    00976  *
    00977  * Tell all synthesis processes on this channel to update their
    00978  * synthesis parameters after an all control off message (i.e. all
    00979  * controller have been reset to their default value).
    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 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    00988 /*   fluid_mutex_unlock(synth->busy); */
    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  * fluid_synth_pitch_bend
    01001  */
    01002 int
    01003 fluid_synth_pitch_bend(fluid_synth_t* synth, int chan, int val)
    01004 {
    01005
    01006 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    01007 /*   fluid_mutex_unlock(synth->busy); */
    01008
    01009   /* check the ranges of the arguments */
    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   /* set the pitch-bend value in the channel */
    01020   fluid_channel_pitch_bend(synth->channel[chan], val);
    01021
    01022   return FLUID_OK;
    01023 }
    01024
    01025 /*
    01026  * fluid_synth_pitch_bend
    01027  */
    01028 int
    01029 fluid_synth_get_pitch_bend(fluid_synth_t* synth, int chan, int* ppitch_bend)
    01030 {
    01031   /* check the ranges of the arguments */
    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  * Fluid_synth_pitch_wheel_sens
    01043  */
    01044 int
    01045 fluid_synth_pitch_wheel_sens(fluid_synth_t* synth, int chan, int val)
    01046 {
    01047
    01048   /* check the ranges of the arguments */
    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   /* set the pitch-bend value in the channel */
    01059   fluid_channel_pitch_wheel_sens(synth->channel[chan], val);
    01060
    01061   return FLUID_OK;
    01062 }
    01063
    01064 /*
    01065  * fluid_synth_get_pitch_wheel_sens
    01066  *
    01067  * Note : this function was added after version 1.0 API freeze.
    01068  * So its API is not in the synth.h file. It should be added in some later
    01069  * version of fluidsynth. Maybe v2.0 ? -- Antoine Schmitt May 2003
    01070  */
    01071
    01072 int
    01073 fluid_synth_get_pitch_wheel_sens(fluid_synth_t* synth, int chan, int* pval)
    01074 {
    01075
    01076   // check the ranges of the arguments
    01077   if ((chan < 0) || (chan >= synth->midi_channels)) {
    01078     FLUID_LOG(FLUID_WARN, "Channel out of range");
    01079     return FLUID_FAILED;
    01080   }
    01081
    01082   // get the pitch-bend value in the channel
    01083   *pval = synth->channel[chan]->pitch_wheel_sensitivity;
    01084
    01085   return FLUID_OK;
    01086 }
    01087
    01088 /*
    01089  * fluid_synth_get_preset
    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  * fluid_synth_get_preset2
    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; /* FIXME */
    01152       return preset;
    01153     }
    01154
    01155     list = fluid_list_next(list);
    01156
    01157   }
    01158   return NULL;
    01159 }
    01160
    01161
    01162 /*
    01163  * fluid_synth_program_change
    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 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    01174 /*   fluid_mutex_unlock(synth->busy); */
    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     /* inform the channel of the new program number */
    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     /* special handling of channel 10 (or 9 counting from 0). channel
    01190        10 is the percussion channel.  */
    01191     if (channel->channum == 9) {
    01192
    01193       /* try to search the drum instrument first */
    01194       preset = fluid_synth_find_preset(synth, banknum | DRUM_INST_MASK, prognum);
    01195
    01196       /* if that fails try to search the melodic instrument */
    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  * fluid_synth_bank_select
    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  * fluid_synth_sfont_select
    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  * fluid_synth_get_program
    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  * fluid_synth_program_select
    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   /* inform the channel of the new bank and program number */
    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  * fluid_synth_program_select2
    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   /* inform the channel of the new bank and program number */
    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  * fluid_synth_update_presets
    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  * fluid_synth_update_gain
    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  * fluid_synth_set_gain
    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  * fluid_synth_get_gain
    01388  */
    01389 float fluid_synth_get_gain(fluid_synth_t* synth)
    01390 {
    01391   return synth->gain;
    01392 }
    01393
    01394 /*
    01395  * fluid_synth_update_polyphony
    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  * fluid_synth_set_polyphony
    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   /* turn off any voices above the new limit */
    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  * fluid_synth_get_polyphony
    01429  */
    01430 int fluid_synth_get_polyphony(fluid_synth_t* synth)
    01431 {
    01432   return synth->polyphony;
    01433 }
    01434
    01435 /*
    01436  * fluid_synth_get_internal_buffer_size
    01437  */
    01438 int fluid_synth_get_internal_bufsize(fluid_synth_t* synth)
    01439 {
    01440   return FLUID_BUFSIZE;
    01441 }
    01442
    01443 /*
    01444  * fluid_synth_program_reset
    01445  *
    01446  * Resend a bank select and a program change for every channel. This
    01447  * function is called mainly after a SoundFont has been loaded,
    01448  * unloaded or reloaded.  */
    01449 int
    01450 fluid_synth_program_reset(fluid_synth_t* synth)
    01451 {
    01452   int i;
    01453   /* try to set the correct presets */
    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  * fluid_synth_set_reverb_preset
    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  * fluid_synth_set_reverb
    01481  */
    01482 void fluid_synth_set_reverb(fluid_synth_t* synth, double roomsize, double damping,
    01483                            double width, double level)
    01484 {
    01485 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    01486 /*   fluid_mutex_unlock(synth->busy); */
    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  * fluid_synth_set_chorus
    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 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    01501 /*   fluid_mutex_unlock(synth->busy); */
    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 #define COMPRESS      1
    01514 #define COMPRESS_X1   4.0
    01515 #define COMPRESS_Y1   0.6
    01516 #define COMPRESS_X2   10.0
    01517 #define COMPRESS_Y2   1.0
    01518
    01519   len2 = 2 * len;
    01520   alpha1 = COMPRESS_Y1 / COMPRESS_X1;
    01521   alpha2 = (COMPRESS_Y2 - COMPRESS_Y1) / (COMPRESS_X2 - COMPRESS_X1);
    01522   if (COMPRESS_X1 == COMPRESS_Y1) {
    01523     for (j = 0; j < len2; j++) {
    01524       if (buf[j] > COMPRESS_X1) {
    01525         if (buf[j] > COMPRESS_X2) {
    01526           buf[j] = COMPRESS_Y2;
    01527         } else {
    01528           buf[j] = COMPRESS_Y1 + alpha2 * (buf[j] - COMPRESS_X1);
    01529         }
    01530       } else if (buf[j] < -COMPRESS_X1) {
    01531         if (buf[j] < -COMPRESS_X2) {
    01532           buf[j] = -COMPRESS_Y2;
    01533         } else {
    01534           buf[j] = -COMPRESS_Y1 + alpha2 * (buf[j] + COMPRESS_X1);
    01535         }
    01536       }
    01537     }
    01538   } else {
    01539     for (j = 0; j < len2; j++) {
    01540       if ((buf[j] >= -COMPRESS_X1) && (buf[j] <= COMPRESS_X1)) {
    01541         buf[j] *= alpha1;
    01542       } else if (buf[j] > COMPRESS_X1) {
    01543         if (buf[j] > COMPRESS_X2) {
    01544           buf[j] = COMPRESS_Y2;
    01545         } else {
    01546           buf[j] = COMPRESS_Y1 + alpha2 * (buf[j] - COMPRESS_X1);
    01547         }
    01548       } else {
    01549         if (buf[j] < -COMPRESS_X2) {
    01550           buf[j] = -COMPRESS_Y2;
    01551         } else {
    01552           buf[j] = -COMPRESS_Y1 + alpha2 * (buf[j] + COMPRESS_X1);
    01553         }
    01554       }
    01555     }
    01556   }
    01557
    01558 ***************************************************/
    01559
    01560 /*
    01561  *  fluid_synth_nwrite_float
    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   /* make sure we're playing */
    01576   if (synth->state != FLUID_SYNTH_PLAYING) {
    01577     return 0;
    01578   }
    01579
    01580   /* First, take what's still available in the buffer */
    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; /* if we're now done, num becomes the new synth->cur below */
    01599   }
    01600
    01601   /* Then, run one_block() and copy till we have 'len' samples  */
    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 /*   printf("CPU: %.2f\n", synth->cpu_load); */
    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  *  fluid_synth_write_float
    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   /* make sure we're playing */
    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     /* fill up the buffers as needed */
    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 /*   printf("CPU: %.2f\n", synth->cpu_load); */
    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 /* A portable replacement for roundf(), seems it may actually be faster too! */
    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  *  fluid_synth_write_s16
    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   /* make sure we're playing */
    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     /* fill up the buffers as needed */
    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     /* digital clipping */
    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;     /* keep dither buffer continous */
    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 /*   printf("CPU: %.2f\n", synth->cpu_load); */
    01780
    01781   return 0;
    01782 }
    01783
    01784 /*
    01785  * fluid_synth_dither_s16
    01786  * Converts stereo floating point sample data to signed 16 bit data with
    01787  * dithering.  'dither_index' parameter is a caller supplied pointer to an
    01788  * integer which should be initialized to 0 before the first call and passed
    01789  * unmodified to additional calls which are part of the same synthesis output.
    01790  * Only used internally currently.
    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     /* digital clipping */
    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;   /* keep dither buffer continous */
    01824
    01825   fluid_profile(FLUID_PROF_WRITE_S16, prof_ref);
    01826 }
    01827
    01828 /*
    01829  *  fluid_synth_one_block
    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 /*   fluid_mutex_lock(synth->busy); /\* Here comes the audio thread. Lock the synth. *\/ */
    01844
    01845   fluid_check_fpe("??? Just starting up ???");
    01846
    01847   /* clean the audio buffers */
    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   /* Set up the reverb / chorus buffers only, when the effect is
    01859    * enabled on synth level.  Nonexisting buffers are detected in the
    01860    * DSP loop. Not sending the reverb / chorus signal saves some time
    01861    * in that case. */
    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   /* call all playing synthesis processes */
    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       /* The output associated with a MIDI channel is wrapped around
    01875        * using the number of audio groups as modulo divider.  This is
    01876        * typically the number of output channels on the 'sound card',
    01877        * as long as the LADSPA Fx unit is not used. In case of LADSPA
    01878        * unit, think of it as subgroups on a mixer.
    01879        *
    01880        * For example: Assume that the number of groups is set to 2.
    01881        * Then MIDI channel 1, 3, 5, 7 etc. go to output 1, channels 2,
    01882        * 4, 6, 8 etc to output 2.  Or assume 3 groups: Then MIDI
    01883        * channels 1, 4, 7, 10 etc go to output 1; 2, 5, 8, 11 etc to
    01884        * output 2, 3, 6, 9, 12 etc to output 3.
    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   /* if multi channel output, don't mix the output of the chorus and
    01902      reverb in the final output. The effects outputs are send
    01903      separately. */
    01904
    01905   if (do_not_mix_fx_to_out) {
    01906
    01907     /* send to reverb */
    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     /* send to chorus */
    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     /* send to reverb */
    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     /* send to chorus */
    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   /* Run the signal through the LADSPA Fx unit */
    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   /* Testcase, that provokes a denormal floating point error */
    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 /*   fluid_mutex_unlock(synth->busy); /\* Allow other threads to touch the synth *\/ */
    01959
    01960   return 0;
    01961 }
    01962
    01963
    01964 /*
    01965  * fluid_synth_free_voice_by_kill
    01966  *
    01967  * selects a voice for killing. the selection algorithm is a refinement
    01968  * of the algorithm previously in fluid_synth_alloc_voice.
    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 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    01980 /*   fluid_mutex_unlock(synth->busy); */
    01981
    01982   for (i = 0; i < synth->polyphony; i++) {
    01983
    01984     voice = synth->voice[i];
    01985
    01986     /* safeguard against an available voice. */
    01987     if (_AVAILABLE(voice)) {
    01988       return voice;
    01989     }
    01990
    01991     /* Determine, how 'important' a voice is.
    01992      * Start with an arbitrary number */
    01993     this_voice_prio = 10000.;
    01994
    01995     /* Is this voice on the drum channel?
    01996      * Then it is very important.
    01997      * Also, forget about the released-note condition:
    01998      * Typically, drum notes are triggered only very briefly, they run most
    01999      * of the time in release phase.
    02000      */
    02001     if (voice->chan == 9){
    02002       this_voice_prio += 4000;
    02003
    02004     } else if (_RELEASED(voice)){
    02005       /* The key for this voice has been released. Consider it much less important
    02006        * than a voice, which is still held.
    02007        */
    02008       this_voice_prio -= 2000.;
    02009     }
    02010
    02011     if (_SUSTAINED(voice)){
    02012       /* The sustain pedal is held down on this channel.
    02013        * Consider it less important than non-sustained channels.
    02014        * This decision is somehow subjective. But usually the sustain pedal
    02015        * is used to play 'more-voices-than-fingers', so it shouldn't hurt
    02016        * if we kill one voice.
    02017        */
    02018       this_voice_prio -= 1000;
    02019     }
    02020
    02021     /* We are not enthusiastic about releasing voices, which have just been started.
    02022      * Otherwise hitting a chord may result in killing notes belonging to that very same
    02023      * chord.
    02024      * So subtract the age of the voice from the priority - an older voice is just a little
    02025      * bit less important than a younger voice.
    02026      * This is a number between roughly 0 and 100.*/
    02027     this_voice_prio -= (synth->noteid - fluid_voice_get_id(voice));
    02028
    02029     /* take a rough estimate of loudness into account. Louder voices are more important. */
    02030     if (voice->volenv_section != FLUID_VOICE_ENVATTACK){
    02031       this_voice_prio += voice->volenv_val * 1000.;
    02032     }
    02033
    02034     /* check if this voice has less priority than the previous candidate. */
    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  * fluid_synth_alloc_voice
    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 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    02061 /*   fluid_mutex_unlock(synth->busy); */
    02062
    02063   /* check if there's an available synthesis process */
    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   /* No success yet? Then stop a running voice. */
    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   /* add the default modulators to the synthesis process. */
    02108   fluid_voice_add_mod(voice, &default_vel2att_mod, FLUID_VOICE_DEFAULT);    /* SF2.01 $8.4.1  */
    02109   fluid_voice_add_mod(voice, &default_vel2filter_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.2  */
    02110   fluid_voice_add_mod(voice, &default_at2viblfo_mod, FLUID_VOICE_DEFAULT);  /* SF2.01 $8.4.3  */
    02111   fluid_voice_add_mod(voice, &default_mod2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.4  */
    02112   fluid_voice_add_mod(voice, &default_att_mod, FLUID_VOICE_DEFAULT);        /* SF2.01 $8.4.5  */
    02113   fluid_voice_add_mod(voice, &default_pan_mod, FLUID_VOICE_DEFAULT);        /* SF2.01 $8.4.6  */
    02114   fluid_voice_add_mod(voice, &default_expr_mod, FLUID_VOICE_DEFAULT);       /* SF2.01 $8.4.7  */
    02115   fluid_voice_add_mod(voice, &default_reverb_mod, FLUID_VOICE_DEFAULT);     /* SF2.01 $8.4.8  */
    02116   fluid_voice_add_mod(voice, &default_chorus_mod, FLUID_VOICE_DEFAULT);     /* SF2.01 $8.4.9  */
    02117   fluid_voice_add_mod(voice, &default_pitch_bend_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.10 */
    02118
    02119   return voice;
    02120 }
    02121
    02122 /*
    02123  * fluid_synth_kill_by_exclusive_class
    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   /* Check if the voice belongs to an exclusive class. In that case,
    02141      previous notes from the same class are released. */
    02142
    02143   /* Excl. class 0: No exclusive class */
    02144   if (excl_class == 0) {
    02145     return;
    02146   }
    02147
    02148   //  FLUID_LOG(FLUID_INFO, "Voice belongs to exclusive class (class=%d, ignore_id=%d)", excl_class, ignore_ID);
    02149
    02150     /* Kill all notes on the same channel with the same exclusive class */
    02151
    02152   for (i = 0; i < synth->polyphony; i++) {
    02153     fluid_voice_t* existing_voice = synth->voice[i];
    02154
    02155     /* Existing voice does not play? Leave it alone. */
    02156     if (!_PLAYING(existing_voice)) {
    02157       continue;
    02158     }
    02159
    02160     /* An exclusive class is valid for a whole channel (or preset).
    02161      * Is the voice on a different channel? Leave it alone. */
    02162     if (existing_voice->chan != new_voice->chan) {
    02163       continue;
    02164     }
    02165
    02166     /* Existing voice has a different (or no) exclusive class? Leave it alone. */
    02167     if ((int)_GEN(existing_voice, GEN_EXCLUSIVECLASS) != excl_class) {
    02168       continue;
    02169     }
    02170
    02171     /* Existing voice is a voice process belonging to this noteon
    02172      * event (for example: stereo sample)?  Leave it alone. */
    02173     if (fluid_voice_get_id(existing_voice) == fluid_voice_get_id(new_voice)) {
    02174       continue;
    02175     }
    02176
    02177     //    FLUID_LOG(FLUID_INFO, "Releasing previous voice of exclusive class (class=%d, id=%d)",
    02178     //     (int)_GEN(existing_voice, GEN_EXCLUSIVECLASS), (int)fluid_voice_get_id(existing_voice));
    02179
    02180     fluid_voice_kill_excl(existing_voice);
    02181   };
    02182 };
    02183
    02184 /*
    02185  * fluid_synth_start_voice
    02186  */
    02187 void fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t* voice)
    02188 {
    02189 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    02190 /*   fluid_mutex_unlock(synth->busy); */
    02191
    02192   /* Find the exclusive class of this voice. If set, kill all voices
    02193    * that match the exclusive class and are younger than the first
    02194    * voice process created by this noteon event. */
    02195   fluid_synth_kill_by_exclusive_class(synth, voice);
    02196
    02197   /* Start the new voice */
    02198
    02199   fluid_voice_start(voice);
    02200 }
    02201
    02202 /*
    02203  * fluid_synth_add_sfloader
    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  * fluid_synth_sfload
    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       /* insert the sfont as the first one on the list */
    02240       synth->sfont = fluid_list_prepend(synth->sfont, sfont);
    02241
    02242       /* reset the presets for all channels */
    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  * fluid_synth_sfunload_callback
    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  * fluid_synth_sfunload_macos9
    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  * fluid_synth_sfunload
    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   /* remove the SoundFont from the list */
    02307   synth->sfont = fluid_list_remove(synth->sfont, sfont);
    02308
    02309   /* reset the presets for all channels */
    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     /* spin off a timer thread to unload the sfont later */
    02321     new_fluid_timer(100, fluid_synth_sfunload_callback, sfont, 1, 1);
    02322 #endif
    02323   }
    02324
    02325   return FLUID_OK;
    02326 }
    02327
    02328 /* fluid_synth_sfreload
    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   /* find the index of the SoundFont */
    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   /* keep a copy of the SoundFont's filename */
    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       /* insert the sfont at the same index */
    02373       synth->sfont = fluid_list_insert_at(synth->sfont, index, sfont);
    02374
    02375       /* reset the presets for all channels */
    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  * fluid_synth_add_sfont
    02389  */
    02390 int fluid_synth_add_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont)
    02391 {
    02392         sfont->id = ++synth->sfont_id;
    02393
    02394         /* insert the sfont as the first one on the list */
    02395         synth->sfont = fluid_list_prepend(synth->sfont, sfont);
    02396
    02397         /* reset the presets for all channels */
    02398         fluid_synth_program_reset(synth);
    02399
    02400         return sfont->id;
    02401 }
    02402
    02403
    02404 /*
    02405  * fluid_synth_remove_sfont
    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         /* remove a possible bank offset */
    02414         fluid_synth_remove_bank_offset(synth, sfont_id);
    02415
    02416         /* reset the presets for all channels */
    02417         fluid_synth_program_reset(synth);
    02418 }
    02419
    02420
    02421 /* fluid_synth_sfcount
    02422  *
    02423  * Returns the number of loaded SoundFonts
    02424  */
    02425 int
    02426 fluid_synth_sfcount(fluid_synth_t* synth)
    02427 {
    02428   return fluid_list_size(synth->sfont);
    02429 }
    02430
    02431 /* fluid_synth_get_sfont
    02432  *
    02433  * Returns SoundFont num
    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 /* fluid_synth_get_sfont_by_id
    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 /* fluid_synth_get_sfont_by_name
    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  * fluid_synth_get_channel_preset
    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  * fluid_synth_get_voicelist
    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 /* Purpose:
    02515  * Turns on / off the reverb unit in the synth */
    02516 void fluid_synth_set_reverb_on(fluid_synth_t* synth, int on)
    02517 {
    02518   synth->with_reverb = on;
    02519 }
    02520
    02521 /* Purpose:
    02522  * Turns on / off the chorus unit in the synth */
    02523 void fluid_synth_set_chorus_on(fluid_synth_t* synth, int on)
    02524 {
    02525   synth->with_chorus = on;
    02526 }
    02527
    02528 /* Purpose:
    02529  * Reports the current setting of the chorus unit. */
    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 /* Purpose:
    02556  * Returns the current settings_old of the reverb unit */
    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 /* Purpose:
    02578  *
    02579  * If the same note is hit twice on the same channel, then the older
    02580  * voice process is advanced to the release stage.  Using a mechanical
    02581  * MIDI controller, the only way this can happen is when the sustain
    02582  * pedal is held.  In this case the behaviour implemented here is
    02583  * natural for many instruments.  Note: One noteon event can trigger
    02584  * several voice processes, for example a stereo sample.  Don't
    02585  * release those...
    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 /*   fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
    02592 /*   fluid_mutex_unlock(synth->busy); */
    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 /* Purpose:
    02606  * Sets the interpolation method to use on channel chan.
    02607  * If chan is < 0, then set the interpolation method on all channels.
    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 /* Purpose:
    02624  * Returns the number of allocated midi channels
    02625  */
    02626 int
    02627 fluid_synth_count_midi_channels(fluid_synth_t* synth)
    02628 {
    02629   return synth->midi_channels;
    02630 }
    02631
    02632 /* Purpose:
    02633  * Returns the number of allocated audio channels
    02634  */
    02635 int
    02636 fluid_synth_count_audio_channels(fluid_synth_t* synth)
    02637 {
    02638   return synth->audio_channels;
    02639 }
    02640
    02641 /* Purpose:
    02642  * Returns the number of allocated audio channels
    02643  */
    02644 int
    02645 fluid_synth_count_audio_groups(fluid_synth_t* synth)
    02646 {
    02647   return synth->audio_groups;
    02648 }
    02649
    02650 /* Purpose:
    02651  * Returns the number of allocated effects channels
    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     /* get the next program number */
    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;  /* make sure the string is null terminated */
    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 /* The synth needs to know the router for the command line handlers (they only
    02998  * supply the synth as argument)
    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 /* Purpose:
    03005  * Any MIDI event from the MIDI router arrives here and is handed
    03006  * to the appropriate function.
    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   /* check the ranges of the arguments */
    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); /* One at a time, please */
    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 }