Merged with trunk R846
[ardour.git] / libs / ardour / ardour / session.h
index 3b1a0bef99319781fe6d61638794bfe4e858d3a2..eeb905a3018a170a4147c1f22b1cb3cf1a563993 100644 (file)
@@ -36,6 +36,7 @@
 #include <pbd/error.h>
 #include <pbd/undo.h>
 #include <pbd/pool.h>
+#include <pbd/rcu.h>
 
 #include <midi++/types.h>
 #include <midi++/mmc.h>
@@ -72,10 +73,13 @@ class Route;
 class AuxInput;
 class Source;
 class AudioSource;
+class BufferSet;
 
 class Diskstream;
 class AudioDiskstream;
+class MidiDiskstream;
 class AudioFileSource;
+class MidiSource;
 class Auditioner;
 class Insert;
 class Send;
@@ -112,9 +116,9 @@ class Session : public sigc::trackable, public Stateful
 
 {
   private:
-       typedef std::pair<Route*,bool> RouteBooleanState;
+       typedef std::pair<boost::shared_ptr<Route>,bool> RouteBooleanState;
        typedef vector<RouteBooleanState> GlobalRouteBooleanState;
-       typedef std::pair<Route*,MeterPoint> RouteMeterState;
+       typedef std::pair<boost::shared_ptr<Route>,MeterPoint> RouteMeterState;
        typedef vector<RouteMeterState> GlobalRouteMeterState;
 
   public:
@@ -127,7 +131,7 @@ class Session : public sigc::trackable, public Stateful
        enum SlaveSource {
                None = 0,
                MTC,
-               JACK,
+               JACK
        };
        
        enum AutoConnectOption {
@@ -158,7 +162,7 @@ class Session : public sigc::trackable, public Stateful
                    */
 
                    StopOnce,
-                   AutoLoop,
+                   AutoLoop
            };
 
            enum Action {
@@ -167,17 +171,18 @@ class Session : public sigc::trackable, public Stateful
                    Replace,
                    Clear
            };
-
-           Type                type;
-           Action              action;
-           jack_nframes_t      action_frame;
-           jack_nframes_t      target_frame;
-           float               speed;
+               
+               Type           type;
+           Action         action;
+           jack_nframes_t action_frame;
+           jack_nframes_t target_frame;
+           float          speed;
 
            union {
-               void*                ptr;
-               bool                 yes_or_no;
-               Session::SlaveSource slave;
+                       void*                ptr;
+                       bool                 yes_or_no;
+                       Session::SlaveSource slave;
+                       Route*               route;
            };
 
            list<AudioRange>     audio_range;
@@ -272,15 +277,17 @@ class Session : public sigc::trackable, public Stateful
        static string change_audio_path_by_name (string oldpath, string oldname, string newname, bool destructive);
        static string peak_path_from_audio_path (string);
        string audio_path_from_name (string, uint32_t nchans, uint32_t chan, bool destructive);
+       string midi_path_from_name (string);
 
        void process (jack_nframes_t nframes);
 
-       vector<Sample*>& get_passthru_buffers() { return _passthru_buffers; }
-       vector<Sample*>& get_silent_buffers (uint32_t howmany);
-       vector<Sample*>& get_send_buffers () { return _send_buffers; }
-
-       Diskstream    *diskstream_by_id (const PBD::ID& id);
-       Diskstream    *diskstream_by_name (string name);
+       BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
+       BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+       BufferSet& get_send_buffers (ChanCount count = ChanCount::ZERO);
+       
+       void add_diskstream (boost::shared_ptr<Diskstream>);
+       boost::shared_ptr<Diskstream> diskstream_by_id (const PBD::ID& id);
+       boost::shared_ptr<Diskstream> diskstream_by_name (string name);
 
        bool have_captured() const { return _have_captured; }
 
@@ -290,29 +297,28 @@ class Session : public sigc::trackable, public Stateful
        uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
        uint32_t n_diskstreams() const;
        
-       typedef list<Diskstream *> DiskstreamList;
+       typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList;
+       typedef std::list<boost::shared_ptr<Route> >      RouteList; 
        
-       typedef list<Route *> RouteList;
-       
-       RouteList get_routes() const {
-               Glib::RWLock::ReaderLock rlock (route_lock);
-               return routes; /* XXX yes, force a copy */
+       boost::shared_ptr<RouteList> get_routes() const {
+               return routes.reader ();
        }
        
-       uint32_t nroutes() const { return routes.size(); }
+       uint32_t nroutes() const { return routes.reader()->size(); }
        uint32_t ntracks () const;
        uint32_t nbusses () const;
 
        struct RoutePublicOrderSorter {
-           bool operator() (Route *, Route *b);
+           bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
        };
        
        template<class T> void foreach_route (T *obj, void (T::*func)(Route&));
-       template<class T> void foreach_route (T *obj, void (T::*func)(Route*));
+       template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>));
        template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg);
 
