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
= 0x000F00, ///< bit mask for control type
64 PF_CTL_DEFAULT
= 0x000000, ///< try to figure out automatically
65 PF_CTL_KNOB
= 0x000100, ///< knob
66 PF_CTL_FADER
= 0x000200, ///< fader (slider)
67 PF_CTL_TOGGLE
= 0x000300, ///< toggle button
68 PF_CTL_COMBO
= 0x000400, ///< combo box
69 PF_CTL_RADIO
= 0x000500, ///< radio button
70 PF_CTL_BUTTON
= 0x000600, ///< push button
71 PF_CTL_METER
= 0x000700, ///< volume meter
72 PF_CTL_LED
= 0x000800, ///< light emitting diode
73 PF_CTL_LABEL
= 0x000900, ///< 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_MASK
= 0x3F0000, ///< bit mask for properties
82 PF_PROP_NOBOUNDS
= 0x010000, ///< no epp:hasStrictBounds
83 PF_PROP_EXPENSIVE
= 0x020000, ///< epp:expensive, may trigger expensive calculation
84 PF_PROP_OUTPUT_GAIN
=0x040000, ///< epp:outputGain + skip epp:hasStrictBounds
85 PF_PROP_OPTIONAL
= 0x080000, ///< connection optional
86 PF_PROP_GRAPH
= 0x100000, ///< add graph
87 PF_PROP_OUTPUT
= 0x200000, ///< output port (flag, cannot be combined with others)
89 PF_UNITMASK
= 0x0F000000, ///< bit mask for units \todo reduce to use only 5 bits
90 PF_UNIT_DB
= 0x01000000, ///< decibels
91 PF_UNIT_COEF
= 0x02000000, ///< multiply-by factor
92 PF_UNIT_HZ
= 0x03000000, ///< Hertz
93 PF_UNIT_SEC
= 0x04000000, ///< second
94 PF_UNIT_MSEC
= 0x05000000, ///< millisecond
95 PF_UNIT_CENTS
= 0x06000000, ///< cents (1/100 of a semitone, 1/1200 of an octave)
96 PF_UNIT_SEMITONES
= 0x07000000,///< semitones
97 PF_UNIT_BPM
= 0x08000000, ///< beats per minute
98 PF_UNIT_DEG
= 0x09000000, ///< degrees
99 PF_UNIT_NOTE
= 0x0A000000, ///< MIDI note number
100 PF_UNIT_RPM
= 0x0B000000, ///< revolutions per minute
101 PF_UNIT_SAMPLES
= 0x0C000000, ///< samples
103 PF_SYNC_BPM
= 0x10000000, ///< sync a bpm setting with the host environment
105 PF_DIGITMASK
= 0xE0000000,
106 PF_DIGIT_0
= 0x20000000,
107 PF_DIGIT_1
= 0x40000000,
108 PF_DIGIT_2
= 0x60000000,
109 PF_DIGIT_3
= 0x80000000,
110 PF_DIGIT_ALL
= 0xA0000000,
113 /// A fake infinity value (because real infinity may break some hosts)
114 #define FAKE_INFINITY (65536.0 * 65536.0)
115 /// Check for infinity (with appropriate-ish tolerance)
116 #define IS_FAKE_INFINITY(value) (fabs(value-FAKE_INFINITY) < 1.0)
118 /// Information record about plugin's menu command
119 struct plugin_command_info
121 const char *label
; ///< short command name / label
122 const char *name
; ///< human-readable command name
123 const char *description
; ///< description (for status line etc.)
126 /// Range, default value, flags and names for a parameter
127 struct parameter_properties
135 /// 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
137 /// logical OR of parameter_flags
139 /// for PF_ENUM: array of text values (from min to max step 1), otherwise NULL
140 const char **choices
;
141 /// parameter label (for use in LV2 label field etc.)
142 const char *short_name
;
143 /// parameter human-readable name
145 /// convert from [0, 1] range to [min, max] (applying scaling)
146 float from_01(double value01
) const;
147 /// convert from [min, max] to [0, 1] range (applying reverse scaling)
148 double to_01(float value
) const;
149 /// stringify (in sensible way)
150 std::string
to_string(float value
) const;
151 /// convert string (from text entry) to value
152 float string_to_value(const char* string
) const;
153 /// get required width (for reserving GUI space)
154 int get_char_count() const;
155 /// get increment step based on step value (if specified) and other factors
156 float get_increment() const;
162 int size_x
, size_y
, pad_x
, pad_y
;
163 virtual void set_source_rgba(float r
, float g
, float b
, float a
= 1.f
) = 0;
164 virtual void set_line_width(float width
) = 0;
165 virtual void set_dash(const double *dash
, int length
) = 0;
166 virtual void draw_label(const char *label
, float x
, float y
, int pos
, float margin
, float align
) = 0;
167 virtual ~cairo_iface() {}
170 struct progress_report_iface
172 virtual void report_progress(float percentage
, const std::string
&message
) = 0;
173 virtual ~progress_report_iface() {}
176 /// possible bit masks for get_layers
179 LG_CACHE_GRID
= 0x000001,
180 LG_REALTIME_GRID
= 0x000002,
181 LG_CACHE_GRAPH
= 0x000004,
182 LG_REALTIME_GRAPH
= 0x000008,
183 LG_CACHE_DOT
= 0x000010,
184 LG_REALTIME_DOT
= 0x000020,
185 LG_CACHE_MOVING
= 0x000040,
186 LG_REALTIME_MOVING
= 0x000080
189 /// possible values for get_moving
190 enum moving_directions
{
191 LG_MOVING_LEFT
= 0x000000,
192 LG_MOVING_RIGHT
= 0x000001,
193 LG_MOVING_UP
= 0x000002,
194 LG_MOVING_DOWN
= 0x000004
197 /// 'provides live line graph values' interface
198 struct line_graph_iface
200 /// Obtain subindex'th graph of parameter 'index'
201 /// @param index parameter/graph number (usually tied to particular plugin control port)
202 /// @param subindex graph number (there may be multiple overlaid graphs for one parameter, eg. for monosynth 2x12dB filters)
203 /// @param phase 0 if in cache phase or 1 if in realtime phase
204 /// @param data buffer for normalized output values
205 /// @param points number of points to fill
206 /// @param context cairo context to adjust (for multicolour graphs etc.)
207 /// @retval true graph data was returned; subindex+1 graph may or may not be available
208 /// @retval false graph data was not returned; subindex+1 graph does not exist either
209 virtual bool get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
= 0) const { return false; }
211 /// Obtain subindex'th moving surface of parameter 'index'
212 /// @param index parameter/dot number (usually tied to particular plugin control port)
213 /// @param subindex mvoing line number (there may be multiple graphs for one parameter)
214 /// @param direction 0 if horizontal or 1 if vertical movement
215 /// @param data buffer for normalized output values
216 /// @param x number of points direction to fill in x
217 /// @param y number of points direction to fill in y
218 virtual bool get_moving(int index
, int subindex
, int &direction
, float *data
, int x
, int y
, int &offset
, uint32_t &color
) const { return false; }
220 /// Obtain subindex'th dot of parameter 'index'
221 /// @param index parameter/dot number (usually tied to particular plugin control port)
222 /// @param subindex dot number (there may be multiple dots graphs for one parameter)
223 /// @param phase 0 if in cache phase or 1 if in realtime phase
224 virtual bool get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const { return false; }
226 /// Obtain subindex'th dot of parameter 'index'
227 /// @param index parameter/dot number (usually tied to particular plugin control port)
228 /// @param subindex dot number (there may be multiple dots graphs for one parameter)
229 /// @param phase 0 if in cache phase or 1 if in realtime phase
230 virtual bool get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const { return false; }
232 /// Retrun which layers need to be redrawn in the next GTK drawing cycle
233 /// @param index Parameter/graph identifier (usually tied to particular plugin control port)
234 /// @param generation The overall amount of drawing cycles since the last full refresh of all surfaces
235 /// @param layers Bitmask defining the layers to be redrawn (see layers_flags above)
236 /// @retval true there's at least one layer to be redrawn; false nothing to draw in this cycle
237 virtual bool get_layers(int index
, int generation
, unsigned int &layers
) const { return false; }
239 /// Return a label for the crosshairs they are enabled
240 /// @param x Position of the mouse pointer in x direction
241 /// @param y Position of the mouse pointer in y direction
242 /// @param sx Horizontal size of the widget in pixels
243 /// @param sy Vertical size of the widget in pixels
244 virtual std::string
get_crosshair_label( int x
, int y
, int sx
, int sy
, int dB
, int name
, int note
, int cents
) const { std::string s
= ""; return s
; }
246 /// Standard destructor to make compiler happy
247 virtual ~line_graph_iface() {}
250 /// 'provides live line graph values' interface
251 struct phase_graph_iface
253 virtual bool get_phase_graph(float ** _buffer
, int *_length
, int * _mode
, bool * _use_fade
, float * _fade
, int * _accuracy
, bool * _display
) const { return false; };
254 virtual ~phase_graph_iface() {}
257 enum table_column_type
259 TCT_UNKNOWN
, ///< guard invalid type
260 TCT_FLOAT
, ///< float value (encoded as C locale string)
261 TCT_ENUM
, ///< enum value (see: 'values' array in table_column_info) - encoded as string base 10 representation of integer
262 TCT_STRING
, ///< string value (encoded as C-escaped string)
263 TCT_OBJECT
, ///< external object, encoded as string
264 TCT_LABEL
, ///< string value (encoded as C-escaped string)
268 struct table_column_info
270 const char *name
; ///< column label
271 table_column_type type
; ///< column data type
272 float min
; ///< minimum value (for float)
273 float max
; ///< maximum value (for float and enum)
274 float def_value
; ///< default value (for float and enum)
275 const char **values
; ///< NULL unless a TCT_ENUM, where it represents a NULL-terminated list of choices
278 /// 'has string parameters containing tabular data' interface
279 struct table_metadata_iface
281 /// retrieve the table layout for specific parameter
282 virtual const table_column_info
*get_table_columns() const = 0;
284 /// return the fixed number of rows, or 0 if the number of rows is variable
285 virtual uint32_t get_table_rows() const = 0;
287 virtual ~table_metadata_iface() {}
290 /// 'may receive configure variables' interface
291 struct send_configure_iface
293 /// Called to set configure variable
294 /// @param key variable name
295 /// @param value variable content
296 virtual void send_configure(const char *key
, const char *value
) = 0;
298 virtual ~send_configure_iface() {}
301 /// 'may receive new status values' interface
302 struct send_updates_iface
304 /// Called to set configure variable
305 /// @param key variable name
306 /// @param value variable content
307 virtual void send_status(const char *key
, const char *value
) = 0;
309 virtual ~send_updates_iface() {}
312 struct plugin_command_info
;
314 /// General information about the plugin - @todo XXXKF lacks the "new" id-label-name triple
315 struct ladspa_plugin_info
319 /// plugin short name (camel case)
321 /// plugin human-readable name
326 const char *copyright
;
327 /// plugin type for LRDF/LV2
328 const char *plugin_type
;
331 /// An interface returning metadata about a plugin
332 struct plugin_metadata_iface
334 enum { simulate_stereo_input
= true };
335 /// @return plugin long name
336 virtual const char *get_name() const = 0;
337 /// @return plugin LV2 label
338 virtual const char *get_id() const = 0;
339 /// @return plugin human-readable label
340 virtual const char *get_label() const = 0;
341 /// @return total number of parameters
342 virtual int get_param_count() const = 0;
343 /// Return custom XML
344 virtual const char *get_gui_xml() const = 0;
345 /// @return number of audio inputs
346 virtual int get_input_count() const =0;
347 /// @return number of audio outputs
348 virtual int get_output_count() const =0;
349 /// @return number of optional inputs
350 virtual int get_inputs_optional() const =0;
351 /// @return number of optional outputs
352 virtual int get_outputs_optional() const =0;
353 /// @return true if plugin can work in hard-realtime conditions
354 virtual bool is_rt_capable() const =0;
355 /// @return true if plugin has MIDI input
356 virtual bool get_midi() const =0;
357 /// @return true if plugin has MIDI input
358 virtual bool requires_midi() const =0;
359 /// @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)
360 virtual int get_param_port_offset() const = 0;
361 /// @return NULL-terminated list of menu commands
362 virtual plugin_command_info
*get_commands() const { return NULL
; }
363 /// @return description structure for given parameter
364 virtual const parameter_properties
*get_param_props(int param_no
) const = 0;
365 /// @return retrieve names of audio ports (@note control ports are named in parameter_properties, not here)
366 virtual const char **get_port_names() const = 0;
367 /// @return description structure for the plugin
368 virtual const ladspa_plugin_info
&get_plugin_info() const = 0;
369 /// is a given parameter a control voltage?
370 virtual bool is_cv(int param_no
) const = 0;
371 /// is the given parameter non-interpolated?
372 virtual bool is_noisy(int param_no
) const = 0;
373 /// does the plugin require string port extension? (or DSSI configure) may be slow
374 virtual bool requires_configure() const = 0;
375 /// obtain array of names of configure variables (or NULL is none needed)
376 virtual void get_configure_vars(std::vector
<std::string
> &names
) const { names
.clear(); }
377 /// @return table_metadata_iface if any
378 virtual const table_metadata_iface
*get_table_metadata_iface(const char *key
) const { return NULL
; }
379 /// @return whether to auto-connect right input with left input if unconnected
380 virtual bool get_simulate_stereo_input() const = 0;
382 /// Do-nothing destructor to silence compiler warning
383 virtual ~plugin_metadata_iface() {}
386 /// Interface for host-GUI-plugin interaction (should be really split in two, but ... meh)
387 struct plugin_ctl_iface
389 /// @return value of given parameter
390 virtual float get_param_value(int param_no
) = 0;
391 /// Set value of given parameter
392 virtual void set_param_value(int param_no
, float value
) = 0;
393 /// Load preset with given number
394 virtual bool activate_preset(int bank
, int program
) = 0;
395 /// @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)
396 virtual float get_level(unsigned int port
)=0;
397 /// Execute menu command with given number
398 virtual void execute(int cmd_no
)=0;
399 /// Set a configure variable on a plugin
400 virtual char *configure(const char *key
, const char *value
) = 0;
401 /// Send all configure variables set within a plugin to given destination (which may be limited to only those that plugin understands)
402 virtual void send_configures(send_configure_iface
*)=0;
403 /// Restore all state (parameters and configure vars) to default values - implemented in giface.cpp
404 virtual void clear_preset();
405 /// Call a named function in a plugin - this will most likely be redesigned soon - and never used
406 /// @retval false call has failed, result contains an error message
407 virtual bool blobcall(const char *command
, const std::string
&request
, std::string
&result
) { result
= "Call not supported"; return false; }
408 /// Update status variables changed since last_serial
409 /// @return new last_serial
410 virtual int send_status_updates(send_updates_iface
*sui
, int last_serial
) = 0;
411 /// Return metadata object
412 virtual const plugin_metadata_iface
*get_metadata_iface() const = 0;
413 /// @return line_graph_iface if any
414 virtual const line_graph_iface
*get_line_graph_iface() const = 0;
415 /// @return phase_graph_iface if any
416 virtual const phase_graph_iface
*get_phase_graph_iface() const = 0;
417 /// @return serial number of last automation write (JACK host only)
418 virtual int get_write_serial(int param_no
) { return 0; }
420 /// Add or update parameter automation routing
421 virtual void add_automation(uint32_t source
, const automation_range
&dest
) {}
422 /// Remove parameter automation routing
423 virtual void delete_automation(uint32_t source
, int param_no
) {}
424 /// Retrieve automation list for a given parameter
425 /// @param param_no parameter to retrieve automation list for, or -1 for all
426 virtual void get_automation(int param_no
, std::multimap
<uint32_t, automation_range
> &dests
) {}
427 /// Return the source identifier for the most recently seen control change that could be used for automation
428 virtual uint32_t get_last_automation_source() { return 0xFFFFFFFF; }
429 virtual void send_automation_configures(send_configure_iface
*) {}
430 /// Do-nothing destructor to silence compiler warning
431 virtual ~plugin_ctl_iface() {}
434 struct plugin_list_info_iface
;
436 /// A class to retrieve and query the list of Calf plugins
437 class plugin_registry
440 typedef std::vector
<const plugin_metadata_iface
*> plugin_vector
;
442 plugin_vector plugins
;
445 /// Get the singleton object.
446 static plugin_registry
&instance();
448 /// Get all plugin metadata objects
449 const plugin_vector
&get_all() { return plugins
; }
450 /// Get single plugin metadata object by URI
451 const plugin_metadata_iface
*get_by_uri(const char *URI
);
452 /// Get single plugin metadata object by URI
453 const plugin_metadata_iface
*get_by_id(const char *id
, bool case_sensitive
= false);
456 /// Load and strdup a text file with GUI definition
457 extern const char *load_gui_xml(const std::string
&plugin_id
);
459 /// Interface to audio processing plugins (the real things, not only metadata)
460 struct audio_module_iface
462 /// Handle MIDI Note On
463 virtual void note_on(int channel
, int note
, int velocity
) = 0;
464 /// Handle MIDI Note Off
465 virtual void note_off(int channel
, int note
, int velocity
) = 0;
466 /// Handle MIDI Program Change
467 virtual void program_change(int channel
, int program
) = 0;
468 /// Handle MIDI Control Change
469 virtual void control_change(int channel
, int controller
, int value
) = 0;
470 /// Handle MIDI Pitch Bend
471 /// @param value pitch bend value (-8192 to 8191, defined as in MIDI ie. 8191 = 200 ct by default)
472 virtual void pitch_bend(int channel
, int value
) = 0;
473 /// Handle MIDI Channel Pressure
474 /// @param value channel pressure (0 to 127)
475 virtual void channel_pressure(int channel
, int value
) = 0;
476 /// Called when params are changed (before processing)
477 virtual void params_changed() = 0;
478 /// LADSPA-esque activate function, except it is called after ports are connected, not before
479 virtual void activate() = 0;
480 /// LADSPA-esque deactivate function
481 virtual void deactivate() = 0;
482 /// Set sample rate for the plugin
483 virtual void set_sample_rate(uint32_t sr
) = 0;
484 /// Execute menu command with given number
485 virtual void execute(int cmd_no
) = 0;
486 /// DSSI configure call, value = NULL = reset to default
487 virtual char *configure(const char *key
, const char *value
) = 0;
488 /// Send all understood configure vars (none by default)
489 virtual void send_configures(send_configure_iface
*sci
) = 0;
490 /// Send all supported status vars (none by default)
491 virtual int send_status_updates(send_updates_iface
*sui
, int last_serial
) = 0;
492 /// Reset parameter values for epp:trigger type parameters (ones activated by oneshot push button instead of check box)
493 virtual void params_reset() = 0;
494 /// Called after instantiating (after all the feature pointers are set - including interfaces like progress_report_iface)
495 virtual void post_instantiate(uint32_t sample_rate
) = 0;
496 /// Return the arrays of port buffer pointers
497 virtual void get_port_arrays(float **&ins_ptrs
, float **&outs_ptrs
, float **¶ms_ptrs
) = 0;
498 /// Return metadata object
499 virtual const plugin_metadata_iface
*get_metadata_iface() const = 0;
500 /// Set the progress report interface to communicate progress to
501 virtual void set_progress_report_iface(progress_report_iface
*iface
) = 0;
502 /// 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
503 virtual uint32_t process_slice(uint32_t offset
, uint32_t end
) = 0;
504 /// The audio processing loop; assumes numsamples <= MAX_SAMPLE_RUN, for larger buffers, call process_slice
505 virtual uint32_t process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) = 0;
506 /// Message port processing function
507 virtual uint32_t message_run(const void *valid_ports
, void *output_ports
) = 0;
508 /// @return line_graph_iface if any
509 virtual const line_graph_iface
*get_line_graph_iface() const = 0;
510 /// @return phase_graph_iface if any
511 virtual const phase_graph_iface
*get_phase_graph_iface() const = 0;
512 virtual ~audio_module_iface() {}
515 /// Empty implementations for plugin functions.
516 template<class Metadata
>
517 class audio_module
: public Metadata
, public audio_module_iface
520 typedef Metadata metadata_type
;
521 using Metadata::in_count
;
522 using Metadata::out_count
;
523 using Metadata::param_count
;
524 float *ins
[Metadata::in_count
];
525 float *outs
[Metadata::out_count
];
526 float *params
[Metadata::param_count
];
527 bool questionable_data_reported_in
;
528 bool questionable_data_reported_out
;
530 progress_report_iface
*progress_report
;
533 progress_report
= NULL
;
534 memset(ins
, 0, sizeof(ins
));
535 memset(outs
, 0, sizeof(outs
));
536 memset(params
, 0, sizeof(params
));
537 questionable_data_reported_in
= false;
538 questionable_data_reported_out
= false;
541 /// Handle MIDI Note On
542 void note_on(int channel
, int note
, int velocity
) {}
543 /// Handle MIDI Note Off
544 void note_off(int channel
, int note
, int velocity
) {}
545 /// Handle MIDI Program Change
546 void program_change(int channel
, int program
) {}
547 /// Handle MIDI Control Change
548 void control_change(int channel
, int controller
, int value
) {}
549 /// Handle MIDI Pitch Bend
550 /// @param value pitch bend value (-8192 to 8191, defined as in MIDI ie. 8191 = 200 ct by default)
551 void pitch_bend(int channel
, int value
) {}
552 /// Handle MIDI Channel Pressure
553 /// @param value channel pressure (0 to 127)
554 void channel_pressure(int channel
, int value
) {}
555 /// Called when params are changed (before processing)
556 void params_changed() {}
557 /// LADSPA-esque activate function, except it is called after ports are connected, not before
559 /// LADSPA-esque deactivate function
561 /// Set sample rate for the plugin
562 void set_sample_rate(uint32_t sr
) { }
563 /// Execute menu command with given number
564 void execute(int cmd_no
) {}
565 /// DSSI configure call
566 virtual char *configure(const char *key
, const char *value
) { return NULL
; }
567 /// Send all understood configure vars (none by default)
568 void send_configures(send_configure_iface
*sci
) {}
569 /// Send all supported status vars (none by default)
570 int send_status_updates(send_updates_iface
*sui
, int last_serial
) { return last_serial
; }
571 /// Reset parameter values for epp:trigger type parameters (ones activated by oneshot push button instead of check box)
572 void params_reset() {}
573 /// Called after instantiating (after all the feature pointers are set - including interfaces like progress_report_iface)
574 void post_instantiate(uint32_t) {}
575 /// Handle 'message context' port message
576 /// @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)
577 uint32_t message_run(const void *valid_ports
, void *output_ports
) {
578 fprintf(stderr
, "ERROR: message run not implemented\n");
581 /// Return the array of input port pointers
582 virtual void get_port_arrays(float **&ins_ptrs
, float **&outs_ptrs
, float **¶ms_ptrs
)
586 params_ptrs
= params
;
588 /// Return metadata object
589 virtual const plugin_metadata_iface
*get_metadata_iface() const { return this; }
590 /// Set the progress report interface to communicate progress to
591 virtual void set_progress_report_iface(progress_report_iface
*iface
) { progress_report
= iface
; }
593 /// utility function: zero port values if mask is 0
594 inline void zero_by_mask(uint32_t mask
, uint32_t offset
, uint32_t nsamples
)
596 for (int i
=0; i
<Metadata::out_count
; i
++) {
597 if ((mask
& (1 << i
)) == 0) {
598 dsp::zero(outs
[i
] + offset
, nsamples
);
602 /// utility function: call process, and if it returned zeros in output masks, zero out the relevant output port buffers
603 uint32_t process_slice(uint32_t offset
, uint32_t end
)
605 bool had_errors
= false;
606 for (int i
=0; i
<Metadata::in_count
; ++i
) {
607 float *indata
= ins
[i
];
610 for (uint32_t j
= offset
; j
< end
; j
++)
612 if (!std::isfinite(indata
[j
]) || fabs(indata
[j
]) > 4294967296.0) {
617 if (had_errors
&& !questionable_data_reported_in
) {
618 fprintf(stderr
, "Warning: Plugin %s got questionable value %f on its input %d\n", Metadata::get_name(), errval
, i
);
619 questionable_data_reported_in
= true;
623 uint32_t total_out_mask
= 0;
626 uint32_t newend
= std::min(offset
+ MAX_SAMPLE_RUN
, end
);
627 uint32_t out_mask
= !had_errors
? process(offset
, newend
- offset
, -1, -1) : 0;
628 total_out_mask
|= out_mask
;
629 zero_by_mask(out_mask
, offset
, newend
- offset
);
632 for (int i
=0; i
<Metadata::out_count
; ++i
) {
633 if (total_out_mask
& (1 << i
))
636 float *outdata
= outs
[i
];
638 for (uint32_t j
= offset
; j
< end
; j
++)
640 if (!std::isfinite(outdata
[j
]) || fabs(outdata
[j
]) > 4294967296.0) {
645 if (had_errors
&& !questionable_data_reported_out
) {
646 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
);
647 questionable_data_reported_out
= true;
650 dsp::zero(outs
[i
] + offset
, end
- offset
);
653 return total_out_mask
;
655 /// @return line_graph_iface if any
656 virtual const line_graph_iface
*get_line_graph_iface() const { return dynamic_cast<const line_graph_iface
*>(this); }
657 /// @return phase_graph_iface if any
658 virtual const phase_graph_iface
*get_phase_graph_iface() const { return dynamic_cast<const phase_graph_iface
*>(this); }
661 #if USE_EXEC_GUI || USE_DSSI
675 /// A class to send status updates via OSC
676 struct dssi_feedback_sender
678 /// OSC client object used to send updates
679 osctl::osc_client
*client
;
680 /// Is client shared with something else?
681 bool is_client_shared
;
682 /// Quit flag (used to terminate the thread)
684 /// Indices of graphs to send
685 std::vector
<int> indices
;
686 /// Source for the graph data (interface to marshal)
687 const calf_plugins::line_graph_iface
*graph
;
689 /// Source for the graph data (interface to marshal)
690 const calf_plugins::phase_graph_iface
*phase
;
692 /// Create using a new client
693 dssi_feedback_sender(const char *URI
, const line_graph_iface
*_graph
);
694 dssi_feedback_sender(osctl::osc_client
*_client
, const line_graph_iface
*_graph
);
695 void add_graphs(const calf_plugins::parameter_properties
*props
, int num_params
);
697 ~dssi_feedback_sender();
701 /// Metadata base class template, to provide default versions of interface functions
702 template<class Metadata
>
703 class plugin_metadata
: public plugin_metadata_iface
706 static const char *port_names
[];
707 static parameter_properties param_props
[];
708 static ladspa_plugin_info plugin_info
;
709 typedef plugin_metadata
<Metadata
> metadata_class
;
711 // These below are stock implementations based on enums and static members in Metadata classes
712 // they may be overridden to provide more interesting functionality
714 const char *get_name() const { return Metadata::impl_get_name(); }
715 const char *get_id() const { return Metadata::impl_get_id(); }
716 const char *get_label() const { return Metadata::impl_get_label(); }
717 int get_input_count() const { return Metadata::in_count
; }
718 int get_output_count() const { return Metadata::out_count
; }
719 int get_inputs_optional() const { return Metadata::ins_optional
; }
720 int get_outputs_optional() const { return Metadata::outs_optional
; }
721 int get_param_count() const { return Metadata::param_count
; }
722 bool get_midi() const { return Metadata::support_midi
; }
723 bool requires_midi() const { return Metadata::require_midi
; }
724 bool is_rt_capable() const { return Metadata::rt_capable
; }
725 int get_param_port_offset() const { return Metadata::in_count
+ Metadata::out_count
; }
726 const char *get_gui_xml() const { static const char *data_ptr
= calf_plugins::load_gui_xml(get_id()); return data_ptr
; }
727 plugin_command_info
*get_commands() const { return NULL
; }
728 const parameter_properties
*get_param_props(int param_no
) const { return ¶m_props
[param_no
]; }
729 const char **get_port_names() const { return port_names
; }
730 bool is_cv(int param_no
) const { return true; }
731 bool is_noisy(int param_no
) const { return false; }
732 const ladspa_plugin_info
&get_plugin_info() const { return plugin_info
; }
733 bool requires_configure() const { return false; }
734 bool get_simulate_stereo_input() const { return Metadata::simulate_stereo_input
; }
737 #define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata<name##_metadata>::port_names[]
738 #define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata<name##_metadata>::param_props[name##_metadata::param_count + 1]
739 #define CALF_PLUGIN_INFO(name) template<> calf_plugins::ladspa_plugin_info plugin_metadata<name##_metadata>::plugin_info
740 #define PLUGIN_NAME_ID_LABEL(name, id, label) \
741 static const char *impl_get_name() { return name; } \
742 static const char *impl_get_id() { return id; } \
743 static const char *impl_get_label() { return label; } \
745 extern const char *calf_copyright_info
;
747 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);
749 /// convert amplitude value to normalized grid-ish value
750 static inline float dB_grid(float amp
, float res
= 256, float ofs
= 0.4)
752 return log(amp
) * (1.0 / log(res
)) + ofs
;
756 static bool get_graph(Fx
&fx
, int subindex
, float *data
, int points
, float res
= 256, float ofs
= 0.4)
758 for (int i
= 0; i
< points
; i
++)
760 //typedef std::complex<double> cfloat;
761 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
762 data
[i
] = dB_grid(fx
.freq_gain(subindex
, freq
), res
, ofs
);
767 /// convert normalized grid-ish value back to amplitude value
768 static inline float dB_grid_inv(float pos
, float res
= 256, float ofs
= 0.4)
770 return pow(res
, pos
- ofs
);
773 /// Line graph interface implementation for frequency response graphs
774 class frequency_response_line_graph
: public line_graph_iface
777 mutable bool redraw_graph
;
778 virtual bool get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const;
779 virtual bool get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const;
780 virtual bool get_layers(int index
, int generation
, unsigned int &layers
) const;
781 virtual float freq_gain(int index
, double freq
) const { return 0; };
782 virtual std::string
get_crosshair_label( int x
, int y
, int sx
, int sy
, int dB
, int name
, int note
, int cents
) const;
784 std::string
frequency_crosshair_label(int x
, int y
, int sx
, int sy
, int dB
, int name
, int note
, int cents
, double res
= 256, double ofs
= 0.4);
787 /// set drawing color based on channel index (0 or 1)
788 void set_channel_color(cairo_iface
*context
, int channel
, float alpha
= 0.6);
789 void set_channel_dash(cairo_iface
*context
, int channel
);
790 void draw_cairo_label(cairo_iface
*context
, const char *label
, float x
, float y
, int pos
, float margin
, float align
);
792 struct preset_access_iface
794 virtual void store_preset() = 0;
795 virtual void activate_preset(int preset
, bool builtin
) = 0;
796 virtual ~preset_access_iface() {}
799 /// Implementation of table_metadata_iface providing metadata for mod matrices
800 class mod_matrix_metadata
: public table_metadata_iface
805 map_positive
, ///< 0..100%
806 map_bipolar
, ///< -100%..100%
807 map_negative
, ///< -100%..0%
808 map_squared
, ///< x^2
809 map_squared_bipolar
, ///< x^2 scaled to -100%..100%
810 map_antisquared
, ///< 1-(1-x)^2 scaled to 0..100%
811 map_antisquared_bipolar
, ///< 1-(1-x)^2 scaled to -100..100%
812 map_parabola
, ///< inverted parabola (peaks at 0.5, then decreases to 0)
815 const char **mod_src_names
, **mod_dest_names
;
817 mod_matrix_metadata(unsigned int _rows
, const char **_src_names
, const char **_dest_names
);
818 virtual const table_column_info
*get_table_columns() const;
819 virtual uint32_t get_table_rows() const;
820 /// Return a list of configure variables used by the modulation matrix
821 void get_configure_vars(std::vector
<std::string
> &names
) const;
824 /// Column descriptions for table widget
825 table_column_info table_columns
[6];
827 unsigned int matrix_rows
;
830 /// Check if a given key is either prefix + rows or prefix + i2s(row) + "," + i2s(column)
831 /// @arg key key to parse
832 /// @arg prefix table prefix (e.g. "modmatrix:")
833 /// @arg is_rows[out] set to true if key == prefix + "rows"
834 /// @arg row[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
835 /// @arg column[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
836 /// @retval true if this is one of the recognized string forms
837 extern bool parse_table_key(const char *key
, const char *prefix
, bool &is_rows
, int &row
, int &column
);
840 class table_via_configure
843 typedef std::pair
<int, int> coord
;
844 std::vector
<table_column_info
> columns
;
845 std::map
<coord
, std::string
> values
;
848 table_via_configure();
849 void configure(const char *key
, const char *value
);
850 virtual ~table_via_configure();
854 struct automation_range
860 automation_range(float l
, float u
, int param
)
865 void send_configure(const plugin_metadata_iface
*metadata
, uint32_t from_controller
, send_configure_iface
*sci
);
866 static automation_range
*new_from_configure(const plugin_metadata_iface
*metadata
, const char *key
, const char *value
, uint32_t &from_controller
);
869 struct automation_map
: public std::multimap
<uint32_t, automation_range
>
873 inline float subindex_to_freq(int subindex
)
877 freq
= 10 * (subindex
+ 1);
878 else if (subindex
< 18)
879 freq
= 100 * (subindex
- 9 + 1);
880 else if (subindex
< 27)
881 freq
= 1000 * (subindex
- 18 + 1);
883 freq
= 10000 * (subindex
- 27 + 1);