2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
25 #define __STDC_FORMAT_MACROS 1
34 #include <cstdio> /* snprintf(3) ... grrr */
49 #include <sys/param.h>
50 #include <sys/mount.h>
54 #include <glibmm/thread.h>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
59 #include "pbd/boost_debug.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.h"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/buffer.h"
78 #include "ardour/butler.h"
79 #include "ardour/configuration.h"
80 #include "ardour/control_protocol_manager.h"
81 #include "ardour/crossfade.h"
82 #include "ardour/cycle_timer.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/io_processor.h"
86 #include "ardour/location.h"
87 #include "ardour/midi_diskstream.h"
88 #include "ardour/midi_patch_manager.h"
89 #include "ardour/midi_playlist.h"
90 #include "ardour/midi_region.h"
91 #include "ardour/midi_source.h"
92 #include "ardour/midi_track.h"
93 #include "ardour/named_selection.h"
94 #include "ardour/processor.h"
95 #include "ardour/region_factory.h"
96 #include "ardour/route_group.h"
97 #include "ardour/send.h"
98 #include "ardour/session.h"
99 #include "ardour/session_directory.h"
100 #include "ardour/session_metadata.h"
101 #include "ardour/session_state_utils.h"
102 #include "ardour/session_playlists.h"
103 #include "ardour/session_utils.h"
104 #include "ardour/silentfilesource.h"
105 #include "ardour/slave.h"
106 #include "ardour/smf_source.h"
107 #include "ardour/sndfile_helpers.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/template_utils.h"
111 #include "ardour/tempo.h"
112 #include "ardour/ticker.h"
113 #include "ardour/user_bundle.h"
114 #include "ardour/utils.h"
115 #include "ardour/utils.h"
116 #include "ardour/version.h"
117 #include "ardour/playlist_factory.h"
119 #include "control_protocol/control_protocol.h"
125 using namespace ARDOUR
;
129 Session::first_stage_init (string fullpath
, string snapshot_name
)
131 if (fullpath
.length() == 0) {
133 throw failed_constructor();
136 char buf
[PATH_MAX
+1];
137 if (!realpath (fullpath
.c_str(), buf
) && (errno
!= ENOENT
)) {
138 error
<< string_compose(_("Could not use path %1 (%s)"), buf
, strerror(errno
)) << endmsg
;
140 throw failed_constructor();
145 if (_path
[_path
.length()-1] != '/') {
149 if (Glib::file_test (_path
, Glib::FILE_TEST_EXISTS
) && ::access (_path
.c_str(), W_OK
)) {
155 /* these two are just provisional settings. set_state()
156 will likely override them.
159 _name
= _current_snapshot_name
= snapshot_name
;
161 set_history_depth (Config
->get_history_depth());
163 _current_frame_rate
= _engine
.frame_rate ();
164 _nominal_frame_rate
= _current_frame_rate
;
165 _base_frame_rate
= _current_frame_rate
;
167 _tempo_map
= new TempoMap (_current_frame_rate
);
168 _tempo_map
->PropertyChanged
.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed
, this, _1
));
171 _non_soloed_outs_muted
= false;
173 g_atomic_int_set (&processing_prohibited
, 0);
174 _transport_speed
= 0;
175 _last_transport_speed
= 0;
176 _target_transport_speed
= 0;
177 auto_play_legal
= false;
178 transport_sub_state
= 0;
179 _transport_frame
= 0;
180 _requested_return_frame
= -1;
181 end_location
= new Location (0, 0, _("end"), Location::Flags ((Location::IsMark
|Location::IsEnd
)));
182 start_location
= new Location (0, 0, _("start"), Location::Flags ((Location::IsMark
|Location::IsStart
)));
183 g_atomic_int_set (&_record_status
, Disabled
);
184 loop_changing
= false;
187 _last_roll_location
= 0;
188 _last_record_location
= 0;
189 pending_locate_frame
= 0;
190 pending_locate_roll
= false;
191 pending_locate_flush
= false;
192 state_was_pending
= false;
194 outbound_mtc_timecode_frame
= 0;
195 next_quarter_frame_to_send
= -1;
196 current_block_size
= 0;
197 solo_update_disabled
= false;
198 _have_captured
= false;
199 _worst_output_latency
= 0;
200 _worst_input_latency
= 0;
201 _worst_track_latency
= 0;
202 _state_of_the_state
= StateOfTheState(CannotSave
|InitialConnecting
|Loading
);
203 _was_seamless
= Config
->get_seamless_loop ();
205 session_send_mmc
= false;
206 session_send_mtc
= false;
207 g_atomic_int_set (&_playback_load
, 100);
208 g_atomic_int_set (&_capture_load
, 100);
209 g_atomic_int_set (&_playback_load_min
, 100);
210 g_atomic_int_set (&_capture_load_min
, 100);
213 _gain_automation_buffer
= 0;
214 _pan_automation_buffer
= 0;
216 pending_abort
= false;
217 destructive_index
= 0;
218 first_file_data_format_reset
= true;
219 first_file_header_format_reset
= true;
220 post_export_sync
= false;
223 AudioDiskstream::allocate_working_buffers();
225 /* default short fade = 15ms */
227 Crossfade::set_short_xfade_length ((nframes_t
) floor (config
.get_short_xfade_seconds() * frame_rate()));
228 SndFileSource::setup_standard_crossfades (*this, frame_rate());
230 last_mmc_step
.tv_sec
= 0;
231 last_mmc_step
.tv_usec
= 0;
234 /* click sounds are unset by default, which causes us to internal
235 waveforms for clicks.
239 click_emphasis_length
= 0;
242 process_function
= &Session::process_with_events
;
244 if (config
.get_use_video_sync()) {
245 waiting_for_sync_offset
= true;
247 waiting_for_sync_offset
= false;
250 last_timecode_when
= 0;
251 _timecode_offset
= 0;
252 _timecode_offset_negative
= true;
253 last_timecode_valid
= false;
257 last_rr_session_dir
= session_dirs
.begin();
258 refresh_disk_space ();
260 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
264 average_slave_delta
= 1800; // !!! why 1800 ????
265 have_first_delta_accumulator
= false;
266 delta_accumulator_cnt
= 0;
267 _slave_state
= Stopped
;
269 _engine
.GraphReordered
.connect_same_thread (*this, boost::bind (&Session::graph_reordered
, this));
271 /* These are all static "per-class" signals */
273 RegionFactory::CheckNewRegion
.connect_same_thread (*this, boost::bind (&Session::add_region
, this, _1
));
274 SourceFactory::SourceCreated
.connect_same_thread (*this, boost::bind (&Session::add_source
, this, _1
));
275 PlaylistFactory::PlaylistCreated
.connect_same_thread (*this, boost::bind (&Session::add_playlist
, this, _1
, _2
));
276 Processor::ProcessorCreated
.connect_same_thread (*this, boost::bind (&Session::add_processor
, this, _1
));
277 AutomationList::AutomationListCreated
.connect_same_thread (*this, boost::bind (&Session::add_automation_list
, this, _1
));
278 Controllable::Destroyed
.connect_same_thread (*this, boost::bind (&Session::remove_controllable
, this, _1
));
279 IO::PortCountChanged
.connect_same_thread (*this, boost::bind (&Session::ensure_buffers
, this, _1
));
281 /* stop IO objects from doing stuff until we're ready for them */
283 Delivery::disable_panners ();
284 IO::disable_connecting ();
288 Session::second_stage_init ()
290 AudioFileSource::set_peak_dir (_session_dir
->peak_path().to_string());
293 if (load_state (_current_snapshot_name
)) {
296 remove_empty_sounds ();
299 if (_butler
->start_thread()) {
303 if (start_midi_thread ()) {
307 // set_state() will call setup_raid_path(), but if it's a new session we need
308 // to call setup_raid_path() here.
311 if (set_state (*state_tree
->root(), Stateful::loading_state_version
)) {
315 setup_raid_path(_path
);
318 /* we can't save till after ::when_engine_running() is called,
319 because otherwise we save state with no connections made.
320 therefore, we reset _state_of_the_state because ::set_state()
321 will have cleared it.
323 we also have to include Loading so that any events that get
324 generated between here and the end of ::when_engine_running()
325 will be processed directly rather than queued.
328 _state_of_the_state
= StateOfTheState (_state_of_the_state
|CannotSave
|Loading
);
331 _locations
.changed
.connect_same_thread (*this, boost::bind (&Session::locations_changed
, this));
332 _locations
.added
.connect_same_thread (*this, boost::bind (&Session::locations_added
, this, _1
));
333 setup_click_sounds (0);
334 setup_midi_control ();
336 /* Pay attention ... */
338 _engine
.Halted
.connect_same_thread (*this, boost::bind (&Session::engine_halted
, this));
339 _engine
.Xrun
.connect_same_thread (*this, boost::bind (&Session::xrun_recovery
, this));
342 when_engine_running ();
345 /* handle this one in a different way than all others, so that its clear what happened */
347 catch (AudioEngine::PortRegistrationFailure
& err
) {
348 error
<< err
.what() << endmsg
;
356 BootMessage (_("Reset Remote Controls"));
358 send_full_time_code (0);
359 _engine
.transport_locate (0);
360 deliver_mmc (MIDI::MachineControl::cmdMmcReset
, 0);
361 deliver_mmc (MIDI::MachineControl::cmdLocate
, 0);
363 MidiClockTicker::instance().set_session (this);
364 MIDI::Name::MidiPatchManager::instance().set_session (this);
366 /* initial program change will be delivered later; see ::config_changed() */
368 BootMessage (_("Reset Control Protocols"));
370 ControlProtocolManager::instance().set_session (this);
372 config
.set_end_marker_is_free (_is_new
);
374 _state_of_the_state
= Clean
;
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending
) {
379 save_state (_current_snapshot_name
);
380 remove_pending_capture_state ();
381 state_was_pending
= false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path
;
394 for (vector
<space_and_path
>::const_iterator i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
395 raid_search_path
+= sys::path((*i
).path
);
398 return raid_search_path
.to_string ();
402 Session::setup_raid_path (string path
)
411 session_dirs
.clear ();
413 SearchPath
search_path(path
);
414 SearchPath sound_search_path
;
415 SearchPath midi_search_path
;
417 for (SearchPath::const_iterator i
= search_path
.begin(); i
!= search_path
.end(); ++i
) {
418 sp
.path
= (*i
).to_string ();
419 sp
.blocks
= 0; // not needed
420 session_dirs
.push_back (sp
);
422 SessionDirectory
sdir(sp
.path
);
424 sound_search_path
+= sdir
.sound_path ();
425 midi_search_path
+= sdir
.midi_path ();
428 // set the search path for each data type
429 FileSource::set_search_path (DataType::AUDIO
, sound_search_path
.to_string ());
430 SMFSource::set_search_path (DataType::MIDI
, midi_search_path
.to_string ());
432 // reset the round-robin soundfile path thingie
433 last_rr_session_dir
= session_dirs
.begin();
437 Session::path_is_within_session (const std::string
& path
)
439 for (vector
<space_and_path
>::const_iterator i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
440 if (path
.find ((*i
).path
) == 0) {
448 Session::ensure_subdirs ()
452 dir
= session_directory().peak_path().to_string();
454 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
455 error
<< string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
459 dir
= session_directory().sound_path().to_string();
461 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
462 error
<< string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
466 dir
= session_directory().midi_path().to_string();
468 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
469 error
<< string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
473 dir
= session_directory().dead_sound_path().to_string();
475 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
476 error
<< string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
480 dir
= session_directory().export_path().to_string();
482 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
483 error
<< string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
487 dir
= analysis_dir ();
489 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
490 error
<< string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
498 Session::create (const string
& mix_template
, nframes_t initial_length
, BusProfile
* bus_profile
)
501 if (g_mkdir_with_parents (_path
.c_str(), 0755) < 0) {
502 error
<< string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path
, strerror (errno
)) << endmsg
;
506 if (ensure_subdirs ()) {
510 if (!mix_template
.empty()) {
511 std::string in_path
= mix_template
;
513 ifstream
in(in_path
.c_str());
516 string out_path
= _path
;
518 out_path
+= statefile_suffix
;
520 ofstream
out(out_path
.c_str());
527 error
<< string_compose (_("Could not open %1 for writing mix template"), out_path
)
533 error
<< string_compose (_("Could not open mix template %1 for reading"), in_path
)
540 /* Instantiate metadata */
542 _metadata
= new SessionMetadata ();
544 /* set initial start + end point */
546 start_location
->set_end (0);
547 _locations
.add (start_location
);
549 end_location
->set_end (initial_length
);
550 _locations
.add (end_location
);
552 _state_of_the_state
= Clean
;
554 /* set up Master Out and Control Out if necessary */
560 ChanCount
count(DataType::AUDIO
, bus_profile
->master_out_channels
);
562 if (bus_profile
->master_out_channels
) {
563 Route
* rt
= new Route (*this, _("master"), Route::MasterOut
, DataType::AUDIO
);
568 boost_debug_shared_ptr_mark_interesting (rt
, "Route");
569 boost::shared_ptr
<Route
> r (rt
);
570 r
->input()->ensure_io (count
, false, this);
571 r
->output()->ensure_io (count
, false, this);
572 r
->set_remote_control_id (control_id
++);
576 if (Config
->get_use_monitor_bus()) {
577 Route
* rt
= new Route (*this, _("monitor"), Route::MonitorOut
, DataType::AUDIO
);
582 boost_debug_shared_ptr_mark_interesting (rt
, "Route");
583 boost::shared_ptr
<Route
> r (rt
);
584 r
->input()->ensure_io (count
, false, this);
585 r
->output()->ensure_io (count
, false, this);
586 r
->set_remote_control_id (control_id
);
592 /* prohibit auto-connect to master, because there isn't one */
593 bus_profile
->output_ac
= AutoConnectOption (bus_profile
->output_ac
& ~AutoConnectMaster
);
597 add_routes (rl
, false);
600 /* this allows the user to override settings with an environment variable.
603 if (no_auto_connect()) {
604 bus_profile
->input_ac
= AutoConnectOption (0);
605 bus_profile
->output_ac
= AutoConnectOption (0);
608 Config
->set_input_auto_connect (bus_profile
->input_ac
);
609 Config
->set_output_auto_connect (bus_profile
->output_ac
);
619 Session::load_diskstreams (const XMLNode
& node
)
622 XMLNodeConstIterator citer
;
624 clist
= node
.children();
626 for (citer
= clist
.begin(); citer
!= clist
.end(); ++citer
) {
629 /* diskstreams added automatically by DiskstreamCreated handler */
630 if ((*citer
)->name() == "AudioDiskstream" || (*citer
)->name() == "DiskStream") {
631 AudioDiskstream
* dsp (new AudioDiskstream (*this, **citer
));
632 boost::shared_ptr
<AudioDiskstream
> dstream (dsp
);
633 add_diskstream (dstream
);
634 } else if ((*citer
)->name() == "MidiDiskstream") {
635 boost::shared_ptr
<MidiDiskstream
> dstream (new MidiDiskstream (*this, **citer
));
636 add_diskstream (dstream
);
638 error
<< _("Session: unknown diskstream type in XML") << endmsg
;
642 catch (failed_constructor
& err
) {
643 error
<< _("Session: could not load diskstream via XML state") << endmsg
;
652 Session::maybe_write_autosave()
654 if (dirty() && record_status() != Recording
) {
655 save_state("", true);
660 Session::remove_pending_capture_state ()
662 sys::path
pending_state_file_path(_session_dir
->root_path());
664 pending_state_file_path
/= legalize_for_path (_current_snapshot_name
) + pending_suffix
;
668 sys::remove (pending_state_file_path
);
670 catch(sys::filesystem_error
& ex
)
672 error
<< string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
673 pending_state_file_path
.to_string(), ex
.what()) << endmsg
;
677 /** Rename a state file.
678 * @param snapshot_name Snapshot name.
681 Session::rename_state (string old_name
, string new_name
)
683 if (old_name
== _current_snapshot_name
|| old_name
== _name
) {
684 /* refuse to rename the current snapshot or the "main" one */
688 const string old_xml_filename
= legalize_for_path (old_name
) + statefile_suffix
;
689 const string new_xml_filename
= legalize_for_path (new_name
) + statefile_suffix
;
691 const sys::path old_xml_path
= _session_dir
->root_path() / old_xml_filename
;
692 const sys::path new_xml_path
= _session_dir
->root_path() / new_xml_filename
;
696 sys::rename (old_xml_path
, new_xml_path
);
698 catch (const sys::filesystem_error
& err
)
700 error
<< string_compose(_("could not rename snapshot %1 to %2 (%3)"),
701 old_name
, new_name
, err
.what()) << endmsg
;
705 /** Remove a state file.
706 * @param snapshot_name Snapshot name.
709 Session::remove_state (string snapshot_name
)
711 if (snapshot_name
== _current_snapshot_name
|| snapshot_name
== _name
) {
712 // refuse to remove the current snapshot or the "main" one
716 sys::path
xml_path(_session_dir
->root_path());
718 xml_path
/= legalize_for_path (snapshot_name
) + statefile_suffix
;
720 if (!create_backup_file (xml_path
)) {
721 // don't remove it if a backup can't be made
722 // create_backup_file will log the error.
727 sys::remove (xml_path
);
731 Session::save_state (string snapshot_name
, bool pending
)
734 sys::path
xml_path(_session_dir
->root_path());
736 if (!_writable
|| (_state_of_the_state
& CannotSave
)) {
740 if (!_engine
.connected ()) {
741 error
<< string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
747 /* tell sources we're saving first, in case they write out to a new file
748 * which should be saved with the state rather than the old one */
749 for (SourceMap::const_iterator i
= sources
.begin(); i
!= sources
.end(); ++i
)
750 i
->second
->session_saved();
752 tree
.set_root (&get_state());
754 if (snapshot_name
.empty()) {
755 snapshot_name
= _current_snapshot_name
;
760 /* proper save: use statefile_suffix (.ardour in English) */
762 xml_path
/= legalize_for_path (snapshot_name
) + statefile_suffix
;
764 /* make a backup copy of the old file */
766 if (sys::exists(xml_path
) && !create_backup_file (xml_path
)) {
767 // create_backup_file will log the error
773 /* pending save: use pending_suffix (.pending in English) */
774 xml_path
/= legalize_for_path (snapshot_name
) + pending_suffix
;
777 sys::path
tmp_path(_session_dir
->root_path());
779 tmp_path
/= legalize_for_path (snapshot_name
) + temp_suffix
;
781 // cerr << "actually writing state to " << xml_path.to_string() << endl;
783 if (!tree
.write (tmp_path
.to_string())) {
784 error
<< string_compose (_("state could not be saved to %1"), tmp_path
.to_string()) << endmsg
;
785 sys::remove (tmp_path
);
790 if (rename (tmp_path
.to_string().c_str(), xml_path
.to_string().c_str()) != 0) {
791 error
<< string_compose (_("could not rename temporary session file %1 to %2"),
792 tmp_path
.to_string(), xml_path
.to_string()) << endmsg
;
793 sys::remove (tmp_path
);
800 save_history (snapshot_name
);
802 bool was_dirty
= dirty();
804 _state_of_the_state
= StateOfTheState (_state_of_the_state
& ~Dirty
);
807 DirtyChanged (); /* EMIT SIGNAL */
810 StateSaved (snapshot_name
); /* EMIT SIGNAL */
817 Session::restore_state (string snapshot_name
)
819 if (load_state (snapshot_name
) == 0) {
820 set_state (*state_tree
->root(), Stateful::loading_state_version
);
827 Session::load_state (string snapshot_name
)
832 state_was_pending
= false;
834 /* check for leftover pending state from a crashed capture attempt */
836 sys::path
xmlpath(_session_dir
->root_path());
837 xmlpath
/= legalize_for_path (snapshot_name
) + pending_suffix
;
839 if (sys::exists (xmlpath
)) {
841 /* there is pending state from a crashed capture attempt */
843 if (*AskAboutPendingState()) {
844 state_was_pending
= true;
848 if (!state_was_pending
) {
849 xmlpath
= _session_dir
->root_path();
850 xmlpath
/= legalize_for_path (snapshot_name
) + statefile_suffix
;
853 if (!sys::exists (xmlpath
)) {
854 error
<< string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name
, xmlpath
.to_string()) << endmsg
;
858 state_tree
= new XMLTree
;
862 /* writable() really reflects the whole folder, but if for any
863 reason the session state file can't be written to, still
867 if (::access (xmlpath
.to_string().c_str(), W_OK
) != 0) {
871 if (!state_tree
->read (xmlpath
.to_string())) {
872 error
<< string_compose(_("Could not understand ardour file %1"), xmlpath
.to_string()) << endmsg
;
878 XMLNode
& root (*state_tree
->root());
880 if (root
.name() != X_("Session")) {
881 error
<< string_compose (_("Session file %1 is not a session"), xmlpath
.to_string()) << endmsg
;
887 const XMLProperty
* prop
;
889 if ((prop
= root
.property ("version")) == 0) {
890 /* no version implies very old version of Ardour */
891 Stateful::loading_state_version
= 1000;
897 sscanf (prop
->value().c_str(), "%d.%d.%d", &major
, &minor
, µ
);
898 Stateful::loading_state_version
= (major
* 1000) + minor
;
901 if (Stateful::loading_state_version
< CURRENT_SESSION_FILE_VERSION
) {
903 sys::path
backup_path(_session_dir
->root_path());
905 backup_path
/= legalize_for_path (snapshot_name
) + "-1" + statefile_suffix
;
907 // only create a backup once
908 if (sys::exists (backup_path
)) {
912 info
<< string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
913 xmlpath
.to_string(), backup_path
.to_string(), PROGRAM_NAME
)
918 sys::copy_file (xmlpath
, backup_path
);
920 catch(sys::filesystem_error
& ex
)
922 error
<< string_compose (_("Unable to make backup of state file %1 (%2)"),
923 xmlpath
.to_string(), ex
.what())
933 Session::load_options (const XMLNode
& node
)
935 LocaleGuard
lg (X_("POSIX"));
936 config
.set_variables (node
);
947 Session::get_template()
949 /* if we don't disable rec-enable, diskstreams
950 will believe they need to store their capture
951 sources in their state node.
954 disable_record (false);
960 Session::state(bool full_state
)
962 XMLNode
* node
= new XMLNode("Session");
965 // store libardour version, just in case
967 snprintf(buf
, sizeof(buf
), "%d.%d.%d", libardour3_major_version
, libardour3_minor_version
, libardour3_micro_version
);
968 node
->add_property("version", string(buf
));
970 /* store configuration settings */
974 node
->add_property ("name", _name
);
975 snprintf (buf
, sizeof (buf
), "%" PRId32
, _nominal_frame_rate
);
976 node
->add_property ("sample-rate", buf
);
978 if (session_dirs
.size() > 1) {
982 vector
<space_and_path
>::iterator i
= session_dirs
.begin();
983 vector
<space_and_path
>::iterator next
;
985 ++i
; /* skip the first one */
989 while (i
!= session_dirs
.end()) {
993 if (next
!= session_dirs
.end()) {
1003 child
= node
->add_child ("Path");
1004 child
->add_content (p
);
1008 /* save the ID counter */
1010 snprintf (buf
, sizeof (buf
), "%" PRIu64
, ID::counter());
1011 node
->add_property ("id-counter", buf
);
1013 /* various options */
1015 node
->add_child_nocopy (config
.get_variables ());
1017 node
->add_child_nocopy (_metadata
->get_state());
1019 child
= node
->add_child ("Sources");
1022 Glib::Mutex::Lock
sl (source_lock
);
1024 for (SourceMap::iterator siter
= sources
.begin(); siter
!= sources
.end(); ++siter
) {
1026 /* Don't save information about non-destructive file sources that are empty */
1027 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1029 boost::shared_ptr
<AudioFileSource
> fs
;
1030 if ((fs
= boost::dynamic_pointer_cast
<AudioFileSource
> (siter
->second
)) != 0) {
1031 if (!fs
->destructive()) {
1032 if (fs
->length(fs
->timeline_position()) == 0) {
1038 child
->add_child_nocopy (siter
->second
->get_state());
1042 child
= node
->add_child ("Regions");
1045 Glib::Mutex::Lock
rl (region_lock
);
1046 const RegionFactory::RegionMap
& region_map (RegionFactory::all_regions());
1047 for (RegionFactory::RegionMap::const_iterator i
= region_map
.begin(); i
!= region_map
.end(); ++i
) {
1048 boost::shared_ptr
<Region
> r
= i
->second
;
1049 /* only store regions not attached to playlists */
1050 if (r
->playlist() == 0) {
1051 child
->add_child_nocopy (r
->state (true));
1056 child
= node
->add_child ("DiskStreams");
1059 boost::shared_ptr
<DiskstreamList
> dsl
= diskstreams
.reader();
1060 for (DiskstreamList::iterator i
= dsl
->begin(); i
!= dsl
->end(); ++i
) {
1061 if (!(*i
)->hidden()) {
1062 child
->add_child_nocopy ((*i
)->get_state());
1068 node
->add_child_nocopy (_locations
.get_state());
1070 // for a template, just create a new Locations, populate it
1071 // with the default start and end, and get the state for that.
1073 Location
* start
= new Location(0, 0, _("start"), Location::Flags ((Location::IsMark
|Location::IsStart
)));
1074 Location
* end
= new Location(0, 0, _("end"), Location::Flags ((Location::IsMark
|Location::IsEnd
)));
1077 end
->set_end(compute_initial_length());
1079 node
->add_child_nocopy (loc
.get_state());
1082 child
= node
->add_child ("Bundles");
1084 boost::shared_ptr
<BundleList
> bundles
= _bundles
.reader ();
1085 for (BundleList::iterator i
= bundles
->begin(); i
!= bundles
->end(); ++i
) {
1086 boost::shared_ptr
<UserBundle
> b
= boost::dynamic_pointer_cast
<UserBundle
> (*i
);
1088 child
->add_child_nocopy (b
->get_state());
1093 child
= node
->add_child ("Routes");
1095 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
1097 RoutePublicOrderSorter cmp
;
1098 RouteList
public_order (*r
);
1099 public_order
.sort (cmp
);
1101 /* the sort should have put control outs first */
1104 assert (_monitor_out
== public_order
.front());
1107 for (RouteList::iterator i
= public_order
.begin(); i
!= public_order
.end(); ++i
) {
1108 if (!(*i
)->is_hidden()) {
1110 child
->add_child_nocopy ((*i
)->get_state());
1112 child
->add_child_nocopy ((*i
)->get_template());
1118 playlists
->add_state (node
, full_state
);
1120 child
= node
->add_child ("RouteGroups");
1121 for (list
<RouteGroup
*>::iterator i
= _route_groups
.begin(); i
!= _route_groups
.end(); ++i
) {
1122 child
->add_child_nocopy ((*i
)->get_state());
1126 child
= node
->add_child ("Click");
1127 child
->add_child_nocopy (_click_io
->state (full_state
));
1131 child
= node
->add_child ("NamedSelections");
1132 for (NamedSelectionList::iterator i
= named_selections
.begin(); i
!= named_selections
.end(); ++i
) {
1134 child
->add_child_nocopy ((*i
)->get_state());
1139 node
->add_child_nocopy (_tempo_map
->get_state());
1141 node
->add_child_nocopy (get_control_protocol_state());
1144 node
->add_child_copy (*_extra_xml
);
1151 Session::get_control_protocol_state ()
1153 ControlProtocolManager
& cpm (ControlProtocolManager::instance());
1154 return cpm
.get_state();
1158 Session::set_state (const XMLNode
& node
, int version
)
1162 const XMLProperty
* prop
;
1165 _state_of_the_state
= StateOfTheState (_state_of_the_state
|CannotSave
);
1167 if (node
.name() != X_("Session")){
1168 fatal
<< _("programming error: Session: incorrect XML node sent to set_state()") << endmsg
;
1172 if ((prop
= node
.property ("version")) != 0) {
1173 version
= atoi (prop
->value ()) * 1000;
1176 if ((prop
= node
.property ("name")) != 0) {
1177 _name
= prop
->value ();
1180 if ((prop
= node
.property (X_("sample-rate"))) != 0) {
1182 _nominal_frame_rate
= atoi (prop
->value());
1184 if (_nominal_frame_rate
!= _current_frame_rate
) {
1185 if (*AskAboutSampleRateMismatch (_nominal_frame_rate
, _current_frame_rate
)) {
1191 setup_raid_path(_session_dir
->root_path().to_string());
1193 if ((prop
= node
.property (X_("id-counter"))) != 0) {
1195 sscanf (prop
->value().c_str(), "%" PRIu64
, &x
);
1196 ID::init_counter (x
);
1198 /* old sessions used a timebased counter, so fake
1199 the startup ID counter based on a standard
1204 ID::init_counter (now
);
1208 IO::disable_connecting ();
1210 /* Object loading order:
1215 MIDI Control // relies on data from Options/Config
1229 if ((child
= find_named_node (node
, "Extra")) != 0) {
1230 _extra_xml
= new XMLNode (*child
);
1233 if (((child
= find_named_node (node
, "Options")) != 0)) { /* old style */
1234 load_options (*child
);
1235 } else if ((child
= find_named_node (node
, "Config")) != 0) { /* new style */
1236 load_options (*child
);
1238 error
<< _("Session: XML state has no options section") << endmsg
;
1241 if (use_config_midi_ports ()) {
1244 if (version
>= 3000) {
1245 if ((child
= find_named_node (node
, "Metadata")) == 0) {
1246 warning
<< _("Session: XML state has no metadata section") << endmsg
;
1247 } else if (_metadata
->set_state (*child
, version
)) {
1252 if ((child
= find_named_node (node
, "Locations")) == 0) {
1253 error
<< _("Session: XML state has no locations section") << endmsg
;
1255 } else if (_locations
.set_state (*child
, version
)) {
1261 if ((location
= _locations
.auto_loop_location()) != 0) {
1262 set_auto_loop_location (location
);
1265 if ((location
= _locations
.auto_punch_location()) != 0) {
1266 set_auto_punch_location (location
);
1269 if ((location
= _locations
.end_location()) == 0) {
1270 _locations
.add (end_location
);
1272 delete end_location
;
1273 end_location
= location
;
1276 if ((location
= _locations
.start_location()) == 0) {
1277 _locations
.add (start_location
);
1279 delete start_location
;
1280 start_location
= location
;
1283 AudioFileSource::set_header_position_offset (start_location
->start());
1285 if ((child
= find_named_node (node
, "Sources")) == 0) {
1286 error
<< _("Session: XML state has no sources section") << endmsg
;
1288 } else if (load_sources (*child
)) {
1292 if ((child
= find_named_node (node
, "Regions")) == 0) {
1293 error
<< _("Session: XML state has no Regions section") << endmsg
;
1295 } else if (load_regions (*child
)) {
1299 if ((child
= find_named_node (node
, "Playlists")) == 0) {
1300 error
<< _("Session: XML state has no playlists section") << endmsg
;
1302 } else if (playlists
->load (*this, *child
)) {
1306 if ((child
= find_named_node (node
, "UnusedPlaylists")) == 0) {
1308 } else if (playlists
->load_unused (*this, *child
)) {
1312 if ((child
= find_named_node (node
, "NamedSelections")) != 0) {
1313 if (load_named_selections (*child
)) {
1318 if ((child
= find_named_node (node
, "DiskStreams")) == 0) {
1319 error
<< _("Session: XML state has no diskstreams section") << endmsg
;
1321 } else if (load_diskstreams (*child
)) {
1325 if (version
>= 3000) {
1326 if ((child
= find_named_node (node
, "Bundles")) == 0) {
1327 warning
<< _("Session: XML state has no bundles section") << endmsg
;
1330 /* We can't load Bundles yet as they need to be able
1331 to convert from port names to Port objects, which can't happen until
1333 _bundle_xml_node
= new XMLNode (*child
);
1337 if ((child
= find_named_node (node
, "TempoMap")) == 0) {
1338 error
<< _("Session: XML state has no Tempo Map section") << endmsg
;
1340 } else if (_tempo_map
->set_state (*child
, version
)) {
1344 if ((child
= find_named_node (node
, "Routes")) == 0) {
1345 error
<< _("Session: XML state has no routes section") << endmsg
;
1347 } else if (load_routes (*child
, version
)) {
1351 if (version
>= 3000) {
1353 if ((child
= find_named_node (node
, "RouteGroups")) == 0) {
1354 error
<< _("Session: XML state has no route groups section") << endmsg
;
1356 } else if (load_route_groups (*child
, version
)) {
1360 } else if (version
< 3000) {
1362 if ((child
= find_named_node (node
, "EditGroups")) == 0) {
1363 error
<< _("Session: XML state has no edit groups section") << endmsg
;
1365 } else if (load_route_groups (*child
, version
)) {
1369 if ((child
= find_named_node (node
, "MixGroups")) == 0) {
1370 error
<< _("Session: XML state has no mix groups section") << endmsg
;
1372 } else if (load_route_groups (*child
, version
)) {
1377 if ((child
= find_named_node (node
, "Click")) == 0) {
1378 warning
<< _("Session: XML state has no click section") << endmsg
;
1379 } else if (_click_io
) {
1380 _click_io
->set_state (*child
, version
);
1383 if ((child
= find_named_node (node
, "ControlProtocols")) != 0) {
1384 ControlProtocolManager::instance().set_protocol_states (*child
);
1387 /* here beginneth the second phase ... */
1389 StateReady (); /* EMIT SIGNAL */
1398 Session::load_routes (const XMLNode
& node
, int version
)
1401 XMLNodeConstIterator niter
;
1402 RouteList new_routes
;
1404 nlist
= node
.children();
1408 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
1410 boost::shared_ptr
<Route
> route (XMLRouteFactory (**niter
, version
));
1413 error
<< _("Session: cannot create Route from XML description.") << endmsg
;
1417 BootMessage (string_compose (_("Loaded track/bus %1"), route
->name()));
1419 new_routes
.push_back (route
);
1422 add_routes (new_routes
, false);
1427 boost::shared_ptr
<Route
>
1428 Session::XMLRouteFactory (const XMLNode
& node
, int version
)
1430 boost::shared_ptr
<Route
> ret
;
1432 if (node
.name() != "Route") {
1436 const XMLProperty
* dsprop
;
1438 if ((dsprop
= node
.property (X_("diskstream-id"))) == 0) {
1439 dsprop
= node
.property (X_("diskstream"));
1442 DataType type
= DataType::AUDIO
;
1443 const XMLProperty
* prop
= node
.property("default-type");
1446 type
= DataType (prop
->value());
1449 assert (type
!= DataType::NIL
);
1453 boost::shared_ptr
<Diskstream
> ds
;
1454 PBD::ID
diskstream_id (dsprop
->value());
1457 /* this wierd hack is used when creating
1458 tracks from a template. We have a special
1459 ID for the diskstream that means "you
1460 should create a new diskstream here, not
1461 look for an old one."
1464 if (diskstream_id
!= zero
) {
1466 ds
= diskstream_by_id (diskstream_id
);
1469 error
<< string_compose (_("cannot find diskstream ID %1"), diskstream_id
.to_s()) << endmsg
;
1476 if (type
== DataType::AUDIO
) {
1477 track
= new AudioTrack (*this, X_("toBeResetFroXML"));
1480 track
= new MidiTrack (*this, X_("toBeResetFroXML"));
1483 if (track
->init()) {
1489 track
->set_diskstream (ds
);
1491 track
->use_new_diskstream ();
1494 if (track
->set_state (node
, version
)) {
1499 boost_debug_shared_ptr_mark_interesting (track
, "Track");
1503 Route
* rt
= new Route (*this, X_("toBeResetFroXML"));
1505 if (rt
->init () == 0 && rt
->set_state (node
, version
) == 0) {
1506 boost_debug_shared_ptr_mark_interesting (rt
, "Route");
1517 Session::load_regions (const XMLNode
& node
)
1520 XMLNodeConstIterator niter
;
1521 boost::shared_ptr
<Region
> region
;
1523 nlist
= node
.children();
1527 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
1528 if ((region
= XMLRegionFactory (**niter
, false)) == 0) {
1529 error
<< _("Session: cannot create Region from XML description.");
1530 const XMLProperty
*name
= (**niter
).property("name");
1533 error
<< " " << string_compose (_("Can not load state for region '%1'"), name
->value());
1543 boost::shared_ptr
<Region
>
1544 Session::XMLRegionFactory (const XMLNode
& node
, bool full
)
1546 const XMLProperty
* type
= node
.property("type");
1550 if ( !type
|| type
->value() == "audio" ) {
1552 return boost::shared_ptr
<Region
>(XMLAudioRegionFactory (node
, full
));
1554 } else if (type
->value() == "midi") {
1556 return boost::shared_ptr
<Region
>(XMLMidiRegionFactory (node
, full
));
1560 } catch (failed_constructor
& err
) {
1561 return boost::shared_ptr
<Region
> ();
1564 return boost::shared_ptr
<Region
> ();
1567 boost::shared_ptr
<AudioRegion
>
1568 Session::XMLAudioRegionFactory (const XMLNode
& node
, bool /*full*/)
1570 const XMLProperty
* prop
;
1571 boost::shared_ptr
<Source
> source
;
1572 boost::shared_ptr
<AudioSource
> as
;
1574 SourceList master_sources
;
1575 uint32_t nchans
= 1;
1578 if (node
.name() != X_("Region")) {
1579 return boost::shared_ptr
<AudioRegion
>();
1582 if ((prop
= node
.property (X_("channels"))) != 0) {
1583 nchans
= atoi (prop
->value().c_str());
1586 if ((prop
= node
.property ("name")) == 0) {
1587 cerr
<< "no name for this region\n";
1591 if ((prop
= node
.property (X_("source-0"))) == 0) {
1592 if ((prop
= node
.property ("source")) == 0) {
1593 error
<< _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg
;
1594 return boost::shared_ptr
<AudioRegion
>();
1598 PBD::ID
s_id (prop
->value());
1600 if ((source
= source_by_id (s_id
)) == 0) {
1601 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id
) << endmsg
;
1602 return boost::shared_ptr
<AudioRegion
>();
1605 as
= boost::dynamic_pointer_cast
<AudioSource
>(source
);
1607 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id
) << endmsg
;
1608 return boost::shared_ptr
<AudioRegion
>();
1611 sources
.push_back (as
);
1613 /* pickup other channels */
1615 for (uint32_t n
=1; n
< nchans
; ++n
) {
1616 snprintf (buf
, sizeof(buf
), X_("source-%d"), n
);
1617 if ((prop
= node
.property (buf
)) != 0) {
1619 PBD::ID
id2 (prop
->value());
1621 if ((source
= source_by_id (id2
)) == 0) {
1622 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2
) << endmsg
;
1623 return boost::shared_ptr
<AudioRegion
>();
1626 as
= boost::dynamic_pointer_cast
<AudioSource
>(source
);
1628 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2
) << endmsg
;
1629 return boost::shared_ptr
<AudioRegion
>();
1631 sources
.push_back (as
);
1635 for (uint32_t n
= 0; n
< nchans
; ++n
) {
1636 snprintf (buf
, sizeof(buf
), X_("master-source-%d"), n
);
1637 if ((prop
= node
.property (buf
)) != 0) {
1639 PBD::ID
id2 (prop
->value());
1641 if ((source
= source_by_id (id2
)) == 0) {
1642 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2
) << endmsg
;
1643 return boost::shared_ptr
<AudioRegion
>();
1646 as
= boost::dynamic_pointer_cast
<AudioSource
>(source
);
1648 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2
) << endmsg
;
1649 return boost::shared_ptr
<AudioRegion
>();
1651 master_sources
.push_back (as
);
1656 boost::shared_ptr
<AudioRegion
> region (boost::dynamic_pointer_cast
<AudioRegion
> (RegionFactory::create (sources
, node
)));
1658 /* a final detail: this is the one and only place that we know how long missing files are */
1660 if (region
->whole_file()) {
1661 for (SourceList::iterator sx
= sources
.begin(); sx
!= sources
.end(); ++sx
) {
1662 boost::shared_ptr
<SilentFileSource
> sfp
= boost::dynamic_pointer_cast
<SilentFileSource
> (*sx
);
1664 sfp
->set_length (region
->length());
1669 if (!master_sources
.empty()) {
1670 if (master_sources
.size() != nchans
) {
1671 error
<< _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg
;
1673 region
->set_master_sources (master_sources
);
1681 catch (failed_constructor
& err
) {
1682 return boost::shared_ptr
<AudioRegion
>();
1686 boost::shared_ptr
<MidiRegion
>
1687 Session::XMLMidiRegionFactory (const XMLNode
& node
, bool /*full*/)
1689 const XMLProperty
* prop
;
1690 boost::shared_ptr
<Source
> source
;
1691 boost::shared_ptr
<MidiSource
> ms
;
1693 uint32_t nchans
= 1;
1695 if (node
.name() != X_("Region")) {
1696 return boost::shared_ptr
<MidiRegion
>();
1699 if ((prop
= node
.property (X_("channels"))) != 0) {
1700 nchans
= atoi (prop
->value().c_str());
1703 if ((prop
= node
.property ("name")) == 0) {
1704 cerr
<< "no name for this region\n";
1708 // Multiple midi channels? that's just crazy talk
1709 assert(nchans
== 1);
1711 if ((prop
= node
.property (X_("source-0"))) == 0) {
1712 if ((prop
= node
.property ("source")) == 0) {
1713 error
<< _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg
;
1714 return boost::shared_ptr
<MidiRegion
>();
1718 PBD::ID
s_id (prop
->value());
1720 if ((source
= source_by_id (s_id
)) == 0) {
1721 error
<< string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id
) << endmsg
;
1722 return boost::shared_ptr
<MidiRegion
>();
1725 ms
= boost::dynamic_pointer_cast
<MidiSource
>(source
);
1727 error
<< string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id
) << endmsg
;
1728 return boost::shared_ptr
<MidiRegion
>();
1731 sources
.push_back (ms
);
1734 boost::shared_ptr
<MidiRegion
> region (boost::dynamic_pointer_cast
<MidiRegion
> (RegionFactory::create (sources
, node
)));
1735 /* a final detail: this is the one and only place that we know how long missing files are */
1737 if (region
->whole_file()) {
1738 for (SourceList::iterator sx
= sources
.begin(); sx
!= sources
.end(); ++sx
) {
1739 boost::shared_ptr
<SilentFileSource
> sfp
= boost::dynamic_pointer_cast
<SilentFileSource
> (*sx
);
1741 sfp
->set_length (region
->length());
1749 catch (failed_constructor
& err
) {
1750 return boost::shared_ptr
<MidiRegion
>();
1755 Session::get_sources_as_xml ()
1758 XMLNode
* node
= new XMLNode (X_("Sources"));
1759 Glib::Mutex::Lock
lm (source_lock
);
1761 for (SourceMap::iterator i
= sources
.begin(); i
!= sources
.end(); ++i
) {
1762 node
->add_child_nocopy (i
->second
->get_state());
1769 Session::path_from_region_name (DataType type
, string name
, string identifier
)
1771 char buf
[PATH_MAX
+1];
1773 SessionDirectory
sdir(get_best_session_directory_for_new_source());
1774 sys::path source_dir
= ((type
== DataType::AUDIO
)
1775 ? sdir
.sound_path() : sdir
.midi_path());
1777 string ext
= ((type
== DataType::AUDIO
) ? ".wav" : ".mid");
1779 for (n
= 0; n
< 999999; ++n
) {
1780 if (identifier
.length()) {
1781 snprintf (buf
, sizeof(buf
), "%s%s%" PRIu32
"%s", name
.c_str(),
1782 identifier
.c_str(), n
, ext
.c_str());
1784 snprintf (buf
, sizeof(buf
), "%s-%" PRIu32
"%s", name
.c_str(),
1788 sys::path source_path
= source_dir
/ buf
;
1790 if (!sys::exists (source_path
)) {
1791 return source_path
.to_string();
1795 error
<< string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1804 Session::load_sources (const XMLNode
& node
)
1807 XMLNodeConstIterator niter
;
1808 boost::shared_ptr
<Source
> source
;
1810 nlist
= node
.children();
1814 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
1816 if ((source
= XMLSourceFactory (**niter
)) == 0) {
1817 error
<< _("Session: cannot create Source from XML description.") << endmsg
;
1819 } catch (MissingSource
& err
) {
1820 warning
<< _("A sound file is missing. It will be replaced by silence.") << endmsg
;
1821 source
= SourceFactory::createSilent (*this, **niter
, max_frames
, _current_frame_rate
);
1828 boost::shared_ptr
<Source
>
1829 Session::XMLSourceFactory (const XMLNode
& node
)
1831 if (node
.name() != "Source") {
1832 return boost::shared_ptr
<Source
>();
1836 /* note: do peak building in another thread when loading session state */
1837 return SourceFactory::create (*this, node
, true);
1840 catch (failed_constructor
& err
) {
1841 error
<< string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME
) << endmsg
;
1842 return boost::shared_ptr
<Source
>();
1847 Session::save_template (string template_name
)
1851 if (_state_of_the_state
& CannotSave
) {
1855 sys::path
user_template_dir(user_template_directory());
1859 sys::create_directories (user_template_dir
);
1861 catch(sys::filesystem_error
& ex
)
1863 error
<< string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1864 user_template_dir
.to_string(), ex
.what()) << endmsg
;
1868 tree
.set_root (&get_template());
1870 sys::path
template_file_path(user_template_dir
);
1871 template_file_path
/= template_name
+ template_suffix
;
1873 if (sys::exists (template_file_path
))
1875 warning
<< string_compose(_("Template \"%1\" already exists - new version not created"),
1876 template_file_path
.to_string()) << endmsg
;
1880 if (!tree
.write (template_file_path
.to_string())) {
1881 error
<< _("mix template not saved") << endmsg
;
1889 Session::rename_template (string old_name
, string new_name
)
1891 sys::path
old_path (user_template_directory());
1892 old_path
/= old_name
+ template_suffix
;
1894 sys::path
new_path(user_template_directory());
1895 new_path
/= new_name
+ template_suffix
;
1897 if (sys::exists (new_path
)) {
1898 warning
<< string_compose(_("Template \"%1\" already exists - template not renamed"),
1899 new_path
.to_string()) << endmsg
;
1904 sys::rename (old_path
, new_path
);
1912 Session::delete_template (string name
)
1914 sys::path path
= user_template_directory();
1915 path
/= name
+ template_suffix
;
1926 Session::refresh_disk_space ()
1929 struct statfs statfsbuf
;
1930 vector
<space_and_path
>::iterator i
;
1931 Glib::Mutex::Lock
lm (space_lock
);
1934 /* get freespace on every FS that is part of the session path */
1936 _total_free_4k_blocks
= 0;
1938 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
1939 statfs ((*i
).path
.c_str(), &statfsbuf
);
1941 scale
= statfsbuf
.f_bsize
/4096.0;
1943 (*i
).blocks
= (uint32_t) floor (statfsbuf
.f_bavail
* scale
);
1944 _total_free_4k_blocks
+= (*i
).blocks
;
1950 Session::get_best_session_directory_for_new_source ()
1952 vector
<space_and_path
>::iterator i
;
1953 string result
= _session_dir
->root_path().to_string();
1955 /* handle common case without system calls */
1957 if (session_dirs
.size() == 1) {
1961 /* OK, here's the algorithm we're following here:
1963 We want to select which directory to use for
1964 the next file source to be created. Ideally,
1965 we'd like to use a round-robin process so as to
1966 get maximum performance benefits from splitting
1967 the files across multiple disks.
1969 However, in situations without much diskspace, an
1970 RR approach may end up filling up a filesystem
1971 with new files while others still have space.
1972 Its therefore important to pay some attention to
1973 the freespace in the filesystem holding each
1974 directory as well. However, if we did that by
1975 itself, we'd keep creating new files in the file
1976 system with the most space until it was as full
1977 as all others, thus negating any performance
1978 benefits of this RAID-1 like approach.
1980 So, we use a user-configurable space threshold. If
1981 there are at least 2 filesystems with more than this
1982 much space available, we use RR selection between them.
1983 If not, then we pick the filesystem with the most space.
1985 This gets a good balance between the two
1989 refresh_disk_space ();
1991 int free_enough
= 0;
1993 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
1994 if ((*i
).blocks
* 4096 >= Config
->get_disk_choice_space_threshold()) {
1999 if (free_enough
>= 2) {
2000 /* use RR selection process, ensuring that the one
2004 i
= last_rr_session_dir
;
2007 if (++i
== session_dirs
.end()) {
2008 i
= session_dirs
.begin();
2011 if ((*i
).blocks
* 4096 >= Config
->get_disk_choice_space_threshold()) {
2012 if (create_session_directory ((*i
).path
)) {
2014 last_rr_session_dir
= i
;
2019 } while (i
!= last_rr_session_dir
);
2023 /* pick FS with the most freespace (and that
2024 seems to actually work ...)
2027 vector
<space_and_path
> sorted
;
2028 space_and_path_ascending_cmp cmp
;
2030 sorted
= session_dirs
;
2031 sort (sorted
.begin(), sorted
.end(), cmp
);
2033 for (i
= sorted
.begin(); i
!= sorted
.end(); ++i
) {
2034 if (create_session_directory ((*i
).path
)) {
2036 last_rr_session_dir
= i
;
2046 Session::load_named_selections (const XMLNode
& node
)
2049 XMLNodeConstIterator niter
;
2052 nlist
= node
.children();
2056 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2058 if ((ns
= XMLNamedSelectionFactory (**niter
)) == 0) {
2059 error
<< _("Session: cannot create Named Selection from XML description.") << endmsg
;
2067 Session::XMLNamedSelectionFactory (const XMLNode
& node
)
2070 return new NamedSelection (*this, node
);
2073 catch (failed_constructor
& err
) {
2079 Session::automation_dir () const
2081 return Glib::build_filename (_path
, "automation");
2085 Session::analysis_dir () const
2087 return Glib::build_filename (_path
, "analysis");
2091 Session::load_bundles (XMLNode
const & node
)
2093 XMLNodeList nlist
= node
.children();
2094 XMLNodeConstIterator niter
;
2098 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2099 if ((*niter
)->name() == "InputBundle") {
2100 add_bundle (boost::shared_ptr
<UserBundle
> (new UserBundle (**niter
, true)));
2101 } else if ((*niter
)->name() == "OutputBundle") {
2102 add_bundle (boost::shared_ptr
<UserBundle
> (new UserBundle (**niter
, false)));
2104 error
<< string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter
)->name()) << endmsg
;
2113 Session::load_route_groups (const XMLNode
& node
, int version
)
2115 XMLNodeList nlist
= node
.children();
2116 XMLNodeConstIterator niter
;
2120 if (version
>= 3000) {
2122 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2123 if ((*niter
)->name() == "RouteGroup") {
2124 RouteGroup
* rg
= new RouteGroup (*this, "");
2125 add_route_group (rg
);
2126 rg
->set_state (**niter
, version
);
2130 } else if (version
< 3000) {
2132 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2133 if ((*niter
)->name() == "EditGroup" || (*niter
)->name() == "MixGroup") {
2134 RouteGroup
* rg
= new RouteGroup (*this, "");
2135 add_route_group (rg
);
2136 rg
->set_state (**niter
, version
);
2145 Session::auto_save()
2147 save_state (_current_snapshot_name
);
2151 state_file_filter (const string
&str
, void */
*arg*/
)
2153 return (str
.length() > strlen(statefile_suffix
) &&
2154 str
.find (statefile_suffix
) == (str
.length() - strlen (statefile_suffix
)));
2158 bool operator()(const string
* a
, const string
* b
) {
2164 remove_end(string
* state
)
2166 string
statename(*state
);
2168 string::size_type start
,end
;
2169 if ((start
= statename
.find_last_of ('/')) != string::npos
) {
2170 statename
= statename
.substr (start
+1);
2173 if ((end
= statename
.rfind(".ardour")) == string::npos
) {
2174 end
= statename
.length();
2177 return new string(statename
.substr (0, end
));
2181 Session::possible_states (string path
)
2183 PathScanner scanner
;
2184 vector
<string
*>* states
= scanner (path
, state_file_filter
, 0, false, false);
2186 transform(states
->begin(), states
->end(), states
->begin(), remove_end
);
2189 sort (states
->begin(), states
->end(), cmp
);
2195 Session::possible_states () const
2197 return possible_states(_path
);
2201 Session::add_route_group (RouteGroup
* g
)
2203 _route_groups
.push_back (g
);
2204 route_group_added (g
); /* EMIT SIGNAL */
2209 Session::remove_route_group (RouteGroup
& rg
)
2211 list
<RouteGroup
*>::iterator i
;
2213 if ((i
= find (_route_groups
.begin(), _route_groups
.end(), &rg
)) != _route_groups
.end()) {
2214 _route_groups
.erase (i
);
2217 route_group_removed (); /* EMIT SIGNAL */
2223 Session::route_group_by_name (string name
)
2225 list
<RouteGroup
*>::iterator i
;
2227 for (i
= _route_groups
.begin(); i
!= _route_groups
.end(); ++i
) {
2228 if ((*i
)->name() == name
) {
2236 Session::start_reversible_command (const string
& name
)
2238 UndoTransaction
* trans
= new UndoTransaction();
2239 trans
->set_name(name
);
2244 Session::finish_reversible_command (UndoTransaction
& ut
)
2247 gettimeofday(&now
, 0);
2248 ut
.set_timestamp(now
);
2253 Session::begin_reversible_command(const string
& name
)
2255 UndoTransaction
* trans
= new UndoTransaction();
2256 trans
->set_name(name
);
2258 if (!_current_trans
.empty()) {
2259 _current_trans
.top()->add_command (trans
);
2261 _current_trans
.push(trans
);
2266 Session::commit_reversible_command(Command
*cmd
)
2268 assert(!_current_trans
.empty());
2272 _current_trans
.top()->add_command(cmd
);
2275 if (_current_trans
.top()->empty()) {
2276 _current_trans
.pop();
2280 gettimeofday(&now
, 0);
2281 _current_trans
.top()->set_timestamp(now
);
2283 _history
.add(_current_trans
.top());
2284 _current_trans
.pop();
2288 accept_all_non_peak_files (const string
& path
, void */
*arg*/
)
2290 return (path
.length() > 5 && path
.find (peakfile_suffix
) != (path
.length() - 5));
2294 accept_all_state_files (const string
& path
, void */
*arg*/
)
2296 return (path
.length() > 7 && path
.find (".ardour") == (path
.length() - 7));
2300 Session::find_all_sources (string path
, set
<string
>& result
)
2305 if (!tree
.read (path
)) {
2309 if ((node
= find_named_node (*tree
.root(), "Sources")) == 0) {
2314 XMLNodeConstIterator niter
;
2316 nlist
= node
->children();
2320 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2324 if ((prop
= (*niter
)->property (X_("type"))) == 0) {
2328 DataType
type (prop
->value());
2330 if ((prop
= (*niter
)->property (X_("name"))) == 0) {
2334 if (prop
->value()[0] == '/') {
2335 /* external file, ignore */
2339 Glib::ustring found_path
;
2343 if (FileSource::find (type
, prop
->value(), true, is_new
, chan
, found_path
)) {
2344 result
.insert (found_path
);
2352 Session::find_all_sources_across_snapshots (set
<string
>& result
, bool exclude_this_snapshot
)
2354 PathScanner scanner
;
2355 vector
<string
*>* state_files
;
2357 string this_snapshot_path
;
2363 if (ripped
[ripped
.length()-1] == '/') {
2364 ripped
= ripped
.substr (0, ripped
.length() - 1);
2367 state_files
= scanner (ripped
, accept_all_state_files
, (void *) 0, false, true);
2369 if (state_files
== 0) {
2374 this_snapshot_path
= _path
;
2375 this_snapshot_path
+= legalize_for_path (_current_snapshot_name
);
2376 this_snapshot_path
+= statefile_suffix
;
2378 for (vector
<string
*>::iterator i
= state_files
->begin(); i
!= state_files
->end(); ++i
) {
2380 if (exclude_this_snapshot
&& **i
== this_snapshot_path
) {
2384 if (find_all_sources (**i
, result
) < 0) {
2392 struct RegionCounter
{
2393 typedef std::map
<PBD::ID
,boost::shared_ptr
<AudioSource
> > AudioSourceList
;
2394 AudioSourceList::iterator iter
;
2395 boost::shared_ptr
<Region
> region
;
2398 RegionCounter() : count (0) {}
2402 Session::ask_about_playlist_deletion (boost::shared_ptr
<Playlist
> p
)
2404 return *AskAboutPlaylistDeletion (p
);
2408 Session::cleanup_sources (CleanupReport
& rep
)
2410 // FIXME: needs adaptation to midi
2412 vector
<boost::shared_ptr
<Source
> > dead_sources
;
2413 PathScanner scanner
;
2415 vector
<space_and_path
>::iterator i
;
2416 vector
<space_and_path
>::iterator nexti
;
2417 vector
<string
*>* soundfiles
;
2418 vector
<string
> unused
;
2419 set
<string
> all_sources
;
2424 _state_of_the_state
= (StateOfTheState
) (_state_of_the_state
| InCleanup
);
2426 /* step 1: consider deleting all unused playlists */
2428 if (playlists
->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion
, _1
))) {
2433 /* step 2: find all un-used sources */
2438 for (SourceMap::iterator i
= sources
.begin(); i
!= sources
.end(); ) {
2440 SourceMap::iterator tmp
;
2445 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2449 if (!playlists
->source_use_count(i
->second
) && i
->second
->length(i
->second
->timeline_position()) > 0) {
2450 dead_sources
.push_back (i
->second
);
2451 i
->second
->drop_references ();
2457 /* build a list of all the possible sound directories for the session */
2459 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ) {
2464 SessionDirectory
sdir ((*i
).path
);
2465 sound_path
+= sdir
.sound_path().to_string();
2467 if (nexti
!= session_dirs
.end()) {
2474 /* now do the same thing for the files that ended up in the sounds dir(s)
2475 but are not referenced as sources in any snapshot.
2478 soundfiles
= scanner (sound_path
, accept_all_non_peak_files
, (void *) 0, false, true);
2480 if (soundfiles
== 0) {
2484 /* find all sources, but don't use this snapshot because the
2485 state file on disk still references sources we may have already
2489 find_all_sources_across_snapshots (all_sources
, true);
2491 /* add our current source list
2494 for (SourceMap::iterator i
= sources
.begin(); i
!= sources
.end(); ++i
) {
2495 boost::shared_ptr
<FileSource
> fs
;
2497 if ((fs
= boost::dynamic_pointer_cast
<FileSource
> (i
->second
)) != 0) {
2498 all_sources
.insert (fs
->path());
2502 char tmppath1
[PATH_MAX
+1];
2503 char tmppath2
[PATH_MAX
+1];
2505 for (vector
<string
*>::iterator x
= soundfiles
->begin(); x
!= soundfiles
->end(); ++x
) {
2510 for (set
<string
>::iterator i
= all_sources
.begin(); i
!= all_sources
.end(); ++i
) {
2512 realpath(spath
.c_str(), tmppath1
);
2513 realpath((*i
).c_str(), tmppath2
);
2515 if (strcmp(tmppath1
, tmppath2
) == 0) {
2522 unused
.push_back (spath
);
2526 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2528 for (vector
<string
>::iterator x
= unused
.begin(); x
!= unused
.end(); ++x
) {
2529 struct stat statbuf
;
2531 rep
.paths
.push_back (*x
);
2532 if (stat ((*x
).c_str(), &statbuf
) == 0) {
2533 rep
.space
+= statbuf
.st_size
;
2538 /* don't move the file across filesystems, just
2539 stick it in the `dead_sound_dir_name' directory
2540 on whichever filesystem it was already on.
2543 if ((*x
).find ("/sounds/") != string::npos
) {
2545 /* old school, go up 1 level */
2547 newpath
= Glib::path_get_dirname (*x
); // "sounds"
2548 newpath
= Glib::path_get_dirname (newpath
); // "session-name"
2552 /* new school, go up 4 levels */
2554 newpath
= Glib::path_get_dirname (*x
); // "audiofiles"
2555 newpath
= Glib::path_get_dirname (newpath
); // "session-name"
2556 newpath
= Glib::path_get_dirname (newpath
); // "interchange"
2557 newpath
= Glib::path_get_dirname (newpath
); // "session-dir"
2561 newpath
+= dead_sound_dir_name
;
2563 if (g_mkdir_with_parents (newpath
.c_str(), 0755) < 0) {
2564 error
<< string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath
, strerror (errno
)) << endmsg
;
2569 newpath
+= Glib::path_get_basename ((*x
));
2571 if (access (newpath
.c_str(), F_OK
) == 0) {
2573 /* the new path already exists, try versioning */
2575 char buf
[PATH_MAX
+1];
2579 snprintf (buf
, sizeof (buf
), "%s.%d", newpath
.c_str(), version
);
2582 while (access (newpath_v
.c_str(), F_OK
) == 0 && version
< 999) {
2583 snprintf (buf
, sizeof (buf
), "%s.%d", newpath
.c_str(), ++version
);
2587 if (version
== 999) {
2588 error
<< string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2592 newpath
= newpath_v
;
2597 /* it doesn't exist, or we can't read it or something */
2601 if (::rename ((*x
).c_str(), newpath
.c_str()) != 0) {
2602 error
<< string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2603 (*x
), newpath
, strerror (errno
))
2608 /* see if there an easy to find peakfile for this file, and remove it.
2611 string peakpath
= (*x
).substr (0, (*x
).find_last_of ('.'));
2612 peakpath
+= peakfile_suffix
;
2614 if (access (peakpath
.c_str(), W_OK
) == 0) {
2615 if (::unlink (peakpath
.c_str()) != 0) {
2616 error
<< string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2617 peakpath
, _path
, strerror (errno
))
2619 /* try to back out */
2620 rename (newpath
.c_str(), _path
.c_str());
2628 /* dump the history list */
2632 /* save state so we don't end up a session file
2633 referring to non-existent sources.
2639 _state_of_the_state
= (StateOfTheState
) (_state_of_the_state
& ~InCleanup
);
2645 Session::cleanup_trash_sources (CleanupReport
& rep
)
2647 // FIXME: needs adaptation for MIDI
2649 vector
<space_and_path
>::iterator i
;
2650 string dead_sound_dir
;
2651 struct dirent
* dentry
;
2652 struct stat statbuf
;
2658 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
2660 dead_sound_dir
= (*i
).path
;
2661 dead_sound_dir
+= dead_sound_dir_name
;
2663 if ((dead
= opendir (dead_sound_dir
.c_str())) == 0) {
2667 while ((dentry
= readdir (dead
)) != 0) {
2669 /* avoid '.' and '..' */
2671 if ((dentry
->d_name
[0] == '.' && dentry
->d_name
[1] == '\0') ||
2672 (dentry
->d_name
[2] == '\0' && dentry
->d_name
[0] == '.' && dentry
->d_name
[1] == '.')) {
2678 fullpath
= dead_sound_dir
;
2680 fullpath
+= dentry
->d_name
;
2682 if (stat (fullpath
.c_str(), &statbuf
)) {
2686 if (!S_ISREG (statbuf
.st_mode
)) {
2690 if (unlink (fullpath
.c_str())) {
2691 error
<< string_compose (_("cannot remove dead sound file %1 (%2)"),
2692 fullpath
, strerror (errno
))
2696 rep
.paths
.push_back (dentry
->d_name
);
2697 rep
.space
+= statbuf
.st_size
;
2708 Session::set_dirty ()
2710 bool was_dirty
= dirty();
2712 _state_of_the_state
= StateOfTheState (_state_of_the_state
| Dirty
);
2716 DirtyChanged(); /* EMIT SIGNAL */
2722 Session::set_clean ()
2724 bool was_dirty
= dirty();
2726 _state_of_the_state
= Clean
;
2730 DirtyChanged(); /* EMIT SIGNAL */
2735 Session::set_deletion_in_progress ()
2737 _state_of_the_state
= StateOfTheState (_state_of_the_state
| Deletion
);
2741 Session::clear_deletion_in_progress ()
2743 _state_of_the_state
= StateOfTheState (_state_of_the_state
& (~Deletion
));
2747 Session::add_controllable (boost::shared_ptr
<Controllable
> c
)
2749 /* this adds a controllable to the list managed by the Session.
2750 this is a subset of those managed by the Controllable class
2751 itself, and represents the only ones whose state will be saved
2752 as part of the session.
2755 Glib::Mutex::Lock
lm (controllables_lock
);
2756 controllables
.insert (c
);
2759 struct null_deleter
{ void operator()(void const *) const {} };
2762 Session::remove_controllable (Controllable
* c
)
2764 if (_state_of_the_state
| Deletion
) {
2768 Glib::Mutex::Lock
lm (controllables_lock
);
2770 Controllables::iterator x
= controllables
.find (boost::shared_ptr
<Controllable
>(c
, null_deleter()));
2772 if (x
!= controllables
.end()) {
2773 controllables
.erase (x
);
2777 boost::shared_ptr
<Controllable
>
2778 Session::controllable_by_id (const PBD::ID
& id
)
2780 Glib::Mutex::Lock
lm (controllables_lock
);
2782 for (Controllables::iterator i
= controllables
.begin(); i
!= controllables
.end(); ++i
) {
2783 if ((*i
)->id() == id
) {
2788 return boost::shared_ptr
<Controllable
>();
2791 boost::shared_ptr
<Controllable
>
2792 Session::controllable_by_descriptor (const ControllableDescriptor
& desc
)
2794 boost::shared_ptr
<Controllable
> c
;
2795 boost::shared_ptr
<Route
> r
;
2797 switch (desc
.top_level_type()) {
2798 case ControllableDescriptor::NamedRoute
:
2800 std::string str
= desc
.top_level_name();
2801 if (str
== "master") {
2803 } else if (str
== "control" || str
== "listen") {
2806 r
= route_by_name (desc
.top_level_name());
2811 case ControllableDescriptor::RemoteControlID
:
2812 r
= route_by_remote_id (desc
.rid());
2820 switch (desc
.subtype()) {
2821 case ControllableDescriptor::Gain
:
2822 c
= r
->gain_control ();
2825 case ControllableDescriptor::Solo
:
2826 c
= r
->solo_control();
2829 case ControllableDescriptor::Mute
:
2830 c
= r
->mute_control();
2833 case ControllableDescriptor::Recenable
:
2835 boost::shared_ptr
<Track
> t
= boost::dynamic_pointer_cast
<Track
>(r
);
2838 c
= t
->rec_enable_control ();
2843 case ControllableDescriptor::Pan
:
2844 /* XXX pan control */
2847 case ControllableDescriptor::Balance
:
2848 /* XXX simple pan control */
2851 case ControllableDescriptor::PluginParameter
:
2853 uint32_t plugin
= desc
.target (0);
2854 uint32_t parameter_index
= desc
.target (1);
2856 /* revert to zero based counting */
2862 if (parameter_index
> 0) {
2866 boost::shared_ptr
<Processor
> p
= r
->nth_plugin (plugin
);
2869 c
= boost::dynamic_pointer_cast
<ARDOUR::AutomationControl
>(
2870 p
->control(Evoral::Parameter(PluginAutomation
, 0, parameter_index
)));
2875 case ControllableDescriptor::SendGain
:
2877 uint32_t send
= desc
.target (0);
2879 /* revert to zero-based counting */
2885 boost::shared_ptr
<Processor
> p
= r
->nth_send (send
);
2888 boost::shared_ptr
<Send
> s
= boost::dynamic_pointer_cast
<Send
>(p
);
2889 boost::shared_ptr
<Amp
> a
= s
->amp();
2892 c
= s
->amp()->gain_control();
2899 /* relax and return a null pointer */
2907 Session::add_instant_xml (XMLNode
& node
, bool write_to_config
)
2910 Stateful::add_instant_xml (node
, _path
);
2913 if (write_to_config
) {
2914 Config
->add_instant_xml (node
);
2919 Session::instant_xml (const string
& node_name
)
2921 return Stateful::instant_xml (node_name
, _path
);
2925 Session::save_history (string snapshot_name
)
2933 if (snapshot_name
.empty()) {
2934 snapshot_name
= _current_snapshot_name
;
2937 const string history_filename
= legalize_for_path (snapshot_name
) + history_suffix
;
2938 const string backup_filename
= history_filename
+ backup_suffix
;
2939 const sys::path xml_path
= _session_dir
->root_path() / history_filename
;
2940 const sys::path backup_path
= _session_dir
->root_path() / backup_filename
;
2942 if (sys::exists (xml_path
)) {
2945 sys::rename (xml_path
, backup_path
);
2947 catch (const sys::filesystem_error
& err
)
2949 error
<< _("could not backup old history file, current history not saved") << endmsg
;
2954 if (!Config
->get_save_history() || Config
->get_saved_history_depth() < 0) {
2958 tree
.set_root (&_history
.get_state (Config
->get_saved_history_depth()));
2960 if (!tree
.write (xml_path
.to_string()))
2962 error
<< string_compose (_("history could not be saved to %1"), xml_path
.to_string()) << endmsg
;
2966 sys::remove (xml_path
);
2967 sys::rename (backup_path
, xml_path
);
2969 catch (const sys::filesystem_error
& err
)
2971 error
<< string_compose (_("could not restore history file from backup %1 (%2)"),
2972 backup_path
.to_string(), err
.what()) << endmsg
;
2982 Session::restore_history (string snapshot_name
)
2986 if (snapshot_name
.empty()) {
2987 snapshot_name
= _current_snapshot_name
;
2990 const string xml_filename
= legalize_for_path (snapshot_name
) + history_suffix
;
2991 const sys::path xml_path
= _session_dir
->root_path() / xml_filename
;
2993 info
<< "Loading history from " << xml_path
.to_string() << endmsg
;
2995 if (!sys::exists (xml_path
)) {
2996 info
<< string_compose (_("%1: no history file \"%2\" for this session."),
2997 _name
, xml_path
.to_string()) << endmsg
;
3001 if (!tree
.read (xml_path
.to_string())) {
3002 error
<< string_compose (_("Could not understand session history file \"%1\""),
3003 xml_path
.to_string()) << endmsg
;
3010 for (XMLNodeConstIterator it
= tree
.root()->children().begin(); it
!= tree
.root()->children().end(); it
++) {
3013 UndoTransaction
* ut
= new UndoTransaction ();
3016 ut
->set_name(t
->property("name")->value());
3017 stringstream
ss(t
->property("tv-sec")->value());
3019 ss
.str(t
->property("tv-usec")->value());
3021 ut
->set_timestamp(tv
);
3023 for (XMLNodeConstIterator child_it
= t
->children().begin();
3024 child_it
!= t
->children().end(); child_it
++)
3026 XMLNode
*n
= *child_it
;
3029 if (n
->name() == "MementoCommand" ||
3030 n
->name() == "MementoUndoCommand" ||
3031 n
->name() == "MementoRedoCommand") {
3033 if ((c
= memento_command_factory(n
))) {
3037 } else if (n
->name() == "DeltaCommand") {
3038 PBD::ID
id(n
->property("midi-source")->value());
3039 boost::shared_ptr
<MidiSource
> midi_source
=
3040 boost::dynamic_pointer_cast
<MidiSource
, Source
>(source_by_id(id
));
3042 ut
->add_command(new MidiModel::DeltaCommand(midi_source
->model(), *n
));
3044 error
<< _("Failed to downcast MidiSource for DeltaCommand") << endmsg
;
3047 } else if (n
->name() == "DiffCommand") {
3048 PBD::ID
id(n
->property("midi-source")->value());
3049 boost::shared_ptr
<MidiSource
> midi_source
=
3050 boost::dynamic_pointer_cast
<MidiSource
, Source
>(source_by_id(id
));
3052 ut
->add_command(new MidiModel::DiffCommand(midi_source
->model(), *n
));
3054 error
<< _("Failed to downcast MidiSource for DeltaCommand") << endmsg
;
3057 } else if (n
->name() == "StatefulDiffCommand") {
3058 if ((c
= stateful_diff_command_factory (n
))) {
3059 ut
->add_command (c
);
3062 error
<< string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n
->name()) << endmsg
;
3073 Session::config_changed (std::string p
, bool ours
)
3079 if (p
== "seamless-loop") {
3081 } else if (p
== "rf-speed") {
3083 } else if (p
== "auto-loop") {
3085 } else if (p
== "auto-input") {
3087 if (Config
->get_monitoring_model() == HardwareMonitoring
&& transport_rolling()) {
3088 /* auto-input only makes a difference if we're rolling */
3090 boost::shared_ptr
<DiskstreamList
> dsl
= diskstreams
.reader();
3092 for (DiskstreamList::iterator i
= dsl
->begin(); i
!= dsl
->end(); ++i
) {
3093 if ((*i
)->record_enabled ()) {
3094 (*i
)->monitor_input (!config
.get_auto_input());
3099 } else if (p
== "punch-in") {
3103 if ((location
= _locations
.auto_punch_location()) != 0) {
3105 if (config
.get_punch_in ()) {
3106 replace_event (SessionEvent::PunchIn
, location
->start());
3108 remove_event (location
->start(), SessionEvent::PunchIn
);
3112 } else if (p
== "punch-out") {
3116 if ((location
= _locations
.auto_punch_location()) != 0) {
3118 if (config
.get_punch_out()) {
3119 replace_event (SessionEvent::PunchOut
, location
->end());
3121 clear_events (SessionEvent::PunchOut
);
3125 } else if (p
== "edit-mode") {
3127 Glib::Mutex::Lock
lm (playlists
->lock
);
3129 for (SessionPlaylists::List::iterator i
= playlists
->playlists
.begin(); i
!= playlists
->playlists
.end(); ++i
) {
3130 (*i
)->set_edit_mode (Config
->get_edit_mode ());
3133 } else if (p
== "use-video-sync") {
3135 waiting_for_sync_offset
= config
.get_use_video_sync();
3137 } else if (p
== "mmc-control") {
3139 //poke_midi_thread ();
3141 } else if (p
== "mmc-device-id" || p
== "mmc-receive-id") {
3144 mmc
->set_receive_device_id (Config
->get_mmc_receive_device_id());
3147 } else if (p
== "mmc-send-id") {
3150 mmc
->set_send_device_id (Config
->get_mmc_send_device_id());
3153 } else if (p
== "midi-control") {
3155 //poke_midi_thread ();
3157 } else if (p
== "raid-path") {
3159 setup_raid_path (config
.get_raid_path());
3161 } else if (p
== "timecode-format") {
3165 } else if (p
== "video-pullup") {
3169 } else if (p
== "seamless-loop") {
3171 if (play_loop
&& transport_rolling()) {
3172 // to reset diskstreams etc
3173 request_play_loop (true);
3176 } else if (p
== "rf-speed") {
3178 cumulative_rf_motion
= 0;
3181 } else if (p
== "click-sound") {
3183 setup_click_sounds (1);
3185 } else if (p
== "click-emphasis-sound") {
3187 setup_click_sounds (-1);
3189 } else if (p
== "clicking") {
3191 if (Config
->get_clicking()) {
3192 if (_click_io
&& click_data
) { // don't require emphasis data
3199 } else if (p
== "send-mtc") {
3201 /* only set the internal flag if we have
3205 if (_mtc_port
!= 0) {
3206 session_send_mtc
= Config
->get_send_mtc();
3207 if (session_send_mtc
) {
3208 /* mark us ready to send */
3209 next_quarter_frame_to_send
= 0;
3212 session_send_mtc
= false;
3215 } else if (p
== "send-mmc") {
3217 /* only set the internal flag if we have
3221 if (_mmc_port
!= 0) {
3222 session_send_mmc
= Config
->get_send_mmc();
3225 session_send_mmc
= false;
3228 } else if (p
== "midi-feedback") {
3230 /* only set the internal flag if we have
3234 if (_mtc_port
!= 0) {
3235 session_midi_feedback
= Config
->get_midi_feedback();
3238 } else if (p
== "jack-time-master") {
3240 engine().reset_timebase ();
3242 } else if (p
== "native-file-header-format") {
3244 if (!first_file_header_format_reset
) {
3245 reset_native_file_format ();
3248 first_file_header_format_reset
= false;
3250 } else if (p
== "native-file-data-format") {
3252 if (!first_file_data_format_reset
) {
3253 reset_native_file_format ();
3256 first_file_data_format_reset
= false;
3258 } else if (p
== "external-sync") {
3259 if (!config
.get_external_sync()) {
3260 drop_sync_source ();
3262 switch_to_sync_source (config
.get_sync_source());
3264 } else if (p
== "remote-model") {
3265 set_remote_control_ids ();
3266 } else if (p
== "denormal-model") {
3268 } else if (p
== "history-depth") {
3269 set_history_depth (Config
->get_history_depth());
3270 } else if (p
== "sync-all-route-ordering") {
3271 sync_order_keys ("session");
3272 } else if (p
== "initial-program-change") {
3274 if (_mmc_port
&& Config
->get_initial_program_change() >= 0) {
3277 buf
[0] = MIDI::program
; // channel zero by default
3278 buf
[1] = (Config
->get_initial_program_change() & 0x7f);
3280 _mmc_port
->midimsg (buf
, sizeof (buf
), 0);
3282 } else if (p
== "initial-program-change") {
3284 if (_mmc_port
&& Config
->get_initial_program_change() >= 0) {
3285 MIDI::byte
* buf
= new MIDI::byte
[2];
3287 buf
[0] = MIDI::program
; // channel zero by default
3288 buf
[1] = (Config
->get_initial_program_change() & 0x7f);
3289 // deliver_midi (_mmc_port, buf, 2);
3291 } else if (p
== "solo-mute-override") {
3292 // catch_up_on_solo_mute_override ();
3293 } else if (p
== "listen-position") {
3294 listen_position_changed ();
3295 } else if (p
== "solo-control-is-listen-control") {
3296 solo_control_mode_changed ();
3304 Session::set_history_depth (uint32_t d
)
3306 _history
.set_depth (d
);