-       Route *route_by_name (string);
-       Route *route_by_remote_id (uint32_t id);
+       boost::shared_ptr<Route> route_by_name (string);
+       boost::shared_ptr<Route> route_by_id (PBD::ID);
+       boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
 
        bool route_name_unique (string) const;
 
@@ -345,7 +351,7 @@ class Session : public sigc::trackable, public Stateful
        
        /* Record status signals */
 
-        sigc::signal<void> RecordStateChanged;
+       sigc::signal<void> RecordStateChanged;
 
        /* Transport mechanism signals */
 
@@ -354,8 +360,7 @@ class Session : public sigc::trackable, public Stateful
        sigc::signal<void> DurationChanged;
        sigc::signal<void> HaltOnXrun;
 
-       sigc::signal<void,Route*> RouteAdded;
-       sigc::signal<void,Diskstream*> DiskstreamAdded;
+       sigc::signal<void,RouteList&> RouteAdded;
 
        void request_roll ();
        void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
@@ -488,6 +493,8 @@ class Session : public sigc::trackable, public Stateful
        int save_state (string snapshot_name, bool pending = false);
        int restore_state (string snapshot_name);
        int save_template (string template_name);
+        int save_history (string snapshot_name = "");
+        int restore_history (string snapshot_name);
 
        static int rename_template (string old_name, string new_name);
 
@@ -500,14 +507,11 @@ class Session : public sigc::trackable, public Stateful
        static vector<string*>* possible_states(string path);
 
        XMLNode& get_state();
-       int      set_state(const XMLNode& node);
+       int      set_state(const XMLNode& node); // not idempotent
        XMLNode& get_template();
 
        void add_instant_xml (XMLNode&, const std::string& dir);
 
-       void swap_configuration(Configuration** new_config);
-       void copy_configuration(Configuration* new_config);
-
        enum StateOfTheState {
                Clean = 0x0,
                Dirty = 0x1,
@@ -548,15 +552,16 @@ class Session : public sigc::trackable, public Stateful
 
        /* fundamental operations. duh. */
 
-       AudioTrack *new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal);
-       Route *new_audio_route (int input_channels, int output_channels);
+       std::list<boost::shared_ptr<AudioTrack> > new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal, uint32_t how_many = 1);
+       RouteList new_audio_route (int input_channels, int output_channels, uint32_t how_many);
        
-       MidiTrack *new_midi_track (TrackMode mode = Normal);
-       Route *new_midi_route ();
-
-       void   remove_route (Route&);
-       void   resort_routes (void *src);
+       std::list<boost::shared_ptr<MidiTrack> > new_midi_track (TrackMode mode = Normal, uint32_t how_many = 1);
+       //boost::shared_ptr<Route>     new_midi_route (uint32_t how_many = 1);
 
+       void   remove_route (boost::shared_ptr<Route>);
+       void   resort_routes ();
+       void   resort_routes_using (boost::shared_ptr<RouteList>);
+       
        AudioEngine &engine() { return _engine; };
 
        /* configuration. there should really be accessors/mutators
@@ -628,19 +633,21 @@ class Session : public sigc::trackable, public Stateful
        
        /* region info  */
 
-       sigc::signal<void,AudioRegion *> AudioRegionAdded;
-       sigc::signal<void,AudioRegion *> AudioRegionRemoved;
+       sigc::signal<void,Region *> RegionAdded;
+       sigc::signal<void,Region *> RegionRemoved;
 
        int region_name (string& result, string base = string(""), bool newlevel = false) const;
        string new_region_name (string);
        string path_from_region_name (string name, string identifier);
 
-       AudioRegion* find_whole_file_parent (AudioRegion&);
-       void find_equivalent_playlist_regions (AudioRegion&, std::vector<AudioRegion*>& result);
+       Region* find_whole_file_parent (Region& child);
+       void find_equivalent_playlist_regions (Region&, std::vector<Region*>& result);
 
