1 /*
2 * Copyright (C) 2016-2019 Robin Gareus <robin@gareus.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef _GNU_SOURCE
20 #define _GNU_SOURCE
21 #endif
22
23 #include <algorithm>
24 #include <cstring>
25 #include <map>
26 #include <string>
27 #include <vector>
28
29 #include <math.h>
30 #include <pthread.h>
31 #include <stdlib.h>
32
33 #define AFS_URN "urn:ardour:a-fluidsynth"
34
35 #ifdef HAVE_LV2_1_10_0
36 #define x_forge_object lv2_atom_forge_object
37 #else
38 #define x_forge_object lv2_atom_forge_blank
39 #endif
40
41 #ifdef LV2_EXTENDED
42 #include "../../ardour/ardour/lv2_extensions.h"
43 #endif
44
45 #include "fluidsynth.h"
46
47 #include <lv2/lv2plug.in/ns/ext/atom/atom.h>
48 #include <lv2/lv2plug.in/ns/ext/atom/forge.h>
49 #include <lv2/lv2plug.in/ns/ext/atom/util.h>
50 #include <lv2/lv2plug.in/ns/ext/log/logger.h>
51 #include <lv2/lv2plug.in/ns/ext/midi/midi.h>
52 #include <lv2/lv2plug.in/ns/ext/patch/patch.h>
53 #include <lv2/lv2plug.in/ns/ext/state/state.h>
54 #include <lv2/lv2plug.in/ns/ext/urid/urid.h>
55 #include <lv2/lv2plug.in/ns/ext/worker/worker.h>
56 #include <lv2/lv2plug.in/ns/lv2core/lv2.h>
57
58 enum {
59 FS_PORT_CONTROL = 0,
60 FS_PORT_NOTIFY,
61 FS_PORT_OUT_L,
62 FS_PORT_OUT_R,
63 FS_OUT_GAIN,
64 FS_REV_ENABLE,
65 FS_REV_ROOMSIZE,
66 FS_REV_DAMPING,
67 FS_REV_WIDTH,
68 FS_REV_LEVEL,
69 FS_CHR_ENABLE,
70 FS_CHR_N,
71 FS_CHR_SPEED,
72 FS_CHR_DEPTH,
73 FS_CHR_LEVEL,
74 FS_CHR_TYPE,
75 FS_PORT_ENABLE,
76 FS_PORT_LAST
77 };
78
79 enum {
80 CMD_APPLY = 0,
81 CMD_FREE = 1,
82 };
83
84 struct BankProgram {
BankProgramBankProgram85 BankProgram (const std::string& n, int b, int p)
86 : name (n)
87 , bank (b)
88 , program (p)
89 {}
90
BankProgramBankProgram91 BankProgram (const BankProgram& other)
92 : name (other.name)
93 , bank (other.bank)
94 , program (other.program)
95 {}
96
97 std::string name;
98 int bank;
99 int program;
100 };
101
102 typedef std::vector<BankProgram> BPList;
103 typedef std::map<int, BPList> BPMap;
104 typedef std::map<int, BankProgram> BPState;
105
106 typedef struct {
107 /* ports */
108 const LV2_Atom_Sequence* control;
109 LV2_Atom_Sequence* notify;
110
111 float* p_ports[FS_PORT_LAST];
112 float v_ports[FS_PORT_LAST];
113
114 /* fluid synth */
115 fluid_settings_t* settings;
116 fluid_synth_t* synth;
117 int synthId;
118
119 /* lv2 URIDs */
120 LV2_URID atom_Blank;
121 LV2_URID atom_Object;
122 LV2_URID atom_URID;
123 LV2_URID atom_Path;
124 LV2_URID atom_Vector;
125 LV2_URID atom_Double;
126 LV2_URID midi_MidiEvent;
127 LV2_URID patch_Get;
128 LV2_URID patch_Set;
129 LV2_URID patch_property;
130 LV2_URID patch_value;
131 LV2_URID state_Changed;
132 LV2_URID afs_sf2file;
133 LV2_URID afs_tuning;
134
135 /* lv2 extensions */
136 LV2_Log_Log* log;
137 LV2_Log_Logger logger;
138 LV2_Worker_Schedule* schedule;
139 LV2_Atom_Forge forge;
140 LV2_Atom_Forge_Frame frame;
141
142 #ifdef LV2_EXTENDED
143 LV2_Midnam* midnam;
144 LV2_BankPatch* bankpatch;
145 BPMap presets;
146 #endif
147 pthread_mutex_t bp_lock;
148
149 /* state */
150 bool panic;
151 bool initialized;
152 bool inform_ui;
153 bool send_bankpgm;
154
155 char current_sf2_file_path[1024];
156 char queue_sf2_file_path[1024];
157 bool reinit_in_progress; // set in run, cleared in work_response
158 bool queue_reinit; // set in restore, cleared in work_response
159
160 bool queue_retune;
161 double queue_tuning[128];
162
163 BankProgram program_state[16];
164
165 fluid_midi_event_t* fmidi_event;
166
167 } AFluidSynth;
168
169 /* *****************************************************************************
170 * helpers
171 */
172
173 static bool
load_sf2(AFluidSynth * self,const char * fn)174 load_sf2 (AFluidSynth* self, const char* fn)
175 {
176 const int synth_id = fluid_synth_sfload (self->synth, fn, 1);
177
178 #ifdef LV2_EXTENDED
179 pthread_mutex_lock (&self->bp_lock);
180 self->presets.clear ();
181 pthread_mutex_unlock (&self->bp_lock);
182 #endif
183
184 if (synth_id == FLUID_FAILED) {
185 return false;
186 }
187
188 fluid_sfont_t* const sfont = fluid_synth_get_sfont_by_id (self->synth, synth_id);
189 if (!sfont) {
190 return false;
191 }
192
193 int chn;
194 fluid_preset_t* preset;
195 fluid_sfont_iteration_start (sfont);
196 pthread_mutex_lock (&self->bp_lock);
197 for (chn = 0; (preset = fluid_sfont_iteration_next (sfont)); ++chn) {
198 if (chn < 16) {
199 fluid_synth_program_select (self->synth, chn, synth_id,
200 fluid_preset_get_banknum (preset), fluid_preset_get_num (preset));
201 }
202 #ifndef LV2_EXTENDED
203 else {
204 break;
205 }
206 #else
207 self->presets[fluid_preset_get_banknum (preset)].push_back (
208 BankProgram (
209 fluid_preset_get_name (preset),
210 fluid_preset_get_banknum (preset),
211 fluid_preset_get_num (preset)));
212 #endif // LV2_EXTENDED
213 }
214 pthread_mutex_unlock (&self->bp_lock);
215
216 if (chn == 0) {
217 return false;
218 }
219
220 return true;
221 }
222
223 static const LV2_Atom*
parse_patch_msg(AFluidSynth * self,const LV2_Atom_Object * obj)224 parse_patch_msg (AFluidSynth* self, const LV2_Atom_Object* obj)
225 {
226 const LV2_Atom* property = NULL;
227 const LV2_Atom* file_path = NULL;
228
229 if (obj->body.otype != self->patch_Set) {
230 return NULL;
231 }
232
233 lv2_atom_object_get (obj, self->patch_property, &property, 0);
234 if (!property || property->type != self->atom_URID) {
235 return NULL;
236 } else if (((const LV2_Atom_URID*)property)->body != self->afs_sf2file) {
237 return NULL;
238 }
239
240 lv2_atom_object_get (obj, self->patch_value, &file_path, 0);
241 if (!file_path || file_path->type != self->atom_Path) {
242 return NULL;
243 }
244
245 return file_path;
246 }
247
248 static void
inform_ui(AFluidSynth * self)249 inform_ui (AFluidSynth* self)
250 {
251 if (strlen (self->current_sf2_file_path) == 0) {
252 return;
253 }
254
255 LV2_Atom_Forge_Frame frame;
256 lv2_atom_forge_frame_time (&self->forge, 0);
257 x_forge_object (&self->forge, &frame, 1, self->patch_Set);
258 lv2_atom_forge_property_head (&self->forge, self->patch_property, 0);
259 lv2_atom_forge_urid (&self->forge, self->afs_sf2file);
260 lv2_atom_forge_property_head (&self->forge, self->patch_value, 0);
261 lv2_atom_forge_path (&self->forge, self->current_sf2_file_path, strlen (self->current_sf2_file_path));
262
263 lv2_atom_forge_pop (&self->forge, &frame);
264 }
265
266 static float
db_to_coeff(float db)267 db_to_coeff (float db)
268 {
269 if (db <= -80) {
270 return 0;
271 } else if (db >= 20) {
272 return 10;
273 }
274 return powf (10.f, .05f * db);
275 }
276
277 static void
parse_mts(AFluidSynth * self,const uint8_t * data,uint32_t len)278 parse_mts (AFluidSynth* self, const uint8_t* data, uint32_t len)
279 {
280 assert (data[0] == 0xf0 && data[3] == 0x08 && len > 11);
281 if (data[4] == 0x01 && len == 408) {
282 /* bulk transfer
283 * 0xf0, 0x7e, -- non-realtime sysex
284 * 0xXX, -- target-id
285 * 0x08, 0x01, -- tuning, bulk dump reply
286 * 0x7X, -- tuning program number 0 to 127
287 * TEXT * 16 -- 16 chars name (zero padded)
288 * TUNE * 3 * 128 -- tuning for all notes (base, MSB, LSB)
289 * 0xXX -- checksum
290 * 0xf7 -- 408 bytes in total
291 */
292 int prog = 0; // data[2]
293 int off = 22;
294 int key[128];
295 double pitch[128];
296 for (int i = 0; i < 128; ++i) {
297 const uint32_t note = data[off];
298 const uint32_t fract = (data[off + 1] << 7) | data[off + 2];
299 key[i] = i;
300 pitch[i] = note * 100.f + fract / 163.83;
301 off += 3;
302 }
303 if (data[off + 1] == 0xf7) {
304 int rv = fluid_synth_tune_notes (self->synth,
305 /* tuning bank */ 0,
306 /* tuning prog */ prog,
307 128, key, pitch,
308 /* apply */ 1);
309 if (rv == FLUID_OK) {
310 for (int c = 0; c < 16; ++c) {
311 fluid_synth_activate_tuning (self->synth, c, 0, prog, 0);
312 }
313 self->inform_ui = true; // StateChanged
314 }
315 }
316 } else if (data[4] == 0x02 && len == 12) {
317 /* single note tuning
318 * 0xf0, 0x7f, -- realtime sysex
319 * 0xXX, -- target-id
320 * 0x08, 0x02, -- tuning, note change request
321 * 0x7X, -- tuning program number 0 to 127
322 * 0x7X -- Note to re-tune
323 * base, -- semitone (MIDI note number to retune to, unit is 100 cents)
324 * cent_msb, -- MSB of fractional part (1/128 semitone = 100/128 cents = .78125 cent units)
325 * cent_lsb, -- LSB of fractional part (1/16384 semitone = 100/16384 cents = .0061 cent units
326 * 0xf7 -- 12 bytesin total
327 */
328 const uint32_t note = data[8];
329 const uint32_t fract = (data[9] << 7) | data[10];
330
331 int prog = 0; // data[2]
332 int key = data[7];
333 double pitch = note * 100.f + fract / 163.83;
334 if (data[11] == 0xf7) {
335 int rv = fluid_synth_tune_notes (self->synth,
336 /* tuning bank */ 0,
337 /* tuning prog */ prog,
338 1, &key, &pitch,
339 /* apply */ 1);
340 if (rv == FLUID_OK) {
341 for (int c = 0; c < 16; ++c) {
342 fluid_synth_activate_tuning (self->synth, c, 0, prog, 0);
343 }
344 self->inform_ui = true; // StateChanged
345 }
346 }
347 }
348 }
349
350 /* *****************************************************************************
351 * LV2 Plugin
352 */
353
354 static LV2_Handle
instantiate(const LV2_Descriptor * descriptor,double rate,const char * bundle_path,const LV2_Feature * const * features)355 instantiate (const LV2_Descriptor* descriptor,
356 double rate,
357 const char* bundle_path,
358 const LV2_Feature* const* features)
359 {
360 AFluidSynth* self = (AFluidSynth*)calloc (1, sizeof (AFluidSynth));
361
362 if (!self) {
363 return NULL;
364 }
365
366 LV2_URID_Map* map = NULL;
367
368 for (int i = 0; features[i] != NULL; ++i) {
369 if (!strcmp (features[i]->URI, LV2_URID__map)) {
370 map = (LV2_URID_Map*)features[i]->data;
371 } else if (!strcmp (features[i]->URI, LV2_LOG__log)) {
372 self->log = (LV2_Log_Log*)features[i]->data;
373 } else if (!strcmp (features[i]->URI, LV2_WORKER__schedule)) {
374 self->schedule = (LV2_Worker_Schedule*)features[i]->data;
375 #ifdef LV2_EXTENDED
376 } else if (!strcmp (features[i]->URI, LV2_MIDNAM__update)) {
377 self->midnam = (LV2_Midnam*)features[i]->data;
378 } else if (!strcmp (features[i]->URI, LV2_BANKPATCH__notify)) {
379 self->bankpatch = (LV2_BankPatch*)features[i]->data;
380 #endif
381 }
382 }
383
384 lv2_log_logger_init (&self->logger, map, self->log);
385
386 if (!map) {
387 lv2_log_error (&self->logger, "a-fluidsynth.lv2: Host does not support urid:map\n");
388 free (self);
389 return NULL;
390 }
391
392 if (!self->schedule) {
393 lv2_log_error (&self->logger, "a-fluidsynth.lv2: Host does not support worker:schedule\n");
394 free (self);
395 return NULL;
396 }
397
398 #ifdef LV2_EXTENDED
399 if (!self->midnam) {
400 lv2_log_warning (&self->logger, "a-fluidsynth.lv2: Host does not support midnam:update\n");
401 }
402
403 if (!self->bankpatch) {
404 lv2_log_warning (&self->logger, "a-fluidsynth.lv2: Host does not support bankpatch:notify\n");
405 }
406 #endif
407
408 /* initialize fluid synth */
409 self->settings = new_fluid_settings ();
410
411 if (!self->settings) {
412 lv2_log_error (&self->logger, "a-fluidsynth.lv2: cannot allocate Fluid Settings\n");
413 free (self);
414 return NULL;
415 }
416
417 fluid_settings_setnum (self->settings, "synth.sample-rate", rate);
418 fluid_settings_setint (self->settings, "synth.threadsafe-api", 0);
419 fluid_settings_setstr (self->settings, "synth.midi-bank-select", "mma");
420
421 self->synth = new_fluid_synth (self->settings);
422
423 if (!self->synth) {
424 lv2_log_error (&self->logger, "a-fluidsynth.lv2: cannot allocate Fluid Synth\n");
425 delete_fluid_settings (self->settings);
426 free (self);
427 return NULL;
428 }
429
430 fluid_synth_set_gain (self->synth, 1.0f);
431 fluid_synth_set_polyphony (self->synth, 256);
432 fluid_synth_set_sample_rate (self->synth, (float)rate);
433
434 fluid_synth_set_reverb_on (self->synth, 0);
435 fluid_synth_set_chorus_on (self->synth, 0);
436
437 self->fmidi_event = new_fluid_midi_event ();
438
439 if (!self->fmidi_event) {
440 lv2_log_error (&self->logger, "a-fluidsynth.lv2: cannot allocate Fluid Event\n");
441 delete_fluid_synth (self->synth);
442 delete_fluid_settings (self->settings);
443 free (self);
444 return NULL;
445 }
446
447 /* initialize plugin state */
448
449 pthread_mutex_init (&self->bp_lock, NULL);
450 #ifdef LV2_EXTENDED
451 self->presets = BPMap ();
452 #endif
453 self->panic = false;
454 self->inform_ui = false;
455 self->send_bankpgm = true;
456 self->initialized = false;
457 self->reinit_in_progress = false;
458 self->queue_reinit = false;
459 self->queue_retune = false;
460 for (int chn = 0; chn < 16; ++chn) {
461 self->program_state[chn].program = -1;
462 }
463
464 lv2_atom_forge_init (&self->forge, map);
465
466 /* map URIDs */
467 self->atom_Blank = map->map (map->handle, LV2_ATOM__Blank);
468 self->atom_Object = map->map (map->handle, LV2_ATOM__Object);
469 self->atom_Path = map->map (map->handle, LV2_ATOM__Path);
470 self->atom_Vector = map->map (map->handle, LV2_ATOM__Vector);
471 self->atom_Double = map->map (map->handle, LV2_ATOM__Double);
472 self->atom_URID = map->map (map->handle, LV2_ATOM__URID);
473 self->midi_MidiEvent = map->map (map->handle, LV2_MIDI__MidiEvent);
474 self->patch_Get = map->map (map->handle, LV2_PATCH__Get);
475 self->patch_Set = map->map (map->handle, LV2_PATCH__Set);
476 self->patch_property = map->map (map->handle, LV2_PATCH__property);
477 self->patch_value = map->map (map->handle, LV2_PATCH__value);
478 self->state_Changed = map->map (map->handle, "http://lv2plug.in/ns/ext/state#StateChanged");
479 self->afs_sf2file = map->map (map->handle, AFS_URN ":sf2file");
480 self->afs_tuning = map->map (map->handle, AFS_URN ":tuning");
481
482 return (LV2_Handle)self;
483 }
484
485 static void
connect_port(LV2_Handle instance,uint32_t port,void * data)486 connect_port (LV2_Handle instance,
487 uint32_t port,
488 void* data)
489 {
490 AFluidSynth* self = (AFluidSynth*)instance;
491
492 switch (port) {
493 case FS_PORT_CONTROL:
494 self->control = (const LV2_Atom_Sequence*)data;
495 break;
496 case FS_PORT_NOTIFY:
497 self->notify = (LV2_Atom_Sequence*)data;
498 break;
499 default:
500 if (port < FS_PORT_LAST) {
501 self->p_ports[port] = (float*)data;
502 }
503 break;
504 }
505 }
506
507 static void
deactivate(LV2_Handle instance)508 deactivate (LV2_Handle instance)
509 {
510 AFluidSynth* self = (AFluidSynth*)instance;
511
512 self->panic = true;
513 }
514
515 static void
run(LV2_Handle instance,uint32_t n_samples)516 run (LV2_Handle instance, uint32_t n_samples)
517 {
518 AFluidSynth* self = (AFluidSynth*)instance;
519
520 if (!self->control || !self->notify) {
521 return;
522 }
523
524 const uint32_t capacity = self->notify->atom.size;
525 lv2_atom_forge_set_buffer (&self->forge, (uint8_t*)self->notify, capacity);
526 lv2_atom_forge_sequence_head (&self->forge, &self->frame, 0);
527
528 const bool enabled = *self->p_ports[FS_PORT_ENABLE] > 0;
529 if (self->v_ports[FS_PORT_ENABLE] != *self->p_ports[FS_PORT_ENABLE]) {
530 if (self->initialized && !self->reinit_in_progress) {
531 fluid_synth_all_notes_off (self->synth, -1);
532 }
533 }
534
535 if (!self->initialized || self->reinit_in_progress) {
536 memset (self->p_ports[FS_PORT_OUT_L], 0, n_samples * sizeof (float));
537 memset (self->p_ports[FS_PORT_OUT_R], 0, n_samples * sizeof (float));
538 } else if (self->panic) {
539 fluid_synth_all_notes_off (self->synth, -1);
540 fluid_synth_all_sounds_off (self->synth, -1);
541 self->panic = false;
542 }
543
544 if (self->initialized && !self->reinit_in_progress) {
545 bool rev_change = false;
546 bool chr_change = false;
547 // TODO clamp values to ranges
548 if (self->v_ports[FS_OUT_GAIN] != *self->p_ports[FS_OUT_GAIN]) {
549 fluid_synth_set_gain (self->synth, db_to_coeff (*self->p_ports[FS_OUT_GAIN]));
550 }
551 if (self->v_ports[FS_REV_ENABLE] != *self->p_ports[FS_REV_ENABLE]) {
552 fluid_synth_set_reverb_on (self->synth, *self->p_ports[FS_REV_ENABLE] > 0 ? 1 : 0);
553 rev_change = true;
554 }
555 if (self->v_ports[FS_CHR_ENABLE] != *self->p_ports[FS_CHR_ENABLE]) {
556 fluid_synth_set_chorus_on (self->synth, *self->p_ports[FS_CHR_ENABLE] > 0 ? 1 : 0);
557 chr_change = true;
558 }
559
560 for (uint32_t p = FS_REV_ROOMSIZE; p <= FS_REV_LEVEL && !rev_change; ++p) {
561 if (self->v_ports[p] != *self->p_ports[p]) {
562 rev_change = true;
563 }
564 }
565 for (uint32_t p = FS_CHR_N; p <= FS_CHR_TYPE && !chr_change; ++p) {
566 if (self->v_ports[p] != *self->p_ports[p]) {
567 chr_change = true;
568 }
569 }
570
571 if (rev_change) {
572 fluid_synth_set_reverb (self->synth,
573 *self->p_ports[FS_REV_ROOMSIZE],
574 *self->p_ports[FS_REV_DAMPING],
575 *self->p_ports[FS_REV_WIDTH],
576 *self->p_ports[FS_REV_LEVEL]);
577 }
578
579 if (chr_change) {
580 fluid_synth_set_chorus (self->synth,
581 rintf (*self->p_ports[FS_CHR_N]),
582 db_to_coeff (*self->p_ports[FS_CHR_LEVEL]),
583 *self->p_ports[FS_CHR_SPEED],
584 *self->p_ports[FS_CHR_DEPTH],
585 (*self->p_ports[FS_CHR_TYPE] > 0) ? FLUID_CHORUS_MOD_SINE : FLUID_CHORUS_MOD_TRIANGLE);
586 }
587 for (uint32_t p = FS_OUT_GAIN; p < FS_PORT_LAST; ++p) {
588 self->v_ports[p] = *self->p_ports[p];
589 }
590 }
591
592 uint32_t offset = 0;
593
594 LV2_ATOM_SEQUENCE_FOREACH (self->control, ev)
595 {
596 const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
597 if (ev->body.type == self->atom_Blank || ev->body.type == self->atom_Object) {
598 if (obj->body.otype == self->patch_Get) {
599 self->inform_ui = false;
600 inform_ui (self);
601 } else if (obj->body.otype == self->patch_Set) {
602 const LV2_Atom* file_path = parse_patch_msg (self, obj);
603 if (file_path && !self->reinit_in_progress && !self->queue_reinit) {
604 const char* fn = (const char*)(file_path + 1);
605 strncpy (self->queue_sf2_file_path, fn, 1023);
606 self->queue_sf2_file_path[1023] = '\0';
607 self->reinit_in_progress = true;
608 int magic = 0x4711;
609 self->schedule->schedule_work (self->schedule->handle, sizeof (int), &magic);
610 }
611 }
612 } else if (ev->body.type == self->midi_MidiEvent) {
613 if (ev->time.frames >= n_samples || self->reinit_in_progress || !enabled) {
614 continue;
615 }
616 if (ev->body.size > 3) {
617 if (ev->body.size > 11) {
618 const uint8_t* const data = (const uint8_t*)(ev + 1);
619 if (data[0] == 0xf0 && (data[1] & 0x7e) == 0x7e && data[3] == 0x08) {
620 parse_mts (self, data, ev->body.size);
621 }
622 }
623 continue;
624 }
625
626 if (ev->time.frames > offset) {
627 fluid_synth_write_float (
628 self->synth,
629 ev->time.frames - offset,
630 &self->p_ports[FS_PORT_OUT_L][offset], 0, 1,
631 &self->p_ports[FS_PORT_OUT_R][offset], 0, 1);
632 }
633
634 offset = ev->time.frames;
635
636 const uint8_t* const data = (const uint8_t*)(ev + 1);
637 fluid_midi_event_set_type (self->fmidi_event, data[0] & 0xf0);
638 fluid_midi_event_set_channel (self->fmidi_event, data[0] & 0x0f);
639 if (ev->body.size > 1) {
640 fluid_midi_event_set_key (self->fmidi_event, data[1]);
641 }
642 if (ev->body.size > 2) {
643 if (0xe0 /*PITCH_BEND*/ == fluid_midi_event_get_type (self->fmidi_event)) {
644 fluid_midi_event_set_value (self->fmidi_event, 0);
645 fluid_midi_event_set_pitch (self->fmidi_event, ((data[2] & 0x7f) << 7) | (data[1] & 0x7f));
646 } else {
647 fluid_midi_event_set_value (self->fmidi_event, data[2]);
648 }
649 if (0xb0 /* CC */ == fluid_midi_event_get_type (self->fmidi_event)) {
650 int chn = fluid_midi_event_get_channel (self->fmidi_event);
651 assert (chn >= 0 && chn < 16);
652 if (data[1] == 0x00) {
653 self->program_state[chn].bank &= 0x7f;
654 self->program_state[chn].bank |= (data[2] & 0x7f) << 7;
655 }
656 if (data[1] == 0x20) {
657 self->program_state[chn].bank &= 0x3F80;
658 self->program_state[chn].bank |= data[2] & 0x7f;
659 }
660 }
661 }
662 if (ev->body.size == 2 && 0xc0 /* Pgm */ == fluid_midi_event_get_type (self->fmidi_event)) {
663 int chn = fluid_midi_event_get_channel (self->fmidi_event);
664 assert (chn >= 0 && chn < 16);
665 self->program_state[chn].program = data[1];
666 #ifdef LV2_EXTENDED
667 if (self->bankpatch) {
668 self->bankpatch->notify (self->bankpatch->handle, chn,
669 self->program_state[chn].bank,
670 self->program_state[chn].program < 0 ? 255 : self->program_state[chn].program);
671 }
672 #endif
673 }
674
675 fluid_synth_handle_midi_event (self->synth, self->fmidi_event);
676 }
677 }
678
679 if (self->queue_reinit && !self->reinit_in_progress) {
680 self->reinit_in_progress = true;
681 int magic = 0x4711;
682 self->schedule->schedule_work (self->schedule->handle, sizeof (int), &magic);
683 }
684
685 /* inform the GUI */
686 if (self->inform_ui) {
687 self->inform_ui = false;
688
689 /* emit stateChanged */
690 LV2_Atom_Forge_Frame frame;
691 lv2_atom_forge_frame_time (&self->forge, 0);
692 x_forge_object (&self->forge, &frame, 1, self->state_Changed);
693 lv2_atom_forge_pop (&self->forge, &frame);
694
695 /* send .sf2 filename */
696 inform_ui (self);
697
698 #ifdef LV2_EXTENDED
699 if (self->midnam)
700 self->midnam->update (self->midnam->handle);
701 #endif
702 }
703
704 #ifdef LV2_EXTENDED
705 if (self->send_bankpgm && self->bankpatch) {
706 self->send_bankpgm = false;
707 for (uint8_t chn = 0; chn < 16; ++chn) {
708 self->bankpatch->notify (self->bankpatch->handle, chn,
709 self->program_state[chn].bank,
710 self->program_state[chn].program < 0 ? 255 : self->program_state[chn].program);
711 }
712 }
713 #endif
714
715 if (n_samples > offset && self->initialized && !self->reinit_in_progress) {
716 fluid_synth_write_float (
717 self->synth,
718 n_samples - offset,
719 &self->p_ports[FS_PORT_OUT_L][offset], 0, 1,
720 &self->p_ports[FS_PORT_OUT_R][offset], 0, 1);
721 }
722 }
723
724 static void
cleanup(LV2_Handle instance)725 cleanup (LV2_Handle instance)
726 {
727 AFluidSynth* self = (AFluidSynth*)instance;
728 delete_fluid_synth (self->synth);
729 delete_fluid_settings (self->settings);
730 delete_fluid_midi_event (self->fmidi_event);
731 pthread_mutex_destroy (&self->bp_lock);
732 free (self);
733 }
734
735 /* *****************************************************************************
736 * LV2 Extensions
737 */
738
739 static LV2_Worker_Status
work(LV2_Handle instance,LV2_Worker_Respond_Function respond,LV2_Worker_Respond_Handle handle,uint32_t size,const void * data)740 work (LV2_Handle instance,
741 LV2_Worker_Respond_Function respond,
742 LV2_Worker_Respond_Handle handle,
743 uint32_t size,
744 const void* data)
745 {
746 AFluidSynth* self = (AFluidSynth*)instance;
747
748 if (size != sizeof (int)) {
749 return LV2_WORKER_ERR_UNKNOWN;
750 }
751 int magic = *((const int*)data);
752 if (magic != 0x4711) {
753 return LV2_WORKER_ERR_UNKNOWN;
754 }
755
756 self->initialized = load_sf2 (self, self->queue_sf2_file_path);
757
758 if (self->initialized) {
759 fluid_synth_all_notes_off (self->synth, -1);
760 fluid_synth_all_sounds_off (self->synth, -1);
761 self->panic = false;
762 // boostrap synth engine.
763 float l[1024];
764 float r[1024];
765 fluid_synth_write_float (self->synth, 1024, l, 0, 1, r, 0, 1);
766 }
767
768 respond (handle, 1, "");
769 return LV2_WORKER_SUCCESS;
770 }
771
772 struct VectorOfDouble {
773 LV2_Atom_Vector_Body vb;
774 double pitch[128];
775 };
776
777 static LV2_Worker_Status
work_response(LV2_Handle instance,uint32_t size,const void * data)778 work_response (LV2_Handle instance,
779 uint32_t size,
780 const void* data)
781 {
782 AFluidSynth* self = (AFluidSynth*)instance;
783
784 if (self->initialized) {
785 strcpy (self->current_sf2_file_path, self->queue_sf2_file_path);
786
787 for (int chn = 0; chn < 16; ++chn) {
788 if (self->program_state[chn].program < 0) {
789 continue;
790 }
791 /* cannot direcly call fluid_channel_set_bank_msb/fluid_channel_set_bank_lsb, use CCs */
792 fluid_midi_event_set_type (self->fmidi_event, 0xb0 /* CC */);
793 fluid_midi_event_set_channel (self->fmidi_event, chn);
794
795 fluid_midi_event_set_control (self->fmidi_event, 0x00); // BANK_SELECT_MSB
796 fluid_midi_event_set_value (self->fmidi_event, (self->program_state[chn].bank >> 7) & 0x7f);
797 fluid_synth_handle_midi_event (self->synth, self->fmidi_event);
798
799 fluid_midi_event_set_control (self->fmidi_event, 0x20); // BANK_SELECT_LSB
800 fluid_midi_event_set_value (self->fmidi_event, self->program_state[chn].bank & 0x7f);
801 fluid_synth_handle_midi_event (self->synth, self->fmidi_event);
802
803 fluid_synth_program_change (self->synth, chn, self->program_state[chn].program);
804 }
805
806 for (int chn = 0; chn < 16; ++chn) {
807 int sfid = 0;
808 int bank = 0;
809 int program = -1;
810 if (FLUID_OK == fluid_synth_get_program (self->synth, chn, &sfid, &bank, &program)) {
811 self->program_state[chn].bank = bank;
812 self->program_state[chn].program = program;
813 }
814 }
815 if (self->queue_retune) {
816 int rv = fluid_synth_activate_key_tuning (self->synth,
817 /* tuning bank */ 0,
818 /* tuning prog */ 0,
819 "ACE", self->queue_tuning, 0);
820 if (rv == FLUID_OK) {
821 for (int c = 0; c < 16; ++c) {
822 fluid_synth_activate_tuning (self->synth, c, 0, 0, 0);
823 }
824 }
825 }
826
827 } else {
828 self->current_sf2_file_path[0] = 0;
829 }
830
831 self->reinit_in_progress = false;
832 self->inform_ui = true;
833 self->send_bankpgm = true;
834 self->queue_retune = false;
835 self->queue_reinit = false;
836 return LV2_WORKER_SUCCESS;
837 }
838
839 static LV2_State_Status
save(LV2_Handle instance,LV2_State_Store_Function store,LV2_State_Handle handle,uint32_t flags,const LV2_Feature * const * features)840 save (LV2_Handle instance,
841 LV2_State_Store_Function store,
842 LV2_State_Handle handle,
843 uint32_t flags,
844 const LV2_Feature* const* features)
845 {
846 AFluidSynth* self = (AFluidSynth*)instance;
847
848 if (strlen (self->current_sf2_file_path) == 0) {
849 return LV2_STATE_ERR_NO_PROPERTY;
850 }
851
852 LV2_State_Map_Path* map_path = NULL;
853 #ifdef LV2_STATE__freePath
854 LV2_State_Free_Path* free_path = NULL;
855 #endif
856
857 for (int i = 0; features[i]; ++i) {
858 if (!strcmp (features[i]->URI, LV2_STATE__mapPath)) {
859 map_path = (LV2_State_Map_Path*)features[i]->data;
860 }
861 }
862
863 if (!map_path) {
864 return LV2_STATE_ERR_NO_FEATURE;
865 }
866
867 char* apath = map_path->abstract_path (map_path->handle, self->current_sf2_file_path);
868 store (handle, self->afs_sf2file,
869 apath, strlen (apath) + 1,
870 self->atom_Path, LV2_STATE_IS_POD);
871 #ifdef LV2_STATE__freePath
872 if (free_path) {
873 free_path->free_path (free_path->handle, apath);
874 } else
875 #endif
876 {
877 #ifndef _WIN32 // https://github.com/drobilla/lilv/issues/14
878 free (apath);
879 #endif
880 }
881
882 int tbank, tprog;
883 fluid_synth_tuning_iteration_start (self->synth);
884 if (0 != fluid_synth_tuning_iteration_next (self->synth, &tbank, &tprog)) {
885 VectorOfDouble vod;
886 vod.vb.child_type = self->atom_Double;
887 vod.vb.child_size = sizeof (double);
888 fluid_synth_tuning_dump (self->synth, tbank, tprog, NULL, 0, vod.pitch);
889 store (handle, self->afs_tuning,
890 (void*)&vod, sizeof (LV2_Atom_Vector_Body) + 128 * sizeof (double),
891 self->atom_Vector,
892 LV2_STATE_IS_POD);
893 }
894
895 return LV2_STATE_SUCCESS;
896 }
897
898 static LV2_State_Status
restore(LV2_Handle instance,LV2_State_Retrieve_Function retrieve,LV2_State_Handle handle,uint32_t flags,const LV2_Feature * const * features)899 restore (LV2_Handle instance,
900 LV2_State_Retrieve_Function retrieve,
901 LV2_State_Handle handle,
902 uint32_t flags,
903 const LV2_Feature* const* features)
904 {
905 AFluidSynth* self = (AFluidSynth*)instance;
906 if (self->reinit_in_progress || self->queue_reinit) {
907 lv2_log_warning (&self->logger, "a-fluidsynth.lv2: sf2 load already queued.\n");
908 return LV2_STATE_ERR_UNKNOWN;
909 }
910
911 LV2_State_Map_Path* map_path = NULL;
912 #ifdef LV2_STATE__freePath
913 LV2_State_Free_Path* free_path = NULL;
914 #endif
915
916 for (int i = 0; features[i]; ++i) {
917 if (!strcmp (features[i]->URI, LV2_STATE__mapPath)) {
918 map_path = (LV2_State_Map_Path*)features[i]->data;
919 }
920 #ifdef LV2_STATE__freePath
921 else if (!strcmp (features[i]->URI, LV2_STATE__freePath)) {
922 free_path = (LV2_State_Free_Path*)features[i]->data;
923 }
924 #endif
925 }
926
927 if (!map_path) {
928 return LV2_STATE_ERR_NO_FEATURE;
929 }
930
931 size_t size;
932 uint32_t type;
933 uint32_t valflags;
934
935 const void* value = retrieve (handle, self->afs_sf2file, &size, &type, &valflags);
936 if (!value) {
937 return LV2_STATE_ERR_NO_PROPERTY;
938 }
939
940 char* apath = map_path->absolute_path (map_path->handle, (const char*)value);
941 strncpy (self->queue_sf2_file_path, apath, 1023);
942 self->queue_sf2_file_path[1023] = '\0';
943 self->queue_reinit = true;
944 #ifdef LV2_STATE__freePath
945 if (free_path) {
946 free_path->free_path (free_path->handle, apath);
947 } else
948 #endif
949 {
950 #ifndef _WIN32 // https://github.com/drobilla/lilv/issues/14
951 free (apath);
952 #endif
953 }
954
955 value = retrieve (handle, self->afs_tuning, &size, &type, &valflags);
956 if (value && size == sizeof (LV2_Atom_Vector_Body) + 128 * sizeof (double) && type == self->atom_Vector) {
957 memcpy (self->queue_tuning, LV2_ATOM_BODY (value), 128 * sizeof (double));
958 self->queue_retune = true;
959 }
960
961 return LV2_STATE_SUCCESS;
962 }
963
964 static std::string
xml_escape(const std::string & s)965 xml_escape (const std::string& s)
966 {
967 std::string r (s);
968 std::replace (r.begin (), r.end (), '"', '\'');
969 size_t pos = 0;
970 while ((pos = r.find ("&", pos)) != std::string::npos) {
971 r.replace (pos, 1, "&");
972 pos += 4;
973 }
974 return r;
975 }
976
977 #ifdef LV2_EXTENDED
978 static char*
mn_file(LV2_Handle instance)979 mn_file (LV2_Handle instance)
980 {
981 AFluidSynth* self = (AFluidSynth*)instance;
982 char* rv = NULL;
983 char tmp[1024];
984
985 rv = (char*)calloc (1, sizeof (char));
986
987 #define pf(...) \
988 do { \
989 snprintf (tmp, sizeof (tmp), __VA_ARGS__); \
990 tmp[sizeof (tmp) - 1] = '\0'; \
991 rv = (char*)realloc (rv, strlen (rv) + strlen (tmp) + 1); \
992 strcat (rv, tmp); \
993 } while (0)
994
995 pf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
996 "<!DOCTYPE MIDINameDocument PUBLIC \"-//MIDI Manufacturers Association//DTD MIDINameDocument 1.0//EN\" \"http://dev.midi.org/dtds/MIDINameDocument10.dtd\">\n"
997 "<MIDINameDocument>\n"
998 " <Author/>\n"
999 " <MasterDeviceNames>\n"
1000 " <Manufacturer>Ardour Foundation</Manufacturer>\n"
1001 " <Model>%s:%p</Model>\n",
1002 AFS_URN, (void*)self);
1003
1004 pf (" <CustomDeviceMode Name=\"Default\">\n");
1005 pf (" <ChannelNameSetAssignments>\n");
1006 for (int c = 0; c < 16; ++c) {
1007 pf (" <ChannelNameSetAssign Channel=\"%d\" NameSet=\"Presets\"/>\n", c + 1);
1008 }
1009 pf (" </ChannelNameSetAssignments>\n");
1010 pf (" </CustomDeviceMode>\n");
1011
1012 // TODO collect used banks, std::set<> would be a nice here
1013
1014 pf (" <ChannelNameSet Name=\"Presets\">\n");
1015 pf (" <AvailableForChannels>\n");
1016 for (int c = 0; c < 16; ++c) {
1017 pf (" <AvailableChannel Channel=\"%d\" Available=\"true\"/>\n", c + 1);
1018 }
1019 pf (" </AvailableForChannels>\n");
1020 pf (" <UsesControlNameList Name=\"Controls\"/>\n");
1021
1022 int bn = 1;
1023 pthread_mutex_lock (&self->bp_lock);
1024 const BPMap& ps (self->presets);
1025 pthread_mutex_unlock (&self->bp_lock);
1026
1027 for (BPMap::const_iterator i = ps.begin (); i != ps.end (); ++i, ++bn) {
1028 pf (" <PatchBank Name=\"Patch Bank %d\">\n", i->first);
1029 if (i->second.size () > 0) {
1030 pf (" <MIDICommands>\n");
1031 pf (" <ControlChange Control=\"0\" Value=\"%d\"/>\n", (i->first >> 7) & 127);
1032 pf (" <ControlChange Control=\"32\" Value=\"%d\"/>\n", i->first & 127);
1033 pf (" </MIDICommands>\n");
1034 pf (" <PatchNameList>\n");
1035 int n = 0;
1036 for (BPList::const_iterator j = i->second.begin (); j != i->second.end (); ++j, ++n) {
1037 pf (" <Patch Number=\"%d\" Name=\"%s\" ProgramChange=\"%d\"/>\n",
1038 n, xml_escape (j->name).c_str (), j->program);
1039 }
1040 pf (" </PatchNameList>\n");
1041 }
1042 pf (" </PatchBank>\n");
1043 }
1044 pf (" </ChannelNameSet>\n");
1045
1046 pf (" <ControlNameList Name=\"Controls\">\n");
1047 pf (" <Control Type=\"7bit\" Number=\"1\" Name=\"Modulation\"/>\n");
1048 pf (" <Control Type=\"7bit\" Number=\"2\" Name=\"Breath\"/>\n");
1049 pf (" <Control Type=\"7bit\" Number=\"5\" Name=\"Portamento Time\"/>\n");
1050 pf (" <Control Type=\"7bit\" Number=\"7\" Name=\"Channel Volume\"/>\n");
1051 pf (" <Control Type=\"7bit\" Number=\"8\" Name=\"Stereo Balance\"/>\n");
1052 pf (" <Control Type=\"7bit\" Number=\"10\" Name=\"Pan\"/>\n");
1053 pf (" <Control Type=\"7bit\" Number=\"11\" Name=\"Expression\"/>\n");
1054 pf (" <Control Type=\"7bit\" Number=\"37\" Name=\"Portamento Time (Fine)\"/>\n");
1055 pf (" <Control Type=\"7bit\" Number=\"64\" Name=\"Sustain On/Off\"/>\n");
1056 pf (" <Control Type=\"7bit\" Number=\"65\" Name=\"Portamento On/Off\"/>\n");
1057 pf (" <Control Type=\"7bit\" Number=\"66\" Name=\"Sostenuto On/Off\"/>\n");
1058 pf (" <Control Type=\"7bit\" Number=\"68\" Name=\"Legato On/Off\"/>\n");
1059 pf (" <Control Type=\"7bit\" Number=\"91\" Name=\"Reverb\"/>\n");
1060 pf (" <Control Type=\"7bit\" Number=\"93\" Name=\"Chorus\"/>\n");
1061 pf (" </ControlNameList>\n");
1062
1063 pf (
1064 " </MasterDeviceNames>\n"
1065 "</MIDINameDocument>");
1066
1067 //printf("-----\n%s\n------\n", rv);
1068 return rv;
1069 }
1070
1071 static char*
mn_model(LV2_Handle instance)1072 mn_model (LV2_Handle instance)
1073 {
1074 AFluidSynth* self = (AFluidSynth*)instance;
1075 char* rv = (char*)malloc (64 * sizeof (char));
1076 snprintf (rv, 64, "%s:%p", AFS_URN, (void*)self);
1077 rv[63] = 0;
1078 return rv;
1079 }
1080
1081 static void
mn_free(char * v)1082 mn_free (char* v)
1083 {
1084 free (v);
1085 }
1086 #endif
1087
1088 static const void*
extension_data(const char * uri)1089 extension_data (const char* uri)
1090 {
1091 if (!strcmp (uri, LV2_WORKER__interface)) {
1092 static const LV2_Worker_Interface worker = { work, work_response, NULL };
1093 return &worker;
1094 } else if (!strcmp (uri, LV2_STATE__interface)) {
1095 static const LV2_State_Interface state = { save, restore };
1096 return &state;
1097 }
1098 #ifdef LV2_EXTENDED
1099 else if (!strcmp (uri, LV2_MIDNAM__interface)) {
1100 static const LV2_Midnam_Interface midnam = { mn_file, mn_model, mn_free };
1101 return &midnam;
1102 }
1103 #endif
1104 return NULL;
1105 }
1106
1107 static const LV2_Descriptor descriptor = {
1108 AFS_URN,
1109 instantiate,
1110 connect_port,
1111 NULL,
1112 run,
1113 deactivate,
1114 cleanup,
1115 extension_data
1116 };
1117
1118 #undef LV2_SYMBOL_EXPORT
1119 #ifdef _WIN32
1120 # define LV2_SYMBOL_EXPORT __declspec(dllexport)
1121 #else
1122 # define LV2_SYMBOL_EXPORT __attribute__ ((visibility ("default")))
1123 #endif
1124 LV2_SYMBOL_EXPORT
1125 const LV2_Descriptor*
lv2_descriptor(uint32_t index)1126 lv2_descriptor (uint32_t index)
1127 {
1128 switch (index) {
1129 case 0:
1130 return &descriptor;
1131 default:
1132 return NULL;
1133 }
1134 }
1135