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., 59 Temple Place, Suite 330,
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 dssi_descriptor
.run_synth
= cb_run_synth
;
294 presets
= new std::vector
<plugin_preset
>;
295 preset_descs
= new std::vector
<DSSI_Program_Descriptor
>;
297 preset_list plist_tmp
, plist
;
298 plist
.load_defaults(true);
299 plist_tmp
.load_defaults(false);
300 plist
.presets
.insert(plist
.presets
.end(), plist_tmp
.presets
.begin(), plist_tmp
.presets
.end());
302 // XXXKF this assumes that plugin name in preset is case-insensitive equal to plugin label
303 // if I forget about this, I'll be in a deep trouble
304 dssi_default_program
.Bank
= 0;
305 dssi_default_program
.Program
= 0;
306 dssi_default_program
.Name
= "default";
309 for (unsigned int i
= 0; i
< plist
.presets
.size(); i
++)
311 plugin_preset
&pp
= plist
.presets
[i
];
312 if (strcasecmp(pp
.plugin
.c_str(), descriptor
.Label
))
314 DSSI_Program_Descriptor pd
;
317 pd
.Name
= pp
.name
.c_str();
318 preset_descs
->push_back(pd
);
319 presets
->push_back(pp
);
321 // printf("presets = %p:%d name = %s\n", presets, presets->size(), descriptor.Label);
328 delete []descriptor
.PortNames
;
329 delete []descriptor
.PortDescriptors
;
330 delete []descriptor
.PortRangeHints
;
333 preset_descs
->clear();
339 /// LADSPA instantiation function (create a plugin instance)
340 static LADSPA_Handle
cb_instantiate(const struct _LADSPA_Descriptor
* Descriptor
, unsigned long sample_rate
)
342 instance
*mod
= new instance();
343 mod
->srate
= sample_rate
;
344 mod
->post_instantiate();
349 /// DSSI get program descriptor function; for 0, it returns the default program (from parameter properties table), for others, it uses global or user preset
350 static const DSSI_Program_Descriptor
*cb_get_program(LADSPA_Handle Instance
, unsigned long index
) {
351 if (index
> presets
->size())
354 return &(*preset_descs
)[index
- 1];
355 return &dssi_default_program
;
358 /// DSSI select program function; for 0, it sets the defaults, for others, it sets global or user preset
359 static void cb_select_program(LADSPA_Handle Instance
, unsigned long Bank
, unsigned long Program
) {
360 instance
*mod
= (instance
*)Instance
;
361 unsigned int no
= (Bank
<< 7) + Program
- 1;
362 // printf("no = %d presets = %p:%d\n", no, presets, presets->size());
364 int rpc
= ladspa_instance
<Module
>::real_param_count();
365 for (int i
=0 ; i
< rpc
; i
++)
366 *mod
->params
[i
] = Module::param_props
[i
].def_value
;
369 if (no
>= presets
->size())
371 plugin_preset
&p
= (*presets
)[no
];
372 // printf("activating preset %s\n", p.name.c_str());
378 /// LADSPA port connection function
379 static void cb_connect(LADSPA_Handle Instance
, unsigned long port
, LADSPA_Data
*DataLocation
) {
380 unsigned long ins
= Module::in_count
;
381 unsigned long outs
= Module::out_count
;
382 unsigned long params
= ladspa_instance
<Module
>::real_param_count();
383 instance
*const mod
= (instance
*)Instance
;
385 mod
->ins
[port
] = DataLocation
;
386 else if (port
< ins
+ outs
)
387 mod
->outs
[port
- ins
] = DataLocation
;
388 else if (port
< ins
+ outs
+ params
) {
389 int i
= port
- ins
- outs
;
390 mod
->params
[i
] = DataLocation
;
391 *mod
->params
[i
] = Module::param_props
[i
].def_value
;
395 /// LADSPA activate function (note that at this moment the ports are not set)
396 static void cb_activate(LADSPA_Handle Instance
) {
397 instance
*const mod
= (instance
*)Instance
;
398 mod
->activate_flag
= true;
401 /// utility function: zero port values if mask is 0
402 static inline void zero_by_mask(Module
*module
, uint32_t mask
, uint32_t offset
, uint32_t nsamples
)
404 for (int i
=0; i
<Module::out_count
; i
++) {
405 if ((mask
& (1 << i
)) == 0) {
406 dsp::zero(module
->outs
[i
] + offset
, nsamples
);
411 /// LADSPA run function - does set sample rate / activate logic when it's run first time after activation
412 static void cb_run(LADSPA_Handle Instance
, unsigned long SampleCount
) {
413 instance
*const mod
= (instance
*)Instance
;
414 if (mod
->activate_flag
)
416 mod
->set_sample_rate(mod
->srate
);
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
)
443 mod
->set_sample_rate(mod
->srate
);
445 mod
->activate_flag
= false;
447 mod
->params_changed();
450 for (uint32_t e
= 0; e
< EventCount
; e
++)
452 uint32_t timestamp
= Events
[e
].time
.tick
;
453 if (timestamp
!= offset
)
454 process_slice(mod
, offset
, timestamp
);
455 process_dssi_event(mod
, Events
[e
]);
458 if (offset
!= SampleCount
)
459 process_slice(mod
, offset
, SampleCount
);
462 /// DSSI configure function (named properties)
463 static char *cb_configure(LADSPA_Handle Instance
,
467 instance
*const mod
= (instance
*)Instance
;
468 return mod
->configure(Key
, Value
);
471 /// Utility function: handle MIDI event (only handles a subset in this version)
472 static void process_dssi_event(Module
*module
, snd_seq_event_t
&event
)
475 case SND_SEQ_EVENT_NOTEON
:
476 module
->note_on(event
.data
.note
.note
, event
.data
.note
.velocity
);
478 case SND_SEQ_EVENT_NOTEOFF
:
479 module
->note_off(event
.data
.note
.note
, event
.data
.note
.velocity
);
481 case SND_SEQ_EVENT_PGMCHANGE
:
482 module
->program_change(event
.data
.control
.value
);
484 case SND_SEQ_EVENT_CONTROLLER
:
485 module
->control_change(event
.data
.control
.param
, event
.data
.control
.value
);
487 case SND_SEQ_EVENT_PITCHBEND
:
488 module
->pitch_bend(event
.data
.control
.value
);
494 /// LADSPA deactivate function
495 static void cb_deactivate(LADSPA_Handle Instance
) {
496 instance
*const mod
= (instance
*)Instance
;
500 /// LADSPA cleanup (delete instance) function
501 static void cb_cleanup(LADSPA_Handle Instance
) {
502 instance
*const mod
= (instance
*)Instance
;
506 /// Get a wrapper singleton - used to prevent initialization order problems which were present in older versions
507 static ladspa_wrapper
&get() {
508 static ladspa_wrapper instance
;