Expose CCs that fluidsynth uses by default in midnam
[ardour.git] / libs / plugins / a-fluidsynth.lv2 / a-fluidsynth.cc
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 <cstring>
24 #include <string>
25 #include <algorithm>
26 #include <map>
27 #include <vector>
28
29 #include <pthread.h>
30 #include <stdlib.h>
31 #include <math.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/lv2core/lv2.h>
48 #include <lv2/lv2plug.in/ns/ext/atom/atom.h>
49 #include <lv2/lv2plug.in/ns/ext/atom/forge.h>
50 #include <lv2/lv2plug.in/ns/ext/atom/util.h>
51 #include <lv2/lv2plug.in/ns/ext/log/logger.h>
52 #include <lv2/lv2plug.in/ns/ext/midi/midi.h>
53 #include <lv2/lv2plug.in/ns/ext/patch/patch.h>
54 #include <lv2/lv2plug.in/ns/ext/state/state.h>
55 #include <lv2/lv2plug.in/ns/ext/urid/urid.h>
56 #include <lv2/lv2plug.in/ns/ext/worker/worker.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_LAST
76 };
77
78 enum {
79   CMD_APPLY    = 0,
80   CMD_FREE     = 1,
81 };
82
83 struct BankProgram {
84         BankProgram (const std::string& n, int b, int p)
85                 : name (n)
86                 , bank (b)
87                 , program (p)
88         {}
89
90         BankProgram (const BankProgram& other)
91                 : name (other.name)
92                 , bank (other.bank)
93                 , program (other.program)
94         {}
95
96         std::string name;
97         int bank;
98         int program;
99 };
100
101 typedef std::vector<BankProgram> BPList;
102 typedef std::map<int, BPList> BPMap;
103 typedef std::map<int, BankProgram> BPState;
104
105 typedef struct {
106         /* ports */
107         const LV2_Atom_Sequence* control;
108   LV2_Atom_Sequence*       notify;
109
110         float* p_ports[FS_PORT_LAST];
111         float  v_ports[FS_PORT_LAST];
112
113         /* fluid synth */
114         fluid_settings_t* settings;
115         fluid_synth_t*    synth;
116         int               synthId;
117
118         /* lv2 URIDs */
119         LV2_URID atom_Blank;
120         LV2_URID atom_Object;
121         LV2_URID atom_URID;
122         LV2_URID atom_Path;
123         LV2_URID midi_MidiEvent;
124         LV2_URID patch_Get;
125         LV2_URID patch_Set;
126         LV2_URID patch_property;
127         LV2_URID patch_value;
128         LV2_URID state_Changed;
129         LV2_URID afs_sf2file;
130
131         /* lv2 extensions */
132         LV2_Log_Log*         log;
133         LV2_Log_Logger       logger;
134   LV2_Worker_Schedule* schedule;
135         LV2_Atom_Forge       forge;
136         LV2_Atom_Forge_Frame frame;
137
138 #ifdef LV2_EXTENDED
139         LV2_Midnam*          midnam;
140         LV2_BankPatch*       bankpatch;
141         BPMap                presets;
142 #endif
143         pthread_mutex_t      bp_lock;
144
145         /* state */
146         bool panic;
147         bool initialized;
148         bool inform_ui;
149         bool send_bankpgm;
150
151         char current_sf2_file_path[1024];
152         char queue_sf2_file_path[1024];
153         bool reinit_in_progress; // set in run, cleared in work_response
154         bool queue_reinit; // set in restore, cleared in work_response
155
156         BankProgram program_state[16];
157
158         fluid_midi_event_t* fmidi_event;
159
160 } AFluidSynth;
161
162 /* *****************************************************************************
163  * helpers
164  */
165
166 static bool
167 load_sf2 (AFluidSynth* self, const char* fn)
168 {
169         const int synth_id = fluid_synth_sfload (self->synth, fn, 1);
170
171 #ifdef LV2_EXTENDED
172         pthread_mutex_lock (&self->bp_lock);
173         self->presets.clear ();
174         pthread_mutex_unlock (&self->bp_lock);
175 #endif
176
177         if (synth_id == FLUID_FAILED) {
178                 return false;
179         }
180
181         fluid_sfont_t* const sfont = fluid_synth_get_sfont_by_id (self->synth, synth_id);
182         if (!sfont) {
183                 return false;
184         }
185
186         int chn;
187         fluid_preset_t *preset;
188         fluid_sfont_iteration_start (sfont);
189         pthread_mutex_lock (&self->bp_lock);
190         for (chn = 0; (preset = fluid_sfont_iteration_next (sfont)); ++chn) {
191                 if (chn < 16) {
192                         fluid_synth_program_select (self->synth, chn, synth_id,
193                                         fluid_preset_get_banknum (preset), fluid_preset_get_num (preset));
194                 }
195 #ifndef LV2_EXTENDED
196                 else { break ; }
197 #else
198                 self->presets[fluid_preset_get_banknum (preset)].push_back (
199                                 BankProgram (
200                                         fluid_preset_get_name (preset),
201                                         fluid_preset_get_banknum (preset),
202                                         fluid_preset_get_num (preset)));
203 #endif // LV2_EXTENDED
204         }
205         pthread_mutex_unlock (&self->bp_lock);
206
207         if (chn == 0) {
208                 return false;
209         }
210
211         return true;
212 }
213
214 static const LV2_Atom*
215 parse_patch_msg (AFluidSynth* self, const LV2_Atom_Object* obj)
216 {
217         const LV2_Atom* property = NULL;
218         const LV2_Atom* file_path = NULL;
219
220         if (obj->body.otype != self->patch_Set) {
221                 return NULL;
222         }
223
224         lv2_atom_object_get (obj, self->patch_property, &property, 0);
225         if (!property || property->type != self->atom_URID) {
226                 return NULL;
227         } else if (((const LV2_Atom_URID*)property)->body != self->afs_sf2file) {
228                 return NULL;
229         }
230
231         lv2_atom_object_get (obj, self->patch_value, &file_path, 0);
232         if (!file_path || file_path->type != self->atom_Path) {
233                 return NULL;
234         }
235
236         return file_path;
237 }
238
239 static void
240 inform_ui (AFluidSynth* self)
241 {
242         if (strlen (self->current_sf2_file_path) == 0) {
243                 return;
244         }
245
246         LV2_Atom_Forge_Frame frame;
247         lv2_atom_forge_frame_time (&self->forge, 0);
248         x_forge_object (&self->forge, &frame, 1, self->patch_Set);
249         lv2_atom_forge_property_head (&self->forge, self->patch_property, 0);
250         lv2_atom_forge_urid (&self->forge, self->afs_sf2file);
251         lv2_atom_forge_property_head (&self->forge, self->patch_value, 0);
252         lv2_atom_forge_path (&self->forge, self->current_sf2_file_path, strlen (self->current_sf2_file_path));
253
254         lv2_atom_forge_pop (&self->forge, &frame);
255 }
256
257 static float
258 db_to_coeff (float db)
259 {
260         if (db <= -80) { return 0; }
261         else if (db >=  20) { return 10; }
262         return powf (10.f, .05f * db);
263 }
264
265 /* *****************************************************************************
266  * LV2 Plugin
267  */
268
269 static LV2_Handle
270 instantiate (const LV2_Descriptor*     descriptor,
271              double                    rate,
272              const char*               bundle_path,
273              const LV2_Feature* const* features)
274 {
275         AFluidSynth* self = (AFluidSynth*)calloc (1, sizeof (AFluidSynth));
276
277         if (!self) {
278                 return NULL;
279         }
280
281         LV2_URID_Map* map = NULL;
282
283         for (int i=0; features[i] != NULL; ++i) {
284                 if (!strcmp (features[i]->URI, LV2_URID__map)) {
285                         map = (LV2_URID_Map*)features[i]->data;
286                 } else if (!strcmp (features[i]->URI, LV2_LOG__log)) {
287                         self->log = (LV2_Log_Log*)features[i]->data;
288                 } else if (!strcmp (features[i]->URI, LV2_WORKER__schedule)) {
289                         self->schedule = (LV2_Worker_Schedule*)features[i]->data;
290 #ifdef LV2_EXTENDED
291                 } else if (!strcmp (features[i]->URI, LV2_MIDNAM__update)) {
292                         self->midnam = (LV2_Midnam*)features[i]->data;
293                 } else if (!strcmp (features[i]->URI, LV2_BANKPATCH__notify)) {
294                         self->bankpatch = (LV2_BankPatch*)features[i]->data;
295 #endif
296                 }
297         }
298
299         lv2_log_logger_init (&self->logger, map, self->log);
300
301         if (!map) {
302                 lv2_log_error (&self->logger, "a-fluidsynth.lv2: Host does not support urid:map\n");
303                 free (self);
304                 return NULL;
305         }
306
307         if (!self->schedule) {
308                 lv2_log_error (&self->logger, "a-fluidsynth.lv2: Host does not support worker:schedule\n");
309                 free (self);
310                 return NULL;
311         }
312
313         /* initialize fluid synth */
314         self->settings = new_fluid_settings ();
315
316         if (!self->settings) {
317                 lv2_log_error (&self->logger, "a-fluidsynth.lv2: cannot allocate Fluid Settings\n");
318                 free (self);
319                 return NULL;
320         }
321
322         fluid_settings_setnum (self->settings, "synth.sample-rate", rate);
323         fluid_settings_setint (self->settings, "synth.threadsafe-api", 0);
324         fluid_settings_setstr (self->settings, "synth.midi-bank-select", "mma");
325
326         self->synth = new_fluid_synth (self->settings);
327
328         if (!self->synth) {
329                 lv2_log_error (&self->logger, "a-fluidsynth.lv2: cannot allocate Fluid Synth\n");
330     delete_fluid_settings (self->settings);
331                 free (self);
332                 return NULL;
333         }
334
335         fluid_synth_set_gain (self->synth, 1.0f);
336         fluid_synth_set_polyphony (self->synth, 32);
337         fluid_synth_set_sample_rate (self->synth, (float)rate);
338
339         fluid_synth_set_reverb_on (self->synth, 0);
340         fluid_synth_set_chorus_on (self->synth, 0);
341
342         self->fmidi_event = new_fluid_midi_event ();
343
344         if (!self->fmidi_event) {
345                 lv2_log_error (&self->logger, "a-fluidsynth.lv2: cannot allocate Fluid Event\n");
346                 delete_fluid_synth (self->synth);
347     delete_fluid_settings (self->settings);
348                 free (self);
349                 return NULL;
350         }
351
352         /* initialize plugin state */
353
354         pthread_mutex_init (&self->bp_lock, NULL);
355 #ifdef LV2_EXTENDED
356         self->presets = BPMap();
357 #endif
358         self->panic = false;
359         self->inform_ui = false;
360         self->send_bankpgm = true;
361         self->initialized = false;
362         self->reinit_in_progress = false;
363         self->queue_reinit = false;
364         for (int chn = 0; chn < 16; ++chn) {
365                 self->program_state[chn].program = -1;
366         }
367
368         lv2_atom_forge_init (&self->forge, map);
369
370         /* map URIDs */
371         self->atom_Blank         = map->map (map->handle, LV2_ATOM__Blank);
372         self->atom_Object        = map->map (map->handle, LV2_ATOM__Object);
373         self->atom_Path          = map->map (map->handle, LV2_ATOM__Path);
374         self->atom_URID          = map->map (map->handle, LV2_ATOM__URID);
375         self->midi_MidiEvent     = map->map (map->handle, LV2_MIDI__MidiEvent);
376         self->patch_Get          = map->map (map->handle, LV2_PATCH__Get);
377         self->patch_Set          = map->map (map->handle, LV2_PATCH__Set);
378         self->patch_property     = map->map (map->handle, LV2_PATCH__property);
379         self->patch_value        = map->map (map->handle, LV2_PATCH__value);
380         self->state_Changed      = map->map (map->handle, "http://lv2plug.in/ns/ext/state#StateChanged");
381         self->afs_sf2file        = map->map (map->handle, AFS_URN ":sf2file");
382
383         return (LV2_Handle)self;
384 }
385
386 static void
387 connect_port (LV2_Handle instance,
388               uint32_t   port,
389               void*      data)
390 {
391         AFluidSynth* self = (AFluidSynth*)instance;
392
393         switch (port) {
394                 case FS_PORT_CONTROL:
395                         self->control = (const LV2_Atom_Sequence*)data;
396                         break;
397                 case FS_PORT_NOTIFY:
398                         self->notify = (LV2_Atom_Sequence*)data;
399                         break;
400                 default:
401                         if (port < FS_PORT_LAST) {
402                                 self->p_ports[port] = (float*)data;
403                         }
404                         break;
405         }
406 }
407
408 static void
409 deactivate (LV2_Handle instance)
410 {
411         AFluidSynth* self = (AFluidSynth*)instance;
412         self->panic = true;
413 }
414
415 static void
416 run (LV2_Handle instance, uint32_t n_samples)
417 {
418         AFluidSynth* self = (AFluidSynth*)instance;
419
420         if (!self->control || !self->notify) {
421                 return;
422         }
423
424         const uint32_t capacity = self->notify->atom.size;
425         lv2_atom_forge_set_buffer (&self->forge, (uint8_t*)self->notify, capacity);
426         lv2_atom_forge_sequence_head (&self->forge, &self->frame, 0);
427
428         if (!self->initialized || self->reinit_in_progress) {
429                 memset (self->p_ports[FS_PORT_OUT_L], 0, n_samples * sizeof (float));
430                 memset (self->p_ports[FS_PORT_OUT_R], 0, n_samples * sizeof (float));
431         } else if (self->panic) {
432                 fluid_synth_all_notes_off (self->synth, -1);
433                 fluid_synth_all_sounds_off (self->synth, -1);
434                 self->panic = false;
435         }
436
437         if (self->initialized && !self->reinit_in_progress) {
438                 bool rev_change = false;
439                 bool chr_change = false;
440                 // TODO clamp values to ranges
441                 if (self->v_ports[FS_OUT_GAIN] != *self->p_ports[FS_OUT_GAIN]) {
442                         fluid_synth_set_gain (self->synth, db_to_coeff (*self->p_ports[FS_OUT_GAIN]));
443                 }
444                 if (self->v_ports[FS_REV_ENABLE] != *self->p_ports[FS_REV_ENABLE]) {
445                         fluid_synth_set_reverb_on (self->synth, *self->p_ports[FS_REV_ENABLE] > 0 ? 1 : 0);
446                         rev_change = true;
447                 }
448                 if (self->v_ports[FS_CHR_ENABLE] != *self->p_ports[FS_CHR_ENABLE]) {
449                         fluid_synth_set_chorus_on (self->synth, *self->p_ports[FS_CHR_ENABLE] > 0 ? 1 : 0);
450                         chr_change = true;
451                 }
452
453                 for (uint32_t p = FS_REV_ROOMSIZE; p <= FS_REV_LEVEL && !rev_change; ++p) {
454                         if (self->v_ports[p] != *self->p_ports[p]) {
455                                 rev_change = true;
456                         }
457                 }
458                 for (uint32_t p = FS_CHR_N; p <= FS_CHR_TYPE && !chr_change; ++p) {
459                         if (self->v_ports[p] != *self->p_ports[p]) {
460                                 chr_change = true;
461                         }
462                 }
463
464                 if (rev_change) {
465                         fluid_synth_set_reverb (self->synth,
466                                         *self->p_ports[FS_REV_ROOMSIZE],
467                                         *self->p_ports[FS_REV_DAMPING],
468                                         *self->p_ports[FS_REV_WIDTH],
469                                         *self->p_ports[FS_REV_LEVEL]);
470                 }
471
472                 if (chr_change) {
473                         fluid_synth_set_chorus (self->synth,
474                                         rintf (*self->p_ports[FS_CHR_N]),
475                                         db_to_coeff (*self->p_ports[FS_CHR_LEVEL]),
476                                         *self->p_ports[FS_CHR_SPEED],
477                                         *self->p_ports[FS_CHR_DEPTH],
478                                         (*self->p_ports[FS_CHR_TYPE] > 0) ? FLUID_CHORUS_MOD_SINE : FLUID_CHORUS_MOD_TRIANGLE);
479                 }
480                 for (uint32_t p = FS_OUT_GAIN; p < FS_PORT_LAST; ++p) {
481                         self->v_ports[p] = *self->p_ports[p];
482                 }
483         }
484
485         uint32_t offset = 0;
486
487         LV2_ATOM_SEQUENCE_FOREACH (self->control, ev) {
488                 const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
489                 if (ev->body.type == self->atom_Blank || ev->body.type == self->atom_Object) {
490                         if (obj->body.otype == self->patch_Get) {
491                                 self->inform_ui = false;
492                                 inform_ui (self);
493                         }
494                         else if (obj->body.otype == self->patch_Set) {
495                                 const LV2_Atom* file_path = parse_patch_msg (self, obj);
496                                 if (file_path && !self->reinit_in_progress && !self->queue_reinit) {
497                                         const char *fn = (const char*)(file_path+1);
498                                         strncpy (self->queue_sf2_file_path, fn, 1023);
499                                         self->queue_sf2_file_path[1023] = '\0';
500                                         self->reinit_in_progress = true;
501                                         int magic = 0x4711;
502                                         self->schedule->schedule_work (self->schedule->handle, sizeof (int), &magic);
503                                 }
504                         }
505                 }
506                 else if (ev->body.type == self->midi_MidiEvent) {
507                         if (ev->body.size > 3 || ev->time.frames >= n_samples) {
508                                 continue;
509                         }
510
511                         if (ev->time.frames > offset) {
512                                 fluid_synth_write_float (
513                                                 self->synth,
514                                                 ev->time.frames - offset,
515                                                 &self->p_ports[FS_PORT_OUT_L][offset], 0, 1,
516                                                 &self->p_ports[FS_PORT_OUT_R][offset], 0, 1);
517                         }
518
519                         offset = ev->time.frames;
520
521                         const uint8_t* const data = (const uint8_t*)(ev + 1);
522                         fluid_midi_event_set_type (self->fmidi_event, data[0] & 0xf0);
523                         fluid_midi_event_set_channel (self->fmidi_event, data[0] & 0x0f);
524                         if (ev->body.size > 1) {
525                                 fluid_midi_event_set_key (self->fmidi_event, data[1]);
526                         }
527                         if (ev->body.size > 2) {
528                                 if (0xe0 /*PITCH_BEND*/ == fluid_midi_event_get_type (self->fmidi_event)) {
529                                         fluid_midi_event_set_value (self->fmidi_event, 0);
530                                         fluid_midi_event_set_pitch (self->fmidi_event, ((data[2] & 0x7f) << 7) | (data[1] & 0x7f));
531                                 } else {
532                                         fluid_midi_event_set_value (self->fmidi_event, data[2]);
533                                 }
534                                 if (0xb0 /* CC */ == fluid_midi_event_get_type (self->fmidi_event)) {
535                                         int chn = fluid_midi_event_get_channel (self->fmidi_event);
536                                         assert (chn >= 0 && chn < 16);
537                                         if (data[1] == 0x00) {
538                                                 self->program_state[chn].bank &= 0x7f;
539                                                 self->program_state[chn].bank |= (data[2] &0x7f) << 7;
540                                         }
541                                         if (data[1] == 0x20) {
542                                                 self->program_state[chn].bank &= 0x3F80;
543                                                 self->program_state[chn].bank |= data[2] & 0x7f;
544                                         }
545                                 }
546                         }
547                         if (ev->body.size == 2 && 0xc0 /* Pgm */ == fluid_midi_event_get_type (self->fmidi_event)) {
548                                 int chn = fluid_midi_event_get_channel (self->fmidi_event);
549                                 assert (chn >= 0 && chn < 16);
550                                 self->program_state[chn].program = data[1];
551 #ifdef LV2_EXTENDED
552                                 if (self->bankpatch) {
553                                         self->bankpatch->notify (self->bankpatch->handle, chn,
554                                                         self->program_state[chn].bank,
555                                                         self->program_state[chn].program < 0 ? 255 : self->program_state[chn].program);
556                                 }
557 #endif
558                         }
559
560                         fluid_synth_handle_midi_event (self->synth, self->fmidi_event);
561                 }
562         }
563
564         if (self->queue_reinit && !self->reinit_in_progress) {
565                 self->reinit_in_progress = true;
566                 int magic = 0x4711;
567                 self->schedule->schedule_work (self->schedule->handle, sizeof (int), &magic);
568         }
569
570         /* inform the GUI */
571         if (self->inform_ui) {
572                 self->inform_ui = false;
573
574                 /* emit stateChanged */
575                 LV2_Atom_Forge_Frame frame;
576                 lv2_atom_forge_frame_time(&self->forge, 0);
577                 x_forge_object(&self->forge, &frame, 1, self->state_Changed);
578                 lv2_atom_forge_pop(&self->forge, &frame);
579
580                 /* send .sf2 filename */
581                 inform_ui (self);
582
583 #ifdef LV2_EXTENDED
584                 self->midnam->update (self->midnam->handle);
585 #endif
586         }
587
588 #ifdef LV2_EXTENDED
589         if (self->send_bankpgm && self->bankpatch) {
590                 self->send_bankpgm = false;
591                 for (uint8_t chn = 0; chn < 16; ++chn) {
592                         self->bankpatch->notify (self->bankpatch->handle, chn,
593                                         self->program_state[chn].bank,
594                                         self->program_state[chn].program < 0 ? 255 : self->program_state[chn].program);
595                 }
596         }
597 #endif
598
599         if (n_samples > offset && self->initialized && !self->reinit_in_progress) {
600                 fluid_synth_write_float (
601                                 self->synth,
602                                 n_samples - offset,
603                                 &self->p_ports[FS_PORT_OUT_L][offset], 0, 1,
604                                 &self->p_ports[FS_PORT_OUT_R][offset], 0, 1);
605         }
606 }
607
608 static void cleanup (LV2_Handle instance)
609 {
610         AFluidSynth* self = (AFluidSynth*)instance;
611         delete_fluid_synth (self->synth);
612         delete_fluid_settings (self->settings);
613         delete_fluid_midi_event (self->fmidi_event);
614         pthread_mutex_destroy (&self->bp_lock);
615         free (self);
616 }
617
618 /* *****************************************************************************
619  * LV2 Extensions
620  */
621
622 static LV2_Worker_Status
623 work (LV2_Handle                  instance,
624       LV2_Worker_Respond_Function respond,
625       LV2_Worker_Respond_Handle   handle,
626       uint32_t                    size,
627       const void*                 data)
628 {
629         AFluidSynth* self = (AFluidSynth*)instance;
630
631   if (size != sizeof (int)) {
632                 return LV2_WORKER_ERR_UNKNOWN;
633         }
634         int magic = *((const int*)data);
635         if (magic != 0x4711) {
636                 return LV2_WORKER_ERR_UNKNOWN;
637         }
638
639
640         self->initialized = load_sf2 (self, self->queue_sf2_file_path);
641
642         if (self->initialized) {
643                 fluid_synth_all_notes_off (self->synth, -1);
644                 fluid_synth_all_sounds_off (self->synth, -1);
645                 self->panic = false;
646                 // boostrap synth engine.
647                 float l[1024];
648                 float r[1024];
649                 fluid_synth_write_float (self->synth, 1024, l, 0, 1, r, 0, 1);
650         }
651
652         respond (handle, 1, "");
653         return LV2_WORKER_SUCCESS;
654 }
655
656 static LV2_Worker_Status
657 work_response (LV2_Handle  instance,
658                uint32_t    size,
659                const void* data)
660 {
661         AFluidSynth* self = (AFluidSynth*)instance;
662
663         if (self->initialized) {
664                 strcpy (self->current_sf2_file_path, self->queue_sf2_file_path);
665
666                 for (int chn = 0; chn < 16; ++chn) {
667                         if (self->program_state[chn].program < 0) {
668                                 continue;
669                         }
670                         /* cannot direcly call fluid_channel_set_bank_msb/fluid_channel_set_bank_lsb, use CCs */
671                         fluid_midi_event_set_type (self->fmidi_event, 0xb0 /* CC */);
672                         fluid_midi_event_set_channel (self->fmidi_event, chn);
673
674                         fluid_midi_event_set_control (self->fmidi_event, 0x00); // BANK_SELECT_MSB
675                         fluid_midi_event_set_value (self->fmidi_event, (self->program_state[chn].bank >> 7) & 0x7f);
676                         fluid_synth_handle_midi_event (self->synth, self->fmidi_event);
677
678                         fluid_midi_event_set_control (self->fmidi_event, 0x20); // BANK_SELECT_LSB
679                         fluid_midi_event_set_value (self->fmidi_event, self->program_state[chn].bank & 0x7f);
680                         fluid_synth_handle_midi_event (self->synth, self->fmidi_event);
681
682                         fluid_synth_program_change (self->synth, chn, self->program_state[chn].program);
683                 }
684
685                 for (int chn = 0; chn < 16; ++chn) {
686                         int sfid = 0;
687                         int bank = 0;
688                         int program = -1;
689                         if (FLUID_OK == fluid_synth_get_program (self->synth, chn, &sfid, &bank, &program)) {
690                                 self->program_state[chn].bank = bank;
691                                 self->program_state[chn].program = program;
692                         }
693                 }
694
695         } else {
696                 self->current_sf2_file_path[0] = 0;
697         }
698
699         self->reinit_in_progress = false;
700         self->inform_ui = true;
701         self->send_bankpgm = true;
702         self->queue_reinit = false;
703         return LV2_WORKER_SUCCESS;
704 }
705
706 static LV2_State_Status
707 save (LV2_Handle                instance,
708       LV2_State_Store_Function  store,
709       LV2_State_Handle          handle,
710       uint32_t                  flags,
711       const LV2_Feature* const* features)
712 {
713         AFluidSynth* self = (AFluidSynth*)instance;
714
715         if (strlen (self->current_sf2_file_path) == 0) {
716                 return LV2_STATE_ERR_NO_PROPERTY;
717         }
718
719         LV2_State_Map_Path* map_path = NULL;
720
721         for (int i = 0; features[i]; ++i) {
722                 if (!strcmp (features[i]->URI, LV2_STATE__mapPath)) {
723                         map_path = (LV2_State_Map_Path*) features[i]->data;
724                 }
725         }
726
727         if (!map_path) {
728                 return LV2_STATE_ERR_NO_FEATURE;
729         }
730
731         char* apath = map_path->abstract_path (map_path->handle, self->current_sf2_file_path);
732         store (handle, self->afs_sf2file,
733                         apath, strlen (apath) + 1,
734                         self->atom_Path, LV2_STATE_IS_POD);
735
736 #ifndef _WIN32 // TODO need lilv_free() -- https://github.com/drobilla/lilv/issues/14
737         free (apath);
738 #endif
739
740         return LV2_STATE_SUCCESS;
741 }
742
743 static LV2_State_Status
744 restore (LV2_Handle                  instance,
745          LV2_State_Retrieve_Function retrieve,
746          LV2_State_Handle            handle,
747          uint32_t                    flags,
748          const LV2_Feature* const*   features)
749 {
750         AFluidSynth* self = (AFluidSynth*)instance;
751         if (self->reinit_in_progress || self->queue_reinit) {
752                 lv2_log_warning (&self->logger, "a-fluidsynth.lv2: sf2 load already queued.\n");
753                 return LV2_STATE_ERR_UNKNOWN;
754         }
755
756         LV2_State_Map_Path* map_path = NULL;
757
758         for (int i = 0; features[i]; ++i) {
759                 if (!strcmp (features[i]->URI, LV2_STATE__mapPath)) {
760                         map_path = (LV2_State_Map_Path*) features[i]->data;
761                 }
762         }
763
764         if (!map_path) {
765                 return LV2_STATE_ERR_NO_FEATURE;
766         }
767
768   size_t   size;
769   uint32_t type;
770   uint32_t valflags;
771
772   const void* value = retrieve (handle, self->afs_sf2file, &size, &type, &valflags);
773         if (value) {
774                 char* apath = map_path->absolute_path (map_path->handle, (const char*) value);
775                 strncpy (self->queue_sf2_file_path, apath, 1023);
776                 printf ("XXX %s -> %s\n", (const char*) value, apath);
777                 self->queue_sf2_file_path[1023] = '\0';
778                 self->queue_reinit = true;
779 #ifndef _WIN32 // TODO need lilv_free() -- https://github.com/drobilla/lilv/issues/14
780                 free (apath);
781 #endif
782         }
783         return LV2_STATE_SUCCESS;
784 }
785
786 static std::string xml_escape (const std::string& s)
787 {
788         std::string r (s);
789         std::replace (r.begin (), r.end(), '"', '\'');
790         size_t pos = 0;
791         while((pos = r.find ("&", pos)) != std::string::npos) {
792                 r.replace (pos, 1, "&amp;");
793                 pos += 4;
794         }
795         return r;
796 }
797
798 #ifdef LV2_EXTENDED
799 static char*
800 mn_file (LV2_Handle instance)
801 {
802         AFluidSynth* self = (AFluidSynth*)instance;
803         char* rv = NULL;
804         char tmp[1024];
805
806         rv = (char*) calloc (1, sizeof (char));
807
808 #define pf(...)                                              \
809         do {                                                       \
810           snprintf (tmp, sizeof(tmp), __VA_ARGS__);                \
811           tmp[sizeof(tmp) - 1] = '\0';                             \
812           rv = (char*)realloc (rv, strlen (rv) + strlen(tmp) + 1); \
813           strcat (rv, tmp);                                        \
814         } while (0)
815
816         pf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
817                         "<!DOCTYPE MIDINameDocument PUBLIC \"-//MIDI Manufacturers Association//DTD MIDINameDocument 1.0//EN\" \"http://dev.midi.org/dtds/MIDINameDocument10.dtd\">\n"
818                         "<MIDINameDocument>\n"
819                         "  <Author/>\n"
820                         "  <MasterDeviceNames>\n"
821                         "    <Manufacturer>Ardour Foundation</Manufacturer>\n"
822                         "    <Model>%s:%p</Model>\n", AFS_URN, (void*) self);
823
824
825         pf ("    <CustomDeviceMode Name=\"Default\">\n");
826         pf ("      <ChannelNameSetAssignments>\n");
827         for (int c = 0; c < 16; ++c) {
828                 pf ("        <ChannelNameSetAssign Channel=\"%d\" NameSet=\"Presets\"/>\n", c + 1);
829         }
830         pf ("      </ChannelNameSetAssignments>\n");
831         pf ("    </CustomDeviceMode>\n");
832
833         // TODO collect used banks, std::set<> would be a nice here
834
835         pf ("    <ChannelNameSet Name=\"Presets\">\n");
836         pf ("      <AvailableForChannels>\n");
837         for (int c = 0; c < 16; ++c) {
838                 pf ("        <AvailableChannel Channel=\"%d\" Available=\"true\"/>\n", c + 1);
839         }
840         pf ("      </AvailableForChannels>\n");
841         pf ("      <UsesControlNameList Name=\"Controls\"/>\n");
842
843         int bn = 1;
844         pthread_mutex_lock (&self->bp_lock);
845         const BPMap& ps (self->presets);
846         pthread_mutex_unlock (&self->bp_lock);
847
848         for (BPMap::const_iterator i = ps.begin (); i != ps.end (); ++i, ++bn) {
849                 pf ("      <PatchBank Name=\"Patch Bank %d\">\n", i->first);
850                 if (i->second.size() > 0) {
851                         pf ("        <MIDICommands>\n");
852                         pf ("            <ControlChange Control=\"0\" Value=\"%d\"/>\n", (i->first >> 7) & 127);
853                         pf ("            <ControlChange Control=\"32\" Value=\"%d\"/>\n", i->first & 127);
854                         pf ("        </MIDICommands>\n");
855                         pf ("        <PatchNameList>\n");
856                         int n = 0;
857                         for (BPList::const_iterator j = i->second.begin(); j != i->second.end(); ++j, ++n) {
858                                 pf ("      <Patch Number=\"%d\" Name=\"%s\" ProgramChange=\"%d\"/>\n",
859                                                 n, xml_escape (j->name).c_str(), j->program);
860                         }
861                         pf ("        </PatchNameList>\n");
862                 }
863                 pf ("      </PatchBank>\n");
864         }
865         pf ("    </ChannelNameSet>\n");
866
867         pf ("    <ControlNameList Name=\"Controls\">\n");
868         pf ("       <Control Type=\"7bit\" Number=\"1\" Name=\"Modulation\"/>\n");
869         pf ("       <Control Type=\"7bit\" Number=\"2\" Name=\"Breath\"/>\n");
870         pf ("       <Control Type=\"7bit\" Number=\"5\" Name=\"Portamento Time\"/>\n");
871         pf ("       <Control Type=\"7bit\" Number=\"7\" Name=\"Channel Volume\"/>\n");
872         pf ("       <Control Type=\"7bit\" Number=\"8\" Name=\"Stereo Balance\"/>\n");
873         pf ("       <Control Type=\"7bit\" Number=\"10\" Name=\"Pan\"/>\n");
874         pf ("       <Control Type=\"7bit\" Number=\"11\" Name=\"Expression\"/>\n");
875         pf ("       <Control Type=\"7bit\" Number=\"37\" Name=\"Portamento Time (Fine)\"/>\n");
876         pf ("       <Control Type=\"7bit\" Number=\"39\" Name=\"Channel Volume (Fine)\"/>\n");
877         pf ("       <Control Type=\"7bit\" Number=\"40\" Name=\"Stereo Balance (Fine)\"/>\n");
878         pf ("       <Control Type=\"7bit\" Number=\"42\" Name=\"Pan (Fine)\"/>\n");
879         pf ("       <Control Type=\"7bit\" Number=\"64\" Name=\"Sustain On/Off\"/>\n");
880         pf ("       <Control Type=\"7bit\" Number=\"65\" Name=\"Portamento On/Off\"/>\n");
881         pf ("       <Control Type=\"7bit\" Number=\"66\" Name=\"Sostenuto On/Off\"/>\n");
882         pf ("       <Control Type=\"7bit\" Number=\"68\" Name=\"Legato On/Off\"/>\n");
883         pf ("       <Control Type=\"7bit\" Number=\"91\" Name=\"Reverb\"/>\n");
884         pf ("       <Control Type=\"7bit\" Number=\"93\" Name=\"Chorus\"/>\n");
885         pf ("    </ControlNameList>\n");
886
887         pf (
888                         "  </MasterDeviceNames>\n"
889                         "</MIDINameDocument>"
890                  );
891
892         //printf("-----\n%s\n------\n", rv);
893         return rv;
894 }
895
896 static char*
897 mn_model (LV2_Handle instance)
898 {
899         AFluidSynth* self = (AFluidSynth*)instance;
900         char* rv = (char*) malloc (64 * sizeof (char));
901         snprintf (rv, 64, "%s:%p", AFS_URN, (void*) self);
902         rv[63] = 0;
903         return rv;
904 }
905
906 static void
907 mn_free (char* v)
908 {
909         free (v);
910 }
911 #endif
912
913 static const void*
914 extension_data (const char* uri)
915 {
916         if (!strcmp (uri, LV2_WORKER__interface)) {
917                 static const LV2_Worker_Interface worker = { work, work_response, NULL };
918                 return &worker;
919         }
920         else if (!strcmp (uri, LV2_STATE__interface)) {
921                 static const LV2_State_Interface  state  = { save, restore };
922                 return &state;
923         }
924 #ifdef LV2_EXTENDED
925         else if (!strcmp (uri, LV2_MIDNAM__interface)) {
926                 static const LV2_Midnam_Interface midnam = { mn_file, mn_model, mn_free };
927                 return &midnam;
928         }
929 #endif
930         return NULL;
931 }
932
933 static const LV2_Descriptor descriptor = {
934         AFS_URN,
935         instantiate,
936         connect_port,
937         NULL,
938         run,
939         deactivate,
940         cleanup,
941         extension_data
942 };
943
944 #undef LV2_SYMBOL_EXPORT
945 #ifdef _WIN32
946 #    define LV2_SYMBOL_EXPORT __declspec(dllexport)
947 #else
948 #    define LV2_SYMBOL_EXPORT  __attribute__ ((visibility ("default")))
949 #endif
950 LV2_SYMBOL_EXPORT
951 const LV2_Descriptor*
952 lv2_descriptor (uint32_t index)
953 {
954         switch (index) {
955         case 0:
956                 return &descriptor;
957         default:
958                 return NULL;
959         }
960 }