changes related to resetting source paths during save-as.
[ardour.git] / libs / ardour / ardour / session.h
index ade8fa79049e4886a7a3b61c25a8d55db5e757fb..4b50e7c21fd671bc0622426b45f82f7bd68097a8 100644 (file)
@@ -36,7 +36,7 @@
 
 #include <glibmm/threads.h>
 
-#include <ltc/ltc.h>
+#include <ltc.h>
 
 #include "pbd/error.h"
 #include "pbd/event_loop.h"
@@ -48,6 +48,7 @@
 #include "evoral/types.hpp"
 
 #include "midi++/types.h"
+#include "midi++/mmc.h"
 
 #include "timecode/time.h"
 
 #include "ardour/interpolation.h"
 #include "ardour/route_graph.h"
 
-#ifdef HAVE_JACK_SESSION
-#include <jack/session.h>
-#endif
-
 
 class XMLTree;
 class XMLNode;
@@ -129,6 +126,7 @@ class Route;
 class RouteGroup;
 class SMFSource;
 class Send;
+class SceneChanger;
 class SessionDirectory;
 class SessionMetadata;
 class SessionPlaylists;
@@ -141,7 +139,7 @@ class WindowsVSTPlugin;
 
 extern void setup_enum_writer ();
 
-class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager
+class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager
 {
   public:
        enum RecordState {
@@ -194,13 +192,16 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
 
        std::string peak_path (std::string) const;
 
-       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&);
+       bool audio_source_name_is_unique (const std::string& name, uint32_t chan);
+       std::string format_audio_source_name (const std::string& legalized_base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required, uint32_t cnt, bool related_exists);
+       std::string new_audio_source_path_for_embedded (const std::string& existing_path);
+       std::string new_audio_source_path (const std::string&, uint32_t nchans, uint32_t chan, bool destructive, bool take_required);
+       std::string new_midi_source_path (const std::string&);
         RouteList new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name);
+       std::vector<std::string> get_paths_for_new_sources (bool allow_replacing, const std::string& import_file_path, uint32_t channels);
+
+       int bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,std::string)> callback);
 
        void process (pframes_t nframes);
 
@@ -226,8 +227,8 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
                return routes.reader ();
        }
 
+       boost::shared_ptr<RouteList> get_tracks() const;
        boost::shared_ptr<RouteList> get_routes_with_internal_returns() const;
-
        boost::shared_ptr<RouteList> get_routes_with_regions_at (framepos_t const) const;
 
        uint32_t nroutes() const { return routes.reader()->size(); }
@@ -238,7 +239,7 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
                return _bundles.reader ();
        }
 
-       struct RoutePublicOrderSorter {
+       struct LIBARDOUR_API RoutePublicOrderSorter {
                bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
        };
 
@@ -261,6 +262,10 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        bool route_name_unique (std::string) const;
        bool route_name_internal (std::string) const;
 
+       uint32_t track_number_decimals () const {
+               return _track_number_decimals;
+       }
+
        bool get_record_enabled() const {
                return (record_status () >= Enabled);
        }
@@ -379,6 +384,7 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
 
        void set_auto_punch_location (Location *);
        void set_auto_loop_location (Location *);
+       void set_session_extents (framepos_t start, framepos_t end);
        int location_name(std::string& result, std::string base = std::string(""));
 
        pframes_t get_block_size()        const { return current_block_size; }
@@ -386,7 +392,33 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        framecnt_t worst_input_latency ()  const { return _worst_input_latency; }
        framecnt_t worst_track_latency ()  const { return _worst_track_latency; }
        framecnt_t worst_playback_latency () const { return _worst_output_latency + _worst_track_latency; }
+       
+       struct SaveAs {
+               std::string new_parent_folder;  /* parent folder where new session folder will be created */
+               std::string new_name;           /* name of newly saved session */
+               bool        switch_to;     /* true if we should be working on newly saved session after save-as; false otherwise */
+               bool        copy_media;    /* true if media files (audio, media, etc) should be copied into newly saved session; false otherwise */
+               bool        copy_external; /* true if external media should be consolidated into the newly saved session; false otherwise */
+               
+               /* emitted as we make progress. 3 arguments passed to signal
+                * handler:
+                *
+                *  1: percentage complete measured as a fraction (0-1.0) of
+                *     total data copying done.
+                *  2: number of files copied so far
+                *  3: total number of files to copy
+                *
+                * Handler should return true for save-as to continue, or false
+                * to stop (and remove all evidence of partial save-as).
+                */
+               PBD::Signal3<bool,float,int64_t,int64_t> Progress;
+
+               /* if save_as() returns non-zero, this string will indicate the reason why.
+                */
+               std::string failure_message;
+       };
 
+       int save_as (SaveAs&);
        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);
