#ifndef __ardour_lv2_plugin_h__
#define __ardour_lv2_plugin_h__
+#include <glibmm/threads.h>
#include <set>
#include <string>
#include <vector>
#include "ardour/worker.h"
#include "pbd/ringbuffer.h"
+#ifdef LV2_EXTENDED // -> needs to eventually go upstream to lv2plug.in
+#include "ardour/lv2_extensions.h"
+#endif
+
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
LV2Plugin (ARDOUR::AudioEngine& engine,
ARDOUR::Session& session,
const void* c_plugin,
- framecnt_t sample_rate);
+ samplecnt_t sample_rate);
LV2Plugin (const LV2Plugin &);
~LV2Plugin ();
+ static bool force_state_save; // to be used only by session-state
+
std::string unique_id () const;
const char* uri () const;
const char* label () const;
uint32_t num_ports () const;
uint32_t parameter_count () const;
float default_value (uint32_t port);
- framecnt_t signal_latency () const;
+ samplecnt_t max_latency () const;
+ samplecnt_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;
+ bool get_layout (uint32_t which, UILayoutHint&) const;
+
+ IOPortDescription describe_io_port (DataType dt, bool input, uint32_t id) const;
const void* extension_data (const char* uri) const;
const LV2_Feature* const* features () { return _features; }
std::set<Evoral::Parameter> automatable () const;
+ virtual void set_automation_control (uint32_t, boost::shared_ptr<AutomationControl>);
void activate ();
void deactivate ();
void cleanup ();
- int set_block_size (pframes_t /*nframes*/) { return 0; }
+ int set_block_size (pframes_t);
+ bool requires_fixed_sized_buffers () const;
int connect_and_run (BufferSet& bufs,
- ChanMapping in, ChanMapping out,
- pframes_t nframes, framecnt_t offset);
+ samplepos_t start, samplepos_t end, double speed,
+ ChanMapping const& in, ChanMapping const& out,
+ pframes_t nframes, samplecnt_t offset);
std::string describe_parameter (Evoral::Parameter);
std::string state_node_name () const { return "lv2"; }
bool parameter_is_output (uint32_t) const;
bool parameter_is_toggled (uint32_t) const;
+ uint32_t designated_bypass_port ();
+
boost::shared_ptr<ScalePoints>
get_scale_points(uint32_t port_index) const;
- void set_insert_info(const PluginInsert* insert);
+ void set_insert_id(PBD::ID id);
+ void set_state_dir (const std::string& d = "");
int set_state (const XMLNode& node, int version);
bool save_preset (std::string uri);
URIMap& uri_map() { return _uri_map; }
const URIMap& uri_map() const { return _uri_map; }
- int work(uint32_t size, const void* data);
+ int work(Worker& worker, uint32_t size, const void* data);
int work_response(uint32_t size, const void* data);
void set_property(uint32_t key, const Variant& value);
void* _module;
LV2_Feature** _features;
Worker* _worker;
- framecnt_t _sample_rate;
+ Worker* _state_worker;
+ samplecnt_t _sample_rate;
float* _control_data;
float* _shadow_data;
float* _defaults;
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
+ samplepos_t _next_cycle_start; ///< Expected start sample of next run cycle
+ double _next_cycle_speed; ///< Expected start sample of next run cycle
+ double _next_cycle_beat; ///< Expected bar_beat of next run cycle
+ double _current_bpm;
PBD::ID _insert_id;
+ std::string _plugin_state_dir;
uint32_t _patch_port_in_index;
uint32_t _patch_port_out_index;
URIMap& _uri_map;
+ bool _no_sample_accurate_ctrl;
+ bool _can_write_automation;
+ samplecnt_t _max_latency;
+ samplecnt_t _current_latency;
friend const void* lv2plugin_get_port_value(const char* port_symbol,
void* user_data,
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
- PORT_PATCHMSG = 1 << 8 ///< Event port supports patch:Message
+ PORT_PATCHMSG = 1 << 8, ///< Event port supports patch:Message
+ PORT_AUTOCTRL = 1 << 9, ///< Event port supports auto:AutomationControl
+ PORT_CTRLED = 1 << 10, ///< Port prop auto:AutomationControlled (can be self controlled)
+ PORT_CTRLER = 1 << 11, ///< Port prop auto:AutomationController (can be self set)
+ PORT_NOAUTO = 1 << 12 ///< Port don't allow to automate
} PortFlag;
typedef unsigned PortFlags;
PropertyDescriptors _property_descriptors;
+ struct AutomationCtrl {
+ AutomationCtrl (const AutomationCtrl &other)
+ : ac (other.ac)
+ , guard (other.guard)
+ { }
+
+ AutomationCtrl (boost::shared_ptr<ARDOUR::AutomationControl> c)
+ : ac (c)
+ , guard (false)
+ { }
+ boost::shared_ptr<ARDOUR::AutomationControl> ac;
+ bool guard;
+ };
+
+ typedef boost::shared_ptr<AutomationCtrl> AutomationCtrlPtr;
+ typedef std::map<uint32_t, AutomationCtrlPtr> AutomationCtrlMap;
+ AutomationCtrlMap _ctrl_map;
+ AutomationCtrlPtr get_automation_control (uint32_t);
+
/// Message send to/from UI via ports
struct UIMessage {
uint32_t index;
uint32_t size,
const uint8_t* body);
- bool write_to(RingBuffer<uint8_t>* dest,
- uint32_t index,
- uint32_t protocol,
- uint32_t size,
- const uint8_t* body);
+ bool write_to(PBD::RingBuffer<uint8_t>* 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<uint8_t>* _to_ui;
- RingBuffer<uint8_t>* _from_ui;
+ PBD::RingBuffer<uint8_t>* _to_ui;
+ PBD::RingBuffer<uint8_t>* _from_ui;
+
+ Glib::Threads::Mutex _work_mutex;
+
+#ifdef LV2_EXTENDED
+ static void queue_draw (LV2_Inline_Display_Handle);
+ static void midnam_update (LV2_Midnam_Handle);
+ static void bankpatch_notify (LV2_BankPatch_Handle, uint8_t, uint32_t, uint8_t);
+
+ const LV2_Inline_Display_Interface* _display_interface;
+ bool _inline_display_in_gui;
+ const LV2_Midnam_Interface* _midname_interface;
+
+ uint32_t _bankpatch[16];
+ bool seen_bankpatch;
+ bool knows_bank_patch () { return seen_bankpatch; }
+ uint32_t bank_patch (uint8_t chn) {
+ assert (chn < 16);
+ if (chn > 15) return UINT32_MAX;
+ return _bankpatch[chn];
+ }
+
+#endif
typedef struct {
const void* (*extension_data) (const char* uri);
LV2_Feature _work_schedule_feature;
LV2_Feature _options_feature;
LV2_Feature _def_state_feature;
+#ifdef LV2_EXTENDED
+ LV2_Feature _queue_draw_feature;
+ LV2_Feature _midnam_feature;
+ LV2_Feature _bankpatch_feature;
+#endif
// Options passed to plugin
- int32_t _block_length;
int32_t _seq_size;
mutable unsigned _state_version;
static char* lv2_state_make_path (void* host_data,
const char* path);
- void init (const void* c_plugin, framecnt_t rate);
+ void init (const void* c_plugin, samplecnt_t rate);
void allocate_atom_event_buffers ();
- void run (pframes_t nsamples);
+ void run (pframes_t nsamples, bool sync_work = false);
void load_supported_properties(PropertyDescriptors& descs);
+#ifdef LV2_EXTENDED
+ bool has_inline_display ();
+ bool inline_display_in_gui ();
+ Plugin::Display_Image_Surface* render_inline_display (uint32_t, uint32_t);
+
+ bool has_midnam ();
+ bool read_midnam ();
+ std::string midnam_model ();
+ bool _midnam_dirty;
+#endif
+
void latency_compute_run ();
std::string do_save_preset (std::string);
void do_remove_preset (std::string);
static PluginInfoList* discover ();
PluginPtr load (Session& session);
+ std::vector<Plugin::PresetRecord> get_presets (bool user_only) const;
char * _plugin_uri;
};