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