delegate signal emission to dedicated thread.
[ardour.git] / libs / ardour / ardour / session.h
index 8d5e439129c6136595529c3aed7c8b0ad808ed5d..9d97bce69f88e09b83abd3bd49677459be2c2842 100644 (file)
@@ -193,7 +193,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        std::string peak_path (std::string) const;
 
        std::string peak_path_from_audio_path (std::string) const;
-       bool audio_source_name_is_unique (const std::string& name, uint32_t chan);
+       bool audio_source_name_is_unique (const std::string& name);
        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);
@@ -243,13 +243,13 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
                bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
        };
 
-       void set_order_hint (uint32_t order_hint) {_order_hint = order_hint;};
+       void set_order_hint (int32_t order_hint) {_order_hint = order_hint;};
        void notify_remote_id_change ();
        void sync_order_keys ();
 
-       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);
+       template<class T> void foreach_route (T *obj, void (T::*func)(Route&), bool sort = true);
+       template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>), bool sort = true);
+       template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg, bool sort = true);
 
        static char session_name_is_legal (const std::string&);
        bool io_name_is_legal (const std::string&);
@@ -392,7 +392,33 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        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);
@@ -401,7 +427,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        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 ();
@@ -553,13 +579,12 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        static PBD::Signal1<void, framepos_t> EndTimeChanged;
 
        void   request_sync_source (Slave*);
-       bool   synced_to_engine() const { return config.get_external_sync() && Config->get_sync_source() == Engine; }
+       bool   synced_to_engine() const { return _slave && config.get_external_sync() && Config->get_sync_source() == Engine; }
 
        double transport_speed() const { return _transport_speed; }
        bool   transport_stopped() const { return _transport_speed == 0.0f; }
        bool   transport_rolling() const { return _transport_speed != 0.0f; }
 
-       void set_silent (bool yn);
        bool silent () { return _silent; }
 
        TempoMap&       tempo_map()       { return *_tempo_map; }
@@ -677,6 +702,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        /* monitor/master out */
 
        void add_monitor_section ();
+       void reset_monitor_section ();
        void remove_monitor_section ();
 
        boost::shared_ptr<Route> monitor_out() const { return _monitor_out; }
@@ -716,12 +742,11 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
 
        /* I/O bundles */
 
-       void add_bundle (boost::shared_ptr<Bundle>);
+       void add_bundle (boost::shared_ptr<Bundle>, bool emit_signal = true);
        void remove_bundle (boost::shared_ptr<Bundle>);
        boost::shared_ptr<Bundle> bundle_by_name (std::string) const;
 
-       PBD::Signal1<void,boost::shared_ptr<Bundle> > BundleAdded;
-       PBD::Signal1<void,boost::shared_ptr<Bundle> > BundleRemoved;
+       PBD::Signal0<void> BundleAddedOrRemoved;
 
        void midi_panic ();
 
@@ -792,6 +817,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        /* buffers for gain and pan */
 
        gain_t* gain_automation_buffer () const;
+       gain_t* trim_automation_buffer () const;
        gain_t* send_gain_automation_buffer () const;
        pan_t** pan_automation_buffer () const;
 
@@ -993,6 +1019,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        double                  _transport_speed;
        double                  _default_transport_speed;
        double                  _last_transport_speed;
+       double                  _signalled_varispeed;
        double                  _target_transport_speed;
        CubicInterpolation       interpolation;
 
@@ -1196,6 +1223,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        void sync_locations_to_skips ();
        void _sync_locations_to_skips ();
     
+       PBD::ScopedConnectionList skip_update_connections;
        bool _ignore_skips_updates;
 
        PBD::ScopedConnectionList punch_connections;
@@ -1239,6 +1267,21 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
 
        void *do_work();
 
+       /* Signal Forwarding */
+       void emit_route_signals () const;
+       void emit_thread_run ();
+       static void *emit_thread (void *);
+       void emit_thread_start ();
+       void emit_thread_terminate ();
+
+       pthread_t       _rt_emit_thread;
+       bool            _rt_thread_active;
+
+       pthread_mutex_t _rt_emit_mutex;
+       pthread_cond_t  _rt_emit_cond;
+       bool            _rt_emit_pending;
+
+
        /* SessionEventManager interface */
 
        void process_event (SessionEvent*);
@@ -1437,8 +1480,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap;
 
   private:
+       void reset_write_sources (bool mark_write_complete, bool force = false);
        SourceMap sources;
 
+
   private:
        int load_sources (const XMLNode& node);
        XMLNode& get_sources_as_xml ();
@@ -1676,7 +1721,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        GraphEdges _current_route_graph;
 
        uint32_t next_control_id () const;
-       uint32_t _order_hint;
+       int32_t _order_hint;
        bool ignore_route_processor_changes;
 
        MidiClockTicker* midi_clock;
@@ -1699,6 +1744,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        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);
 };