1 /* FluidSynth DSSI software synthesizer plugin
2 *
3 * Copyright (C) 2004-2008 Sean Bolton and others.
4 *
5 * Portions of this file may have come from Peter Hanappe's
6 * Fluidsynth, copyright (C) 2003 Peter Hanappe and others.
7 * Portions of this file may have come from Chris Cannam and Steve
8 * Harris's public domain DSSI example code.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be
16 * useful, but WITHOUT ANY WARRANTY; without even the implied
17 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18 * PURPOSE. See the GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this program; if not, write to the Free
22 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301 USA.
24 */
25
26 #define _BSD_SOURCE 1
27 #define _SVID_SOURCE 1
28 #define _ISOC99_SOURCE 1
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <stdarg.h>
38 #include <pthread.h>
39
40 #include <ladspa.h>
41 #include <dssi.h>
42
43 #include "fluidsynth.h"
44
45 #include "fluidsynth-dssi.h"
46
47 /* in locate_soundfont.c: */
48 char *fsd_locate_soundfont_file(const char *origpath,
49 const char *projectDirectory);
50
51 static LADSPA_Descriptor *fsd_LADSPA_descriptor = NULL;
52 static DSSI_Descriptor *fsd_DSSI_descriptor = NULL;
53
54 static fsd_synth_t fsd_synth;
55
56 struct fsd_port_descriptor fsd_port_description[FSD_PORTS_COUNT] = {
57 #define PD_OUT (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO)
58 #define PD_IN (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL)
59 { PD_OUT, "Output Left", 0, 0.0f, 0.0f },
60 { PD_OUT, "Output Right", 0, 0.0f, 0.0f },
61 #undef PD_OUT
62 #undef PD_IN
63 };
64
65 static void
66 fsd_all_voices_off(void);
67
68 static void
69 fsd_cleanup(LADSPA_Handle handle);
70
71 static void
72 fsd_run_multiple_synths(unsigned long instance_count, LADSPA_Handle *handles,
73 unsigned long sample_count, snd_seq_event_t **events,
74 unsigned long *event_counts);
75
76 /* ---- FluidSynth helper functions ---- */
77
78 /*
79 * fsd_chan_all_voices_off
80 *
81 * turn off all voices on channel immediately
82 */
83 static inline void
fsd_chan_all_voices_off(int channel)84 fsd_chan_all_voices_off(int channel)
85 {
86 fluid_synth_cc(fsd_synth.fluid_synth, channel, 0x78, 0); /* 0x78 = MIDI 'all sound off' control change */
87 }
88
89 /*
90 * fsd_all_voices_off
91 *
92 * turn off all voices on all channels immediately
93 */
94 static void
fsd_all_voices_off(void)95 fsd_all_voices_off(void)
96 {
97 int i;
98
99 for (i = 0; i < FSD_CHANNEL_COUNT; i++) {
100 fsd_chan_all_voices_off(i);
101 }
102 }
103
104 /* ---- mutual exclusion ---- */
105
106 static inline int
fsd_mutex_trylock(void)107 fsd_mutex_trylock(void)
108 {
109 int rc;
110
111 /* Attempt the mutex lock */
112 rc = pthread_mutex_trylock(&fsd_synth.mutex);
113 if (rc) {
114 #ifndef NWRITE_FLOAT_WORKS_CORRECTLY
115 fsd_synth.burst_remains = 0;
116 #endif
117 fsd_synth.mutex_grab_failed = 1;
118 return rc;
119 }
120 /* Clean up if a previous mutex grab failed */
121 if (fsd_synth.mutex_grab_failed) {
122 fsd_all_voices_off();
123 fsd_synth.mutex_grab_failed = 0;
124 }
125 return 0;
126 }
127
128 static inline int
fsd_mutex_lock(void)129 fsd_mutex_lock(void)
130 {
131 return pthread_mutex_lock(&fsd_synth.mutex);
132 }
133
134 static inline int
fsd_mutex_unlock(void)135 fsd_mutex_unlock(void)
136 {
137 return pthread_mutex_unlock(&fsd_synth.mutex);
138 }
139
140 /* ---- soundfont handling ---- */
141
142 /*
143 * fsd_find_loaded_soundfont
144 */
145 fsd_sfont_t *
fsd_find_loaded_soundfont(const char * path)146 fsd_find_loaded_soundfont(const char *path)
147 {
148 fsd_sfont_t *sfont;
149
150 /* check if we already have the soundfont loaded */
151 sfont = fsd_synth.soundfonts;
152 while (sfont) {
153 if (!strcmp(path, sfont->path)) {
154 return sfont;
155 }
156 sfont = sfont->next;
157 }
158 return NULL;
159 }
160
161 /*
162 * fsd_get_soundfont
163 */
164 fsd_sfont_t *
fsd_get_soundfont(const char * path)165 fsd_get_soundfont(const char *path)
166 {
167 fsd_sfont_t *sfont;
168 int palloc;
169 fluid_sfont_t *fluid_sfont;
170 #if FLUIDSYNTH_VERSION_MAJOR < 2
171 fluid_preset_t preset;
172 #else
173 fluid_preset_t *preset;
174 #endif
175
176 /* soundfont already loaded? */
177 sfont = fsd_find_loaded_soundfont(path);
178 if (sfont) {
179 sfont->ref_count++;
180 DEBUG_DSSI("fsd: soundfont %d refcount now %d\n", sfont->sfont_id, sfont->ref_count);
181 return sfont;
182 }
183
184 /* nope, so load it */
185 sfont = (fsd_sfont_t *)calloc(1, sizeof(fsd_sfont_t));
186 if (!sfont) {
187 return NULL;
188 }
189 sfont->path = strdup(path);
190 if (!sfont->path) {
191 free(sfont);
192 return NULL;
193 }
194 sfont->sfont_id = fluid_synth_sfload(fsd_synth.fluid_synth, path, 0);
195 if (sfont->sfont_id == -1) {
196 free(sfont->path);
197 free(sfont);
198 return NULL;
199 }
200 sfont->ref_count = 1;
201
202 /* enumerate presets */
203 sfont->preset_count = 0;
204 palloc = 256;
205 sfont->presets = (DSSI_Program_Descriptor *)malloc(palloc * sizeof(DSSI_Program_Descriptor));
206 if (!sfont->presets) {
207 fluid_synth_sfunload(fsd_synth.fluid_synth, sfont->sfont_id, 0);
208 free(sfont->path);
209 free(sfont);
210 return NULL;
211 }
212 fluid_sfont = fluid_synth_get_sfont_by_id(fsd_synth.fluid_synth, sfont->sfont_id);
213 #if FLUIDSYNTH_VERSION_MAJOR < 2
214 fluid_sfont->iteration_start(fluid_sfont);
215 while (fluid_sfont->iteration_next(fluid_sfont, &preset)) {
216 #else
217 fluid_sfont_iteration_start(fluid_sfont);
218 while ((preset = fluid_sfont_iteration_next(fluid_sfont))) {
219 #endif
220 if (sfont->preset_count == palloc) {
221 palloc *= 2;
222 sfont->presets = (DSSI_Program_Descriptor *)realloc(sfont->presets,
223 palloc * sizeof(DSSI_Program_Descriptor));
224 if (!sfont->presets) {
225 fluid_synth_sfunload(fsd_synth.fluid_synth, sfont->sfont_id, 0);
226 free(sfont->path);
227 free(sfont);
228 return NULL;
229 }
230 }
231 #if FLUIDSYNTH_VERSION_MAJOR < 2
232 sfont->presets[sfont->preset_count].Bank = preset.get_banknum(&preset);
233 sfont->presets[sfont->preset_count].Program = preset.get_num(&preset);
234 sfont->presets[sfont->preset_count].Name = preset.get_name(&preset);
235 #else
236 sfont->presets[sfont->preset_count].Bank = fluid_preset_get_banknum(preset);
237 sfont->presets[sfont->preset_count].Program = fluid_preset_get_num(preset);
238 sfont->presets[sfont->preset_count].Name = fluid_preset_get_name(preset);
239 #endif
240 sfont->preset_count++;
241 }
242
243 /* add it to soundfont list */
244 sfont->next = fsd_synth.soundfonts;
245 fsd_synth.soundfonts = sfont;
246
247 DEBUG_DSSI("fsd: soundfont '%s' loaded as sfont_id %d (refcount 1, %d presets)\n", path, sfont->sfont_id, sfont->preset_count);
248 return sfont;
249 }
250
251 /*
252 * fsd_release_soundfont
253 */
254 void
255 fsd_release_soundfont(fsd_sfont_t *sfont)
256 {
257 if (--sfont->ref_count == 0) {
258 fsd_sfont_t *prev;
259
260 DEBUG_DSSI("fsd: freeing soundfont %d\n", sfont->sfont_id);
261
262 /* remove soundfont from list */
263 if (fsd_synth.soundfonts == sfont) {
264 fsd_synth.soundfonts = sfont->next;
265 } else {
266 prev = fsd_synth.soundfonts;
267 while (prev->next != sfont)
268 prev = prev->next;
269 prev->next = sfont->next;
270 }
271
272 /* I haven't figured out how or where, but it seems that when calling
273 * fluid_synth_sfunload, fluidsynth turns off notes that are using the
274 * soundfont being unloaded, so I'm hoping we don't need to do that
275 * here. Please correct me if I'm wrong about that.... */
276
277 /* free soundfont */
278 fluid_synth_sfunload(fsd_synth.fluid_synth, sfont->sfont_id, 0);
279 free(sfont->presets);
280 free(sfont->path);
281 free(sfont);
282 } else {
283 DEBUG_DSSI("fsd: soundfont %d refcount now %d\n", sfont->sfont_id, sfont->ref_count);
284 }
285 }
286
287 /* ---- LADSPA interface ---- */
288
289 /*
290 * fsd_instantiate
291 *
292 * implements LADSPA (*instantiate)()
293 */
294 static LADSPA_Handle
295 fsd_instantiate(const LADSPA_Descriptor *descriptor, unsigned long sample_rate)
296 {
297 fsd_instance_t *instance;
298 int i;
299
300 /* refuse another instantiation if we've reached out limit */
301 if (fsd_synth.instance_count == FSD_CHANNEL_COUNT) {
302 return NULL;
303 }
304
305 /* initialize FluidSynth if this is our first instance */
306 if (fsd_synth.instance_count == 0) {
307
308 /* initialize the settings */
309 if (!fsd_synth.fluid_settings &&
310 !(fsd_synth.fluid_settings = new_fluid_settings())) {
311 return NULL;
312 }
313
314 /* set appropriate settings here */
315 fluid_settings_setnum(fsd_synth.fluid_settings, "synth.sample-rate", sample_rate);
316 fluid_settings_setint(fsd_synth.fluid_settings, "synth.midi-channels", FSD_CHANNEL_COUNT);
317 fluid_settings_setint(fsd_synth.fluid_settings, "synth.audio-channels", FSD_CHANNEL_COUNT);
318 fluid_settings_setint(fsd_synth.fluid_settings, "synth.audio-groups", FSD_CHANNEL_COUNT);
319 #ifdef USE_AUGMENTED_FLUIDSYNTH_API
320 fsd_synth.polyphony = FSD_MAX_POLYPHONY;
321 fluid_settings_setint(fsd_synth.fluid_settings, "synth.polyphony", fsd_synth.polyphony);
322 #else
323 fluid_settings_setint(fsd_synth.fluid_settings, "synth.polyphony", FSD_DEFAULT_POLYPHONY);
324 #endif
325 fluid_settings_setstr(fsd_synth.fluid_settings, "synth.reverb.active", "no");
326 fluid_settings_setstr(fsd_synth.fluid_settings, "synth.chorus.active", "no");
327
328 /* initialize the FluidSynth engine */
329 if (!fsd_synth.fluid_synth &&
330 !(fsd_synth.fluid_synth = new_fluid_synth(fsd_synth.fluid_settings))) {
331 delete_fluid_settings(fsd_synth.fluid_settings);
332 return NULL;
333 }
334
335 /* other module-wide initialization */
336 fsd_synth.project_directory = NULL;
337 #ifndef NWRITE_FLOAT_WORKS_CORRECTLY
338 fsd_synth.fluid_bufsize = fluid_synth_get_internal_bufsize(fsd_synth.fluid_synth);
339 fsd_synth.burst_remains = 0;
340 #endif
341 fsd_synth.gain = -1.0f;
342 fsd_synth.fx_buckets[0] = fsd_synth.bit_bucket;
343 fsd_synth.fx_buckets[1] = fsd_synth.bit_bucket;
344 }
345
346 instance = (fsd_instance_t *)calloc(1, sizeof(fsd_instance_t));
347 if (!instance) {
348 fsd_synth.instance_count++;
349 fsd_cleanup(NULL);
350 return NULL;
351 }
352 /* find a free channel */
353 for (i = 0; i < FSD_CHANNEL_COUNT; i++) {
354 if (fsd_synth.channel_map[i] == NULL) {
355 fsd_synth.channel_map[i] = instance;
356 instance->channel = i;
357 break;
358 }
359 }
360
361 #ifndef NWRITE_FLOAT_WORKS_CORRECTLY
362 instance->tmpbuf_l = (LADSPA_Data *)malloc(fsd_synth.fluid_bufsize *
363 sizeof(LADSPA_Data));
364 if (!instance->tmpbuf_l) {
365 fsd_synth.instance_count++;
366 fsd_cleanup(instance);
367 return NULL;
368 }
369 instance->tmpbuf_r = (LADSPA_Data *)malloc(fsd_synth.fluid_bufsize *
370 sizeof(LADSPA_Data));
371 if (!instance->tmpbuf_r) {
372 fsd_synth.instance_count++;
373 fsd_cleanup(instance);
374 return NULL;
375 }
376 #endif
377
378 instance->pending_preset_change = -1;
379 instance->soundfont = NULL;
380
381 fsd_synth.instance_count++;
382
383 return (LADSPA_Handle)instance;
384 }
385
386 /*
387 * fsd_connect_port
388 *
389 * implements LADSPA (*connect_port)()
390 */
391 static void
392 fsd_connect_port(LADSPA_Handle handle, unsigned long port, LADSPA_Data *data)
393 {
394 fsd_instance_t *instance = (fsd_instance_t *)handle;
395
396 switch (port) {
397 case PORT_OUTPUT_LEFT: instance->output_l = data; break;
398 case PORT_OUTPUT_RIGHT: instance->output_r = data; break;
399
400 default:
401 break;
402 }
403 }
404
405 /*
406 * fsd_activate
407 *
408 * implements LADSPA (*activate)()
409 */
410 static void
411 fsd_activate(LADSPA_Handle handle)
412 {
413 // fsd_instance_t *instance = (fsd_instance_t *)handle;
414
415 /* we're already ready to go.... */
416 }
417
418 /*
419 * fsd_ladspa_run
420 *
421 * since we can't implement LADSPA (*run)() safely in a way that supports
422 * more than one instance, we just return immediately
423 */
424 static void
425 fsd_ladspa_run(LADSPA_Handle handle, unsigned long sample_count)
426 {
427 return;
428 }
429
430 // optional:
431 // void (*run_adding)(LADSPA_Handle Instance,
432 // unsigned long SampleCount);
433 // void (*set_run_adding_gain)(LADSPA_Handle Instance,
434 // LADSPA_Data Gain);
435
436 /*
437 * fsd_deactivate
438 *
439 * implements LADSPA (*deactivate)()
440 */
441 void
442 fsd_deactivate(LADSPA_Handle handle)
443 {
444 fsd_instance_t *instance = (fsd_instance_t *)handle;
445
446 /* stop all voices on channel immediately */
447 fsd_chan_all_voices_off(instance->channel);
448 }
449
450 /*
451 * fsd_cleanup
452 *
453 * implements LADSPA (*cleanup)()
454 */
455 static void
456 fsd_cleanup(LADSPA_Handle handle)
457 {
458 fsd_instance_t *instance = (fsd_instance_t *)handle;
459
460 if (instance) {
461 /* release the soundfont */
462 if (instance->soundfont) {
463 fsd_release_soundfont(instance->soundfont);
464 instance->soundfont = NULL;
465 }
466
467 /* free the channel */
468 fsd_synth.channel_map[instance->channel] = NULL;
469
470 #ifndef NWRITE_FLOAT_WORKS_CORRECTLY
471 if (instance->tmpbuf_l) {
472 free(instance->tmpbuf_l);
473 instance->tmpbuf_l = NULL;
474 }
475 if (instance->tmpbuf_r) {
476 free(instance->tmpbuf_r);
477 instance->tmpbuf_r = NULL;
478 }
479 #endif
480 }
481
482 /* if there are no more instances, take down FluidSynth */
483 if (--fsd_synth.instance_count == 0) {
484 while (fsd_synth.soundfonts) {
485 fsd_sfont_t *next = fsd_synth.soundfonts->next;
486 fluid_synth_sfunload(fsd_synth.fluid_synth, fsd_synth.soundfonts->sfont_id, 0);
487 free(fsd_synth.soundfonts->presets);
488 free(fsd_synth.soundfonts->path);
489 free(fsd_synth.soundfonts);
490 fsd_synth.soundfonts = next;
491 }
492 delete_fluid_synth(fsd_synth.fluid_synth);
493 delete_fluid_settings(fsd_synth.fluid_settings);
494 }
495 free(instance);
496 }
497
498 /* ---- DSSI interface ---- */
499
500 /*
501 * dssi_configure_message
502 */
503 char *
504 dssi_configure_message(const char *fmt, ...)
505 {
506 va_list args;
507 char buffer[256];
508
509 va_start(args, fmt);
510 vsnprintf(buffer, 256, fmt, args);
511 va_end(args);
512 return strdup(buffer);
513 }
514
515 /*
516 * fsd_configure
517 *
518 * implements DSSI (*configure)()
519 */
520 char *
521 fsd_configure(LADSPA_Handle handle, const char *key, const char *value)
522 {
523 /* Some of our configuration options are global to the plugin, yet DSSI
524 * configure() calls are per-instance. So for those global options, we'll
525 * have our UI send the same configuration message to each instance, and
526 * we'll check each call here to see if it repeats the current setting,
527 * before acting upon it. */
528
529 fsd_instance_t *instance = (fsd_instance_t *)handle;
530 int have_mutex_lock = 0;
531
532 DEBUG_DSSI("fsd %d: fsd_configure called with '%s' and '%s'\n", instance->channel, key, value);
533
534 if (!strcmp(key, "load")) {
535
536 char *sfpath = fsd_locate_soundfont_file(value, fsd_synth.project_directory);
537
538 if (!sfpath)
539 return dssi_configure_message("error: could not find soundfont '%s'", value);
540
541 if (instance->soundfont &&
542 !strcmp(sfpath, instance->soundfont->path)) {
543 free(sfpath);
544 return NULL; /* soundfont already loaded */
545 }
546
547 /* avoid grabbing the mutex if possible */
548 if ((instance->soundfont && instance->soundfont->ref_count < 2) /* if current soundfont needs unloading */
549 || !fsd_find_loaded_soundfont(sfpath)) { /* or requested soundfont not loaded */
550
551 fsd_mutex_lock();
552 have_mutex_lock = 1;
553 }
554
555 if (instance->soundfont) {
556 fsd_release_soundfont(instance->soundfont);
557 if (have_mutex_lock) {
558 instance->soundfont = NULL;
559 }
560 }
561
562 instance->soundfont = fsd_get_soundfont(sfpath);
563 if (instance->soundfont) {
564 instance->pending_preset_change = instance->soundfont->preset_count ? 0 : -1;
565 }
566
567 if (have_mutex_lock) {
568 fsd_mutex_unlock();
569 }
570
571 if (instance->soundfont) {
572 if (!strcmp(value, sfpath)) {
573 free(sfpath);
574 return NULL; /* success */
575 } else {
576 char *rv = dssi_configure_message("warning: soundfont '%s' not "
577 "found, loaded '%s' instead",
578 value, sfpath);
579 free(sfpath);
580 return rv;
581 }
582 } else {
583 free(sfpath);
584 return dssi_configure_message("error: could not load soundfont '%s'", value);
585 }
586
587 } else if (!strcmp(key, DSSI_GLOBAL_CONFIGURE_PREFIX "gain")) {
588
589 float new_gain = atof(value);
590
591 if (new_gain < 0.0000001f || new_gain > 10.0f) {
592 return dssi_configure_message("error: out-of-range gain '%s'", value);
593 }
594 if (new_gain == fsd_synth.gain) {
595 return NULL; /* gain already set at new_gain */
596 }
597
598 fsd_mutex_lock();
599
600 fluid_synth_set_gain(fsd_synth.fluid_synth, new_gain);
601
602 fsd_mutex_unlock();
603
604 fsd_synth.gain = new_gain;
605
606 return NULL;
607
608 #ifdef USE_AUGMENTED_FLUIDSYNTH_API
609 } else if (!strcmp(key, DSSI_GLOBAL_CONFIGURE_PREFIX "polyphony")) {
610
611 float new_polyphony = atol(value);
612
613 if (new_polyphony < 1 || new_polyphony > FSD_MAX_POLYPHONY) {
614 return dssi_configure_message("error: out-of-range polyphony '%s'", value);
615 }
616 if (new_polyphony == fsd_synth.polyphony) {
617 return NULL; /* polyphony already set at new_polyphony */
618 }
619
620 fsd_mutex_lock();
621
622 fluid_synth_set_polyphony(fsd_synth.fluid_synth, new_polyphony);
623
624 fsd_mutex_unlock();
625
626 fsd_synth.polyphony = new_polyphony;
627
628 return NULL;
629 #endif
630
631 } else if (!strcmp(key, DSSI_PROJECT_DIRECTORY_KEY)) {
632
633 if (fsd_synth.project_directory) {
634 free(fsd_synth.project_directory);
635 }
636 if (value) {
637 fsd_synth.project_directory = strdup(value);
638 } else {
639 fsd_synth.project_directory = NULL;
640 }
641
642 return NULL;
643
644 }
645
646 return strdup("error: unrecognized configure key");
647 }
648
649 /*
650 * fsd_get_program
651 *
652 * implements DSSI (*get_program)()
653 */
654 const DSSI_Program_Descriptor *
655 fsd_get_program(LADSPA_Handle handle, unsigned long index)
656 {
657 fsd_instance_t *instance = (fsd_instance_t *)handle;
658
659 DEBUG_DSSI("fsd %d: fsd_get_program called with %lu\n", instance->channel, index);
660
661 if (!instance->soundfont || index >= instance->soundfont->preset_count) {
662 return NULL;
663 }
664
665 return &instance->soundfont->presets[index];
666 }
667
668 /*
669 * fsd_select_program
670 *
671 * implements DSSI (*select_program)()
672 */
673 void
674 fsd_select_program(LADSPA_Handle handle, unsigned long bank,
675 unsigned long program)
676 {
677 fsd_instance_t *instance = (fsd_instance_t *)handle;
678 int preset;
679
680 DEBUG_DSSI("fsd %d: fsd_select_program called with %lu and %lu\n", instance->channel, bank, program);
681
682 if (!instance->soundfont)
683 return;
684
685 /* ignore invalid program requests */
686 for (preset = 0; preset < instance->soundfont->preset_count; preset++) {
687 if (instance->soundfont->presets[preset].Bank == bank &&
688 instance->soundfont->presets[preset].Program == program)
689 break;
690 }
691 if (preset == instance->soundfont->preset_count)
692 return;
693
694 /* Attempt the mutex, return if lock fails. */
695 if (fsd_mutex_trylock()) {
696 instance->pending_preset_change = preset;
697 return;
698 }
699 fluid_synth_program_select(fsd_synth.fluid_synth, instance->channel,
700 instance->soundfont->sfont_id, bank, program);
701
702 fsd_mutex_unlock();
703 }
704
705 /*
706 * fsd_get_midi_controller
707 *
708 * implements DSSI (*get_midi_controller_for_port)()
709 */
710 int
711 fsd_get_midi_controller(LADSPA_Handle handle, unsigned long port)
712 {
713 // fsd_instance_t *instance = (fsd_instance_t *)handle;
714
715 // DEBUG_DSSI("fsd %d: fsd_get_midi_controller called for port %lu\n", instance->channel, port);
716 // switch (port) {
717 // case PORT_VOLUME:
718 // return DSSI_CC(7);
719 // default:
720 // break;
721 // }
722
723 return DSSI_NONE;
724 }
725
726 // optional:
727 // void (*run_synth)(LADSPA_Handle Instance,
728 // unsigned long SampleCount,
729 // snd_seq_event_t *Events,
730 // unsigned long EventCount);
731 // void (*run_synth_adding)(LADSPA_Handle Instance,
732 // unsigned long SampleCount,
733 // snd_seq_event_t *Events,
734 // unsigned long EventCount);
735
736 /*
737 * fsd_handle_pending_preset_change
738 */
739 static inline void
740 fsd_handle_pending_preset_change(fsd_instance_t *instance)
741 {
742 int preset = instance->pending_preset_change;
743
744 fluid_synth_program_select(fsd_synth.fluid_synth,
745 instance->channel,
746 instance->soundfont->sfont_id,
747 instance->soundfont->presets[preset].Bank,
748 instance->soundfont->presets[preset].Program);
749 }
750
751 /*
752 * fsd_handle_event
753 */
754 static inline void
755 fsd_handle_event(fsd_instance_t *instance, snd_seq_event_t *event)
756 {
757 DEBUG_DSSI("fsd %d: fsd_handle_event called with event type %d\n", instance->channel, event->type);
758
759 switch (event->type) {
760 case SND_SEQ_EVENT_NOTEOFF:
761 fluid_synth_noteoff(fsd_synth.fluid_synth, instance->channel,
762 event->data.note.note);
763 break;
764 case SND_SEQ_EVENT_NOTEON:
765 if (event->data.note.velocity > 0)
766 fluid_synth_noteon(fsd_synth.fluid_synth, instance->channel,
767 event->data.note.note, event->data.note.velocity);
768 else
769 fluid_synth_noteoff(fsd_synth.fluid_synth, instance->channel,
770 event->data.note.note);
771 break;
772 case SND_SEQ_EVENT_KEYPRESS:
773 /* FluidSynth does not implement */
774 /* fluid_synth_key_pressure(fsd_synth.fluid_synth, instance->channel, event->data.note.note, event->data.note.velocity); */
775 break;
776 case SND_SEQ_EVENT_CONTROLLER:
777 fluid_synth_cc(fsd_synth.fluid_synth, instance->channel,
778 event->data.control.param, event->data.control.value);
779 break;
780 case SND_SEQ_EVENT_CHANPRESS:
781 /* FluidSynth does not implement */
782 /* fluid_synth_channel_pressure(fsd_synth.fluid_synth, instance->channel, event->data.control.value); */
783 break;
784 case SND_SEQ_EVENT_PITCHBEND:
785 /* ALSA pitch bend is -8192 - 8191, FluidSynth wants 0 - 16383 */
786 fluid_synth_pitch_bend(fsd_synth.fluid_synth, instance->channel,
787 event->data.control.value + 8192);
788 break;
789 /* SND_SEQ_EVENT_PGMCHANGE - shouldn't happen */
790 /* SND_SEQ_EVENT_SYSEX - shouldn't happen */
791 /* SND_SEQ_EVENT_CONTROL14? */
792 /* SND_SEQ_EVENT_NONREGPARAM? */
793 /* SND_SEQ_EVENT_REGPARAM? */
794 default:
795 break;
796 }
797 }
798
799 /*
800 * fsd_run_multiple_synths
801 *
802 * implements DSSI (*run_multiple_synths)()
803 */
804 static void
805 fsd_run_multiple_synths(unsigned long instance_count, LADSPA_Handle *handles,
806 unsigned long sample_count, snd_seq_event_t **events,
807 unsigned long *event_count)
808 {
809 /* FluidSynth renders everything in blocks of FLUID_BUFSIZE (64) samples,
810 * while DSSI plugins are expected to handle any sample count given them.
811 * While we can't have sample-accurate event rendering here (because of the
812 * FLUID_BUFSIZE blocking), we can make sure the ordering of our event
813 * handling is sample-accurate across all instances of this plugin. */
814
815 fsd_instance_t **instances = (fsd_instance_t **)handles;
816 unsigned long samples_done = 0;
817 unsigned long event_index[instance_count];
818 static LADSPA_Data *l_outputs[FSD_CHANNEL_COUNT];
819 static LADSPA_Data *r_outputs[FSD_CHANNEL_COUNT];
820 unsigned long this_pending_event_tick;
821 unsigned long next_pending_event_tick;
822 int i;
823
824 /* Attempt the mutex, return only silence if lock fails. */
825 if (fsd_mutex_trylock()) {
826 for (i = 0; i < instance_count; i++) {
827 memset(instances[i]->output_l, 0, sizeof(LADSPA_Data) * sample_count);
828 memset(instances[i]->output_r, 0, sizeof(LADSPA_Data) * sample_count);
829 }
830 return;
831 }
832
833 for (i = 0; i < instance_count; i++) {
834 event_index[i] = 0;
835 if (instances[i]->pending_preset_change > -1) {
836 fsd_handle_pending_preset_change(instances[i]);
837 instances[i]->pending_preset_change = -1;
838 }
839 }
840 for (i = 0; i < FSD_CHANNEL_COUNT; i++) {
841 l_outputs[i] = fsd_synth.bit_bucket;
842 r_outputs[i] = fsd_synth.bit_bucket;
843 }
844
845 #ifdef NWRITE_FLOAT_WORKS_CORRECTLY
846 /* fluid_synth_nwrite_float() works correctly in FluidSynth beginning
847 * with CVS as of 2005/6/7 (and I would assume releases > 1.0.5).
848 * So here we can just have it write our output buffers directly,
849 * without the extra copy. */
850
851 next_pending_event_tick = 0;
852 while (samples_done < sample_count) {
853 unsigned long burst_size;
854
855 /* process any ready events */
856 while (next_pending_event_tick <= samples_done) {
857 this_pending_event_tick = next_pending_event_tick;
858 next_pending_event_tick = sample_count;
859 for (i = 0; i < instance_count; i++) {
860 while (event_index[i] < event_count[i]
861 && events[i][event_index[i]].time.tick == this_pending_event_tick) {
862 fsd_handle_event(instances[i], &events[i][event_index[i]]);
863 event_index[i]++;
864 }
865 if (event_index[i] < event_count[i]
866 && events[i][event_index[i]].time.tick < next_pending_event_tick) {
867 next_pending_event_tick = events[i][event_index[i]].time.tick;
868 }
869 }
870 }
871
872 /* render the burst */
873 burst_size = next_pending_event_tick - samples_done;
874 if (burst_size > FSD_MAX_BURST_SIZE)
875 burst_size = FSD_MAX_BURST_SIZE;
876
877 for (i = 0; i < FSD_CHANNEL_COUNT; i++) {
878 if (fsd_synth.channel_map[i]) {
879 fsd_instance_t *instance = fsd_synth.channel_map[i];
880 l_outputs[instance->channel] = instance->output_l + samples_done;
881 r_outputs[instance->channel] = instance->output_r + samples_done;
882 }
883 }
884
885 fluid_synth_nwrite_float(fsd_synth.fluid_synth, burst_size,
886 l_outputs, r_outputs,
887 fsd_synth.fx_buckets, fsd_synth.fx_buckets);
888
889 samples_done += burst_size;
890 }
891
892 #else /* fluid_synth_nwrite_float() doesn't work correctly */
893
894 /* Because fluid_synth_nwrite_float() doesn't work correctly in FluidSynth
895 * versions <= 1.0.5 (including CVS before 2005/6/7) for block lengths less
896 * than FLUID_BUFSIZE (64), we have to always call it with block lengths
897 * that are multiples of 64, buffering any odd block remains for the next
898 * run_multiple_synths() call ourself.
899 * (Note that if the block length is _always_ 32, the bug is not triggered,
900 * luckily, simply because 64 - 32 = 32 (see the code)). */
901
902 /* First, if there is any data remaining from a previous render burst,
903 * copy it from our temporary buffers. */
904 if (fsd_synth.burst_remains) {
905 unsigned long burst_copy = (fsd_synth.burst_remains > sample_count) ?
906 sample_count : fsd_synth.burst_remains;
907 unsigned long burst_offset = fsd_synth.fluid_bufsize - fsd_synth.burst_remains;
908
909 for (i = 0; i < instance_count; i++) {
910 memcpy(instances[i]->output_l,
911 instances[i]->tmpbuf_l + burst_offset,
912 burst_copy * sizeof(LADSPA_Data));
913 memcpy(instances[i]->output_r,
914 instances[i]->tmpbuf_r + burst_offset,
915 burst_copy * sizeof(LADSPA_Data));
916 }
917 samples_done += burst_copy;
918 fsd_synth.burst_remains -= burst_copy;
919 }
920
921 /* Next, write as many full render bursts as possible into the output
922 * buffers, processing ready events as we go. */
923 next_pending_event_tick = 0;
924 while (samples_done + fsd_synth.fluid_bufsize <= sample_count) {
925 unsigned long burst_size;
926
927 /* process any ready events */
928 while (next_pending_event_tick <= samples_done) {
929 this_pending_event_tick = next_pending_event_tick;
930 next_pending_event_tick = sample_count;
931 for (i = 0; i < instance_count; i++) {
932 while (event_index[i] < event_count[i]
933 && events[i][event_index[i]].time.tick == this_pending_event_tick) {
934 fsd_handle_event(instances[i], &events[i][event_index[i]]);
935 event_index[i]++;
936 }
937 if (event_index[i] < event_count[i]
938 && events[i][event_index[i]].time.tick < next_pending_event_tick) {
939 next_pending_event_tick = events[i][event_index[i]].time.tick;
940 }
941 }
942 }
943
944 /* render the burst */
945 burst_size = next_pending_event_tick - samples_done;
946 burst_size = (burst_size + fsd_synth.fluid_bufsize - 1) &
947 ~(fsd_synth.fluid_bufsize - 1); /* round up to nearest whole bufsize */
948 if (burst_size > sample_count - samples_done) /* don't overshoot sample_count */
949 burst_size -= fsd_synth.fluid_bufsize;
950 if (burst_size == 0) /* leave loop if too close to end */
951 break;
952 if (burst_size > FSD_MAX_BURST_SIZE)
953 burst_size = FSD_MAX_BURST_SIZE;
954
955 for (i = 0; i < FSD_CHANNEL_COUNT; i++) {
956 if (fsd_synth.channel_map[i]) {
957 fsd_instance_t *instance = fsd_synth.channel_map[i];
958 l_outputs[instance->channel] = instance->output_l + samples_done;
959 r_outputs[instance->channel] = instance->output_r + samples_done;
960 }
961 }
962
963 fluid_synth_nwrite_float(fsd_synth.fluid_synth, burst_size,
964 l_outputs, r_outputs,
965 fsd_synth.fx_buckets, fsd_synth.fx_buckets);
966
967 samples_done += burst_size;
968 }
969
970 /* Third, process any remaining events. */
971 while (next_pending_event_tick < sample_count) {
972 this_pending_event_tick = next_pending_event_tick;
973 next_pending_event_tick = sample_count;
974 for (i = 0; i < instance_count; i++) {
975 while (event_index[i] < event_count[i]
976 && events[i][event_index[i]].time.tick == this_pending_event_tick) {
977 fsd_handle_event(instances[i], &events[i][event_index[i]]);
978 event_index[i]++;
979 }
980 if (event_index[i] < event_count[i]
981 && events[i][event_index[i]].time.tick < next_pending_event_tick) {
982 next_pending_event_tick = events[i][event_index[i]].time.tick;
983 }
984 }
985 }
986
987 /* Finally, if we're still short on samples, render one more block, then
988 * copy enough data to finish this run */
989 if (samples_done < sample_count) {
990 unsigned long samples_remaining = (sample_count - samples_done);
991
992 /* render one burst */
993 for (i = 0; i < FSD_CHANNEL_COUNT; i++) {
994 if (fsd_synth.channel_map[i]) {
995 fsd_instance_t *instance = fsd_synth.channel_map[i];
996 l_outputs[instance->channel] = instance->tmpbuf_l;
997 r_outputs[instance->channel] = instance->tmpbuf_r;
998 }
999 }
1000
1001 fluid_synth_nwrite_float(fsd_synth.fluid_synth, fsd_synth.fluid_bufsize,
1002 l_outputs, r_outputs,
1003 fsd_synth.fx_buckets, fsd_synth.fx_buckets);
1004
1005 /* copy rendered data to output buffers */
1006 for (i = 0; i < instance_count; i++) {
1007 memcpy(instances[i]->output_l + samples_done,
1008 instances[i]->tmpbuf_l,
1009 samples_remaining * sizeof(LADSPA_Data));
1010 memcpy(instances[i]->output_r + samples_done,
1011 instances[i]->tmpbuf_r,
1012 samples_remaining * sizeof(LADSPA_Data));
1013 }
1014
1015 fsd_synth.burst_remains = fsd_synth.fluid_bufsize - samples_remaining;
1016 }
1017 #endif /* NWRITE_FLOAT_WORKS_CORRECTLY */
1018
1019 #ifdef DEBUG_AUDIO
1020 /* add a 'buzz' to output so there's something audible even when quiescent */
1021 for (i = 0; i < instance_count; i++) {
1022 *instances[i]->output_l += 0.10f;
1023 *instances[i]->output_r += 0.10f;
1024 }
1025 #endif /* DEBUG_AUDIO */
1026
1027 fsd_mutex_unlock();
1028 }
1029
1030 // optional:
1031 // void (*run_multiple_synths_adding)(unsigned long InstanceCount,
1032 // LADSPA_Handle **Instances,
1033 // unsigned long SampleCount,
1034 // snd_seq_event_t **Events,
1035 // unsigned long *EventCounts);
1036
1037 /* ---- export ---- */
1038
1039 const LADSPA_Descriptor *ladspa_descriptor(unsigned long index)
1040 {
1041 switch (index) {
1042 case 0:
1043 return fsd_LADSPA_descriptor;
1044 default:
1045 return NULL;
1046 }
1047 }
1048
1049 const DSSI_Descriptor *dssi_descriptor(unsigned long index)
1050 {
1051 switch (index) {
1052 case 0:
1053 return fsd_DSSI_descriptor;
1054 default:
1055 return NULL;
1056 }
1057 }
1058
1059 #ifdef __GNUC__
1060 __attribute__((constructor)) void init()
1061 #else
1062 void _init()
1063 #endif
1064 {
1065 int i;
1066 char **port_names;
1067 LADSPA_PortDescriptor *port_descriptors;
1068 LADSPA_PortRangeHint *port_range_hints;
1069
1070 fsd_synth.instance_count = 0;
1071 pthread_mutex_init(&fsd_synth.mutex, NULL);
1072 fsd_synth.mutex_grab_failed = 0;
1073 fsd_synth.soundfonts = NULL;
1074 for (i = 0; i < FSD_CHANNEL_COUNT; i++) {
1075 fsd_synth.channel_map[i] = NULL;
1076 }
1077
1078 fsd_LADSPA_descriptor =
1079 (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor));
1080 if (fsd_LADSPA_descriptor) {
1081 fsd_LADSPA_descriptor->UniqueID = 2182;
1082 fsd_LADSPA_descriptor->Label = "FluidSynth-DSSI";
1083 fsd_LADSPA_descriptor->Properties = 0;
1084 fsd_LADSPA_descriptor->Name = "FluidSynth DSSI plugin";
1085 fsd_LADSPA_descriptor->Maker = "Sean Bolton <musound AT jps DOT net>";
1086 fsd_LADSPA_descriptor->Copyright = "(c)2005 GNU General Public License version 2 or later";
1087 fsd_LADSPA_descriptor->PortCount = FSD_PORTS_COUNT;
1088
1089 port_descriptors = (LADSPA_PortDescriptor *)
1090 calloc(fsd_LADSPA_descriptor->PortCount, sizeof
1091 (LADSPA_PortDescriptor));
1092 fsd_LADSPA_descriptor->PortDescriptors =
1093 (const LADSPA_PortDescriptor *) port_descriptors;
1094
1095 port_range_hints = (LADSPA_PortRangeHint *)
1096 calloc(fsd_LADSPA_descriptor->PortCount, sizeof
1097 (LADSPA_PortRangeHint));
1098 fsd_LADSPA_descriptor->PortRangeHints =
1099 (const LADSPA_PortRangeHint *) port_range_hints;
1100
1101 port_names = (char **) calloc(fsd_LADSPA_descriptor->PortCount, sizeof(char *));
1102 fsd_LADSPA_descriptor->PortNames = (const char **) port_names;
1103
1104 for (i = 0; i < FSD_PORTS_COUNT; i++) {
1105 port_descriptors[i] = fsd_port_description[i].port_descriptor;
1106 port_names[i] = fsd_port_description[i].name;
1107 port_range_hints[i].HintDescriptor = fsd_port_description[i].hint_descriptor;
1108 port_range_hints[i].LowerBound = fsd_port_description[i].lower_bound;
1109 port_range_hints[i].UpperBound = fsd_port_description[i].upper_bound;
1110 }
1111
1112 fsd_LADSPA_descriptor->instantiate = fsd_instantiate;
1113 fsd_LADSPA_descriptor->connect_port = fsd_connect_port;
1114 fsd_LADSPA_descriptor->activate = fsd_activate;
1115 fsd_LADSPA_descriptor->run = fsd_ladspa_run;
1116 fsd_LADSPA_descriptor->run_adding = NULL;
1117 fsd_LADSPA_descriptor->set_run_adding_gain = NULL;
1118 fsd_LADSPA_descriptor->deactivate = fsd_deactivate;
1119 fsd_LADSPA_descriptor->cleanup = fsd_cleanup;
1120 }
1121
1122 fsd_DSSI_descriptor = (DSSI_Descriptor *) malloc(sizeof(DSSI_Descriptor));
1123 if (fsd_DSSI_descriptor) {
1124 fsd_DSSI_descriptor->DSSI_API_Version = 1;
1125 fsd_DSSI_descriptor->LADSPA_Plugin = fsd_LADSPA_descriptor;
1126 fsd_DSSI_descriptor->configure = fsd_configure;
1127 fsd_DSSI_descriptor->get_program = fsd_get_program;
1128 fsd_DSSI_descriptor->select_program = fsd_select_program;
1129 fsd_DSSI_descriptor->get_midi_controller_for_port = fsd_get_midi_controller;
1130 fsd_DSSI_descriptor->run_synth = NULL;
1131 fsd_DSSI_descriptor->run_synth_adding = NULL;
1132 fsd_DSSI_descriptor->run_multiple_synths = fsd_run_multiple_synths;
1133 fsd_DSSI_descriptor->run_multiple_synths_adding = NULL;
1134 }
1135 }
1136
1137 #ifdef __GNUC__
1138 __attribute__((destructor)) void fini()
1139 #else
1140 void _fini()
1141 #endif
1142 {
1143 if (fsd_LADSPA_descriptor) {
1144 free((LADSPA_PortDescriptor *) fsd_LADSPA_descriptor->PortDescriptors);
1145 free((char **) fsd_LADSPA_descriptor->PortNames);
1146 free((LADSPA_PortRangeHint *) fsd_LADSPA_descriptor->PortRangeHints);
1147 free(fsd_LADSPA_descriptor);
1148 }
1149 if (fsd_DSSI_descriptor) {
1150 free(fsd_DSSI_descriptor);
1151 }
1152 }
1153
1154