X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Flv2_plugin.h;h=6b4b1a1c67461e073cd2c8f169a0349e20a1b67e;hb=ff9e1dfe602ab7b54d49849373fb2ce265c4f4a0;hp=978e52b446538f6fa0e5da48819a1b75f1f94874;hpb=b5ec66ae6cb60fa43c343d3d29340b2370d0b9d1;p=ardour.git diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index 978e52b446..6b4b1a1c67 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,164 +15,273 @@ 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 -#include +#include "ardour/plugin.h" +#include "ardour/uri_map.h" +#include "ardour/worker.h" +#include "pbd/ringbuffer.h" -#include -#include -#include +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* 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); } + std::string unique_id () const; + const char* uri () const; + const char* label () const; + const char* name () const; + const char* maker () const; + + 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; } - SLV2Port slv2_port(uint32_t i) { return slv2_plugin_get_port_by_index(_plugin, i); } - - const LV2_Feature* const* features() { return _features; } - - std::set automatable() const; - - void activate () { - if (!_was_activated) { - slv2_instance_activate(_instance); - _was_activated = true; - } - } - - void deactivate () { - if (_was_activated) { - slv2_instance_deactivate(_instance); - _was_activated = false; - } - } - - void cleanup () { - activate(); - deactivate(); - slv2_instance_free(_instance); - _instance = NULL; - } - - void set_block_size (nframes_t nframes) {} - - int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_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; + const void* extension_data (const char* uri) const; + + const void* c_plugin(); + const void* c_ui(); + const void* c_ui_type(); + + bool is_external_ui () const; + bool is_external_kx () const; + bool ui_is_resizable () const; + + const char* port_symbol (uint32_t port) const; + uint32_t port_index (const char* symbol) const; + + const LV2_Feature* const* features () { return _features; } - 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; + std::set automatable () const; - XMLNode& get_state(); - int set_state(const XMLNode& node); - bool save_preset(std::string name); + void activate (); + void deactivate (); + void cleanup (); - bool has_editor() const; + int set_block_size (pframes_t /*nframes*/) { return 0; } + + int connect_and_run (BufferSet& bufs, + 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 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; 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; - vector _port_is_input; - - typedef struct { const void* (*extension_data)(const char* uri); } LV2_DataAccess; + 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; + + /// Message send to/from UI via ports + struct UIMessage { + uint32_t index; + uint32_t protocol; + uint32_t size; + }; + + bool write_to_ui(uint32_t index, + uint32_t protocol, + uint32_t size, + const uint8_t* body); + + bool write_to(RingBuffer* dest, + uint32_t index, + uint32_t protocol, + uint32_t size, + const uint8_t* body); + + // 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; + 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; - void init (LV2World& world, SLV2Plugin plugin, nframes_t rate); - void run (nframes_t nsamples); - void latency_compute_run (); -}; + // Options passed to plugin + int32_t _block_length; + int32_t _seq_size; + mutable unsigned _state_version; -/** 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; + bool _was_activated; + bool _has_state_interface; + + 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); +public: + 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;