2 * API wrappers for LADSPA/DSSI
4 * Copyright (C) 2007-2008 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02111-1307, USA.
21 #ifndef __CALF_LADSPA_WRAP_H
22 #define __CALF_LADSPA_WRAP_H
32 namespace calf_plugins
{
34 template<class Module
>
35 inline int calc_real_param_count()
37 for (int i
=0; i
< Module::param_count
; i
++)
39 if ((Module::param_props
[i
].flags
& PF_TYPEMASK
) >= PF_STRING
)
42 return Module::param_count
;
45 /// A template implementing plugin_ctl_iface for a given plugin
46 template<class Module
>
47 struct ladspa_instance
: public Module
, public plugin_ctl_iface
51 dssi_feedback_sender
*feedback_sender
;
54 static int real_param_count()
56 static int _real_param_count
= calc_real_param_count
<Module
>();
57 return _real_param_count
;
61 for (int i
=0; i
< Module::in_count
; i
++)
62 Module::ins
[i
] = NULL
;
63 for (int i
=0; i
< Module::out_count
; i
++)
64 Module::outs
[i
] = NULL
;
65 int rpc
= real_param_count();
66 for (int i
=0; i
< rpc
; i
++)
67 Module::params
[i
] = NULL
;
70 feedback_sender
= NULL
;
73 virtual parameter_properties
*get_param_props(int param_no
)
75 return &Module::param_props
[param_no
];
77 virtual float get_param_value(int param_no
)
80 if (param_no
>= real_param_count())
82 return *Module::params
[param_no
];
84 virtual void set_param_value(int param_no
, float value
)
87 if (param_no
>= real_param_count())
89 *Module::params
[param_no
] = value
;
91 virtual int get_param_count()
93 return real_param_count();
95 virtual int get_param_port_offset()
97 return Module::in_count
+ Module::out_count
;
99 virtual const char *get_gui_xml() {
100 return Module::get_gui_xml();
102 virtual line_graph_iface
*get_line_graph_iface()
104 return dynamic_cast<line_graph_iface
*>(this);
106 virtual bool activate_preset(int bank
, int program
) {
109 virtual const char *get_name()
111 return Module::get_name();
113 virtual const char *get_id()
115 return Module::get_id();
117 virtual const char *get_label()
119 return Module::get_label();
121 virtual char *configure(const char *key
, const char *value
)
124 if (!strcmp(key
, "OSC:FEEDBACK_URI"))
126 line_graph_iface
*lgi
= dynamic_cast<line_graph_iface
*>(this);
131 if (feedback_sender
) {
132 delete feedback_sender
;
133 feedback_sender
= NULL
;
135 feedback_sender
= new dssi_feedback_sender(value
, lgi
, get_param_props(0), get_param_count());
139 if (feedback_sender
) {
140 delete feedback_sender
;
141 feedback_sender
= NULL
;
147 if (!strcmp(key
, "OSC:UPDATE"))
150 feedback_sender
->update();
155 if (!strcmp(key
, "ExecCommand"))
159 execute(atoi(value
));
163 return Module::configure(key
, value
);
165 virtual int get_input_count() { return Module::in_count
; }
166 virtual int get_output_count() { return Module::out_count
; }
167 virtual bool get_midi() { return Module::support_midi
; }
168 virtual float get_level(unsigned int port
) { return 0.f
; }
169 virtual void execute(int cmd_no
) {
170 Module::execute(cmd_no
);
172 virtual void send_configures(send_configure_iface
*sci
) {
173 Module::send_configures(sci
);
177 /// A wrapper class for plugin class object (there is only one ladspa_wrapper for many instances of the same plugin)
178 template<class Module
>
179 struct ladspa_wrapper
181 typedef ladspa_instance
<Module
> instance
;
183 /// LADSPA descriptor
184 static LADSPA_Descriptor descriptor
;
185 /// LADSPA descriptor for DSSI (uses a different name for the plugin, otherwise same as descriptor)
186 static LADSPA_Descriptor descriptor_for_dssi
;
188 /// Extended DSSI descriptor (points to descriptor_for_dssi for things like name/label/port info etc.)
189 static DSSI_Descriptor dssi_descriptor
;
190 static DSSI_Program_Descriptor dssi_default_program
;
192 static std::vector
<plugin_preset
> *presets
;
193 static std::vector
<DSSI_Program_Descriptor
> *preset_descs
;
198 int ins
= Module::in_count
;
199 int outs
= Module::out_count
;
200 int params
= ladspa_instance
<Module
>::real_param_count();
201 ladspa_plugin_info
&plugin_info
= Module::plugin_info
;
202 descriptor
.UniqueID
= plugin_info
.unique_id
;
203 descriptor
.Label
= plugin_info
.label
;
204 descriptor
.Name
= strdup((std::string(plugin_info
.name
) + " LADSPA").c_str());
205 descriptor
.Maker
= plugin_info
.maker
;
206 descriptor
.Copyright
= plugin_info
.copyright
;
207 descriptor
.Properties
= Module::rt_capable
? LADSPA_PROPERTY_HARD_RT_CAPABLE
: 0;
208 descriptor
.PortCount
= ins
+ outs
+ params
;
209 descriptor
.PortNames
= new char *[descriptor
.PortCount
];
210 descriptor
.PortDescriptors
= new LADSPA_PortDescriptor
[descriptor
.PortCount
];
211 descriptor
.PortRangeHints
= new LADSPA_PortRangeHint
[descriptor
.PortCount
];
213 for (i
= 0; i
< ins
+ outs
; i
++)
215 LADSPA_PortRangeHint
&prh
= ((LADSPA_PortRangeHint
*)descriptor
.PortRangeHints
)[i
];
216 ((int *)descriptor
.PortDescriptors
)[i
] = i
< ins
? LADSPA_PORT_INPUT
| LADSPA_PORT_AUDIO
217 : i
< ins
+ outs
? LADSPA_PORT_OUTPUT
| LADSPA_PORT_AUDIO
218 : LADSPA_PORT_INPUT
| LADSPA_PORT_CONTROL
;
219 prh
.HintDescriptor
= 0;
220 ((const char **)descriptor
.PortNames
)[i
] = Module::port_names
[i
];
222 for (; i
< ins
+ outs
+ params
; i
++)
224 LADSPA_PortRangeHint
&prh
= ((LADSPA_PortRangeHint
*)descriptor
.PortRangeHints
)[i
];
225 parameter_properties
&pp
= Module::param_props
[i
- ins
- outs
];
226 ((int *)descriptor
.PortDescriptors
)[i
] =
227 LADSPA_PORT_CONTROL
| (pp
.flags
& PF_PROP_OUTPUT
? LADSPA_PORT_OUTPUT
: LADSPA_PORT_INPUT
);
228 prh
.HintDescriptor
= LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_BOUNDED_BELOW
;
229 ((const char **)descriptor
.PortNames
)[i
] = pp
.name
;
230 prh
.LowerBound
= pp
.min
;
231 prh
.UpperBound
= pp
.max
;
232 switch(pp
.flags
& PF_TYPEMASK
) {
234 prh
.HintDescriptor
|= LADSPA_HINT_TOGGLED
;
235 prh
.HintDescriptor
&= ~(LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_BOUNDED_BELOW
);
239 prh
.HintDescriptor
|= LADSPA_HINT_INTEGER
;
242 int defpt
= (int)(100 * (pp
.def_value
- pp
.min
) / (pp
.max
- pp
.min
));
243 if ((pp
.flags
& PF_SCALEMASK
) == PF_SCALE_LOG
)
244 defpt
= (int)(100 * log(pp
.def_value
/ pp
.min
) / log(pp
.max
/ pp
.min
));
246 prh
.HintDescriptor
|= LADSPA_HINT_DEFAULT_MINIMUM
;
248 prh
.HintDescriptor
|= LADSPA_HINT_DEFAULT_LOW
;
250 prh
.HintDescriptor
|= LADSPA_HINT_DEFAULT_MIDDLE
;
252 prh
.HintDescriptor
|= LADSPA_HINT_DEFAULT_HIGH
;
254 prh
.HintDescriptor
|= LADSPA_HINT_DEFAULT_MAXIMUM
;
257 if (pp
.def_value
== 0 || pp
.def_value
== 1 || pp
.def_value
== 100 || pp
.def_value
== 440 ) {
258 prh
.HintDescriptor
&= ~LADSPA_HINT_DEFAULT_MASK
;
259 if (pp
.def_value
== 1)
260 prh
.HintDescriptor
|= LADSPA_HINT_DEFAULT_1
;
261 else if (pp
.def_value
== 100)
262 prh
.HintDescriptor
|= LADSPA_HINT_DEFAULT_100
;
263 else if (pp
.def_value
== 440)
264 prh
.HintDescriptor
|= LADSPA_HINT_DEFAULT_440
;
266 prh
.HintDescriptor
|= LADSPA_HINT_DEFAULT_0
;
268 switch(pp
.flags
& PF_SCALEMASK
) {
270 prh
.HintDescriptor
|= LADSPA_HINT_LOGARITHMIC
;
274 descriptor
.ImplementationData
= this;
275 descriptor
.instantiate
= cb_instantiate
;
276 descriptor
.connect_port
= cb_connect
;
277 descriptor
.activate
= cb_activate
;
278 descriptor
.run
= cb_run
;
279 descriptor
.run_adding
= NULL
;
280 descriptor
.set_run_adding_gain
= NULL
;
281 descriptor
.deactivate
= cb_deactivate
;
282 descriptor
.cleanup
= cb_cleanup
;
284 memcpy(&descriptor_for_dssi
, &descriptor
, sizeof(descriptor
));
285 descriptor_for_dssi
.Name
= strdup((std::string(plugin_info
.name
) + " DSSI").c_str());
286 memset(&dssi_descriptor
, 0, sizeof(dssi_descriptor
));
287 dssi_descriptor
.DSSI_API_Version
= 1;
288 dssi_descriptor
.LADSPA_Plugin
= &descriptor_for_dssi
;
289 dssi_descriptor
.configure
= cb_configure
;
290 dssi_descriptor
.get_program
= cb_get_program
;
291 dssi_descriptor
.select_program
= cb_select_program
;
292 if (Module::support_midi
)
293 dssi_descriptor
.run_synth
= cb_run_synth
;
295 presets
= new std::vector
<plugin_preset
>;
296 preset_descs
= new std::vector
<DSSI_Program_Descriptor
>;
298 preset_list plist_tmp
, plist
;
299 plist
.load_defaults(true);
300 plist_tmp
.load_defaults(false);
301 plist
.presets
.insert(plist
.presets
.end(), plist_tmp
.presets
.begin(), plist_tmp
.presets
.end());
303 // XXXKF this assumes that plugin name in preset is case-insensitive equal to plugin label
304 // if I forget about this, I'll be in a deep trouble
305 dssi_default_program
.Bank
= 0;
306 dssi_default_program
.Program
= 0;
307 dssi_default_program
.Name
= "default";
310 for (unsigned int i
= 0; i
< plist
.presets
.size(); i
++)
312 plugin_preset
&pp
= plist
.presets
[i
];
313 if (strcasecmp(pp
.plugin
.c_str(), descriptor
.Label
))
315 DSSI_Program_Descriptor pd
;
318 pd
.Name
= pp
.name
.c_str();
319 preset_descs
->push_back(pd
);
320 presets
->push_back(pp
);
322 // printf("presets = %p:%d name = %s\n", presets, presets->size(), descriptor.Label);
329 delete []descriptor
.PortNames
;
330 delete []descriptor
.PortDescriptors
;
331 delete []descriptor
.PortRangeHints
;
334 preset_descs
->clear();
340 /// LADSPA instantiation function (create a plugin instance)
341 static LADSPA_Handle
cb_instantiate(const struct _LADSPA_Descriptor
* Descriptor
, unsigned long sample_rate
)
343 instance
*mod
= new instance();
344 mod
->set_sample_rate(sample_rate
);
345 mod
->post_instantiate();
350 /// DSSI get program descriptor function; for 0, it returns the default program (from parameter properties table), for others, it uses global or user preset
351 static const DSSI_Program_Descriptor
*cb_get_program(LADSPA_Handle Instance
, unsigned long index
) {
352 if (index
> presets
->size())
355 return &(*preset_descs
)[index
- 1];
356 return &dssi_default_program
;
359 /// DSSI select program function; for 0, it sets the defaults, for others, it sets global or user preset
360 static void cb_select_program(LADSPA_Handle Instance
, unsigned long Bank
, unsigned long Program
) {
361 instance
*mod
= (instance
*)Instance
;
362 unsigned int no
= (Bank
<< 7) + Program
- 1;
363 // printf("no = %d presets = %p:%d\n", no, presets, presets->size());
365 int rpc
= ladspa_instance
<Module
>::real_param_count();
366 for (int i
=0 ; i
< rpc
; i
++)
367 *mod
->params
[i
] = Module::param_props
[i
].def_value
;
370 if (no
>= presets
->size())
372 plugin_preset
&p
= (*presets
)[no
];
373 // printf("activating preset %s\n", p.name.c_str());
379 /// LADSPA port connection function
380 static void cb_connect(LADSPA_Handle Instance
, unsigned long port
, LADSPA_Data
*DataLocation
) {
381 unsigned long ins
= Module::in_count
;
382 unsigned long outs
= Module::out_count
;
383 unsigned long params
= ladspa_instance
<Module
>::real_param_count();
384 instance
*const mod
= (instance
*)Instance
;
386 mod
->ins
[port
] = DataLocation
;
387 else if (port
< ins
+ outs
)
388 mod
->outs
[port
- ins
] = DataLocation
;
389 else if (port
< ins
+ outs
+ params
) {
390 int i
= port
- ins
- outs
;
391 mod
->params
[i
] = DataLocation
;
392 *mod
->params
[i
] = Module::param_props
[i
].def_value
;
396 /// LADSPA activate function (note that at this moment the ports are not set)
397 static void cb_activate(LADSPA_Handle Instance
) {
398 instance
*const mod
= (instance
*)Instance
;
399 mod
->activate_flag
= true;
402 /// utility function: zero port values if mask is 0
403 static inline void zero_by_mask(Module
*module
, uint32_t mask
, uint32_t offset
, uint32_t nsamples
)
405 for (int i
=0; i
<Module::out_count
; i
++) {
406 if ((mask
& (1 << i
)) == 0) {
407 dsp::zero(module
->outs
[i
] + offset
, nsamples
);
412 /// LADSPA run function - does set sample rate / activate logic when it's run first time after activation
413 static void cb_run(LADSPA_Handle Instance
, unsigned long SampleCount
) {
414 instance
*const mod
= (instance
*)Instance
;
415 if (mod
->activate_flag
)
418 mod
->activate_flag
= false;
420 mod
->params_changed();
421 process_slice(mod
, 0, SampleCount
);
424 /// utility function: call process, and if it returned zeros in output masks, zero out the relevant output port buffers
425 static inline void process_slice(Module
*mod
, uint32_t offset
, uint32_t end
)
429 uint32_t newend
= std::min(offset
+ MAX_SAMPLE_RUN
, end
);
430 uint32_t out_mask
= mod
->process(offset
, newend
- offset
, -1, -1);
431 zero_by_mask(mod
, out_mask
, offset
, newend
- offset
);
437 /// DSSI "run synth" function, same as run() except it allows for event delivery
438 static void cb_run_synth(LADSPA_Handle Instance
, unsigned long SampleCount
,
439 snd_seq_event_t
*Events
, unsigned long EventCount
) {
440 instance
*const mod
= (instance
*)Instance
;
441 if (mod
->activate_flag
)
444 mod
->activate_flag
= false;
446 mod
->params_changed();
449 for (uint32_t e
= 0; e
< EventCount
; e
++)
451 uint32_t timestamp
= Events
[e
].time
.tick
;
452 if (timestamp
!= offset
)
453 process_slice(mod
, offset
, timestamp
);
454 process_dssi_event(mod
, Events
[e
]);
457 if (offset
!= SampleCount
)
458 process_slice(mod
, offset
, SampleCount
);
461 /// DSSI configure function (named properties)
462 static char *cb_configure(LADSPA_Handle Instance
,
466 instance
*const mod
= (instance
*)Instance
;
467 return mod
->configure(Key
, Value
);
470 /// Utility function: handle MIDI event (only handles a subset in this version)
471 static void process_dssi_event(Module
*module
, snd_seq_event_t
&event
)
474 case SND_SEQ_EVENT_NOTEON
:
475 module
->note_on(event
.data
.note
.note
, event
.data
.note
.velocity
);
477 case SND_SEQ_EVENT_NOTEOFF
:
478 module
->note_off(event
.data
.note
.note
, event
.data
.note
.velocity
);
480 case SND_SEQ_EVENT_PGMCHANGE
:
481 module
->program_change(event
.data
.control
.value
);
483 case SND_SEQ_EVENT_CONTROLLER
:
484 module
->control_change(event
.data
.control
.param
, event
.data
.control
.value
);
486 case SND_SEQ_EVENT_PITCHBEND
:
487 module
->pitch_bend(event
.data
.control
.value
);
493 /// LADSPA deactivate function
494 static void cb_deactivate(LADSPA_Handle Instance
) {
495 instance
*const mod
= (instance
*)Instance
;
499 /// LADSPA cleanup (delete instance) function
500 static void cb_cleanup(LADSPA_Handle Instance
) {
501 instance
*const mod
= (instance
*)Instance
;
505 /// Get a wrapper singleton - used to prevent initialization order problems which were present in older versions
506 static ladspa_wrapper
&get() {
507 static ladspa_wrapper instance
;