-       AudioRegion *XMLRegionFactory (const XMLNode&, bool full);
+       Region*      XMLRegionFactory (const XMLNode&, bool full);
+       AudioRegion* XMLAudioRegionFactory (const XMLNode&, bool full);
+       MidiRegion* XMLMidiRegionFactory (const XMLNode&, bool full);
 
-       template<class T> void foreach_audio_region (T *obj, void (T::*func)(AudioRegion *));
+       template<class T> void foreach_region (T *obj, void (T::*func)(Region *));
 
        /* source management */
 
@@ -654,7 +661,7 @@ class Session : public sigc::trackable, public Stateful
            string pathname;
            
            /* result */
-           std::vector<AudioRegion*> new_regions;
+           std::vector<Region*> new_regions;
            
        };
 
@@ -668,7 +675,7 @@ class Session : public sigc::trackable, public Stateful
        int start_audio_export (ARDOUR::AudioExportSpecification&);
        int stop_audio_export (ARDOUR::AudioExportSpecification&);
        
-       void add_audio_source (AudioSource *);
+       void add_source (Source *);
        void remove_source (Source *);
        int  cleanup_audio_file_source (AudioFileSource&);
 
@@ -704,6 +711,8 @@ class Session : public sigc::trackable, public Stateful
 
        AudioFileSource *create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
 
+       MidiSource *create_midi_source_for_session (ARDOUR::MidiDiskstream&);
+
        Source *source_by_id (const PBD::ID&);
 
        /* playlist management */
@@ -727,6 +736,10 @@ class Session : public sigc::trackable, public Stateful
        sigc::signal<void> NamedSelectionAdded;
        sigc::signal<void> NamedSelectionRemoved;
 
+        /* Curves and AutomationLists (TODO when they go away) */
+        void add_curve(Curve*);
+        void add_automation_list(AutomationList*);
+
        /* fade curves */
 
        float get_default_fade_length () const { return default_fade_msecs; }
@@ -735,9 +748,9 @@ class Session : public sigc::trackable, public Stateful
 
        /* auditioning */
 
-       Auditioner& the_auditioner() { return *auditioner; }
+       boost::shared_ptr<Auditioner> the_auditioner() { return auditioner; }
        void audition_playlist ();
-       void audition_region (AudioRegion&);
+       void audition_region (Region&);
        void cancel_audition ();
        bool is_auditioning () const;
        
@@ -745,8 +758,7 @@ class Session : public sigc::trackable, public Stateful
 
        /* flattening stuff */
 
-       int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<AudioSource*>&,
-                                  InterThreadInfo& wot);
+       int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<Source*>&, InterThreadInfo& wot);
        int freeze (InterThreadInfo&);
 
        /* session-wide solo/mute/rec-enable */
@@ -774,8 +786,8 @@ class Session : public sigc::trackable, public Stateful
 
        /* control/master out */
 
-       IO* control_out() const { return _control_out; }
-       IO* master_out() const { return _master_out; }
+       boost::shared_ptr<IO> control_out() const { return _control_out; }
+       boost::shared_ptr<IO> master_out() const { return _master_out; }
 
        /* insert/send management */
        
@@ -845,23 +857,67 @@ class Session : public sigc::trackable, public Stateful
        string next_undo() const { return history.next_undo(); }
        string next_redo() const { return history.next_redo(); }
 
-       void begin_reversible_command (string cmd_name, UndoAction *private_undo = 0);
-       void commit_reversible_command (UndoAction* private_redo = 0);
+       void begin_reversible_command (string cmd_name);
+       void commit_reversible_command (Command* cmd = 0);
 
