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
26 #include <jack/jack.h>
28 #include <calf/giface.h>
29 #include <calf/modules_synths.h>
30 #include <calf/modules_dev.h>
32 #if ENABLE_EXPERIMENTAL
35 using namespace calf_plugins
;
38 fluidsynth_audio_module::fluidsynth_audio_module()
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
)
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);
70 delete_fluid_synth(s
);
74 printf("sid=%d\n", sid
);
75 fluid_synth_sfont_select(s
, 0, sid
);
78 fluid_sfont_t
* sfont
= fluid_synth_get_sfont(s
, 0);
79 soundfont_name
= (*sfont
->get_name
)(sfont
);
81 sfont
->iteration_start(sfont
);
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)
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
;
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)
127 void fluidsynth_audio_module::program_change(int program
)
129 fluid_synth_program_change(synth
, 0, program
);
135 void fluidsynth_audio_module::update_preset_num()
137 fluid_preset_t
*p
= fluid_synth_get_channel_preset(synth
, 0);
139 last_selected_preset
= p
->get_num(p
) + 128 * p
->get_banknum(p
);
141 last_selected_preset
= -1;
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
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);
165 char *fluidsynth_audio_module::configure(const char *key
, const char *value
)
167 if (!strcmp(key
, "preset_key_set"))
169 set_preset
= atoi(value
);
172 if (!strcmp(key
, "soundfont"))
175 printf("Loading %s\n", value
);
177 printf("Creating a blank synth\n");
180 fluid_synth_t
*new_synth
= create_synth(newsfid
);
189 return strdup("Cannot load a soundfont");
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", "");
211 sui
->send_status("preset_name", i
->second
.c_str());
213 return status_serial
;
216 fluidsynth_audio_module::~fluidsynth_audio_module()
219 delete_fluid_synth(synth
);
223 // delete_fluid_settings(settings);