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