'libs/ardour' - Main body of changes required for building with MSVC
[ardour.git] / libs / ardour / ardour / lv2_plugin.h
index d42c34a5461e631c6c6148521c695f9a2e7360fa..5154cd4d3e710cc8148e3a3322f2c44ed9096ef0 100644 (file)
@@ -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
     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 <set>
-#include <vector>
 #include <string>
-#include <dlfcn.h>
-
-
-#include "pbd/stateful.h"
+#include <vector>
 
-#include <jack/types.h>
-#include <slv2/slv2.h>
 #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<Evoral::Parameter> 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<Evoral::Parameter> 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<Plugin::ScalePoints>
+       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<PortFlags>         _port_flags;
+       std::vector<size_t>            _port_minimumSize;
+       std::map<std::string,uint32_t> _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<Plugin::PresetRecord> 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<uint8_t>* 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<bool>        _port_is_input;
-       std::map<std::string,uint32_t> _port_indices;
+       // Created on demand so the space is only consumed if necessary
+       RingBuffer<uint8_t>* _to_ui;
+       RingBuffer<uint8_t>* _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<LV2PluginInfo> LV2PluginInfoPtr;