-       void add_undo (const UndoAction& ua) {
-               current_cmd.add_undo (ua);
-       }
-       void add_redo (const UndoAction& ua) {
-               current_cmd.add_redo (ua);
-       }
-       void add_redo_no_execute (const UndoAction& ua) {
-               current_cmd.add_redo_no_execute (ua);
+       void add_command (Command *const cmd) {
+               current_trans.add_command (cmd);
        }
 
-       UndoAction global_solo_memento (void *src);
-       UndoAction global_mute_memento (void *src);
-       UndoAction global_record_enable_memento (void *src);
-       UndoAction global_metering_memento (void *src);
+        // these commands are implemented in libs/ardour/session_command.cc
+       Command *memento_command_factory(XMLNode *n);
+        void register_with_memento_command_factory(PBD::ID, Stateful *);
+        class GlobalSoloStateCommand : public Command
+        {
+            GlobalRouteBooleanState before, after;
+            Session &sess;
+            void *src;
+        public:
+            GlobalSoloStateCommand(Session &, void *src);
+            void operator()();
+            void undo();
+            XMLNode &get_state();
+            void mark();
+        };
+
+        class GlobalMuteStateCommand : public Command
+        {
+            GlobalRouteBooleanState before, after;
+            Session &sess;
+            void *src;
+        public:
+            GlobalMuteStateCommand(Session &, void *src);
+            void operator()();
+            void undo();
+            XMLNode &get_state();
+            void mark();
+        };
+
+        class GlobalRecordEnableStateCommand : public Command
+        {
+            GlobalRouteBooleanState before, after;
+            Session &sess;
+            void *src;
+        public:
+            GlobalRecordEnableStateCommand(Session &, void *src);
+            void operator()();
+            void undo();
+            XMLNode &get_state();
+            void mark();
+        };
+
+        class GlobalMeteringStateCommand : public Command
+        {
+            GlobalRouteMeterState before, after;
+            Session &sess;
+            void *src;
+        public:
+            GlobalMeteringStateCommand(Session &, void *src);
+            void operator()();
+            void undo();
+            XMLNode &get_state();
+            void mark();
+        };
 
        /* edit mode */
 
@@ -870,7 +926,7 @@ class Session : public sigc::trackable, public Stateful
 
        /* clicking */
 
-       IO&  click_io() { return *_click_io; }
+       boost::shared_ptr<IO>  click_io() { return _click_io; }
        void set_clicking (bool yn);
        bool get_clicking() const;
 
@@ -936,7 +992,7 @@ class Session : public sigc::trackable, public Stateful
        /* buffers for gain and pan */
 
        gain_t* gain_automation_buffer () const { return _gain_automation_buffer; }
-       pan_t** pan_automation_buffer() const { return _pan_automation_buffer; }
+       pan_t** pan_automation_buffer () const  { return _pan_automation_buffer; }
 
        /* buffers for conversion */
        enum RunContext {
@@ -945,8 +1001,6 @@ class Session : public sigc::trackable, public Stateful
                ExportContext
        };
        
-       char *  conversion_buffer(RunContext context) { return _conversion_buffers[context]; }
-       
        /* VST support */
 
        static long vst_callback (AEffect* effect,
@@ -1027,10 +1081,9 @@ class Session : public sigc::trackable, public Stateful
        jack_nframes_t          _last_slave_transport_frame;
        jack_nframes_t           maximum_output_latency;
        jack_nframes_t           last_stop_frame;
-       vector<Sample *>        _passthru_buffers;
-       vector<Sample *>        _silent_buffers;
-       vector<Sample *>        _send_buffers;
-       map<RunContext,char*>   _conversion_buffers;
+       BufferSet*              _scratch_buffers;
+       BufferSet*              _silent_buffers;
+       BufferSet*              _send_buffers;
        jack_nframes_t           current_block_size;
        jack_nframes_t          _worst_output_latency;
        jack_nframes_t          _worst_input_latency;
@@ -1040,14 +1093,14 @@ class Session : public sigc::trackable, public Stateful
        float                   _meter_falloff;
        bool                    _end_location_is_free;
 
-       void set_worst_io_latencies (bool take_lock);
+       void set_worst_io_latencies ();
        void set_worst_io_latencies_x (IOChange asifwecare, void *ignored) {
-               set_worst_io_latencies (true);
+               set_worst_io_latencies ();
        }
 
        void update_latency_compensation_proxy (void* ignored);
 
-       void ensure_passthru_buffers (uint32_t howmany);
+       void ensure_buffers (ChanCount howmany);
        
        void process_scrub          (jack_nframes_t);
        void process_without_events (jack_nframes_t);
@@ -1473,21 +1526,20 @@ class Session : public sigc::trackable, public Stateful
 
        /* disk-streams */
 
-       DiskstreamList  diskstreams; 
-       mutable Glib::RWLock diskstream_lock;
+       SerializedRCUManager<DiskstreamList>  diskstreams; 
+
        uint32_t dstream_buffer_size;
-       void add_diskstream (Diskstream*);
        int  load_diskstreams (const XMLNode&);
 
        /* routes stuff */
 
-       RouteList       routes;
-       mutable Glib::RWLock route_lock;
-       void   add_route (Route*);
+       SerializedRCUManager<RouteList>  routes;
+
+       void   add_routes (RouteList&, bool save = true);
        uint32_t destructive_index;
 
        int load_routes (const XMLNode&);
-       Route* XMLRouteFactory (const XMLNode&);
+       boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&);
 
        /* mixer stuff */
 
@@ -1497,7 +1549,7 @@ class Session : public sigc::trackable, public Stateful
        bool       currently_soloing;
        
        void route_mute_changed (void *src);
-       void route_solo_changed (void *src, Route *);
+       void route_solo_changed (void *src, boost::shared_ptr<Route>);
        void catch_up_on_solo ();
        void update_route_solo_state ();
        void modify_solo_mute (bool, bool);
@@ -1506,8 +1558,8 @@ class Session : public sigc::trackable, public Stateful
        /* REGION MANAGEMENT */
 
        mutable Glib::Mutex region_lock;
-       typedef map<PBD::ID,AudioRegion *> AudioRegionList;
-       AudioRegionList audio_regions;
+       typedef map<PBD::ID,Region *> RegionList;
+       RegionList regions;
        
        void region_renamed (Region *);
        void region_changed (Change, Region *);
@@ -1518,10 +1570,10 @@ class Session : public sigc::trackable, public Stateful
 
        /* SOURCES */
        
-       mutable Glib::Mutex audio_source_lock;
-       typedef std::map<PBD::ID,AudioSource *> AudioSourceList;
+       mutable Glib::Mutex source_lock;
+       typedef std::map<PBD::ID,Source *> SourceList;
 
-       AudioSourceList audio_sources;
+       SourceList sources;
 
        int load_sources (const XMLNode& node);
        XMLNode& get_sources_as_xml ();
@@ -1544,7 +1596,7 @@ class Session : public sigc::trackable, public Stateful
        Playlist *XMLPlaylistFactory (const XMLNode&);
 
        void playlist_length_changed (Playlist *);
-       void diskstream_playlist_changed (Diskstream *);
+       void diskstream_playlist_changed (boost::shared_ptr<Diskstream>);
 
        /* NAMED SELECTIONS */
 
@@ -1557,6 +1609,10 @@ class Session : public sigc::trackable, public Stateful
        NamedSelection *named_selection_factory (string name);
        NamedSelection *XMLNamedSelectionFactory (const XMLNode&);
 
+        /* CURVES and AUTOMATION LISTS */
+        std::map<PBD::ID, Curve*> curves;
+        std::map<PBD::ID, AutomationList*> automation_lists;
+
        /* DEFAULT FADE CURVES */
 
        float default_fade_steepness;
@@ -1564,7 +1620,7 @@ class Session : public sigc::trackable, public Stateful
 
        /* AUDITIONING */
 
-       Auditioner *auditioner;
+       boost::shared_ptr<Auditioner> auditioner;
        void set_audition (AudioRegion*);
        void non_realtime_set_audition ();
        AudioRegion *pending_audition_region;
@@ -1636,7 +1692,7 @@ class Session : public sigc::trackable, public Stateful
        void reverse_diskstream_buffers ();
 
        UndoHistory history;
-       UndoCommand current_cmd;
+       UndoTransaction current_trans;
 
        GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
        GlobalRouteMeterState get_global_route_metering ();
@@ -1681,7 +1737,7 @@ class Session : public sigc::trackable, public Stateful
 
        Clicks          clicks;
        bool           _clicking;
-       IO*            _click_io;
+       boost::shared_ptr<IO> _click_io;
        Sample*         click_data;
        Sample*         click_emphasis_data;
        jack_nframes_t  click_length;
@@ -1713,8 +1769,8 @@ class Session : public sigc::trackable, public Stateful
        /* main outs */
        uint32_t main_outs;
        
-       IO* _master_out;
-       IO* _control_out;
+       boost::shared_ptr<IO> _master_out;
+       boost::shared_ptr<IO> _control_out;
 
        AutoConnectOption input_auto_connect;
        AutoConnectOption output_auto_connect;
@@ -1756,6 +1812,6 @@ class Session : public sigc::trackable, public Stateful
        void remove_controllable (PBD::Controllable*);
 };
 
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
 
 #endif /* __ardour_session_h__ */