X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fsession.h;h=e327a9c1134fddd4a1875e84b9d40c97e8dde116;hb=c4a7d25b34aec71ab7d594af50f7b522518e0221;hp=f3594118469e5c66dc09aec65cda5de0caeb0311;hpb=52423fa8c3a460c5057b560121a84758f108a17c;p=ardour.git diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index f359411846..e327a9c113 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -36,6 +36,8 @@ #include +#include + #include "pbd/error.h" #include "pbd/event_loop.h" #include "pbd/rcu.h" @@ -64,9 +66,6 @@ #include #endif -#ifdef HAVE_LTC -#include -#endif class XMLTree; class XMLNode; @@ -112,6 +111,8 @@ class IOProcessor; class ImportStatus; class MidiClockTicker; class MidiControlUI; +class MidiPortManager; +class MidiPort; class MidiRegion; class MidiSource; class MidiTrack; @@ -128,6 +129,7 @@ class Route; class RouteGroup; class SMFSource; class Send; +class SceneChanger; class SessionDirectory; class SessionMetadata; class SessionPlaylists; @@ -140,7 +142,7 @@ class WindowsVSTPlugin; extern void setup_enum_writer (); -class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager +class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager { public: enum RecordState { @@ -161,6 +163,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi virtual ~Session (); + static int get_info_from_path (const std::string& xmlpath, float& sample_rate, SampleFormat& data_format); + std::string path() const { return _path; } std::string name() const { return _name; } std::string snap_name() const { return _current_snapshot_name; } @@ -191,18 +195,22 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi 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&); - RouteList new_route_from_template (uint32_t how_many, const std::string& template_path); + 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 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 callback); void process (pframes_t nframes); BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO); - BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO); + BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO, bool silence = true ); + BufferSet& get_route_buffers (ChanCount count = ChanCount::ZERO, bool silence = true); BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO); bool have_rec_enabled_track () const; @@ -222,8 +230,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi return routes.reader (); } + boost::shared_ptr get_tracks() const; boost::shared_ptr get_routes_with_internal_returns() const; - boost::shared_ptr get_routes_with_regions_at (framepos_t const) const; uint32_t nroutes() const { return routes.reader()->size(); } @@ -234,12 +242,13 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi return _bundles.reader (); } - struct RoutePublicOrderSorter { + struct LIBARDOUR_API RoutePublicOrderSorter { bool operator() (boost::shared_ptr, boost::shared_ptr b); }; + void set_order_hint (uint32_t order_hint) {_order_hint = order_hint;}; void notify_remote_id_change (); - void sync_order_keys (RouteSortOrderKey); + void sync_order_keys (); template void foreach_route (T *obj, void (T::*func)(Route&)); template void foreach_route (T *obj, void (T::*func)(boost::shared_ptr)); @@ -251,11 +260,15 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::shared_ptr route_by_id (PBD::ID); boost::shared_ptr route_by_remote_id (uint32_t id); boost::shared_ptr track_by_diskstream_id (PBD::ID); - void routes_using_input_from (const std::string& str, RouteList& rl); + void routes_using_input_from (const std::string& str, RouteList& rl); 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); } @@ -361,7 +374,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi return mtc_timecode_bits; /* encoding of SMTPE type for MTC */ } - float timecode_frames_per_second() const; + double timecode_frames_per_second() const; bool timecode_drop_frames() const; /* Locations */ @@ -382,9 +395,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi framecnt_t worst_track_latency () const { return _worst_track_latency; } framecnt_t worst_playback_latency () const { return _worst_output_latency + _worst_track_latency; } -#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); @@ -394,12 +404,16 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void rename_state (std::string old_name, std::string new_name); void remove_pending_capture_state (); int rename (const std::string&); + 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 StateSaved; PBD::Signal0 StateReady; + PBD::Signal0 SaveSession; - std::vector* possible_states() const; - static std::vector* possible_states (std::string path); + std::vector possible_states() const; + static std::vector possible_states (std::string path); XMLNode& get_state(); int set_state(const XMLNode& node, int version); // not idempotent @@ -421,6 +435,23 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi 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); @@ -474,8 +505,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* 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, @@ -499,7 +532,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void timecode_time_subframes (framepos_t when, Timecode::Time&); void timecode_duration (framecnt_t, Timecode::Time&) const; - void timecode_duration_string (char *, framecnt_t) const; + void timecode_duration_string (char *, size_t len, framecnt_t) const; framecnt_t convert_to_frames (AnyTime const & position); framecnt_t any_duration_to_frames (framepos_t position, AnyTime const & duration); @@ -508,7 +541,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi static PBD::Signal1 EndTimeChanged; void request_sync_source (Slave*); - bool synced_to_jack() const { return config.get_external_sync() && Config->get_sync_source() == JACK; } + bool synced_to_engine() const { return 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; } @@ -523,8 +556,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::shared_ptr find_whole_file_parent (boost::shared_ptr) const; - std::string path_from_region_name (DataType type, std::string name, std::string identifier); - boost::shared_ptr XMLRegionFactory (const XMLNode&, bool full); boost::shared_ptr XMLAudioRegionFactory (const XMLNode&, bool full); boost::shared_ptr XMLMidiRegionFactory (const XMLNode&, bool full); @@ -554,6 +585,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi int remove_last_capture (); + /** handlers should return 0 for "everything OK", and any other value for + * "cannot setup audioengine". + */ + static PBD::Signal1 AudioEngineSetupRequired; + /** handlers should return -1 for "stop cleanup", 0 for "yes, delete this playlist", 1 for "no, don't delete this playlist". @@ -572,11 +608,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::shared_ptr create_audio_source_for_session ( size_t, std::string const &, uint32_t, bool destructive); - boost::shared_ptr create_midi_source_for_session ( - Track*, std::string const &); + boost::shared_ptr create_midi_source_for_session (std::string const &); + boost::shared_ptr create_midi_source_by_stealing_name (boost::shared_ptr); boost::shared_ptr source_by_id (const PBD::ID&); - boost::shared_ptr source_by_path_and_channel (const std::string&, uint16_t); + boost::shared_ptr audio_source_by_path_and_channel (const std::string&, uint16_t) const; + boost::shared_ptr midi_source_by_path (const std::string&) const; uint32_t count_sources_by_origin (const std::string&); void add_playlist (boost::shared_ptr, bool unused = false); @@ -598,7 +635,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::shared_ptr write_one_track (AudioTrack&, framepos_t start, framepos_t end, bool overwrite, std::vector >&, InterThreadInfo& wot, - boost::shared_ptr endpoint, bool include_endpoint, bool for_export); + boost::shared_ptr endpoint, + bool include_endpoint, bool for_export, bool for_freeze); int freeze_all (InterThreadInfo&); /* session-wide solo/mute/rec-enable */ @@ -616,8 +654,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void set_listen (boost::shared_ptr, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false); void set_record_enabled (boost::shared_ptr, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false); void set_solo_isolated (boost::shared_ptr, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false); - void set_exclusive_input_active (boost::shared_ptr rt, bool others_on); void set_monitoring (boost::shared_ptr, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false); + void set_exclusive_input_active (boost::shared_ptr rt, bool onoff, bool flip_others=false); PBD::Signal1 SoloActive; PBD::Signal0 SoloChanged; @@ -732,8 +770,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* ranges */ void request_play_range (std::list*, 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); + /* buffers for gain and pan */ gain_t* gain_automation_buffer () const; @@ -744,6 +785,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* 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, @@ -775,6 +820,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi 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. @@ -809,7 +858,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::shared_ptr playlists; void send_mmc_locate (framepos_t); - int send_full_time_code (framepos_t); + void queue_full_time_code () { _send_timecode_update = true; } + void queue_song_position_pointer () { /* currently does nothing */ } bool step_editing() const { return (_step_editors > 0); } @@ -817,8 +867,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void request_resume_timecode_transmission (); bool timecode_transmission_suspended () const; - std::string source_search_path(DataType) const; + std::vector 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 unknown_processors () const; @@ -847,12 +898,37 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /** Emitted when the session wants Ardour to quit */ static PBD::Signal0 Quit; + /** Emitted when Ardour is asked to load a session in an older session + * format, and makes a backup copy. + */ + static PBD::Signal2 VersionMismatch; + + SceneChanger* scene_changer() const { return _scene_changer; } + boost::shared_ptr ltc_input_port() const; boost::shared_ptr ltc_output_port() const; boost::shared_ptr ltc_input_io() { return _ltc_input; } boost::shared_ptr 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* scene_input_port () const; + MIDI::Port* scene_output_port () const; + + boost::shared_ptr scene_in () const; + boost::shared_ptr scene_out () const; + + boost::shared_ptr midi_clock_output_port () const; + boost::shared_ptr midi_clock_input_port () const; + boost::shared_ptr mtc_output_port () const; + boost::shared_ptr mtc_input_port () const; + + MIDI::MachineControl& mmc() { return *_mmc; } + protected: friend class AudioEngine; void set_block_size (pframes_t nframes); @@ -886,6 +962,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi 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 @@ -897,8 +974,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi Slave* _slave; bool _silent; - void maybe_update_session_range (framepos_t, framepos_t); - // varispeed playback double _transport_speed; double _default_transport_speed; @@ -922,6 +997,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi uint32_t _solo_isolated_cnt; bool _writable; bool _was_seamless; + bool _under_nsm_control; void initialize_latencies (); void set_worst_io_latencies (); @@ -941,13 +1017,15 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void process_without_events (pframes_t); void process_with_events (pframes_t); void process_audition (pframes_t); - void 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; @@ -983,6 +1061,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi int pre_export (); int stop_audio_export (); void finalize_audio_export (); + void finalize_export_internal (bool stop_freewheel); bool _pre_export_mmc_enabled; PBD::ScopedConnection export_freewheel_connection; @@ -1036,7 +1115,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::scoped_ptr _session_dir; void hookup_io (); - void when_engine_running (); void graph_reordered (); /** current snapshot name, without the .ardour suffix */ @@ -1046,7 +1124,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi 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); @@ -1075,7 +1157,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi PostTransportClearSubstate); gint _post_transport_work; /* accessed only atomic ops */ - PostTransportWork post_transport_work() const { return (PostTransportWork) g_atomic_int_get (&_post_transport_work); } + PostTransportWork post_transport_work() const { return (PostTransportWork) g_atomic_int_get (const_cast(&_post_transport_work)); } void set_post_transport_work (PostTransportWork ptw) { g_atomic_int_set (&_post_transport_work, (gint) ptw); } void add_post_transport_work (PostTransportWork ptw); @@ -1102,8 +1184,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void auto_loop_changed (Location *); void auto_loop_declick_range (Location *, framepos_t &, framepos_t &); - void first_stage_init (std::string path, std::string snapshot_name); - int second_stage_init (); + int ensure_engine (uint32_t desired_sample_rate); + void pre_engine_init (std::string path); + int post_engine_init (); + int immediately_post_engine (); void remove_empty_sounds (); void setup_midi_control (); @@ -1170,7 +1254,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi MIDI::byte mtc_msg[16]; MIDI::byte mtc_timecode_bits; /* encoding of SMTPE type for MTC */ MIDI::byte midi_msg[16]; - framepos_t outbound_mtc_timecode_frame; + double outbound_mtc_timecode_frame; Timecode::Time transmitting_timecode_time; int next_quarter_frame_to_send; @@ -1188,7 +1272,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi int send_midi_time_code_for_cycle (framepos_t, framepos_t, pframes_t nframes); -#ifdef HAVE_LTC LTCEncoder* ltc_encoder; ltcsnd_sample_t* ltc_enc_buf; @@ -1201,16 +1284,21 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi framepos_t ltc_enc_pos; double ltc_enc_cnt; framepos_t ltc_enc_off; + bool restarting; + framepos_t ltc_prev_cycle; + + framepos_t ltc_timecode_offset; + bool ltc_timecode_negative_offset; - jack_latency_range_t ltc_out_latency; + LatencyRange ltc_out_latency; void ltc_tx_initialize(); void ltc_tx_cleanup(); void ltc_tx_reset(); void ltc_tx_resync_latency(); void ltc_tx_recalculate_position(); + void ltc_tx_parse_offset(); void ltc_tx_send_time_code_for_cycle (framepos_t, framepos_t, double, double, pframes_t nframes); -#endif void reset_record_status (); @@ -1224,7 +1312,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi 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 (); @@ -1247,6 +1335,13 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void engine_halted (); void xrun_recovery (); + /* These are synchronous and so can only be called from within the process + * cycle + */ + + int send_full_time_code (framepos_t, pframes_t nframes); + void send_song_position_pointer (framepos_t); + TempoMap *_tempo_map; void tempo_map_changed (const PBD::PropertyChange&); @@ -1264,6 +1359,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi SerializedRCUManager routes; void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save); + void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect); + bool _adding_routes_in_progress; uint32_t destructive_index; boost::shared_ptr XMLRouteFactory (const XMLNode&, int); @@ -1278,6 +1375,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi ChanCount input_start = ChanCount (), ChanCount output_start = ChanCount ()); void midi_output_change_handler (IOChange change, void* /*src*/, boost::weak_ptr midi_track); + /* track numbering */ + + void reassign_track_numbers (); + uint32_t _track_number_decimals; + /* mixer stuff */ bool solo_update_disabled; @@ -1312,9 +1414,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi private: SourceMap sources; - public: - SourceMap get_sources() { return sources; } - private: int load_sources (const XMLNode& node); XMLNode& get_sources_as_xml (); @@ -1393,7 +1492,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi 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; @@ -1413,9 +1512,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi */ std::list _current_trans_quarks; - void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int); - int jack_sync_callback (jack_transport_state_t, jack_position_t*); - void reset_jack_connection (jack_client_t* jack); + int backend_sync_callback (TransportState, framepos_t); + void process_rtop (SessionEvent*); void update_latency (bool playback); @@ -1474,13 +1572,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi float opt ); - /* number of hardware ports we're using, - based on max (requested,available) - */ - - ChanCount n_physical_outputs; - ChanCount n_physical_inputs; - int find_all_sources (std::string path, std::set& result); int find_all_sources_across_snapshots (std::set& result, bool exclude_this_snapshot); @@ -1560,6 +1651,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi GraphEdges _current_route_graph; uint32_t next_control_id () const; + uint32_t _order_hint; bool ignore_route_processor_changes; MidiClockTicker* midi_clock; @@ -1569,8 +1661,23 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void reconnect_ltc_input (); void reconnect_ltc_output (); + + /* 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 (); + + static int get_session_info_from_path (XMLTree& state_tree, const std::string& xmlpath); }; + } // namespace ARDOUR #endif /* __ardour_session_h__ */