Update Fluidsynth to 2.0.1
[ardour.git] / libs / fluidsynth / src / fluid_synth.c
1 /* FluidSynth - A Software Synthesizer
2  *
3  * Copyright (C) 2003  Peter Hanappe and others.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License
7  * as published by the Free Software Foundation; either version 2.1 of
8  * the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free
17  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  */
20
21 #include "fluid_synth.h"
22 #include "fluid_sys.h"
23 #include "fluid_chan.h"
24 #include "fluid_tuning.h"
25 #include "fluid_settings.h"
26 #include "fluid_sfont.h"
27 #include "fluid_defsfont.h"
28
29 #ifdef TRAP_ON_FPE
30 #define _GNU_SOURCE
31 #include <fenv.h>
32
33 /* seems to not be declared in fenv.h */
34 extern int feenableexcept(int excepts);
35 #endif
36
37 #define FLUID_API_RETURN(return_value) \
38   do { fluid_synth_api_exit(synth); \
39   return return_value; } while (0)
40
41 #define FLUID_API_RETURN_IF_CHAN_DISABLED(return_value) \
42   do { if (FLUID_LIKELY(synth->channel[chan]->mode & FLUID_CHANNEL_ENABLED)) \
43        {} \
44        else \
45        { FLUID_API_RETURN(return_value); } \
46   } while (0)
47
48 #define FLUID_API_ENTRY_CHAN(fail_value)  \
49   fluid_return_val_if_fail (synth != NULL, fail_value); \
50   fluid_return_val_if_fail (chan >= 0, fail_value); \
51   fluid_synth_api_enter(synth); \
52   if (chan >= synth->midi_channels) { \
53     FLUID_API_RETURN(fail_value); \
54   } \
55
56 static void fluid_synth_init(void);
57 static void fluid_synth_api_enter(fluid_synth_t *synth);
58 static void fluid_synth_api_exit(fluid_synth_t *synth);
59
60 static int fluid_synth_noteon_LOCAL(fluid_synth_t *synth, int chan, int key,
61                                     int vel);
62 static int fluid_synth_noteoff_LOCAL(fluid_synth_t *synth, int chan, int key);
63 static int fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num);
64 static int fluid_synth_sysex_midi_tuning(fluid_synth_t *synth, const char *data,
65         int len, char *response,
66         int *response_len, int avail_response,
67         int *handled, int dryrun);
68 int fluid_synth_all_notes_off_LOCAL(fluid_synth_t *synth, int chan);
69 static int fluid_synth_all_sounds_off_LOCAL(fluid_synth_t *synth, int chan);
70 static int fluid_synth_system_reset_LOCAL(fluid_synth_t *synth);
71 static int fluid_synth_modulate_voices_LOCAL(fluid_synth_t *synth, int chan,
72         int is_cc, int ctrl);
73 static int fluid_synth_modulate_voices_all_LOCAL(fluid_synth_t *synth, int chan);
74 static int fluid_synth_update_channel_pressure_LOCAL(fluid_synth_t *synth, int channum);
75 static int fluid_synth_update_key_pressure_LOCAL(fluid_synth_t *synth, int chan, int key);
76 static int fluid_synth_update_pitch_bend_LOCAL(fluid_synth_t *synth, int chan);
77 static int fluid_synth_update_pitch_wheel_sens_LOCAL(fluid_synth_t *synth, int chan);
78 static int fluid_synth_set_preset(fluid_synth_t *synth, int chan,
79                                   fluid_preset_t *preset);
80 static fluid_preset_t *
81 fluid_synth_get_preset(fluid_synth_t *synth, int sfontnum,
82                        int banknum, int prognum);
83 static fluid_preset_t *
84 fluid_synth_get_preset_by_sfont_name(fluid_synth_t *synth, const char *sfontname,
85                                      int banknum, int prognum);
86
87 static void fluid_synth_update_presets(fluid_synth_t *synth);
88 static void fluid_synth_update_gain_LOCAL(fluid_synth_t *synth);
89 static int fluid_synth_update_polyphony_LOCAL(fluid_synth_t *synth, int new_polyphony);
90 static void init_dither(void);
91 static FLUID_INLINE int roundi(float x);
92 static int fluid_synth_render_blocks(fluid_synth_t *synth, int blockcount);
93
94 static fluid_voice_t *fluid_synth_free_voice_by_kill_LOCAL(fluid_synth_t *synth);
95 static void fluid_synth_kill_by_exclusive_class_LOCAL(fluid_synth_t *synth,
96         fluid_voice_t *new_voice);
97 static int fluid_synth_sfunload_callback(void *data, unsigned int msec);
98 void fluid_synth_release_voice_on_same_note_LOCAL(fluid_synth_t *synth,
99         int chan, int key);
100 static fluid_tuning_t *fluid_synth_get_tuning(fluid_synth_t *synth,
101         int bank, int prog);
102 static int fluid_synth_replace_tuning_LOCK(fluid_synth_t *synth,
103         fluid_tuning_t *tuning,
104         int bank, int prog, int apply);
105 static void fluid_synth_replace_tuning_LOCAL(fluid_synth_t *synth,
106         fluid_tuning_t *old_tuning,
107         fluid_tuning_t *new_tuning,
108         int apply, int unref_new);
109 static void fluid_synth_update_voice_tuning_LOCAL(fluid_synth_t *synth,
110         fluid_channel_t *channel);
111 static int fluid_synth_set_tuning_LOCAL(fluid_synth_t *synth, int chan,
112                                         fluid_tuning_t *tuning, int apply);
113 static void fluid_synth_set_gen_LOCAL(fluid_synth_t *synth, int chan,
114                                       int param, float value, int absolute);
115 static void fluid_synth_stop_LOCAL(fluid_synth_t *synth, unsigned int id);
116
117
118 static int fluid_synth_set_important_channels(fluid_synth_t *synth, const char *channels);
119
120
121 /* Callback handlers for real-time settings */
122 static void fluid_synth_handle_sample_rate(void *data, const char *name, double value);
123 static void fluid_synth_handle_gain(void *data, const char *name, double value);
124 static void fluid_synth_handle_polyphony(void *data, const char *name, int value);
125 static void fluid_synth_handle_device_id(void *data, const char *name, int value);
126 static void fluid_synth_handle_overflow(void *data, const char *name, double value);
127 static void fluid_synth_handle_important_channels(void *data, const char *name,
128         const char *value);
129 static void fluid_synth_handle_reverb_chorus_num(void *data, const char *name, double value);
130 static void fluid_synth_handle_reverb_chorus_int(void *data, const char *name, int value);
131
132
133 static void fluid_synth_reset_basic_channel_LOCAL(fluid_synth_t *synth, int chan, int nbr_chan);
134 static int fluid_synth_check_next_basic_channel(fluid_synth_t *synth, int basicchan, int mode, int val);
135 static void fluid_synth_set_basic_channel_LOCAL(fluid_synth_t *synth, int basicchan, int mode, int val);
136 static int fluid_synth_set_reverb_full_LOCAL(fluid_synth_t *synth, int set, double roomsize,
137         double damping, double width, double level);
138
139 static int fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double level,
140         double speed, double depth_ms, int type);
141
142 /***************************************************************
143  *
144  *                         GLOBAL
145  */
146
147 /* has the synth module been initialized? */
148 /* fluid_atomic_int_t may be anything, so init with {0} to catch most cases */
149 static fluid_atomic_int_t fluid_synth_initialized = {0};
150 static void fluid_synth_init(void);
151 static void init_dither(void);
152
153 /* default modulators
154  * SF2.01 page 52 ff:
155  *
156  * There is a set of predefined default modulators. They have to be
157  * explicitly overridden by the sound font in order to turn them off.
158  */
159
160 static fluid_mod_t default_vel2att_mod;        /* SF2.01 section 8.4.1  */
161 /*not static */ fluid_mod_t default_vel2filter_mod;     /* SF2.01 section 8.4.2  */
162 static fluid_mod_t default_at2viblfo_mod;      /* SF2.01 section 8.4.3  */
163 static fluid_mod_t default_mod2viblfo_mod;     /* SF2.01 section 8.4.4  */
164 static fluid_mod_t default_att_mod;            /* SF2.01 section 8.4.5  */
165 static fluid_mod_t default_pan_mod;            /* SF2.01 section 8.4.6  */
166 static fluid_mod_t default_expr_mod;           /* SF2.01 section 8.4.7  */
167 static fluid_mod_t default_reverb_mod;         /* SF2.01 section 8.4.8  */
168 static fluid_mod_t default_chorus_mod;         /* SF2.01 section 8.4.9  */
169 static fluid_mod_t default_pitch_bend_mod;     /* SF2.01 section 8.4.10 */
170 static fluid_mod_t custom_balance_mod;         /* Non-standard modulator */
171
172
173 /* custom_breath2att_modulator is not a default modulator specified in SF
174 it is intended to replace default_vel2att_mod on demand using
175 API fluid_set_breath_mode() or command shell setbreathmode.
176 */
177 static fluid_mod_t custom_breath2att_mod;
178
179 /* reverb presets */
180 static const fluid_revmodel_presets_t revmodel_preset[] =
181 {
182     /* name */    /* roomsize */ /* damp */ /* width */ /* level */
183     { "Test 1",          0.2f,      0.0f,       0.5f,       0.9f },
184     { "Test 2",          0.4f,      0.2f,       0.5f,       0.8f },
185     { "Test 3",          0.6f,      0.4f,       0.5f,       0.7f },
186     { "Test 4",          0.8f,      0.7f,       0.5f,       0.6f },
187     { "Test 5",          0.8f,      1.0f,       0.5f,       0.5f },
188 };
189
190
191 /***************************************************************
192  *
193  *               INITIALIZATION & UTILITIES
194  */
195
196 void fluid_synth_settings(fluid_settings_t *settings)
197 {
198     fluid_settings_register_int(settings, "synth.verbose", 0, 0, 1, FLUID_HINT_TOGGLED);
199
200     fluid_settings_register_int(settings, "synth.reverb.active", 1, 0, 1, FLUID_HINT_TOGGLED);
201     fluid_settings_register_num(settings, "synth.reverb.room-size", FLUID_REVERB_DEFAULT_ROOMSIZE, 0.0f, 1.0f, 0);
202     fluid_settings_register_num(settings, "synth.reverb.damp", FLUID_REVERB_DEFAULT_DAMP, 0.0f, 1.0f, 0);
203     fluid_settings_register_num(settings, "synth.reverb.width", FLUID_REVERB_DEFAULT_WIDTH, 0.0f, 100.0f, 0);
204     fluid_settings_register_num(settings, "synth.reverb.level", FLUID_REVERB_DEFAULT_LEVEL, 0.0f, 1.0f, 0);
205
206     fluid_settings_register_int(settings, "synth.chorus.active", 1, 0, 1, FLUID_HINT_TOGGLED);
207     fluid_settings_register_int(settings, "synth.chorus.nr", FLUID_CHORUS_DEFAULT_N, 0, 99, 0);
208     fluid_settings_register_num(settings, "synth.chorus.level", FLUID_CHORUS_DEFAULT_LEVEL, 0.0f, 10.0f, 0);
209     fluid_settings_register_num(settings, "synth.chorus.speed", FLUID_CHORUS_DEFAULT_SPEED, 0.29f, 5.0f, 0);
210     fluid_settings_register_num(settings, "synth.chorus.depth", FLUID_CHORUS_DEFAULT_DEPTH, 0.0f, 256.0f, 0);
211
212     fluid_settings_register_int(settings, "synth.ladspa.active", 0, 0, 1, FLUID_HINT_TOGGLED);
213     fluid_settings_register_int(settings, "synth.lock-memory", 1, 0, 1, FLUID_HINT_TOGGLED);
214     fluid_settings_register_str(settings, "midi.portname", "", 0);
215
216 #ifdef DEFAULT_SOUNDFONT
217     fluid_settings_register_str(settings, "synth.default-soundfont", DEFAULT_SOUNDFONT, 0);
218 #endif
219
220     fluid_settings_register_int(settings, "synth.polyphony", 256, 1, 65535, 0);
221     fluid_settings_register_int(settings, "synth.midi-channels", 16, 16, 256, 0);
222     fluid_settings_register_num(settings, "synth.gain", 0.2f, 0.0f, 10.0f, 0);
223     fluid_settings_register_int(settings, "synth.audio-channels", 1, 1, 128, 0);
224     fluid_settings_register_int(settings, "synth.audio-groups", 1, 1, 128, 0);
225     fluid_settings_register_int(settings, "synth.effects-channels", 2, 2, 2, 0);
226     fluid_settings_register_int(settings, "synth.effects-groups", 1, 1, 128, 0);
227     fluid_settings_register_num(settings, "synth.sample-rate", 44100.0f, 8000.0f, 96000.0f, 0);
228     fluid_settings_register_int(settings, "synth.device-id", 0, 0, 126, 0);
229     fluid_settings_register_int(settings, "synth.cpu-cores", 1, 1, 256, 0);
230
231     fluid_settings_register_int(settings, "synth.min-note-length", 10, 0, 65535, 0);
232
233     fluid_settings_register_int(settings, "synth.threadsafe-api", 1, 0, 1, FLUID_HINT_TOGGLED);
234
235     fluid_settings_register_num(settings, "synth.overflow.percussion", 4000, -10000, 10000, 0);
236     fluid_settings_register_num(settings, "synth.overflow.sustained", -1000, -10000, 10000, 0);
237     fluid_settings_register_num(settings, "synth.overflow.released", -2000, -10000, 10000, 0);
238     fluid_settings_register_num(settings, "synth.overflow.age", 1000, -10000, 10000, 0);
239     fluid_settings_register_num(settings, "synth.overflow.volume", 500, -10000, 10000, 0);
240     fluid_settings_register_num(settings, "synth.overflow.important", 5000, -50000, 50000, 0);
241     fluid_settings_register_str(settings, "synth.overflow.important-channels", "", 0);
242
243     fluid_settings_register_str(settings, "synth.midi-bank-select", "gs", 0);
244     fluid_settings_add_option(settings, "synth.midi-bank-select", "gm");
245     fluid_settings_add_option(settings, "synth.midi-bank-select", "gs");
246     fluid_settings_add_option(settings, "synth.midi-bank-select", "xg");
247     fluid_settings_add_option(settings, "synth.midi-bank-select", "mma");
248
249     fluid_settings_register_int(settings, "synth.dynamic-sample-loading", 0, 0, 1, FLUID_HINT_TOGGLED);
250 }
251
252 /**
253  * Get FluidSynth runtime version.
254  * @param major Location to store major number
255  * @param minor Location to store minor number
256  * @param micro Location to store micro number
257  */
258 void fluid_version(int *major, int *minor, int *micro)
259 {
260     *major = FLUIDSYNTH_VERSION_MAJOR;
261     *minor = FLUIDSYNTH_VERSION_MINOR;
262     *micro = FLUIDSYNTH_VERSION_MICRO;
263 }
264
265 /**
266  * Get FluidSynth runtime version as a string.
267  * @return FluidSynth version string, which is internal and should not be
268  *   modified or freed.
269  */
270 const char *
271 fluid_version_str(void)
272 {
273     return FLUIDSYNTH_VERSION;
274 }
275
276 /*
277  * void fluid_synth_init
278  *
279  * Does all the initialization for this module.
280  */
281 static void
282 fluid_synth_init(void)
283 {
284 #ifdef TRAP_ON_FPE
285     /* Turn on floating point exception traps */
286     feenableexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);
287 #endif
288
289     fluid_conversion_config();
290
291     fluid_rvoice_dsp_config();
292
293     init_dither();
294
295     /* custom_breath2att_mod is not a default modulator specified in SF2.01.
296      it is intended to replace default_vel2att_mod on demand using
297      API fluid_set_breath_mode() or command shell setbreathmode.
298      */
299     fluid_mod_set_source1(&custom_breath2att_mod, /* The modulator we are programming here */
300                           BREATH_MSB,    /* Source. breath MSB corresponds to 2. */
301                           FLUID_MOD_CC           /* MIDI continuous controller */
302                           | FLUID_MOD_CONCAVE    /* Curve shape. Corresponds to 'type=1' */
303                           | FLUID_MOD_UNIPOLAR   /* Polarity. Corresponds to 'P=0' */
304                           | FLUID_MOD_NEGATIVE   /* Direction. Corresponds to 'D=1' */
305                          );
306     fluid_mod_set_source2(&custom_breath2att_mod, 0, 0); /* No 2nd source */
307     fluid_mod_set_dest(&custom_breath2att_mod, GEN_ATTENUATION);  /* Target: Initial attenuation */
308     fluid_mod_set_amount(&custom_breath2att_mod, FLUID_PEAK_ATTENUATION); /* Modulation amount: 960 */
309
310     /* SF2.01 page 53 section 8.4.1: MIDI Note-On Velocity to Initial Attenuation */
311     fluid_mod_set_source1(&default_vel2att_mod, /* The modulator we are programming here */
312                           FLUID_MOD_VELOCITY,    /* Source. VELOCITY corresponds to 'index=2'. */
313                           FLUID_MOD_GC           /* Not a MIDI continuous controller */
314                           | FLUID_MOD_CONCAVE    /* Curve shape. Corresponds to 'type=1' */
315                           | FLUID_MOD_UNIPOLAR   /* Polarity. Corresponds to 'P=0' */
316                           | FLUID_MOD_NEGATIVE   /* Direction. Corresponds to 'D=1' */
317                          );
318     fluid_mod_set_source2(&default_vel2att_mod, 0, 0); /* No 2nd source */
319     fluid_mod_set_dest(&default_vel2att_mod, GEN_ATTENUATION);  /* Target: Initial attenuation */
320     fluid_mod_set_amount(&default_vel2att_mod, FLUID_PEAK_ATTENUATION); /* Modulation amount: 960 */
321
322
323
324     /* SF2.01 page 53 section 8.4.2: MIDI Note-On Velocity to Filter Cutoff
325      * Have to make a design decision here. The specs don't make any sense this way or another.
326      * One sound font, 'Kingston Piano', which has been praised for its quality, tries to
327      * override this modulator with an amount of 0 and positive polarity (instead of what
328      * the specs say, D=1) for the secondary source.
329      * So if we change the polarity to 'positive', one of the best free sound fonts works...
330      */
331     fluid_mod_set_source1(&default_vel2filter_mod, FLUID_MOD_VELOCITY, /* Index=2 */
332                           FLUID_MOD_GC                        /* CC=0 */
333                           | FLUID_MOD_LINEAR                  /* type=0 */
334                           | FLUID_MOD_UNIPOLAR                /* P=0 */
335                           | FLUID_MOD_NEGATIVE                /* D=1 */
336                          );
337     fluid_mod_set_source2(&default_vel2filter_mod, FLUID_MOD_VELOCITY, /* Index=2 */
338                           FLUID_MOD_GC                                 /* CC=0 */
339                           | FLUID_MOD_SWITCH                           /* type=3 */
340                           | FLUID_MOD_UNIPOLAR                         /* P=0 */
341                           // do not remove       | FLUID_MOD_NEGATIVE                         /* D=1 */
342                           | FLUID_MOD_POSITIVE                         /* D=0 */
343                          );
344     fluid_mod_set_dest(&default_vel2filter_mod, GEN_FILTERFC);        /* Target: Initial filter cutoff */
345     fluid_mod_set_amount(&default_vel2filter_mod, -2400);
346
347
348
349     /* SF2.01 page 53 section 8.4.3: MIDI Channel pressure to Vibrato LFO pitch depth */
350     fluid_mod_set_source1(&default_at2viblfo_mod, FLUID_MOD_CHANNELPRESSURE, /* Index=13 */
351                           FLUID_MOD_GC                        /* CC=0 */
352                           | FLUID_MOD_LINEAR                  /* type=0 */
353                           | FLUID_MOD_UNIPOLAR                /* P=0 */
354                           | FLUID_MOD_POSITIVE                /* D=0 */
355                          );
356     fluid_mod_set_source2(&default_at2viblfo_mod, 0, 0); /* no second source */
357     fluid_mod_set_dest(&default_at2viblfo_mod, GEN_VIBLFOTOPITCH);        /* Target: Vib. LFO => pitch */
358     fluid_mod_set_amount(&default_at2viblfo_mod, 50);
359
360
361
362     /* SF2.01 page 53 section 8.4.4: Mod wheel (Controller 1) to Vibrato LFO pitch depth */
363     fluid_mod_set_source1(&default_mod2viblfo_mod, MODULATION_MSB, /* Index=1 */
364                           FLUID_MOD_CC                        /* CC=1 */
365                           | FLUID_MOD_LINEAR                  /* type=0 */
366                           | FLUID_MOD_UNIPOLAR                /* P=0 */
367                           | FLUID_MOD_POSITIVE                /* D=0 */
368                          );
369     fluid_mod_set_source2(&default_mod2viblfo_mod, 0, 0); /* no second source */
370     fluid_mod_set_dest(&default_mod2viblfo_mod, GEN_VIBLFOTOPITCH);        /* Target: Vib. LFO => pitch */
371     fluid_mod_set_amount(&default_mod2viblfo_mod, 50);
372
373
374
375     /* SF2.01 page 55 section 8.4.5: MIDI continuous controller 7 to initial attenuation*/
376     fluid_mod_set_source1(&default_att_mod, VOLUME_MSB,    /* index=7 */
377                           FLUID_MOD_CC                              /* CC=1 */
378                           | FLUID_MOD_CONCAVE                       /* type=1 */
379                           | FLUID_MOD_UNIPOLAR                      /* P=0 */
380                           | FLUID_MOD_NEGATIVE                      /* D=1 */
381                          );
382     fluid_mod_set_source2(&default_att_mod, 0, 0);                 /* No second source */
383     fluid_mod_set_dest(&default_att_mod, GEN_ATTENUATION);         /* Target: Initial attenuation */
384     fluid_mod_set_amount(&default_att_mod, FLUID_PEAK_ATTENUATION);  /* Amount: 960 */
385
386
387
388     /* SF2.01 page 55 section 8.4.6 MIDI continuous controller 10 to Pan Position */
389     fluid_mod_set_source1(&default_pan_mod, PAN_MSB,       /* index=10 */
390                           FLUID_MOD_CC                              /* CC=1 */
391                           | FLUID_MOD_LINEAR                        /* type=0 */
392                           | FLUID_MOD_BIPOLAR                       /* P=1 */
393                           | FLUID_MOD_POSITIVE                      /* D=0 */
394                          );
395     fluid_mod_set_source2(&default_pan_mod, 0, 0);                 /* No second source */
396     fluid_mod_set_dest(&default_pan_mod, GEN_PAN);                 /* Target: pan */
397     /* Amount: 500. The SF specs $8.4.6, p. 55 syas: "Amount = 1000
398        tenths of a percent". The center value (64) corresponds to 50%,
399        so it follows that amount = 50% x 1000/% = 500. */
400     fluid_mod_set_amount(&default_pan_mod, 500.0);
401
402
403     /* SF2.01 page 55 section 8.4.7: MIDI continuous controller 11 to initial attenuation*/
404     fluid_mod_set_source1(&default_expr_mod, EXPRESSION_MSB, /* index=11 */
405                           FLUID_MOD_CC                              /* CC=1 */
406                           | FLUID_MOD_CONCAVE                       /* type=1 */
407                           | FLUID_MOD_UNIPOLAR                      /* P=0 */
408                           | FLUID_MOD_NEGATIVE                      /* D=1 */
409                          );
410     fluid_mod_set_source2(&default_expr_mod, 0, 0);                 /* No second source */
411     fluid_mod_set_dest(&default_expr_mod, GEN_ATTENUATION);         /* Target: Initial attenuation */
412     fluid_mod_set_amount(&default_expr_mod, FLUID_PEAK_ATTENUATION);  /* Amount: 960 */
413
414
415
416     /* SF2.01 page 55 section 8.4.8: MIDI continuous controller 91 to Reverb send */
417     fluid_mod_set_source1(&default_reverb_mod, EFFECTS_DEPTH1, /* index=91 */
418                           FLUID_MOD_CC                              /* CC=1 */
419                           | FLUID_MOD_LINEAR                        /* type=0 */
420                           | FLUID_MOD_UNIPOLAR                      /* P=0 */
421                           | FLUID_MOD_POSITIVE                      /* D=0 */
422                          );
423     fluid_mod_set_source2(&default_reverb_mod, 0, 0);              /* No second source */
424     fluid_mod_set_dest(&default_reverb_mod, GEN_REVERBSEND);       /* Target: Reverb send */
425     fluid_mod_set_amount(&default_reverb_mod, 200);                /* Amount: 200 ('tenths of a percent') */
426
427
428
429     /* SF2.01 page 55 section 8.4.9: MIDI continuous controller 93 to Chorus send */
430     fluid_mod_set_source1(&default_chorus_mod, EFFECTS_DEPTH3, /* index=93 */
431                           FLUID_MOD_CC                              /* CC=1 */
432                           | FLUID_MOD_LINEAR                        /* type=0 */
433                           | FLUID_MOD_UNIPOLAR                      /* P=0 */
434                           | FLUID_MOD_POSITIVE                      /* D=0 */
435                          );
436     fluid_mod_set_source2(&default_chorus_mod, 0, 0);              /* No second source */
437     fluid_mod_set_dest(&default_chorus_mod, GEN_CHORUSSEND);       /* Target: Chorus */
438     fluid_mod_set_amount(&default_chorus_mod, 200);                /* Amount: 200 ('tenths of a percent') */
439
440
441
442     /* SF2.01 page 57 section 8.4.10 MIDI Pitch Wheel to Initial Pitch ... */
443     fluid_mod_set_source1(&default_pitch_bend_mod, FLUID_MOD_PITCHWHEEL, /* Index=14 */
444                           FLUID_MOD_GC                              /* CC =0 */
445                           | FLUID_MOD_LINEAR                        /* type=0 */
446                           | FLUID_MOD_BIPOLAR                       /* P=1 */
447                           | FLUID_MOD_POSITIVE                      /* D=0 */
448                          );
449     fluid_mod_set_source2(&default_pitch_bend_mod, FLUID_MOD_PITCHWHEELSENS,  /* Index = 16 */
450                           FLUID_MOD_GC                                        /* CC=0 */
451                           | FLUID_MOD_LINEAR                                  /* type=0 */
452                           | FLUID_MOD_UNIPOLAR                                /* P=0 */
453                           | FLUID_MOD_POSITIVE                                /* D=0 */
454                          );
455     fluid_mod_set_dest(&default_pitch_bend_mod, GEN_PITCH);                 /* Destination: Initial pitch */
456     fluid_mod_set_amount(&default_pitch_bend_mod, 12700.0);                 /* Amount: 12700 cents */
457
458
459     /* Non-standard MIDI continuous controller 8 to channel stereo balance */
460     fluid_mod_set_source1(&custom_balance_mod, BALANCE_MSB, /* Index=8 */
461                           FLUID_MOD_CC                              /* CC=1 */
462                           | FLUID_MOD_CONCAVE                       /* type=1 */
463                           | FLUID_MOD_BIPOLAR                       /* P=1 */
464                           | FLUID_MOD_POSITIVE                      /* D=0 */
465                          );
466     fluid_mod_set_source2(&custom_balance_mod, 0, 0);
467     fluid_mod_set_dest(&custom_balance_mod, GEN_CUSTOM_BALANCE);     /* Destination: stereo balance */
468     /* Amount: 96 dB of attenuation (on the opposite channel) */
469     fluid_mod_set_amount(&custom_balance_mod, FLUID_PEAK_ATTENUATION); /* Amount: 960 */
470 }
471
472 static FLUID_INLINE unsigned int fluid_synth_get_ticks(fluid_synth_t *synth)
473 {
474     return fluid_atomic_int_get(&synth->ticks_since_start);
475 }
476
477 static FLUID_INLINE void fluid_synth_add_ticks(fluid_synth_t *synth, int val)
478 {
479     fluid_atomic_int_add(&synth->ticks_since_start, val);
480 }
481
482
483 /***************************************************************
484  *                    FLUID SAMPLE TIMERS
485  *    Timers that use written audio data as timing reference
486  */
487 struct _fluid_sample_timer_t
488 {
489     fluid_sample_timer_t *next; /* Single linked list of timers */
490     unsigned long starttick;
491     fluid_timer_callback_t callback;
492     void *data;
493     int isfinished;
494 };
495
496 /*
497  * fluid_sample_timer_process - called when synth->ticks is updated
498  */
499 static void fluid_sample_timer_process(fluid_synth_t *synth)
500 {
501     fluid_sample_timer_t *st, *stnext;
502     long msec;
503     int cont;
504     unsigned int ticks = fluid_synth_get_ticks(synth);
505
506     for(st = synth->sample_timers; st; st = stnext)
507     {
508         /* st may be freed in the callback below. cache it's successor now to avoid use after free */
509         stnext = st->next;
510
511         if(st->isfinished)
512         {
513             continue;
514         }
515
516         msec = (long)(1000.0 * ((double)(ticks - st->starttick)) / synth->sample_rate);
517         cont = (*st->callback)(st->data, msec);
518
519         if(cont == 0)
520         {
521             st->isfinished = 1;
522         }
523     }
524 }
525
526 fluid_sample_timer_t *new_fluid_sample_timer(fluid_synth_t *synth, fluid_timer_callback_t callback, void *data)
527 {
528     fluid_sample_timer_t *result = FLUID_NEW(fluid_sample_timer_t);
529
530     if(result == NULL)
531     {
532         FLUID_LOG(FLUID_ERR, "Out of memory");
533         return NULL;
534     }
535
536     result->starttick = fluid_synth_get_ticks(synth);
537     result->isfinished = 0;
538     result->data = data;
539     result->callback = callback;
540     result->next = synth->sample_timers;
541     synth->sample_timers = result;
542     return result;
543 }
544
545 void delete_fluid_sample_timer(fluid_synth_t *synth, fluid_sample_timer_t *timer)
546 {
547     fluid_sample_timer_t **ptr;
548     fluid_return_if_fail(synth != NULL);
549     fluid_return_if_fail(timer != NULL);
550
551     ptr = &synth->sample_timers;
552
553     while(*ptr)
554     {
555         if(*ptr == timer)
556         {
557             *ptr = timer->next;
558             FLUID_FREE(timer);
559             return;
560         }
561
562         ptr = &((*ptr)->next);
563     }
564 }
565
566
567 /***************************************************************
568  *
569  *                      FLUID SYNTH
570  */
571
572 static FLUID_INLINE void
573 fluid_synth_update_mixer(fluid_synth_t *synth, fluid_rvoice_function_t method, int intparam,
574                          fluid_real_t realparam)
575 {
576     fluid_return_if_fail(synth != NULL && synth->eventhandler != NULL);
577     fluid_return_if_fail(synth->eventhandler->mixer != NULL);
578     fluid_rvoice_eventhandler_push_int_real(synth->eventhandler, method,
579                                             synth->eventhandler->mixer,
580                                             intparam, realparam);
581 }
582
583 static FLUID_INLINE unsigned int fluid_synth_get_min_note_length_LOCAL(fluid_synth_t *synth)
584 {
585     int i;
586     fluid_settings_getint(synth->settings, "synth.min-note-length", &i);
587     return (unsigned int)(i * synth->sample_rate / 1000.0f);
588 }
589
590 /**
591  * Create new FluidSynth instance.
592  * @param settings Configuration parameters to use (used directly).
593  * @return New FluidSynth instance or NULL on error
594  *
595  * @note The settings parameter is used directly and should not be modified
596  * or freed independently.
597  */
598 fluid_synth_t *
599 new_fluid_synth(fluid_settings_t *settings)
600 {
601     fluid_synth_t *synth;
602     fluid_sfloader_t *loader;
603     char *important_channels;
604     int i, nbuf, prio_level = 0;
605     int with_ladspa = 0;
606
607     /* initialize all the conversion tables and other stuff */
608     if(fluid_atomic_int_compare_and_exchange(&fluid_synth_initialized, 0, 1))
609     {
610         fluid_synth_init();
611     }
612
613     /* allocate a new synthesizer object */
614     synth = FLUID_NEW(fluid_synth_t);
615
616     if(synth == NULL)
617     {
618         FLUID_LOG(FLUID_ERR, "Out of memory");
619         return NULL;
620     }
621
622     FLUID_MEMSET(synth, 0, sizeof(fluid_synth_t));
623
624     fluid_rec_mutex_init(synth->mutex);
625     fluid_settings_getint(settings, "synth.threadsafe-api", &synth->use_mutex);
626     synth->public_api_count = 0;
627
628     synth->settings = settings;
629
630     fluid_settings_getint(settings, "synth.reverb.active", &synth->with_reverb);
631     fluid_settings_getint(settings, "synth.chorus.active", &synth->with_chorus);
632     fluid_settings_getint(settings, "synth.verbose", &synth->verbose);
633
634     fluid_settings_getint(settings, "synth.polyphony", &synth->polyphony);
635     fluid_settings_getnum(settings, "synth.sample-rate", &synth->sample_rate);
636     fluid_settings_getint(settings, "synth.midi-channels", &synth->midi_channels);
637     fluid_settings_getint(settings, "synth.audio-channels", &synth->audio_channels);
638     fluid_settings_getint(settings, "synth.audio-groups", &synth->audio_groups);
639     fluid_settings_getint(settings, "synth.effects-channels", &synth->effects_channels);
640     fluid_settings_getint(settings, "synth.effects-groups", &synth->effects_groups);
641     fluid_settings_getnum_float(settings, "synth.gain", &synth->gain);
642     fluid_settings_getint(settings, "synth.device-id", &synth->device_id);
643     fluid_settings_getint(settings, "synth.cpu-cores", &synth->cores);
644
645     fluid_settings_getnum_float(settings, "synth.overflow.percussion", &synth->overflow.percussion);
646     fluid_settings_getnum_float(settings, "synth.overflow.released", &synth->overflow.released);
647     fluid_settings_getnum_float(settings, "synth.overflow.sustained", &synth->overflow.sustained);
648     fluid_settings_getnum_float(settings, "synth.overflow.volume", &synth->overflow.volume);
649     fluid_settings_getnum_float(settings, "synth.overflow.age", &synth->overflow.age);
650     fluid_settings_getnum_float(settings, "synth.overflow.important", &synth->overflow.important);
651
652     /* register the callbacks */
653     fluid_settings_callback_num(settings, "synth.sample-rate",
654                                 fluid_synth_handle_sample_rate, synth);
655     fluid_settings_callback_num(settings, "synth.gain",
656                                 fluid_synth_handle_gain, synth);
657     fluid_settings_callback_int(settings, "synth.polyphony",
658                                 fluid_synth_handle_polyphony, synth);
659     fluid_settings_callback_int(settings, "synth.device-id",
660                                 fluid_synth_handle_device_id, synth);
661     fluid_settings_callback_num(settings, "synth.overflow.percussion",
662                                 fluid_synth_handle_overflow, synth);
663     fluid_settings_callback_num(settings, "synth.overflow.sustained",
664                                 fluid_synth_handle_overflow, synth);
665     fluid_settings_callback_num(settings, "synth.overflow.released",
666                                 fluid_synth_handle_overflow, synth);
667     fluid_settings_callback_num(settings, "synth.overflow.age",
668                                 fluid_synth_handle_overflow, synth);
669     fluid_settings_callback_num(settings, "synth.overflow.volume",
670                                 fluid_synth_handle_overflow, synth);
671     fluid_settings_callback_num(settings, "synth.overflow.important",
672                                 fluid_synth_handle_overflow, synth);
673     fluid_settings_callback_str(settings, "synth.overflow.important-channels",
674                                 fluid_synth_handle_important_channels, synth);
675     fluid_settings_callback_num(settings, "synth.reverb.room-size",
676                                 fluid_synth_handle_reverb_chorus_num, synth);
677     fluid_settings_callback_num(settings, "synth.reverb.damp",
678                                 fluid_synth_handle_reverb_chorus_num, synth);
679     fluid_settings_callback_num(settings, "synth.reverb.width",
680                                 fluid_synth_handle_reverb_chorus_num, synth);
681     fluid_settings_callback_num(settings, "synth.reverb.level",
682                                 fluid_synth_handle_reverb_chorus_num, synth);
683     fluid_settings_callback_int(settings, "synth.reverb.active",
684                                 fluid_synth_handle_reverb_chorus_int, synth);
685     fluid_settings_callback_int(settings, "synth.chorus.active",
686                                 fluid_synth_handle_reverb_chorus_int, synth);
687     fluid_settings_callback_int(settings, "synth.chorus.nr",
688                                 fluid_synth_handle_reverb_chorus_int, synth);
689     fluid_settings_callback_num(settings, "synth.chorus.level",
690                                 fluid_synth_handle_reverb_chorus_num, synth);
691     fluid_settings_callback_num(settings, "synth.chorus.depth",
692                                 fluid_synth_handle_reverb_chorus_num, synth);
693     fluid_settings_callback_num(settings, "synth.chorus.speed",
694                                 fluid_synth_handle_reverb_chorus_num, synth);
695
696     /* do some basic sanity checking on the settings */
697
698     if(synth->midi_channels % 16 != 0)
699     {
700         int n = synth->midi_channels / 16;
701         synth->midi_channels = (n + 1) * 16;
702         fluid_settings_setint(settings, "synth.midi-channels", synth->midi_channels);
703         FLUID_LOG(FLUID_WARN, "Requested number of MIDI channels is not a multiple of 16. "
704                   "I'll increase the number of channels to the next multiple.");
705     }
706
707     if(synth->audio_channels < 1)
708     {
709         FLUID_LOG(FLUID_WARN, "Requested number of audio channels is smaller than 1. "
710                   "Changing this setting to 1.");
711         synth->audio_channels = 1;
712     }
713     else if(synth->audio_channels > 128)
714     {
715         FLUID_LOG(FLUID_WARN, "Requested number of audio channels is too big (%d). "
716                   "Limiting this setting to 128.", synth->audio_channels);
717         synth->audio_channels = 128;
718     }
719
720     if(synth->audio_groups < 1)
721     {
722         FLUID_LOG(FLUID_WARN, "Requested number of audio groups is smaller than 1. "
723                   "Changing this setting to 1.");
724         synth->audio_groups = 1;
725     }
726     else if(synth->audio_groups > 128)
727     {
728         FLUID_LOG(FLUID_WARN, "Requested number of audio groups is too big (%d). "
729                   "Limiting this setting to 128.", synth->audio_groups);
730         synth->audio_groups = 128;
731     }
732
733     if(synth->effects_channels < 2)
734     {
735         FLUID_LOG(FLUID_WARN, "Invalid number of effects channels (%d)."
736                   "Setting effects channels to 2.", synth->effects_channels);
737         synth->effects_channels = 2;
738     }
739
740     /* The number of buffers is determined by the higher number of nr
741      * groups / nr audio channels.  If LADSPA is unused, they should be
742      * the same. */
743     nbuf = synth->audio_channels;
744
745     if(synth->audio_groups > nbuf)
746     {
747         nbuf = synth->audio_groups;
748     }
749
750     if(fluid_settings_dupstr(settings, "synth.overflow.important-channels",
751                              &important_channels) == FLUID_OK)
752     {
753         if(fluid_synth_set_important_channels(synth, important_channels) != FLUID_OK)
754         {
755             FLUID_LOG(FLUID_WARN, "Failed to set overflow important channels");
756         }
757
758         FLUID_FREE(important_channels);
759     }
760
761     /* as soon as the synth is created it starts playing. */
762     synth->state = FLUID_SYNTH_PLAYING;
763
764     synth->fromkey_portamento = INVALID_NOTE;           /* disable portamento */
765
766     fluid_atomic_int_set(&synth->ticks_since_start, 0);
767     synth->tuning = NULL;
768     fluid_private_init(synth->tuning_iter);
769
770     /* Initialize multi-core variables if multiple cores enabled */
771     if(synth->cores > 1)
772     {
773         fluid_settings_getint(synth->settings, "audio.realtime-prio", &prio_level);
774     }
775
776     /* Allocate event queue for rvoice mixer */
777     /* In an overflow situation, a new voice takes about 50 spaces in the queue! */
778     synth->eventhandler = new_fluid_rvoice_eventhandler(synth->polyphony * 64,
779                           synth->polyphony, nbuf, synth->effects_channels, synth->effects_groups, synth->sample_rate, synth->cores - 1, prio_level);
780
781     if(synth->eventhandler == NULL)
782     {
783         goto error_recovery;
784     }
785
786     /* Setup the list of default modulators.
787      * Needs to happen after eventhandler has been set up, as fluid_synth_enter_api is called in the process */
788     synth->default_mod = NULL;
789     fluid_synth_add_default_mod(synth, &default_vel2att_mod, FLUID_SYNTH_ADD);
790     fluid_synth_add_default_mod(synth, &default_vel2filter_mod, FLUID_SYNTH_ADD);
791     fluid_synth_add_default_mod(synth, &default_at2viblfo_mod, FLUID_SYNTH_ADD);
792     fluid_synth_add_default_mod(synth, &default_mod2viblfo_mod, FLUID_SYNTH_ADD);
793     fluid_synth_add_default_mod(synth, &default_att_mod, FLUID_SYNTH_ADD);
794     fluid_synth_add_default_mod(synth, &default_pan_mod, FLUID_SYNTH_ADD);
795     fluid_synth_add_default_mod(synth, &default_expr_mod, FLUID_SYNTH_ADD);
796     fluid_synth_add_default_mod(synth, &default_reverb_mod, FLUID_SYNTH_ADD);
797     fluid_synth_add_default_mod(synth, &default_chorus_mod, FLUID_SYNTH_ADD);
798     fluid_synth_add_default_mod(synth, &default_pitch_bend_mod, FLUID_SYNTH_ADD);
799     fluid_synth_add_default_mod(synth, &custom_balance_mod, FLUID_SYNTH_ADD);
800
801     /* Create and initialize the Fx unit.*/
802     fluid_settings_getint(settings, "synth.ladspa.active", &with_ladspa);
803
804     if(with_ladspa)
805     {
806 #ifdef LADSPA
807         synth->ladspa_fx = new_fluid_ladspa_fx(synth->sample_rate,
808                                                FLUID_MIXER_MAX_BUFFERS_DEFAULT * FLUID_BUFSIZE);
809
810         if(synth->ladspa_fx == NULL)
811         {
812             FLUID_LOG(FLUID_ERR, "Out of memory");
813             goto error_recovery;
814         }
815
816         fluid_rvoice_mixer_set_ladspa(synth->eventhandler->mixer, synth->ladspa_fx,
817                                       synth->audio_groups);
818 #else /* LADSPA */
819         FLUID_LOG(FLUID_WARN, "FluidSynth has not been compiled with LADSPA support");
820 #endif /* LADSPA */
821     }
822
823     /* allocate and add the default sfont loader */
824     loader = new_fluid_defsfloader(settings);
825
826     if(loader == NULL)
827     {
828         FLUID_LOG(FLUID_WARN, "Failed to create the default SoundFont loader");
829     }
830     else
831     {
832         fluid_synth_add_sfloader(synth, loader);
833     }
834
835     /* allocate all channel objects */
836     synth->channel = FLUID_ARRAY(fluid_channel_t *, synth->midi_channels);
837
838     if(synth->channel == NULL)
839     {
840         FLUID_LOG(FLUID_ERR, "Out of memory");
841         goto error_recovery;
842     }
843
844     for(i = 0; i < synth->midi_channels; i++)
845     {
846         synth->channel[i] = new_fluid_channel(synth, i);
847
848         if(synth->channel[i] == NULL)
849         {
850             goto error_recovery;
851         }
852     }
853
854     /* allocate all synthesis processes */
855     synth->nvoice = synth->polyphony;
856     synth->voice = FLUID_ARRAY(fluid_voice_t *, synth->nvoice);
857
858     if(synth->voice == NULL)
859     {
860         goto error_recovery;
861     }
862
863     for(i = 0; i < synth->nvoice; i++)
864     {
865         synth->voice[i] = new_fluid_voice(synth->eventhandler, synth->sample_rate);
866
867         if(synth->voice[i] == NULL)
868         {
869             goto error_recovery;
870         }
871     }
872
873     /* sets a default basic channel */
874     /* Sets one basic channel: basic channel 0, mode 0 (Omni On - Poly) */
875     /* (i.e all channels are polyphonic) */
876     /* Must be called after channel objects allocation */
877     fluid_synth_set_basic_channel_LOCAL(synth, 0, FLUID_CHANNEL_MODE_OMNION_POLY,
878                                         synth->midi_channels);
879
880     synth->min_note_length_ticks = fluid_synth_get_min_note_length_LOCAL(synth);
881
882
883     fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_polyphony,
884                              synth->polyphony, 0.0f);
885     fluid_synth_set_reverb_on(synth, synth->with_reverb);
886     fluid_synth_set_chorus_on(synth, synth->with_chorus);
887
888     synth->cur = FLUID_BUFSIZE;
889     synth->curmax = 0;
890     synth->dither_index = 0;
891
892     {
893         double room, damp, width, level;
894
895         fluid_settings_getnum(settings, "synth.reverb.room-size", &room);
896         fluid_settings_getnum(settings, "synth.reverb.damp", &damp);
897         fluid_settings_getnum(settings, "synth.reverb.width", &width);
898         fluid_settings_getnum(settings, "synth.reverb.level", &level);
899
900         fluid_synth_set_reverb_full_LOCAL(synth,
901                                           FLUID_REVMODEL_SET_ALL,
902                                           room,
903                                           damp,
904                                           width,
905                                           level);
906     }
907
908     {
909         double level, speed, depth;
910
911         fluid_settings_getint(settings, "synth.chorus.nr", &i);
912         fluid_settings_getnum(settings, "synth.chorus.level", &level);
913         fluid_settings_getnum(settings, "synth.chorus.speed", &speed);
914         fluid_settings_getnum(settings, "synth.chorus.depth", &depth);
915
916         fluid_synth_set_chorus_full_LOCAL(synth,
917                                           FLUID_CHORUS_SET_ALL,
918                                           i,
919                                           level,
920                                           speed,
921                                           depth,
922                                           FLUID_CHORUS_DEFAULT_TYPE);
923     }
924
925
926     synth->bank_select = FLUID_BANK_STYLE_GS;
927
928     if(fluid_settings_str_equal(settings, "synth.midi-bank-select", "gm"))
929     {
930         synth->bank_select = FLUID_BANK_STYLE_GM;
931     }
932     else if(fluid_settings_str_equal(settings, "synth.midi-bank-select", "gs"))
933     {
934         synth->bank_select = FLUID_BANK_STYLE_GS;
935     }
936     else if(fluid_settings_str_equal(settings, "synth.midi-bank-select", "xg"))
937     {
938         synth->bank_select = FLUID_BANK_STYLE_XG;
939     }
940     else if(fluid_settings_str_equal(settings, "synth.midi-bank-select", "mma"))
941     {
942         synth->bank_select = FLUID_BANK_STYLE_MMA;
943     }
944
945     fluid_synth_process_event_queue(synth);
946
947     /* FIXME */
948     synth->start = fluid_curtime();
949
950     return synth;
951
952 error_recovery:
953     delete_fluid_synth(synth);
954     return NULL;
955 }
956
957
958 /**
959  * Delete a FluidSynth instance.
960  * @param synth FluidSynth instance to delete
961  *
962  * @note Other users of a synthesizer instance, such as audio and MIDI drivers,
963  * should be deleted prior to freeing the FluidSynth instance.
964  */
965 void
966 delete_fluid_synth(fluid_synth_t *synth)
967 {
968     int i, k;
969     fluid_list_t *list;
970     fluid_sfont_t *sfont;
971     fluid_sfloader_t *loader;
972     fluid_mod_t *default_mod;
973     fluid_mod_t *mod;
974
975     fluid_return_if_fail(synth != NULL);
976
977     fluid_profiling_print();
978
979     /* turn off all voices, needed to unload SoundFont data */
980     if(synth->voice != NULL)
981     {
982         for(i = 0; i < synth->nvoice; i++)
983         {
984             fluid_voice_t *voice = synth->voice[i];
985
986             if(!voice)
987             {
988                 continue;
989             }
990
991             fluid_voice_unlock_rvoice(voice);
992             fluid_voice_overflow_rvoice_finished(voice);
993
994             if(fluid_voice_is_playing(voice))
995             {
996                 fluid_voice_off(voice);
997                 /* If we only use fluid_voice_off(voice) it will trigger a delayed
998                  * fluid_voice_stop(voice) via fluid_synth_check_finished_voices().
999                  * But here, we are deleting the fluid_synth_t instance so
1000                  * fluid_voice_stop() will be never triggered resulting in
1001                  * SoundFont data never unloaded (i.e a serious memory leak).
1002                  * So, fluid_voice_stop() must be explicitly called to insure
1003                  * unloading SoundFont data
1004                  */
1005                 fluid_voice_stop(voice);
1006             }
1007         }
1008     }
1009
1010     /* also unset all presets for clean SoundFont unload */
1011     if(synth->channel != NULL)
1012     {
1013         for(i = 0; i < synth->midi_channels; i++)
1014         {
1015             fluid_channel_set_preset(synth->channel[i], NULL);
1016         }
1017     }
1018
1019     delete_fluid_rvoice_eventhandler(synth->eventhandler);
1020
1021     /* delete all the SoundFonts */
1022     for(list = synth->sfont; list; list = fluid_list_next(list))
1023     {
1024         sfont = fluid_list_get(list);
1025         fluid_sfont_delete_internal(sfont);
1026     }
1027
1028     delete_fluid_list(synth->sfont);
1029
1030     /* delete all the SoundFont loaders */
1031
1032     for(list = synth->loaders; list; list = fluid_list_next(list))
1033     {
1034         loader = (fluid_sfloader_t *) fluid_list_get(list);
1035         fluid_sfloader_delete(loader);
1036     }
1037
1038     delete_fluid_list(synth->loaders);
1039
1040
1041     if(synth->channel != NULL)
1042     {
1043         for(i = 0; i < synth->midi_channels; i++)
1044         {
1045             delete_fluid_channel(synth->channel[i]);
1046         }
1047
1048         FLUID_FREE(synth->channel);
1049     }
1050
1051     if(synth->voice != NULL)
1052     {
1053         for(i = 0; i < synth->nvoice; i++)
1054         {
1055             delete_fluid_voice(synth->voice[i]);
1056         }
1057
1058         FLUID_FREE(synth->voice);
1059     }
1060
1061
1062     /* free the tunings, if any */
1063     if(synth->tuning != NULL)
1064     {
1065         for(i = 0; i < 128; i++)
1066         {
1067             if(synth->tuning[i] != NULL)
1068             {
1069                 for(k = 0; k < 128; k++)
1070                 {
1071                     delete_fluid_tuning(synth->tuning[i][k]);
1072                 }
1073
1074                 FLUID_FREE(synth->tuning[i]);
1075             }
1076         }
1077
1078         FLUID_FREE(synth->tuning);
1079     }
1080
1081     fluid_private_free(synth->tuning_iter);
1082
1083 #ifdef LADSPA
1084     /* Release the LADSPA effects unit */
1085     delete_fluid_ladspa_fx(synth->ladspa_fx);
1086 #endif
1087
1088     /* delete all default modulators */
1089     default_mod = synth->default_mod;
1090
1091     while(default_mod != NULL)
1092     {
1093         mod = default_mod;
1094         default_mod = mod->next;
1095         delete_fluid_mod(mod);
1096     }
1097
1098     FLUID_FREE(synth->overflow.important_channels);
1099
1100     fluid_rec_mutex_destroy(synth->mutex);
1101
1102     FLUID_FREE(synth);
1103 }
1104
1105 /**
1106  * Get a textual representation of the last error
1107  * @param synth FluidSynth instance
1108  * @return Pointer to string of last error message.  Valid until the same
1109  *   calling thread calls another FluidSynth function which fails.  String is
1110  *   internal and should not be modified or freed.
1111  */
1112 /* FIXME - The error messages are not thread-safe, yet. They are still stored
1113  * in a global message buffer (see fluid_sys.c). */
1114 const char *
1115 fluid_synth_error(fluid_synth_t *synth)
1116 {
1117     return fluid_error();
1118 }
1119
1120 /**
1121  * Send a note-on event to a FluidSynth object.
1122  * @param synth FluidSynth instance
1123  * @param chan MIDI channel number (0 to MIDI channel count - 1)
1124  * @param key MIDI note number (0-127)
1125  * @param vel MIDI velocity (0-127, 0=noteoff)
1126  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
1127  */
1128 int
1129 fluid_synth_noteon(fluid_synth_t *synth, int chan, int key, int vel)
1130 {
1131     int result;
1132     fluid_return_val_if_fail(key >= 0 && key <= 127, FLUID_FAILED);
1133     fluid_return_val_if_fail(vel >= 0 && vel <= 127, FLUID_FAILED);
1134     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
1135
1136     /* Allowed only on MIDI channel enabled */
1137     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
1138
1139     result = fluid_synth_noteon_LOCAL(synth, chan, key, vel);
1140     FLUID_API_RETURN(result);
1141 }
1142
1143 /* Local synthesis thread variant of fluid_synth_noteon */
1144 static int
1145 fluid_synth_noteon_LOCAL(fluid_synth_t *synth, int chan, int key, int vel)
1146 {
1147     fluid_channel_t *channel ;
1148
1149     /* notes with velocity zero go to noteoff  */
1150     if(vel == 0)
1151     {
1152         return fluid_synth_noteoff_LOCAL(synth, chan, key);
1153     }
1154
1155     channel = synth->channel[chan];
1156
1157     /* makes sure this channel has a preset */
1158     if(channel->preset == NULL)
1159     {
1160         if(synth->verbose)
1161         {
1162             FLUID_LOG(FLUID_INFO, "noteon\t%d\t%d\t%d\t%05d\t%.3f\t%.3f\t%.3f\t%d\t%s",
1163                       chan, key, vel, 0,
1164                       fluid_synth_get_ticks(synth) / 44100.0f,
1165                       (fluid_curtime() - synth->start) / 1000.0f,
1166                       0.0f, 0, "channel has no preset");
1167         }
1168
1169         return FLUID_FAILED;
1170     }
1171
1172     if(fluid_channel_is_playing_mono(channel)) /* channel is mono or legato CC is On) */
1173     {
1174         /* play the noteOn in monophonic */
1175         return fluid_synth_noteon_mono_LOCAL(synth, chan, key, vel);
1176     }
1177     else
1178     {
1179         /* channel is poly and legato CC is Off) */
1180
1181         /* plays the noteOn in polyphonic */
1182         /* Sets the note at first position in monophonic list */
1183         /* In the case where the musician intends to inter the channel in monophonic
1184         (by depressing the CC legato on), the next noteOn mono could be played legato
1185          with the previous note poly (if the musician choose this).
1186             */
1187         fluid_channel_set_onenote_monolist(channel, (unsigned char) key,
1188                                            (unsigned char) vel);
1189
1190         /* If there is another voice process on the same channel and key,
1191            advance it to the release phase. */
1192         fluid_synth_release_voice_on_same_note_LOCAL(synth, chan, key);
1193
1194         /* a noteon poly is passed to fluid_synth_noteon_monopoly_legato().
1195           This allows an opportunity to get this note played legato with a previous
1196           note if a CC PTC have been received before this noteon. This behavior is
1197           a MIDI specification (see FluidPolymono-0004.pdf chapter 4.3-a ,3.4.11
1198           for details).
1199         */
1200         return fluid_synth_noteon_monopoly_legato(synth, chan, INVALID_NOTE, key, vel);
1201     }
1202 }
1203
1204 /**
1205  * Sends a note-off event to a FluidSynth object.
1206  * @param synth FluidSynth instance
1207  * @param chan MIDI channel number (0 to MIDI channel count - 1)
1208  * @param key MIDI note number (0-127)
1209  * @return #FLUID_OK on success, #FLUID_FAILED otherwise (may just mean that no
1210  *   voices matched the note off event)
1211  */
1212 int
1213 fluid_synth_noteoff(fluid_synth_t *synth, int chan, int key)
1214 {
1215     int result;
1216     fluid_return_val_if_fail(key >= 0 && key <= 127, FLUID_FAILED);
1217     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
1218
1219     /* Allowed only on MIDI channel enabled */
1220     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
1221
1222     result = fluid_synth_noteoff_LOCAL(synth, chan, key);
1223     FLUID_API_RETURN(result);
1224 }
1225
1226 /* Local synthesis thread variant of fluid_synth_noteoff */
1227 static int
1228 fluid_synth_noteoff_LOCAL(fluid_synth_t *synth, int chan, int key)
1229 {
1230     int status;
1231     fluid_channel_t *channel = synth->channel[chan];
1232
1233     if(fluid_channel_is_playing_mono(channel)) /* channel is mono or legato CC is On) */
1234     {
1235         /* play the noteOff in monophonic */
1236         status = fluid_synth_noteoff_mono_LOCAL(synth, chan, key);
1237     }
1238     else
1239     {
1240         /* channel is poly and legato CC is Off) */
1241         /* removes the note from the monophonic list */
1242         if(key == fluid_channel_last_note(channel))
1243         {
1244             fluid_channel_clear_monolist(channel);
1245         }
1246
1247         status = fluid_synth_noteoff_monopoly(synth, chan, key, 0);
1248     }
1249
1250     /* Changes the state (Valid/Invalid) of the most recent note played in a
1251        staccato manner */
1252     fluid_channel_invalid_prev_note_staccato(channel);
1253     return status;
1254 }
1255
1256 /* Damps voices on a channel (turn notes off), if they're sustained by
1257    sustain pedal */
1258 static int
1259 fluid_synth_damp_voices_by_sustain_LOCAL(fluid_synth_t *synth, int chan)
1260 {
1261     fluid_channel_t *channel = synth->channel[chan];
1262     fluid_voice_t *voice;
1263     int i;
1264
1265     for(i = 0; i < synth->polyphony; i++)
1266     {
1267         voice = synth->voice[i];
1268
1269         if((fluid_voice_get_channel(voice) == chan) && fluid_voice_is_sustained(voice))
1270         {
1271             if(voice->key == channel->key_mono_sustained)
1272             {
1273                 /* key_mono_sustained is a possible mono note sustainted
1274                 (by sustain or sostenuto pedal). It must be marked released
1275                 (INVALID_NOTE) here because it is released only by sustain pedal */
1276                 channel->key_mono_sustained = INVALID_NOTE;
1277             }
1278
1279             fluid_voice_release(voice);
1280         }
1281     }
1282
1283     return FLUID_OK;
1284 }
1285
1286 /* Damps voices on a channel (turn notes off), if they're sustained by
1287    sostenuto pedal */
1288 static int
1289 fluid_synth_damp_voices_by_sostenuto_LOCAL(fluid_synth_t *synth, int chan)
1290 {
1291     fluid_channel_t *channel = synth->channel[chan];
1292     fluid_voice_t *voice;
1293     int i;
1294
1295     for(i = 0; i < synth->polyphony; i++)
1296     {
1297         voice = synth->voice[i];
1298
1299         if((fluid_voice_get_channel(voice) == chan) && fluid_voice_is_sostenuto(voice))
1300         {
1301             if(voice->key == channel->key_mono_sustained)
1302             {
1303                 /* key_mono_sustained is a possible mono note sustainted
1304                 (by sustain or sostenuto pedal). It must be marked released
1305                 (INVALID_NOTE) here because it is released only by sostenuto pedal */
1306                 channel->key_mono_sustained = INVALID_NOTE;
1307             }
1308
1309             fluid_voice_release(voice);
1310         }
1311     }
1312
1313     return FLUID_OK;
1314 }
1315
1316 /**
1317  * Adds the specified modulator \c mod as default modulator to the synth. \c mod will
1318  * take effect for any subsequently created voice.
1319  * @param synth FluidSynth instance
1320  * @param mod Modulator info (values copied, passed in object can be freed immediately afterwards)
1321  * @param mode Determines how to handle an existing identical modulator (#fluid_synth_add_mod)
1322  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
1323  * 
1324  * @note Not realtime safe (due to internal memory allocation) and therefore should not be called
1325  * from synthesis context at the risk of stalling audio output.
1326  */
1327 int
1328 fluid_synth_add_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod, int mode)
1329 {
1330     fluid_mod_t *default_mod;
1331     fluid_mod_t *last_mod = NULL;
1332     fluid_mod_t *new_mod;
1333
1334     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
1335     fluid_return_val_if_fail(mod != NULL, FLUID_FAILED);
1336     fluid_synth_api_enter(synth);
1337
1338     default_mod = synth->default_mod;
1339
1340     while(default_mod != NULL)
1341     {
1342         if(fluid_mod_test_identity(default_mod, mod))
1343         {
1344             if(mode == FLUID_SYNTH_ADD)
1345             {
1346                 default_mod->amount += mod->amount;
1347             }
1348             else if(mode == FLUID_SYNTH_OVERWRITE)
1349             {
1350                 default_mod->amount = mod->amount;
1351             }
1352             else
1353             {
1354                 FLUID_API_RETURN(FLUID_FAILED);
1355             }
1356
1357             FLUID_API_RETURN(FLUID_OK);
1358         }
1359
1360         last_mod = default_mod;
1361         default_mod = default_mod->next;
1362     }
1363
1364     /* Add a new modulator (no existing modulator to add / overwrite). */
1365     new_mod = new_fluid_mod();
1366
1367     if(new_mod == NULL)
1368     {
1369         FLUID_API_RETURN(FLUID_FAILED);
1370     }
1371
1372     fluid_mod_clone(new_mod, mod);
1373     new_mod->next = NULL;
1374
1375     if(last_mod == NULL)
1376     {
1377         synth->default_mod = new_mod;
1378     }
1379     else
1380     {
1381         last_mod->next = new_mod;
1382     }
1383
1384     FLUID_API_RETURN(FLUID_OK);
1385 }
1386
1387 /**
1388  * Removes the specified modulator \c mod from the synth's default modulator list.
1389  * fluid_mod_test_identity() will be used to test modulator matching.
1390  * @param synth synth instance
1391  * @param mod The modulator to remove
1392  * @return #FLUID_OK if a matching modulator was found and successfully removed, #FLUID_FAILED otherwise
1393  * 
1394  * @note Not realtime safe (due to internal memory allocation) and therefore should not be called
1395  * from synthesis context at the risk of stalling audio output.
1396  */
1397 int
1398 fluid_synth_remove_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod)
1399 {
1400     fluid_mod_t *default_mod;
1401     fluid_mod_t *last_mod;
1402
1403     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
1404     fluid_return_val_if_fail(mod != NULL, FLUID_FAILED);
1405     fluid_synth_api_enter(synth);
1406
1407     last_mod = default_mod = synth->default_mod;
1408
1409     while(default_mod != NULL)
1410     {
1411         if(fluid_mod_test_identity(default_mod, mod))
1412         {
1413             if(synth->default_mod == default_mod)
1414             {
1415                 synth->default_mod = synth->default_mod->next;
1416             }
1417             else
1418             {
1419                 last_mod->next = default_mod->next;
1420             }
1421
1422             delete_fluid_mod(default_mod);
1423             FLUID_API_RETURN(FLUID_OK);
1424         }
1425
1426         last_mod = default_mod;
1427         default_mod = default_mod->next;
1428     }
1429
1430     FLUID_API_RETURN(FLUID_FAILED);
1431 }
1432
1433
1434 /**
1435  * Send a MIDI controller event on a MIDI channel.
1436  * @param synth FluidSynth instance
1437  * @param chan MIDI channel number (0 to MIDI channel count - 1)
1438  * @param num MIDI controller number (0-127)
1439  * @param val MIDI controller value (0-127)
1440  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
1441  * @note This function supports MIDI Global Controllers which will be sent to
1442  * all channels of the basic channel if this basic channel is in mode OmniOff/Mono.
1443  * This is accomplished by sending the CC one MIDI channel below the basic
1444  * channel of the receiver.
1445  * Examples: let a synthesizer with 16 MIDI channels:
1446  * - Let a basic channel 7 in mode 3 (Omni Off, Mono). If MIDI channel 6 is disabled it
1447  *    could be used as CC global for all channels belonging to basic channel 7.
1448  * - Let a basic channel 0 in mode 3. If MIDI channel 15  is disabled it could be used
1449  *   as CC global for all channels belonging to basic channel 0.
1450  */
1451 int
1452 fluid_synth_cc(fluid_synth_t *synth, int chan, int num, int val)
1453 {
1454     int result = FLUID_FAILED;
1455     fluid_channel_t *channel;
1456     fluid_return_val_if_fail(num >= 0 && num <= 127, FLUID_FAILED);
1457     fluid_return_val_if_fail(val >= 0 && val <= 127, FLUID_FAILED);
1458     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
1459
1460     channel = synth->channel[chan];
1461
1462     if(channel->mode &  FLUID_CHANNEL_ENABLED)
1463     {
1464         /* chan is enabled */
1465         if(synth->verbose)
1466         {
1467             FLUID_LOG(FLUID_INFO, "cc\t%d\t%d\t%d", chan, num, val);
1468         }
1469
1470         fluid_channel_set_cc(channel, num, val);
1471         result = fluid_synth_cc_LOCAL(synth, chan, num);
1472     }
1473     else /* chan is disabled so it is a candidate for global channel */
1474     {
1475         /* looks for next basic channel */
1476         int n_chan = synth->midi_channels; /* MIDI Channels number */
1477         int basicchan ;
1478
1479         if(chan < n_chan - 1)
1480         {
1481             basicchan = chan + 1;    /* next channel */
1482         }
1483         else
1484         {
1485             basicchan = 0;    /* wrap to 0 */
1486         }
1487
1488         channel = synth->channel[basicchan];
1489
1490         /* Channel must be a basicchan in mode OMNIOFF_MONO */
1491         if((channel->mode &  FLUID_CHANNEL_BASIC) &&
1492                 ((channel->mode & FLUID_CHANNEL_MODE_MASK) == FLUID_CHANNEL_MODE_OMNIOFF_MONO))
1493         {
1494             /* sends cc to all channels in this basic channel */
1495             int i, nbr = channel->mode_val;
1496
1497             for(i = basicchan; i < basicchan + nbr; i++)
1498             {
1499                 if(synth->verbose)
1500                 {
1501                     FLUID_LOG(FLUID_INFO, "cc\t%d\t%d\t%d", i, num, val);
1502                 }
1503
1504                 fluid_channel_set_cc(synth->channel[i], num, val);
1505                 result = fluid_synth_cc_LOCAL(synth, i, num);
1506             }
1507         }
1508         /* The channel chan is not a valid 'global channel' */
1509         else
1510         {
1511             result = FLUID_FAILED;
1512         }
1513     }
1514
1515     FLUID_API_RETURN(result);
1516 }
1517
1518 /* Local synthesis thread variant of MIDI CC set function. */
1519 static int
1520 fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
1521 {
1522     fluid_channel_t *chan = synth->channel[channum];
1523     int nrpn_select;
1524     int value;
1525
1526     value = fluid_channel_get_cc(chan, num);
1527
1528     switch(num)
1529     {
1530
1531     /* CC omnioff, omnion, mono, poly */
1532     case POLY_OFF:
1533     case POLY_ON:
1534     case OMNI_OFF:
1535     case OMNI_ON:
1536
1537         /* allowed only if channum is a basic channel */
1538         if(chan->mode &  FLUID_CHANNEL_BASIC)
1539         {
1540             /* Construction of new_mode from current channel mode and this CC mode */
1541             int new_mode = chan->mode & FLUID_CHANNEL_MODE_MASK;
1542
1543             switch(num)
1544             {
1545             case POLY_OFF:
1546                 new_mode |= FLUID_CHANNEL_POLY_OFF;
1547                 break;
1548
1549             case POLY_ON:
1550                 new_mode &= ~FLUID_CHANNEL_POLY_OFF;
1551                 break;
1552
1553             case OMNI_OFF:
1554                 new_mode |= FLUID_CHANNEL_OMNI_OFF;
1555                 break;
1556
1557             case OMNI_ON:
1558                 new_mode &= ~FLUID_CHANNEL_OMNI_OFF;
1559                 break;
1560
1561             default: /* should never happen */
1562                 return FLUID_FAILED;
1563             }
1564
1565             /* MIDI specs: if value is 0 it means all channels from channum to next
1566                 basic channel minus 1 (if any) or to MIDI channel count minus 1.
1567                 However, if value is > 0 (e.g. 4), the group of channels will be be
1568                 limited to 4.
1569                 value is ignored for #FLUID_CHANNEL_MODE_OMNIOFF_POLY as this mode
1570                 implies a group of only one channel.
1571             */
1572             /* Checks value range and changes this existing basic channel group */
1573             value = fluid_synth_check_next_basic_channel(synth, channum, new_mode, value);
1574
1575             if(value != FLUID_FAILED)
1576             {
1577                 /* reset the current basic channel before changing it */
1578                 fluid_synth_reset_basic_channel_LOCAL(synth, channum, chan->mode_val);
1579                 fluid_synth_set_basic_channel_LOCAL(synth, channum, new_mode, value);
1580                 break; /* FLUID_OK */
1581             }
1582         }
1583
1584         return FLUID_FAILED;
1585
1586     case LEGATO_SWITCH:
1587         /* handles Poly/mono commutation on Legato pedal On/Off.*/
1588         fluid_channel_cc_legato(chan, value);
1589         break;
1590
1591     case PORTAMENTO_SWITCH:
1592         /* Special handling of the monophonic list  */
1593         /* Invalids the most recent note played in a staccato manner */
1594         fluid_channel_invalid_prev_note_staccato(chan);
1595         break;
1596
1597     case SUSTAIN_SWITCH:
1598
1599         /* Release voices if Sustain switch is released */
1600         if(value < 64)  /* Sustain is released */
1601         {
1602             fluid_synth_damp_voices_by_sustain_LOCAL(synth, channum);
1603         }
1604
1605         break;
1606
1607     case SOSTENUTO_SWITCH:
1608
1609         /* Release voices if Sostetuno switch is released */
1610         if(value < 64)  /* Sostenuto is released */
1611         {
1612             fluid_synth_damp_voices_by_sostenuto_LOCAL(synth, channum);
1613         }
1614         else /* Sostenuto is depressed */
1615             /* Update sostenuto order id when pedaling on Sostenuto */
1616         {
1617             chan->sostenuto_orderid = synth->noteid; /* future voice id value */
1618         }
1619
1620         break;
1621
1622     case BANK_SELECT_MSB:
1623         fluid_channel_set_bank_msb(chan, value & 0x7F);
1624         break;
1625
1626     case BANK_SELECT_LSB:
1627         fluid_channel_set_bank_lsb(chan, value & 0x7F);
1628         break;
1629
1630     case ALL_NOTES_OFF:
1631         fluid_synth_all_notes_off_LOCAL(synth, channum);
1632         break;
1633
1634     case ALL_SOUND_OFF:
1635         fluid_synth_all_sounds_off_LOCAL(synth, channum);
1636         break;
1637
1638     case ALL_CTRL_OFF:
1639         fluid_channel_init_ctrl(chan, 1);
1640         fluid_synth_modulate_voices_all_LOCAL(synth, channum);
1641         break;
1642
1643     case DATA_ENTRY_MSB:
1644     {
1645         int data = (value << 7) + fluid_channel_get_cc(chan, DATA_ENTRY_LSB);
1646
1647         if(chan->nrpn_active)   /* NRPN is active? */
1648         {
1649             /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74)  */
1650             if((fluid_channel_get_cc(chan, NRPN_MSB) == 120)
1651                     && (fluid_channel_get_cc(chan, NRPN_LSB) < 100))
1652             {
1653                 nrpn_select = chan->nrpn_select;
1654
1655                 if(nrpn_select < GEN_LAST)
1656                 {
1657                     float val = fluid_gen_scale_nrpn(nrpn_select, data);
1658                     fluid_synth_set_gen_LOCAL(synth, channum, nrpn_select, val, FALSE);
1659                 }
1660
1661                 chan->nrpn_select = 0;  /* Reset to 0 */
1662             }
1663         }
1664         else if(fluid_channel_get_cc(chan, RPN_MSB) == 0)      /* RPN is active: MSB = 0? */
1665         {
1666             switch(fluid_channel_get_cc(chan, RPN_LSB))
1667             {
1668             case RPN_PITCH_BEND_RANGE:    /* Set bend range in semitones */
1669                 fluid_channel_set_pitch_wheel_sensitivity(synth->channel[channum], value);
1670                 fluid_synth_update_pitch_wheel_sens_LOCAL(synth, channum);    /* Update bend range */
1671                 /* FIXME - Handle LSB? (Fine bend range in cents) */
1672                 break;
1673
1674             case RPN_CHANNEL_FINE_TUNE:   /* Fine tune is 14 bit over +/-1 semitone (+/- 100 cents, 8192 = center) */
1675                 fluid_synth_set_gen_LOCAL(synth, channum, GEN_FINETUNE,
1676                                           (data - 8192) / 8192.0 * 100.0, FALSE);
1677                 break;
1678
1679             case RPN_CHANNEL_COARSE_TUNE: /* Coarse tune is 7 bit and in semitones (64 is center) */
1680                 fluid_synth_set_gen_LOCAL(synth, channum, GEN_COARSETUNE,
1681                                           value - 64, FALSE);
1682                 break;
1683
1684             case RPN_TUNING_PROGRAM_CHANGE:
1685                 fluid_channel_set_tuning_prog(chan, value);
1686                 fluid_synth_activate_tuning(synth, channum,
1687                                             fluid_channel_get_tuning_bank(chan),
1688                                             value, TRUE);
1689                 break;
1690
1691             case RPN_TUNING_BANK_SELECT:
1692                 fluid_channel_set_tuning_bank(chan, value);
1693                 break;
1694
1695             case RPN_MODULATION_DEPTH_RANGE:
1696                 break;
1697             }
1698         }
1699
1700         break;
1701     }
1702
1703     case NRPN_MSB:
1704         fluid_channel_set_cc(chan, NRPN_LSB, 0);
1705         chan->nrpn_select = 0;
1706         chan->nrpn_active = 1;
1707         break;
1708
1709     case NRPN_LSB:
1710
1711         /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74)  */
1712         if(fluid_channel_get_cc(chan, NRPN_MSB) == 120)
1713         {
1714             if(value == 100)
1715             {
1716                 chan->nrpn_select += 100;
1717             }
1718             else if(value == 101)
1719             {
1720                 chan->nrpn_select += 1000;
1721             }
1722             else if(value == 102)
1723             {
1724                 chan->nrpn_select += 10000;
1725             }
1726             else if(value < 100)
1727             {
1728                 chan->nrpn_select += value;
1729             }
1730         }
1731
1732         chan->nrpn_active = 1;
1733         break;
1734
1735     case RPN_MSB:
1736     case RPN_LSB:
1737         chan->nrpn_active = 0;
1738         break;
1739
1740     case BREATH_MSB:
1741         /* handles CC Breath On/Off noteOn/noteOff mode */
1742         fluid_channel_cc_breath_note_on_off(chan, value);
1743
1744     /* fall-through */
1745     default:
1746         return fluid_synth_modulate_voices_LOCAL(synth, channum, 1, num);
1747     }
1748
1749     return FLUID_OK;
1750 }
1751
1752 /**
1753  * Get current MIDI controller value on a MIDI channel.
1754  * @param synth FluidSynth instance
1755  * @param chan MIDI channel number (0 to MIDI channel count - 1)
1756  * @param num MIDI controller number (0-127)
1757  * @param pval Location to store MIDI controller value (0-127)
1758  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
1759  */
1760 int
1761 fluid_synth_get_cc(fluid_synth_t *synth, int chan, int num, int *pval)
1762 {
1763     fluid_return_val_if_fail(num >= 0 && num < 128, FLUID_FAILED);
1764     fluid_return_val_if_fail(pval != NULL, FLUID_FAILED);
1765
1766     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
1767
1768     /* Allowed only on MIDI channel enabled */
1769     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
1770
1771     *pval = fluid_channel_get_cc(synth->channel[chan], num);
1772     FLUID_API_RETURN(FLUID_OK);
1773 }
1774
1775 /*
1776  * Handler for synth.device-id setting.
1777  */
1778 static void
1779 fluid_synth_handle_device_id(void *data, const char *name, int value)
1780 {
1781     fluid_synth_t *synth = (fluid_synth_t *)data;
1782     fluid_return_if_fail(synth != NULL);
1783
1784     fluid_synth_api_enter(synth);
1785     synth->device_id = value;
1786     fluid_synth_api_exit(synth);
1787 }
1788
1789 /**
1790  * Process a MIDI SYSEX (system exclusive) message.
1791  * @param synth FluidSynth instance
1792  * @param data Buffer containing SYSEX data (not including 0xF0 and 0xF7)
1793  * @param len Length of data in buffer
1794  * @param response Buffer to store response to or NULL to ignore
1795  * @param response_len IN/OUT parameter, in: size of response buffer, out:
1796  *   amount of data written to response buffer (if FLUID_FAILED is returned and
1797  *   this value is non-zero, it indicates the response buffer is too small)
1798  * @param handled Optional location to store boolean value if message was
1799  *   recognized and handled or not (set to TRUE if it was handled)
1800  * @param dryrun TRUE to just do a dry run but not actually execute the SYSEX
1801  *   command (useful for checking if a SYSEX message would be handled)
1802  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
1803  * @since 1.1.0
1804  */
1805 /* SYSEX format (0xF0 and 0xF7 not passed to this function):
1806  * Non-realtime:    0xF0 0x7E <DeviceId> [BODY] 0xF7
1807  * Realtime:        0xF0 0x7F <DeviceId> [BODY] 0xF7
1808  * Tuning messages: 0xF0 0x7E/0x7F <DeviceId> 0x08 <sub ID2> [BODY] <ChkSum> 0xF7
1809  */
1810 int
1811 fluid_synth_sysex(fluid_synth_t *synth, const char *data, int len,
1812                   char *response, int *response_len, int *handled, int dryrun)
1813 {
1814     int avail_response = 0;
1815
1816     if(handled)
1817     {
1818         *handled = FALSE;
1819     }
1820
1821     if(response_len)
1822     {
1823         avail_response = *response_len;
1824         *response_len = 0;
1825     }
1826
1827     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
1828     fluid_return_val_if_fail(data != NULL, FLUID_FAILED);
1829     fluid_return_val_if_fail(len > 0, FLUID_FAILED);
1830     fluid_return_val_if_fail(!response || response_len, FLUID_FAILED);
1831
1832     if(len < 4)
1833     {
1834         return FLUID_OK;
1835     }
1836
1837     /* MIDI tuning SYSEX message? */
1838     if((data[0] == MIDI_SYSEX_UNIV_NON_REALTIME || data[0] == MIDI_SYSEX_UNIV_REALTIME)
1839             && (data[1] == synth->device_id || data[1] == MIDI_SYSEX_DEVICE_ID_ALL)
1840             && data[2] == MIDI_SYSEX_MIDI_TUNING_ID)
1841     {
1842         int result;
1843         fluid_synth_api_enter(synth);
1844         result = fluid_synth_sysex_midi_tuning(synth, data, len, response,
1845                                                response_len, avail_response,
1846                                                handled, dryrun);
1847
1848         FLUID_API_RETURN(result);
1849     }
1850
1851     return FLUID_OK;
1852 }
1853
1854 /* Handler for MIDI tuning SYSEX messages */
1855 static int
1856 fluid_synth_sysex_midi_tuning(fluid_synth_t *synth, const char *data, int len,
1857                               char *response, int *response_len, int avail_response,
1858                               int *handled, int dryrun)
1859 {
1860     int realtime, msgid;
1861     int bank = 0, prog, channels;
1862     double tunedata[128];
1863     int keys[128];
1864     char name[17];
1865     int note, frac, frac2;
1866     uint8_t chksum;
1867     int i, count, index;
1868     const char *dataptr;
1869     char *resptr;;
1870
1871     realtime = data[0] == MIDI_SYSEX_UNIV_REALTIME;
1872     msgid = data[3];
1873
1874     switch(msgid)
1875     {
1876     case MIDI_SYSEX_TUNING_BULK_DUMP_REQ:
1877     case MIDI_SYSEX_TUNING_BULK_DUMP_REQ_BANK:
1878         if(data[3] == MIDI_SYSEX_TUNING_BULK_DUMP_REQ)
1879         {
1880             if(len != 5 || data[4] & 0x80 || !response)
1881             {
1882                 return FLUID_OK;
1883             }
1884
1885             *response_len = 406;
1886             prog = data[4];
1887         }
1888         else
1889         {
1890             if(len != 6 || data[4] & 0x80 || data[5] & 0x80 || !response)
1891             {
1892                 return FLUID_OK;
1893             }
1894
1895             *response_len = 407;
1896             bank = data[4];
1897             prog = data[5];
1898         }
1899
1900         if(dryrun)
1901         {
1902             if(handled)
1903             {
1904                 *handled = TRUE;
1905             }
1906
1907             return FLUID_OK;
1908         }
1909
1910         if(avail_response < *response_len)
1911         {
1912             return FLUID_FAILED;
1913         }
1914
1915         /* Get tuning data, return if tuning not found */
1916         if(fluid_synth_tuning_dump(synth, bank, prog, name, 17, tunedata) == FLUID_FAILED)
1917         {
1918             *response_len = 0;
1919             return FLUID_OK;
1920         }
1921
1922         resptr = response;
1923
1924         *resptr++ = MIDI_SYSEX_UNIV_NON_REALTIME;
1925         *resptr++ = synth->device_id;
1926         *resptr++ = MIDI_SYSEX_MIDI_TUNING_ID;
1927         *resptr++ = MIDI_SYSEX_TUNING_BULK_DUMP;
1928
1929         if(msgid == MIDI_SYSEX_TUNING_BULK_DUMP_REQ_BANK)
1930         {
1931             *resptr++ = bank;
1932         }
1933
1934         *resptr++ = prog;
1935         FLUID_STRNCPY(resptr, name, 16);
1936         resptr += 16;
1937
1938         for(i = 0; i < 128; i++)
1939         {
1940             note = tunedata[i] / 100.0;
1941             fluid_clip(note, 0, 127);
1942
1943             frac = ((tunedata[i] - note * 100.0) * 16384.0 + 50.0) / 100.0;
1944             fluid_clip(frac, 0, 16383);
1945
1946             *resptr++ = note;
1947             *resptr++ = frac >> 7;
1948             *resptr++ = frac & 0x7F;
1949         }
1950
1951         if(msgid == MIDI_SYSEX_TUNING_BULK_DUMP_REQ)
1952         {
1953             /* NOTE: Checksum is not as straight forward as the bank based messages */
1954             chksum = MIDI_SYSEX_UNIV_NON_REALTIME ^ MIDI_SYSEX_MIDI_TUNING_ID
1955                      ^ MIDI_SYSEX_TUNING_BULK_DUMP ^ prog;
1956
1957             for(i = 21; i < 128 * 3 + 21; i++)
1958             {
1959                 chksum ^= response[i];
1960             }
1961         }
1962         else
1963         {
1964             for(i = 1, chksum = 0; i < 406; i++)
1965             {
1966                 chksum ^= response[i];
1967             }
1968         }
1969
1970         *resptr++ = chksum & 0x7F;
1971
1972         if(handled)
1973         {
1974             *handled = TRUE;
1975         }
1976
1977         break;
1978
1979     case MIDI_SYSEX_TUNING_NOTE_TUNE:
1980     case MIDI_SYSEX_TUNING_NOTE_TUNE_BANK:
1981         dataptr = data + 4;
1982
1983         if(msgid == MIDI_SYSEX_TUNING_NOTE_TUNE)
1984         {
1985             if(len < 10 || data[4] & 0x80 || data[5] & 0x80 || len != data[5] * 4 + 6)
1986             {
1987                 return FLUID_OK;
1988             }
1989         }
1990         else
1991         {
1992             if(len < 11 || data[4] & 0x80 || data[5] & 0x80 || data[6] & 0x80
1993                     || len != data[6] * 4 + 7)
1994             {
1995                 return FLUID_OK;
1996             }
1997
1998             bank = *dataptr++;
1999         }
2000
2001         if(dryrun)
2002         {
2003             if(handled)
2004             {
2005                 *handled = TRUE;
2006             }
2007
2008             return FLUID_OK;
2009         }
2010
2011         prog = *dataptr++;
2012         count = *dataptr++;
2013
2014         for(i = 0, index = 0; i < count; i++)
2015         {
2016             note = *dataptr++;
2017
2018             if(note & 0x80)
2019             {
2020                 return FLUID_OK;
2021             }
2022
2023             keys[index] = note;
2024
2025             note = *dataptr++;
2026             frac = *dataptr++;
2027             frac2 = *dataptr++;
2028
2029             if(note & 0x80 || frac & 0x80 || frac2 & 0x80)
2030             {
2031                 return FLUID_OK;
2032             }
2033
2034             frac = frac << 7 | frac2;
2035
2036             /* No change pitch value?  Doesn't really make sense to send that, but.. */
2037             if(note == 0x7F && frac == 16383)
2038             {
2039                 continue;
2040             }
2041
2042             tunedata[index] = note * 100.0 + (frac * 100.0 / 16384.0);
2043             index++;
2044         }
2045
2046         if(index > 0)
2047         {
2048             if(fluid_synth_tune_notes(synth, bank, prog, index, keys, tunedata,
2049                                       realtime) == FLUID_FAILED)
2050             {
2051                 return FLUID_FAILED;
2052             }
2053         }
2054
2055         if(handled)
2056         {
2057             *handled = TRUE;
2058         }
2059
2060         break;
2061
2062     case MIDI_SYSEX_TUNING_OCTAVE_TUNE_1BYTE:
2063     case MIDI_SYSEX_TUNING_OCTAVE_TUNE_2BYTE:
2064         if((msgid == MIDI_SYSEX_TUNING_OCTAVE_TUNE_1BYTE && len != 19)
2065                 || (msgid == MIDI_SYSEX_TUNING_OCTAVE_TUNE_2BYTE && len != 31))
2066         {
2067             return FLUID_OK;
2068         }
2069
2070         if(data[4] & 0x80 || data[5] & 0x80 || data[6] & 0x80)
2071         {
2072             return FLUID_OK;
2073         }
2074
2075         if(dryrun)
2076         {
2077             if(handled)
2078             {
2079                 *handled = TRUE;
2080             }
2081
2082             return FLUID_OK;
2083         }
2084
2085         channels = (data[4] & 0x03) << 14 | data[5] << 7 | data[6];
2086
2087         if(msgid == MIDI_SYSEX_TUNING_OCTAVE_TUNE_1BYTE)
2088         {
2089             for(i = 0; i < 12; i++)
2090             {
2091                 frac = data[i + 7];
2092
2093                 if(frac & 0x80)
2094                 {
2095                     return FLUID_OK;
2096                 }
2097
2098                 tunedata[i] = (int)frac - 64;
2099             }
2100         }
2101         else
2102         {
2103             for(i = 0; i < 12; i++)
2104             {
2105                 frac = data[i * 2 + 7];
2106                 frac2 = data[i * 2 + 8];
2107
2108                 if(frac & 0x80 || frac2 & 0x80)
2109                 {
2110                     return FLUID_OK;
2111                 }
2112
2113                 tunedata[i] = (((int)frac << 7 | (int)frac2) - 8192) * (200.0 / 16384.0);
2114             }
2115         }
2116
2117         if(fluid_synth_activate_octave_tuning(synth, 0, 0, "SYSEX",
2118                                               tunedata, realtime) == FLUID_FAILED)
2119         {
2120             return FLUID_FAILED;
2121         }
2122
2123         if(channels)
2124         {
2125             for(i = 0; i < 16; i++)
2126             {
2127                 if(channels & (1 << i))
2128                 {
2129                     fluid_synth_activate_tuning(synth, i, 0, 0, realtime);
2130                 }
2131             }
2132         }
2133
2134         if(handled)
2135         {
2136             *handled = TRUE;
2137         }
2138
2139         break;
2140     }
2141
2142     return FLUID_OK;
2143 }
2144
2145 /**
2146  * Turn off all notes on a MIDI channel (put them into release phase).
2147  * @param synth FluidSynth instance
2148  * @param chan MIDI channel number (0 to MIDI channel count - 1), (chan=-1 selects all channels)
2149  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2150  * @since 1.1.4
2151  */
2152 int
2153 fluid_synth_all_notes_off(fluid_synth_t *synth, int chan)
2154 {
2155     int result;
2156
2157     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
2158     fluid_return_val_if_fail(chan >= -1, FLUID_FAILED);
2159     fluid_synth_api_enter(synth);
2160
2161     if(chan >= synth->midi_channels)
2162     {
2163         result = FLUID_FAILED;
2164     }
2165     else
2166     {
2167         /* Allowed (even for channel disabled) as chan = -1 selects all channels */
2168         result = fluid_synth_all_notes_off_LOCAL(synth, chan);
2169     }
2170
2171     FLUID_API_RETURN(result);
2172 }
2173
2174 /* Local synthesis thread variant of all notes off, (chan=-1 selects all channels) */
2175 //static int
2176 int
2177 fluid_synth_all_notes_off_LOCAL(fluid_synth_t *synth, int chan)
2178 {
2179     fluid_voice_t *voice;
2180     int i;
2181
2182     for(i = 0; i < synth->polyphony; i++)
2183     {
2184         voice = synth->voice[i];
2185
2186         if(fluid_voice_is_playing(voice) && ((-1 == chan) || (chan == fluid_voice_get_channel(voice))))
2187         {
2188             fluid_voice_noteoff(voice);
2189         }
2190     }
2191
2192     return FLUID_OK;
2193 }
2194
2195 /**
2196  * Immediately stop all notes on a MIDI channel (skips release phase).
2197  * @param synth FluidSynth instance
2198  * @param chan MIDI channel number (0 to MIDI channel count - 1), (chan=-1 selects all channels)
2199  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2200  * @since 1.1.4
2201  */
2202 int
2203 fluid_synth_all_sounds_off(fluid_synth_t *synth, int chan)
2204 {
2205     int result;
2206
2207     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
2208     fluid_return_val_if_fail(chan >= -1, FLUID_FAILED);
2209     fluid_synth_api_enter(synth);
2210
2211     if(chan >= synth->midi_channels)
2212     {
2213         result = FLUID_FAILED;
2214     }
2215     else
2216     {
2217         /* Allowed (even for channel disabled) as chan = -1 selects all channels */
2218         result = fluid_synth_all_sounds_off_LOCAL(synth, chan);
2219     }
2220
2221     FLUID_API_RETURN(result);
2222 }
2223
2224 /* Local synthesis thread variant of all sounds off, (chan=-1 selects all channels) */
2225 static int
2226 fluid_synth_all_sounds_off_LOCAL(fluid_synth_t *synth, int chan)
2227 {
2228     fluid_voice_t *voice;
2229     int i;
2230
2231     for(i = 0; i < synth->polyphony; i++)
2232     {
2233         voice = synth->voice[i];
2234
2235         if(fluid_voice_is_playing(voice) && ((-1 == chan) || (chan == fluid_voice_get_channel(voice))))
2236         {
2237             fluid_voice_off(voice);
2238         }
2239     }
2240
2241     return FLUID_OK;
2242 }
2243
2244 /**
2245  * Reset reverb engine
2246  * @param synth FluidSynth instance
2247  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2248  */
2249 int
2250 fluid_synth_reset_reverb(fluid_synth_t *synth)
2251 {
2252     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
2253     fluid_synth_api_enter(synth);
2254     fluid_synth_update_mixer(synth, fluid_rvoice_mixer_reset_reverb, 0, 0.0f);
2255     FLUID_API_RETURN(FLUID_OK);
2256 }
2257
2258 /**
2259  * Reset chorus engine
2260  * @param synth FluidSynth instance
2261  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2262  */
2263 int
2264 fluid_synth_reset_chorus(fluid_synth_t *synth)
2265 {
2266     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
2267     fluid_synth_api_enter(synth);
2268     fluid_synth_update_mixer(synth, fluid_rvoice_mixer_reset_chorus, 0, 0.0f);
2269     FLUID_API_RETURN(FLUID_OK);
2270 }
2271
2272
2273 /**
2274  * Send MIDI system reset command (big red 'panic' button), turns off notes, resets
2275  * controllers and restores initial basic channel configuration.
2276  * @param synth FluidSynth instance
2277  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2278  */
2279 int
2280 fluid_synth_system_reset(fluid_synth_t *synth)
2281 {
2282     int result;
2283     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
2284     fluid_synth_api_enter(synth);
2285     result = fluid_synth_system_reset_LOCAL(synth);
2286     FLUID_API_RETURN(result);
2287 }
2288
2289 /* Local variant of the system reset command */
2290 static int
2291 fluid_synth_system_reset_LOCAL(fluid_synth_t *synth)
2292 {
2293     int i;
2294
2295     fluid_synth_all_sounds_off_LOCAL(synth, -1);
2296
2297     for(i = 0; i < synth->midi_channels; i++)
2298     {
2299         fluid_channel_reset(synth->channel[i]);
2300     }
2301
2302     /* Basic channel 0, Mode Omni On Poly */
2303     fluid_synth_set_basic_channel(synth, 0, FLUID_CHANNEL_MODE_OMNION_POLY,
2304                                   synth->midi_channels);
2305
2306     fluid_synth_update_mixer(synth, fluid_rvoice_mixer_reset_reverb, 0, 0.0f);
2307     fluid_synth_update_mixer(synth, fluid_rvoice_mixer_reset_chorus, 0, 0.0f);
2308
2309     return FLUID_OK;
2310 }
2311
2312 /**
2313  * Update voices on a MIDI channel after a MIDI control change.
2314  * @param synth FluidSynth instance
2315  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2316  * @param is_cc Boolean value indicating if ctrl is a CC controller or not
2317  * @param ctrl MIDI controller value
2318  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2319  */
2320 static int
2321 fluid_synth_modulate_voices_LOCAL(fluid_synth_t *synth, int chan, int is_cc, int ctrl)
2322 {
2323     fluid_voice_t *voice;
2324     int i;
2325
2326     for(i = 0; i < synth->polyphony; i++)
2327     {
2328         voice = synth->voice[i];
2329
2330         if(fluid_voice_get_channel(voice) == chan)
2331         {
2332             fluid_voice_modulate(voice, is_cc, ctrl);
2333         }
2334     }
2335
2336     return FLUID_OK;
2337 }
2338
2339 /**
2340  * Update voices on a MIDI channel after all MIDI controllers have been changed.
2341  * @param synth FluidSynth instance
2342  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2343  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2344  */
2345 static int
2346 fluid_synth_modulate_voices_all_LOCAL(fluid_synth_t *synth, int chan)
2347 {
2348     fluid_voice_t *voice;
2349     int i;
2350
2351     for(i = 0; i < synth->polyphony; i++)
2352     {
2353         voice = synth->voice[i];
2354
2355         if(fluid_voice_get_channel(voice) == chan)
2356         {
2357             fluid_voice_modulate_all(voice);
2358         }
2359     }
2360
2361     return FLUID_OK;
2362 }
2363
2364 /**
2365  * Set the MIDI channel pressure controller value.
2366  * @param synth FluidSynth instance
2367  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2368  * @param val MIDI channel pressure value (0-127)
2369  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2370  */
2371 int
2372 fluid_synth_channel_pressure(fluid_synth_t *synth, int chan, int val)
2373 {
2374     int result;
2375     fluid_return_val_if_fail(val >= 0 && val <= 127, FLUID_FAILED);
2376
2377     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2378
2379     /* Allowed only on MIDI channel enabled */
2380     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2381
2382     if(synth->verbose)
2383     {
2384         FLUID_LOG(FLUID_INFO, "channelpressure\t%d\t%d", chan, val);
2385     }
2386
2387     fluid_channel_set_channel_pressure(synth->channel[chan], val);
2388     result = fluid_synth_update_channel_pressure_LOCAL(synth, chan);
2389
2390     FLUID_API_RETURN(result);
2391 }
2392
2393 /* Updates channel pressure from within synthesis thread */
2394 static int
2395 fluid_synth_update_channel_pressure_LOCAL(fluid_synth_t *synth, int chan)
2396 {
2397     return fluid_synth_modulate_voices_LOCAL(synth, chan, 0, FLUID_MOD_CHANNELPRESSURE);
2398 }
2399
2400 /**
2401  * Set the MIDI polyphonic key pressure controller value.
2402  * @param synth FluidSynth instance
2403  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2404  * @param key MIDI key number (0-127)
2405  * @param val MIDI key pressure value (0-127)
2406  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2407  * @since 2.0.0
2408  */
2409 int
2410 fluid_synth_key_pressure(fluid_synth_t *synth, int chan, int key, int val)
2411 {
2412     int result;
2413     fluid_return_val_if_fail(key >= 0 && key <= 127, FLUID_FAILED);
2414     fluid_return_val_if_fail(val >= 0 && val <= 127, FLUID_FAILED);
2415
2416     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2417
2418     /* Allowed only on MIDI channel enabled */
2419     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2420
2421     if(synth->verbose)
2422     {
2423         FLUID_LOG(FLUID_INFO, "keypressure\t%d\t%d\t%d", chan, key, val);
2424     }
2425
2426     fluid_channel_set_key_pressure(synth->channel[chan], key, val);
2427     result = fluid_synth_update_key_pressure_LOCAL(synth, chan, key);
2428
2429     FLUID_API_RETURN(result);
2430 }
2431
2432 /* Updates key pressure from within synthesis thread */
2433 static int
2434 fluid_synth_update_key_pressure_LOCAL(fluid_synth_t *synth, int chan, int key)
2435 {
2436     fluid_voice_t *voice;
2437     int i;
2438     int result = FLUID_OK;
2439
2440     for(i = 0; i < synth->polyphony; i++)
2441     {
2442         voice = synth->voice[i];
2443
2444         if(voice->chan == chan && voice->key == key)
2445         {
2446             result = fluid_voice_modulate(voice, 0, FLUID_MOD_KEYPRESSURE);
2447
2448             if(result != FLUID_OK)
2449             {
2450                 return result;
2451             }
2452         }
2453     }
2454
2455     return result;
2456 }
2457
2458 /**
2459  * Set the MIDI pitch bend controller value on a MIDI channel.
2460  * @param synth FluidSynth instance
2461  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2462  * @param val MIDI pitch bend value (0-16383 with 8192 being center)
2463  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2464  */
2465 int
2466 fluid_synth_pitch_bend(fluid_synth_t *synth, int chan, int val)
2467 {
2468     int result;
2469     fluid_return_val_if_fail(val >= 0 && val <= 16383, FLUID_FAILED);
2470     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2471
2472     /* Allowed only on MIDI channel enabled */
2473     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2474
2475     if(synth->verbose)
2476     {
2477         FLUID_LOG(FLUID_INFO, "pitchb\t%d\t%d", chan, val);
2478     }
2479
2480     fluid_channel_set_pitch_bend(synth->channel[chan], val);
2481     result = fluid_synth_update_pitch_bend_LOCAL(synth, chan);
2482
2483     FLUID_API_RETURN(result);
2484 }
2485
2486 /* Local synthesis thread variant of pitch bend */
2487 static int
2488 fluid_synth_update_pitch_bend_LOCAL(fluid_synth_t *synth, int chan)
2489 {
2490     return fluid_synth_modulate_voices_LOCAL(synth, chan, 0, FLUID_MOD_PITCHWHEEL);
2491 }
2492
2493 /**
2494  * Get the MIDI pitch bend controller value on a MIDI channel.
2495  * @param synth FluidSynth instance
2496  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2497  * @param ppitch_bend Location to store MIDI pitch bend value (0-16383 with
2498  *   8192 being center)
2499  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2500  */
2501 int
2502 fluid_synth_get_pitch_bend(fluid_synth_t *synth, int chan, int *ppitch_bend)
2503 {
2504     int result;
2505     fluid_return_val_if_fail(ppitch_bend != NULL, FLUID_FAILED);
2506     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2507
2508     /* Allowed only on MIDI channel enabled */
2509     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2510
2511     *ppitch_bend = fluid_channel_get_pitch_bend(synth->channel[chan]);
2512     result = FLUID_OK;
2513
2514     FLUID_API_RETURN(result);
2515 }
2516
2517 /**
2518  * Set MIDI pitch wheel sensitivity on a MIDI channel.
2519  * @param synth FluidSynth instance
2520  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2521  * @param val Pitch wheel sensitivity value in semitones
2522  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2523  */
2524 int
2525 fluid_synth_pitch_wheel_sens(fluid_synth_t *synth, int chan, int val)
2526 {
2527     int result;
2528     fluid_return_val_if_fail(val >= 0 && val <= 72, FLUID_FAILED);        /* 6 octaves!?  Better than no limit.. */
2529     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2530
2531     /* Allowed only on MIDI channel enabled */
2532     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2533
2534     if(synth->verbose)
2535     {
2536         FLUID_LOG(FLUID_INFO, "pitchsens\t%d\t%d", chan, val);
2537     }
2538
2539     fluid_channel_set_pitch_wheel_sensitivity(synth->channel[chan], val);
2540     result = fluid_synth_update_pitch_wheel_sens_LOCAL(synth, chan);
2541
2542     FLUID_API_RETURN(result);
2543 }
2544
2545 /* Local synthesis thread variant of set pitch wheel sensitivity */
2546 static int
2547 fluid_synth_update_pitch_wheel_sens_LOCAL(fluid_synth_t *synth, int chan)
2548 {
2549     return fluid_synth_modulate_voices_LOCAL(synth, chan, 0, FLUID_MOD_PITCHWHEELSENS);
2550 }
2551
2552 /**
2553  * Get MIDI pitch wheel sensitivity on a MIDI channel.
2554  * @param synth FluidSynth instance
2555  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2556  * @param pval Location to store pitch wheel sensitivity value in semitones
2557  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2558  * @since Sometime AFTER v1.0 API freeze.
2559  */
2560 int
2561 fluid_synth_get_pitch_wheel_sens(fluid_synth_t *synth, int chan, int *pval)
2562 {
2563     int result;
2564     fluid_return_val_if_fail(pval != NULL, FLUID_FAILED);
2565     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2566
2567     /* Allowed only on MIDI channel enabled */
2568     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2569
2570     *pval = fluid_channel_get_pitch_wheel_sensitivity(synth->channel[chan]);
2571     result = FLUID_OK;
2572
2573     FLUID_API_RETURN(result);
2574 }
2575
2576 /**
2577  * Assign a preset to a MIDI channel.
2578  * @param synth FluidSynth instance
2579  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2580  * @param preset Preset to assign to channel or NULL to clear (ownership is taken over)
2581  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2582  */
2583 static int
2584 fluid_synth_set_preset(fluid_synth_t *synth, int chan, fluid_preset_t *preset)
2585 {
2586     fluid_channel_t *channel;
2587
2588     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
2589     fluid_return_val_if_fail(chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
2590
2591     channel = synth->channel[chan];
2592
2593     return fluid_channel_set_preset(channel, preset);
2594 }
2595
2596 /* Get a preset by SoundFont, bank and program numbers.
2597  * Returns preset pointer or NULL.
2598  */
2599 static fluid_preset_t *
2600 fluid_synth_get_preset(fluid_synth_t *synth, int sfontnum,
2601                        int banknum, int prognum)
2602 {
2603     fluid_sfont_t *sfont;
2604     fluid_list_t *list;
2605
2606     /* 128 indicates an "unset" operation" */
2607     if(prognum == FLUID_UNSET_PROGRAM)
2608     {
2609         return NULL;
2610     }
2611
2612     for(list = synth->sfont; list; list = fluid_list_next(list))
2613     {
2614         sfont = fluid_list_get(list);
2615
2616         if(fluid_sfont_get_id(sfont) == sfontnum)
2617         {
2618             return fluid_sfont_get_preset(sfont, banknum - sfont->bankofs, prognum);
2619         }
2620     }
2621
2622     return NULL;
2623 }
2624
2625 /* Get a preset by SoundFont name, bank and program.
2626  * Returns preset pointer or NULL.
2627  */
2628 static fluid_preset_t *
2629 fluid_synth_get_preset_by_sfont_name(fluid_synth_t *synth, const char *sfontname,
2630                                      int banknum, int prognum)
2631 {
2632     fluid_sfont_t *sfont;
2633     fluid_list_t *list;
2634
2635     for(list = synth->sfont; list; list = fluid_list_next(list))
2636     {
2637         sfont = fluid_list_get(list);
2638
2639         if(FLUID_STRCMP(fluid_sfont_get_name(sfont), sfontname) == 0)
2640         {
2641             return fluid_sfont_get_preset(sfont, banknum - sfont->bankofs, prognum);
2642         }
2643     }
2644
2645     return NULL;
2646 }
2647
2648 /* Find a preset by bank and program numbers.
2649  * Returns preset pointer or NULL.
2650  */
2651 fluid_preset_t *
2652 fluid_synth_find_preset(fluid_synth_t *synth, int banknum,
2653                         int prognum)
2654 {
2655     fluid_preset_t *preset;
2656     fluid_sfont_t *sfont;
2657     fluid_list_t *list;
2658
2659     for(list = synth->sfont; list; list = fluid_list_next(list))
2660     {
2661         sfont = fluid_list_get(list);
2662
2663         preset = fluid_sfont_get_preset(sfont, banknum - sfont->bankofs, prognum);
2664
2665         if(preset)
2666         {
2667             return preset;
2668         }
2669     }
2670
2671     return NULL;
2672 }
2673
2674 /**
2675  * Send a program change event on a MIDI channel.
2676  * @param synth FluidSynth instance
2677  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2678  * @param prognum MIDI program number (0-127)
2679  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2680  */
2681 /* FIXME - Currently not real-time safe, due to preset allocation and mutex lock,
2682  * and may be called from within synthesis context. */
2683
2684 /* As of 1.1.1 prognum can be set to 128 to unset the preset.  Not documented
2685  * since fluid_synth_unset_program() should be used instead. */
2686 int
2687 fluid_synth_program_change(fluid_synth_t *synth, int chan, int prognum)
2688 {
2689     fluid_preset_t *preset = NULL;
2690     fluid_channel_t *channel;
2691     int subst_bank, subst_prog, banknum = 0, result = FLUID_FAILED;
2692
2693     fluid_return_val_if_fail(prognum >= 0 && prognum <= 128, FLUID_FAILED);
2694     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2695
2696     /* Allowed only on MIDI channel enabled */
2697     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2698
2699     channel = synth->channel[chan];
2700
2701     if(channel->channel_type == CHANNEL_TYPE_DRUM)
2702     {
2703         banknum = DRUM_INST_BANK;
2704     }
2705     else
2706     {
2707         fluid_channel_get_sfont_bank_prog(channel, NULL, &banknum, NULL);
2708     }
2709
2710     if(synth->verbose)
2711     {
2712         FLUID_LOG(FLUID_INFO, "prog\t%d\t%d\t%d", chan, banknum, prognum);
2713     }
2714
2715     /* I think this is a hack for MIDI files that do bank changes in GM mode.
2716     * Proper way to handle this would probably be to ignore bank changes when in
2717     * GM mode. - JG
2718     * This is now possible by setting synth.midi-bank-select=gm, but let the hack
2719     * stay for the time being. - DH
2720     */
2721     if(prognum != FLUID_UNSET_PROGRAM)
2722     {
2723         subst_bank = banknum;
2724         subst_prog = prognum;
2725
2726         preset = fluid_synth_find_preset(synth, subst_bank, subst_prog);
2727
2728         /* Fallback to another preset if not found */
2729         if(!preset)
2730         {
2731             /* Percussion: Fallback to preset 0 in percussion bank */
2732             if(channel->channel_type == CHANNEL_TYPE_DRUM)
2733             {
2734                 subst_prog = 0;
2735                 subst_bank = DRUM_INST_BANK;
2736                 preset = fluid_synth_find_preset(synth, subst_bank, subst_prog);
2737             }
2738             /* Melodic instrument */
2739             else
2740             {
2741                 /* Fallback first to bank 0:prognum */
2742                 subst_bank = 0;
2743                 preset = fluid_synth_find_preset(synth, subst_bank, subst_prog);
2744
2745                 /* Fallback to first preset in bank 0 (usually piano...) */
2746                 if(!preset)
2747                 {
2748                     subst_prog = 0;
2749                     preset = fluid_synth_find_preset(synth, subst_bank, subst_prog);
2750                 }
2751             }
2752
2753             if(preset)
2754             {
2755                 FLUID_LOG(FLUID_WARN, "Instrument not found on channel %d [bank=%d prog=%d], substituted [bank=%d prog=%d]",
2756                           chan, banknum, prognum, subst_bank, subst_prog);
2757             }
2758             else
2759             {
2760                 FLUID_LOG(FLUID_WARN, "No preset found on channel %d [bank=%d prog=%d]", chan, banknum, prognum);
2761             }
2762         }
2763     }
2764
2765     /* Assign the SoundFont ID and program number to the channel */
2766     fluid_channel_set_sfont_bank_prog(channel, preset ? fluid_sfont_get_id(preset->sfont) : 0,
2767                                       -1, prognum);
2768     result = fluid_synth_set_preset(synth, chan, preset);
2769
2770     FLUID_API_RETURN(result);
2771 }
2772
2773 /**
2774  * Set instrument bank number on a MIDI channel.
2775  * @param synth FluidSynth instance
2776  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2777  * @param bank MIDI bank number
2778  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2779  * @note This function does not change the instrument currently assigned to \c chan,
2780  * as it is usually called prior to fluid_synth_program_change(). If you still want
2781  * instrument changes to take effect immediately, call fluid_synth_program_reset()
2782  * after having set up the bank configuration.
2783  *
2784  */
2785 int
2786 fluid_synth_bank_select(fluid_synth_t *synth, int chan, int bank)
2787 {
2788     int result;
2789     fluid_return_val_if_fail(bank <= 16383, FLUID_FAILED);
2790     fluid_return_val_if_fail(bank >= 0, FLUID_FAILED);
2791     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2792
2793     /* Allowed only on MIDI channel enabled */
2794     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2795
2796     fluid_channel_set_sfont_bank_prog(synth->channel[chan], -1, bank, -1);
2797     result = FLUID_OK;
2798
2799     FLUID_API_RETURN(result);
2800 }
2801
2802 /**
2803  * Set SoundFont ID on a MIDI channel.
2804  * @param synth FluidSynth instance
2805  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2806  * @param sfont_id ID of a loaded SoundFont
2807  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2808  * @note This function does not change the instrument currently assigned to \c chan,
2809  * as it is usually called prior to fluid_synth_bank_select() or fluid_synth_program_change().
2810  * If you still want instrument changes to take effect immediately, call fluid_synth_program_reset()
2811  * after having selected the soundfont.
2812  */
2813 int
2814 fluid_synth_sfont_select(fluid_synth_t *synth, int chan, int sfont_id)
2815 {
2816     int result;
2817     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2818
2819     /* Allowed only on MIDI channel enabled */
2820     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2821
2822     fluid_channel_set_sfont_bank_prog(synth->channel[chan], sfont_id, -1, -1);
2823     result = FLUID_OK;
2824
2825     FLUID_API_RETURN(result);
2826 }
2827
2828 /**
2829  * Set the preset of a MIDI channel to an unassigned state.
2830  * @param synth FluidSynth instance
2831  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2832  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2833  * @since 1.1.1
2834  *
2835  * @note Channel retains its SoundFont ID and bank numbers, while the program
2836  * number is set to an "unset" state.  MIDI program changes may re-assign a
2837  * preset if one matches.
2838  */
2839 int
2840 fluid_synth_unset_program(fluid_synth_t *synth, int chan)
2841 {
2842     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2843     FLUID_API_RETURN(fluid_synth_program_change(synth, chan, FLUID_UNSET_PROGRAM));
2844 }
2845
2846 /**
2847  * Get current SoundFont ID, bank number and program number for a MIDI channel.
2848  * @param synth FluidSynth instance
2849  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2850  * @param sfont_id Location to store SoundFont ID
2851  * @param bank_num Location to store MIDI bank number
2852  * @param preset_num Location to store MIDI program number
2853  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2854  */
2855 int
2856 fluid_synth_get_program(fluid_synth_t *synth, int chan, int *sfont_id,
2857                         int *bank_num, int *preset_num)
2858 {
2859     int result;
2860     fluid_channel_t *channel;
2861
2862     fluid_return_val_if_fail(sfont_id != NULL, FLUID_FAILED);
2863     fluid_return_val_if_fail(bank_num != NULL, FLUID_FAILED);
2864     fluid_return_val_if_fail(preset_num != NULL, FLUID_FAILED);
2865     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2866
2867     /* Allowed only on MIDI channel enabled */
2868     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2869
2870     channel = synth->channel[chan];
2871     fluid_channel_get_sfont_bank_prog(channel, sfont_id, bank_num, preset_num);
2872
2873     /* 128 indicates that the preset is unset.  Set to 0 to be backwards compatible. */
2874     if(*preset_num == FLUID_UNSET_PROGRAM)
2875     {
2876         *preset_num = 0;
2877     }
2878
2879     result = FLUID_OK;
2880
2881     FLUID_API_RETURN(result);
2882 }
2883
2884 /**
2885  * Select an instrument on a MIDI channel by SoundFont ID, bank and program numbers.
2886  * @param synth FluidSynth instance
2887  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2888  * @param sfont_id ID of a loaded SoundFont
2889  * @param bank_num MIDI bank number
2890  * @param preset_num MIDI program number
2891  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2892  */
2893 int
2894 fluid_synth_program_select(fluid_synth_t *synth, int chan, int sfont_id,
2895                            int bank_num, int preset_num)
2896 {
2897     fluid_preset_t *preset = NULL;
2898     fluid_channel_t *channel;
2899     int result;
2900     fluid_return_val_if_fail(bank_num >= 0, FLUID_FAILED);
2901     fluid_return_val_if_fail(preset_num >= 0, FLUID_FAILED);
2902
2903     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2904
2905     /* Allowed only on MIDI channel enabled */
2906     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2907
2908     channel = synth->channel[chan];
2909
2910     preset = fluid_synth_get_preset(synth, sfont_id, bank_num, preset_num);
2911
2912     if(preset == NULL)
2913     {
2914         FLUID_LOG(FLUID_ERR,
2915                   "There is no preset with bank number %d and preset number %d in SoundFont %d",
2916                   bank_num, preset_num, sfont_id);
2917         FLUID_API_RETURN(FLUID_FAILED);
2918     }
2919
2920     /* Assign the new SoundFont ID, bank and program number to the channel */
2921     fluid_channel_set_sfont_bank_prog(channel, sfont_id, bank_num, preset_num);
2922     result = fluid_synth_set_preset(synth, chan, preset);
2923
2924     FLUID_API_RETURN(result);
2925 }
2926
2927 /**
2928  * Select an instrument on a MIDI channel by SoundFont name, bank and program numbers.
2929  * @param synth FluidSynth instance
2930  * @param chan MIDI channel number (0 to MIDI channel count - 1)
2931  * @param sfont_name Name of a loaded SoundFont
2932  * @param bank_num MIDI bank number
2933  * @param preset_num MIDI program number
2934  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
2935  * @since 1.1.0
2936  */
2937 int
2938 fluid_synth_program_select_by_sfont_name(fluid_synth_t *synth, int chan,
2939         const char *sfont_name, int bank_num,
2940         int preset_num)
2941 {
2942     fluid_preset_t *preset = NULL;
2943     fluid_channel_t *channel;
2944     int result;
2945     fluid_return_val_if_fail(sfont_name != NULL, FLUID_FAILED);
2946     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
2947
2948     /* Allowed only on MIDI channel enabled */
2949     FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED);
2950
2951     channel = synth->channel[chan];
2952
2953     preset = fluid_synth_get_preset_by_sfont_name(synth, sfont_name, bank_num,
2954              preset_num);
2955
2956     if(preset == NULL)
2957     {
2958         FLUID_LOG(FLUID_ERR,
2959                   "There is no preset with bank number %d and preset number %d in SoundFont %s",
2960                   bank_num, preset_num, sfont_name);
2961         FLUID_API_RETURN(FLUID_FAILED);
2962     }
2963
2964     /* Assign the new SoundFont ID, bank and program number to the channel */
2965     fluid_channel_set_sfont_bank_prog(channel, fluid_sfont_get_id(preset->sfont),
2966                                       bank_num, preset_num);
2967     result = fluid_synth_set_preset(synth, chan, preset);
2968
2969     FLUID_API_RETURN(result);
2970 }
2971
2972 /*
2973  * This function assures that every MIDI channel has a valid preset
2974  * (NULL is okay). This function is called after a SoundFont is
2975  * unloaded or reloaded.
2976  */
2977 static void
2978 fluid_synth_update_presets(fluid_synth_t *synth)
2979 {
2980     fluid_channel_t *channel;
2981     fluid_preset_t *preset;
2982     int sfont, bank, prog;
2983     int chan;
2984
2985     for(chan = 0; chan < synth->midi_channels; chan++)
2986     {
2987         channel = synth->channel[chan];
2988         fluid_channel_get_sfont_bank_prog(channel, &sfont, &bank, &prog);
2989         preset = fluid_synth_get_preset(synth, sfont, bank, prog);
2990         fluid_synth_set_preset(synth, chan, preset);
2991     }
2992 }
2993
2994 /* Handler for synth.sample-rate setting. */
2995 static void
2996 fluid_synth_handle_sample_rate(void *data, const char *name, double value)
2997 {
2998     fluid_synth_t *synth = (fluid_synth_t *)data;
2999     fluid_synth_set_sample_rate(synth, (float) value);
3000 }
3001
3002
3003 /**
3004  * Set sample rate of the synth.
3005  * @note This function should only be used when no voices or notes are active.
3006  * @param synth FluidSynth instance
3007  * @param sample_rate New sample rate (Hz)
3008  * @since 1.1.2
3009  */
3010 void
3011 fluid_synth_set_sample_rate(fluid_synth_t *synth, float sample_rate)
3012 {
3013     int i;
3014     fluid_return_if_fail(synth != NULL);
3015     fluid_synth_api_enter(synth);
3016     fluid_clip(sample_rate, 8000.0f, 96000.0f);
3017     synth->sample_rate = sample_rate;
3018
3019     synth->min_note_length_ticks = fluid_synth_get_min_note_length_LOCAL(synth);
3020
3021     for(i = 0; i < synth->polyphony; i++)
3022     {
3023         fluid_voice_set_output_rate(synth->voice[i], sample_rate);
3024     }
3025
3026     fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_samplerate,
3027                              0, sample_rate);
3028     fluid_synth_api_exit(synth);
3029 }
3030
3031
3032 /* Handler for synth.gain setting. */
3033 static void
3034 fluid_synth_handle_gain(void *data, const char *name, double value)
3035 {
3036     fluid_synth_t *synth = (fluid_synth_t *)data;
3037     fluid_synth_set_gain(synth, (float) value);
3038 }
3039
3040 /**
3041  * Set synth output gain value.
3042  * @param synth FluidSynth instance
3043  * @param gain Gain value (function clamps value to the range 0.0 to 10.0)
3044  */
3045 void
3046 fluid_synth_set_gain(fluid_synth_t *synth, float gain)
3047 {
3048     fluid_return_if_fail(synth != NULL);
3049     fluid_synth_api_enter(synth);
3050
3051     fluid_clip(gain, 0.0f, 10.0f);
3052
3053     synth->gain = gain;
3054     fluid_synth_update_gain_LOCAL(synth);
3055     fluid_synth_api_exit(synth);
3056 }
3057
3058 /* Called by synthesis thread to update the gain in all voices */
3059 static void
3060 fluid_synth_update_gain_LOCAL(fluid_synth_t *synth)
3061 {
3062     fluid_voice_t *voice;
3063     float gain;
3064     int i;
3065
3066     gain = synth->gain;
3067
3068     for(i = 0; i < synth->polyphony; i++)
3069     {
3070         voice = synth->voice[i];
3071
3072         if(fluid_voice_is_playing(voice))
3073         {
3074             fluid_voice_set_gain(voice, gain);
3075         }
3076     }
3077 }
3078
3079 /**
3080  * Get synth output gain value.
3081  * @param synth FluidSynth instance
3082  * @return Synth gain value (0.0 to 10.0)
3083  */
3084 float
3085 fluid_synth_get_gain(fluid_synth_t *synth)
3086 {
3087     float result;
3088     fluid_return_val_if_fail(synth != NULL, 0.0);
3089     fluid_synth_api_enter(synth);
3090
3091     result = synth->gain;
3092     FLUID_API_RETURN(result);
3093 }
3094
3095 /*
3096  * Handler for synth.polyphony setting.
3097  */
3098 static void
3099 fluid_synth_handle_polyphony(void *data, const char *name, int value)
3100 {
3101     fluid_synth_t *synth = (fluid_synth_t *)data;
3102     fluid_synth_set_polyphony(synth, value);
3103 }
3104
3105 /**
3106  * Set synthesizer polyphony (max number of voices).
3107  * @param synth FluidSynth instance
3108  * @param polyphony Polyphony to assign
3109  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
3110  * @since 1.0.6
3111  */
3112 int
3113 fluid_synth_set_polyphony(fluid_synth_t *synth, int polyphony)
3114 {
3115     int result;
3116     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
3117     fluid_return_val_if_fail(polyphony >= 1 && polyphony <= 65535, FLUID_FAILED);
3118     fluid_synth_api_enter(synth);
3119
3120     result = fluid_synth_update_polyphony_LOCAL(synth, polyphony);
3121
3122     FLUID_API_RETURN(result);
3123 }
3124
3125 /* Called by synthesis thread to update the polyphony value */
3126 static int
3127 fluid_synth_update_polyphony_LOCAL(fluid_synth_t *synth, int new_polyphony)
3128 {
3129     fluid_voice_t *voice;
3130     int i;
3131
3132     if(new_polyphony > synth->nvoice)
3133     {
3134         /* Create more voices */
3135         fluid_voice_t **new_voices = FLUID_REALLOC(synth->voice,
3136                                      sizeof(fluid_voice_t *) * new_polyphony);
3137
3138         if(new_voices == NULL)
3139         {
3140             return FLUID_FAILED;
3141         }
3142
3143         synth->voice = new_voices;
3144
3145         for(i = synth->nvoice; i < new_polyphony; i++)
3146         {
3147             synth->voice[i] = new_fluid_voice(synth->eventhandler, synth->sample_rate);
3148
3149             if(synth->voice[i] == NULL)
3150             {
3151                 return FLUID_FAILED;
3152             }
3153
3154             fluid_voice_set_custom_filter(synth->voice[i], synth->custom_filter_type, synth->custom_filter_flags);
3155         }
3156
3157         synth->nvoice = new_polyphony;
3158     }
3159
3160     synth->polyphony = new_polyphony;
3161
3162     /* turn off any voices above the new limit */
3163     for(i = synth->polyphony; i < synth->nvoice; i++)
3164     {
3165         voice = synth->voice[i];
3166
3167         if(fluid_voice_is_playing(voice))
3168         {
3169             fluid_voice_off(voice);
3170         }
3171     }
3172
3173     fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_polyphony,
3174                              synth->polyphony, 0.0f);
3175
3176     return FLUID_OK;
3177 }
3178
3179 /**
3180  * Get current synthesizer polyphony (max number of voices).
3181  * @param synth FluidSynth instance
3182  * @return Synth polyphony value.
3183  * @since 1.0.6
3184  */
3185 int
3186 fluid_synth_get_polyphony(fluid_synth_t *synth)
3187 {
3188     int result;
3189     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
3190     fluid_synth_api_enter(synth);
3191
3192     result = synth->polyphony;
3193     FLUID_API_RETURN(result);
3194 }
3195
3196 /**
3197  * @brief Get current number of active voices.
3198  *
3199  * I.e. the no. of voices that have been
3200  * started and have not yet finished. Unless called from synthesis context,
3201  * this number does not necessarily have to be equal to the number of voices
3202  * currently processed by the DSP loop, see below.
3203  * @param synth FluidSynth instance
3204  * @return Number of currently active voices.
3205  * @since 1.1.0
3206  *
3207  * @note To generate accurate continuous statistics of the voice count, caller
3208  * should ensure this function is called synchronously with the audio synthesis
3209  * process. This can be done in the new_fluid_audio_driver2() audio callback
3210  * function for example. Otherwise every call to this function may return different
3211  * voice counts as it may change after any (concurrent) call to fluid_synth_write_*() made by
3212  * e.g. an audio driver or the applications audio rendering thread.
3213  */
3214 int
3215 fluid_synth_get_active_voice_count(fluid_synth_t *synth)
3216 {
3217     int result;
3218     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
3219     fluid_synth_api_enter(synth);
3220
3221     result = synth->active_voice_count;
3222     FLUID_API_RETURN(result);
3223 }
3224
3225 /**
3226  * Get the internal synthesis buffer size value.
3227  * @param synth FluidSynth instance
3228  * @return Internal buffer size in audio frames.
3229  *
3230  * Audio is synthesized this number of frames at a time.  Defaults to 64 frames.
3231  */
3232 int
3233 fluid_synth_get_internal_bufsize(fluid_synth_t *synth)
3234 {
3235     return FLUID_BUFSIZE;
3236 }
3237
3238 /**
3239  * Resend a bank select and a program change for every channel and assign corresponding instruments.
3240  * @param synth FluidSynth instance
3241  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
3242  *
3243  * This function is called mainly after a SoundFont has been loaded,
3244  * unloaded or reloaded.
3245  */
3246 int
3247 fluid_synth_program_reset(fluid_synth_t *synth)
3248 {
3249     int i, prog;
3250     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
3251     fluid_synth_api_enter(synth);
3252
3253     /* try to set the correct presets */
3254     for(i = 0; i < synth->midi_channels; i++)
3255     {
3256         fluid_channel_get_sfont_bank_prog(synth->channel[i], NULL, NULL, &prog);
3257         fluid_synth_program_change(synth, i, prog);
3258     }
3259
3260     FLUID_API_RETURN(FLUID_OK);
3261 }
3262
3263 /**
3264  * Synthesize a block of floating point audio to separate audio buffers (multichannel rendering). First effect channel used by reverb, second for chorus.
3265  * @param synth FluidSynth instance
3266  * @param len Count of audio frames to synthesize
3267  * @param left Array of float buffers to store left channel of planar audio (as many as \c synth.audio-channels buffers, each of \c len in size)
3268  * @param right Array of float buffers to store right channel of planar audio (size: dito)
3269  * @param fx_left Since 1.1.7: If not \c NULL, array of float buffers to store left effect channels (as many as \c synth.effects-channels buffers, each of \c len in size)
3270  * @param fx_right Since 1.1.7: If not \c NULL, array of float buffers to store right effect channels (size: dito)
3271  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
3272  *
3273  * @note Should only be called from synthesis thread.
3274  *
3275  * @deprecated fluid_synth_nwrite_float() is deprecated and will be removed in a future release. It may continue to work or it may return #FLUID_FAILED in the future. Consider using the more powerful and flexible fluid_synth_process().
3276  *
3277  * Usage example:
3278  * @code{.cpp}
3279     const int FramesToRender = 64;
3280     int channels;
3281     // retrieve number of stereo audio channels
3282     fluid_settings_getint(settings, "synth.audio-channels", &channels);
3283
3284     // we need twice as many (mono-)buffers
3285     channels *= 2;
3286
3287     // fluid_synth_nwrite_float renders planar audio, e.g. if synth.audio-channels==16: each midi channel gets rendered to its own stereo buffer, rather than having one buffer and interleaved PCM
3288     float** mix_buf = new float*[channels];
3289     for(int i = 0; i < channels; i++)
3290     {
3291         mix_buf[i] = new float[FramesToRender];
3292     }
3293
3294     // retrieve number of (stereo) effect channels (internally hardcoded to reverb (first chan) and chrous (second chan))
3295     fluid_settings_getint(settings, "synth.effects-channels", &channels);
3296     channels *= 2;
3297
3298     float** fx_buf = new float*[channels];
3299     for(int i = 0; i < channels; i++)
3300     {
3301         fx_buf[i] = new float[FramesToRender];
3302     }
3303
3304     float** mix_buf_l = mix_buf;
3305     float** mix_buf_r = &mix_buf[channels/2];
3306
3307     float** fx_buf_l = fx_buf;
3308     float** fx_buf_r = &fx_buf[channels/2];
3309
3310     fluid_synth_nwrite_float(synth, FramesToRender, mix_buf_l, mix_buf_r, fx_buf_l, fx_buf_r)
3311  * @endcode
3312  */
3313 int
3314 fluid_synth_nwrite_float(fluid_synth_t *synth, int len,
3315                          float **left, float **right,
3316                          float **fx_left, float **fx_right)
3317 {
3318     fluid_real_t *left_in, *fx_left_in;
3319     fluid_real_t *right_in, *fx_right_in;
3320     double time = fluid_utime();
3321     int i, num, available, count;
3322 #ifdef WITH_FLOAT
3323     int bytes;
3324 #endif
3325     float cpu_load;
3326
3327     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
3328     fluid_return_val_if_fail(left != NULL, FLUID_FAILED);
3329     fluid_return_val_if_fail(right != NULL, FLUID_FAILED);
3330     
3331     /* First, take what's still available in the buffer */
3332     count = 0;
3333     num = synth->cur;
3334
3335     if(synth->cur < FLUID_BUFSIZE)
3336     {
3337         available = FLUID_BUFSIZE - synth->cur;
3338         fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
3339         fluid_rvoice_mixer_get_fx_bufs(synth->eventhandler->mixer, &fx_left_in, &fx_right_in);
3340
3341         num = (available > len) ? len : available;
3342 #ifdef WITH_FLOAT
3343         bytes = num * sizeof(float);
3344 #endif
3345
3346         for(i = 0; i < synth->audio_channels; i++)
3347         {
3348 #ifdef WITH_FLOAT
3349             FLUID_MEMCPY(left[i], &left_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + synth->cur], bytes);
3350             FLUID_MEMCPY(right[i], &right_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + synth->cur], bytes);
3351 #else //WITH_FLOAT
3352             int j;
3353
3354             for(j = 0; j < num; j++)
3355             {
3356                 left[i][j] = (float) left_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + j + synth->cur];
3357                 right[i][j] = (float) right_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + j + synth->cur];
3358             }
3359
3360 #endif //WITH_FLOAT
3361         }
3362
3363         for(i = 0; i < synth->effects_channels; i++)
3364         {
3365 #ifdef WITH_FLOAT
3366
3367             if(fx_left != NULL)
3368             {
3369                 FLUID_MEMCPY(fx_left[i], &fx_left_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + synth->cur], bytes);
3370             }
3371
3372             if(fx_right != NULL)
3373             {
3374                 FLUID_MEMCPY(fx_right[i], &fx_right_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + synth->cur], bytes);
3375             }
3376
3377 #else //WITH_FLOAT
3378             int j;
3379
3380             if(fx_left != NULL)
3381             {
3382                 for(j = 0; j < num; j++)
3383                 {
3384                     fx_left[i][j] = (float) fx_left_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + j + synth->cur];
3385                 }
3386             }
3387
3388             if(fx_right != NULL)
3389             {
3390                 for(j = 0; j < num; j++)
3391                 {
3392                     fx_right[i][j] = (float) fx_right_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + j + synth->cur];
3393                 }
3394             }
3395
3396 #endif //WITH_FLOAT
3397         }
3398
3399         count += num;
3400         num += synth->cur; /* if we're now done, num becomes the new synth->cur below */
3401     }
3402
3403     /* Then, run one_block() and copy till we have 'len' samples  */
3404     while(count < len)
3405     {
3406         fluid_rvoice_mixer_set_mix_fx(synth->eventhandler->mixer, 0);
3407         fluid_synth_render_blocks(synth, 1); // TODO:
3408         fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
3409         fluid_rvoice_mixer_get_fx_bufs(synth->eventhandler->mixer, &fx_left_in, &fx_right_in);
3410
3411         num = (FLUID_BUFSIZE > len - count) ? len - count : FLUID_BUFSIZE;
3412 #ifdef WITH_FLOAT
3413         bytes = num * sizeof(float);
3414 #endif
3415
3416         for(i = 0; i < synth->audio_channels; i++)
3417         {
3418 #ifdef WITH_FLOAT
3419             FLUID_MEMCPY(left[i] + count, &left_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT], bytes);
3420             FLUID_MEMCPY(right[i] + count, &right_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT], bytes);
3421 #else //WITH_FLOAT
3422             int j;
3423
3424             for(j = 0; j < num; j++)
3425             {
3426                 left[i][j + count] = (float) left_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + j];
3427                 right[i][j + count] = (float) right_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + j];
3428             }
3429
3430 #endif //WITH_FLOAT
3431         }
3432
3433         for(i = 0; i < synth->effects_channels; i++)
3434         {
3435 #ifdef WITH_FLOAT
3436
3437             if(fx_left != NULL)
3438             {
3439                 FLUID_MEMCPY(fx_left[i] + count, &fx_left_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT], bytes);
3440             }
3441
3442             if(fx_right != NULL)
3443             {
3444                 FLUID_MEMCPY(fx_right[i] + count, &fx_right_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT], bytes);
3445             }
3446
3447 #else //WITH_FLOAT
3448             int j;
3449
3450             if(fx_left != NULL)
3451             {
3452                 for(j = 0; j < num; j++)
3453                 {
3454                     fx_left[i][j + count] = (float) fx_left_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + j];
3455                 }
3456             }
3457
3458             if(fx_right != NULL)
3459             {
3460                 for(j = 0; j < num; j++)
3461                 {
3462                     fx_right[i][j + count] = (float) fx_right_in[i * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + j];
3463                 }
3464             }
3465
3466 #endif //WITH_FLOAT
3467         }
3468
3469         count += num;
3470     }
3471
3472     synth->cur = num;
3473
3474     time = fluid_utime() - time;
3475     cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
3476     fluid_atomic_float_set(&synth->cpu_load, cpu_load);
3477
3478     return FLUID_OK;
3479 }
3480
3481 /**
3482  * mixes the samples of \p in to \p out
3483  * 
3484  * @param out the output sample buffer to mix to
3485  * @param ooff sample offset in \p out
3486  * @param in the rvoice_mixer input sample buffer to mix from
3487  * @param ioff sample offset in \p in
3488  * @param buf_idx the sample buffer index of \p in to mix from
3489  * @param num number of samples to mix
3490  */
3491 static FLUID_INLINE void fluid_synth_mix_single_buffer(float *FLUID_RESTRICT out,
3492                                                        int ooff,
3493                                                        const fluid_real_t *FLUID_RESTRICT in,
3494                                                        int ioff,
3495                                                        int buf_idx,
3496                                                        int num)
3497 {
3498     if(out != NULL)
3499     {
3500         int j;
3501         for(j = 0; j < num; j++)
3502         {
3503             out[j + ooff] += (float) in[buf_idx * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + j + ioff];
3504         }
3505     }
3506 }
3507
3508 /**
3509  * @brief Synthesize floating point audio to stereo audio channels (implements the default interface #fluid_audio_func_t).
3510  *
3511  * Synthesize and <strong>mix</strong> audio to a given number of planar audio buffers.
3512  * Therefore pass <code>nout = N*2</code> float buffers to \p out in order to render
3513  * the synthesized audio to \p N stereo channels. Each float buffer must be
3514  * able to hold \p len elements.
3515  *
3516  * \p out contains an array of planar buffers for normal, dry, stereo
3517  * audio (alternating left and right). Like:
3518 @code{.cpp}
3519 out[0]  = left_buffer_audio_channel_0
3520 out[1]  = right_buffer_audio_channel_0
3521 out[2]  = left_buffer_audio_channel_1
3522 out[3]  = right_buffer_audio_channel_1
3523 ...
3524 out[ (i * 2 + 0) % nout ]  = left_buffer_audio_channel_i
3525 out[ (i * 2 + 1) % nout ]  = right_buffer_audio_channel_i
3526 @endcode
3527  *
3528  * for zero-based channel index \p i.
3529  * The buffer layout of \p fx used for storing effects
3530  * like reverb and chorus looks similar:
3531 @code{.cpp}
3532 fx[0]  = left_buffer_channel_of_reverb_unit_0
3533 fx[1]  = right_buffer_channel_of_reverb_unit_0
3534 fx[2]  = left_buffer_channel_of_chorus_unit_0
3535 fx[3]  = right_buffer_channel_of_chorus_unit_0
3536 fx[4]  = left_buffer_channel_of_reverb_unit_1
3537 fx[5]  = right_buffer_channel_of_reverb_unit_1
3538 fx[6]  = left_buffer_channel_of_chorus_unit_1
3539 fx[7]  = right_buffer_channel_of_chorus_unit_1
3540 fx[8]  = left_buffer_channel_of_reverb_unit_2
3541 ...
3542 fx[ ((k * fluid_synth_count_effects_channels() + j) * 2 + 0) % nfx ]  = left_buffer_for_effect_channel_j_of_unit_k
3543 fx[ ((k * fluid_synth_count_effects_channels() + j) * 2 + 1) % nfx ]  = right_buffer_for_effect_channel_j_of_unit_k
3544 @endcode
3545  * where <code>0 <= k < fluid_synth_count_effects_groups()</code> is a zero-based index denoting the effects unit and
3546  * <code>0 <= j < fluid_synth_count_effects_channels()</code> is a zero-based index denoting the effect channel within
3547  * unit \p k.
3548  *
3549  * Any voice playing is assigned to audio channels based on the MIDI channel its playing on. Let \p chan be the
3550  * zero-based MIDI channel index an arbitrary voice is playing on. To determine the audio channel and effects unit it is
3551  * going to be rendered to use:
3552  *
3553  * <code>i = chan % fluid_synth_count_audio_groups()</code>
3554  *
3555  * <code>k = chan % fluid_synth_count_effects_groups()</code>
3556  *
3557  * @param synth FluidSynth instance
3558  * @param len Count of audio frames to synthesize and store in every single buffer provided by \p out and \p fx.
3559  * @param nfx Count of arrays in \c fx. Must be a multiple of 2 (because of stereo)
3560  * and in the range <code>0 <= nfx/2 <= (fluid_synth_count_effects_channels() * fluid_synth_count_effects_groups())</code>.
3561  * @param fx Array of buffers to store effects audio to. Buffers may
3562 alias with buffers of \c out. NULL buffers are permitted and will cause to skip mixing any audio into that buffer.
3563  * @param nout Count of arrays in \c out. Must be a multiple of 2
3564 (because of stereo) and in the range <code>0 <= nout/2 <= fluid_synth_count_audio_channels()</code>.
3565  * @param out Array of buffers to store (dry) audio to. Buffers may
3566 alias with buffers of \c fx. NULL buffers are permitted and will cause to skip mixing any audio into that buffer.
3567  * @return #FLUID_OK on success, #FLUID_FAILED otherwise.
3568  *
3569  * @parblock
3570  * @note The owner of the sample buffers must zero them out before calling this
3571  * function, because any synthesized audio is mixed (i.e. added) to the buffers.
3572  * E.g. if fluid_synth_process() is called from a custom audio driver process function
3573  * (see new_fluid_audio_driver2()), the audio driver takes care of zeroing the buffers.
3574  * @endparblock
3575  *
3576  * @parblock
3577  * @note No matter how many buffers you pass in, fluid_synth_process()
3578  * will always render all audio channels to the
3579  * buffers in \c out and all effects channels to the
3580  * buffers in \c fx, provided that <code>nout > 0</code> and <code>nfx > 0</code> respectively. If
3581  * <code>nout/2 < fluid_synth_count_audio_channels()</code> it will wrap around. Same
3582  * is true for effects audio if <code>nfx/2 < (fluid_synth_count_effects_channels() * fluid_synth_count_effects_groups())</code>.
3583  * See usage examples below.
3584  * @endparblock
3585  *
3586  * @parblock
3587  * @note Should only be called from synthesis thread.
3588  * @endparblock
3589  */
3590 int
3591 fluid_synth_process(fluid_synth_t *synth, int len, int nfx, float *fx[],
3592                     int nout, float *out[])
3593 {
3594     fluid_real_t *left_in, *fx_left_in;
3595     fluid_real_t *right_in, *fx_right_in;
3596     int nfxchan, nfxunits, naudchan;
3597
3598     double time = fluid_utime();
3599     int i, f, num, count;
3600
3601     float cpu_load;
3602
3603     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
3604     fluid_return_val_if_fail(nfx % 2 == 0, FLUID_FAILED);
3605     fluid_return_val_if_fail(nout % 2 == 0, FLUID_FAILED);
3606
3607     nfxchan = synth->effects_channels;
3608     nfxunits = synth->effects_groups;
3609     naudchan = synth->audio_channels;
3610
3611     fluid_return_val_if_fail(0 <= nfx / 2 && nfx / 2 <= nfxchan * nfxunits, FLUID_FAILED);
3612     fluid_return_val_if_fail(0 <= nout / 2 && nout / 2 <= naudchan, FLUID_FAILED);
3613
3614     fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
3615     fluid_rvoice_mixer_get_fx_bufs(synth->eventhandler->mixer, &fx_left_in, &fx_right_in);
3616     fluid_rvoice_mixer_set_mix_fx(synth->eventhandler->mixer, FALSE);
3617
3618
3619     /* First, take what's still available in the buffer */
3620     count = 0;
3621     num = synth->cur;
3622
3623     if(synth->cur < FLUID_BUFSIZE)
3624     {
3625         int available = FLUID_BUFSIZE - synth->cur;
3626         num = (available > len) ? len : available;
3627
3628         if(nout != 0)
3629         {
3630             for(i = 0; i < naudchan; i++)
3631             {
3632                 float *out_buf = out[(i * 2) % nout];
3633                 fluid_synth_mix_single_buffer(out_buf, 0, left_in, synth->cur, i, num);
3634
3635                 out_buf = out[(i * 2 + 1) % nout];
3636                 fluid_synth_mix_single_buffer(out_buf, 0, right_in, synth->cur, i, num);
3637             }
3638         }
3639
3640         if(nfx != 0)
3641         {
3642             // loop over all effects units
3643             for(f = 0; f < nfxunits; f++)
3644             {
3645                 // write out all effects (i.e. reverb and chorus)
3646                 for(i = 0; i < nfxchan; i++)
3647                 {
3648                     int buf_idx = f * nfxchan + i;
3649                     
3650                     float *out_buf = fx[(buf_idx * 2) % nfx];
3651                     fluid_synth_mix_single_buffer(out_buf, 0, fx_left_in, synth->cur, buf_idx, num);
3652
3653                     out_buf = fx[(buf_idx * 2 + 1) % nfx];
3654                     fluid_synth_mix_single_buffer(out_buf, 0, fx_right_in, synth->cur, buf_idx, num);
3655                 }
3656             }
3657         }
3658
3659         count += num;
3660         num += synth->cur; /* if we're now done, num becomes the new synth->cur below */
3661     }
3662
3663     /* Then, render blocks and copy till we have 'len' samples  */
3664     while(count < len)
3665     {
3666         int blocksleft = (len - count + FLUID_BUFSIZE - 1) / FLUID_BUFSIZE;
3667         int blockcount = fluid_synth_render_blocks(synth, blocksleft);
3668
3669         num = (blockcount * FLUID_BUFSIZE > len - count) ? len - count : blockcount * FLUID_BUFSIZE;
3670
3671         if(nout != 0)
3672         {
3673             for(i = 0; i < naudchan; i++)
3674             {
3675                 float *out_buf = out[(i * 2) % nout];
3676                 fluid_synth_mix_single_buffer(out_buf, count, left_in, 0, i, num);
3677
3678                 out_buf = out[(i * 2 + 1) % nout];
3679                 fluid_synth_mix_single_buffer(out_buf, count, right_in, 0, i, num);
3680             }
3681         }
3682
3683         if(nfx != 0)
3684         {
3685             // loop over all effects units
3686             for(f = 0; f < nfxunits; f++)
3687             {
3688                 // write out all effects (i.e. reverb and chorus)
3689                 for(i = 0; i < nfxchan; i++)
3690                 {
3691                     int buf_idx = f * nfxchan + i;
3692                     
3693                     float *out_buf = fx[(buf_idx * 2) % nfx];
3694                     fluid_synth_mix_single_buffer(out_buf, count, fx_left_in, 0, buf_idx, num);
3695                     
3696                     out_buf = fx[(buf_idx * 2 + 1) % nfx];
3697                     fluid_synth_mix_single_buffer(out_buf, count, fx_right_in, 0, buf_idx, num);
3698                 }
3699             }
3700         }
3701
3702         count += num;
3703     }
3704
3705     synth->cur = num;
3706
3707     time = fluid_utime() - time;
3708     cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
3709     fluid_atomic_float_set(&synth->cpu_load, cpu_load);
3710
3711     return FLUID_OK;
3712 }
3713
3714 /**
3715  * Synthesize a block of floating point audio samples to audio buffers.
3716  * @param synth FluidSynth instance
3717  * @param len Count of audio frames to synthesize
3718  * @param lout Array of floats to store left channel of audio
3719  * @param loff Offset index in 'lout' for first sample
3720  * @param lincr Increment between samples stored to 'lout'
3721  * @param rout Array of floats to store right channel of audio
3722  * @param roff Offset index in 'rout' for first sample
3723  * @param rincr Increment between samples stored to 'rout'
3724  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
3725  *
3726  * Useful for storing interleaved stereo (lout = rout, loff = 0, roff = 1,
3727  * lincr = 2, rincr = 2).
3728  *
3729  * @note Should only be called from synthesis thread.
3730  * @note Reverb and Chorus are mixed to \c lout resp. \c rout.
3731  */
3732 int
3733 fluid_synth_write_float(fluid_synth_t *synth, int len,
3734                         void *lout, int loff, int lincr,
3735                         void *rout, int roff, int rincr)
3736 {
3737     int i, j, k, l;
3738     float *left_out = (float *) lout;
3739     float *right_out = (float *) rout;
3740     fluid_real_t *left_in;
3741     fluid_real_t *right_in;
3742     double time = fluid_utime();
3743     float cpu_load;
3744
3745     fluid_profile_ref_var(prof_ref);
3746     
3747     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
3748     fluid_return_val_if_fail(lout != NULL, FLUID_FAILED);
3749     fluid_return_val_if_fail(rout != NULL, FLUID_FAILED);
3750
3751     fluid_rvoice_mixer_set_mix_fx(synth->eventhandler->mixer, 1);
3752     l = synth->cur;
3753     fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
3754
3755     for(i = 0, j = loff, k = roff; i < len; i++, l++, j += lincr, k += rincr)
3756     {
3757         /* fill up the buffers as needed */
3758         if(l >= synth->curmax)
3759         {
3760             int blocksleft = (len - i + FLUID_BUFSIZE - 1) / FLUID_BUFSIZE;
3761             synth->curmax = FLUID_BUFSIZE * fluid_synth_render_blocks(synth, blocksleft);
3762             fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
3763
3764             l = 0;
3765         }
3766
3767         left_out[j] = (float) left_in[0 * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + l];
3768         right_out[k] = (float) right_in[0 * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + l];
3769     }
3770
3771     synth->cur = l;
3772
3773     time = fluid_utime() - time;
3774     cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
3775     fluid_atomic_float_set(&synth->cpu_load, cpu_load);
3776
3777     fluid_profile_write(FLUID_PROF_WRITE, prof_ref,
3778                         fluid_rvoice_mixer_get_active_voices(synth->eventhandler->mixer),
3779                         len);
3780     return FLUID_OK;
3781 }
3782
3783 #define DITHER_SIZE 48000
3784 #define DITHER_CHANNELS 2
3785
3786 static float rand_table[DITHER_CHANNELS][DITHER_SIZE];
3787
3788 /* Init dither table */
3789 static void
3790 init_dither(void)
3791 {
3792     float d, dp;
3793     int c, i;
3794
3795     for(c = 0; c < DITHER_CHANNELS; c++)
3796     {
3797         dp = 0;
3798
3799         for(i = 0; i < DITHER_SIZE - 1; i++)
3800         {
3801             d = rand() / (float)RAND_MAX - 0.5f;
3802             rand_table[c][i] = d - dp;
3803             dp = d;
3804         }
3805
3806         rand_table[c][DITHER_SIZE - 1] = 0 - dp;
3807     }
3808 }
3809
3810 /* A portable replacement for roundf(), seems it may actually be faster too! */
3811 static FLUID_INLINE int
3812 roundi(float x)
3813 {
3814     if(x >= 0.0f)
3815     {
3816         return (int)(x + 0.5f);
3817     }
3818     else
3819     {
3820         return (int)(x - 0.5f);
3821     }
3822 }
3823
3824 /**
3825  * Synthesize a block of 16 bit audio samples to audio buffers.
3826  * @param synth FluidSynth instance
3827  * @param len Count of audio frames to synthesize
3828  * @param lout Array of 16 bit words to store left channel of audio
3829  * @param loff Offset index in 'lout' for first sample
3830  * @param lincr Increment between samples stored to 'lout'
3831  * @param rout Array of 16 bit words to store right channel of audio
3832  * @param roff Offset index in 'rout' for first sample
3833  * @param rincr Increment between samples stored to 'rout'
3834  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
3835  *
3836  * Useful for storing interleaved stereo (lout = rout, loff = 0, roff = 1,
3837  * lincr = 2, rincr = 2).
3838  *
3839  * @note Should only be called from synthesis thread.
3840  * @note Reverb and Chorus are mixed to \c lout resp. \c rout.
3841  * @note Dithering is performed when converting from internal floating point to
3842  * 16 bit audio.
3843  */
3844 int
3845 fluid_synth_write_s16(fluid_synth_t *synth, int len,
3846                       void *lout, int loff, int lincr,
3847                       void *rout, int roff, int rincr)
3848 {
3849     int i, j, k, cur;
3850     signed short *left_out = (signed short *) lout;
3851     signed short *right_out = (signed short *) rout;
3852     fluid_real_t *left_in;
3853     fluid_real_t *right_in;
3854     fluid_real_t left_sample;
3855     fluid_real_t right_sample;
3856     double time = fluid_utime();
3857     int di;
3858     float cpu_load;
3859
3860     fluid_profile_ref_var(prof_ref);
3861
3862     fluid_rvoice_mixer_set_mix_fx(synth->eventhandler->mixer, 1);
3863     fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
3864
3865     cur = synth->cur;
3866     di = synth->dither_index;
3867
3868     for(i = 0, j = loff, k = roff; i < len; i++, cur++, j += lincr, k += rincr)
3869     {
3870
3871         /* fill up the buffers as needed */
3872         if(cur >= synth->curmax)
3873         {
3874             int blocksleft = (len - i + FLUID_BUFSIZE - 1) / FLUID_BUFSIZE;
3875             synth->curmax = FLUID_BUFSIZE * fluid_synth_render_blocks(synth, blocksleft);
3876             fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
3877             cur = 0;
3878         }
3879
3880         left_sample = roundi(left_in[0 * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + cur] * 32766.0f + rand_table[0][di]);
3881         right_sample = roundi(right_in[0 * FLUID_BUFSIZE * FLUID_MIXER_MAX_BUFFERS_DEFAULT + cur] * 32766.0f + rand_table[1][di]);
3882
3883         di++;
3884
3885         if(di >= DITHER_SIZE)
3886         {
3887             di = 0;
3888         }
3889
3890         /* digital clipping */
3891         if(left_sample > 32767.0f)
3892         {
3893             left_sample = 32767.0f;
3894         }
3895
3896         if(left_sample < -32768.0f)
3897         {
3898             left_sample = -32768.0f;
3899         }
3900
3901         if(right_sample > 32767.0f)
3902         {
3903             right_sample = 32767.0f;
3904         }
3905
3906         if(right_sample < -32768.0f)
3907         {
3908             right_sample = -32768.0f;
3909         }
3910
3911         left_out[j] = (signed short) left_sample;
3912         right_out[k] = (signed short) right_sample;
3913     }
3914
3915     synth->cur = cur;
3916     synth->dither_index = di;   /* keep dither buffer continous */
3917
3918     time = fluid_utime() - time;
3919     cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
3920     fluid_atomic_float_set(&synth->cpu_load, cpu_load);
3921
3922     fluid_profile_write(FLUID_PROF_WRITE, prof_ref,
3923                         fluid_rvoice_mixer_get_active_voices(synth->eventhandler->mixer),
3924                         len);
3925     return 0;
3926 }
3927
3928 /**
3929  * Converts stereo floating point sample data to signed 16 bit data with dithering.
3930  * @param dither_index Pointer to an integer which should be initialized to 0
3931  *   before the first call and passed unmodified to additional calls which are
3932  *   part of the same synthesis output.
3933  * @param len Length in frames to convert
3934  * @param lin Buffer of left audio samples to convert from
3935  * @param rin Buffer of right audio samples to convert from
3936  * @param lout Array of 16 bit words to store left channel of audio
3937  * @param loff Offset index in 'lout' for first sample
3938  * @param lincr Increment between samples stored to 'lout'
3939  * @param rout Array of 16 bit words to store right channel of audio
3940  * @param roff Offset index in 'rout' for first sample
3941  * @param rincr Increment between samples stored to 'rout'
3942  *
3943  * @note Currently private to libfluidsynth.
3944  */
3945 void
3946 fluid_synth_dither_s16(int *dither_index, int len, float *lin, float *rin,
3947                        void *lout, int loff, int lincr,
3948                        void *rout, int roff, int rincr)
3949 {
3950     int i, j, k;
3951     signed short *left_out = (signed short *) lout;
3952     signed short *right_out = (signed short *) rout;
3953     fluid_real_t left_sample;
3954     fluid_real_t right_sample;
3955     int di = *dither_index;
3956     fluid_profile_ref_var(prof_ref);
3957
3958     for(i = 0, j = loff, k = roff; i < len; i++, j += lincr, k += rincr)
3959     {
3960
3961         left_sample = roundi(lin[i] * 32766.0f + rand_table[0][di]);
3962         right_sample = roundi(rin[i] * 32766.0f + rand_table[1][di]);
3963
3964         di++;
3965
3966         if(di >= DITHER_SIZE)
3967         {
3968             di = 0;
3969         }
3970
3971         /* digital clipping */
3972         if(left_sample > 32767.0f)
3973         {
3974             left_sample = 32767.0f;
3975         }
3976
3977         if(left_sample < -32768.0f)
3978         {
3979             left_sample = -32768.0f;
3980         }
3981
3982         if(right_sample > 32767.0f)
3983         {
3984             right_sample = 32767.0f;
3985         }
3986
3987         if(right_sample < -32768.0f)
3988         {
3989             right_sample = -32768.0f;
3990         }
3991
3992         left_out[j] = (signed short) left_sample;
3993         right_out[k] = (signed short) right_sample;
3994     }
3995
3996     *dither_index = di; /* keep dither buffer continous */
3997
3998     fluid_profile(FLUID_PROF_WRITE, prof_ref, 0, len);
3999 }
4000
4001 static void
4002 fluid_synth_check_finished_voices(fluid_synth_t *synth)
4003 {
4004     int j;
4005     fluid_rvoice_t *fv;
4006
4007     while(NULL != (fv = fluid_rvoice_eventhandler_get_finished_voice(synth->eventhandler)))
4008     {
4009         for(j = 0; j < synth->polyphony; j++)
4010         {
4011             if(synth->voice[j]->rvoice == fv)
4012             {
4013                 fluid_voice_unlock_rvoice(synth->voice[j]);
4014                 fluid_voice_stop(synth->voice[j]);
4015                 break;
4016             }
4017             else if(synth->voice[j]->overflow_rvoice == fv)
4018             {
4019                 fluid_voice_overflow_rvoice_finished(synth->voice[j]);
4020                 break;
4021             }
4022         }
4023     }
4024 }
4025
4026 /**
4027  * Process all waiting events in the rvoice queue.
4028  * Make sure no (other) rendering is running in parallel when
4029  * you call this function!
4030  */
4031 void fluid_synth_process_event_queue(fluid_synth_t *synth)
4032 {
4033     fluid_rvoice_eventhandler_dispatch_all(synth->eventhandler);
4034 }
4035
4036
4037 /**
4038  * Process blocks (FLUID_BUFSIZE) of audio.
4039  * Must be called from renderer thread only!
4040  * @return number of blocks rendered. Might (often) return less than requested
4041  */
4042 static int
4043 fluid_synth_render_blocks(fluid_synth_t *synth, int blockcount)
4044 {
4045     int i, maxblocks;
4046     fluid_profile_ref_var(prof_ref);
4047
4048     /* Assign ID of synthesis thread */
4049 //  synth->synth_thread_id = fluid_thread_get_id ();
4050
4051     fluid_check_fpe("??? Just starting up ???");
4052
4053     fluid_rvoice_eventhandler_dispatch_all(synth->eventhandler);
4054
4055     /* do not render more blocks than we can store internally */
4056     maxblocks = fluid_rvoice_mixer_get_bufcount(synth->eventhandler->mixer);
4057
4058     if(blockcount > maxblocks)
4059     {
4060         blockcount = maxblocks;
4061     }
4062
4063     for(i = 0; i < blockcount; i++)
4064     {
4065         fluid_sample_timer_process(synth);
4066         fluid_synth_add_ticks(synth, FLUID_BUFSIZE);
4067
4068         /* If events have been queued waiting for fluid_rvoice_eventhandler_dispatch_all()
4069          * (should only happen with parallel render) stop processing and go for rendering
4070          */
4071         if(fluid_rvoice_eventhandler_dispatch_count(synth->eventhandler))
4072         {
4073             // Something has happened, we can't process more
4074             blockcount = i + 1;
4075             break;
4076         }
4077     }
4078
4079     fluid_check_fpe("fluid_sample_timer_process");
4080
4081     blockcount = fluid_rvoice_mixer_render(synth->eventhandler->mixer, blockcount);
4082
4083     /* Testcase, that provokes a denormal floating point error */
4084 #if 0
4085     {
4086         float num = 1;
4087
4088         while(num != 0)
4089         {
4090             num *= 0.5;
4091         };
4092     };
4093 #endif
4094     fluid_check_fpe("??? Remainder of synth_one_block ???");
4095     fluid_profile(FLUID_PROF_ONE_BLOCK, prof_ref,
4096                   fluid_rvoice_mixer_get_active_voices(synth->eventhandler->mixer),
4097                   blockcount * FLUID_BUFSIZE);
4098     return blockcount;
4099 }
4100
4101 /*
4102  * Handler for synth.reverb.* and synth.chorus.* double settings.
4103  */
4104 static void fluid_synth_handle_reverb_chorus_num(void *data, const char *name, double value)
4105 {
4106     fluid_synth_t *synth = (fluid_synth_t *)data;
4107     fluid_return_if_fail(synth != NULL);
4108
4109     if(FLUID_STRCMP(name, "synth.reverb.room-size") == 0)
4110     {
4111         fluid_synth_set_reverb_roomsize(synth, value);
4112     }
4113     else if(FLUID_STRCMP(name, "synth.reverb.damp") == 0)
4114     {
4115         fluid_synth_set_reverb_damp(synth, value);
4116     }
4117     else if(FLUID_STRCMP(name, "synth.reverb.width") == 0)
4118     {
4119         fluid_synth_set_reverb_width(synth, value);
4120     }
4121     else if(FLUID_STRCMP(name, "synth.reverb.level") == 0)
4122     {
4123         fluid_synth_set_reverb_level(synth, value);
4124     }
4125     else if(FLUID_STRCMP(name, "synth.chorus.depth") == 0)
4126     {
4127         fluid_synth_set_chorus_depth(synth, value);
4128     }
4129     else if(FLUID_STRCMP(name, "synth.chorus.speed") == 0)
4130     {
4131         fluid_synth_set_chorus_speed(synth, value);
4132     }
4133     else if(FLUID_STRCMP(name, "synth.chorus.level") == 0)
4134     {
4135         fluid_synth_set_chorus_level(synth, value);
4136     }
4137 }
4138
4139 /*
4140  * Handler for synth.reverb.* and synth.chorus.* integer settings.
4141  */
4142 static void fluid_synth_handle_reverb_chorus_int(void *data, const char *name, int value)
4143 {
4144     fluid_synth_t *synth = (fluid_synth_t *)data;
4145     fluid_return_if_fail(synth != NULL);
4146
4147     if(FLUID_STRCMP(name, "synth.reverb.active") == 0)
4148     {
4149         fluid_synth_set_reverb_on(synth, value);
4150     }
4151     else if(FLUID_STRCMP(name, "synth.chorus.active") == 0)
4152     {
4153         fluid_synth_set_chorus_on(synth, value);
4154     }
4155     else if(FLUID_STRCMP(name, "synth.chorus.nr") == 0)
4156     {
4157         fluid_synth_set_chorus_nr(synth, value);
4158     }
4159 }
4160
4161 /*
4162  * Handler for synth.overflow.* settings.
4163  */
4164 static void fluid_synth_handle_overflow(void *data, const char *name, double value)
4165 {
4166     fluid_synth_t *synth = (fluid_synth_t *)data;
4167     fluid_return_if_fail(synth != NULL);
4168
4169     fluid_synth_api_enter(synth);
4170
4171     if(FLUID_STRCMP(name, "synth.overflow.percussion") == 0)
4172     {
4173         synth->overflow.percussion = value;
4174     }
4175     else if(FLUID_STRCMP(name, "synth.overflow.released") == 0)
4176     {
4177         synth->overflow.released = value;
4178     }
4179     else if(FLUID_STRCMP(name, "synth.overflow.sustained") == 0)
4180     {
4181         synth->overflow.sustained = value;
4182     }
4183     else if(FLUID_STRCMP(name, "synth.overflow.volume") == 0)
4184     {
4185         synth->overflow.volume = value;
4186     }
4187     else if(FLUID_STRCMP(name, "synth.overflow.age") == 0)
4188     {
4189         synth->overflow.age = value;
4190     }
4191     else if(FLUID_STRCMP(name, "synth.overflow.important") == 0)
4192     {
4193         synth->overflow.important = value;
4194     }
4195
4196     fluid_synth_api_exit(synth);
4197 }
4198
4199 /* Selects a voice for killing. */
4200 static fluid_voice_t *
4201 fluid_synth_free_voice_by_kill_LOCAL(fluid_synth_t *synth)
4202 {
4203     int i;
4204     float best_prio = OVERFLOW_PRIO_CANNOT_KILL - 1;
4205     float this_voice_prio;
4206     fluid_voice_t *voice;
4207     int best_voice_index = -1;
4208     unsigned int ticks = fluid_synth_get_ticks(synth);
4209
4210     for(i = 0; i < synth->polyphony; i++)
4211     {
4212
4213         voice = synth->voice[i];
4214
4215         /* safeguard against an available voice. */
4216         if(_AVAILABLE(voice))
4217         {
4218             return voice;
4219         }
4220
4221         this_voice_prio = fluid_voice_get_overflow_prio(voice, &synth->overflow,
4222                           ticks);
4223
4224         /* check if this voice has less priority than the previous candidate. */
4225         if(this_voice_prio < best_prio)
4226         {
4227             best_voice_index = i;
4228             best_prio = this_voice_prio;
4229         }
4230     }
4231
4232     if(best_voice_index < 0)
4233     {
4234         return NULL;
4235     }
4236
4237     voice = synth->voice[best_voice_index];
4238     FLUID_LOG(FLUID_DBG, "Killing voice %d, index %d, chan %d, key %d ",
4239               fluid_voice_get_id(voice), best_voice_index, fluid_voice_get_channel(voice), fluid_voice_get_key(voice));
4240     fluid_voice_off(voice);
4241
4242     return voice;
4243 }
4244
4245
4246 /**
4247  * Allocate a synthesis voice.
4248  * @param synth FluidSynth instance
4249  * @param sample Sample to assign to the voice
4250  * @param chan MIDI channel number (0 to MIDI channel count - 1)
4251  * @param key MIDI note number for the voice (0-127)
4252  * @param vel MIDI velocity for the voice (0-127)
4253  * @return Allocated synthesis voice or NULL on error
4254  *
4255  * This function is called by a SoundFont's preset in response to a noteon event.
4256  * The returned voice comes with default modulators and generators.
4257  * A single noteon event may create any number of voices, when the preset is layered.
4258  *
4259  * @note Should only be called from within synthesis thread, which includes
4260  * SoundFont loader preset noteon method.
4261  */
4262 fluid_voice_t *
4263 fluid_synth_alloc_voice(fluid_synth_t *synth, fluid_sample_t *sample,
4264                         int chan, int key, int vel)
4265 {
4266     fluid_return_val_if_fail(sample != NULL, NULL);
4267     FLUID_API_ENTRY_CHAN(NULL);
4268     FLUID_API_RETURN(fluid_synth_alloc_voice_LOCAL(synth, sample, chan, key, vel, NULL));
4269
4270 }
4271
4272 fluid_voice_t *
4273 fluid_synth_alloc_voice_LOCAL(fluid_synth_t *synth, fluid_sample_t *sample, int chan, int key, int vel, fluid_zone_range_t *zone_range)
4274 {
4275     int i, k;
4276     fluid_voice_t *voice = NULL;
4277     fluid_channel_t *channel = NULL;
4278     unsigned int ticks;
4279
4280     /* check if there's an available synthesis process */
4281     for(i = 0; i < synth->polyphony; i++)
4282     {
4283         if(_AVAILABLE(synth->voice[i]))
4284         {
4285             voice = synth->voice[i];
4286             break;
4287         }
4288     }
4289
4290     /* No success yet? Then stop a running voice. */
4291     if(voice == NULL)
4292     {
4293         FLUID_LOG(FLUID_DBG, "Polyphony exceeded, trying to kill a voice");
4294         voice = fluid_synth_free_voice_by_kill_LOCAL(synth);
4295     }
4296
4297     if(voice == NULL)
4298     {
4299         FLUID_LOG(FLUID_WARN, "Failed to allocate a synthesis process. (chan=%d,key=%d)", chan, key);
4300         return NULL;
4301     }
4302
4303     ticks = fluid_synth_get_ticks(synth);
4304
4305     if(synth->verbose)
4306     {
4307         k = 0;
4308
4309         for(i = 0; i < synth->polyphony; i++)
4310         {
4311             if(!_AVAILABLE(synth->voice[i]))
4312             {
4313                 k++;
4314             }
4315         }
4316
4317         FLUID_LOG(FLUID_INFO, "noteon\t%d\t%d\t%d\t%05d\t%.3f\t%.3f\t%.3f\t%d",
4318                   chan, key, vel, synth->storeid,
4319                   (float) ticks / 44100.0f,
4320                   (fluid_curtime() - synth->start) / 1000.0f,
4321                   0.0f,
4322                   k);
4323     }
4324
4325     channel = synth->channel[chan];
4326
4327     if(fluid_voice_init(voice, sample, zone_range, channel, key, vel,
4328                         synth->storeid, ticks, synth->gain) != FLUID_OK)
4329     {
4330         FLUID_LOG(FLUID_WARN, "Failed to initialize voice");
4331         return NULL;
4332     }
4333
4334     /* add the default modulators to the synthesis process. */
4335     /* custom_breath2att_modulator is not a default modulator specified in SF
4336       it is intended to replace default_vel2att_mod for this channel on demand using
4337       API fluid_synth_set_breath_mode() or shell command setbreathmode for this channel.
4338     */
4339     {
4340         int mono = fluid_channel_is_playing_mono(channel);
4341         fluid_mod_t *default_mod = synth->default_mod;
4342
4343         while(default_mod != NULL)
4344         {
4345             if(
4346                 /* See if default_mod is the velocity_to_attenuation modulator */
4347                 fluid_mod_test_identity(default_mod, &default_vel2att_mod) &&
4348                 // See if a replacement by custom_breath2att_modulator has been demanded
4349                 // for this channel
4350                 ((!mono && (channel->mode &  FLUID_CHANNEL_BREATH_POLY)) ||
4351                  (mono && (channel->mode &  FLUID_CHANNEL_BREATH_MONO)))
4352             )
4353             {
4354                 // Replacement of default_vel2att modulator by custom_breath2att_modulator
4355                 fluid_voice_add_mod(voice, &custom_breath2att_mod, FLUID_VOICE_DEFAULT);
4356             }
4357             else
4358             {
4359                 fluid_voice_add_mod(voice, default_mod, FLUID_VOICE_DEFAULT);
4360             }
4361
4362             // Next default modulator to add to the voice
4363             default_mod = default_mod->next;
4364         }
4365     }
4366
4367     return voice;
4368 }
4369
4370 /* Kill all voices on a given channel, which have the same exclusive class
4371  * generator as new_voice.
4372  */
4373 static void
4374 fluid_synth_kill_by_exclusive_class_LOCAL(fluid_synth_t *synth,
4375         fluid_voice_t *new_voice)
4376 {
4377     int excl_class = fluid_voice_gen_value(new_voice, GEN_EXCLUSIVECLASS);
4378     int i;
4379
4380     /* Excl. class 0: No exclusive class */
4381     if(excl_class == 0)
4382     {
4383         return;
4384     }
4385
4386     /* Kill all notes on the same channel with the same exclusive class */
4387     for(i = 0; i < synth->polyphony; i++)
4388     {
4389         fluid_voice_t *existing_voice = synth->voice[i];
4390         int existing_excl_class = fluid_voice_gen_value(existing_voice, GEN_EXCLUSIVECLASS);
4391
4392         /* If voice is playing, on the same channel, has same exclusive
4393          * class and is not part of the same noteon event (voice group), then kill it */
4394
4395         if(fluid_voice_is_playing(existing_voice)
4396                 && fluid_voice_get_channel(existing_voice) == fluid_voice_get_channel(new_voice)
4397                 && existing_excl_class == excl_class
4398                 && fluid_voice_get_id(existing_voice) != fluid_voice_get_id(new_voice))
4399         {
4400             fluid_voice_kill_excl(existing_voice);
4401         }
4402     }
4403 }
4404
4405 /**
4406  * Activate a voice previously allocated with fluid_synth_alloc_voice().
4407  * @param synth FluidSynth instance
4408  * @param voice Voice to activate
4409  *
4410  * This function is called by a SoundFont's preset in response to a noteon
4411  * event.  Exclusive classes are processed here.
4412  *
4413  * @note Should only be called from within synthesis thread, which includes
4414  * SoundFont loader preset noteon method.
4415  */
4416 void
4417 fluid_synth_start_voice(fluid_synth_t *synth, fluid_voice_t *voice)
4418 {
4419     fluid_return_if_fail(synth != NULL);
4420     fluid_return_if_fail(voice != NULL);
4421 //  fluid_return_if_fail (fluid_synth_is_synth_thread (synth));
4422     fluid_synth_api_enter(synth);
4423
4424     /* Find the exclusive class of this voice. If set, kill all voices
4425      * that match the exclusive class and are younger than the first
4426      * voice process created by this noteon event. */
4427     fluid_synth_kill_by_exclusive_class_LOCAL(synth, voice);
4428
4429     fluid_voice_start(voice);     /* Start the new voice */
4430     fluid_voice_lock_rvoice(voice);
4431     fluid_rvoice_eventhandler_add_rvoice(synth->eventhandler, voice->rvoice);
4432     fluid_synth_api_exit(synth);
4433 }
4434
4435 /**
4436  * Add a SoundFont loader to the synth. This function takes ownership of \c loader
4437  * and frees it automatically upon \c synth destruction.
4438  * @param synth FluidSynth instance
4439  * @param loader Loader API structure
4440  *
4441  * SoundFont loaders are used to add custom instrument loading to FluidSynth.
4442  * The caller supplied functions for loading files, allocating presets,
4443  * retrieving information on them and synthesizing note-on events.  Using this
4444  * method even non SoundFont instruments can be synthesized, although limited
4445  * to the SoundFont synthesis model.
4446  *
4447  * @note Should only be called before any SoundFont files are loaded.
4448  */
4449 void
4450 fluid_synth_add_sfloader(fluid_synth_t *synth, fluid_sfloader_t *loader)
4451 {
4452     fluid_return_if_fail(synth != NULL);
4453     fluid_return_if_fail(loader != NULL);
4454     fluid_synth_api_enter(synth);
4455
4456     /* Test if sfont is already loaded */
4457     if(synth->sfont == NULL)
4458     {
4459         synth->loaders = fluid_list_prepend(synth->loaders, loader);
4460     }
4461
4462     fluid_synth_api_exit(synth);
4463 }
4464
4465 /**
4466  * Load a SoundFont file (filename is interpreted by SoundFont loaders).
4467  * The newly loaded SoundFont will be put on top of the SoundFont
4468  * stack. Presets are searched starting from the SoundFont on the
4469  * top of the stack, working the way down the stack until a preset is found.
4470  *
4471  * @param synth FluidSynth instance
4472  * @param filename File to load
4473  * @param reset_presets TRUE to re-assign presets for all MIDI channels (equivalent to calling fluid_synth_program_reset())
4474  * @return SoundFont ID on success, #FLUID_FAILED on error
4475  */
4476 int
4477 fluid_synth_sfload(fluid_synth_t *synth, const char *filename, int reset_presets)
4478 {
4479     fluid_sfont_t *sfont;
4480     fluid_list_t *list;
4481     fluid_sfloader_t *loader;
4482     int sfont_id;
4483
4484     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
4485     fluid_return_val_if_fail(filename != NULL, FLUID_FAILED);
4486     fluid_synth_api_enter(synth);
4487
4488     sfont_id = synth->sfont_id;
4489
4490     if(++sfont_id != FLUID_FAILED)
4491     {
4492         /* MT NOTE: Loaders list should not change. */
4493
4494         for(list = synth->loaders; list; list = fluid_list_next(list))
4495         {
4496             loader = (fluid_sfloader_t *) fluid_list_get(list);
4497
4498             sfont = fluid_sfloader_load(loader, filename);
4499
4500             if(sfont != NULL)
4501             {
4502                 sfont->refcount++;
4503                 synth->sfont_id = sfont->id = sfont_id;
4504
4505                 synth->sfont = fluid_list_prepend(synth->sfont, sfont);   /* prepend to list */
4506
4507                 /* reset the presets for all channels if requested */
4508                 if(reset_presets)
4509                 {
4510                     fluid_synth_program_reset(synth);
4511                 }
4512
4513                 FLUID_API_RETURN(sfont_id);
4514             }
4515         }
4516     }
4517
4518     FLUID_LOG(FLUID_ERR, "Failed to load SoundFont \"%s\"", filename);
4519     FLUID_API_RETURN(FLUID_FAILED);
4520 }
4521
4522 /**
4523  * Unload a SoundFont.
4524  * @param synth FluidSynth instance
4525  * @param id ID of SoundFont to unload
4526  * @param reset_presets TRUE to re-assign presets for all MIDI channels
4527  * @return #FLUID_OK on success, #FLUID_FAILED on error
4528  */
4529 int
4530 fluid_synth_sfunload(fluid_synth_t *synth, int id, int reset_presets)
4531 {
4532     fluid_sfont_t *sfont = NULL;
4533     fluid_list_t *list;
4534
4535     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
4536     fluid_synth_api_enter(synth);
4537
4538     /* remove the SoundFont from the list */
4539     for(list = synth->sfont; list; list = fluid_list_next(list))
4540     {
4541         sfont = fluid_list_get(list);
4542
4543         if(fluid_sfont_get_id(sfont) == id)
4544         {
4545             synth->sfont = fluid_list_remove(synth->sfont, sfont);
4546             break;
4547         }
4548     }
4549
4550     if(!list)
4551     {
4552         FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", id);
4553         FLUID_API_RETURN(FLUID_FAILED);
4554     }
4555
4556     /* reset the presets for all channels (SoundFont will be freed when there are no more references) */
4557     if(reset_presets)
4558     {
4559         fluid_synth_program_reset(synth);
4560     }
4561     else
4562     {
4563         fluid_synth_update_presets(synth);
4564     }
4565
4566     /* -- Remove synth->sfont list's reference to SoundFont */
4567     fluid_synth_sfont_unref(synth, sfont);
4568
4569     FLUID_API_RETURN(FLUID_OK);
4570 }
4571
4572 /* Unref a SoundFont and destroy if no more references */
4573 void
4574 fluid_synth_sfont_unref(fluid_synth_t *synth, fluid_sfont_t *sfont)
4575 {
4576     fluid_return_if_fail(sfont != NULL);     /* Shouldn't happen, programming error if so */
4577
4578     sfont->refcount--;             /* -- Remove the sfont list's reference */
4579
4580     if(sfont->refcount == 0)  /* No more references? - Attempt delete */
4581     {
4582         if(fluid_sfont_delete_internal(sfont) == 0)      /* SoundFont loader can block SoundFont unload */
4583         {
4584             FLUID_LOG(FLUID_DBG, "Unloaded SoundFont");
4585         } /* spin off a timer thread to unload the sfont later (SoundFont loader blocked unload) */
4586         else
4587         {
4588             new_fluid_timer(100, fluid_synth_sfunload_callback, sfont, TRUE, TRUE, FALSE);
4589         }
4590     }
4591 }
4592
4593 /* Callback to continually attempt to unload a SoundFont,
4594  * only if a SoundFont loader blocked the unload operation */
4595 static int
4596 fluid_synth_sfunload_callback(void *data, unsigned int msec)
4597 {
4598     fluid_sfont_t *sfont = data;
4599
4600     if(fluid_sfont_delete_internal(sfont) == 0)
4601     {
4602         FLUID_LOG(FLUID_DBG, "Unloaded SoundFont");
4603         return FALSE;
4604     }
4605     else
4606     {
4607         return TRUE;
4608     }
4609 }
4610
4611 /**
4612  * Reload a SoundFont.  The SoundFont retains its ID and index on the SoundFont stack.
4613  * @param synth FluidSynth instance
4614  * @param id ID of SoundFont to reload
4615  * @return SoundFont ID on success, #FLUID_FAILED on error
4616  */
4617 int
4618 fluid_synth_sfreload(fluid_synth_t *synth, int id)
4619 {
4620     char *filename = NULL;
4621     fluid_sfont_t *sfont;
4622     fluid_sfloader_t *loader;
4623     fluid_list_t *list;
4624     int index, ret = FLUID_FAILED;
4625
4626     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
4627     fluid_synth_api_enter(synth);
4628
4629     /* Search for SoundFont and get its index */
4630     for(list = synth->sfont, index = 0; list; list = fluid_list_next(list), index++)
4631     {
4632         sfont = fluid_list_get(list);
4633
4634         if(fluid_sfont_get_id(sfont) == id)
4635         {
4636             break;
4637         }
4638     }
4639
4640     if(!list)
4641     {
4642         FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", id);
4643         goto exit;
4644     }
4645
4646     /* keep a copy of the SoundFont's filename */
4647     filename = FLUID_STRDUP(fluid_sfont_get_name(sfont));
4648
4649     if(filename == NULL || fluid_synth_sfunload(synth, id, FALSE) != FLUID_OK)
4650     {
4651         goto exit;
4652     }
4653
4654     /* MT Note: SoundFont loader list will not change */
4655
4656     for(list = synth->loaders; list; list = fluid_list_next(list))
4657     {
4658         loader = (fluid_sfloader_t *) fluid_list_get(list);
4659
4660         sfont = fluid_sfloader_load(loader, filename);
4661
4662         if(sfont != NULL)
4663         {
4664             sfont->id = id;
4665             sfont->refcount++;
4666
4667             synth->sfont = fluid_list_insert_at(synth->sfont, index, sfont);  /* insert the sfont at the same index */
4668
4669             /* reset the presets for all channels */
4670             fluid_synth_update_presets(synth);
4671             ret = id;
4672             goto exit;
4673         }
4674     }
4675
4676     FLUID_LOG(FLUID_ERR, "Failed to load SoundFont \"%s\"", filename);
4677
4678 exit:
4679     FLUID_FREE(filename);
4680     FLUID_API_RETURN(ret);
4681 }
4682
4683 /**
4684  * Add a SoundFont.  The SoundFont will be added to the top of the SoundFont stack.
4685  * @param synth FluidSynth instance
4686  * @param sfont SoundFont to add
4687  * @return New assigned SoundFont ID or #FLUID_FAILED on error
4688  */
4689 int
4690 fluid_synth_add_sfont(fluid_synth_t *synth, fluid_sfont_t *sfont)
4691 {
4692     int sfont_id;
4693
4694     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
4695     fluid_return_val_if_fail(sfont != NULL, FLUID_FAILED);
4696     fluid_synth_api_enter(synth);
4697
4698     sfont_id = synth->sfont_id;
4699
4700     if(++sfont_id != FLUID_FAILED)
4701     {
4702         synth->sfont_id = sfont->id = sfont_id;
4703         synth->sfont = fluid_list_prepend(synth->sfont, sfont);        /* prepend to list */
4704
4705         /* reset the presets for all channels */
4706         fluid_synth_program_reset(synth);
4707     }
4708
4709     FLUID_API_RETURN(sfont_id);
4710 }
4711
4712 /**
4713  * Remove a SoundFont from the SoundFont stack without deleting it.
4714  * @param synth FluidSynth instance
4715  * @param sfont SoundFont to remove
4716  * @return #FLUID_OK if \c sfont successfully removed, #FLUID_FAILED otherwise
4717  *
4718  * SoundFont is not freed and is left as the responsibility of the caller.
4719  *
4720  * @note The SoundFont should only be freed after there are no presets
4721  *   referencing it.  This can only be ensured by the SoundFont loader and
4722  *   therefore this function should not normally be used.
4723  */
4724 int
4725 fluid_synth_remove_sfont(fluid_synth_t *synth, fluid_sfont_t *sfont)
4726 {
4727     fluid_sfont_t *sfont_tmp;
4728     fluid_list_t *list;
4729     int ret = FLUID_FAILED;
4730
4731     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
4732     fluid_return_val_if_fail(sfont != NULL, FLUID_FAILED);
4733     fluid_synth_api_enter(synth);
4734
4735     /* remove the SoundFont from the list */
4736     for(list = synth->sfont; list; list = fluid_list_next(list))
4737     {
4738         sfont_tmp = fluid_list_get(list);
4739
4740         if(sfont_tmp == sfont)
4741         {
4742             synth->sfont = fluid_list_remove(synth->sfont, sfont_tmp);
4743             ret = FLUID_OK;
4744             break;
4745         }
4746     }
4747
4748     /* reset the presets for all channels */
4749     fluid_synth_program_reset(synth);
4750
4751     FLUID_API_RETURN(ret);
4752 }
4753
4754 /**
4755  * Count number of loaded SoundFont files.
4756  * @param synth FluidSynth instance
4757  * @return Count of loaded SoundFont files.
4758  */
4759 int
4760 fluid_synth_sfcount(fluid_synth_t *synth)
4761 {
4762     int count;
4763
4764     fluid_return_val_if_fail(synth != NULL, 0);
4765     fluid_synth_api_enter(synth);
4766     count = fluid_list_size(synth->sfont);
4767     FLUID_API_RETURN(count);
4768 }
4769
4770 /**
4771  * Get SoundFont by index.
4772  * @param synth FluidSynth instance
4773  * @param num SoundFont index on the stack (starting from 0 for top of stack).
4774  * @return SoundFont instance or NULL if invalid index
4775  *
4776  * @note Caller should be certain that SoundFont is not deleted (unloaded) for
4777  * the duration of use of the returned pointer.
4778  */
4779 fluid_sfont_t *
4780 fluid_synth_get_sfont(fluid_synth_t *synth, unsigned int num)
4781 {
4782     fluid_sfont_t *sfont = NULL;
4783     fluid_list_t *list;
4784
4785     fluid_return_val_if_fail(synth != NULL, NULL);
4786     fluid_synth_api_enter(synth);
4787     list = fluid_list_nth(synth->sfont, num);
4788
4789     if(list)
4790     {
4791         sfont = fluid_list_get(list);
4792     }
4793
4794     FLUID_API_RETURN(sfont);
4795 }
4796
4797 /**
4798  * Get SoundFont by ID.
4799  * @param synth FluidSynth instance
4800  * @param id SoundFont ID
4801  * @return SoundFont instance or NULL if invalid ID
4802  *
4803  * @note Caller should be certain that SoundFont is not deleted (unloaded) for
4804  * the duration of use of the returned pointer.
4805  */
4806 fluid_sfont_t *
4807 fluid_synth_get_sfont_by_id(fluid_synth_t *synth, int id)
4808 {
4809     fluid_sfont_t *sfont = NULL;
4810     fluid_list_t *list;
4811
4812     fluid_return_val_if_fail(synth != NULL, NULL);
4813     fluid_synth_api_enter(synth);
4814
4815     for(list = synth->sfont; list; list = fluid_list_next(list))
4816     {
4817         sfont = fluid_list_get(list);
4818
4819         if(fluid_sfont_get_id(sfont) == id)
4820         {
4821             break;
4822         }
4823     }
4824
4825     FLUID_API_RETURN(list ? sfont : NULL);
4826 }
4827
4828 /**
4829  * Get SoundFont by name.
4830  * @param synth FluidSynth instance
4831  * @param name Name of SoundFont
4832  * @return SoundFont instance or NULL if invalid name
4833  * @since 1.1.0
4834  *
4835  * @note Caller should be certain that SoundFont is not deleted (unloaded) for
4836  * the duration of use of the returned pointer.
4837  */
4838 fluid_sfont_t *
4839 fluid_synth_get_sfont_by_name(fluid_synth_t *synth, const char *name)
4840 {
4841     fluid_sfont_t *sfont = NULL;
4842     fluid_list_t *list;
4843
4844     fluid_return_val_if_fail(synth != NULL, NULL);
4845     fluid_return_val_if_fail(name != NULL, NULL);
4846     fluid_synth_api_enter(synth);
4847
4848     for(list = synth->sfont; list; list = fluid_list_next(list))
4849     {
4850         sfont = fluid_list_get(list);
4851
4852         if(FLUID_STRCMP(fluid_sfont_get_name(sfont), name) == 0)
4853         {
4854             break;
4855         }
4856     }
4857
4858     FLUID_API_RETURN(list ? sfont : NULL);
4859 }
4860
4861 /**
4862  * Get active preset on a MIDI channel.
4863  * @param synth FluidSynth instance
4864  * @param chan MIDI channel number (0 to MIDI channel count - 1)
4865  * @return Preset or NULL if no preset active on \c chan
4866  *
4867  * @note Should only be called from within synthesis thread, which includes
4868  * SoundFont loader preset noteon methods. Not thread safe otherwise.
4869  */
4870 fluid_preset_t *
4871 fluid_synth_get_channel_preset(fluid_synth_t *synth, int chan)
4872 {
4873     fluid_preset_t *result;
4874     fluid_channel_t *channel;
4875     FLUID_API_ENTRY_CHAN(NULL);
4876
4877     channel = synth->channel[chan];
4878     result = channel->preset;
4879     fluid_synth_api_exit(synth);
4880     return result;
4881 }
4882
4883 /**
4884  * Get list of currently playing voices.
4885  * @param synth FluidSynth instance
4886  * @param buf Array to store voices to (NULL terminated if not filled completely)
4887  * @param bufsize Count of indexes in buf
4888  * @param id Voice ID to search for or < 0 to return list of all playing voices
4889  *
4890  * @note Should only be called from within synthesis thread, which includes
4891  * SoundFont loader preset noteon methods.  Voices are only guaranteed to remain
4892  * unchanged until next synthesis process iteration.
4893  */
4894 void
4895 fluid_synth_get_voicelist(fluid_synth_t *synth, fluid_voice_t *buf[], int bufsize,
4896                           int id)
4897 {
4898     int count = 0;
4899     int i;
4900
4901     fluid_return_if_fail(synth != NULL);
4902     fluid_return_if_fail(buf != NULL);
4903     fluid_synth_api_enter(synth);
4904
4905     for(i = 0; i < synth->polyphony && count < bufsize; i++)
4906     {
4907         fluid_voice_t *voice = synth->voice[i];
4908
4909         if(fluid_voice_is_playing(voice) && (id < 0 || (int)voice->id == id))
4910         {
4911             buf[count++] = voice;
4912         }
4913     }
4914
4915     if(count < bufsize)
4916     {
4917         buf[count] = NULL;
4918     }
4919
4920     fluid_synth_api_exit(synth);
4921 }
4922
4923 /**
4924  * Enable or disable reverb effect.
4925  * @param synth FluidSynth instance
4926  * @param on TRUE to enable reverb, FALSE to disable
4927  */
4928 void
4929 fluid_synth_set_reverb_on(fluid_synth_t *synth, int on)
4930 {
4931     fluid_return_if_fail(synth != NULL);
4932
4933     fluid_synth_api_enter(synth);
4934
4935     synth->with_reverb = (on != 0);
4936     fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_reverb_enabled,
4937                              on != 0, 0.0f);
4938     fluid_synth_api_exit(synth);
4939 }
4940
4941 /**
4942  * Activate a reverb preset.
4943  * @param synth FluidSynth instance
4944  * @param num Reverb preset number
4945  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
4946  *
4947  * @note Currently private to libfluidsynth.
4948  */
4949 int
4950 fluid_synth_set_reverb_preset(fluid_synth_t *synth, unsigned int num)
4951 {
4952     fluid_return_val_if_fail(
4953         num < FLUID_N_ELEMENTS(revmodel_preset),
4954         FLUID_FAILED
4955     );
4956
4957     fluid_synth_set_reverb(synth, revmodel_preset[num].roomsize,
4958                            revmodel_preset[num].damp, revmodel_preset[num].width,
4959                            revmodel_preset[num].level);
4960     return FLUID_OK;
4961 }
4962
4963 /**
4964  * Set reverb parameters.
4965  * @param synth FluidSynth instance
4966  * @param roomsize Reverb room size value (0.0-1.0)
4967  * @param damping Reverb damping value (0.0-1.0)
4968  * @param width Reverb width value (0.0-100.0)
4969  * @param level Reverb level value (0.0-1.0)
4970  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
4971  *
4972  * @note Not realtime safe and therefore should not be called from synthesis
4973  * context at the risk of stalling audio output.
4974  */
4975 int
4976 fluid_synth_set_reverb(fluid_synth_t *synth, double roomsize, double damping,
4977                        double width, double level)
4978 {
4979     return fluid_synth_set_reverb_full(synth, FLUID_REVMODEL_SET_ALL,
4980                                        roomsize, damping, width, level);
4981 }
4982
4983 /**
4984  * Set reverb roomsize. See fluid_synth_set_reverb() for further info.
4985  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
4986  */
4987 int fluid_synth_set_reverb_roomsize(fluid_synth_t *synth, double roomsize)
4988 {
4989     return fluid_synth_set_reverb_full(synth, FLUID_REVMODEL_SET_ROOMSIZE, roomsize, 0, 0, 0);
4990 }
4991
4992 /**
4993  * Set reverb damping. See fluid_synth_set_reverb() for further info.
4994  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
4995  */
4996 int fluid_synth_set_reverb_damp(fluid_synth_t *synth, double damping)
4997 {
4998     return fluid_synth_set_reverb_full(synth, FLUID_REVMODEL_SET_DAMPING, 0, damping, 0, 0);
4999 }
5000
5001 /**
5002  * Set reverb width. See fluid_synth_set_reverb() for further info.
5003  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5004  */
5005 int fluid_synth_set_reverb_width(fluid_synth_t *synth, double width)
5006 {
5007     return fluid_synth_set_reverb_full(synth, FLUID_REVMODEL_SET_WIDTH, 0, 0, width, 0);
5008 }
5009
5010 /**
5011  * Set reverb level. See fluid_synth_set_reverb() for further info.
5012  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5013  */
5014 int fluid_synth_set_reverb_level(fluid_synth_t *synth, double level)
5015 {
5016     return fluid_synth_set_reverb_full(synth, FLUID_REVMODEL_SET_LEVEL, 0, 0, 0, level);
5017 }
5018
5019 /**
5020  * Set one or more reverb parameters.
5021  * @param synth FluidSynth instance
5022  * @param set Flags indicating which parameters should be set (#fluid_revmodel_set_t)
5023  * @param roomsize Reverb room size value (0.0-1.2)
5024  * @param damping Reverb damping value (0.0-1.0)
5025  * @param width Reverb width value (0.0-100.0)
5026  * @param level Reverb level value (0.0-1.0)
5027  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5028  *
5029  * @note Not realtime safe and therefore should not be called from synthesis
5030  * context at the risk of stalling audio output.
5031  */
5032 int
5033 fluid_synth_set_reverb_full(fluid_synth_t *synth, int set, double roomsize,
5034                             double damping, double width, double level)
5035 {
5036     int ret;
5037
5038     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
5039     /* if non of the flags is set, fail */
5040     fluid_return_val_if_fail(set & FLUID_REVMODEL_SET_ALL, FLUID_FAILED);
5041
5042     /* Synth shadow values are set here so that they will be returned if querried */
5043
5044     fluid_synth_api_enter(synth);
5045     ret = fluid_synth_set_reverb_full_LOCAL(synth, set, roomsize, damping, width, level);
5046     FLUID_API_RETURN(ret);
5047 }
5048
5049 static int
5050 fluid_synth_set_reverb_full_LOCAL(fluid_synth_t *synth, int set, double roomsize,
5051                                   double damping, double width, double level)
5052 {
5053     int ret;
5054     fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
5055
5056     if(set & FLUID_REVMODEL_SET_ROOMSIZE)
5057     {
5058         synth->reverb_roomsize = roomsize;
5059     }
5060
5061     if(set & FLUID_REVMODEL_SET_DAMPING)
5062     {
5063         synth->reverb_damping = damping;
5064     }
5065
5066     if(set & FLUID_REVMODEL_SET_WIDTH)
5067     {
5068         synth->reverb_width = width;
5069     }
5070
5071     if(set & FLUID_REVMODEL_SET_LEVEL)
5072     {
5073         synth->reverb_level = level;
5074     }
5075
5076     param[0].i = set;
5077     param[1].real = roomsize;
5078     param[2].real = damping;
5079     param[3].real = width;
5080     param[4].real = level;
5081     /* finally enqueue an rvoice event to the mixer to actual update reverb */
5082     ret = fluid_rvoice_eventhandler_push(synth->eventhandler,
5083                                          fluid_rvoice_mixer_set_reverb_params,
5084                                          synth->eventhandler->mixer,
5085                                          param);
5086     return ret;
5087 }
5088
5089 /**
5090  * Get reverb room size.
5091  * @param synth FluidSynth instance
5092  * @return Reverb room size (0.0-1.2)
5093  */
5094 double
5095 fluid_synth_get_reverb_roomsize(fluid_synth_t *synth)
5096 {
5097     double result;
5098     fluid_return_val_if_fail(synth != NULL, 0.0);
5099     fluid_synth_api_enter(synth);
5100     result = synth->reverb_roomsize;
5101     FLUID_API_RETURN(result);
5102 }
5103
5104 /**
5105  * Get reverb damping.
5106  * @param synth FluidSynth instance
5107  * @return Reverb damping value (0.0-1.0)
5108  */
5109 double
5110 fluid_synth_get_reverb_damp(fluid_synth_t *synth)
5111 {
5112     double result;
5113     fluid_return_val_if_fail(synth != NULL, 0.0);
5114     fluid_synth_api_enter(synth);
5115
5116     result = synth->reverb_damping;
5117     FLUID_API_RETURN(result);
5118 }
5119
5120 /**
5121  * Get reverb level.
5122  * @param synth FluidSynth instance
5123  * @return Reverb level value (0.0-1.0)
5124  */
5125 double
5126 fluid_synth_get_reverb_level(fluid_synth_t *synth)
5127 {
5128     double result;
5129     fluid_return_val_if_fail(synth != NULL, 0.0);
5130     fluid_synth_api_enter(synth);
5131
5132     result = synth->reverb_level;
5133     FLUID_API_RETURN(result);
5134 }
5135
5136 /**
5137  * Get reverb width.
5138  * @param synth FluidSynth instance
5139  * @return Reverb width value (0.0-100.0)
5140  */
5141 double
5142 fluid_synth_get_reverb_width(fluid_synth_t *synth)
5143 {
5144     double result;
5145     fluid_return_val_if_fail(synth != NULL, 0.0);
5146     fluid_synth_api_enter(synth);
5147
5148     result = synth->reverb_width;
5149     FLUID_API_RETURN(result);
5150 }
5151
5152 /**
5153  * Enable or disable chorus effect.
5154  * @param synth FluidSynth instance
5155  * @param on TRUE to enable chorus, FALSE to disable
5156  */
5157 void
5158 fluid_synth_set_chorus_on(fluid_synth_t *synth, int on)
5159 {
5160     fluid_return_if_fail(synth != NULL);
5161     fluid_synth_api_enter(synth);
5162
5163     synth->with_chorus = (on != 0);
5164     fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_chorus_enabled,
5165                              on != 0, 0.0f);
5166     fluid_synth_api_exit(synth);
5167 }
5168
5169 /**
5170  * Set chorus parameters. It should be turned on with fluid_synth_set_chorus_on().
5171  * Keep in mind, that the needed CPU time is proportional to 'nr'.
5172  * @param synth FluidSynth instance
5173  * @param nr Chorus voice count (0-99, CPU time consumption proportional to
5174  *   this value)
5175  * @param level Chorus level (0.0-10.0)
5176  * @param speed Chorus speed in Hz (0.29-5.0)
5177  * @param depth_ms Chorus depth (max value depends on synth sample rate,
5178  *   0.0-21.0 is safe for sample rate values up to 96KHz)
5179  * @param type Chorus waveform type (#fluid_chorus_mod)
5180  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5181  */
5182 int fluid_synth_set_chorus(fluid_synth_t *synth, int nr, double level,
5183                            double speed, double depth_ms, int type)
5184 {
5185     return fluid_synth_set_chorus_full(synth, FLUID_CHORUS_SET_ALL, nr, level, speed,
5186                                        depth_ms, type);
5187 }
5188
5189 /**
5190  * Set the chorus voice count. See fluid_synth_set_chorus() for further info.
5191  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5192  */
5193 int fluid_synth_set_chorus_nr(fluid_synth_t *synth, int nr)
5194 {
5195     return fluid_synth_set_chorus_full(synth, FLUID_CHORUS_SET_NR, nr, 0, 0, 0, 0);
5196 }
5197
5198 /**
5199  * Set the chorus level. See fluid_synth_set_chorus() for further info.
5200  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5201  */
5202 int fluid_synth_set_chorus_level(fluid_synth_t *synth, double level)
5203 {
5204     return fluid_synth_set_chorus_full(synth, FLUID_CHORUS_SET_LEVEL, 0, level, 0, 0, 0);
5205 }
5206
5207 /**
5208  * Set the chorus speed. See fluid_synth_set_chorus() for further info.
5209  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5210  */
5211 int fluid_synth_set_chorus_speed(fluid_synth_t *synth, double speed)
5212 {
5213     return fluid_synth_set_chorus_full(synth, FLUID_CHORUS_SET_SPEED, 0, 0, speed, 0, 0);
5214 }
5215
5216 /**
5217  * Set the chorus depth. See fluid_synth_set_chorus() for further info.
5218  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5219  */
5220 int fluid_synth_set_chorus_depth(fluid_synth_t *synth, double depth_ms)
5221 {
5222     return fluid_synth_set_chorus_full(synth, FLUID_CHORUS_SET_DEPTH, 0, 0, 0, depth_ms, 0);
5223 }
5224
5225 /**
5226  * Set the chorus type. See fluid_synth_set_chorus() for further info.
5227  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5228  */
5229 int fluid_synth_set_chorus_type(fluid_synth_t *synth, int type)
5230 {
5231     return fluid_synth_set_chorus_full(synth, FLUID_CHORUS_SET_TYPE, 0, 0, 0, 0, type);
5232 }
5233
5234 /**
5235  * Set one or more chorus parameters.
5236  * @param synth FluidSynth instance
5237  * @param set Flags indicating which chorus parameters to set (#fluid_chorus_set_t)
5238  * @param nr Chorus voice count (0-99, CPU time consumption proportional to
5239  *   this value)
5240  * @param level Chorus level (0.0-10.0)
5241  * @param speed Chorus speed in Hz (0.29-5.0)
5242  * @param depth_ms Chorus depth (max value depends on synth sample rate,
5243  *   0.0-21.0 is safe for sample rate values up to 96KHz)
5244  * @param type Chorus waveform type (#fluid_chorus_mod)
5245  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5246  */
5247 int
5248 fluid_synth_set_chorus_full(fluid_synth_t *synth, int set, int nr, double level,
5249                             double speed, double depth_ms, int type)
5250 {
5251     int ret;
5252
5253     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
5254     /* if non of the flags is set, fail */
5255     fluid_return_val_if_fail(set & FLUID_CHORUS_SET_ALL, FLUID_FAILED);
5256
5257     /* Synth shadow values are set here so that they will be returned if queried */
5258     fluid_synth_api_enter(synth);
5259
5260     ret = fluid_synth_set_chorus_full_LOCAL(synth, set, nr, level, speed, depth_ms, type);
5261
5262     FLUID_API_RETURN(ret);
5263 }
5264
5265 static int
5266 fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double level,
5267                                   double speed, double depth_ms, int type)
5268 {
5269     int ret;
5270     fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
5271
5272     if(set & FLUID_CHORUS_SET_NR)
5273     {
5274         synth->chorus_nr = nr;
5275     }
5276
5277     if(set & FLUID_CHORUS_SET_LEVEL)
5278     {
5279         synth->chorus_level = level;
5280     }
5281
5282     if(set & FLUID_CHORUS_SET_SPEED)
5283     {
5284         synth->chorus_speed = speed;
5285     }
5286
5287     if(set & FLUID_CHORUS_SET_DEPTH)
5288     {
5289         synth->chorus_depth = depth_ms;
5290     }
5291
5292     if(set & FLUID_CHORUS_SET_TYPE)
5293     {
5294         synth->chorus_type = type;
5295     }
5296
5297     param[0].i = set;
5298     param[1].i = nr;
5299     param[2].real = level;
5300     param[3].real = speed;
5301     param[4].real = depth_ms;
5302     param[5].i = type;
5303     ret = fluid_rvoice_eventhandler_push(synth->eventhandler,
5304                                          fluid_rvoice_mixer_set_chorus_params,
5305                                          synth->eventhandler->mixer,
5306                                          param);
5307
5308     return (ret);
5309 }
5310
5311 /**
5312  * Get chorus voice number (delay line count) value.
5313  * @param synth FluidSynth instance
5314  * @return Chorus voice count (0-99)
5315  */
5316 int
5317 fluid_synth_get_chorus_nr(fluid_synth_t *synth)
5318 {
5319     double result;
5320     fluid_return_val_if_fail(synth != NULL, 0.0);
5321     fluid_synth_api_enter(synth);
5322
5323     result = synth->chorus_nr;
5324     FLUID_API_RETURN(result);
5325 }
5326
5327 /**
5328  * Get chorus level.
5329  * @param synth FluidSynth instance
5330  * @return Chorus level value (0.0-10.0)
5331  */
5332 double
5333 fluid_synth_get_chorus_level(fluid_synth_t *synth)
5334 {
5335     double result;
5336     fluid_return_val_if_fail(synth != NULL, 0.0);
5337     fluid_synth_api_enter(synth);
5338
5339     result = synth->chorus_level;
5340     FLUID_API_RETURN(result);
5341 }
5342
5343 /**
5344  * Get chorus speed in Hz.
5345  * @param synth FluidSynth instance
5346  * @return Chorus speed in Hz (0.29-5.0)
5347  */
5348 double
5349 fluid_synth_get_chorus_speed(fluid_synth_t *synth)
5350 {
5351     double result;
5352     fluid_return_val_if_fail(synth != NULL, 0.0);
5353     fluid_synth_api_enter(synth);
5354
5355     result = synth->chorus_speed;
5356     FLUID_API_RETURN(result);
5357 }
5358
5359 /**
5360  * Get chorus depth.
5361  * @param synth FluidSynth instance
5362  * @return Chorus depth
5363  */
5364 double
5365 fluid_synth_get_chorus_depth(fluid_synth_t *synth)
5366 {
5367     double result;
5368     fluid_return_val_if_fail(synth != NULL, 0.0);
5369     fluid_synth_api_enter(synth);
5370
5371     result = synth->chorus_depth;
5372     FLUID_API_RETURN(result);
5373 }
5374
5375 /**
5376  * Get chorus waveform type.
5377  * @param synth FluidSynth instance
5378  * @return Chorus waveform type (#fluid_chorus_mod)
5379  */
5380 int
5381 fluid_synth_get_chorus_type(fluid_synth_t *synth)
5382 {
5383     double result;
5384     fluid_return_val_if_fail(synth != NULL, 0.0);
5385     fluid_synth_api_enter(synth);
5386
5387     result = synth->chorus_type;
5388     FLUID_API_RETURN(result);
5389 }
5390
5391 /*
5392  * If the same note is hit twice on the same channel, then the older
5393  * voice process is advanced to the release stage.  Using a mechanical
5394  * MIDI controller, the only way this can happen is when the sustain
5395  * pedal is held.  In this case the behaviour implemented here is
5396  * natural for many instruments.  Note: One noteon event can trigger
5397  * several voice processes, for example a stereo sample.  Don't
5398  * release those...
5399  */
5400 void
5401 fluid_synth_release_voice_on_same_note_LOCAL(fluid_synth_t *synth, int chan,
5402         int key)
5403 {
5404     int i;
5405     fluid_voice_t *voice;
5406
5407     /* storeid is a parameter for fluid_voice_init() */
5408     synth->storeid = synth->noteid++;
5409
5410     /* for "monophonic playing" key is the previous sustained note
5411       if it exists (0 to 127) or INVALID_NOTE otherwise */
5412     if(key == INVALID_NOTE)
5413     {
5414         return;
5415     }
5416
5417     for(i = 0; i < synth->polyphony; i++)
5418     {
5419         voice = synth->voice[i];
5420
5421         if(fluid_voice_is_playing(voice)
5422                 && (fluid_voice_get_channel(voice) == chan)
5423                 && (fluid_voice_get_key(voice) == key)
5424                 && (fluid_voice_get_id(voice) != synth->noteid))
5425         {
5426             /* Id of voices that was sustained by sostenuto */
5427             if(fluid_voice_is_sostenuto(voice))
5428             {
5429                 synth->storeid = fluid_voice_get_id(voice);
5430             }
5431
5432             /* Force the voice into release stage (pedaling is ignored) */
5433             fluid_voice_release(voice);
5434         }
5435     }
5436 }
5437
5438 /**
5439  * Set synthesis interpolation method on one or all MIDI channels.
5440  * @param synth FluidSynth instance
5441  * @param chan MIDI channel to set interpolation method on or -1 for all channels
5442  * @param interp_method Interpolation method (#fluid_interp)
5443  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5444  */
5445 int
5446 fluid_synth_set_interp_method(fluid_synth_t *synth, int chan, int interp_method)
5447 {
5448     int i;
5449
5450     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
5451     fluid_synth_api_enter(synth);
5452
5453     if(chan < -1 || chan >= synth->midi_channels)
5454     {
5455         FLUID_API_RETURN(FLUID_FAILED);
5456     }
5457
5458     if(synth->channel[0] == NULL)
5459     {
5460         FLUID_LOG(FLUID_ERR, "Channels don't exist (yet)!");
5461         FLUID_API_RETURN(FLUID_FAILED);
5462     }
5463
5464     for(i = 0; i < synth->midi_channels; i++)
5465     {
5466         if(chan < 0 || fluid_channel_get_num(synth->channel[i]) == chan)
5467         {
5468             fluid_channel_set_interp_method(synth->channel[i], interp_method);
5469         }
5470     }
5471
5472     FLUID_API_RETURN(FLUID_OK);
5473 };
5474
5475 /**
5476  * Get the total count of MIDI channels.
5477  * @param synth FluidSynth instance
5478  * @return Count of MIDI channels
5479  */
5480 int
5481 fluid_synth_count_midi_channels(fluid_synth_t *synth)
5482 {
5483     int result;
5484     fluid_return_val_if_fail(synth != NULL, 0);
5485     fluid_synth_api_enter(synth);
5486
5487     result = synth->midi_channels;
5488     FLUID_API_RETURN(result);
5489 }
5490
5491 /**
5492  * Get the total count of audio channels.
5493  * @param synth FluidSynth instance
5494  * @return Count of audio channel stereo pairs (1 = 2 channels, 2 = 4, etc)
5495  */
5496 int
5497 fluid_synth_count_audio_channels(fluid_synth_t *synth)
5498 {
5499     int result;
5500     fluid_return_val_if_fail(synth != NULL, 0);
5501     fluid_synth_api_enter(synth);
5502
5503     result = synth->audio_channels;
5504     FLUID_API_RETURN(result);
5505 }
5506
5507 /**
5508  * Get the total number of allocated audio channels.  Usually identical to the
5509  * number of audio channels.  Can be employed by LADSPA effects subsystem.
5510  *
5511  * @param synth FluidSynth instance
5512  * @return Count of audio group stereo pairs (1 = 2 channels, 2 = 4, etc)
5513  */
5514 int
5515 fluid_synth_count_audio_groups(fluid_synth_t *synth)
5516 {
5517     int result;
5518     fluid_return_val_if_fail(synth != NULL, 0);
5519     fluid_synth_api_enter(synth);
5520
5521     result = synth->audio_groups;
5522     FLUID_API_RETURN(result);
5523 }
5524
5525 /**
5526  * Get the total number of allocated effects channels.
5527  * @param synth FluidSynth instance
5528  * @return Count of allocated effects channels
5529  */
5530 int
5531 fluid_synth_count_effects_channels(fluid_synth_t *synth)
5532 {
5533     int result;
5534     fluid_return_val_if_fail(synth != NULL, 0);
5535     fluid_synth_api_enter(synth);
5536
5537     result = synth->effects_channels;
5538     FLUID_API_RETURN(result);
5539 }
5540
5541 /**
5542  * Get the total number of allocated effects units.
5543  * @param synth FluidSynth instance
5544  * @return Count of allocated effects units
5545  */
5546 int
5547 fluid_synth_count_effects_groups(fluid_synth_t *synth)
5548 {
5549     int result;
5550     fluid_return_val_if_fail(synth != NULL, 0);
5551     fluid_synth_api_enter(synth);
5552
5553     result = synth->effects_groups;
5554     FLUID_API_RETURN(result);
5555 }
5556
5557 /**
5558  * Get the synth CPU load value.
5559  * @param synth FluidSynth instance
5560  * @return Estimated CPU load value in percent (0-100)
5561  */
5562 double
5563 fluid_synth_get_cpu_load(fluid_synth_t *synth)
5564 {
5565     fluid_return_val_if_fail(synth != NULL, 0);
5566     return fluid_atomic_float_get(&synth->cpu_load);
5567 }
5568
5569 /* Get tuning for a given bank:program */
5570 static fluid_tuning_t *
5571 fluid_synth_get_tuning(fluid_synth_t *synth, int bank, int prog)
5572 {
5573
5574     if((synth->tuning == NULL) ||
5575             (synth->tuning[bank] == NULL) ||
5576             (synth->tuning[bank][prog] == NULL))
5577     {
5578         return NULL;
5579     }
5580
5581     return synth->tuning[bank][prog];
5582 }
5583
5584 /* Replace tuning on a given bank:program (need not already exist).
5585  * Synth mutex should already be locked by caller. */
5586 static int
5587 fluid_synth_replace_tuning_LOCK(fluid_synth_t *synth, fluid_tuning_t *tuning,
5588                                 int bank, int prog, int apply)
5589 {
5590     fluid_tuning_t *old_tuning;
5591
5592     if(synth->tuning == NULL)
5593     {
5594         synth->tuning = FLUID_ARRAY(fluid_tuning_t **, 128);
5595
5596         if(synth->tuning == NULL)
5597         {
5598             FLUID_LOG(FLUID_PANIC, "Out of memory");
5599             return FLUID_FAILED;
5600         }
5601
5602         FLUID_MEMSET(synth->tuning, 0, 128 * sizeof(fluid_tuning_t **));
5603     }
5604
5605     if(synth->tuning[bank] == NULL)
5606     {
5607         synth->tuning[bank] = FLUID_ARRAY(fluid_tuning_t *, 128);
5608
5609         if(synth->tuning[bank] == NULL)
5610         {
5611             FLUID_LOG(FLUID_PANIC, "Out of memory");
5612             return FLUID_FAILED;
5613         }
5614
5615         FLUID_MEMSET(synth->tuning[bank], 0, 128 * sizeof(fluid_tuning_t *));
5616     }
5617
5618     old_tuning = synth->tuning[bank][prog];
5619     synth->tuning[bank][prog] = tuning;
5620
5621     if(old_tuning)
5622     {
5623         if(!fluid_tuning_unref(old_tuning, 1))       /* -- unref old tuning */
5624         {
5625             /* Replace old tuning if present */
5626             fluid_synth_replace_tuning_LOCAL(synth, old_tuning, tuning, apply, FALSE);
5627         }
5628     }
5629
5630     return FLUID_OK;
5631 }
5632
5633 /* Replace a tuning with a new one in all MIDI channels.  new_tuning can be
5634  * NULL, in which case channels are reset to default equal tempered scale. */
5635 static void
5636 fluid_synth_replace_tuning_LOCAL(fluid_synth_t *synth, fluid_tuning_t *old_tuning,
5637                                  fluid_tuning_t *new_tuning, int apply, int unref_new)
5638 {
5639     fluid_channel_t *channel;
5640     int old_tuning_unref = 0;
5641     int i;
5642
5643     for(i = 0; i < synth->midi_channels; i++)
5644     {
5645         channel = synth->channel[i];
5646
5647         if(fluid_channel_get_tuning(channel) == old_tuning)
5648         {
5649             old_tuning_unref++;
5650
5651             if(new_tuning)
5652             {
5653                 fluid_tuning_ref(new_tuning);    /* ++ ref new tuning for channel */
5654             }
5655
5656             fluid_channel_set_tuning(channel, new_tuning);
5657
5658             if(apply)
5659             {
5660                 fluid_synth_update_voice_tuning_LOCAL(synth, channel);
5661             }
5662         }
5663     }
5664
5665     /* Send unref old tuning event if any unrefs */
5666     if(old_tuning && old_tuning_unref)
5667     {
5668         fluid_tuning_unref(old_tuning, old_tuning_unref);
5669     }
5670
5671     if(!unref_new || !new_tuning)
5672     {
5673         return;
5674     }
5675
5676     fluid_tuning_unref(new_tuning, 1);
5677 }
5678
5679 /* Update voice tunings in realtime */
5680 static void
5681 fluid_synth_update_voice_tuning_LOCAL(fluid_synth_t *synth, fluid_channel_t *channel)
5682 {
5683     fluid_voice_t *voice;
5684     int i;
5685
5686     for(i = 0; i < synth->polyphony; i++)
5687     {
5688         voice = synth->voice[i];
5689
5690         if(fluid_voice_is_on(voice) && (voice->channel == channel))
5691         {
5692             fluid_voice_calculate_gen_pitch(voice);
5693             fluid_voice_update_param(voice, GEN_PITCH);
5694         }
5695     }
5696 }
5697
5698 /**
5699  * Set the tuning of the entire MIDI note scale.
5700  * @param synth FluidSynth instance
5701  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
5702  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
5703  * @param name Label name for this tuning
5704  * @param pitch Array of pitch values (length of 128, each value is number of
5705  *   cents, for example normally note 0 is 0.0, 1 is 100.0, 60 is 6000.0, etc).
5706  *   Pass NULL to create a equal tempered (normal) scale.
5707  * @param apply TRUE to apply new tuning in realtime to existing notes which
5708  *   are using the replaced tuning (if any), FALSE otherwise
5709  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5710  * @since 1.1.0
5711  */
5712 int
5713 fluid_synth_activate_key_tuning(fluid_synth_t *synth, int bank, int prog,
5714                                 const char *name, const double *pitch, int apply)
5715 {
5716     fluid_tuning_t *tuning;
5717     int retval = FLUID_OK;
5718
5719     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
5720     fluid_return_val_if_fail(bank >= 0 && bank < 128, FLUID_FAILED);
5721     fluid_return_val_if_fail(prog >= 0 && prog < 128, FLUID_FAILED);
5722     fluid_return_val_if_fail(name != NULL, FLUID_FAILED);
5723
5724     fluid_synth_api_enter(synth);
5725
5726     tuning = new_fluid_tuning(name, bank, prog);
5727
5728     if(tuning)
5729     {
5730         if(pitch)
5731         {
5732             fluid_tuning_set_all(tuning, pitch);
5733         }
5734
5735         retval = fluid_synth_replace_tuning_LOCK(synth, tuning, bank, prog, apply);
5736
5737         if(retval == FLUID_FAILED)
5738         {
5739             fluid_tuning_unref(tuning, 1);
5740         }
5741     }
5742     else
5743     {
5744         retval = FLUID_FAILED;
5745     }
5746
5747     FLUID_API_RETURN(retval);
5748 }
5749
5750 /**
5751  * Activate an octave tuning on every octave in the MIDI note scale.
5752  * @param synth FluidSynth instance
5753  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
5754  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
5755  * @param name Label name for this tuning
5756  * @param pitch Array of pitch values (length of 12 for each note of an octave
5757  *   starting at note C, values are number of offset cents to add to the normal
5758  *   tuning amount)
5759  * @param apply TRUE to apply new tuning in realtime to existing notes which
5760  *   are using the replaced tuning (if any), FALSE otherwise
5761  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5762  * @since 1.1.0
5763  */
5764 int
5765 fluid_synth_activate_octave_tuning(fluid_synth_t *synth, int bank, int prog,
5766                                    const char *name, const double *pitch, int apply)
5767 {
5768     fluid_tuning_t *tuning;
5769     int retval = FLUID_OK;
5770
5771     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
5772     fluid_return_val_if_fail(bank >= 0 && bank < 128, FLUID_FAILED);
5773     fluid_return_val_if_fail(prog >= 0 && prog < 128, FLUID_FAILED);
5774     fluid_return_val_if_fail(name != NULL, FLUID_FAILED);
5775     fluid_return_val_if_fail(pitch != NULL, FLUID_FAILED);
5776
5777     fluid_synth_api_enter(synth);
5778     tuning = new_fluid_tuning(name, bank, prog);
5779
5780     if(tuning)
5781     {
5782         fluid_tuning_set_octave(tuning, pitch);
5783         retval = fluid_synth_replace_tuning_LOCK(synth, tuning, bank, prog, apply);
5784
5785         if(retval == FLUID_FAILED)
5786         {
5787             fluid_tuning_unref(tuning, 1);
5788         }
5789     }
5790     else
5791     {
5792         retval = FLUID_FAILED;
5793     }
5794
5795     FLUID_API_RETURN(retval);
5796 }
5797
5798 /**
5799  * Set tuning values for one or more MIDI notes for an existing tuning.
5800  * @param synth FluidSynth instance
5801  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
5802  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
5803  * @param len Number of MIDI notes to assign
5804  * @param key Array of MIDI key numbers (length of 'len', values 0-127)
5805  * @param pitch Array of pitch values (length of 'len', values are number of
5806  *   cents from MIDI note 0)
5807  * @param apply TRUE to apply tuning change in realtime to existing notes using
5808  *   the specified tuning, FALSE otherwise
5809  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5810  *
5811  * @note Prior to version 1.1.0 it was an error to specify a tuning that didn't
5812  * already exist. Starting with 1.1.0, the default equal tempered scale will be
5813  * used as a basis, if no tuning exists for the given bank and prog.
5814  */
5815 int
5816 fluid_synth_tune_notes(fluid_synth_t *synth, int bank, int prog,
5817                        int len, const int *key, const double *pitch, int apply)
5818 {
5819     fluid_tuning_t *old_tuning, *new_tuning;
5820     int retval = FLUID_OK;
5821     int i;
5822
5823     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
5824     fluid_return_val_if_fail(bank >= 0 && bank < 128, FLUID_FAILED);
5825     fluid_return_val_if_fail(prog >= 0 && prog < 128, FLUID_FAILED);
5826     fluid_return_val_if_fail(len > 0, FLUID_FAILED);
5827     fluid_return_val_if_fail(key != NULL, FLUID_FAILED);
5828     fluid_return_val_if_fail(pitch != NULL, FLUID_FAILED);
5829
5830     fluid_synth_api_enter(synth);
5831
5832     old_tuning = fluid_synth_get_tuning(synth, bank, prog);
5833
5834     if(old_tuning)
5835     {
5836         new_tuning = fluid_tuning_duplicate(old_tuning);
5837     }
5838     else
5839     {
5840         new_tuning = new_fluid_tuning("Unnamed", bank, prog);
5841     }
5842
5843     if(new_tuning)
5844     {
5845         for(i = 0; i < len; i++)
5846         {
5847             fluid_tuning_set_pitch(new_tuning, key[i], pitch[i]);
5848         }
5849
5850         retval = fluid_synth_replace_tuning_LOCK(synth, new_tuning, bank, prog, apply);
5851
5852         if(retval == FLUID_FAILED)
5853         {
5854             fluid_tuning_unref(new_tuning, 1);
5855         }
5856     }
5857     else
5858     {
5859         retval = FLUID_FAILED;
5860     }
5861
5862     FLUID_API_RETURN(retval);
5863 }
5864
5865 /**
5866  * Activate a tuning scale on a MIDI channel.
5867  * @param synth FluidSynth instance
5868  * @param chan MIDI channel number (0 to MIDI channel count - 1)
5869  * @param bank Tuning bank number (0-127), not related to MIDI instrument bank
5870  * @param prog Tuning preset number (0-127), not related to MIDI instrument program
5871  * @param apply TRUE to apply tuning change to active notes, FALSE otherwise
5872  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5873  * @since 1.1.0
5874  *
5875  * @note A default equal tempered scale will be created, if no tuning exists
5876  * on the given bank and prog.
5877  */
5878 int
5879 fluid_synth_activate_tuning(fluid_synth_t *synth, int chan, int bank, int prog,
5880                             int apply)
5881 {
5882     fluid_tuning_t *tuning;
5883     int retval = FLUID_OK;
5884
5885     //fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
5886     //fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
5887     fluid_return_val_if_fail(bank >= 0 && bank < 128, FLUID_FAILED);
5888     fluid_return_val_if_fail(prog >= 0 && prog < 128, FLUID_FAILED);
5889
5890     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
5891
5892     tuning = fluid_synth_get_tuning(synth, bank, prog);
5893
5894     /* If no tuning exists, create a new default tuning.  We do this, so that
5895      * it can be replaced later, if any changes are made. */
5896     if(!tuning)
5897     {
5898         tuning = new_fluid_tuning("Unnamed", bank, prog);
5899
5900         if(tuning)
5901         {
5902             fluid_synth_replace_tuning_LOCK(synth, tuning, bank, prog, FALSE);
5903         }
5904     }
5905
5906     if(tuning)
5907     {
5908         fluid_tuning_ref(tuning);    /* ++ ref for outside of lock */
5909     }
5910
5911     if(!tuning)
5912     {
5913         FLUID_API_RETURN(FLUID_FAILED);
5914     }
5915
5916     fluid_tuning_ref(tuning);     /* ++ ref new tuning for following function */
5917     retval = fluid_synth_set_tuning_LOCAL(synth, chan, tuning, apply);
5918
5919     fluid_tuning_unref(tuning, 1);    /* -- unref for outside of lock */
5920
5921     FLUID_API_RETURN(retval);
5922 }
5923
5924 /* Local synthesis thread set tuning function (takes over tuning reference) */
5925 static int
5926 fluid_synth_set_tuning_LOCAL(fluid_synth_t *synth, int chan,
5927                              fluid_tuning_t *tuning, int apply)
5928 {
5929     fluid_tuning_t *old_tuning;
5930     fluid_channel_t *channel;
5931
5932     channel = synth->channel[chan];
5933
5934     old_tuning = fluid_channel_get_tuning(channel);
5935     fluid_channel_set_tuning(channel, tuning);    /* !! Takes over callers reference */
5936
5937     if(apply)
5938     {
5939         fluid_synth_update_voice_tuning_LOCAL(synth, channel);
5940     }
5941
5942     /* Send unref old tuning event */
5943     if(old_tuning)
5944     {
5945         fluid_tuning_unref(old_tuning, 1);
5946     }
5947
5948
5949     return FLUID_OK;
5950 }
5951
5952 /**
5953  * Clear tuning scale on a MIDI channel (use default equal tempered scale).
5954  * @param synth FluidSynth instance
5955  * @param chan MIDI channel number (0 to MIDI channel count - 1)
5956  * @param apply TRUE to apply tuning change to active notes, FALSE otherwise
5957  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
5958  * @since 1.1.0
5959  */
5960 int
5961 fluid_synth_deactivate_tuning(fluid_synth_t *synth, int chan, int apply)
5962 {
5963     int retval = FLUID_OK;
5964
5965     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
5966
5967     retval = fluid_synth_set_tuning_LOCAL(synth, chan, NULL, apply);
5968
5969     FLUID_API_RETURN(retval);
5970 }
5971
5972 /**
5973  * Start tuning iteration.
5974  * @param synth FluidSynth instance
5975  */
5976 void
5977 fluid_synth_tuning_iteration_start(fluid_synth_t *synth)
5978 {
5979     fluid_return_if_fail(synth != NULL);
5980     fluid_synth_api_enter(synth);
5981     fluid_private_set(synth->tuning_iter, FLUID_INT_TO_POINTER(0));
5982     fluid_synth_api_exit(synth);
5983 }
5984
5985 /**
5986  * Advance to next tuning.
5987  * @param synth FluidSynth instance
5988  * @param bank Location to store MIDI bank number of next tuning scale
5989  * @param prog Location to store MIDI program number of next tuning scale
5990  * @return 1 if tuning iteration advanced, 0 if no more tunings
5991  */
5992 int
5993 fluid_synth_tuning_iteration_next(fluid_synth_t *synth, int *bank, int *prog)
5994 {
5995     void *pval;
5996     int b = 0, p = 0;
5997
5998     fluid_return_val_if_fail(synth != NULL, 0);
5999     fluid_return_val_if_fail(bank != NULL, 0);
6000     fluid_return_val_if_fail(prog != NULL, 0);
6001     fluid_synth_api_enter(synth);
6002
6003     /* Current tuning iteration stored as: bank << 8 | program */
6004     pval = fluid_private_get(synth->tuning_iter);
6005     p = FLUID_POINTER_TO_INT(pval);
6006     b = (p >> 8) & 0xFF;
6007     p &= 0xFF;
6008
6009     if(!synth->tuning)
6010     {
6011         FLUID_API_RETURN(0);
6012     }
6013
6014     for(; b < 128; b++, p = 0)
6015     {
6016         if(synth->tuning[b] == NULL)
6017         {
6018             continue;
6019         }
6020
6021         for(; p < 128; p++)
6022         {
6023             if(synth->tuning[b][p] == NULL)
6024             {
6025                 continue;
6026             }
6027
6028             *bank = b;
6029             *prog = p;
6030
6031             if(p < 127)
6032             {
6033                 fluid_private_set(synth->tuning_iter,
6034                                   FLUID_INT_TO_POINTER(b << 8 | (p + 1)));
6035             }
6036             else
6037             {
6038                 fluid_private_set(synth->tuning_iter, FLUID_INT_TO_POINTER((b + 1) << 8));
6039             }
6040
6041             FLUID_API_RETURN(1);
6042         }
6043     }
6044
6045     FLUID_API_RETURN(0);
6046 }
6047
6048 /**
6049  * Get the entire note tuning for a given MIDI bank and program.
6050  * @param synth FluidSynth instance
6051  * @param bank MIDI bank number of tuning
6052  * @param prog MIDI program number of tuning
6053  * @param name Location to store tuning name or NULL to ignore
6054  * @param len Maximum number of chars to store to 'name' (including NULL byte)
6055  * @param pitch Array to store tuning scale to or NULL to ignore (len of 128)
6056  * @return #FLUID_OK if matching tuning was found, #FLUID_FAILED otherwise
6057  */
6058 int
6059 fluid_synth_tuning_dump(fluid_synth_t *synth, int bank, int prog,
6060                         char *name, int len, double *pitch)
6061 {
6062     fluid_tuning_t *tuning;
6063
6064     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
6065     fluid_synth_api_enter(synth);
6066
6067     tuning = fluid_synth_get_tuning(synth, bank, prog);
6068
6069     if(tuning)
6070     {
6071         if(name)
6072         {
6073             FLUID_SNPRINTF(name, len - 1, "%s", fluid_tuning_get_name(tuning));
6074             name[len - 1] = 0;  /* make sure the string is null terminated */
6075         }
6076
6077         if(pitch)
6078         {
6079             FLUID_MEMCPY(pitch, fluid_tuning_get_all(tuning), 128 * sizeof(double));
6080         }
6081     }
6082
6083     FLUID_API_RETURN(tuning ? FLUID_OK : FLUID_FAILED);
6084 }
6085
6086 /**
6087  * Get settings assigned to a synth.
6088  * @param synth FluidSynth instance
6089  * @return FluidSynth settings which are assigned to the synth
6090  */
6091 fluid_settings_t *
6092 fluid_synth_get_settings(fluid_synth_t *synth)
6093 {
6094     fluid_return_val_if_fail(synth != NULL, NULL);
6095
6096     return synth->settings;
6097 }
6098
6099 /**
6100  * Set a SoundFont generator (effect) value on a MIDI channel in real-time.
6101  * @param synth FluidSynth instance
6102  * @param chan MIDI channel number (0 to MIDI channel count - 1)
6103  * @param param SoundFont generator ID (#fluid_gen_type)
6104  * @param value Offset or absolute generator value to assign to the MIDI channel
6105  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
6106  *
6107  * This function allows for setting all effect parameters in real time on a
6108  * MIDI channel. Setting absolute to non-zero will cause the value to override
6109  * any generator values set in the instruments played on the MIDI channel.
6110  * See SoundFont 2.01 spec, paragraph 8.1.3, page 48 for details on SoundFont
6111  * generator parameters and valid ranges.
6112  */
6113 int fluid_synth_set_gen(fluid_synth_t *synth, int chan, int param, float value)
6114 {
6115     return fluid_synth_set_gen2(synth, chan, param, value, FALSE, FALSE);
6116 }
6117
6118 /**
6119  * Set a SoundFont generator (effect) value on a MIDI channel in real-time.
6120  * @param synth FluidSynth instance
6121  * @param chan MIDI channel number (0 to MIDI channel count - 1)
6122  * @param param SoundFont generator ID (#fluid_gen_type)
6123  * @param value Offset or absolute generator value to assign to the MIDI channel
6124  * @param absolute FALSE to assign a relative value, TRUE to assign an absolute value
6125  * @param normalized FALSE if value is specified in the native units of the generator,
6126  *   TRUE to take the value as a 0.0-1.0 range and apply it to the valid
6127  *   generator effect range (scaled and shifted as necessary).
6128  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
6129  *
6130  * This function allows for setting all effect parameters in real time on a
6131  * MIDI channel. Setting absolute to non-zero will cause the value to override
6132  * any generator values set in the instruments played on the MIDI channel.
6133  * See SoundFont 2.01 spec, paragraph 8.1.3, page 48 for details on SoundFont
6134  * generator parameters and valid ranges.
6135  */
6136 int
6137 fluid_synth_set_gen2(fluid_synth_t *synth, int chan, int param,
6138                      float value, int absolute, int normalized)
6139 {
6140     float v;
6141     fluid_return_val_if_fail(param >= 0 && param < GEN_LAST, FLUID_FAILED);
6142     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6143
6144     v = normalized ? fluid_gen_scale(param, value) : value;
6145
6146     fluid_synth_set_gen_LOCAL(synth, chan, param, v, absolute);
6147
6148     FLUID_API_RETURN(FLUID_OK);
6149 }
6150
6151 /* Synthesis thread local set gen function */
6152 static void
6153 fluid_synth_set_gen_LOCAL(fluid_synth_t *synth, int chan, int param, float value,
6154                           int absolute)
6155 {
6156     fluid_voice_t *voice;
6157     int i;
6158
6159     fluid_channel_set_gen(synth->channel[chan], param, value, absolute);
6160
6161     for(i = 0; i < synth->polyphony; i++)
6162     {
6163         voice = synth->voice[i];
6164
6165         if(fluid_voice_get_channel(voice) == chan)
6166         {
6167             fluid_voice_set_param(voice, param, value, absolute);
6168         }
6169     }
6170 }
6171
6172 /**
6173  * Get generator value assigned to a MIDI channel.
6174  * @param synth FluidSynth instance
6175  * @param chan MIDI channel number (0 to MIDI channel count - 1)
6176  * @param param SoundFont generator ID (#fluid_gen_type)
6177  * @return Current generator value assigned to MIDI channel
6178  */
6179 float
6180 fluid_synth_get_gen(fluid_synth_t *synth, int chan, int param)
6181 {
6182     float result;
6183     fluid_return_val_if_fail(param >= 0 && param < GEN_LAST, FLUID_FAILED);
6184     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6185
6186     result = fluid_channel_get_gen(synth->channel[chan], param);
6187     FLUID_API_RETURN(result);
6188 }
6189
6190 /**
6191  * Handle MIDI event from MIDI router, used as a callback function.
6192  * @param data FluidSynth instance
6193  * @param event MIDI event to handle
6194  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
6195  */
6196 int
6197 fluid_synth_handle_midi_event(void *data, fluid_midi_event_t *event)
6198 {
6199     fluid_synth_t *synth = (fluid_synth_t *) data;
6200     int type = fluid_midi_event_get_type(event);
6201     int chan = fluid_midi_event_get_channel(event);
6202
6203     switch(type)
6204     {
6205     case NOTE_ON:
6206         return fluid_synth_noteon(synth, chan,
6207                                   fluid_midi_event_get_key(event),
6208                                   fluid_midi_event_get_velocity(event));
6209
6210     case NOTE_OFF:
6211         return fluid_synth_noteoff(synth, chan, fluid_midi_event_get_key(event));
6212
6213     case CONTROL_CHANGE:
6214         return fluid_synth_cc(synth, chan,
6215                               fluid_midi_event_get_control(event),
6216                               fluid_midi_event_get_value(event));
6217
6218     case PROGRAM_CHANGE:
6219         return fluid_synth_program_change(synth, chan, fluid_midi_event_get_program(event));
6220
6221     case CHANNEL_PRESSURE:
6222         return fluid_synth_channel_pressure(synth, chan, fluid_midi_event_get_program(event));
6223
6224     case KEY_PRESSURE:
6225         return fluid_synth_key_pressure(synth, chan,
6226                                         fluid_midi_event_get_key(event),
6227                                         fluid_midi_event_get_value(event));
6228
6229     case PITCH_BEND:
6230         return fluid_synth_pitch_bend(synth, chan, fluid_midi_event_get_pitch(event));
6231
6232     case MIDI_SYSTEM_RESET:
6233         return fluid_synth_system_reset(synth);
6234
6235     case MIDI_SYSEX:
6236         return fluid_synth_sysex(synth, event->paramptr, event->param1, NULL, NULL, NULL, FALSE);
6237
6238     case MIDI_TEXT:
6239     case MIDI_LYRIC:
6240     case MIDI_SET_TEMPO:
6241         return FLUID_OK;
6242     }
6243
6244     return FLUID_FAILED;
6245 }
6246
6247 /**
6248  * Create and start voices using a preset and a MIDI note on event.
6249  * @param synth FluidSynth instance
6250  * @param id Voice group ID to use (can be used with fluid_synth_stop()).
6251  * @param preset Preset to synthesize
6252  * @param audio_chan Unused currently, set to 0
6253  * @param chan MIDI channel number (0 to MIDI channel count - 1)
6254  * @param key MIDI note number (0-127)
6255  * @param vel MIDI velocity number (1-127)
6256  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
6257  *
6258  * @note Should only be called from within synthesis thread, which includes
6259  * SoundFont loader preset noteon method.
6260  */
6261 int
6262 fluid_synth_start(fluid_synth_t *synth, unsigned int id, fluid_preset_t *preset,
6263                   int audio_chan, int chan, int key, int vel)
6264 {
6265     int result;
6266     fluid_return_val_if_fail(preset != NULL, FLUID_FAILED);
6267     fluid_return_val_if_fail(key >= 0 && key <= 127, FLUID_FAILED);
6268     fluid_return_val_if_fail(vel >= 1 && vel <= 127, FLUID_FAILED);
6269     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6270     synth->storeid = id;
6271     result = fluid_preset_noteon(preset, synth, chan, key, vel);
6272     FLUID_API_RETURN(result);
6273 }
6274
6275 /**
6276  * Stop notes for a given note event voice ID.
6277  * @param synth FluidSynth instance
6278  * @param id Voice note event ID
6279  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
6280  *
6281  * @note In FluidSynth versions prior to 1.1.0 #FLUID_FAILED would be returned
6282  * if no matching voice note event ID was found.  Versions after 1.1.0 only
6283  * return #FLUID_FAILED if an error occurs.
6284  */
6285 int
6286 fluid_synth_stop(fluid_synth_t *synth, unsigned int id)
6287 {
6288     int result;
6289     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
6290     fluid_synth_api_enter(synth);
6291     fluid_synth_stop_LOCAL(synth, id);
6292     result = FLUID_OK;
6293     FLUID_API_RETURN(result);
6294 }
6295
6296 /* Local synthesis thread variant of fluid_synth_stop */
6297 static void
6298 fluid_synth_stop_LOCAL(fluid_synth_t *synth, unsigned int id)
6299 {
6300     fluid_voice_t *voice;
6301     int i;
6302
6303     for(i = 0; i < synth->polyphony; i++)
6304     {
6305         voice = synth->voice[i];
6306
6307         if(fluid_voice_is_on(voice) && (fluid_voice_get_id(voice) == id))
6308         {
6309             fluid_voice_noteoff(voice);
6310         }
6311     }
6312 }
6313
6314 /**
6315  * Offset the bank numbers of a loaded SoundFont, i.e.\ subtract
6316  * \c offset from any bank number when assigning instruments.
6317  *
6318  * @param synth FluidSynth instance
6319  * @param sfont_id ID of a loaded SoundFont
6320  * @param offset Bank offset value to apply to all instruments
6321  * @return #FLUID_OK if the offset was set successfully, #FLUID_FAILED otherwise
6322  */
6323 int
6324 fluid_synth_set_bank_offset(fluid_synth_t *synth, int sfont_id, int offset)
6325 {
6326     fluid_sfont_t *sfont;
6327     fluid_list_t *list;
6328
6329     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
6330     fluid_synth_api_enter(synth);
6331
6332     for(list = synth->sfont; list; list = fluid_list_next(list))
6333     {
6334         sfont = fluid_list_get(list);
6335
6336         if(fluid_sfont_get_id(sfont) == sfont_id)
6337         {
6338             sfont->bankofs = offset;
6339             break;
6340         }
6341     }
6342
6343     if(!list)
6344     {
6345         FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", sfont_id);
6346         FLUID_API_RETURN(FLUID_FAILED);
6347     }
6348
6349     FLUID_API_RETURN(FLUID_OK);
6350 }
6351
6352 /**
6353  * Get bank offset of a loaded SoundFont.
6354  * @param synth FluidSynth instance
6355  * @param sfont_id ID of a loaded SoundFont
6356  * @return SoundFont bank offset value
6357  */
6358 int
6359 fluid_synth_get_bank_offset(fluid_synth_t *synth, int sfont_id)
6360 {
6361     fluid_sfont_t *sfont;
6362     fluid_list_t *list;
6363     int offset = 0;
6364
6365     fluid_return_val_if_fail(synth != NULL, 0);
6366     fluid_synth_api_enter(synth);
6367
6368     for(list = synth->sfont; list; list = fluid_list_next(list))
6369     {
6370         sfont = fluid_list_get(list);
6371
6372         if(fluid_sfont_get_id(sfont) == sfont_id)
6373         {
6374             offset = sfont->bankofs;
6375             break;
6376         }
6377     }
6378
6379     if(!list)
6380     {
6381         FLUID_LOG(FLUID_ERR, "No SoundFont with id = %d", sfont_id);
6382         FLUID_API_RETURN(0);
6383     }
6384
6385     FLUID_API_RETURN(offset);
6386 }
6387
6388 void
6389 fluid_synth_api_enter(fluid_synth_t *synth)
6390 {
6391     if(synth->use_mutex)
6392     {
6393         fluid_rec_mutex_lock(synth->mutex);
6394     }
6395
6396     if(!synth->public_api_count)
6397     {
6398         fluid_synth_check_finished_voices(synth);
6399     }
6400
6401     synth->public_api_count++;
6402 }
6403
6404 void fluid_synth_api_exit(fluid_synth_t *synth)
6405 {
6406     synth->public_api_count--;
6407
6408     if(!synth->public_api_count)
6409     {
6410         fluid_rvoice_eventhandler_flush(synth->eventhandler);
6411     }
6412
6413     if(synth->use_mutex)
6414     {
6415         fluid_rec_mutex_unlock(synth->mutex);
6416     }
6417
6418 }
6419
6420 /**
6421  * Set midi channel type
6422  * @param synth FluidSynth instance
6423  * @param chan MIDI channel number (0 to MIDI channel count - 1)
6424  * @param type MIDI channel type (#fluid_midi_channel_type)
6425  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
6426  * @since 1.1.4
6427  */
6428 int fluid_synth_set_channel_type(fluid_synth_t *synth, int chan, int type)
6429 {
6430     fluid_return_val_if_fail((type >= CHANNEL_TYPE_MELODIC) && (type <= CHANNEL_TYPE_DRUM), FLUID_FAILED);
6431     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6432
6433     synth->channel[chan]->channel_type = type;
6434
6435     FLUID_API_RETURN(FLUID_OK);
6436 }
6437
6438 #ifdef LADSPA
6439 /**
6440  * Return the LADSPA effects instance used by FluidSynth
6441  *
6442  * @param synth FluidSynth instance
6443  * @return pointer to LADSPA fx or NULL if compiled without LADSPA support or LADSPA is not active
6444  */
6445 fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth)
6446 {
6447     fluid_return_val_if_fail(synth != NULL, NULL);
6448
6449     return synth->ladspa_fx;
6450 }
6451 #endif
6452
6453 /**
6454  * Configure a general-purpose IIR biquad filter.
6455  *
6456  * This is an optional, additional filter that operates independently from the default low-pass filter required by the Soundfont2 standard.
6457  * By default this filter is off (#FLUID_IIR_DISABLED).
6458  *
6459  * @param synth FluidSynth instance
6460  * @param type Type of the IIR filter to use (see #fluid_iir_filter_type)
6461  * @param flags Additional flags to customize this filter or zero to stay with the default (see #fluid_iir_filter_flags)
6462  *
6463  * @return #FLUID_OK if the settings have been successfully applied, otherwise #FLUID_FAILED
6464  */
6465 int fluid_synth_set_custom_filter(fluid_synth_t *synth, int type, int flags)
6466 {
6467     int i;
6468     fluid_voice_t *voice;
6469
6470     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
6471     fluid_return_val_if_fail(type >= FLUID_IIR_DISABLED && type < FLUID_IIR_LAST, FLUID_FAILED);
6472
6473     fluid_synth_api_enter(synth);
6474
6475     synth->custom_filter_type = type;
6476     synth->custom_filter_flags = flags;
6477
6478     for(i = 0; i < synth->polyphony; i++)
6479     {
6480         voice = synth->voice[i];
6481
6482         fluid_voice_set_custom_filter(voice, type, flags);
6483     }
6484
6485     FLUID_API_RETURN(FLUID_OK);
6486 }
6487
6488 /**
6489  * Set the important channels for voice overflow priority calculation.
6490  *
6491  * @param synth FluidSynth instance
6492  * @param channels comma-separated list of channel numbers
6493  * @return #FLUID_OK on success, otherwise #FLUID_FAILED
6494  */
6495 static int fluid_synth_set_important_channels(fluid_synth_t *synth, const char *channels)
6496 {
6497     int i;
6498     int retval = FLUID_FAILED;
6499     int *values = NULL;
6500     int num_values;
6501     fluid_overflow_prio_t *scores;
6502
6503     fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
6504
6505     scores = &synth->overflow;
6506
6507     if(scores->num_important_channels < synth->midi_channels)
6508     {
6509         scores->important_channels = FLUID_REALLOC(scores->important_channels,
6510                                      sizeof(*scores->important_channels) * synth->midi_channels);
6511
6512         if(scores->important_channels == NULL)
6513         {
6514             FLUID_LOG(FLUID_ERR, "Out of memory");
6515             goto exit;
6516         }
6517
6518         scores->num_important_channels = synth->midi_channels;
6519     }
6520
6521     FLUID_MEMSET(scores->important_channels, FALSE,
6522                  sizeof(*scores->important_channels) * scores->num_important_channels);
6523
6524     if(channels != NULL)
6525     {
6526         values = FLUID_ARRAY(int, synth->midi_channels);
6527
6528         if(values == NULL)
6529         {
6530             FLUID_LOG(FLUID_ERR, "Out of memory");
6531             goto exit;
6532         }
6533
6534         /* Every channel given in the comma-separated list of channel numbers
6535          * is set to TRUE, i.e. flagging it as "important". Channel numbers are
6536          * 1-based. */
6537         num_values = fluid_settings_split_csv(channels, values, synth->midi_channels);
6538
6539         for(i = 0; i < num_values; i++)
6540         {
6541             if(values[i] > 0 && values[i] <= synth->midi_channels)
6542             {
6543                 scores->important_channels[values[i] - 1] = TRUE;
6544             }
6545         }
6546     }
6547
6548     retval = FLUID_OK;
6549
6550 exit:
6551     FLUID_FREE(values);
6552     return retval;
6553 }
6554
6555 /*
6556  * Handler for synth.overflow.important-channels setting.
6557  */
6558 static void fluid_synth_handle_important_channels(void *data, const char *name,
6559         const char *value)
6560 {
6561     fluid_synth_t *synth = (fluid_synth_t *)data;
6562
6563     fluid_synth_api_enter(synth);
6564     fluid_synth_set_important_channels(synth, value);
6565     fluid_synth_api_exit(synth);
6566 }
6567
6568
6569 /**  API legato mode *********************************************************/
6570
6571 /**
6572  * Sets the legato mode of a channel.
6573  *
6574  * @param synth the synth instance.
6575  * @param chan MIDI channel number (0 to MIDI channel count - 1).
6576  * @param legatomode The legato mode as indicated by #fluid_channel_legato_mode.
6577  *
6578  * @return
6579  * - #FLUID_OK on success.
6580  * - #FLUID_FAILED
6581  *   - \a synth is NULL.
6582  *   - \a chan is outside MIDI channel count.
6583  *   - \a legatomode is invalid.
6584  */
6585 int fluid_synth_set_legato_mode(fluid_synth_t *synth, int chan, int legatomode)
6586 {
6587     /* checks parameters first */
6588     fluid_return_val_if_fail(legatomode >= 0, FLUID_FAILED);
6589     fluid_return_val_if_fail(legatomode < FLUID_CHANNEL_LEGATO_MODE_LAST, FLUID_FAILED);
6590     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6591     /**/
6592     synth->channel[chan]->legatomode = legatomode;
6593     /**/
6594     FLUID_API_RETURN(FLUID_OK);
6595 }
6596
6597 /**
6598  * Gets the legato mode of a channel.
6599  *
6600  * @param synth the synth instance.
6601  * @param chan MIDI channel number (0 to MIDI channel count - 1).
6602  * @param legatomode The legato mode as indicated by #fluid_channel_legato_mode.
6603  *
6604  * @return
6605  * - #FLUID_OK on success.
6606  * - #FLUID_FAILED
6607  *   - \a synth is NULL.
6608  *   - \a chan is outside MIDI channel count.
6609  *   - \a legatomode is NULL.
6610  */
6611 int fluid_synth_get_legato_mode(fluid_synth_t *synth, int chan, int *legatomode)
6612 {
6613     /* checks parameters first */
6614     fluid_return_val_if_fail(legatomode != NULL, FLUID_FAILED);
6615     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6616     /**/
6617     * legatomode = synth->channel[chan]->legatomode;
6618     /**/
6619     FLUID_API_RETURN(FLUID_OK);
6620 }
6621
6622 /**  API portamento mode *********************************************************/
6623
6624 /**
6625  * Sets the portamento mode of a channel.
6626  *
6627  * @param synth the synth instance.
6628  * @param chan MIDI channel number (0 to MIDI channel count - 1).
6629  * @param portamentomode The portamento mode as indicated by #fluid_channel_portamento_mode.
6630  * @return
6631  * - #FLUID_OK on success.
6632  * - #FLUID_FAILED
6633  *   - \a synth is NULL.
6634  *   - \a chan is outside MIDI channel count.
6635  *   - \a portamentomode is invalid.
6636  */
6637 int fluid_synth_set_portamento_mode(fluid_synth_t *synth, int chan,
6638                                     int portamentomode)
6639 {
6640     /* checks parameters first */
6641     fluid_return_val_if_fail(portamentomode >= 0, FLUID_FAILED);
6642     fluid_return_val_if_fail(portamentomode < FLUID_CHANNEL_PORTAMENTO_MODE_LAST, FLUID_FAILED);
6643     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6644     /**/
6645     synth->channel[chan]->portamentomode = portamentomode;
6646     /**/
6647     FLUID_API_RETURN(FLUID_OK);
6648 }
6649
6650 /**
6651  * Gets the portamento mode of a channel.
6652  *
6653  * @param synth the synth instance.
6654  * @param chan MIDI channel number (0 to MIDI channel count - 1).
6655  * @param portamentomode Pointer to the portamento mode as indicated by #fluid_channel_portamento_mode.
6656  * @return
6657  * - #FLUID_OK on success.
6658  * - #FLUID_FAILED
6659  *   - \a synth is NULL.
6660  *   - \a chan is outside MIDI channel count.
6661  *   - \a portamentomode is NULL.
6662  */
6663 int fluid_synth_get_portamento_mode(fluid_synth_t *synth, int chan,
6664                                     int *portamentomode)
6665 {
6666     /* checks parameters first */
6667     fluid_return_val_if_fail(portamentomode != NULL, FLUID_FAILED);
6668     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6669     /**/
6670     * portamentomode = synth->channel[chan]->portamentomode;
6671     /**/
6672     FLUID_API_RETURN(FLUID_OK);
6673 }
6674
6675 /**  API breath mode *********************************************************/
6676
6677 /**
6678  * Sets the breath mode of a channel.
6679  *
6680  * @param synth the synth instance.
6681  * @param chan MIDI channel number (0 to MIDI channel count - 1).
6682  * @param breathmode The breath mode as indicated by #fluid_channel_breath_flags.
6683  *
6684  * @return
6685  * - #FLUID_OK on success.
6686  * - #FLUID_FAILED
6687  *   - \a synth is NULL.
6688  *   - \a chan is outside MIDI channel count.
6689  */
6690 int fluid_synth_set_breath_mode(fluid_synth_t *synth, int chan, int breathmode)
6691 {
6692     /* checks parameters first */
6693     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6694     /**/
6695     fluid_channel_set_breath_info(synth->channel[chan], breathmode);
6696     /**/
6697     FLUID_API_RETURN(FLUID_OK);
6698 }
6699
6700 /**
6701  * Gets the breath mode of a channel.
6702  *
6703  * @param synth the synth instance.
6704  * @param chan MIDI channel number (0 to MIDI channel count - 1).
6705  * @param breathmode Pointer to the returned breath mode as indicated by #fluid_channel_breath_flags.
6706  *
6707  * @return
6708  * - #FLUID_OK on success.
6709  * - #FLUID_FAILED
6710  *   - \a synth is NULL.
6711  *   - \a chan is outside MIDI channel count.
6712  *   - \a breathmode is NULL.
6713  */
6714 int fluid_synth_get_breath_mode(fluid_synth_t *synth, int chan, int *breathmode)
6715 {
6716     /* checks parameters first */
6717     fluid_return_val_if_fail(breathmode != NULL, FLUID_FAILED);
6718     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6719     /**/
6720     * breathmode = fluid_channel_get_breath_info(synth->channel[chan]);
6721     /**/
6722     FLUID_API_RETURN(FLUID_OK);
6723 }
6724
6725 /**  API Poly/mono mode ******************************************************/
6726
6727 /*
6728  * Resets a basic channel group of MIDI channels.
6729  * @param synth the synth instance.
6730  * @param chan the beginning channel of the group.
6731  * @param nbr_chan the number of channel in the group.
6732 */
6733 static void
6734 fluid_synth_reset_basic_channel_LOCAL(fluid_synth_t *synth, int chan, int nbr_chan)
6735 {
6736     int i;
6737
6738     for(i = chan; i < chan + nbr_chan; i++)
6739     {
6740         fluid_channel_reset_basic_channel_info(synth->channel[i]);
6741         synth->channel[i]->mode_val = 0;
6742     }
6743 }
6744
6745 /**
6746  * Disables and unassigns all channels from a basic channel group.
6747  *
6748  * @param synth The synth instance.
6749  * @param chan The basic channel of the group to reset or -1 to reset all channels.
6750  * @note By default (i.e. on creation after new_fluid_synth() and after fluid_synth_system_reset())
6751  * a synth instance has one basic channel at channel 0 in mode #FLUID_CHANNEL_MODE_OMNION_POLY.
6752  * All other channels belong to this basic channel group. Make sure to call this function before
6753  * setting any custom basic channel setup.
6754  *
6755  * @return
6756  *  - #FLUID_OK on success.
6757  *  - #FLUID_FAILED
6758  *    - \a synth is NULL.
6759  *    - \a chan is outside MIDI channel count.
6760  *    - \a chan isn't a basic channel.
6761  */
6762 int fluid_synth_reset_basic_channel(fluid_synth_t *synth, int chan)
6763 {
6764     int nbr_chan;
6765
6766     /* checks parameters first */
6767     if(chan < 0)
6768     {
6769         fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
6770         fluid_synth_api_enter(synth);
6771         /* The range is all MIDI channels from 0 to MIDI channel count -1 */
6772         chan = 0; /* beginning chan */
6773         nbr_chan =  synth->midi_channels; /* MIDI Channels number */
6774     }
6775     else
6776     {
6777         FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6778
6779         /* checks if chan is a basic channel */
6780         if(!(synth->channel[chan]->mode &  FLUID_CHANNEL_BASIC))
6781         {
6782             FLUID_API_RETURN(FLUID_FAILED);
6783         }
6784
6785         /* The range is all MIDI channels in the group from chan */
6786         nbr_chan = synth->channel[chan]->mode_val; /* nbr of channels in the group */
6787     }
6788
6789     /* resets the range of MIDI channels */
6790     fluid_synth_reset_basic_channel_LOCAL(synth, chan, nbr_chan);
6791     FLUID_API_RETURN(FLUID_OK);
6792 }
6793
6794 /**
6795  * Checks if a new basic channel group overlaps the next basic channel group.
6796  *
6797  * On success the function returns the possible number of channel for this
6798  * new basic channel group.
6799  * The function fails if the new group overlaps the next basic channel group.
6800  *
6801  * @param see fluid_synth_set_basic_channel.
6802  * @return
6803  * - On success, the effective number of channels for this new basic channel group,
6804  *   #FLUID_FAILED otherwise.
6805  * - #FLUID_FAILED
6806  *   - \a val has a number of channels overlapping next basic channel group or been
6807  *     above MIDI channel count.
6808  */
6809 static int
6810 fluid_synth_check_next_basic_channel(fluid_synth_t *synth, int basicchan, int mode, int val)
6811 {
6812     int i, n_chan = synth->midi_channels; /* MIDI Channels count */
6813     int real_val = val; /* real number of channels in the group */
6814
6815     /* adjusts val range */
6816     if(mode == FLUID_CHANNEL_MODE_OMNIOFF_POLY)
6817     {
6818         real_val = 1; /* mode poly omnioff implies a group of only one channel.*/
6819     }
6820     else if(val == 0)
6821     {
6822         /* mode poly omnion (0), mono omnion (1), mono omni off (3) */
6823         /* value 0 means all possible channels from basicchan to MIDI channel count -1.*/
6824         real_val = n_chan - basicchan;
6825     }
6826     /* checks if val range is above MIDI channel count */
6827     else if(basicchan + val > n_chan)
6828     {
6829         return FLUID_FAILED;
6830     }
6831
6832     /* checks if this basic channel group overlaps next basic channel group */
6833     for(i = basicchan + 1; i < basicchan + real_val; i++)
6834     {
6835         if(synth->channel[i]->mode &  FLUID_CHANNEL_BASIC)
6836         {
6837             /* A value of 0 for val means all possible channels from basicchan to
6838             to the next basic channel -1 (if any).
6839             When i reachs the next basic channel group, real_val will be
6840             limited if it is possible */
6841             if(val == 0)
6842             {
6843                 /* limitation of real_val */
6844                 real_val = i - basicchan;
6845                 break;
6846             }
6847
6848             /* overlap with the next basic channel group */
6849             return FLUID_FAILED;
6850         }
6851     }
6852
6853     return real_val;
6854 }
6855
6856 /**
6857  * Sets a new basic channel group only. The function doesn't allow to change an
6858  * existing basic channel.
6859  *
6860  * The function fails if any channel overlaps any existing basic channel group.
6861  * To make room if necessary, basic channel groups can be cleared using
6862  * fluid_synth_reset_basic_channel().
6863  *
6864  * @param synth the synth instance.
6865  * @param chan the basic Channel number (0 to MIDI channel count-1).
6866  * @param mode the MIDI mode to use for chan (see #fluid_basic_channel_modes).
6867  * @param val number of channels in the group.
6868  * @note \a val is only relevant for mode #FLUID_CHANNEL_MODE_OMNION_POLY,
6869  * #FLUID_CHANNEL_MODE_OMNION_MONO and #FLUID_CHANNEL_MODE_OMNIOFF_MONO. A value
6870  * of 0 means all possible channels from \a chan to to next basic channel minus 1 (if any)
6871  * or to MIDI channel count minus 1. Val is ignored for #FLUID_CHANNEL_MODE_OMNIOFF_POLY
6872  * as this mode implies a group of only one channel.
6873  * @return
6874  * - #FLUID_OK on success.
6875  * - #FLUID_FAILED
6876  *   - \a synth is NULL.
6877  *   - \a chan is outside MIDI channel count.
6878  *   - \a mode is invalid.
6879  *   - \a val has a number of channels overlapping another basic channel group or been
6880  *     above MIDI channel count.
6881  *   - When the function fails, any existing basic channels aren't modified.
6882  */
6883 int fluid_synth_set_basic_channel(fluid_synth_t *synth, int chan, int mode, int val)
6884 {
6885     /* check parameters */
6886     fluid_return_val_if_fail(mode >= 0, FLUID_FAILED);
6887     fluid_return_val_if_fail(mode < FLUID_CHANNEL_MODE_LAST, FLUID_FAILED);
6888     fluid_return_val_if_fail(val >= 0, FLUID_FAILED);
6889     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
6890
6891     /**/
6892     if(val > 0 && chan + val > synth->midi_channels)
6893     {
6894         FLUID_API_RETURN(FLUID_FAILED);
6895     }
6896
6897     /* Checks if there is an overlap with the next basic channel */
6898     val = fluid_synth_check_next_basic_channel(synth, chan, mode, val);
6899
6900     if(val == FLUID_FAILED || synth->channel[chan]->mode &  FLUID_CHANNEL_ENABLED)
6901     {
6902         /* overlap with the next or previous channel group */
6903         FLUID_LOG(FLUID_INFO, "basic channel %d overlaps another group", chan);
6904         FLUID_API_RETURN(FLUID_FAILED);
6905     }
6906
6907     /* sets a new basic channel group */
6908     fluid_synth_set_basic_channel_LOCAL(synth, chan, mode, val);
6909     /**/
6910     FLUID_API_RETURN(FLUID_OK);
6911 }
6912
6913 /*
6914  * Local version of fluid_synth_set_basic_channel(), called internally:
6915  * - by fluid_synth_set_basic_channel() to set a new basic channel group.
6916  * - during creation new_fluid_synth() or on CC reset to set a default basic channel group.
6917  * - on CC ominoff, CC omnion, CC poly , CC mono to change an existing basic channel group.
6918  *
6919  * @param see fluid_synth_set_basic_channel()
6920 */
6921 static void
6922 fluid_synth_set_basic_channel_LOCAL(fluid_synth_t *synth, int basicchan, int mode, int val)
6923 {
6924     int i;
6925
6926     /* sets the basic channel group */
6927     for(i = basicchan; i < basicchan + val; i++)
6928     {
6929         int new_mode = mode; /* OMNI_OFF/ON, MONO/POLY ,others bits are zero */
6930         int new_val;
6931         /* MIDI specs: when mode is changed, channel must receive ALL_NOTES_OFF */
6932         fluid_synth_all_notes_off_LOCAL(synth, i);
6933
6934         if(i == basicchan)
6935         {
6936             new_mode |= FLUID_CHANNEL_BASIC; /* First channel in the group */
6937             new_val = val;      /* number of channels in the group */
6938         }
6939         else
6940         {
6941             new_val = 0; /* val is 0 for other channel than basic channel */
6942         }
6943
6944         /* Channel is enabled */
6945         new_mode |= FLUID_CHANNEL_ENABLED;
6946         /* Now new_mode is OMNI OFF/ON,MONO/POLY, BASIC_CHANNEL or not and enabled */
6947         fluid_channel_set_basic_channel_info(synth->channel[i], new_mode);
6948         synth->channel[i]->mode_val = new_val;
6949     }
6950 }
6951
6952 /**
6953  * Searchs a previous basic channel starting from chan.
6954  *
6955  * @param synth the synth instance.
6956  * @param chan starting index of the search (including chan).
6957  * @return index of the basic channel if found , FLUID_FAILED otherwise.
6958  */
6959 static int fluid_synth_get_previous_basic_channel(fluid_synth_t *synth, int chan)
6960 {
6961     for(; chan >= 0; chan--)
6962     {
6963         /* searchs previous basic channel */
6964         if(synth->channel[chan]->mode &  FLUID_CHANNEL_BASIC)
6965         {
6966             /* chan is the previous basic channel */
6967             return chan;
6968         }
6969     }
6970
6971     return FLUID_FAILED;
6972 }
6973
6974 /**
6975  * Returns poly mono mode information of any MIDI channel.
6976  *
6977  * @param synth the synth instance
6978  * @param chan MIDI channel number (0 to MIDI channel count - 1)
6979  * @param basic_chan_out Buffer to store the basic channel \a chan belongs to or #FLUID_FAILED if \a chan is disabled.
6980  * @param mode_out Buffer to store the mode of \a chan (see #fluid_basic_channel_modes) or #FLUID_FAILED if \a chan is disabled.
6981  * @param val_out Buffer to store the total number of channels in this basic channel group or #FLUID_FAILED if \a chan is disabled.
6982  * @note If any of \a basic_chan_out, \a mode_out, \a val_out pointer is NULL
6983  *  the corresponding information isn't returned.
6984  *
6985  * @return
6986  * - #FLUID_OK on success.
6987  * - #FLUID_FAILED
6988  *   - \a synth is NULL.
6989  *   - \a chan is outside MIDI channel count.
6990  */
6991 int fluid_synth_get_basic_channel(fluid_synth_t *synth, int chan,
6992                                   int *basic_chan_out,
6993                                   int *mode_out,
6994                                   int *val_out)
6995 {
6996     int basic_chan = FLUID_FAILED;
6997     int mode = FLUID_FAILED;
6998     int val = FLUID_FAILED;
6999
7000     /* checks parameters first */
7001     FLUID_API_ENTRY_CHAN(FLUID_FAILED);
7002
7003     if((synth->channel[chan]->mode &  FLUID_CHANNEL_ENABLED) &&
7004             /* chan is enabled , we search the basic channel chan belongs to */
7005             (basic_chan = fluid_synth_get_previous_basic_channel(synth, chan)) != FLUID_FAILED)
7006     {
7007         mode = synth->channel[chan]->mode & FLUID_CHANNEL_MODE_MASK;
7008         val = synth->channel[basic_chan]->mode_val;
7009     }
7010
7011     /* returns the informations if they are requested */
7012     if(basic_chan_out)
7013     {
7014         * basic_chan_out = basic_chan;
7015     }
7016
7017     if(mode_out)
7018     {
7019         * mode_out = mode;
7020     }
7021
7022     if(val_out)
7023     {
7024         * val_out = val;
7025     }
7026
7027     FLUID_API_RETURN(FLUID_OK);
7028 }