@@ -395,16 +427,17 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        void remove_state (std::string snapshot_name);
        void rename_state (std::string old_name, std::string new_name);
        void remove_pending_capture_state ();
-       int rename (const std::string&);
+       int rename (const std::string&, bool after_copy = false);
        bool get_nsm_state () const { return _under_nsm_control; }
        void set_nsm_state (bool state) { _under_nsm_control = state; }
+       bool save_default_options ();
 
        PBD::Signal1<void,std::string> StateSaved;
        PBD::Signal0<void> StateReady;
        PBD::Signal0<void> SaveSession;
 
-       std::vector<std::string*>* possible_states() const;
-       static std::vector<std::string*>* possible_states (std::string path);
+       std::vector<std::string> possible_states() const;
+       static std::vector<std::string> possible_states (std::string path);
 
        XMLNode& get_state();
        int      set_state(const XMLNode& node, int version); // not idempotent
@@ -426,6 +459,23 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
 
        StateOfTheState state_of_the_state() const { return _state_of_the_state; }
 
+       class StateProtector {
+               public:
+                       StateProtector (Session* s) : _session (s) {
+                               g_atomic_int_inc (&s->_suspend_save);
+                       }
+                       ~StateProtector () {
+                               if (g_atomic_int_dec_and_test (&_session->_suspend_save)) {
+                                       while (_session->_save_queued) {
+                                               _session->_save_queued = false;
+                                               _session->save_state ("");
+                                       }
+                               }
+                       }
+               private:
+                       Session * _session;
+       };
+
        void add_route_group (RouteGroup *);
        void remove_route_group (RouteGroup&);
        void reorder_route_groups (std::list<RouteGroup*>);
@@ -479,8 +529,10 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        /* Time */
 
        framepos_t transport_frame () const {return _transport_frame; }
+       framepos_t record_location () const {return _last_record_location; }
        framepos_t audible_frame () const;
        framepos_t requested_return_frame() const { return _requested_return_frame; }
+       void set_requested_return_frame(framepos_t return_to);
 
        enum PullupFormat {
                pullup_Plus4Plus1,
@@ -522,14 +574,13 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        void set_silent (bool yn);
        bool silent () { return _silent; }
 
-       TempoMap& tempo_map() { return *_tempo_map; }
+       TempoMap&       tempo_map()       { return *_tempo_map; }
+       const TempoMap& tempo_map() const { return *_tempo_map; }
 
        /* region info  */
 
        boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>) const;
 
-       std::string path_from_region_name (DataType type, std::string name, std::string identifier);
-
        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);
@@ -582,11 +633,12 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        boost::shared_ptr<AudioFileSource> create_audio_source_for_session (
                size_t, std::string const &, uint32_t, bool destructive);
 
-       boost::shared_ptr<MidiSource> create_midi_source_for_session (
-               Track*, std::string const &);
+       boost::shared_ptr<MidiSource> create_midi_source_for_session (std::string const &);
+       boost::shared_ptr<MidiSource> create_midi_source_by_stealing_name (boost::shared_ptr<Track>);
 
        boost::shared_ptr<Source> source_by_id (const PBD::ID&);
-       boost::shared_ptr<Source> source_by_path_and_channel (const std::string&, uint16_t);
+       boost::shared_ptr<AudioFileSource> audio_source_by_path_and_channel (const std::string&, uint16_t) const;
+       boost::shared_ptr<MidiSource> midi_source_by_path (const std::string&) const;
        uint32_t count_sources_by_origin (const std::string&);
 
        void add_playlist (boost::shared_ptr<Playlist>, bool unused = false);
@@ -606,9 +658,10 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
 
        /* flattening stuff */
 
-       boost::shared_ptr<Region> write_one_track (AudioTrack&, framepos_t start, framepos_t end,
+       boost::shared_ptr<Region> write_one_track (Track&, framepos_t start, framepos_t end,
                                                   bool overwrite, std::vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot,
-                                                  boost::shared_ptr<Processor> endpoint, bool include_endpoint, bool for_export);
+                                                  boost::shared_ptr<Processor> endpoint,
+                                                        bool include_endpoint, bool for_export, bool for_freeze);
        int freeze_all (InterThreadInfo&);
 
        /* session-wide solo/mute/rec-enable */
@@ -742,6 +795,7 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        /* ranges */
 
        void request_play_range (std::list<AudioRange>*, bool leave_rolling = false);
+       void request_cancel_play_range ();
        bool get_play_range () const { return _play_range; }
 
        void maybe_update_session_range (framepos_t, framepos_t);
@@ -756,6 +810,10 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
 
        /* VST support */
 
