+ AutoHell: print the dependency detection result for the GUI code shared between...
[calf.git] / src / fluidsynth.cpp
blob0026eeff223bc3e61ee18316786c0e847e8d8623
1 /* Calf DSP Library
2 * Fluidsynth wrapper
4 * Copyright (C) 2001-2007 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
21 #include <assert.h>
22 #include <memory.h>
23 #include <config.h>
24 #include <complex>
25 #if USE_JACK
26 #include <jack/jack.h>
27 #endif
28 #include <calf/giface.h>
29 #include <calf/modules_synths.h>
30 #include <calf/modules_dev.h>
32 #if ENABLE_EXPERIMENTAL
34 using namespace dsp;
35 using namespace calf_plugins;
36 using namespace std;
38 fluidsynth_audio_module::fluidsynth_audio_module()
40 settings = NULL;
41 synth = NULL;
42 status_serial = 1;
43 set_preset = -1;
46 void fluidsynth_audio_module::post_instantiate()
48 settings = new_fluid_settings();
49 synth = create_synth(sfid);
52 void fluidsynth_audio_module::activate()
56 void fluidsynth_audio_module::deactivate()
60 fluid_synth_t *fluidsynth_audio_module::create_synth(int &new_sfid)
62 set_preset = -1;
63 fluid_settings_t *new_settings = new_fluid_settings();
64 fluid_synth_t *s = new_fluid_synth(new_settings);
65 if (!soundfont.empty())
67 int sid = fluid_synth_sfload(s, soundfont.c_str(), 1);
68 if (sid == -1)
70 delete_fluid_synth(s);
71 return NULL;
73 assert(sid >= 0);
74 printf("sid=%d\n", sid);
75 fluid_synth_sfont_select(s, 0, sid);
76 new_sfid = sid;
78 fluid_sfont_t* sfont = fluid_synth_get_sfont(s, 0);
79 soundfont_name = (*sfont->get_name)(sfont);
81 sfont->iteration_start(sfont);
83 string preset_list;
84 fluid_preset_t tmp;
85 int first_preset = -1;
86 while(sfont->iteration_next(sfont, &tmp))
88 string pname = tmp.get_name(&tmp);
89 int bank = tmp.get_banknum(&tmp);
90 int num = tmp.get_num(&tmp);
91 int id = num + 128 * bank;
92 sf_preset_names[id] = pname;
93 preset_list += calf_utils::i2s(id) + "\t" + pname + "\n";
94 if (first_preset == -1)
95 first_preset = id;
97 if (first_preset != -1)
99 fluid_synth_bank_select(s, 0, first_preset >> 7);
100 fluid_synth_program_change(s, 0, first_preset & 127);
102 soundfont_preset_list = preset_list;
104 else
105 new_sfid = -1;
106 return s;
109 void fluidsynth_audio_module::note_on(int note, int vel)
111 fluid_synth_noteon(synth, 0, note, vel);
114 void fluidsynth_audio_module::note_off(int note, int vel)
116 fluid_synth_noteoff(synth, 0, note);
119 void fluidsynth_audio_module::control_change(int controller, int value)
121 fluid_synth_cc(synth, 0, controller, value);
123 if (controller == 0 || controller == 32)
124 update_preset_num();
127 void fluidsynth_audio_module::program_change(int program)
129 fluid_synth_program_change(synth, 0, program);
131 update_preset_num();
135 void fluidsynth_audio_module::update_preset_num()
137 fluid_preset_t *p = fluid_synth_get_channel_preset(synth, 0);
138 if (p)
139 last_selected_preset = p->get_num(p) + 128 * p->get_banknum(p);
140 else
141 last_selected_preset = -1;
142 status_serial++;
145 uint32_t fluidsynth_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
147 static const int interp_lens[] = { 0, 1, 4, 7 };
148 int new_preset = set_preset;
149 if (new_preset != -1)
151 // XXXKF yeah there's a tiny chance of race here, have to live with it until I write some utility classes for lock-free data passing
152 set_preset = -1;
153 fluid_synth_bank_select(synth, 0, new_preset >> 7);
154 fluid_synth_program_change(synth, 0, new_preset & 127);
155 last_selected_preset = new_preset;
157 fluid_synth_set_interp_method(synth, -1, interp_lens[dsp::clip<int>(fastf2i_drm(*params[par_interpolation]), 0, 3)]);
158 fluid_synth_set_reverb_on(synth, *params[par_reverb] > 0);
159 fluid_synth_set_chorus_on(synth, *params[par_chorus] > 0);
160 fluid_synth_set_gain(synth, *params[par_master]);
161 fluid_synth_write_float(synth, nsamples, outs[0], offset, 1, outs[1], offset, 1);
162 return 3;
165 char *fluidsynth_audio_module::configure(const char *key, const char *value)
167 if (!strcmp(key, "preset_key_set"))
169 set_preset = atoi(value);
170 return NULL;
172 if (!strcmp(key, "soundfont"))
174 if (*value)
175 printf("Loading %s\n", value);
176 else
177 printf("Creating a blank synth\n");
178 soundfont = value;
179 int newsfid = -1;
180 fluid_synth_t *new_synth = create_synth(newsfid);
182 if (new_synth)
184 synth = new_synth;
185 sfid = newsfid;
186 update_preset_num();
188 else
189 return strdup("Cannot load a soundfont");
190 // XXXKF memory leak
192 return NULL;
195 void fluidsynth_audio_module::send_configures(send_configure_iface *sci)
197 sci->send_configure("soundfont", soundfont.c_str());
200 int fluidsynth_audio_module::send_status_updates(send_updates_iface *sui, int last_serial)
202 if (status_serial != last_serial)
204 sui->send_status("sf_name", soundfont_name.c_str());
205 sui->send_status("preset_list", soundfont_preset_list.c_str());
206 sui->send_status("preset_key", calf_utils::i2s(last_selected_preset).c_str());
207 map<uint32_t, string>::const_iterator i = sf_preset_names.find(last_selected_preset);
208 if (i == sf_preset_names.end())
209 sui->send_status("preset_name", "");
210 else
211 sui->send_status("preset_name", i->second.c_str());
213 return status_serial;
216 fluidsynth_audio_module::~fluidsynth_audio_module()
218 if (synth) {
219 delete_fluid_synth(synth);
220 synth = NULL;
222 if (settings) {
223 // delete_fluid_settings(settings);
224 settings = NULL;
228 #endif