#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;
std::string peak_path (std::string) const;
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);
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(); }
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);
}
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; }
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);
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
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*>);
/* 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,
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);
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<AudioFileSource> source_by_path_and_channel (const std::string&, uint16_t) const;
- boost::shared_ptr<MidiSource> source_by_path (const std::string&) const;
+ 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);
/* 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 */
/* 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);
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;
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;
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;
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);
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 *);
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 */
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);
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;
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 ();
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;
/** 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);
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__ */