X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fplugin.h;h=935b75faead0719bdb869998413e79d5a30710f2;hb=ace9ee194d4f6599c79242d6dc523af5099eab0f;hp=a69b87efbdf14da59ddce9cbc0aea969bc2be207;hpb=86343b6c15a3a43f082802484d2bc813d34db821;p=ardour.git diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index a69b87efbd..935b75faea 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -22,19 +22,21 @@ #include #include +#include #include "pbd/statefuldestructible.h" #include "pbd/controllable.h" -#include +#include "ardour/buffer_set.h" #include "ardour/chan_count.h" #include "ardour/chan_mapping.h" #include "ardour/cycles.h" #include "ardour/latent.h" -#include "ardour/plugin_insert.h" #include "ardour/libardour_visibility.h" -#include "ardour/types.h" #include "ardour/midi_state_tracker.h" +#include "ardour/parameter_descriptor.h" +#include "ardour/types.h" +#include "ardour/variant.h" #include #include @@ -45,49 +47,24 @@ namespace ARDOUR { class AudioEngine; class Session; class BufferSet; - +class PluginInsert; class Plugin; +class PluginInfo; +class AutomationControl; typedef boost::shared_ptr PluginPtr; - -class LIBARDOUR_API PluginInfo { - public: - PluginInfo () { } - virtual ~PluginInfo () { } - - std::string name; - std::string category; - std::string creator; - std::string path; - ChanCount n_inputs; - ChanCount n_outputs; - ARDOUR::PluginType type; - - std::string unique_id; - - virtual PluginPtr load (Session& session) = 0; - virtual bool is_instrument() const; - - /* NOTE: this block of virtual methods looks like the interface - to a Processor, but Plugin does not inherit from Processor. - It is therefore not required that these precisely match - the interface, but it is likely that they will evolve together. - */ - - /* this returns true if the plugin can change its inputs or outputs on demand. - LADSPA, LV2 and VST plugins cannot do this. AudioUnits can. - */ - - virtual bool reconfigurable_io() const { return false; } - - protected: - friend class PluginManager; - uint32_t index; -}; - typedef boost::shared_ptr PluginInfoPtr; typedef std::list PluginInfoList; - +typedef std::set PluginOutputConfiguration; + +/** A plugin is an external module (usually 3rd party provided) loaded into Ardour + * for the purpose of digital signal processing. + * + * This class provides an abstraction for methords provided by + * all supported plugin standards such as presets, name, parameters etc. + * + * Plugins are not used directly in Ardour but always wrapped by a PluginInsert. + */ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent { public: @@ -95,46 +72,11 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent Plugin (const Plugin&); virtual ~Plugin (); - struct ParameterDescriptor { - - ParameterDescriptor () - : integer_step(false) - , toggled (false) - , logarithmic (false) - , sr_dependent (false) - , lower (0) - , upper (0) - , step (0) - , smallstep (0) - , largestep (0) - , min_unbound (0) - , max_unbound (0) - , enumeration (false) - , midinote(false) - {} - - /* essentially a union of LADSPA, VST and LV2 info */ - - bool integer_step; - bool toggled; - bool logarithmic; - bool sr_dependent; - std::string label; - float lower; ///< if this is a frequency, it will be in Hz (not a fraction of the sample rate) - float upper; ///< if this is a frequency, it will be in Hz (not a fraction of the sample rate) - float step; - float smallstep; - float largestep; - bool min_unbound; - bool max_unbound; - bool enumeration; - bool midinote; ///< only used if integer_step is also true - }; - XMLNode& get_state (); virtual int set_state (const XMLNode &, int version); - virtual void set_insert_info (const PluginInsert*) {} + virtual void set_insert_id (PBD::ID id) {} + virtual void set_state_dir (const std::string& d = "") {} virtual std::string unique_id() const = 0; virtual const char * label() const = 0; @@ -153,10 +95,13 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent virtual void flush () { deactivate(); activate(); } virtual int set_block_size (pframes_t nframes) = 0; + virtual bool requires_fixed_sized_buffers() const { return false; } + virtual bool inplace_broken() const { return false; } virtual int connect_and_run (BufferSet& bufs, - ChanMapping in, ChanMapping out, - pframes_t nframes, framecnt_t offset); + framepos_t start, framepos_t end, double speed, + ChanMapping in, ChanMapping out, + pframes_t nframes, framecnt_t offset); virtual std::set automatable() const = 0; virtual std::string describe_parameter (Evoral::Parameter) = 0; @@ -168,7 +113,24 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent virtual bool parameter_is_input(uint32_t) const = 0; virtual bool parameter_is_output(uint32_t) const = 0; - typedef std::map ScalePoints; + struct LIBARDOUR_API IOPortDescription { + public: + IOPortDescription (const std::string& n) + : name (n) + , is_sidechain (false) + {} + IOPortDescription (const IOPortDescription &other) + : name (other.name) + , is_sidechain (other.is_sidechain) + {} + std::string name; + bool is_sidechain; + }; + + virtual IOPortDescription describe_io_port (DataType dt, bool input, uint32_t id) const; + virtual PluginOutputConfiguration possible_output () const; + + virtual void set_automation_control (uint32_t /*port_index*/, boost::shared_ptr) { } virtual boost::shared_ptr get_scale_points(uint32_t /*port_index*/) const { return boost::shared_ptr(); @@ -178,18 +140,29 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent void realtime_locate (); void monitoring_changed (); + typedef struct { + unsigned char *data; + int width; + int height; + int stride; + } Display_Image_Surface; + + virtual bool has_inline_display () { return false; } + virtual Display_Image_Surface* render_inline_display (uint32_t, uint32_t) { return NULL; } + PBD::Signal0 QueueDraw; + struct PresetRecord { - PresetRecord () : number (-1), user (true) {} - PresetRecord (const std::string& u, const std::string& l, int n = -1, bool s = true) : uri (u), label (l), number (n), user (s) {} - + PresetRecord () : valid (false) {} + PresetRecord (const std::string& u, const std::string& l, bool s = true) : uri (u), label (l), user (s), valid (true) {} + bool operator!= (PresetRecord const & a) const { - return number != a.number || uri != a.uri || label != a.label; + return uri != a.uri || label != a.label; } - + std::string uri; std::string label; - int number; // if <0, invalid bool user; + bool valid; }; PresetRecord save_preset (std::string); @@ -203,25 +176,25 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent std::vector get_presets (); - /** @return true if this plugin will respond to MIDI program + /** @return true if this plugin will respond to MIDI program * change messages by changing presets. * * This is hard to return a correct value for because most plugin APIs * do not specify plugin behaviour. However, if you want to force - * the display of plugin built-in preset names rather than MIDI program - * numbers, return true. If you want a generic description, return + * the display of plugin built-in preset names rather than MIDI program + * numbers, return true. If you want a generic description, return * false. - */ - virtual bool presets_are_MIDI_programs() const { return false; } + */ + virtual bool presets_are_MIDI_programs() const { return false; } - /** @return true if this plugin is General MIDI compliant, false + /** @return true if this plugin is General MIDI compliant, false * otherwise. * * It is important to note that it is is almost impossible for a host * (e.g. Ardour) to determine this for just about any plugin API * known as of June 2012 */ - virtual bool current_preset_uses_general_midi() const { return false; } + virtual bool current_preset_uses_general_midi() const { return false; } /** @return Last preset to be requested; the settings may have * been changed since; find out with parameter_changed_since_last_preset. @@ -238,24 +211,54 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent return 0; } + /** Emitted when a Latency Changes + * + * (this cannot be part of ARDOUR::Latent because + * signals cannot be copy-constructed). + */ + PBD::Signal2 LatencyChanged; + + /* overload Latent::set_user_latency w/signal emission */ + virtual void set_user_latency (framecnt_t val) { + bool changed = val != _user_latency; + framecnt_t old = effective_latency (); + _user_latency = val; + if (changed) { + LatencyChanged (old, effective_latency ()); /* EMIT SIGNAL */ + } + } + + /** the max possible latency a plugin will have */ + virtual framecnt_t max_latency () const { return 0; } // TODO = 0, require implementation + /** Emitted when a preset is added or removed, respectively */ PBD::Signal0 PresetAdded; PBD::Signal0 PresetRemoved; + /** Emitted when any preset has been changed */ + static PBD::Signal2 PresetsChanged; + /** Emitted when a preset has been loaded */ PBD::Signal0 PresetLoaded; + /** Emitted when a parameter is altered in a way that may have + * changed the settings with respect to any loaded preset. + */ + PBD::Signal0 PresetDirty; + virtual bool has_editor () const = 0; - /** Emitted when any parameter changes */ - PBD::Signal2 ParameterChanged; + /** Emitted when a parameter is altered by something outside of our + * control, most typically a Plugin GUI/editor + */ + PBD::Signal2 ParameterChangedExternally; virtual bool configure_io (ChanCount /*in*/, ChanCount /*out*/) { return true; } /* specific types of plugins can overload this. As of September 2008, only AUPlugin does this. */ - virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) { return false; } + virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/, ChanCount* imprecise = 0) { return false; } virtual ChanCount output_streams() const; virtual ChanCount input_streams() const; @@ -268,14 +271,58 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent void set_cycles (uint32_t c) { _cycles = c; } cycles_t cycles() const { return _cycles; } - PBD::Signal1 StartTouch; - PBD::Signal1 EndTouch; + typedef std::map PropertyDescriptors; + + /** Get a descrption of all properties supported by this plugin. + * + * Properties are distinct from parameters in that they are potentially + * dynamic, referred to by key, and do not correspond 1:1 with ports. + * + * For LV2 plugins, properties are implemented by sending/receiving set/get + * messages to/from the plugin via event ports. + */ + virtual const PropertyDescriptors& get_supported_properties() const { + static const PropertyDescriptors nothing; + return nothing; + } + + virtual const ParameterDescriptor& get_property_descriptor(uint32_t id) const { + static const ParameterDescriptor nothing; + return nothing; + } + + /** Set a property from the UI. + * + * This is not UI-specific, but may only be used by one thread. If the + * Ardour UI is present, that is the UI thread, but otherwise, any thread + * except the audio thread may call this function as long as it is not + * called concurrently. + */ + virtual void set_property(uint32_t key, const Variant& value) {} + + /** Emit PropertyChanged for all current property values. */ + virtual void announce_property_values() {} + + /** Emitted when a property is changed in the plugin. */ + PBD::Signal2 PropertyChanged; + + PBD::Signal1 StartTouch; + PBD::Signal1 EndTouch; protected: friend class PluginInsert; - friend struct PluginInsert::PluginControl; + friend class Session; + + /* Called when a parameter of the plugin is changed outside of this + * host's control (typical via a plugin's own GUI/editor) + */ + void parameter_changed_externally (uint32_t which, float val); + /* should be overridden by plugin API specific derived types to + * actually implement changing the parameter. The derived type should + * call this after the change is made. + */ virtual void set_parameter (uint32_t which, float val); /** Do the actual saving of the current plugin settings to a preset of the provided name. @@ -296,6 +343,8 @@ private: /** Fill _presets with our presets */ virtual void find_presets () = 0; + void update_presets (std::string src_unique_id, Plugin* src ); + /** Add state to an existing XMLNode */ virtual void add_state (XMLNode *) const = 0; @@ -306,11 +355,71 @@ private: PresetRecord _last_preset; bool _parameter_changed_since_last_preset; + PBD::ScopedConnection _preset_connection; + void resolve_midi (); }; +struct PluginPreset { + PluginInfoPtr _pip; + Plugin::PresetRecord _preset; + + PluginPreset (PluginInfoPtr pip, const Plugin::PresetRecord *preset = NULL) + : _pip (pip) + { + if (preset) { + _preset.uri = preset->uri; + _preset.label = preset->label; + _preset.user = preset->user; + _preset.valid = preset->valid; + } + } +}; + +typedef boost::shared_ptr PluginPresetPtr; +typedef std::list PluginPresetList; + PluginPtr find_plugin(ARDOUR::Session&, std::string unique_id, ARDOUR::PluginType); +class LIBARDOUR_API PluginInfo { + public: + PluginInfo () { } + virtual ~PluginInfo () { } + + std::string name; + std::string category; + std::string creator; + std::string path; + ChanCount n_inputs; + ChanCount n_outputs; + ARDOUR::PluginType type; + + std::string unique_id; + + virtual PluginPtr load (Session& session) = 0; + virtual bool is_instrument() const; + virtual bool needs_midi_input() const { return is_instrument (); } + virtual bool in_category (const std::string &) const { return false; } + + virtual std::vector get_presets (bool user_only) const = 0; + + /* NOTE: this block of virtual methods looks like the interface + to a Processor, but Plugin does not inherit from Processor. + It is therefore not required that these precisely match + the interface, but it is likely that they will evolve together. + */ + + /* this returns true if the plugin can change its inputs or outputs on demand. + LADSPA, LV2 and VST plugins cannot do this. AudioUnits can. + */ + + virtual bool reconfigurable_io() const { return false; } + + protected: + friend class PluginManager; + uint32_t index; +}; + } // namespace ARDOUR #endif /* __ardour_plugin_h__ */