X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Flv2_plugin.h;h=5154cd4d3e710cc8148e3a3322f2c44ed9096ef0;hb=490311bc081b12d328e6e02cac8170538e96fb2f;hp=9705459ee1dc7e9f53168470bf482e993e1e7fc3;hpb=155338d168b362dd135597695aaa1e419831a277;p=ardour.git diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index 9705459ee1..5154cd4d3e 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2008 Paul Davis - Author: Dave Robillard + Copyright (C) 2008-2012 Paul Davis + Author: David Robillard This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,181 +15,272 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ #ifndef __ardour_lv2_plugin_h__ #define __ardour_lv2_plugin_h__ #include -#include #include -#include - -#include - -#include "pbd/stateful.h" +#include -#include -#include #include "ardour/plugin.h" #include "ardour/uri_map.h" +#include "ardour/worker.h" +#include "pbd/ringbuffer.h" + +typedef struct LV2_Evbuf_Impl LV2_Evbuf; namespace ARDOUR { + +// a callback function for lilv_state_new_from_instance(). friend of LV2Plugin +// so we can pass an LV2Plugin* in user_data and access its private members. +const void* lv2plugin_get_port_value(const char* port_symbol, + void* user_data, + uint32_t* size, + uint32_t* type); + class AudioEngine; class Session; -struct LV2World; -class LV2Plugin : public ARDOUR::Plugin +class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee { public: - LV2Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&, ARDOUR::LV2World&, SLV2Plugin plugin, nframes_t sample_rate); + LV2Plugin (ARDOUR::AudioEngine& engine, + ARDOUR::Session& session, + const void* c_plugin, + framecnt_t sample_rate); LV2Plugin (const LV2Plugin &); ~LV2Plugin (); - /* Plugin interface */ + std::string unique_id () const; + const char* uri () const; + const char* label () const; + const char* name () const; + const char* maker () const; - std::string unique_id() const; - const char* label() const { return slv2_value_as_string(_name); } - const char* name() const { return slv2_value_as_string(_name); } - const char* maker() const { return _author ? slv2_value_as_string(_author) : "Unknown"; } - uint32_t parameter_count() const { return slv2_plugin_get_num_ports(_plugin); } + uint32_t num_ports () const; + uint32_t parameter_count () const; float default_value (uint32_t port); - nframes_t signal_latency() const; + framecnt_t signal_latency () const; void set_parameter (uint32_t port, float val); float get_parameter (uint32_t port) const; + std::string get_docs() const; + std::string get_parameter_docs(uint32_t which) const; int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const; uint32_t nth_parameter (uint32_t port, bool& ok) const; - const void* extension_data(const char* uri) { return _instance->lv2_descriptor->extension_data(uri); } - - SLV2Plugin slv2_plugin() { return _plugin; } - SLV2UI slv2_ui() { return _ui; } - bool is_external_ui() const; - SLV2Port slv2_port(uint32_t i) { return slv2_plugin_get_port_by_index(_plugin, i); } + const void* extension_data (const char* uri) const; - const char* port_symbol(uint32_t port); + const void* c_plugin(); + const void* c_ui(); + const void* c_ui_type(); - const LV2_Feature* const* features() { return _features; } + bool is_external_ui () const; + bool ui_is_resizable () const; - std::set automatable() const; + const char* port_symbol (uint32_t port) const; + uint32_t port_index (const char* symbol) const; - void activate () { - if (!_was_activated) { - slv2_instance_activate(_instance); - _was_activated = true; - } - } + const LV2_Feature* const* features () { return _features; } - void deactivate () { - if (_was_activated) { - slv2_instance_deactivate(_instance); - _was_activated = false; - } - } + std::set automatable () const; - void cleanup () { - activate(); - deactivate(); - slv2_instance_free(_instance); - _instance = NULL; - } + void activate (); + void deactivate (); + void cleanup (); - void set_block_size (nframes_t /*nframes*/) {} + int set_block_size (pframes_t /*nframes*/) { return 0; } int connect_and_run (BufferSet& bufs, - ChanMapping in, ChanMapping out, - nframes_t nframes, nframes_t offset); + ChanMapping in, ChanMapping out, + pframes_t nframes, framecnt_t offset); std::string describe_parameter (Evoral::Parameter); - std::string state_node_name() const { return "lv2"; } - void print_parameter (uint32_t, char*, uint32_t len) const; + std::string state_node_name () const { return "lv2"; } + + void print_parameter (uint32_t param, + char* buf, + uint32_t len) const; + + bool parameter_is_audio (uint32_t) const; + bool parameter_is_control (uint32_t) const; + bool parameter_is_event (uint32_t) const; + bool parameter_is_input (uint32_t) const; + bool parameter_is_output (uint32_t) const; + bool parameter_is_toggled (uint32_t) const; + + boost::shared_ptr + get_scale_points(uint32_t port_index) const; + + void set_insert_info(const PluginInsert* insert); + + int set_state (const XMLNode& node, int version); + bool save_preset (std::string uri); + void remove_preset (std::string uri); + bool load_preset (PresetRecord); + std::string current_preset () const; + + bool has_editor () const; + bool has_message_output () const; + + bool write_from_ui(uint32_t index, + uint32_t protocol, + uint32_t size, + const uint8_t* body); + + typedef void UIMessageSink(void* controller, + uint32_t index, + uint32_t size, + uint32_t format, + const void* buffer); + + void enable_ui_emmission(); + void emit_to_ui(void* controller, UIMessageSink sink); + + Worker* worker() { return _worker; } + + int work(uint32_t size, const void* data); + int work_response(uint32_t size, const void* data); + + static URIMap _uri_map; + + struct URIDs { + uint32_t atom_Chunk; + uint32_t atom_Path; + uint32_t atom_Sequence; + uint32_t atom_eventTransfer; + uint32_t log_Error; + uint32_t log_Note; + uint32_t log_Warning; + uint32_t midi_MidiEvent; + uint32_t time_Position; + uint32_t time_bar; + uint32_t time_barBeat; + uint32_t time_beatUnit; + uint32_t time_beatsPerBar; + uint32_t time_beatsPerMinute; + uint32_t time_frame; + uint32_t time_speed; + }; + + static URIDs urids; - bool parameter_is_audio(uint32_t) const; - bool parameter_is_control(uint32_t) const; - bool parameter_is_midi(uint32_t) const; - bool parameter_is_input(uint32_t) const; - bool parameter_is_output(uint32_t) const; - bool parameter_is_toggled(uint32_t) const; + private: + struct Impl; + Impl* _impl; + void* _module; + LV2_Feature** _features; + Worker* _worker; + framecnt_t _sample_rate; + float* _control_data; + float* _shadow_data; + float* _defaults; + LV2_Evbuf** _ev_buffers; + LV2_Evbuf** _atom_ev_buffers; + float* _bpm_control_port; ///< Special input set by ardour + float* _freewheel_control_port; ///< Special input set by ardour + float* _latency_control_port; ///< Special output set by ardour + framepos_t _next_cycle_start; ///< Expected start frame of next run cycle + double _next_cycle_speed; ///< Expected start frame of next run cycle + PBD::ID _insert_id; + + friend const void* lv2plugin_get_port_value(const char* port_symbol, + void* user_data, + uint32_t* size, + uint32_t* type); + + typedef enum { + PORT_INPUT = 1, ///< Input port + PORT_OUTPUT = 1 << 1, ///< Output port + PORT_AUDIO = 1 << 2, ///< Audio (buffer of float) + PORT_CONTROL = 1 << 3, ///< Control (single float) + PORT_EVENT = 1 << 4, ///< Old event API event port + PORT_SEQUENCE = 1 << 5, ///< New atom API event port + PORT_MIDI = 1 << 6, ///< Event port understands MIDI + PORT_POSITION = 1 << 7 ///< Event port understands position + } PortFlag; + + typedef unsigned PortFlags; + + std::vector _port_flags; + std::vector _port_minimumSize; + std::map _port_indices; - static uint32_t midi_event_type() { return _midi_event_type; } + /// Message send to/from UI via ports + struct UIMessage { + uint32_t index; + uint32_t protocol; + uint32_t size; + }; - XMLNode& get_state(); - int set_state(const XMLNode& node, int version); - bool save_preset(std::string uri); - bool load_preset(const std::string uri); - virtual std::vector get_presets(); + bool write_to_ui(uint32_t index, + uint32_t protocol, + uint32_t size, + const uint8_t* body); - bool has_editor() const; + bool write_to(RingBuffer* dest, + uint32_t index, + uint32_t protocol, + uint32_t size, + const uint8_t* body); - private: - void* _module; - LV2World& _world; - LV2_Feature** _features; - SLV2Plugin _plugin; - SLV2UI _ui; - SLV2Value _name; - SLV2Value _author; - SLV2Instance _instance; - nframes_t _sample_rate; - float* _control_data; - float* _shadow_data; - float* _defaults; - float* _latency_control_port; - bool _was_activated; - std::vector _port_is_input; - std::map _port_indices; + // Created on demand so the space is only consumed if necessary + RingBuffer* _to_ui; + RingBuffer* _from_ui; + + typedef struct { + const void* (*extension_data) (const char* uri); + } LV2_DataAccess; - typedef struct { const void* (*extension_data)(const char* uri); } LV2_DataAccess; LV2_DataAccess _data_access_extension_data; - LV2_Feature _data_access_feature; - LV2_Feature _instance_access_feature; + LV2_Feature _data_access_feature; + LV2_Feature _instance_access_feature; + LV2_Feature _make_path_feature; + LV2_Feature _log_feature; + LV2_Feature _work_schedule_feature; + LV2_Feature _options_feature; + LV2_Feature _def_state_feature; - static URIMap _uri_map; - static uint32_t _midi_event_type; + // Options passed to plugin + int32_t _block_length; + int32_t _seq_size; - void init (LV2World& world, SLV2Plugin plugin, nframes_t rate); - void run (nframes_t nsamples); - void latency_compute_run (); -}; + mutable unsigned _state_version; + bool _was_activated; + bool _has_state_interface; -/** The SLV2World, and various cached (as symbols, fast) URIs. - * - * This object represents everything ardour 'knows' about LV2 - * (ie understood extensions/features/etc) - */ -struct LV2World { - LV2World(); - ~LV2World(); - - SLV2World world; - SLV2Value input_class; ///< Input port - SLV2Value output_class; ///< Output port - SLV2Value audio_class; ///< Audio port - SLV2Value control_class; ///< Control port - SLV2Value event_class; ///< Event port - SLV2Value midi_class; ///< MIDI event - SLV2Value in_place_broken; - SLV2Value integer; - SLV2Value toggled; - SLV2Value srate; - SLV2Value gtk_gui; - SLV2Value external_gui; - SLV2Value logarithmic; + const std::string plugin_dir () const; + const std::string scratch_dir () const; + const std::string file_dir () const; + const std::string state_dir (unsigned num) const; + + static char* lv2_state_make_path (void* host_data, + const char* path); + + void init (const void* c_plugin, framecnt_t rate); + void allocate_atom_event_buffers (); + void run (pframes_t nsamples); + + void latency_compute_run (); + std::string do_save_preset (std::string); + void do_remove_preset (std::string); + void find_presets (); + void add_state (XMLNode *) const; }; class LV2PluginInfo : public PluginInfo { public: - LV2PluginInfo (void* slv2_world, void* slv2_plugin);; - ~LV2PluginInfo ();; - static PluginInfoList* discover (void* slv2_world); + LV2PluginInfo (const void* c_plugin); + ~LV2PluginInfo (); + + static PluginInfoList* discover (); PluginPtr load (Session& session); - void* _lv2_world; - void* _slv2_plugin; + const void* _c_plugin; }; typedef boost::shared_ptr LV2PluginInfoPtr;