Create the session range location as and when the session first gets some content...
[ardour.git] / libs / ardour / ardour / session.h
index 4af432eeb567945ffdd985aceb49dd9c4e0728b9..0f5a73a28032df055e40272cbf2ddc8f20b5398c 100644 (file)
 #include "ardour/timecode.h"
 #include "ardour/interpolation.h"
 
+#ifdef HAVE_JACK_SESSION
+#include <jack/session.h>
+#endif
+
 class XMLTree;
 class XMLNode;
 class AEffect;
@@ -73,7 +77,6 @@ namespace Evoral {
 
 namespace ARDOUR {
 
-class AudioDiskstream;
 class AudioEngine;
 class AudioFileSource;
 class AudioRegion;
@@ -92,7 +95,6 @@ class ExportStatus;
 class IO;
 class IOProcessor;
 class ImportStatus;
-class MidiDiskstream;
 class MidiRegion;
 class MidiSource;
 class MidiTrack;
@@ -102,6 +104,7 @@ class Playlist;
 class PluginInsert;
 class Port;
 class PortInsert;
+class ProcessThread;
 class Processor;
 class Region;
 class Return;
@@ -116,6 +119,7 @@ class Slave;
 class Source;
 class TempoMap;
 class VSTPlugin;
+class Track;
 
 extern void setup_enum_writer ();
 
@@ -188,26 +192,18 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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 ();
@@ -235,6 +231,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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);
@@ -273,7 +270,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        PBD::Signal0<void> TransportStateChange; /* generic */
        PBD::Signal1<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
-       PBD::Signal0<void> DurationChanged;
        PBD::Signal1<void,nframes64_t> Xrun;
        PBD::Signal0<void> TransportLooped;
 
@@ -294,15 +290,15 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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 request_track_speed (Track *, double speed);
        void request_input_change_handling ();
 
        bool locate_pending() const { return static_cast<bool>(post_transport_work()&PostTransportLocate); }
@@ -310,9 +306,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        int wipe ();
 
-       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
@@ -348,7 +344,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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 = "");
@@ -421,9 +420,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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; }
@@ -533,9 +529,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        */
        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<AudioFileSource> create_audio_source_for_session (size_t, std::string const &, uint32_t, bool);
 
-       boost::shared_ptr<MidiSource> create_midi_source_for_session (ARDOUR::MidiDiskstream&);
+       boost::shared_ptr<MidiSource> create_midi_source_for_session (std::string const &);
 
        boost::shared_ptr<Source> source_by_id (const PBD::ID&);
        boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t);
@@ -582,6 +578,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        bool soloing() const { return _non_soloed_outs_muted; }
        bool listening() const { return _listen_cnt > 0; }
+        bool solo_isolated() const { return _solo_isolated_cnt > 0; }
 
        static const SessionEvent::RTeventCallback rt_cleanup;
 
@@ -590,11 +587,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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> monitor_out() const { return _monitor_out; }
@@ -619,6 +617,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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 */
 
@@ -726,8 +727,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        /* 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);
 
@@ -803,11 +804,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        void update_latency_compensation (bool, bool);
 
   private:
-       int  create (const std::string& mix_template, nframes_t initial_length, BusProfile*);
+       int  create (const std::string& mix_template, BusProfile*);
        void destroy ();
 
-       nframes_t compute_initial_length ();
-
        enum SubState {
                PendingDeclickIn   = 0x1,
                PendingDeclickOut  = 0x2,
@@ -834,8 +833,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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;
 
@@ -849,9 +847,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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;
@@ -861,6 +856,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        float                   _meter_falloff;
        bool                    _non_soloed_outs_muted;
        uint32_t                _listen_cnt;
+       uint32_t                _solo_isolated_cnt;
        bool                    _writable;
        bool                    _was_seamless;
 
@@ -871,7 +867,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        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);
@@ -884,6 +880,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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;
@@ -921,7 +920,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        PBD::ScopedConnection export_freewheel_connection;
 
-       void get_diskstream_statistics ();
+       void get_track_statistics ();
        int  process_routes (nframes_t, bool& need_butler);
        int  silent_process_routes (nframes_t, bool& need_butler);
 
@@ -985,6 +984,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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;
@@ -1053,7 +1053,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        void first_stage_init (std::string path, std::string snapshot_name);
        int  second_stage_init ();
-       void find_current_end ();
+       void update_session_range_location_marker ();
        void remove_empty_sounds ();
 
        void setup_midi_control ();
@@ -1163,13 +1163,13 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        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 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 ();
@@ -1192,12 +1192,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        std::list<RouteGroup *> _route_groups;
 
-       /* disk-streams */
-
-       SerializedRCUManager<DiskstreamList>  diskstreams;
-
-       int load_diskstreams (const XMLNode&);
-
        /* routes stuff */
 
        SerializedRCUManager<RouteList>  routes;
@@ -1206,6 +1200,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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);
 
@@ -1220,7 +1215,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        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 ();
@@ -1254,7 +1250,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        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 */
 
@@ -1294,9 +1290,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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 {
@@ -1334,7 +1327,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        XMLNode* _bundle_xml_node;
        int load_bundles (XMLNode const &);
 
-       void reverse_diskstream_buffers ();
+       void reverse_track_buffers ();
 
        UndoHistory                  _history;
        std::stack<UndoTransaction*> _current_trans;
@@ -1382,11 +1375,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        boost::shared_ptr<Route> _master_out;
        boost::shared_ptr<Route> _monitor_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;
-
        /* VST support */
 
        long _vst_callback (VSTPlugin*,
@@ -1433,8 +1421,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        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>);
 
@@ -1446,7 +1434,13 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        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);
 };
 
 } // namespace ARDOUR