Less weak plugin preset system (maybe AU preset stuff can use the 'normal' thing...
[ardour.git] / libs / ardour / ardour / io.h
index fc49f0699fa10f17987e7e8753ebc8a2315c341d..c5f90bcd90807859284833b1b8afc63451b2aac2 100644 (file)
 #include <ardour/ardour.h>
 #include <ardour/automatable.h>
 #include <ardour/utils.h>
-#include <ardour/curve.h>
 #include <ardour/types.h>
 #include <ardour/data_type.h>
 #include <ardour/port_set.h>
 #include <ardour/chan_count.h>
 #include <ardour/latent.h>
+#include <ardour/automation_control.h>
+#include <ardour/session_object.h>
+#include <ardour/bundle.h>
 
 using std::string;
 using std::vector;
@@ -52,6 +54,7 @@ namespace ARDOUR {
 
 class Session;
 class AudioEngine;
+class UserBundle;
 class Bundle;
 class Panner;
 class PeakMeter;
@@ -66,7 +69,7 @@ class BufferSet;
  * varied combinations of types (eg MIDI and audio) possible.
  */
 
-class IO : public Automatable, public Latent
+class IO : public SessionObject, public AutomatableControls, public Latent
 {
   public:
        static const string state_node_name;
@@ -90,6 +93,9 @@ class IO : public Automatable, public Latent
        void set_output_minimum (ChanCount n);
        void set_output_maximum (ChanCount n);
        
+       bool active() const { return _active; }
+       void set_active (bool yn);
+       
        DataType default_type() const         { return _default_type; }
        void     set_default_type(DataType t) { _default_type = t; }
        
@@ -103,8 +109,8 @@ class IO : public Automatable, public Latent
        void just_meter_input (nframes_t start_frame, nframes_t end_frame, 
                               nframes_t nframes, nframes_t offset);
 
-       virtual void   set_gain (gain_t g, void *src);
-       void           inc_gain (gain_t delta, void *src);
+       BufferSet& output_buffers() { return *_output_buffers; }
+
        gain_t         gain () const { return _desired_gain; }
        virtual gain_t effective_gain () const;
        
@@ -117,15 +123,21 @@ class IO : public Automatable, public Latent
        Panner& panner()        { return *_panner; }
        PeakMeter& peak_meter() { return *_meter; }
        const Panner& panner() const { return *_panner; }
+       void reset_panner ();
        
        int ensure_io (ChanCount in, ChanCount out, bool clear, void *src);
 
-       int use_input_bundle (Bundle&, void *src);
-       int use_output_bundle (Bundle&, void *src);
+       int connect_input_ports_to_bundle (boost::shared_ptr<Bundle>, void *);
+       int disconnect_input_ports_from_bundle (boost::shared_ptr<Bundle>, void *);
+       int connect_output_ports_to_bundle (boost::shared_ptr<Bundle>, void *);
+       int disconnect_output_ports_from_bundle (boost::shared_ptr<Bundle>, void *);
 
-       Bundle *input_bundle() const { return _input_bundle; }
-       Bundle *output_bundle() const { return _output_bundle; }
+       BundleList bundles_connected_to_inputs ();
+       BundleList bundles_connected_to_outputs ();
 
+        boost::shared_ptr<Bundle> bundle_for_inputs () { return _bundle_for_inputs; }
+        boost::shared_ptr<Bundle> bundle_for_outputs () { return _bundle_for_outputs; }
+       
        int add_input_port (string source, void *src, DataType type = DataType::NIL);
        int add_output_port (string destination, void *src, DataType type = DataType::NIL);
 
@@ -178,68 +190,68 @@ class IO : public Automatable, public Latent
        const ChanCount& n_outputs () const { return _outputs.count(); }
 
        void attach_buffers(ChanCount ignored);
+       
+       sigc::signal<void>                active_changed;
 
        sigc::signal<void,IOChange,void*> input_changed;
        sigc::signal<void,IOChange,void*> output_changed;
 
-       sigc::signal<void,void*> gain_changed;
-
        virtual XMLNode& state (bool full);
        XMLNode& get_state (void);
        int set_state (const XMLNode&);
 
        static int  disable_connecting (void);
-
        static int  enable_connecting (void);
-
        static int  disable_ports (void);
-
        static int  enable_ports (void);
-
        static int  disable_panners (void);
-
        static int  reset_panners (void);
        
        static sigc::signal<int>            PortsLegal;
        static sigc::signal<int>            PannersLegal;
        static sigc::signal<int>            ConnectingLegal;
-       static sigc::signal<void,ChanCount> MoreChannels;
+       /// raised when the number of input or output ports changes
+       static sigc::signal<void,ChanCount> PortCountChanged;
        static sigc::signal<int>            PortsCreated;
 
-       PBD::Controllable& gain_control() {
-               return _gain_control;
-       }
-       
-    static void update_meters();
+       static void update_meters();
 
   private: 
-
-    static sigc::signal<void>   Meter;
-    static Glib::StaticMutex    m_meter_signal_lock;
-    sigc::connection            m_meter_connection;
+       
+       static sigc::signal<void>   Meter;
+       static Glib::StaticMutex    m_meter_signal_lock;
+       sigc::connection            m_meter_connection;
 
   public:
-
+    
        /* automation */
 
-       static void set_automation_interval (nframes_t frames) {
-               _automation_interval = frames;
-       }
+       struct GainControl : public AutomationControl {
+           GainControl (std::string name, IO* i, const Evoral::Parameter &param,
+                   boost::shared_ptr<AutomationList> al = boost::shared_ptr<AutomationList>() )
+                       : AutomationControl (i->_session, param, al, name )
+                       , _io (i)
+               {}
+        
+           void set_value (float val);
+           float get_value (void) const;
+   
+           IO* _io;
+       };
 
-       static nframes_t automation_interval() { 
-               return _automation_interval;
+       boost::shared_ptr<GainControl> gain_control() {
+               return _gain_control;
+       }
+       boost::shared_ptr<const GainControl> gain_control() const {
+               return _gain_control;
        }
 
        void clear_automation ();
        
-       void set_parameter_automation_state (ParamID, AutoState);
-
-       virtual void transport_stopped (nframes_t now); // interface: matches Insert
-       void automation_snapshot (nframes_t now); // interface: matches Automatable
+       void set_parameter_automation_state (Evoral::Parameter, AutoState);
 
-       // FIXME: these will probably become unsafe in the near future
-       ARDOUR::AutomationList&       gain_automation()       { return *automation_list(GainAutomation); }
-       const ARDOUR::AutomationList& gain_automation() const { return *automation_list(GainAutomation); }
+       virtual void transport_stopped (nframes_t now);
+       virtual void automation_snapshot (nframes_t now, bool force);
 
        void start_pan_touch (uint32_t which);
        void end_pan_touch (uint32_t which);
@@ -260,47 +272,34 @@ class IO : public Automatable, public Latent
   protected:
        Panner*             _panner;
        BufferSet*          _output_buffers; //< Set directly to output port buffers
+       bool                _active;
        gain_t              _gain;
        gain_t              _effective_gain;
        gain_t              _desired_gain;
-       Glib::Mutex         declick_lock;
+       Glib::Mutex          declick_lock;
        PortSet             _outputs;
        PortSet             _inputs;
        PeakMeter*          _meter;
-       Bundle*             _input_bundle;
-       Bundle*             _output_bundle;
        bool                 no_panner_reset;
        bool                _phase_invert;
        bool                _denormal_protection;
        XMLNode*             deferred_state;
        DataType            _default_type;
-       
-       virtual void set_deferred_state() {}
 
-       void reset_panner ();
+       virtual void prepare_inputs (nframes_t nframes, nframes_t offset);
+       virtual void flush_outputs (nframes_t nframes, nframes_t offset);
+
+       virtual void set_deferred_state() {}
 
        virtual uint32_t pans_required() const
                { return _inputs.count().n_audio(); }
 
-       struct GainControllable : public PBD::Controllable {
-           GainControllable (std::string name, IO& i) : Controllable (name), io (i) {}
-        
-           void set_value (float val);
-           float get_value (void) const;
-   
-           IO& io;
-       };
-
-       GainControllable _gain_control;
-
-       nframes_t last_automation_snapshot;
-       static nframes_t _automation_interval;
+       boost::shared_ptr<GainControl> _gain_control;
 
-       /*AutoState      _gain_automation_state;
-       AutoStyle      _gain_automation_style;*/
+       virtual void   set_gain (gain_t g, void *src);
+       void           inc_gain (gain_t delta, void *src);
 
        bool apply_gain_automation;
-       //Curve     _gain_automation_curve;
        
        virtual int load_automation (std::string path);
 
@@ -312,32 +311,34 @@ class IO : public Automatable, public Latent
        static bool connecting_legal;
        static bool ports_legal;
 
-       BufferSet& output_buffers() { return *_output_buffers; }
-
   private:
+       static bool panners_legal;
 
-       friend class Send;
-
-       /* are these the best variable names ever, or what? */
-
-       sigc::connection input_bundle_configuration_connection;
-       sigc::connection output_bundle_configuration_connection;
-       sigc::connection input_bundle_connection_connection;
-       sigc::connection output_bundle_connection_connection;
+       void copy_to_outputs (BufferSet& bufs, DataType type, nframes_t nframes, nframes_t offset);
 
-       static bool panners_legal;
-       
        int connecting_became_legal ();
        int panners_became_legal ();
        sigc::connection connection_legal_c;
        sigc::connection port_legal_c;
        sigc::connection panner_legal_c;
 
-       ChanCount _input_minimum;
-       ChanCount _input_maximum;
-       ChanCount _output_minimum;
-       ChanCount _output_maximum;
+       ChanCount _input_minimum; ///< minimum number of input channels (0 for no minimum)
+       ChanCount _input_maximum; ///< maximum number of input channels (ChanCount::INFINITE for no maximum)
+       ChanCount _output_minimum; ///< minimum number of output channels (0 for no minimum)
+       ChanCount _output_maximum; ///< maximum number of output channels (ChanCount::INFINITE for no maximum)
+
+       boost::shared_ptr<Bundle> _bundle_for_inputs; ///< a bundle representing our inputs
+       boost::shared_ptr<Bundle> _bundle_for_outputs; ///< a bundle representing our outputs
 
+       struct UserBundleInfo {
+               UserBundleInfo (IO*, boost::shared_ptr<UserBundle> b);
+               
+               boost::shared_ptr<UserBundle> bundle;
+               sigc::connection changed;
+       };
+       
+       std::vector<UserBundleInfo> _bundles_connected_to_outputs; ///< user bundles connected to our outputs
+       std::vector<UserBundleInfo> _bundles_connected_to_inputs; ///< user bundles connected to our inputs
 
        static int parse_io_string (const string&, vector<string>& chns);
 
@@ -349,16 +350,15 @@ class IO : public Automatable, public Latent
        int ensure_inputs (ChanCount, bool clear, bool lockit, void *src);
        int ensure_outputs (ChanCount, bool clear, bool lockit, void *src);
 
-       void drop_input_bundle ();
-       void drop_output_bundle ();
+       void check_bundles_connected_to_inputs ();
+       void check_bundles_connected_to_outputs ();
+       void check_bundles (std::vector<UserBundleInfo>&, const PortSet&);
 
-       void input_bundle_configuration_changed ();
-       void input_bundle_connection_changed (int);
-       void output_bundle_configuration_changed ();
-       void output_bundle_connection_changed (int);
+       void bundle_changed (Bundle::Change);
 
        int create_ports (const XMLNode&);
        int make_connections (const XMLNode&);
+       boost::shared_ptr<Bundle> find_possible_bundle (const string &desired_name, const string &default_name, const string &connection_type_name);
 
        void setup_peak_meters ();
        void meter ();
@@ -366,8 +366,14 @@ class IO : public Automatable, public Latent
        bool ensure_inputs_locked (ChanCount, bool clear, void *src);
        bool ensure_outputs_locked (ChanCount, bool clear, void *src);
 
-       int32_t find_input_port_hole ();
-       int32_t find_output_port_hole ();
+       std::string build_legal_port_name (DataType type, bool for_input);
+       int32_t find_input_port_hole (const char* base);
+       int32_t find_output_port_hole (const char* base);
+
+       void setup_bundles_for_inputs_and_outputs ();
+       void setup_bundle_for_inputs ();
+       void setup_bundle_for_outputs ();
+       std::string bundle_channel_name (uint32_t, uint32_t) const;
 };
 
 } // namespace ARDOUR