+       static int  vst_current_loading_id;
+       static const char* vst_can_do_strings[];
+       static const int vst_can_do_string_count;
+
        static intptr_t vst_callback (
                AEffect* effect,
                int32_t opcode,
@@ -787,6 +845,10 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
                return _exporting;
        }
 
+       bool bounce_processing() const {
+               return _bounce_processing_active;
+       }
+
        /* this is a private enum, but setup_enum_writer() needs it,
           and i can't find a way to give that function
           friend access. sigh.
@@ -830,8 +892,9 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        void request_resume_timecode_transmission ();
        bool timecode_transmission_suspended () const;
 
-       std::string source_search_path(DataType) const;
+       std::vector<std::string> source_search_path(DataType) const;
        void ensure_search_path_includes (const std::string& path, DataType type);
+       void remove_dir_from_search_path (const std::string& path, DataType type);
 
        std::list<std::string> unknown_processors () const;
 
@@ -865,28 +928,37 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
         */
         static PBD::Signal2<void,std::string,std::string> VersionMismatch;
 
+       SceneChanger* scene_changer() const { return _scene_changer; }
+
         boost::shared_ptr<Port> ltc_input_port() const;
         boost::shared_ptr<Port> ltc_output_port() const;
 
        boost::shared_ptr<IO> ltc_input_io() { return _ltc_input; }
        boost::shared_ptr<IO> ltc_output_io() { return _ltc_output; }
 
-    MIDI::Port* midi_input_port () const;
-    MIDI::Port* midi_output_port () const;
-    MIDI::Port* mmc_output_port () const;
-    MIDI::Port* mmc_input_port () const;
+       MIDI::Port* midi_input_port () const;
+       MIDI::Port* midi_output_port () const;
+       MIDI::Port* mmc_output_port () const;
+       MIDI::Port* mmc_input_port () const;
 
-    boost::shared_ptr<MidiPort> midi_clock_output_port () const;
-    boost::shared_ptr<MidiPort> midi_clock_input_port () const;
-    boost::shared_ptr<MidiPort> mtc_output_port () const;
-    boost::shared_ptr<MidiPort> mtc_input_port () const;
+       MIDI::Port* scene_input_port () const;
+       MIDI::Port* scene_output_port () const;
 
-    MIDI::MachineControl& mmc() { return *_mmc; }
+       boost::shared_ptr<MidiPort> scene_in () const;
+       boost::shared_ptr<MidiPort> scene_out () const;
+       
+       boost::shared_ptr<MidiPort> midi_clock_output_port () const;
+       boost::shared_ptr<MidiPort> midi_clock_input_port () const;
+       boost::shared_ptr<MidiPort> mtc_output_port () const;
+       boost::shared_ptr<MidiPort> mtc_input_port () const;
+    
+       MIDI::MachineControl& mmc() { return *_mmc; }
 
   protected:
        friend class AudioEngine;
        void set_block_size (pframes_t nframes);
        void set_frame_rate (framecnt_t nframes);
+        void reconnect_existing_routes (bool withLock, bool reconnect_master = true, bool reconnect_inputs = true, bool reconnect_outputs = true);
 
   protected:
        friend class Route;
@@ -916,6 +988,7 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        mutable gint             processing_prohibited;
        process_function_type    process_function;
        process_function_type    last_process_function;
+       bool                    _bounce_processing_active;
        bool                     waiting_for_sync_offset;
        framecnt_t              _base_frame_rate;
        framecnt_t              _current_frame_rate;  //this includes video pullup offset
@@ -943,8 +1016,6 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        framecnt_t              _worst_input_latency;
        framecnt_t              _worst_track_latency;
        bool                    _have_captured;
-       float                   _meter_hold;
-       float                   _meter_falloff;
        bool                    _non_soloed_outs_muted;
        uint32_t                _listen_cnt;
        uint32_t                _solo_isolated_cnt;
@@ -970,13 +1041,15 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        void process_without_events (pframes_t);
        void process_with_events    (pframes_t);
        void process_audition       (pframes_t);
-        int  process_export         (pframes_t);
+       int  process_export         (pframes_t);
        int  process_export_fw      (pframes_t);
 
        void block_processing() { g_atomic_int_set (&processing_prohibited, 1); }
        void unblock_processing() { g_atomic_int_set (&processing_prohibited, 0); }
        bool processing_blocked() const { return g_atomic_int_get (&processing_prohibited); }
 
+       static const framecnt_t bounce_chunk_size;
+
        /* slave tracking */
 
        static const int delta_accumulator_size = 25;
@@ -1075,7 +1148,11 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        bool             state_was_pending;
        StateOfTheState _state_of_the_state;
 
