first part of using appropriate .ext extensions for the current chosen native file...
[ardour.git] / libs / ardour / ardour / session.h
index 18af14a313218599d18afdca985b0e868ffc62f5..21bde800d303d041a32479ff5720522eabeb8dc5 100644 (file)
 #include "pbd/error.h"
 #include "pbd/rcu.h"
 #include "pbd/statefuldestructible.h"
+#include "pbd/signals.h"
 #include "pbd/undo.h"
 
-#include "midi++/mmc.h"
 #include "midi++/types.h"
 
-#include "pbd/destructible.h"
-#include "pbd/stateful.h"
-
 #include "ardour/ardour.h"
 #include "ardour/click.h"
 #include "ardour/chan_count.h"
 #include "ardour/timecode.h"
 #include "ardour/interpolation.h"
 
+#ifdef HAVE_JACK_SESSION
+#include <jack/session.h>
+#endif
+
 class XMLTree;
 class XMLNode;
 class AEffect;
 
 namespace MIDI {
        class Port;
+       class MachineControl;
+       class Parser;
 }
 
 namespace PBD {
        class Controllable;
+       class ControllableDescriptor;
 }
 
 namespace Evoral {
@@ -74,7 +78,6 @@ namespace Evoral {
 
 namespace ARDOUR {
 
-class AudioDiskstream;
 class AudioEngine;
 class AudioFileSource;
 class AudioRegion;
@@ -93,15 +96,16 @@ class ExportStatus;
 class IO;
 class IOProcessor;
 class ImportStatus;
-class MidiDiskstream;
 class MidiRegion;
 class MidiSource;
 class MidiTrack;
+class MidiControlUI;
 class NamedSelection;
 class Playlist;
 class PluginInsert;
 class Port;
 class PortInsert;
+class ProcessThread;
 class Processor;
 class Region;
 class Return;
@@ -116,46 +120,32 @@ class Slave;
 class Source;
 class TempoMap;
 class VSTPlugin;
+class Graph;
+class Track;
 
 extern void setup_enum_writer ();
 
-class Session : public PBD::StatefulDestructible, public SessionEventManager, public boost::noncopyable
+class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager
 {
-  private:
-       typedef std::pair<boost::weak_ptr<Route>,bool> RouteBooleanState;
-       typedef std::vector<RouteBooleanState> GlobalRouteBooleanState;
-       typedef std::pair<boost::weak_ptr<Route>,MeterPoint> RouteMeterState;
-       typedef std::vector<RouteMeterState> GlobalRouteMeterState;
-
   public:
-       enum RecordState {
+        enum RecordState {
                Disabled = 0,
                Enabled = 1,
                Recording = 2
        };
 
-       /* creating from an XML file */
+        /* a new session might have non-empty mix_template, an existing session should always have an empty one.
+           the bus profile can be null if no master out bus is required.
+         */
 
        Session (AudioEngine&,
-                       const std::string& fullpath,
-                       const std::string& snapshot_name,
-                       std::string mix_template = "");
-
-       /* creating a new Session */
-
-       Session (AudioEngine&,
-                       std::string fullpath,
-                       std::string snapshot_name,
-                       AutoConnectOption input_auto_connect,
-                       AutoConnectOption output_auto_connect,
-                       uint32_t control_out_channels,
-                       uint32_t master_out_channels,
-                       uint32_t n_physical_in,
-                       uint32_t n_physical_out,
-                       nframes_t initial_length);
+                 const std::string& fullpath,
+                 const std::string& snapshot_name,
+                 BusProfile* bus_profile = 0,
+                 std::string mix_template = "");
 
        virtual ~Session ();
-
+        
        std::string path() const { return _path; }
        std::string name() const { return _name; }
        std::string snap_name() const { return _current_snapshot_name; }
@@ -171,14 +161,14 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void set_deletion_in_progress ();
        void clear_deletion_in_progress ();
        bool deletion_in_progress() const { return _state_of_the_state & Deletion; }
-       sigc::signal<void> DirtyChanged;
+       PBD::Signal0<void> DirtyChanged;
 
        const SessionDirectory& session_directory () const { return *(_session_dir.get()); }
 
-       static sigc::signal<void> AutoBindingOn;
-       static sigc::signal<void> AutoBindingOff;
+       static PBD::Signal0<void> AutoBindingOn;
+       static PBD::Signal0<void> AutoBindingOff;
 
-       static sigc::signal<void,std::string> Dialog;
+       static PBD::Signal1<void,std::string> Dialog;
 
        std::string sound_dir (bool with_path = true) const;
        std::string peak_dir () const;
@@ -190,12 +180,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        Glib::ustring peak_path (Glib::ustring) const;
 
-       static std::string change_source_path_by_name (std::string oldpath, std::string oldname, std::string newname, bool destructive);
+       std::string change_source_path_by_name (std::string oldpath, std::string oldname, std::string newname, bool destructive);
 
        std::string peak_path_from_audio_path (std::string) const;
        std::string new_audio_source_name (const std::string&, uint32_t nchans, uint32_t chan, bool destructive);
        std::string new_midi_source_name (const std::string&);
-       std::string new_source_path_from_name (DataType type, const std::string&);
+       std::string new_source_path_from_name (DataType type, const std::string&, bool as_stub = false);
        RouteList new_route_from_template (uint32_t how_many, const std::string& template_path);
 
        void process (nframes_t nframes);
@@ -204,26 +194,18 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
        BufferSet& get_mix_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 (std::string name);
-       bool have_rec_enabled_diskstream () const;
+       bool have_rec_enabled_track () const;
 
        bool have_captured() const { return _have_captured; }
 
-       void refill_all_diskstream_buffers ();
+       void refill_all_track_buffers ();
        Butler* butler() { return _butler; }
        void butler_transport_work ();
 
-       uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
-       uint32_t n_diskstreams() const;
-
        void refresh_disk_space ();
 
-       typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList;
-
-       SerializedRCUManager<DiskstreamList>& diskstream_list() { return diskstreams; }
-
+       int load_diskstreams_2X (XMLNode const &, int);
+       
        int load_routes (const XMLNode&, int);
        boost::shared_ptr<RouteList> get_routes() const {
                return routes.reader ();
@@ -251,6 +233,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        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);
 
+        bool io_name_is_legal (const std::string&);
        boost::shared_ptr<Route> route_by_name (std::string);
        boost::shared_ptr<Route> route_by_id (PBD::ID);
        boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
@@ -277,31 +260,29 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        void maybe_write_autosave ();
 
-       /* Proxy signal for region hidden changes */
-
-       sigc::signal<void,boost::shared_ptr<Region> > RegionHiddenChange;
-
        /* Emitted when all i/o connections are complete */
 
-       sigc::signal<void> IOConnectionsComplete;
+       PBD::Signal0<void> IOConnectionsComplete;
 
        /* Record status signals */
 
-       sigc::signal<void> RecordStateChanged;
+       PBD::Signal0<void> RecordStateChanged;
 
        /* Transport mechanism signals */
 
-       sigc::signal<void> TransportStateChange; /* generic */
-       sigc::signal<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
-       sigc::signal<void> DurationChanged;
-       sigc::signal<void,nframes64_t> Xrun;
-       sigc::signal<void> TransportLooped;
+       PBD::Signal0<void> TransportStateChange; /* generic */
+       PBD::Signal1<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
+       PBD::Signal1<void,nframes64_t> Xrun;
+       PBD::Signal0<void> TransportLooped;
 
        /** emitted when a locate has occurred */
-       sigc::signal<void> Located;
+       PBD::Signal0<void> Located;
 
-       sigc::signal<void,RouteList&> RouteAdded;
-       sigc::signal<void> RouteGroupChanged;
+       PBD::Signal1<void,RouteList&> RouteAdded;
+       /** Emitted when anything about any of our route groups changes */
+       PBD::Signal0<void> RouteGroupChanged;
+
+       void queue_event (SessionEvent*);
 
        void request_roll_at_and_return (nframes_t start, nframes_t return_to);
        void request_bounded_roll (nframes_t start, nframes_t end);
@@ -312,15 +293,17 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        bool get_play_loop () const { return play_loop; }
 
        nframes_t  last_transport_start() const { return _last_roll_location; }
-       void goto_end ()   { request_locate (end_location->start(), false);}
-       void goto_start () { request_locate (start_location->start(), false); }
-       void set_session_start (nframes_t start) { start_location->set_start(start); }
-       void set_session_end (nframes_t end) { end_location->set_start(end); config.set_end_marker_is_free (false); }
+       void goto_end ();
+       void goto_start ();
+       void set_session_start (nframes_t);
+       void set_session_end (nframes_t);
        void use_rf_shuttle_speed ();
        void allow_auto_play (bool yn);
        void request_transport_speed (double speed);
-       void request_overwrite_buffer (Diskstream*);
-       void request_diskstream_speed (Diskstream&, double speed);
+       void request_overwrite_buffer (Track *);
+       void adjust_playback_buffering();
+       void adjust_capture_buffering();
+       void request_track_speed (Track *, double speed);
        void request_input_change_handling ();
 
        bool locate_pending() const { return static_cast<bool>(post_transport_work()&PostTransportLocate); }
@@ -328,17 +311,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        int wipe ();
 
-       int remove_region_from_region_list (boost::shared_ptr<Region>);
-
-       /* ask the session to do realtime things, in RT context, then get back to us via a callback (which must be
-          cross-thread or RT safe, since it too is called from RT context)
-       */
-
-       void request_real_time_operation (sigc::slot<void> rt_op, sigc::slot<void,SessionEvent*> callback);
-
-       nframes_t get_maximum_extent () const;
-       nframes_t current_end_frame() const { return end_location->start(); }
-       nframes_t current_start_frame() const { return start_location->start(); }
+       std::pair<nframes_t, nframes_t> get_extent () const;
+       nframes_t current_end_frame () const;
+       nframes_t current_start_frame () const;
        /// "actual" sample rate of session, set by current audioengine rate, pullup/down etc.
        nframes_t frame_rate() const   { return _current_frame_rate; }
        /// "native" sample rate of session, regardless of current audioengine rate, pullup/down etc
@@ -359,9 +334,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        Locations *locations() { return &_locations; }
 
-       sigc::signal<void,Location*>    auto_loop_location_changed;
-       sigc::signal<void,Location*>    auto_punch_location_changed;
-       sigc::signal<void>              locations_modified;
+       PBD::Signal1<void,Location*>    auto_loop_location_changed;
+       PBD::Signal1<void,Location*>    auto_punch_location_changed;
+       PBD::Signal0<void>              locations_modified;
 
        void set_auto_punch_location (Location *);
        void set_auto_loop_location (Location *);
@@ -374,7 +349,10 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        nframes_t worst_input_latency ()  const { return _worst_input_latency; }
        nframes_t worst_track_latency ()  const { return _worst_track_latency; }
 
-       int save_state (std::string snapshot_name, bool pending = false);
+#ifdef HAVE_JACK_SESSION 
+       void jack_session_event (jack_session_event_t* event);
+#endif
+       int save_state (std::string snapshot_name, bool pending = false, bool switch_to_snapshot = false);
        int restore_state (std::string snapshot_name);
        int save_template (std::string template_name);
        int save_history (std::string snapshot_name = "");
@@ -386,8 +364,8 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        static int rename_template (std::string old_name, std::string new_name);
        static int delete_template (std::string name);
 
-       sigc::signal<void,std::string> StateSaved;
-       sigc::signal<void> StateReady;
+       PBD::Signal1<void,std::string> StateSaved;
+       PBD::Signal0<void> StateReady;
 
        std::vector<std::string*>* possible_states() const;
        static std::vector<std::string*>* possible_states (std::string path);
@@ -417,12 +395,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        RouteGroup *route_group_by_name (std::string);
 
-       sigc::signal<void,RouteGroup*> route_group_added;
-       sigc::signal<void>             route_group_removed;
+       PBD::Signal1<void,RouteGroup*> route_group_added;
+       PBD::Signal0<void>             route_group_removed;
 
-       void foreach_route_group (sigc::slot<void,RouteGroup*> sl) {
-               for (std::list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); i++) {
-                       sl (*i);
+       void foreach_route_group (boost::function<void(RouteGroup*)> f) {
+               for (std::list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
+                       f (*i);
                }
        }
 
@@ -447,9 +425,6 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        AudioEngine & engine() { return _engine; }
        AudioEngine const & engine () const { return _engine; }
 
-       int32_t  max_level;
-       int32_t  min_level;
-
        /* Time */
 
         nframes64_t transport_frame () const {return _transport_frame; }
@@ -487,9 +462,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        nframes_t convert_to_frames_at (nframes_t position, AnyTime const &);
 
-       static sigc::signal<void> StartTimeChanged;
-       static sigc::signal<void> EndTimeChanged;
-       static sigc::signal<void> TimecodeOffsetChanged;
+       static PBD::Signal0<void> StartTimeChanged;
+       static PBD::Signal0<void> EndTimeChanged;
+       static PBD::Signal0<void> TimecodeOffsetChanged;
 
         std::vector<SyncSource> get_available_sync_options() const;
        void   request_sync_source (Slave*);
@@ -507,28 +482,18 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        TempoMap& tempo_map() { return *_tempo_map; }
 
        /// signals the current transport position in frames, bbt and timecode time (in that order)
-       sigc::signal<void, const nframes_t&, const BBT_Time&, const Timecode::Time&> tick;
+       PBD::Signal3<void,const nframes_t&, const BBT_Time&, const Timecode::Time&> tick;
 
        /* region info  */
 
-       void add_regions (std::vector<boost::shared_ptr<Region> >&);
-
-       sigc::signal<void,boost::weak_ptr<Region> > RegionAdded;
-       sigc::signal<void,std::vector<boost::weak_ptr<Region> >& > RegionsAdded;
-       sigc::signal<void,boost::weak_ptr<Region> > RegionRemoved;
+       boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>) const;
 
-       int region_name (std::string& result, std::string base = std::string(""), bool newlevel = false);
-       std::string new_region_name (std::string);
        std::string path_from_region_name (DataType type, std::string name, std::string identifier);
 
-       boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>);
-
        boost::shared_ptr<Region>      XMLRegionFactory (const XMLNode&, bool full);
        boost::shared_ptr<AudioRegion> XMLAudioRegionFactory (const XMLNode&, bool full);
        boost::shared_ptr<MidiRegion>  XMLMidiRegionFactory (const XMLNode&, bool full);
 
-       template<class T> void foreach_region (T *obj, void (T::*func)(boost::shared_ptr<Region>));
-
        /* source management */
 
        void import_audiofiles (ImportStatus&);
@@ -540,9 +505,8 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        int  start_audio_export (nframes_t position, bool realtime);
 
-       sigc::signal<int, nframes_t> ProcessExport;
-       sigc::signal<void> ExportReadFinished;
-       static sigc::signal<void, std::string, std::string> Exported;
+       PBD::Signal1<int,nframes_t> ProcessExport;
+       static PBD::Signal2<void,std::string, std::string> Exported;
 
        void add_source (boost::shared_ptr<Source>);
        void remove_source (boost::weak_ptr<Source>);
@@ -550,8 +514,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        int  cleanup_sources (CleanupReport&);
        int  cleanup_trash_sources (CleanupReport&);
 
-       int destroy_region (boost::shared_ptr<Region>);
-       int destroy_regions (std::list<boost::shared_ptr<Region> >);
+       int destroy_sources (std::list<boost::shared_ptr<Source> >);
 
        int remove_last_capture ();
 
@@ -559,20 +522,21 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
            0 for "yes, delete this playlist",
            1 for "no, don't delete this playlist".
        */
-       sigc::signal<int,boost::shared_ptr<Playlist> > AskAboutPlaylistDeletion;
+       static PBD::Signal1<int,boost::shared_ptr<Playlist> >  AskAboutPlaylistDeletion;
 
        /** handlers should return 0 for "ignore the rate mismatch",
            !0 for "do not use this session"
        */
-       static sigc::signal<int,nframes_t, nframes_t> AskAboutSampleRateMismatch;
+       static PBD::Signal2<int,nframes_t, nframes_t> AskAboutSampleRateMismatch;
 
        /** handlers should return !0 for use pending state, 0 for ignore it.
        */
-       static sigc::signal<int> AskAboutPendingState;
+       static PBD::Signal0<int> AskAboutPendingState;
 
-       boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
-
-       boost::shared_ptr<MidiSource> create_midi_source_for_session (ARDOUR::MidiDiskstream&);
+       boost::shared_ptr<AudioFileSource> create_audio_source_for_session (size_t, std::string const &, uint32_t, 
+                                                                            bool destructive, bool as_stub = false);
+        
+       boost::shared_ptr<MidiSource> create_midi_source_for_session (Track*, std::string const &, bool as_stub = false);
 
        boost::shared_ptr<Source> source_by_id (const PBD::ID&);
        boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t);
@@ -581,13 +545,13 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        /* named selections */
 
-       NamedSelection* named_selection_by_name (std::string name);
-       void add_named_selection (NamedSelection *);
-       void remove_named_selection (NamedSelection *);
+       boost::shared_ptr<NamedSelection> named_selection_by_name (std::string name);
+       void add_named_selection (boost::shared_ptr<NamedSelection>);
+       void remove_named_selection (boost::shared_ptr<NamedSelection>);
 
-       template<class T> void foreach_named_selection (T& obj, void (T::*func)(NamedSelection&));
-       sigc::signal<void> NamedSelectionAdded;
-       sigc::signal<void> NamedSelectionRemoved;
+       template<class T> void foreach_named_selection (T& obj, void (T::*func)(boost::shared_ptr<NamedSelection>));
+       PBD::Signal0<void> NamedSelectionAdded;
+       PBD::Signal0<void> NamedSelectionRemoved;
 
        /* Curves and AutomationLists (TODO when they go away) */
        void add_automation_list(AutomationList*);
@@ -606,33 +570,37 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void cancel_audition ();
        bool is_auditioning () const;
 
-       sigc::signal<void,bool> AuditionActive;
+       PBD::Signal1<void,bool> AuditionActive;
 
        /* flattening stuff */
 
        boost::shared_ptr<Region> write_one_track (AudioTrack&, nframes_t start, nframes_t end,
                        bool overwrite, std::vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot,
                        bool enable_processing = true);
-       int freeze (InterThreadInfo&);
+       int freeze_all (InterThreadInfo&);
 
        /* session-wide solo/mute/rec-enable */
 
        bool soloing() const { return _non_soloed_outs_muted; }
        bool listening() const { return _listen_cnt > 0; }
+        bool solo_isolated() const { return _solo_isolated_cnt > 0; }
 
-       void set_all_solo (bool);
-       void set_all_mute (bool);
-       void set_all_listen (bool);
-
-       sigc::signal<void,bool> SoloActive;
-       sigc::signal<void> SoloChanged;
+       static const SessionEvent::RTeventCallback rt_cleanup;
 
-       void record_disenable_all (sigc::slot<void,SessionEvent*>);
-       void record_enable_all (sigc::slot<void,SessionEvent*>);
+       void set_solo (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+       void set_just_one_solo (boost::shared_ptr<Route>, bool, SessionEvent::RTeventCallback after = rt_cleanup);
+       void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+       void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+       void set_record_enable (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+        void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
 
+       PBD::Signal1<void,bool> SoloActive;
+       PBD::Signal0<void> SoloChanged;
+        PBD::Signal0<void> IsolatedChanged;
+       
        /* control/master out */
 
-       boost::shared_ptr<Route> control_out() const { return _control_out; }
+       boost::shared_ptr<Route> monitor_out() const { return _monitor_out; }
        boost::shared_ptr<Route> master_out() const { return _master_out; }
 
        void globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p);
@@ -654,6 +622,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void mark_send_id (uint32_t);
        void mark_return_id (uint32_t);
        void mark_insert_id (uint32_t);
+       void unmark_send_id (uint32_t);
+       void unmark_return_id (uint32_t);
+       void unmark_insert_id (uint32_t);
 
        /* s/w "RAID" management */
 
@@ -665,34 +636,10 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void remove_bundle (boost::shared_ptr<Bundle>);
        boost::shared_ptr<Bundle> bundle_by_name (std::string) const;
 
-       sigc::signal<void,boost::shared_ptr<Bundle> > BundleAdded;
-       sigc::signal<void,boost::shared_ptr<Bundle> > BundleRemoved;
-
-       /* MIDI control */
-
-       void midi_panic(void);
-       int set_mtc_port (std::string port_tag);
-       int set_mmc_port (std::string port_tag);
-       int set_midi_port (std::string port_tag);
-       int set_midi_clock_port (std::string port_tag);
-       MIDI::Port *mtc_port() const { return _mtc_port; }
-       MIDI::Port *mmc_port() const { return _mmc_port; }
-       MIDI::Port *midi_port() const { return _midi_port; }
-       MIDI::Port *midi_clock_port() const { return _midi_clock_port; }
-
-       sigc::signal<void> MTC_PortChanged;
-       sigc::signal<void> MMC_PortChanged;
-       sigc::signal<void> MIDI_PortChanged;
-       sigc::signal<void> MIDIClock_PortChanged;
-
-       void set_trace_midi_input (bool, MIDI::Port* port = 0);
-       void set_trace_midi_output (bool, MIDI::Port* port = 0);
+       PBD::Signal1<void,boost::shared_ptr<Bundle> > BundleAdded;
+       PBD::Signal1<void,boost::shared_ptr<Bundle> > BundleRemoved;
 
-       bool get_trace_midi_input(MIDI::Port *port = 0);
-       bool get_trace_midi_output(MIDI::Port *port = 0);
-
-       void set_mmc_receive_device_id (uint32_t id);
-       void set_mmc_send_device_id (uint32_t id);
+       void midi_panic ();
 
        /* Scrubbing */
 
@@ -700,7 +647,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void stop_scrub ();
        void set_scrub_speed (float);
        nframes_t scrub_buffer_size() const;
-       sigc::signal<void> ScrubReady;
+       PBD::Signal0<void> ScrubReady;
 
        /* History (for editors, mixers, UIs etc.) */
 
@@ -733,78 +680,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
                _current_trans.top()->add_command (cmd);
        }
 
-       std::map<PBD::ID, PBD::StatefulThingWithGoingAway*> registry;
+       std::map<PBD::ID,PBD::StatefulDestructible*> registry;
 
        // these commands are implemented in libs/ardour/session_command.cc
        Command* memento_command_factory(XMLNode* n);
-       void register_with_memento_command_factory(PBD::ID, PBD::StatefulThingWithGoingAway*);
-
-       Command* global_state_command_factory (const XMLNode& n);
-
-       class GlobalRouteStateCommand : public Command
-       {
-       public:
-               GlobalRouteStateCommand (Session&, void*);
-               GlobalRouteStateCommand (Session&, const XMLNode& node);
-               int set_state (const XMLNode&, int version);
-               XMLNode& get_state ();
-
-       protected:
-               GlobalRouteBooleanState before, after;
-               Session& sess;
-               void* src;
-       };
-
-       class GlobalSoloStateCommand : public GlobalRouteStateCommand
-       {
-       public:
-               GlobalSoloStateCommand (Session &, void *src);
-               GlobalSoloStateCommand (Session&, const XMLNode&);
-               void operator()(); //redo
-               void undo();
-               XMLNode &get_state();
-               void mark();
-       };
-
-       class GlobalMuteStateCommand : public GlobalRouteStateCommand
-       {
-       public:
-               GlobalMuteStateCommand(Session &, void *src);
-               GlobalMuteStateCommand (Session&, const XMLNode&);
-               void operator()(); // redo
-               void undo();
-               XMLNode &get_state();
-               void mark();
-       };
-
-       class GlobalRecordEnableStateCommand : public GlobalRouteStateCommand
-       {
-       public:
-               GlobalRecordEnableStateCommand(Session &, void *src);
-               GlobalRecordEnableStateCommand (Session&, const XMLNode&);
-               void operator()(); // redo
-               void undo();
-               XMLNode &get_state();
-               void mark();
-       };
-
-       class GlobalMeteringStateCommand : public Command
-       {
-       public:
-               GlobalMeteringStateCommand(Session &, void *src);
-               GlobalMeteringStateCommand (Session&, const XMLNode&);
-               void operator()();
-               void undo();
-               XMLNode &get_state();
-               int set_state (const XMLNode&, int version);
-               void mark();
-
-       protected:
-               Session& sess;
-               void* src;
-               GlobalRouteMeterState before;
-               GlobalRouteMeterState after;
-       };
+       Command* stateful_diff_command_factory (XMLNode *);
+       void register_with_memento_command_factory(PBD::ID, PBD::StatefulDestructible*);
 
        /* clicking */
 
@@ -814,11 +695,6 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        uint32_t playback_load ();
        uint32_t capture_load ();
-       uint32_t playback_load_min ();
-       uint32_t capture_load_min ();
-
-       void reset_playback_load_min ();
-       void reset_capture_load_min ();
 
        /* ranges */
 
@@ -827,8 +703,8 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        /* 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; }
+       gain_t* gain_automation_buffer () const;
+       pan_t** pan_automation_buffer () const;
 
        void ensure_buffer_set (BufferSet& buffers, const ChanCount& howmany);
 
@@ -841,11 +717,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
                        void* ptr,
                        float opt);
 
-       static sigc::signal<void> SendFeedback;
+       static PBD::Signal0<void> SendFeedback;
 
        /* Controllables */
 
        boost::shared_ptr<PBD::Controllable> controllable_by_id (const PBD::ID&);
+       boost::shared_ptr<PBD::Controllable> controllable_by_descriptor (const PBD::ControllableDescriptor&);
 
        void add_controllable (boost::shared_ptr<PBD::Controllable>);
        void remove_controllable (PBD::Controllable*);
@@ -879,7 +756,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
                PostTransportReverse            = 0x10000,
                PostTransportInputChange        = 0x20000,
                PostTransportCurveRealloc       = 0x40000,
-               PostTransportClearSubstate      = 0x80000
+               PostTransportClearSubstate      = 0x80000,
+               PostTransportAdjustPlaybackBuffering  = 0x100000,
+               PostTransportAdjustCaptureBuffering   = 0x200000
        };
 
        enum SlaveState {
@@ -892,6 +771,11 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        boost::shared_ptr<SessionPlaylists> playlists;
 
+       void send_mmc_locate (nframes64_t);
+       int send_full_time_code (nframes64_t);
+
+       PBD::Signal0<void> RouteOrderKeyChanged;
+
   protected:
        friend class AudioEngine;
        void set_block_size (nframes_t nframes);
@@ -903,18 +787,14 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void update_latency_compensation (bool, bool);
 
   private:
-       int  create (bool& new_session, const std::string& mix_template, nframes_t initial_length);
+       int  create (const std::string& mix_template, BusProfile*);
        void destroy ();
 
-       nframes_t compute_initial_length ();
-
        enum SubState {
                PendingDeclickIn   = 0x1,
                PendingDeclickOut  = 0x2,
                StopPendingCapture = 0x4,
-               AutoReturning      = 0x10,
                PendingLocate      = 0x20,
-               PendingSetLoop     = 0x40
        };
 
        /* stuff used in process() should be close together to
@@ -934,8 +814,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        int                      transport_sub_state;
        mutable gint            _record_status;
        volatile nframes64_t    _transport_frame;
-       Location*                end_location;
-       Location*                start_location;
+       Location*               _session_range_location; ///< session range, or 0 if there is nothing in the session yet
        Slave*                  _slave;
        bool                    _silent;
 
@@ -949,9 +828,6 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        nframes64_t             _last_slave_transport_frame;
        nframes_t                maximum_output_latency;
        volatile nframes64_t    _requested_return_frame;
-       BufferSet*              _scratch_buffers;
-       BufferSet*              _silent_buffers;
-       BufferSet*              _mix_buffers;
        nframes_t                current_block_size;
        nframes_t               _worst_output_latency;
        nframes_t               _worst_input_latency;
@@ -961,6 +837,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        float                   _meter_falloff;
        bool                    _non_soloed_outs_muted;
        uint32_t                _listen_cnt;
+       uint32_t                _solo_isolated_cnt;
        bool                    _writable;
        bool                    _was_seamless;
 
@@ -971,7 +848,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        void update_latency_compensation_proxy (void* ignored);
 
-       void ensure_buffers (ChanCount howmany);
+       void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
 
        void process_scrub          (nframes_t);
        void process_without_events (nframes_t);
@@ -984,6 +861,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void unblock_processing() { g_atomic_int_set (&processing_prohibited, 0); }
        bool processing_blocked() const { return g_atomic_int_get (&processing_prohibited); }
 
+        Glib::Mutex                process_thread_lock;
+        std::list<ProcessThread*>  process_threads;
+
        /* slave tracking */
 
        static const int delta_accumulator_size = 25;
@@ -1010,7 +890,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        nframes_t post_export_position;
 
        bool _exporting;
-       bool _exporting_realtime;
+       bool _export_rolling;
 
        boost::shared_ptr<ExportHandler> export_handler;
        boost::shared_ptr<ExportStatus>  export_status;
@@ -1019,12 +899,11 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        int  stop_audio_export ();
        void finalize_audio_export ();
 
-       sigc::connection export_freewheel_connection;
+       PBD::ScopedConnection export_freewheel_connection;
 
-       void prepare_diskstreams ();
-       void commit_diskstreams (nframes_t, bool& session_requires_butler);
-       int  process_routes (nframes_t);
-       int  silent_process_routes (nframes_t);
+       void get_track_statistics ();
+       int  process_routes (nframes_t, bool& need_butler);
+       int  silent_process_routes (nframes_t, bool& need_butler);
 
        bool get_rec_monitors_input () {
                if (actively_recording()) {
@@ -1054,14 +933,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        void check_declick_out ();
 
-       MIDI::MachineControl*    mmc;
-       MIDI::Port*             _mmc_port;
-       MIDI::Port*             _mtc_port;
-       MIDI::Port*             _midi_port;
-       MIDI::Port*             _midi_clock_port;
        std::string             _path;
        std::string             _name;
-       bool                     session_send_mmc;
+        bool                    _is_new;
        bool                     session_send_mtc;
        bool                     session_midi_feedback;
        bool                     play_loop;
@@ -1085,6 +959,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        int      load_state (std::string snapshot_name);
 
        nframes_t _last_roll_location;
+       nframes_t _last_roll_or_reversal_location;
        nframes_t _last_record_location;
 
        bool              pending_locate_roll;
@@ -1132,6 +1007,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void set_post_transport_work (PostTransportWork ptw) { g_atomic_int_set (&_post_transport_work, (gint) ptw); }
        void add_post_transport_work (PostTransportWork ptw);
 
+        void schedule_playback_buffering_adjustment ();
+        void schedule_capture_buffering_adjustment ();
+
        uint32_t    cumulative_rf_motion;
        uint32_t    rf_scale;
 
@@ -1143,21 +1021,17 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void              locations_added (Location*);
        void              handle_locations_changed (Locations::LocationList&);
 
-       sigc::connection auto_punch_start_changed_connection;
-       sigc::connection auto_punch_end_changed_connection;
-       sigc::connection auto_punch_changed_connection;
+       PBD::ScopedConnectionList punch_connections;
        void             auto_punch_start_changed (Location *);
        void             auto_punch_end_changed (Location *);
        void             auto_punch_changed (Location *);
 
-       sigc::connection auto_loop_start_changed_connection;
-       sigc::connection auto_loop_end_changed_connection;
-       sigc::connection auto_loop_changed_connection;
+       PBD::ScopedConnectionList loop_connections;
        void             auto_loop_changed (Location *);
 
        void first_stage_init (std::string path, std::string snapshot_name);
-       int  second_stage_init (bool new_tracks);
-       void find_current_end ();
+       int  second_stage_init ();
+       void update_session_range_location_marker ();
        void remove_empty_sounds ();
 
        void setup_midi_control ();
@@ -1188,15 +1062,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        /* SessionEventManager interface */
 
-       void queue_event (SessionEvent*);
        void process_event (SessionEvent*);
        void set_next_event ();
        void cleanup_event (SessionEvent*,int);
 
        /* MIDI Machine Control */
 
-       void deliver_mmc (MIDI::MachineControl::Command, nframes_t);
-
        void spp_start (MIDI::Parser&, nframes_t timestamp);
        void spp_continue (MIDI::Parser&, nframes_t timestamp);
        void spp_stop (MIDI::Parser&, nframes_t timestamp);
@@ -1218,13 +1089,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        struct timeval last_mmc_step;
        double step_speed;
 
-       typedef sigc::slot<bool> MidiTimeoutCallback;
+       typedef boost::function<bool()> MidiTimeoutCallback;
        typedef std::list<MidiTimeoutCallback> MidiTimeoutList;
 
        MidiTimeoutList midi_timeouts;
        bool mmc_step_timeout ();
 
-       MIDI::byte mmc_buffer[32];
        MIDI::byte mtc_msg[16];
        MIDI::byte mtc_timecode_bits;   /* encoding of SMTPE type for MTC */
        MIDI::byte midi_msg[16];
@@ -1246,7 +1116,6 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        bool _send_timecode_update; ///< Flag to send a full frame (Timecode) MTC message this cycle
 
-       int send_full_time_code(nframes_t nframes);
        int send_midi_time_code_for_cycle(nframes_t nframes);
 
        nframes_t adjust_apparent_position (nframes_t frames);
@@ -1259,36 +1128,20 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        bool non_realtime_work_pending() const { return static_cast<bool>(post_transport_work()); }
        bool process_can_proceed() const { return !(post_transport_work() & ProcessCannotProceedMask); }
 
-       struct MIDIRequest {
-               enum Type {
-                       PortChange,
-                       Quit
-               };
-               Type type;
-       };
-
-       Glib::Mutex  midi_lock;
-       pthread_t    midi_thread;
-       int          midi_request_pipe[2];
-       RingBuffer<MIDIRequest*> midi_requests;
+       MidiControlUI* midi_control_ui;
 
        int           start_midi_thread ();
        void          terminate_midi_thread ();
-       void          poke_midi_thread ();
-       static void *_midi_thread_work (void *arg);
-       void          midi_thread_work ();
-       void          change_midi_ports ();
-       int           use_config_midi_ports ();
 
        void set_play_loop (bool yn);
        void unset_play_loop ();
-       void overwrite_some_buffers (Diskstream*);
+       void overwrite_some_buffers (Track *);
        void flush_all_inserts ();
        int  micro_locate (nframes_t distance);
-        void locate (nframes64_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
+        void locate (nframes64_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false, bool with_mmc=true);
         void start_locate (nframes64_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
        void force_locate (nframes64_t frame, bool with_roll = false);
-       void set_diskstream_speed (Diskstream*, double speed);
+       void set_track_speed (Track *, double speed);
         void set_transport_speed (double speed, bool abort = false, bool clear_state = false);
        void stop_transport (bool abort = false, bool clear_state = false);
        void start_transport ();
@@ -1303,7 +1156,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        void xrun_recovery ();
 
        TempoMap    *_tempo_map;
-       void          tempo_map_changed (Change);
+       void          tempo_map_changed (const PBD::PropertyChange&);
 
        /* edit/mix groups */
 
@@ -1311,30 +1164,32 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        std::list<RouteGroup *> _route_groups;
 
-       /* disk-streams */
-
-       SerializedRCUManager<DiskstreamList>  diskstreams;
-
-       int load_diskstreams (const XMLNode&);
-
        /* routes stuff */
 
+       boost::shared_ptr<Graph> route_graph;
+
        SerializedRCUManager<RouteList>  routes;
 
        void add_routes (RouteList&, bool save);
        uint32_t destructive_index;
 
        boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&, int);
+       boost::shared_ptr<Route> XMLRouteFactory_2X (const XMLNode&, int);
 
        void route_processors_changed (RouteProcessorChange);
 
+       bool find_route_name (const char* base, uint32_t& id, char* name, size_t name_len);
+       void count_existing_route_channels (ChanCount& in, ChanCount& out);
+       void auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs = true);
+
        /* mixer stuff */
 
        bool solo_update_disabled;
 
        void route_listen_changed (void *src, boost::weak_ptr<Route>);
        void route_mute_changed (void *src);
-       void route_solo_changed (void *src, boost::weak_ptr<Route>);
+       void route_solo_changed (bool self_solo_change, void *src, boost::weak_ptr<Route>);
+       void route_solo_isolated_changed (void *src, boost::weak_ptr<Route>);
        void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());
 
        void listen_position_changed ();
@@ -1342,16 +1197,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        /* REGION MANAGEMENT */
 
-       std::map<std::string,uint32_t> region_name_map;
-       void update_region_name_map (boost::shared_ptr<Region>);
-
        mutable Glib::Mutex region_lock;
-       typedef std::map<PBD::ID,boost::shared_ptr<Region> > RegionList;
-       RegionList regions;
-
-       void add_region (boost::shared_ptr<Region>);
-       void region_changed (Change, boost::weak_ptr<Region>);
-       void remove_region (boost::weak_ptr<Region>);
 
        int load_regions (const XMLNode& node);
 
@@ -1360,8 +1206,11 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        /* SOURCES */
 
        mutable Glib::Mutex source_lock;
+
+  public:      
        typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap;
 
+  private:     
        SourceMap sources;
 
   public:
@@ -1377,12 +1226,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        void remove_playlist (boost::weak_ptr<Playlist>);
        void playlist_length_changed ();
-       void diskstream_playlist_changed (boost::weak_ptr<Diskstream>);
+       void track_playlist_changed (boost::weak_ptr<Track>);
 
        /* NAMED SELECTIONS */
 
        mutable Glib::Mutex named_selection_lock;
-       typedef std::set<NamedSelection *> NamedSelectionList;
+       typedef std::set<boost::shared_ptr<NamedSelection> > NamedSelectionList;
        NamedSelectionList named_selections;
 
        int load_named_selections (const XMLNode&);
@@ -1417,9 +1266,6 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        boost::dynamic_bitset<uint32_t> return_bitset;
        boost::dynamic_bitset<uint32_t> insert_bitset;
 
-       void add_processor (Processor *);
-       void remove_processor (Processor *);
-
        /* S/W RAID */
 
        struct space_and_path {
@@ -1448,8 +1294,6 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        mutable gint _playback_load;
        mutable gint _capture_load;
-       mutable gint _playback_load_min;
-       mutable gint _capture_load_min;
 
        /* I/O bundles */
 
@@ -1457,26 +1301,14 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        XMLNode* _bundle_xml_node;
        int load_bundles (XMLNode const &);
 
-       void reverse_diskstream_buffers ();
+       void reverse_track_buffers ();
 
        UndoHistory                  _history;
        std::stack<UndoTransaction*> _current_trans;
 
-       GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
-       GlobalRouteMeterState get_global_route_metering ();
-
-       void set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void *arg);
-       void set_global_route_metering (GlobalRouteMeterState s, void *arg);
-
-       void set_global_mute (GlobalRouteBooleanState s, void *src);
-       void set_global_solo (GlobalRouteBooleanState s, void *src);
-       void set_global_record_enable (GlobalRouteBooleanState s, void *src);
-
        void jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int);
        int  jack_sync_callback (jack_transport_state_t, jack_position_t*);
        void reset_jack_connection (jack_client_t* jack);
-       void record_enable_change_all (bool yn, sigc::slot<void,SessionEvent*>);
-       void do_record_enable_change_all (RouteList*, bool);
        void process_rtop (SessionEvent*);
 
        XMLNode& state(bool);
@@ -1515,12 +1347,7 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
        uint32_t main_outs;
 
        boost::shared_ptr<Route> _master_out;
-       boost::shared_ptr<Route> _control_out;
-
-       gain_t* _gain_automation_buffer;
-       pan_t** _pan_automation_buffer;
-       void allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force);
-       uint32_t _npan_buffers;
+       boost::shared_ptr<Route> _monitor_out;
 
        /* VST support */
 
@@ -1568,8 +1395,31 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu
 
        mutable bool have_looped; ///< Used in ::audible_frame(*)
 
-       void update_have_rec_enabled_diskstream ();
-       gint _have_rec_enabled_diskstream;
+       void update_have_rec_enabled_track ();
+       gint _have_rec_enabled_track;
+
+       static int ask_about_playlist_deletion (boost::shared_ptr<Playlist>);
+
+       /* realtime "apply to set of routes" operations */
+       SessionEvent* get_rt_event (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override, 
+               void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool));
+
+       void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+       void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
+       void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+       void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+       void rt_set_solo_isolated (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+       void rt_set_record_enable (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+
+       /** temporary list of Diskstreams used only during load of 2.X sessions */
+       std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;
+
+       void add_session_range_location (nframes_t, nframes_t);
+
+       void setup_midi_machine_control ();
+        void cleanup_stubfiles ();
+
+       void route_order_key_changed ();
 };
 
 } // namespace ARDOUR