2 * Common plugin interface definitions (shared between LADSPA/LV2/DSSI/standalone).
4 * Copyright (C) 2007-2010 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.
25 #include "primitives.h"
30 #include <cairo/cairo.h>
36 namespace calf_plugins
{
42 struct automation_range
;
44 /// Values ORed together for flags field in parameter_properties
47 PF_TYPEMASK
= 0x000F, ///< bit mask for type
48 PF_FLOAT
= 0x0000, ///< any float value
49 PF_INT
= 0x0001, ///< integer value (still represented as float)
50 PF_BOOL
= 0x0002, ///< bool value (usually >=0.5f is treated as TRUE, which is inconsistent with LV2 etc. which treats anything >0 as TRUE)
51 PF_ENUM
= 0x0003, ///< enum value (min, min+1, ..., max, only guaranteed to work when min = 0)
52 PF_ENUM_MULTI
= 0x0004, ///< SET / multiple-choice
54 PF_SCALEMASK
= 0xF0, ///< bit mask for scale
55 PF_SCALE_DEFAULT
= 0x00, ///< no scale given
56 PF_SCALE_LINEAR
= 0x10, ///< linear scale
57 PF_SCALE_LOG
= 0x20, ///< log scale
58 PF_SCALE_GAIN
= 0x30, ///< gain = -96dB..0 or -inf dB
59 PF_SCALE_PERC
= 0x40, ///< percent
60 PF_SCALE_QUAD
= 0x50, ///< quadratic scale (decent for some gain/amplitude values)
61 PF_SCALE_LOG_INF
= 0x60, ///< log scale + +inf (FAKE_INFINITY)
63 PF_CTLMASK
= 0x0F00, ///< bit mask for control type
64 PF_CTL_DEFAULT
= 0x0000, ///< try to figure out automatically
65 PF_CTL_KNOB
= 0x0100, ///< knob
66 PF_CTL_FADER
= 0x0200, ///< fader (slider)
67 PF_CTL_TOGGLE
= 0x0300, ///< toggle button
68 PF_CTL_COMBO
= 0x0400, ///< combo box
69 PF_CTL_RADIO
= 0x0500, ///< radio button
70 PF_CTL_BUTTON
= 0x0600, ///< push button
71 PF_CTL_METER
= 0x0700, ///< volume meter
72 PF_CTL_LED
= 0x0800, ///< light emitting diode
73 PF_CTL_LABEL
= 0x0900, ///< label
75 PF_CTLOPTIONS
= 0x00F000, ///< bit mask for control (widget) options
76 PF_CTLO_HORIZ
= 0x001000, ///< horizontal version of the control (unused)
77 PF_CTLO_VERT
= 0x002000, ///< vertical version of the control (unused)
78 PF_CTLO_LABEL
= 0x004000, ///< add a text display to the control (meters only)
79 PF_CTLO_REVERSE
= 0x008000, ///< use VU_MONOCHROME_REVERSE mode (meters only)
81 PF_PROP_NOBOUNDS
= 0x010000, ///< no epp:hasStrictBounds
82 PF_PROP_EXPENSIVE
= 0x020000, ///< epp:expensive, may trigger expensive calculation
83 PF_PROP_OUTPUT_GAIN
=0x050000, ///< epp:outputGain + skip epp:hasStrictBounds
84 PF_PROP_OUTPUT
= 0x080000, ///< output port
85 PF_PROP_OPTIONAL
= 0x100000, ///< connection optional
86 PF_PROP_GRAPH
= 0x200000, ///< add graph
88 PF_UNITMASK
= 0xFF000000, ///< bit mask for units \todo reduce to use only 5 bits
89 PF_UNIT_DB
= 0x01000000, ///< decibels
90 PF_UNIT_COEF
= 0x02000000, ///< multiply-by factor
91 PF_UNIT_HZ
= 0x03000000, ///< Hertz
92 PF_UNIT_SEC
= 0x04000000, ///< second
93 PF_UNIT_MSEC
= 0x05000000, ///< millisecond
94 PF_UNIT_CENTS
= 0x06000000, ///< cents (1/100 of a semitone, 1/1200 of an octave)
95 PF_UNIT_SEMITONES
= 0x07000000,///< semitones
96 PF_UNIT_BPM
= 0x08000000, ///< beats per minute
97 PF_UNIT_DEG
= 0x09000000, ///< degrees
98 PF_UNIT_NOTE
= 0x0A000000, ///< MIDI note number
99 PF_UNIT_RPM
= 0x0B000000, ///< revolutions per minute
100 PF_UNIT_SAMPLES
= 0x0C000000, ///< samples
102 PF_SYNC_BPM
= 0x10000000, ///< sync a bpm setting with the host environment
105 /// A fake infinity value (because real infinity may break some hosts)
106 #define FAKE_INFINITY (65536.0 * 65536.0)
107 /// Check for infinity (with appropriate-ish tolerance)
108 #define IS_FAKE_INFINITY(value) (fabs(value-FAKE_INFINITY) < 1.0)
110 /// Information record about plugin's menu command
111 struct plugin_command_info
113 const char *label
; ///< short command name / label
114 const char *name
; ///< human-readable command name
115 const char *description
; ///< description (for status line etc.)
118 /// Range, default value, flags and names for a parameter
119 struct parameter_properties
127 /// number of steps (for an integer value from 0 to 100 this will be 101; for 0/90/180/270/360 this will be 5), or 0 for continuous
129 /// logical OR of parameter_flags
131 /// for PF_ENUM: array of text values (from min to max step 1), otherwise NULL
132 const char **choices
;
133 /// parameter label (for use in LV2 label field etc.)
134 const char *short_name
;
135 /// parameter human-readable name
137 /// convert from [0, 1] range to [min, max] (applying scaling)
138 float from_01(double value01
) const;
139 /// convert from [min, max] to [0, 1] range (applying reverse scaling)
140 double to_01(float value
) const;
141 /// stringify (in sensible way)
142 std::string
to_string(float value
) const;
143 /// convert string (from text entry) to value
144 float string_to_value(const char* string
) const;
145 /// get required width (for reserving GUI space)
146 int get_char_count() const;
147 /// get increment step based on step value (if specified) and other factors
148 float get_increment() const;
154 int size_x
, size_y
, pad_x
, pad_y
;
155 virtual void set_source_rgba(float r
, float g
, float b
, float a
= 1.f
) = 0;
156 virtual void set_line_width(float width
) = 0;
157 virtual void set_dash(const double *dash
, int length
) = 0;
158 virtual void draw_label(const char *label
, float x
, float y
, int pos
, float margin
, float align
) = 0;
159 virtual ~cairo_iface() {}
162 class cairo_impl
: public calf_plugins::cairo_iface
166 virtual void set_source_rgba(float r
, float g
, float b
, float a
= 1.f
) { cairo_set_source_rgba(context
, r
, g
, b
, a
); }
167 virtual void set_line_width(float width
) { cairo_set_line_width(context
, width
); }
168 virtual void set_dash(const double *dash
, int length
) { cairo_set_dash(context
, dash
, length
, 0); }
169 virtual void draw_label(const char *label
, float x
, float y
, int pos
, float margin
, float align
) {
170 cairo_text_extents_t extents
;
171 cairo_text_extents(context
, label
, &extents
);
176 cairo_move_to(context
, x
- extents
.width
/ 2, y
- margin
);
180 cairo_move_to(context
, x
+ margin
, y
+ 2);
184 cairo_move_to(context
, x
- extents
.width
/ 2, y
+ margin
+ extents
.height
);
188 cairo_move_to(context
, x
- margin
- extents
.width
, y
+ 2);
191 cairo_show_text(context
, label
);
195 struct progress_report_iface
197 virtual void report_progress(float percentage
, const std::string
&message
) = 0;
198 virtual ~progress_report_iface() {}
201 /// possible bit masks for get_layers
204 LG_CACHE_GRID
= 0x000001,
205 LG_REALTIME_GRID
= 0x000002,
206 LG_CACHE_GRAPH
= 0x000004,
207 LG_REALTIME_GRAPH
= 0x000008,
208 LG_CACHE_DOT
= 0x000010,
209 LG_REALTIME_DOT
= 0x000020,
210 LG_CACHE_MOVING
= 0x000040,
211 LG_REALTIME_MOVING
= 0x000080
214 /// possible values for get_moving
215 enum moving_directions
{
216 LG_MOVING_LEFT
= 0x000000,
217 LG_MOVING_RIGHT
= 0x000001,
218 LG_MOVING_UP
= 0x000002,
219 LG_MOVING_DOWN
= 0x000004
222 /// 'provides live line graph values' interface
223 struct line_graph_iface
225 /// Obtain subindex'th graph of parameter 'index'
226 /// @param index parameter/graph number (usually tied to particular plugin control port)
227 /// @param subindex graph number (there may be multiple overlaid graphs for one parameter, eg. for monosynth 2x12dB filters)
228 /// @param phase 0 if in cache phase or 1 if in realtime phase
229 /// @param data buffer for normalized output values
230 /// @param points number of points to fill
231 /// @param context cairo context to adjust (for multicolour graphs etc.)
232 /// @retval true graph data was returned; subindex+1 graph may or may not be available
233 /// @retval false graph data was not returned; subindex+1 graph does not exist either
234 virtual bool get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
= 0) const { return false; }
236 /// Obtain subindex'th moving surface of parameter 'index'
237 /// @param index parameter/dot number (usually tied to particular plugin control port)
238 /// @param subindex mvoing line number (there may be multiple graphs for one parameter)
239 /// @param direction 0 if horizontal or 1 if vertical movement
240 /// @param data buffer for normalized output values
241 /// @param x number of points direction to fill in x
242 /// @param y number of points direction to fill in y
243 virtual bool get_moving(int index
, int subindex
, int &direction
, float *data
, int x
, int y
, int &offset
, uint32_t &color
) const { return false; }
245 /// Obtain subindex'th dot of parameter 'index'
246 /// @param index parameter/dot number (usually tied to particular plugin control port)
247 /// @param subindex dot number (there may be multiple dots graphs for one parameter)
248 /// @param phase 0 if in cache phase or 1 if in realtime phase
249 virtual bool get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const { return false; }
251 /// Obtain subindex'th dot of parameter 'index'
252 /// @param index parameter/dot number (usually tied to particular plugin control port)
253 /// @param subindex dot number (there may be multiple dots graphs for one parameter)
254 /// @param phase 0 if in cache phase or 1 if in realtime phase
255 virtual bool get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const { return false; }
257 /// Retrun which layers need to be redrawn in the next GTK drawing cycle
258 /// @param index Parameter/graph identifier (usually tied to particular plugin control port)
259 /// @param generation The overall amount of drawing cycles since the last full refresh of all surfaces
260 /// @param layers Bitmask defining the layers to be redrawn (see layers_flags above)
261 /// @retval true there's at least one layer to be redrawn; false nothing to draw in this cycle
262 virtual bool get_layers(int index
, int generation
, unsigned int &layers
) const { return false; }
264 /// Return a label for the crosshairs they are enabled
265 /// @param x Position of the mouse pointer in x direction
266 /// @param y Position of the mouse pointer in y direction
267 /// @param sx Horizontal size of the widget in pixels
268 /// @param sy Vertical size of the widget in pixels
269 virtual std::string
get_crosshair_label( int x
, int y
, int sx
, int sy
, cairo_iface
*context
) const { std::string s
= ""; return s
; }
271 /// Standard destructor to make compiler happy
272 virtual ~line_graph_iface() {}
275 /// 'provides live line graph values' interface
276 struct phase_graph_iface
278 virtual bool get_phase_graph(float ** _buffer
, int *_length
, int * _mode
, bool * _use_fade
, float * _fade
, int * _accuracy
, bool * _display
) const { return false; };
279 virtual ~phase_graph_iface() {}
282 enum table_column_type
284 TCT_UNKNOWN
, ///< guard invalid type
285 TCT_FLOAT
, ///< float value (encoded as C locale string)
286 TCT_ENUM
, ///< enum value (see: 'values' array in table_column_info) - encoded as string base 10 representation of integer
287 TCT_STRING
, ///< string value (encoded as C-escaped string)
288 TCT_OBJECT
, ///< external object, encoded as string
289 TCT_LABEL
, ///< string value (encoded as C-escaped string)
293 struct table_column_info
295 const char *name
; ///< column label
296 table_column_type type
; ///< column data type
297 float min
; ///< minimum value (for float)
298 float max
; ///< maximum value (for float and enum)
299 float def_value
; ///< default value (for float and enum)
300 const char **values
; ///< NULL unless a TCT_ENUM, where it represents a NULL-terminated list of choices
303 /// 'has string parameters containing tabular data' interface
304 struct table_metadata_iface
306 /// retrieve the table layout for specific parameter
307 virtual const table_column_info
*get_table_columns() const = 0;
309 /// return the fixed number of rows, or 0 if the number of rows is variable
310 virtual uint32_t get_table_rows() const = 0;
312 virtual ~table_metadata_iface() {}
315 /// 'may receive configure variables' interface
316 struct send_configure_iface
318 /// Called to set configure variable
319 /// @param key variable name
320 /// @param value variable content
321 virtual void send_configure(const char *key
, const char *value
) = 0;
323 virtual ~send_configure_iface() {}
326 /// 'may receive new status values' interface
327 struct send_updates_iface
329 /// Called to set configure variable
330 /// @param key variable name
331 /// @param value variable content
332 virtual void send_status(const char *key
, const char *value
) = 0;
334 virtual ~send_updates_iface() {}
337 struct plugin_command_info
;
339 /// General information about the plugin - @todo XXXKF lacks the "new" id-label-name triple
340 struct ladspa_plugin_info
344 /// plugin short name (camel case)
346 /// plugin human-readable name
351 const char *copyright
;
352 /// plugin type for LRDF/LV2
353 const char *plugin_type
;
356 /// An interface returning metadata about a plugin
357 struct plugin_metadata_iface
359 enum { simulate_stereo_input
= true };
360 /// @return plugin long name
361 virtual const char *get_name() const = 0;
362 /// @return plugin LV2 label
363 virtual const char *get_id() const = 0;
364 /// @return plugin human-readable label
365 virtual const char *get_label() const = 0;
366 /// @return total number of parameters
367 virtual int get_param_count() const = 0;
368 /// Return custom XML
369 virtual const char *get_gui_xml() const = 0;
370 /// @return number of audio inputs
371 virtual int get_input_count() const =0;
372 /// @return number of audio outputs
373 virtual int get_output_count() const =0;
374 /// @return number of optional inputs
375 virtual int get_inputs_optional() const =0;
376 /// @return number of optional outputs
377 virtual int get_outputs_optional() const =0;
378 /// @return true if plugin can work in hard-realtime conditions
379 virtual bool is_rt_capable() const =0;
380 /// @return true if plugin has MIDI input
381 virtual bool get_midi() const =0;
382 /// @return true if plugin has MIDI input
383 virtual bool requires_midi() const =0;
384 /// @return port offset of first control (parameter) port (= number of audio inputs + number of audio outputs in all existing plugins as for 1 Aug 2008)
385 virtual int get_param_port_offset() const = 0;
386 /// @return NULL-terminated list of menu commands
387 virtual plugin_command_info
*get_commands() const { return NULL
; }
388 /// @return description structure for given parameter
389 virtual const parameter_properties
*get_param_props(int param_no
) const = 0;
390 /// @return retrieve names of audio ports (@note control ports are named in parameter_properties, not here)
391 virtual const char **get_port_names() const = 0;
392 /// @return description structure for the plugin
393 virtual const ladspa_plugin_info
&get_plugin_info() const = 0;
394 /// is a given parameter a control voltage?
395 virtual bool is_cv(int param_no
) const = 0;
396 /// is the given parameter non-interpolated?
397 virtual bool is_noisy(int param_no
) const = 0;
398 /// does the plugin require string port extension? (or DSSI configure) may be slow
399 virtual bool requires_configure() const = 0;
400 /// obtain array of names of configure variables (or NULL is none needed)
401 virtual void get_configure_vars(std::vector
<std::string
> &names
) const { names
.clear(); }
402 /// @return table_metadata_iface if any
403 virtual const table_metadata_iface
*get_table_metadata_iface(const char *key
) const { return NULL
; }
404 /// @return whether to auto-connect right input with left input if unconnected
405 virtual bool get_simulate_stereo_input() const = 0;
407 /// Do-nothing destructor to silence compiler warning
408 virtual ~plugin_metadata_iface() {}
411 /// Interface for host-GUI-plugin interaction (should be really split in two, but ... meh)
412 struct plugin_ctl_iface
414 /// @return value of given parameter
415 virtual float get_param_value(int param_no
) = 0;
416 /// Set value of given parameter
417 virtual void set_param_value(int param_no
, float value
) = 0;
418 /// Load preset with given number
419 virtual bool activate_preset(int bank
, int program
) = 0;
420 /// @return volume level for port'th port (if supported by the implementation, currently only jack_host<Module> implements that by measuring signal level on plugin ports)
421 virtual float get_level(unsigned int port
)=0;
422 /// Execute menu command with given number
423 virtual void execute(int cmd_no
)=0;
424 /// Set a configure variable on a plugin
425 virtual char *configure(const char *key
, const char *value
) = 0;
426 /// Send all configure variables set within a plugin to given destination (which may be limited to only those that plugin understands)
427 virtual void send_configures(send_configure_iface
*)=0;
428 /// Restore all state (parameters and configure vars) to default values - implemented in giface.cpp
429 virtual void clear_preset();
430 /// Call a named function in a plugin - this will most likely be redesigned soon - and never used
431 /// @retval false call has failed, result contains an error message
432 virtual bool blobcall(const char *command
, const std::string
&request
, std::string
&result
) { result
= "Call not supported"; return false; }
433 /// Update status variables changed since last_serial
434 /// @return new last_serial
435 virtual int send_status_updates(send_updates_iface
*sui
, int last_serial
) = 0;
436 /// Return metadata object
437 virtual const plugin_metadata_iface
*get_metadata_iface() const = 0;
438 /// @return line_graph_iface if any
439 virtual const line_graph_iface
*get_line_graph_iface() const = 0;
440 /// @return phase_graph_iface if any
441 virtual const phase_graph_iface
*get_phase_graph_iface() const = 0;
442 /// @return serial number of last automation write (JACK host only)
443 virtual int get_write_serial(int param_no
) { return 0; }
445 /// Add or update parameter automation routing
446 virtual void add_automation(uint32_t source
, const automation_range
&dest
) {}
447 /// Remove parameter automation routing
448 virtual void delete_automation(uint32_t source
, int param_no
) {}
449 /// Retrieve automation list for a given parameter
450 /// @param param_no parameter to retrieve automation list for, or -1 for all
451 virtual void get_automation(int param_no
, std::multimap
<uint32_t, automation_range
> &dests
) {}
452 /// Return the source identifier for the most recently seen control change that could be used for automation
453 virtual uint32_t get_last_automation_source() { return 0xFFFFFFFF; }
454 virtual void send_automation_configures(send_configure_iface
*) {}
455 /// Do-nothing destructor to silence compiler warning
456 virtual ~plugin_ctl_iface() {}
459 struct plugin_list_info_iface
;
461 /// A class to retrieve and query the list of Calf plugins
462 class plugin_registry
465 typedef std::vector
<const plugin_metadata_iface
*> plugin_vector
;
467 plugin_vector plugins
;
470 /// Get the singleton object.
471 static plugin_registry
&instance();
473 /// Get all plugin metadata objects
474 const plugin_vector
&get_all() { return plugins
; }
475 /// Get single plugin metadata object by URI
476 const plugin_metadata_iface
*get_by_uri(const char *URI
);
477 /// Get single plugin metadata object by URI
478 const plugin_metadata_iface
*get_by_id(const char *id
, bool case_sensitive
= false);
481 /// Load and strdup a text file with GUI definition
482 extern const char *load_gui_xml(const std::string
&plugin_id
);
484 /// Interface to audio processing plugins (the real things, not only metadata)
485 struct audio_module_iface
487 /// Handle MIDI Note On
488 virtual void note_on(int channel
, int note
, int velocity
) = 0;
489 /// Handle MIDI Note Off
490 virtual void note_off(int channel
, int note
, int velocity
) = 0;
491 /// Handle MIDI Program Change
492 virtual void program_change(int channel
, int program
) = 0;
493 /// Handle MIDI Control Change
494 virtual void control_change(int channel
, int controller
, int value
) = 0;
495 /// Handle MIDI Pitch Bend
496 /// @param value pitch bend value (-8192 to 8191, defined as in MIDI ie. 8191 = 200 ct by default)
497 virtual void pitch_bend(int channel
, int value
) = 0;
498 /// Handle MIDI Channel Pressure
499 /// @param value channel pressure (0 to 127)
500 virtual void channel_pressure(int channel
, int value
) = 0;
501 /// Called when params are changed (before processing)
502 virtual void params_changed() = 0;
503 /// LADSPA-esque activate function, except it is called after ports are connected, not before
504 virtual void activate() = 0;
505 /// LADSPA-esque deactivate function
506 virtual void deactivate() = 0;
507 /// Set sample rate for the plugin
508 virtual void set_sample_rate(uint32_t sr
) = 0;
509 /// Execute menu command with given number
510 virtual void execute(int cmd_no
) = 0;
511 /// DSSI configure call, value = NULL = reset to default
512 virtual char *configure(const char *key
, const char *value
) = 0;
513 /// Send all understood configure vars (none by default)
514 virtual void send_configures(send_configure_iface
*sci
) = 0;
515 /// Send all supported status vars (none by default)
516 virtual int send_status_updates(send_updates_iface
*sui
, int last_serial
) = 0;
517 /// Reset parameter values for epp:trigger type parameters (ones activated by oneshot push button instead of check box)
518 virtual void params_reset() = 0;
519 /// Called after instantiating (after all the feature pointers are set - including interfaces like progress_report_iface)
520 virtual void post_instantiate(uint32_t sample_rate
) = 0;
521 /// Return the arrays of port buffer pointers
522 virtual void get_port_arrays(float **&ins_ptrs
, float **&outs_ptrs
, float **¶ms_ptrs
) = 0;
523 /// Return metadata object
524 virtual const plugin_metadata_iface
*get_metadata_iface() const = 0;
525 /// Set the progress report interface to communicate progress to
526 virtual void set_progress_report_iface(progress_report_iface
*iface
) = 0;
527 /// Clear a part of output buffers that have 0s at mask; subdivide the buffer so that no runs > MAX_SAMPLE_RUN are fed to process function
528 virtual uint32_t process_slice(uint32_t offset
, uint32_t end
) = 0;
529 /// The audio processing loop; assumes numsamples <= MAX_SAMPLE_RUN, for larger buffers, call process_slice
530 virtual uint32_t process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) = 0;
531 /// Message port processing function
532 virtual uint32_t message_run(const void *valid_ports
, void *output_ports
) = 0;
533 /// @return line_graph_iface if any
534 virtual const line_graph_iface
*get_line_graph_iface() const = 0;
535 /// @return phase_graph_iface if any
536 virtual const phase_graph_iface
*get_phase_graph_iface() const = 0;
537 virtual ~audio_module_iface() {}
540 /// Empty implementations for plugin functions.
541 template<class Metadata
>
542 class audio_module
: public Metadata
, public audio_module_iface
545 typedef Metadata metadata_type
;
546 using Metadata::in_count
;
547 using Metadata::out_count
;
548 using Metadata::param_count
;
549 float *ins
[Metadata::in_count
];
550 float *outs
[Metadata::out_count
];
551 float *params
[Metadata::param_count
];
552 bool questionable_data_reported_in
;
553 bool questionable_data_reported_out
;
555 progress_report_iface
*progress_report
;
558 progress_report
= NULL
;
559 memset(ins
, 0, sizeof(ins
));
560 memset(outs
, 0, sizeof(outs
));
561 memset(params
, 0, sizeof(params
));
562 questionable_data_reported_in
= false;
563 questionable_data_reported_out
= false;
566 /// Handle MIDI Note On
567 void note_on(int channel
, int note
, int velocity
) {}
568 /// Handle MIDI Note Off
569 void note_off(int channel
, int note
, int velocity
) {}
570 /// Handle MIDI Program Change
571 void program_change(int channel
, int program
) {}
572 /// Handle MIDI Control Change
573 void control_change(int channel
, int controller
, int value
) {}
574 /// Handle MIDI Pitch Bend
575 /// @param value pitch bend value (-8192 to 8191, defined as in MIDI ie. 8191 = 200 ct by default)
576 void pitch_bend(int channel
, int value
) {}
577 /// Handle MIDI Channel Pressure
578 /// @param value channel pressure (0 to 127)
579 void channel_pressure(int channel
, int value
) {}
580 /// Called when params are changed (before processing)
581 void params_changed() {}
582 /// LADSPA-esque activate function, except it is called after ports are connected, not before
584 /// LADSPA-esque deactivate function
586 /// Set sample rate for the plugin
587 void set_sample_rate(uint32_t sr
) { }
588 /// Execute menu command with given number
589 void execute(int cmd_no
) {}
590 /// DSSI configure call
591 virtual char *configure(const char *key
, const char *value
) { return NULL
; }
592 /// Send all understood configure vars (none by default)
593 void send_configures(send_configure_iface
*sci
) {}
594 /// Send all supported status vars (none by default)
595 int send_status_updates(send_updates_iface
*sui
, int last_serial
) { return last_serial
; }
596 /// Reset parameter values for epp:trigger type parameters (ones activated by oneshot push button instead of check box)
597 void params_reset() {}
598 /// Called after instantiating (after all the feature pointers are set - including interfaces like progress_report_iface)
599 void post_instantiate(uint32_t) {}
600 /// Handle 'message context' port message
601 /// @arg output_ports pointer to bit array of output port "changed" flags, note that 0 = first audio input, not first parameter (use input_count + output_count)
602 uint32_t message_run(const void *valid_ports
, void *output_ports
) {
603 fprintf(stderr
, "ERROR: message run not implemented\n");
606 /// Return the array of input port pointers
607 virtual void get_port_arrays(float **&ins_ptrs
, float **&outs_ptrs
, float **¶ms_ptrs
)
611 params_ptrs
= params
;
613 /// Return metadata object
614 virtual const plugin_metadata_iface
*get_metadata_iface() const { return this; }
615 /// Set the progress report interface to communicate progress to
616 virtual void set_progress_report_iface(progress_report_iface
*iface
) { progress_report
= iface
; }
618 /// utility function: zero port values if mask is 0
619 inline void zero_by_mask(uint32_t mask
, uint32_t offset
, uint32_t nsamples
)
621 for (int i
=0; i
<Metadata::out_count
; i
++) {
622 if ((mask
& (1 << i
)) == 0) {
623 dsp::zero(outs
[i
] + offset
, nsamples
);
627 /// utility function: call process, and if it returned zeros in output masks, zero out the relevant output port buffers
628 uint32_t process_slice(uint32_t offset
, uint32_t end
)
630 bool had_errors
= false;
631 for (int i
=0; i
<Metadata::in_count
; ++i
) {
632 float *indata
= ins
[i
];
635 for (uint32_t j
= offset
; j
< end
; j
++)
637 if (!std::isfinite(indata
[j
]) || fabs(indata
[j
]) > 4294967296.0) {
642 if (had_errors
&& !questionable_data_reported_in
) {
643 fprintf(stderr
, "Warning: Plugin %s got questionable value %f on its input %d\n", Metadata::get_name(), errval
, i
);
644 questionable_data_reported_in
= true;
648 uint32_t total_out_mask
= 0;
651 uint32_t newend
= std::min(offset
+ MAX_SAMPLE_RUN
, end
);
652 uint32_t out_mask
= !had_errors
? process(offset
, newend
- offset
, -1, -1) : 0;
653 total_out_mask
|= out_mask
;
654 zero_by_mask(out_mask
, offset
, newend
- offset
);
657 for (int i
=0; i
<Metadata::out_count
; ++i
) {
658 if (total_out_mask
& (1 << i
))
661 float *outdata
= outs
[i
];
663 for (uint32_t j
= offset
; j
< end
; j
++)
665 if (!std::isfinite(outdata
[j
]) || fabs(outdata
[j
]) > 4294967296.0) {
670 if (had_errors
&& !questionable_data_reported_out
) {
671 fprintf(stderr
, "Warning: Plugin %s generated questionable value %f on its output %d - this is most likely a bug in the plugin!\n", Metadata::get_name(), errval
, i
);
672 questionable_data_reported_out
= true;
675 dsp::zero(outs
[i
] + offset
, end
- offset
);
678 return total_out_mask
;
680 /// @return line_graph_iface if any
681 virtual const line_graph_iface
*get_line_graph_iface() const { return dynamic_cast<const line_graph_iface
*>(this); }
682 /// @return phase_graph_iface if any
683 virtual const phase_graph_iface
*get_phase_graph_iface() const { return dynamic_cast<const phase_graph_iface
*>(this); }
686 #if USE_EXEC_GUI || USE_DSSI
700 /// A class to send status updates via OSC
701 struct dssi_feedback_sender
703 /// OSC client object used to send updates
704 osctl::osc_client
*client
;
705 /// Is client shared with something else?
706 bool is_client_shared
;
707 /// Quit flag (used to terminate the thread)
709 /// Indices of graphs to send
710 std::vector
<int> indices
;
711 /// Source for the graph data (interface to marshal)
712 const calf_plugins::line_graph_iface
*graph
;
714 /// Source for the graph data (interface to marshal)
715 const calf_plugins::phase_graph_iface
*phase
;
717 /// Create using a new client
718 dssi_feedback_sender(const char *URI
, const line_graph_iface
*_graph
);
719 dssi_feedback_sender(osctl::osc_client
*_client
, const line_graph_iface
*_graph
);
720 void add_graphs(const calf_plugins::parameter_properties
*props
, int num_params
);
722 ~dssi_feedback_sender();
726 /// Metadata base class template, to provide default versions of interface functions
727 template<class Metadata
>
728 class plugin_metadata
: public plugin_metadata_iface
731 static const char *port_names
[];
732 static parameter_properties param_props
[];
733 static ladspa_plugin_info plugin_info
;
734 typedef plugin_metadata
<Metadata
> metadata_class
;
736 // These below are stock implementations based on enums and static members in Metadata classes
737 // they may be overridden to provide more interesting functionality
739 const char *get_name() const { return Metadata::impl_get_name(); }
740 const char *get_id() const { return Metadata::impl_get_id(); }
741 const char *get_label() const { return Metadata::impl_get_label(); }
742 int get_input_count() const { return Metadata::in_count
; }
743 int get_output_count() const { return Metadata::out_count
; }
744 int get_inputs_optional() const { return Metadata::ins_optional
; }
745 int get_outputs_optional() const { return Metadata::outs_optional
; }
746 int get_param_count() const { return Metadata::param_count
; }
747 bool get_midi() const { return Metadata::support_midi
; }
748 bool requires_midi() const { return Metadata::require_midi
; }
749 bool is_rt_capable() const { return Metadata::rt_capable
; }
750 int get_param_port_offset() const { return Metadata::in_count
+ Metadata::out_count
; }
751 const char *get_gui_xml() const { static const char *data_ptr
= calf_plugins::load_gui_xml(get_id()); return data_ptr
; }
752 plugin_command_info
*get_commands() const { return NULL
; }
753 const parameter_properties
*get_param_props(int param_no
) const { return ¶m_props
[param_no
]; }
754 const char **get_port_names() const { return port_names
; }
755 bool is_cv(int param_no
) const { return true; }
756 bool is_noisy(int param_no
) const { return false; }
757 const ladspa_plugin_info
&get_plugin_info() const { return plugin_info
; }
758 bool requires_configure() const { return false; }
759 bool get_simulate_stereo_input() const { return Metadata::simulate_stereo_input
; }
762 #define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata<name##_metadata>::port_names[]
763 #define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata<name##_metadata>::param_props[name##_metadata::param_count + 1]
764 #define CALF_PLUGIN_INFO(name) template<> calf_plugins::ladspa_plugin_info plugin_metadata<name##_metadata>::plugin_info
765 #define PLUGIN_NAME_ID_LABEL(name, id, label) \
766 static const char *impl_get_name() { return name; } \
767 static const char *impl_get_id() { return id; } \
768 static const char *impl_get_label() { return label; } \
770 extern const char *calf_copyright_info
;
772 bool get_freq_gridline(int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
, bool use_frequencies
= true, float res
= 256, float ofs
= 0.4);
774 /// convert amplitude value to normalized grid-ish value
775 static inline float dB_grid(float amp
, float res
= 256, float ofs
= 0.4)
777 return log(amp
) * (1.0 / log(res
)) + ofs
;
781 static bool get_graph(Fx
&fx
, int subindex
, float *data
, int points
, float res
= 256, float ofs
= 0.4)
783 for (int i
= 0; i
< points
; i
++)
785 //typedef std::complex<double> cfloat;
786 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
787 data
[i
] = dB_grid(fx
.freq_gain(subindex
, freq
), res
, ofs
);
792 /// convert normalized grid-ish value back to amplitude value
793 static inline float dB_grid_inv(float pos
)
795 return pow(256.0, pos
- 0.4);
798 /// Line graph interface implementation for frequency response graphs
799 class frequency_response_line_graph
: public line_graph_iface
802 mutable bool redraw_graph
;
803 virtual bool get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const;
804 virtual bool get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const;
805 virtual bool get_layers(int index
, int generation
, unsigned int &layers
) const;
806 virtual float freq_gain(int index
, double freq
) const { return 0; };
807 virtual std::string
get_crosshair_label( int x
, int y
, int sx
, int sy
, cairo_iface
*context
) const;
810 /// set drawing color based on channel index (0 or 1)
811 void set_channel_color(cairo_iface
*context
, int channel
, float alpha
= 0.6);
812 void set_channel_dash(cairo_iface
*context
, int channel
);
813 void draw_cairo_label(cairo_iface
*context
, const char *label
, float x
, float y
, int pos
, float margin
, float align
);
815 struct preset_access_iface
817 virtual void store_preset() = 0;
818 virtual void activate_preset(int preset
, bool builtin
) = 0;
819 virtual ~preset_access_iface() {}
822 /// Implementation of table_metadata_iface providing metadata for mod matrices
823 class mod_matrix_metadata
: public table_metadata_iface
828 map_positive
, ///< 0..100%
829 map_bipolar
, ///< -100%..100%
830 map_negative
, ///< -100%..0%
831 map_squared
, ///< x^2
832 map_squared_bipolar
, ///< x^2 scaled to -100%..100%
833 map_antisquared
, ///< 1-(1-x)^2 scaled to 0..100%
834 map_antisquared_bipolar
, ///< 1-(1-x)^2 scaled to -100..100%
835 map_parabola
, ///< inverted parabola (peaks at 0.5, then decreases to 0)
838 const char **mod_src_names
, **mod_dest_names
;
840 mod_matrix_metadata(unsigned int _rows
, const char **_src_names
, const char **_dest_names
);
841 virtual const table_column_info
*get_table_columns() const;
842 virtual uint32_t get_table_rows() const;
843 /// Return a list of configure variables used by the modulation matrix
844 void get_configure_vars(std::vector
<std::string
> &names
) const;
847 /// Column descriptions for table widget
848 table_column_info table_columns
[6];
850 unsigned int matrix_rows
;
853 /// Check if a given key is either prefix + rows or prefix + i2s(row) + "," + i2s(column)
854 /// @arg key key to parse
855 /// @arg prefix table prefix (e.g. "modmatrix:")
856 /// @arg is_rows[out] set to true if key == prefix + "rows"
857 /// @arg row[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
858 /// @arg column[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
859 /// @retval true if this is one of the recognized string forms
860 extern bool parse_table_key(const char *key
, const char *prefix
, bool &is_rows
, int &row
, int &column
);
863 class table_via_configure
866 typedef std::pair
<int, int> coord
;
867 std::vector
<table_column_info
> columns
;
868 std::map
<coord
, std::string
> values
;
871 table_via_configure();
872 void configure(const char *key
, const char *value
);
873 virtual ~table_via_configure();
877 struct automation_range
883 automation_range(float l
, float u
, int param
)
888 void send_configure(const plugin_metadata_iface
*metadata
, uint32_t from_controller
, send_configure_iface
*sci
);
889 static automation_range
*new_from_configure(const plugin_metadata_iface
*metadata
, const char *key
, const char *value
, uint32_t &from_controller
);
892 struct automation_map
: public std::multimap
<uint32_t, automation_range
>
896 inline float subindex_to_freq(int subindex
)
900 freq
= 10 * (subindex
+ 1);
901 else if (subindex
< 18)
902 freq
= 100 * (subindex
- 9 + 1);
903 else if (subindex
< 27)
904 freq
= 1000 * (subindex
- 18 + 1);
906 freq
= 10000 * (subindex
- 27 + 1);