-       void     auto_save();
+       friend class    StateProtector;
+       gint            _suspend_save; /* atomic */
+       volatile bool   _save_queued;
+       Glib::Threads::Mutex save_state_lock;
+
        int      load_options (const XMLNode&);
        int      load_state (std::string snapshot_name);
 
@@ -1118,9 +1195,15 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        void reset_rf_scale (framecnt_t frames_moved);
 
        Locations*       _locations;
-       void              locations_changed ();
-       void              locations_added (Location*);
-       void              handle_locations_changed (Locations::LocationList&);
+       void              location_added (Location*);
+       void              location_removed (Location*);
+        void              locations_changed ();
+        void             _locations_changed (const Locations::LocationList&);
+
+        void              update_skips (Location*, bool consolidate);
+        Locations::LocationList consolidate_skips (Location*);
+       void              sync_locations_to_skips (const Locations::LocationList&);
+        PBD::ScopedConnectionList skip_connections;
 
        PBD::ScopedConnectionList punch_connections;
        void             auto_punch_start_changed (Location *);
@@ -1197,6 +1280,7 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
 
        MidiTimeoutList midi_timeouts;
        bool mmc_step_timeout ();
+       void send_immediate_mmc (MIDI::MachineControlCommand);
 
        MIDI::byte mtc_msg[16];
        MIDI::byte mtc_timecode_bits;   /* encoding of SMTPE type for MTC */
@@ -1259,7 +1343,7 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
 
        int           start_midi_thread ();
 
-       void set_play_loop (bool yn);
+       void set_play_loop (bool yn, double speed);
        void unset_play_loop ();
        void overwrite_some_buffers (Track *);
        void flush_all_inserts ();
@@ -1268,7 +1352,7 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        void start_locate (framepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
        void force_locate (framepos_t frame, bool with_roll = false);
        void set_track_speed (Track *, double speed);
-        void set_transport_speed (double speed, bool abort = false, bool clear_state = false, bool as_default = false);
+        void set_transport_speed (double speed, framepos_t destination_frame, bool abort = false, bool clear_state = false, bool as_default = false);
        void stop_transport (bool abort = false, bool clear_state = false);
        void start_transport ();
        void realtime_stop (bool abort, bool clear_state);
@@ -1322,6 +1406,11 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
                                 ChanCount input_start = ChanCount (), ChanCount output_start = ChanCount ());
        void midi_output_change_handler (IOChange change, void* /*src*/, boost::weak_ptr<Route> midi_track);
 
+       /* track numbering */
+
+       void reassign_track_numbers ();
+       uint32_t _track_number_decimals;
+
        /* mixer stuff */
 
        bool solo_update_disabled;
@@ -1354,10 +1443,9 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap;
 
   private:
+       void reset_write_sources (bool mark_write_complete, bool force = false);
        SourceMap sources;
 
-  public:
-       SourceMap get_sources() { return sources; }
 
   private:
        int load_sources (const XMLNode& node);
@@ -1437,7 +1525,7 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
 
        bool no_questions_about_missing_files;
 
-       std::string get_best_session_directory_for_new_source ();
+       std::string get_best_session_directory_for_new_audio ();
 
        mutable gint _playback_load;
        mutable gint _capture_load;
@@ -1579,7 +1667,7 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
        /** true if timecode transmission by the transport is suspended, otherwise false */
        mutable gint _suspend_timecode_transmission;
 
-       void update_locations_after_tempo_map_change (Locations::LocationList &);
+       void update_locations_after_tempo_map_change (const Locations::LocationList &);
 
        void start_time_changed (framepos_t);
        void end_time_changed (framepos_t);
@@ -1607,18 +1695,24 @@ class LIBARDOUR_API LIBARDOUR_API Session : public PBD::StatefulDestructible, pu
         void reconnect_ltc_input ();
         void reconnect_ltc_output ();
 
-    /* persistent, non-track related MIDI ports */
-    MidiPortManager* _midi_ports;
-    MIDI::MachineControl* _mmc;
-
-    void setup_ltc ();
-    void setup_click ();
-    void setup_click_state (const XMLNode*);
-    void setup_bundles ();
-
-    static int get_session_info_from_path (XMLTree& state_tree, const std::string& xmlpath);
+       /* Scene Changing */
+       SceneChanger* _scene_changer;
+       
+       /* persistent, non-track related MIDI ports */
+       MidiPortManager* _midi_ports;
+       MIDI::MachineControl* _mmc;
+       
+       void setup_ltc ();
+       void setup_click ();
+       void setup_click_state (const XMLNode*);
+       void setup_bundles ();
+       
+       void save_as_bring_callback (uint32_t, uint32_t, std::string);
+
+       static int get_session_info_from_path (XMLTree& state_tree, const std::string& xmlpath);
 };
 
+
 } // namespace ARDOUR
 
 #endif /* __ardour_session_h__ */