fix assumption that Session::_mmc != 0
[ardour2.git] / libs / ardour / session_state.cc
blob86bc6a112b812f3f4d43746b75fa1dae0927023f
1 /*
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.
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
25 #define __STDC_FORMAT_MACROS 1
26 #include <stdint.h>
28 #include <algorithm>
29 #include <fstream>
30 #include <string>
31 #include <cerrno>
34 #include <cstdio> /* snprintf(3) ... grrr */
35 #include <cmath>
36 #include <unistd.h>
37 #include <sys/stat.h>
38 #include <climits>
39 #include <fcntl.h>
40 #include <poll.h>
41 #include <signal.h>
42 #include <sys/mman.h>
43 #include <sys/time.h>
44 #include <dirent.h>
46 #ifdef HAVE_SYS_VFS_H
47 #include <sys/vfs.h>
48 #else
49 #include <sys/param.h>
50 #include <sys/mount.h>
51 #endif
53 #include <glibmm.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/port.h"
96 #include "ardour/region_factory.h"
97 #include "ardour/route_group.h"
98 #include "ardour/send.h"
99 #include "ardour/session.h"
100 #include "ardour/session_directory.h"
101 #include "ardour/session_metadata.h"
102 #include "ardour/session_state_utils.h"
103 #include "ardour/session_playlists.h"
104 #include "ardour/session_utils.h"
105 #include "ardour/silentfilesource.h"
106 #include "ardour/slave.h"
107 #include "ardour/smf_source.h"
108 #include "ardour/sndfile_helpers.h"
109 #include "ardour/sndfilesource.h"
110 #include "ardour/source_factory.h"
111 #include "ardour/template_utils.h"
112 #include "ardour/tempo.h"
113 #include "ardour/ticker.h"
114 #include "ardour/user_bundle.h"
115 #include "ardour/utils.h"
116 #include "ardour/utils.h"
117 #include "ardour/version.h"
118 #include "ardour/playlist_factory.h"
120 #include "control_protocol/control_protocol.h"
122 #include "i18n.h"
123 #include <locale.h>
125 using namespace std;
126 using namespace ARDOUR;
127 using namespace PBD;
129 void
130 Session::first_stage_init (string fullpath, string snapshot_name)
132 if (fullpath.length() == 0) {
133 destroy ();
134 throw failed_constructor();
137 char buf[PATH_MAX+1];
138 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
139 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
140 destroy ();
141 throw failed_constructor();
144 _path = string(buf);
146 if (_path[_path.length()-1] != '/') {
147 _path += '/';
150 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
151 _writable = false;
152 } else {
153 _writable = true;
156 /* these two are just provisional settings. set_state()
157 will likely override them.
160 _name = _current_snapshot_name = snapshot_name;
162 set_history_depth (Config->get_history_depth());
164 _current_frame_rate = _engine.frame_rate ();
165 _nominal_frame_rate = _current_frame_rate;
166 _base_frame_rate = _current_frame_rate;
168 _tempo_map = new TempoMap (_current_frame_rate);
169 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
172 _non_soloed_outs_muted = false;
173 _listen_cnt = 0;
174 _solo_isolated_cnt = 0;
175 g_atomic_int_set (&processing_prohibited, 0);
176 _transport_speed = 0;
177 _last_transport_speed = 0;
178 _target_transport_speed = 0;
179 auto_play_legal = false;
180 transport_sub_state = 0;
181 _transport_frame = 0;
182 _requested_return_frame = -1;
183 _session_range_location = 0;
184 g_atomic_int_set (&_record_status, Disabled);
185 loop_changing = false;
186 play_loop = false;
187 have_looped = false;
188 _last_roll_location = 0;
189 _last_roll_or_reversal_location = 0;
190 _last_record_location = 0;
191 pending_locate_frame = 0;
192 pending_locate_roll = false;
193 pending_locate_flush = false;
194 state_was_pending = false;
195 set_next_event ();
196 outbound_mtc_timecode_frame = 0;
197 next_quarter_frame_to_send = -1;
198 current_block_size = 0;
199 solo_update_disabled = false;
200 _have_captured = false;
201 _worst_output_latency = 0;
202 _worst_input_latency = 0;
203 _worst_track_latency = 0;
204 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
205 _was_seamless = Config->get_seamless_loop ();
206 _slave = 0;
207 session_send_mtc = false;
208 g_atomic_int_set (&_playback_load, 100);
209 g_atomic_int_set (&_capture_load, 100);
210 _play_range = false;
211 _exporting = false;
212 pending_abort = false;
213 destructive_index = 0;
214 first_file_data_format_reset = true;
215 first_file_header_format_reset = true;
216 post_export_sync = false;
217 midi_control_ui = 0;
219 AudioDiskstream::allocate_working_buffers();
221 /* default short fade = 15ms */
223 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
224 SndFileSource::setup_standard_crossfades (*this, frame_rate());
226 last_mmc_step.tv_sec = 0;
227 last_mmc_step.tv_usec = 0;
228 step_speed = 0.0;
230 /* click sounds are unset by default, which causes us to internal
231 waveforms for clicks.
234 click_length = 0;
235 click_emphasis_length = 0;
236 _clicking = false;
238 process_function = &Session::process_with_events;
240 if (config.get_use_video_sync()) {
241 waiting_for_sync_offset = true;
242 } else {
243 waiting_for_sync_offset = false;
246 last_timecode_when = 0;
247 _timecode_offset = 0;
248 _timecode_offset_negative = true;
249 last_timecode_valid = false;
251 sync_time_vars ();
253 last_rr_session_dir = session_dirs.begin();
254 refresh_disk_space ();
256 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
258 /* slave stuff */
260 average_slave_delta = 1800; // !!! why 1800 ????
261 have_first_delta_accumulator = false;
262 delta_accumulator_cnt = 0;
263 _slave_state = Stopped;
265 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
267 /* These are all static "per-class" signals */
269 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
270 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
271 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
272 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
273 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
275 /* stop IO objects from doing stuff until we're ready for them */
277 Delivery::disable_panners ();
278 IO::disable_connecting ();
282 Session::second_stage_init ()
284 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
286 if (!_is_new) {
287 if (load_state (_current_snapshot_name)) {
288 return -1;
290 remove_empty_sounds ();
293 if (_butler->start_thread()) {
294 return -1;
297 if (start_midi_thread ()) {
298 return -1;
301 setup_midi_machine_control ();
303 // set_state() will call setup_raid_path(), but if it's a new session we need
304 // to call setup_raid_path() here.
306 if (state_tree) {
307 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
308 return -1;
310 } else {
311 setup_raid_path(_path);
314 /* we can't save till after ::when_engine_running() is called,
315 because otherwise we save state with no connections made.
316 therefore, we reset _state_of_the_state because ::set_state()
317 will have cleared it.
319 we also have to include Loading so that any events that get
320 generated between here and the end of ::when_engine_running()
321 will be processed directly rather than queued.
324 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
326 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
327 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
328 setup_click_sounds (0);
329 setup_midi_control ();
331 /* Pay attention ... */
333 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
334 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
336 try {
337 when_engine_running ();
340 /* handle this one in a different way than all others, so that its clear what happened */
342 catch (AudioEngine::PortRegistrationFailure& err) {
343 error << err.what() << endmsg;
344 return -1;
347 catch (...) {
348 return -1;
351 BootMessage (_("Reset Remote Controls"));
353 send_full_time_code (0);
354 _engine.transport_locate (0);
356 if (_mmc) {
357 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
358 _mmc->send (MIDI::MachineControlCommand (Timecode::Time ()));
361 MidiClockTicker::instance().set_session (this);
362 MIDI::Name::MidiPatchManager::instance().set_session (this);
364 /* initial program change will be delivered later; see ::config_changed() */
366 BootMessage (_("Reset Control Protocols"));
368 ControlProtocolManager::instance().set_session (this);
370 _state_of_the_state = Clean;
372 Port::set_connecting_blocked (false);
374 DirtyChanged (); /* EMIT SIGNAL */
376 if (state_was_pending) {
377 save_state (_current_snapshot_name);
378 remove_pending_capture_state ();
379 state_was_pending = false;
382 BootMessage (_("Session loading complete"));
384 return 0;
387 string
388 Session::raid_path () const
390 SearchPath raid_search_path;
392 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
393 raid_search_path += sys::path((*i).path);
396 return raid_search_path.to_string ();
399 void
400 Session::setup_raid_path (string path)
402 if (path.empty()) {
403 return;
406 space_and_path sp;
407 string fspath;
409 session_dirs.clear ();
411 SearchPath search_path(path);
412 SearchPath sound_search_path;
413 SearchPath midi_search_path;
415 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
416 sp.path = (*i).to_string ();
417 sp.blocks = 0; // not needed
418 session_dirs.push_back (sp);
420 SessionDirectory sdir(sp.path);
422 sound_search_path += sdir.sound_path ();
423 midi_search_path += sdir.midi_path ();
426 // set the search path for each data type
427 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
428 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
430 // reset the round-robin soundfile path thingie
431 last_rr_session_dir = session_dirs.begin();
434 bool
435 Session::path_is_within_session (const std::string& path)
437 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
438 if (path.find ((*i).path) == 0) {
439 return true;
442 return false;
446 Session::ensure_subdirs ()
448 string dir;
450 dir = session_directory().peak_path().to_string();
452 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 return -1;
457 dir = session_directory().sound_path().to_string();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 return -1;
464 dir = session_directory().midi_path().to_string();
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 return -1;
471 dir = session_directory().dead_sound_path().to_string();
473 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 return -1;
478 dir = session_directory().export_path().to_string();
480 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 return -1;
485 dir = analysis_dir ();
487 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
489 return -1;
492 return 0;
496 Session::create (const string& mix_template, BusProfile* bus_profile)
499 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
501 return -1;
504 if (ensure_subdirs ()) {
505 return -1;
508 if (!mix_template.empty()) {
509 std::string in_path = mix_template;
511 ifstream in(in_path.c_str());
513 if (in){
514 string out_path = _path;
515 out_path += _name;
516 out_path += statefile_suffix;
518 ofstream out(out_path.c_str());
520 if (out){
521 out << in.rdbuf();
522 _is_new = false;
523 return 0;
525 } else {
526 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
527 << endmsg;
528 return -1;
531 } else {
532 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
533 << endmsg;
534 return -1;
539 /* Instantiate metadata */
541 _metadata = new SessionMetadata ();
543 /* set initial start + end point */
545 _state_of_the_state = Clean;
547 /* set up Master Out and Control Out if necessary */
549 if (bus_profile) {
551 RouteList rl;
552 int control_id = 1;
553 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
555 if (bus_profile->master_out_channels) {
556 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
557 if (rt->init ()) {
558 delete rt;
559 return -1;
561 boost_debug_shared_ptr_mark_interesting (rt, "Route");
562 boost::shared_ptr<Route> r (rt);
563 r->input()->ensure_io (count, false, this);
564 r->output()->ensure_io (count, false, this);
565 r->set_remote_control_id (control_id++);
567 rl.push_back (r);
569 if (Config->get_use_monitor_bus()) {
570 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
571 if (rt->init ()) {
572 delete rt;
573 return -1;
575 boost_debug_shared_ptr_mark_interesting (rt, "Route");
576 boost::shared_ptr<Route> r (rt);
577 r->input()->ensure_io (count, false, this);
578 r->output()->ensure_io (count, false, this);
579 r->set_remote_control_id (control_id);
581 rl.push_back (r);
584 } else {
585 /* prohibit auto-connect to master, because there isn't one */
586 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
589 if (!rl.empty()) {
590 add_routes (rl, false);
593 /* this allows the user to override settings with an environment variable.
596 if (no_auto_connect()) {
597 bus_profile->input_ac = AutoConnectOption (0);
598 bus_profile->output_ac = AutoConnectOption (0);
601 Config->set_input_auto_connect (bus_profile->input_ac);
602 Config->set_output_auto_connect (bus_profile->output_ac);
605 save_state ("");
607 return 0;
610 void
611 Session::maybe_write_autosave()
613 if (dirty() && record_status() != Recording) {
614 save_state("", true);
618 void
619 Session::remove_pending_capture_state ()
621 sys::path pending_state_file_path(_session_dir->root_path());
623 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
627 sys::remove (pending_state_file_path);
629 catch(sys::filesystem_error& ex)
631 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
632 pending_state_file_path.to_string(), ex.what()) << endmsg;
636 /** Rename a state file.
637 * @param snapshot_name Snapshot name.
639 void
640 Session::rename_state (string old_name, string new_name)
642 if (old_name == _current_snapshot_name || old_name == _name) {
643 /* refuse to rename the current snapshot or the "main" one */
644 return;
647 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
648 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
650 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
651 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
655 sys::rename (old_xml_path, new_xml_path);
657 catch (const sys::filesystem_error& err)
659 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
660 old_name, new_name, err.what()) << endmsg;
664 /** Remove a state file.
665 * @param snapshot_name Snapshot name.
667 void
668 Session::remove_state (string snapshot_name)
670 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
671 // refuse to remove the current snapshot or the "main" one
672 return;
675 sys::path xml_path(_session_dir->root_path());
677 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
679 if (!create_backup_file (xml_path)) {
680 // don't remove it if a backup can't be made
681 // create_backup_file will log the error.
682 return;
685 // and delete it
686 sys::remove (xml_path);
689 #ifdef HAVE_JACK_SESSION
690 void
691 Session::jack_session_event (jack_session_event_t * event)
693 char timebuf[128];
694 time_t n;
695 struct tm local_time;
697 time (&n);
698 localtime_r (&n, &local_time);
699 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
701 if (event->type == JackSessionSaveTemplate)
703 if (save_template( timebuf )) {
704 event->flags = JackSessionSaveError;
705 } else {
706 string cmd ("ardour3 -P -U ");
707 cmd += event->client_uuid;
708 cmd += " -T ";
709 cmd += timebuf;
711 event->command_line = strdup (cmd.c_str());
714 else
716 if (save_state (timebuf)) {
717 event->flags = JackSessionSaveError;
718 } else {
719 sys::path xml_path (_session_dir->root_path());
720 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
722 string cmd ("ardour3 -P -U ");
723 cmd += event->client_uuid;
724 cmd += " \"";
725 cmd += xml_path.to_string();
726 cmd += '\"';
728 event->command_line = strdup (cmd.c_str());
732 jack_session_reply (_engine.jack(), event);
734 if (event->type == JackSessionSaveAndQuit) {
735 // TODO: make ardour quit.
738 jack_session_event_free( event );
740 #endif
743 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
745 XMLTree tree;
746 sys::path xml_path(_session_dir->root_path());
748 if (!_writable || (_state_of_the_state & CannotSave)) {
749 return 1;
752 if (!_engine.connected ()) {
753 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
754 PROGRAM_NAME)
755 << endmsg;
756 return 1;
759 /* tell sources we're saving first, in case they write out to a new file
760 * which should be saved with the state rather than the old one */
761 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
762 i->second->session_saved();
765 tree.set_root (&get_state());
767 if (snapshot_name.empty()) {
768 snapshot_name = _current_snapshot_name;
769 } else if (switch_to_snapshot) {
770 _current_snapshot_name = snapshot_name;
773 if (!pending) {
775 /* proper save: use statefile_suffix (.ardour in English) */
777 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
779 /* make a backup copy of the old file */
781 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
782 // create_backup_file will log the error
783 return -1;
786 } else {
788 /* pending save: use pending_suffix (.pending in English) */
789 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
792 sys::path tmp_path(_session_dir->root_path());
794 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
796 // cerr << "actually writing state to " << xml_path.to_string() << endl;
798 if (!tree.write (tmp_path.to_string())) {
799 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
800 sys::remove (tmp_path);
801 return -1;
803 } else {
805 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
806 error << string_compose (_("could not rename temporary session file %1 to %2"),
807 tmp_path.to_string(), xml_path.to_string()) << endmsg;
808 sys::remove (tmp_path);
809 return -1;
813 if (!pending) {
815 save_history (snapshot_name);
817 bool was_dirty = dirty();
819 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
821 if (was_dirty) {
822 DirtyChanged (); /* EMIT SIGNAL */
825 StateSaved (snapshot_name); /* EMIT SIGNAL */
828 return 0;
832 Session::restore_state (string snapshot_name)
834 if (load_state (snapshot_name) == 0) {
835 set_state (*state_tree->root(), Stateful::loading_state_version);
838 return 0;
842 Session::load_state (string snapshot_name)
844 delete state_tree;
845 state_tree = 0;
847 state_was_pending = false;
849 /* check for leftover pending state from a crashed capture attempt */
851 sys::path xmlpath(_session_dir->root_path());
852 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
854 if (sys::exists (xmlpath)) {
856 /* there is pending state from a crashed capture attempt */
858 boost::optional<int> r = AskAboutPendingState();
859 if (r.get_value_or (1)) {
860 state_was_pending = true;
864 if (!state_was_pending) {
865 xmlpath = _session_dir->root_path();
866 xmlpath /= snapshot_name;
869 if (!sys::exists (xmlpath)) {
870 xmlpath = _session_dir->root_path();
871 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
872 if (!sys::exists (xmlpath)) {
873 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
874 return 1;
878 state_tree = new XMLTree;
880 set_dirty();
882 /* writable() really reflects the whole folder, but if for any
883 reason the session state file can't be written to, still
884 make us unwritable.
887 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
888 _writable = false;
891 if (!state_tree->read (xmlpath.to_string())) {
892 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
893 delete state_tree;
894 state_tree = 0;
895 return -1;
898 XMLNode& root (*state_tree->root());
900 if (root.name() != X_("Session")) {
901 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
902 delete state_tree;
903 state_tree = 0;
904 return -1;
907 const XMLProperty* prop;
909 if ((prop = root.property ("version")) == 0) {
910 /* no version implies very old version of Ardour */
911 Stateful::loading_state_version = 1000;
912 } else {
913 int major;
914 int minor;
915 int micro;
917 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, &micro);
918 Stateful::loading_state_version = (major * 1000) + minor;
921 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
923 sys::path backup_path(_session_dir->root_path());
925 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
927 // only create a backup once
928 if (sys::exists (backup_path)) {
929 return 0;
932 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
933 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
934 << endmsg;
938 sys::copy_file (xmlpath, backup_path);
940 catch(sys::filesystem_error& ex)
942 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
943 xmlpath.to_string(), ex.what())
944 << endmsg;
945 return -1;
949 return 0;
953 Session::load_options (const XMLNode& node)
955 LocaleGuard lg (X_("POSIX"));
956 config.set_variables (node);
957 return 0;
960 XMLNode&
961 Session::get_state()
963 return state(true);
966 XMLNode&
967 Session::get_template()
969 /* if we don't disable rec-enable, diskstreams
970 will believe they need to store their capture
971 sources in their state node.
974 disable_record (false);
976 return state(false);
979 XMLNode&
980 Session::state(bool full_state)
982 XMLNode* node = new XMLNode("Session");
983 XMLNode* child;
985 // store libardour version, just in case
986 char buf[16];
987 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
988 node->add_property("version", string(buf));
990 /* store configuration settings */
992 if (full_state) {
994 node->add_property ("name", _name);
995 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
996 node->add_property ("sample-rate", buf);
998 if (session_dirs.size() > 1) {
1000 string p;
1002 vector<space_and_path>::iterator i = session_dirs.begin();
1003 vector<space_and_path>::iterator next;
1005 ++i; /* skip the first one */
1006 next = i;
1007 ++next;
1009 while (i != session_dirs.end()) {
1011 p += (*i).path;
1013 if (next != session_dirs.end()) {
1014 p += ':';
1015 } else {
1016 break;
1019 ++next;
1020 ++i;
1023 child = node->add_child ("Path");
1024 child->add_content (p);
1028 /* save the ID counter */
1030 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1031 node->add_property ("id-counter", buf);
1033 /* various options */
1035 node->add_child_nocopy (config.get_variables ());
1037 node->add_child_nocopy (_metadata->get_state());
1039 child = node->add_child ("Sources");
1041 if (full_state) {
1042 Glib::Mutex::Lock sl (source_lock);
1044 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1046 /* Don't save information about non-destructive file sources that are empty
1047 and unused by any regions.
1050 boost::shared_ptr<FileSource> fs;
1051 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1052 if (!fs->destructive()) {
1053 if (fs->empty() && !fs->used()) {
1054 continue;
1059 child->add_child_nocopy (siter->second->get_state());
1063 child = node->add_child ("Regions");
1065 if (full_state) {
1066 Glib::Mutex::Lock rl (region_lock);
1067 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1068 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1069 boost::shared_ptr<Region> r = i->second;
1070 /* only store regions not attached to playlists */
1071 if (r->playlist() == 0) {
1072 child->add_child_nocopy (r->state (true));
1077 if (full_state) {
1078 node->add_child_nocopy (_locations.get_state());
1079 } else {
1080 // for a template, just create a new Locations, populate it
1081 // with the default start and end, and get the state for that.
1082 Locations loc;
1083 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1084 range->set (max_frames, 0);
1085 loc.add (range);
1086 node->add_child_nocopy (loc.get_state());
1089 child = node->add_child ("Bundles");
1091 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1092 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1093 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1094 if (b) {
1095 child->add_child_nocopy (b->get_state());
1100 child = node->add_child ("Routes");
1102 boost::shared_ptr<RouteList> r = routes.reader ();
1104 RoutePublicOrderSorter cmp;
1105 RouteList public_order (*r);
1106 public_order.sort (cmp);
1108 /* the sort should have put control outs first */
1110 if (_monitor_out) {
1111 assert (_monitor_out == public_order.front());
1114 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1115 if (!(*i)->is_hidden()) {
1116 if (full_state) {
1117 child->add_child_nocopy ((*i)->get_state());
1118 } else {
1119 child->add_child_nocopy ((*i)->get_template());
1125 playlists->add_state (node, full_state);
1127 child = node->add_child ("RouteGroups");
1128 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1129 child->add_child_nocopy ((*i)->get_state());
1132 if (_click_io) {
1133 child = node->add_child ("Click");
1134 child->add_child_nocopy (_click_io->state (full_state));
1137 if (full_state) {
1138 child = node->add_child ("NamedSelections");
1139 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1140 if (full_state) {
1141 child->add_child_nocopy ((*i)->get_state());
1146 node->add_child_nocopy (_tempo_map->get_state());
1148 node->add_child_nocopy (get_control_protocol_state());
1150 if (_extra_xml) {
1151 node->add_child_copy (*_extra_xml);
1154 return *node;
1157 XMLNode&
1158 Session::get_control_protocol_state ()
1160 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1161 return cpm.get_state();
1165 Session::set_state (const XMLNode& node, int version)
1167 XMLNodeList nlist;
1168 XMLNode* child;
1169 const XMLProperty* prop;
1170 int ret = -1;
1172 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1174 if (node.name() != X_("Session")){
1175 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1176 return -1;
1179 if ((prop = node.property ("version")) != 0) {
1180 version = atoi (prop->value ()) * 1000;
1183 if ((prop = node.property ("name")) != 0) {
1184 _name = prop->value ();
1187 if ((prop = node.property (X_("sample-rate"))) != 0) {
1189 _nominal_frame_rate = atoi (prop->value());
1191 if (_nominal_frame_rate != _current_frame_rate) {
1192 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1193 if (r.get_value_or (0)) {
1194 return -1;
1199 setup_raid_path(_session_dir->root_path().to_string());
1201 if ((prop = node.property (X_("id-counter"))) != 0) {
1202 uint64_t x;
1203 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1204 ID::init_counter (x);
1205 } else {
1206 /* old sessions used a timebased counter, so fake
1207 the startup ID counter based on a standard
1208 timestamp.
1210 time_t now;
1211 time (&now);
1212 ID::init_counter (now);
1216 IO::disable_connecting ();
1218 /* Object loading order:
1220 Path
1221 Extra
1222 Options/Config
1223 MIDI Control // relies on data from Options/Config
1224 Metadata
1225 Locations
1226 Sources
1227 AudioRegions
1228 Connections
1229 Routes
1230 RouteGroups
1231 MixGroups
1232 Click
1233 ControlProtocols
1236 if ((child = find_named_node (node, "Extra")) != 0) {
1237 _extra_xml = new XMLNode (*child);
1240 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1241 load_options (*child);
1242 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1243 load_options (*child);
1244 } else {
1245 error << _("Session: XML state has no options section") << endmsg;
1248 setup_midi_machine_control ();
1250 if (use_config_midi_ports ()) {
1253 if (version >= 3000) {
1254 if ((child = find_named_node (node, "Metadata")) == 0) {
1255 warning << _("Session: XML state has no metadata section") << endmsg;
1256 } else if (_metadata->set_state (*child, version)) {
1257 goto out;
1261 if ((child = find_named_node (node, "Locations")) == 0) {
1262 error << _("Session: XML state has no locations section") << endmsg;
1263 goto out;
1264 } else if (_locations.set_state (*child, version)) {
1265 goto out;
1268 Location* location;
1270 if ((location = _locations.auto_loop_location()) != 0) {
1271 set_auto_loop_location (location);
1274 if ((location = _locations.auto_punch_location()) != 0) {
1275 set_auto_punch_location (location);
1278 if ((location = _locations.session_range_location()) != 0) {
1279 delete _session_range_location;
1280 _session_range_location = location;
1283 if (_session_range_location) {
1284 AudioFileSource::set_header_position_offset (_session_range_location->start());
1287 if ((child = find_named_node (node, "Sources")) == 0) {
1288 error << _("Session: XML state has no sources section") << endmsg;
1289 goto out;
1290 } else if (load_sources (*child)) {
1291 goto out;
1294 if ((child = find_named_node (node, "Regions")) == 0) {
1295 error << _("Session: XML state has no Regions section") << endmsg;
1296 goto out;
1297 } else if (load_regions (*child)) {
1298 goto out;
1301 if ((child = find_named_node (node, "Playlists")) == 0) {
1302 error << _("Session: XML state has no playlists section") << endmsg;
1303 goto out;
1304 } else if (playlists->load (*this, *child)) {
1305 goto out;
1308 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1309 // this is OK
1310 } else if (playlists->load_unused (*this, *child)) {
1311 goto out;
1314 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1315 if (load_named_selections (*child)) {
1316 goto out;
1320 if (version >= 3000) {
1321 if ((child = find_named_node (node, "Bundles")) == 0) {
1322 warning << _("Session: XML state has no bundles section") << endmsg;
1323 //goto out;
1324 } else {
1325 /* We can't load Bundles yet as they need to be able
1326 to convert from port names to Port objects, which can't happen until
1327 later */
1328 _bundle_xml_node = new XMLNode (*child);
1332 if ((child = find_named_node (node, "TempoMap")) == 0) {
1333 error << _("Session: XML state has no Tempo Map section") << endmsg;
1334 goto out;
1335 } else if (_tempo_map->set_state (*child, version)) {
1336 goto out;
1339 if (version < 3000) {
1340 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1341 error << _("Session: XML state has no diskstreams section") << endmsg;
1342 goto out;
1343 } else if (load_diskstreams_2X (*child, version)) {
1344 goto out;
1348 if ((child = find_named_node (node, "Routes")) == 0) {
1349 error << _("Session: XML state has no routes section") << endmsg;
1350 goto out;
1351 } else if (load_routes (*child, version)) {
1352 goto out;
1355 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1356 _diskstreams_2X.clear ();
1358 if (version >= 3000) {
1360 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1361 error << _("Session: XML state has no route groups section") << endmsg;
1362 goto out;
1363 } else if (load_route_groups (*child, version)) {
1364 goto out;
1367 } else if (version < 3000) {
1369 if ((child = find_named_node (node, "EditGroups")) == 0) {
1370 error << _("Session: XML state has no edit groups section") << endmsg;
1371 goto out;
1372 } else if (load_route_groups (*child, version)) {
1373 goto out;
1376 if ((child = find_named_node (node, "MixGroups")) == 0) {
1377 error << _("Session: XML state has no mix groups section") << endmsg;
1378 goto out;
1379 } else if (load_route_groups (*child, version)) {
1380 goto out;
1384 if ((child = find_named_node (node, "Click")) == 0) {
1385 warning << _("Session: XML state has no click section") << endmsg;
1386 } else if (_click_io) {
1387 _click_io->set_state (*child, version);
1390 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1391 ControlProtocolManager::instance().set_protocol_states (*child);
1394 /* here beginneth the second phase ... */
1396 StateReady (); /* EMIT SIGNAL */
1398 return 0;
1400 out:
1401 return ret;
1405 Session::load_routes (const XMLNode& node, int version)
1407 XMLNodeList nlist;
1408 XMLNodeConstIterator niter;
1409 RouteList new_routes;
1411 nlist = node.children();
1413 set_dirty();
1415 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1417 boost::shared_ptr<Route> route;
1418 if (version < 3000) {
1419 route = XMLRouteFactory_2X (**niter, version);
1420 } else {
1421 route = XMLRouteFactory (**niter, version);
1424 if (route == 0) {
1425 error << _("Session: cannot create Route from XML description.") << endmsg;
1426 return -1;
1429 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1431 new_routes.push_back (route);
1434 add_routes (new_routes, false);
1436 return 0;
1439 boost::shared_ptr<Route>
1440 Session::XMLRouteFactory (const XMLNode& node, int version)
1442 boost::shared_ptr<Route> ret;
1444 if (node.name() != "Route") {
1445 return ret;
1448 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1450 DataType type = DataType::AUDIO;
1451 const XMLProperty* prop = node.property("default-type");
1453 if (prop) {
1454 type = DataType (prop->value());
1457 assert (type != DataType::NIL);
1459 if (ds_child) {
1461 Track* track;
1463 if (type == DataType::AUDIO) {
1464 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1466 } else {
1467 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1470 if (track->init()) {
1471 delete track;
1472 return ret;
1475 if (track->set_state (node, version)) {
1476 delete track;
1477 return ret;
1480 boost_debug_shared_ptr_mark_interesting (track, "Track");
1481 ret.reset (track);
1483 } else {
1484 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1486 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1487 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1488 ret.reset (rt);
1489 } else {
1490 delete rt;
1494 return ret;
1497 boost::shared_ptr<Route>
1498 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1500 boost::shared_ptr<Route> ret;
1502 if (node.name() != "Route") {
1503 return ret;
1506 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1507 if (!ds_prop) {
1508 ds_prop = node.property (X_("diskstream"));
1511 DataType type = DataType::AUDIO;
1512 const XMLProperty* prop = node.property("default-type");
1514 if (prop) {
1515 type = DataType (prop->value());
1518 assert (type != DataType::NIL);
1520 if (ds_prop) {
1522 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1523 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1524 ++i;
1527 if (i == _diskstreams_2X.end()) {
1528 error << _("Could not find diskstream for route") << endmsg;
1529 return boost::shared_ptr<Route> ();
1532 Track* track;
1534 if (type == DataType::AUDIO) {
1535 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1537 } else {
1538 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1541 if (track->init()) {
1542 delete track;
1543 return ret;
1546 if (track->set_state (node, version)) {
1547 delete track;
1548 return ret;
1551 track->set_diskstream (*i);
1553 boost_debug_shared_ptr_mark_interesting (track, "Track");
1554 ret.reset (track);
1556 } else {
1557 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1559 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1560 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1561 ret.reset (rt);
1562 } else {
1563 delete rt;
1567 return ret;
1571 Session::load_regions (const XMLNode& node)
1573 XMLNodeList nlist;
1574 XMLNodeConstIterator niter;
1575 boost::shared_ptr<Region> region;
1577 nlist = node.children();
1579 set_dirty();
1581 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1582 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1583 error << _("Session: cannot create Region from XML description.");
1584 const XMLProperty *name = (**niter).property("name");
1586 if (name) {
1587 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1590 error << endmsg;
1594 return 0;
1597 boost::shared_ptr<Region>
1598 Session::XMLRegionFactory (const XMLNode& node, bool full)
1600 const XMLProperty* type = node.property("type");
1602 try {
1604 if ( !type || type->value() == "audio" ) {
1606 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1608 } else if (type->value() == "midi") {
1610 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1614 } catch (failed_constructor& err) {
1615 return boost::shared_ptr<Region> ();
1618 return boost::shared_ptr<Region> ();
1621 boost::shared_ptr<AudioRegion>
1622 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1624 const XMLProperty* prop;
1625 boost::shared_ptr<Source> source;
1626 boost::shared_ptr<AudioSource> as;
1627 SourceList sources;
1628 SourceList master_sources;
1629 uint32_t nchans = 1;
1630 char buf[128];
1632 if (node.name() != X_("Region")) {
1633 return boost::shared_ptr<AudioRegion>();
1636 if ((prop = node.property (X_("channels"))) != 0) {
1637 nchans = atoi (prop->value().c_str());
1640 if ((prop = node.property ("name")) == 0) {
1641 cerr << "no name for this region\n";
1642 abort ();
1645 if ((prop = node.property (X_("source-0"))) == 0) {
1646 if ((prop = node.property ("source")) == 0) {
1647 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1648 return boost::shared_ptr<AudioRegion>();
1652 PBD::ID s_id (prop->value());
1654 if ((source = source_by_id (s_id)) == 0) {
1655 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1656 return boost::shared_ptr<AudioRegion>();
1659 as = boost::dynamic_pointer_cast<AudioSource>(source);
1660 if (!as) {
1661 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1662 return boost::shared_ptr<AudioRegion>();
1665 sources.push_back (as);
1667 /* pickup other channels */
1669 for (uint32_t n=1; n < nchans; ++n) {
1670 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1671 if ((prop = node.property (buf)) != 0) {
1673 PBD::ID id2 (prop->value());
1675 if ((source = source_by_id (id2)) == 0) {
1676 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1677 return boost::shared_ptr<AudioRegion>();
1680 as = boost::dynamic_pointer_cast<AudioSource>(source);
1681 if (!as) {
1682 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1683 return boost::shared_ptr<AudioRegion>();
1685 sources.push_back (as);
1689 for (uint32_t n = 0; n < nchans; ++n) {
1690 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1691 if ((prop = node.property (buf)) != 0) {
1693 PBD::ID id2 (prop->value());
1695 if ((source = source_by_id (id2)) == 0) {
1696 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1697 return boost::shared_ptr<AudioRegion>();
1700 as = boost::dynamic_pointer_cast<AudioSource>(source);
1701 if (!as) {
1702 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1703 return boost::shared_ptr<AudioRegion>();
1705 master_sources.push_back (as);
1709 try {
1710 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1712 /* a final detail: this is the one and only place that we know how long missing files are */
1714 if (region->whole_file()) {
1715 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1716 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1717 if (sfp) {
1718 sfp->set_length (region->length());
1723 if (!master_sources.empty()) {
1724 if (master_sources.size() != nchans) {
1725 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1726 } else {
1727 region->set_master_sources (master_sources);
1731 return region;
1735 catch (failed_constructor& err) {
1736 return boost::shared_ptr<AudioRegion>();
1740 boost::shared_ptr<MidiRegion>
1741 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1743 const XMLProperty* prop;
1744 boost::shared_ptr<Source> source;
1745 boost::shared_ptr<MidiSource> ms;
1746 SourceList sources;
1747 uint32_t nchans = 1;
1749 if (node.name() != X_("Region")) {
1750 return boost::shared_ptr<MidiRegion>();
1753 if ((prop = node.property (X_("channels"))) != 0) {
1754 nchans = atoi (prop->value().c_str());
1757 if ((prop = node.property ("name")) == 0) {
1758 cerr << "no name for this region\n";
1759 abort ();
1762 // Multiple midi channels? that's just crazy talk
1763 assert(nchans == 1);
1765 if ((prop = node.property (X_("source-0"))) == 0) {
1766 if ((prop = node.property ("source")) == 0) {
1767 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1768 return boost::shared_ptr<MidiRegion>();
1772 PBD::ID s_id (prop->value());
1774 if ((source = source_by_id (s_id)) == 0) {
1775 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1776 return boost::shared_ptr<MidiRegion>();
1779 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1780 if (!ms) {
1781 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1782 return boost::shared_ptr<MidiRegion>();
1785 sources.push_back (ms);
1787 try {
1788 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1789 /* a final detail: this is the one and only place that we know how long missing files are */
1791 if (region->whole_file()) {
1792 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1793 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1794 if (sfp) {
1795 sfp->set_length (region->length());
1800 return region;
1803 catch (failed_constructor& err) {
1804 return boost::shared_ptr<MidiRegion>();
1808 XMLNode&
1809 Session::get_sources_as_xml ()
1812 XMLNode* node = new XMLNode (X_("Sources"));
1813 Glib::Mutex::Lock lm (source_lock);
1815 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1816 node->add_child_nocopy (i->second->get_state());
1819 return *node;
1822 string
1823 Session::path_from_region_name (DataType type, string name, string identifier)
1825 char buf[PATH_MAX+1];
1826 uint32_t n;
1827 SessionDirectory sdir(get_best_session_directory_for_new_source());
1828 sys::path source_dir = ((type == DataType::AUDIO)
1829 ? sdir.sound_path() : sdir.midi_path());
1831 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1833 for (n = 0; n < 999999; ++n) {
1834 if (identifier.length()) {
1835 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1836 identifier.c_str(), n, ext.c_str());
1837 } else {
1838 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1839 n, ext.c_str());
1842 sys::path source_path = source_dir / buf;
1844 if (!sys::exists (source_path)) {
1845 return source_path.to_string();
1849 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1850 name, identifier)
1851 << endmsg;
1853 return "";
1858 Session::load_sources (const XMLNode& node)
1860 XMLNodeList nlist;
1861 XMLNodeConstIterator niter;
1862 boost::shared_ptr<Source> source;
1864 nlist = node.children();
1866 set_dirty();
1868 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1869 try {
1870 if ((source = XMLSourceFactory (**niter)) == 0) {
1871 error << _("Session: cannot create Source from XML description.") << endmsg;
1873 } catch (MissingSource& err) {
1874 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1875 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1879 return 0;
1882 boost::shared_ptr<Source>
1883 Session::XMLSourceFactory (const XMLNode& node)
1885 if (node.name() != "Source") {
1886 return boost::shared_ptr<Source>();
1889 try {
1890 /* note: do peak building in another thread when loading session state */
1891 return SourceFactory::create (*this, node, true);
1894 catch (failed_constructor& err) {
1895 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1896 return boost::shared_ptr<Source>();
1901 Session::save_template (string template_name)
1903 XMLTree tree;
1905 if (_state_of_the_state & CannotSave) {
1906 return -1;
1909 sys::path user_template_dir(user_template_directory());
1913 sys::create_directories (user_template_dir);
1915 catch(sys::filesystem_error& ex)
1917 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1918 user_template_dir.to_string(), ex.what()) << endmsg;
1919 return -1;
1922 tree.set_root (&get_template());
1924 sys::path template_file_path(user_template_dir);
1925 template_file_path /= template_name + template_suffix;
1927 if (sys::exists (template_file_path))
1929 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1930 template_file_path.to_string()) << endmsg;
1931 return -1;
1934 if (!tree.write (template_file_path.to_string())) {
1935 error << _("mix template not saved") << endmsg;
1936 return -1;
1939 return 0;
1943 Session::rename_template (string old_name, string new_name)
1945 sys::path old_path (user_template_directory());
1946 old_path /= old_name + template_suffix;
1948 sys::path new_path(user_template_directory());
1949 new_path /= new_name + template_suffix;
1951 if (sys::exists (new_path)) {
1952 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1953 new_path.to_string()) << endmsg;
1954 return -1;
1957 try {
1958 sys::rename (old_path, new_path);
1959 return 0;
1960 } catch (...) {
1961 return -1;
1966 Session::delete_template (string name)
1968 sys::path path = user_template_directory();
1969 path /= name + template_suffix;
1971 try {
1972 sys::remove (path);
1973 return 0;
1974 } catch (...) {
1975 return -1;
1979 void
1980 Session::refresh_disk_space ()
1982 #if HAVE_SYS_VFS_H
1983 struct statfs statfsbuf;
1984 vector<space_and_path>::iterator i;
1985 Glib::Mutex::Lock lm (space_lock);
1986 double scale;
1988 /* get freespace on every FS that is part of the session path */
1990 _total_free_4k_blocks = 0;
1992 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1993 statfs ((*i).path.c_str(), &statfsbuf);
1995 scale = statfsbuf.f_bsize/4096.0;
1997 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1998 _total_free_4k_blocks += (*i).blocks;
2000 #endif
2003 string
2004 Session::get_best_session_directory_for_new_source ()
2006 vector<space_and_path>::iterator i;
2007 string result = _session_dir->root_path().to_string();
2009 /* handle common case without system calls */
2011 if (session_dirs.size() == 1) {
2012 return result;
2015 /* OK, here's the algorithm we're following here:
2017 We want to select which directory to use for
2018 the next file source to be created. Ideally,
2019 we'd like to use a round-robin process so as to
2020 get maximum performance benefits from splitting
2021 the files across multiple disks.
2023 However, in situations without much diskspace, an
2024 RR approach may end up filling up a filesystem
2025 with new files while others still have space.
2026 Its therefore important to pay some attention to
2027 the freespace in the filesystem holding each
2028 directory as well. However, if we did that by
2029 itself, we'd keep creating new files in the file
2030 system with the most space until it was as full
2031 as all others, thus negating any performance
2032 benefits of this RAID-1 like approach.
2034 So, we use a user-configurable space threshold. If
2035 there are at least 2 filesystems with more than this
2036 much space available, we use RR selection between them.
2037 If not, then we pick the filesystem with the most space.
2039 This gets a good balance between the two
2040 approaches.
2043 refresh_disk_space ();
2045 int free_enough = 0;
2047 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2048 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2049 free_enough++;
2053 if (free_enough >= 2) {
2054 /* use RR selection process, ensuring that the one
2055 picked works OK.
2058 i = last_rr_session_dir;
2060 do {
2061 if (++i == session_dirs.end()) {
2062 i = session_dirs.begin();
2065 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2066 if (create_session_directory ((*i).path)) {
2067 result = (*i).path;
2068 last_rr_session_dir = i;
2069 return result;
2073 } while (i != last_rr_session_dir);
2075 } else {
2077 /* pick FS with the most freespace (and that
2078 seems to actually work ...)
2081 vector<space_and_path> sorted;
2082 space_and_path_ascending_cmp cmp;
2084 sorted = session_dirs;
2085 sort (sorted.begin(), sorted.end(), cmp);
2087 for (i = sorted.begin(); i != sorted.end(); ++i) {
2088 if (create_session_directory ((*i).path)) {
2089 result = (*i).path;
2090 last_rr_session_dir = i;
2091 return result;
2096 return result;
2100 Session::load_named_selections (const XMLNode& node)
2102 XMLNodeList nlist;
2103 XMLNodeConstIterator niter;
2104 NamedSelection *ns;
2106 nlist = node.children();
2108 set_dirty();
2110 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2112 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2113 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2117 return 0;
2120 NamedSelection *
2121 Session::XMLNamedSelectionFactory (const XMLNode& node)
2123 try {
2124 return new NamedSelection (*this, node);
2127 catch (failed_constructor& err) {
2128 return 0;
2132 string
2133 Session::automation_dir () const
2135 return Glib::build_filename (_path, "automation");
2138 string
2139 Session::analysis_dir () const
2141 return Glib::build_filename (_path, "analysis");
2145 Session::load_bundles (XMLNode const & node)
2147 XMLNodeList nlist = node.children();
2148 XMLNodeConstIterator niter;
2150 set_dirty();
2152 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2153 if ((*niter)->name() == "InputBundle") {
2154 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2155 } else if ((*niter)->name() == "OutputBundle") {
2156 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2157 } else {
2158 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2159 return -1;
2163 return 0;
2167 Session::load_route_groups (const XMLNode& node, int version)
2169 XMLNodeList nlist = node.children();
2170 XMLNodeConstIterator niter;
2172 set_dirty ();
2174 if (version >= 3000) {
2176 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2177 if ((*niter)->name() == "RouteGroup") {
2178 RouteGroup* rg = new RouteGroup (*this, "");
2179 add_route_group (rg);
2180 rg->set_state (**niter, version);
2184 } else if (version < 3000) {
2186 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2187 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2188 RouteGroup* rg = new RouteGroup (*this, "");
2189 add_route_group (rg);
2190 rg->set_state (**niter, version);
2195 return 0;
2198 void
2199 Session::auto_save()
2201 save_state (_current_snapshot_name);
2204 static bool
2205 state_file_filter (const string &str, void */*arg*/)
2207 return (str.length() > strlen(statefile_suffix) &&
2208 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2211 struct string_cmp {
2212 bool operator()(const string* a, const string* b) {
2213 return *a < *b;
2217 static string*
2218 remove_end(string* state)
2220 string statename(*state);
2222 string::size_type start,end;
2223 if ((start = statename.find_last_of ('/')) != string::npos) {
2224 statename = statename.substr (start+1);
2227 if ((end = statename.rfind(".ardour")) == string::npos) {
2228 end = statename.length();
2231 return new string(statename.substr (0, end));
2234 vector<string *> *
2235 Session::possible_states (string path)
2237 PathScanner scanner;
2238 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2240 transform(states->begin(), states->end(), states->begin(), remove_end);
2242 string_cmp cmp;
2243 sort (states->begin(), states->end(), cmp);
2245 return states;
2248 vector<string *> *
2249 Session::possible_states () const
2251 return possible_states(_path);
2254 void
2255 Session::add_route_group (RouteGroup* g)
2257 _route_groups.push_back (g);
2258 route_group_added (g); /* EMIT SIGNAL */
2259 set_dirty ();
2262 void
2263 Session::remove_route_group (RouteGroup& rg)
2265 list<RouteGroup*>::iterator i;
2267 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2268 _route_groups.erase (i);
2269 delete &rg;
2271 route_group_removed (); /* EMIT SIGNAL */
2276 RouteGroup *
2277 Session::route_group_by_name (string name)
2279 list<RouteGroup *>::iterator i;
2281 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2282 if ((*i)->name() == name) {
2283 return* i;
2286 return 0;
2289 UndoTransaction*
2290 Session::start_reversible_command (const string& name)
2292 UndoTransaction* trans = new UndoTransaction();
2293 trans->set_name(name);
2294 return trans;
2297 void
2298 Session::finish_reversible_command (UndoTransaction& ut)
2300 struct timeval now;
2301 gettimeofday(&now, 0);
2302 ut.set_timestamp(now);
2303 _history.add (&ut);
2306 void
2307 Session::begin_reversible_command(const string& name)
2309 UndoTransaction* trans = new UndoTransaction();
2310 trans->set_name(name);
2312 if (!_current_trans.empty()) {
2313 _current_trans.top()->add_command (trans);
2314 } else {
2315 _current_trans.push(trans);
2319 void
2320 Session::commit_reversible_command(Command *cmd)
2322 assert(!_current_trans.empty());
2323 struct timeval now;
2325 if (cmd) {
2326 _current_trans.top()->add_command(cmd);
2329 if (_current_trans.top()->empty()) {
2330 _current_trans.pop();
2331 return;
2334 gettimeofday(&now, 0);
2335 _current_trans.top()->set_timestamp(now);
2337 _history.add(_current_trans.top());
2338 _current_trans.pop();
2341 static bool
2342 accept_all_non_peak_files (const string& path, void */*arg*/)
2344 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2347 static bool
2348 accept_all_state_files (const string& path, void */*arg*/)
2350 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2354 Session::find_all_sources (string path, set<string>& result)
2356 XMLTree tree;
2357 XMLNode* node;
2359 if (!tree.read (path)) {
2360 return -1;
2363 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2364 return -2;
2367 XMLNodeList nlist;
2368 XMLNodeConstIterator niter;
2370 nlist = node->children();
2372 set_dirty();
2374 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2376 XMLProperty* prop;
2378 if ((prop = (*niter)->property (X_("type"))) == 0) {
2379 continue;
2382 DataType type (prop->value());
2384 if ((prop = (*niter)->property (X_("name"))) == 0) {
2385 continue;
2388 if (prop->value()[0] == '/') {
2389 /* external file, ignore */
2390 continue;
2393 Glib::ustring found_path;
2394 bool is_new;
2395 uint16_t chan;
2397 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2398 result.insert (found_path);
2402 return 0;
2406 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2408 PathScanner scanner;
2409 vector<string*>* state_files;
2410 string ripped;
2411 string this_snapshot_path;
2413 result.clear ();
2415 ripped = _path;
2417 if (ripped[ripped.length()-1] == '/') {
2418 ripped = ripped.substr (0, ripped.length() - 1);
2421 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2423 if (state_files == 0) {
2424 /* impossible! */
2425 return 0;
2428 this_snapshot_path = _path;
2429 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2430 this_snapshot_path += statefile_suffix;
2432 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2434 if (exclude_this_snapshot && **i == this_snapshot_path) {
2435 continue;
2438 if (find_all_sources (**i, result) < 0) {
2439 return -1;
2443 return 0;
2446 struct RegionCounter {
2447 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2448 AudioSourceList::iterator iter;
2449 boost::shared_ptr<Region> region;
2450 uint32_t count;
2452 RegionCounter() : count (0) {}
2456 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2458 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2459 return r.get_value_or (1);
2463 Session::cleanup_sources (CleanupReport& rep)
2465 // FIXME: needs adaptation to midi
2467 vector<boost::shared_ptr<Source> > dead_sources;
2468 PathScanner scanner;
2469 string sound_path;
2470 vector<space_and_path>::iterator i;
2471 vector<space_and_path>::iterator nexti;
2472 vector<string*>* soundfiles;
2473 vector<string> unused;
2474 set<string> all_sources;
2475 bool used;
2476 string spath;
2477 int ret = -1;
2479 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2481 /* step 1: consider deleting all unused playlists */
2483 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2484 ret = 0;
2485 goto out;
2488 /* step 2: find all un-used sources */
2490 rep.paths.clear ();
2491 rep.space = 0;
2493 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2495 SourceMap::iterator tmp;
2497 tmp = i;
2498 ++tmp;
2500 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2501 capture files.
2504 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2505 dead_sources.push_back (i->second);
2506 i->second->drop_references ();
2509 i = tmp;
2512 /* build a list of all the possible sound directories for the session */
2514 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2516 nexti = i;
2517 ++nexti;
2519 SessionDirectory sdir ((*i).path);
2520 sound_path += sdir.sound_path().to_string();
2522 if (nexti != session_dirs.end()) {
2523 sound_path += ':';
2526 i = nexti;
2529 /* now do the same thing for the files that ended up in the sounds dir(s)
2530 but are not referenced as sources in any snapshot.
2533 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2535 if (soundfiles == 0) {
2536 return 0;
2539 /* find all sources, but don't use this snapshot because the
2540 state file on disk still references sources we may have already
2541 dropped.
2544 find_all_sources_across_snapshots (all_sources, true);
2546 /* add our current source list
2549 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2550 boost::shared_ptr<FileSource> fs;
2552 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2553 all_sources.insert (fs->path());
2557 char tmppath1[PATH_MAX+1];
2558 char tmppath2[PATH_MAX+1];
2560 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2562 used = false;
2563 spath = **x;
2565 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2567 if (realpath(spath.c_str(), tmppath1) == 0) {
2568 error << string_compose (_("Cannot expand path %1 (%2)"),
2569 spath, strerror (errno)) << endmsg;
2570 continue;
2573 if (realpath((*i).c_str(), tmppath2) == 0) {
2574 error << string_compose (_("Cannot expand path %1 (%2)"),
2575 (*i), strerror (errno)) << endmsg;
2576 continue;
2579 if (strcmp(tmppath1, tmppath2) == 0) {
2580 used = true;
2581 break;
2585 if (!used) {
2586 unused.push_back (spath);
2590 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2592 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2593 struct stat statbuf;
2595 rep.paths.push_back (*x);
2596 if (stat ((*x).c_str(), &statbuf) == 0) {
2597 rep.space += statbuf.st_size;
2600 string newpath;
2602 /* don't move the file across filesystems, just
2603 stick it in the `dead_sound_dir_name' directory
2604 on whichever filesystem it was already on.
2607 if ((*x).find ("/sounds/") != string::npos) {
2609 /* old school, go up 1 level */
2611 newpath = Glib::path_get_dirname (*x); // "sounds"
2612 newpath = Glib::path_get_dirname (newpath); // "session-name"
2614 } else {
2616 /* new school, go up 4 levels */
2618 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2619 newpath = Glib::path_get_dirname (newpath); // "session-name"
2620 newpath = Glib::path_get_dirname (newpath); // "interchange"
2621 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2624 newpath += '/';
2625 newpath += dead_sound_dir_name;
2627 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2628 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2629 return -1;
2632 newpath += '/';
2633 newpath += Glib::path_get_basename ((*x));
2635 if (access (newpath.c_str(), F_OK) == 0) {
2637 /* the new path already exists, try versioning */
2639 char buf[PATH_MAX+1];
2640 int version = 1;
2641 string newpath_v;
2643 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2644 newpath_v = buf;
2646 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2647 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2648 newpath_v = buf;
2651 if (version == 999) {
2652 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2653 newpath)
2654 << endmsg;
2655 } else {
2656 newpath = newpath_v;
2659 } else {
2661 /* it doesn't exist, or we can't read it or something */
2665 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2666 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2667 (*x), newpath, strerror (errno))
2668 << endmsg;
2669 goto out;
2672 /* see if there an easy to find peakfile for this file, and remove it.
2675 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2676 peakpath += peakfile_suffix;
2678 if (access (peakpath.c_str(), W_OK) == 0) {
2679 if (::unlink (peakpath.c_str()) != 0) {
2680 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2681 peakpath, _path, strerror (errno))
2682 << endmsg;
2683 /* try to back out */
2684 rename (newpath.c_str(), _path.c_str());
2685 goto out;
2690 ret = 0;
2692 /* dump the history list */
2694 _history.clear ();
2696 /* save state so we don't end up a session file
2697 referring to non-existent sources.
2700 save_state ("");
2702 out:
2703 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2705 return ret;
2709 Session::cleanup_trash_sources (CleanupReport& rep)
2711 // FIXME: needs adaptation for MIDI
2713 vector<space_and_path>::iterator i;
2714 string dead_sound_dir;
2715 struct dirent* dentry;
2716 struct stat statbuf;
2717 DIR* dead;
2719 rep.paths.clear ();
2720 rep.space = 0;
2722 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2724 dead_sound_dir = (*i).path;
2725 dead_sound_dir += dead_sound_dir_name;
2727 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2728 continue;
2731 while ((dentry = readdir (dead)) != 0) {
2733 /* avoid '.' and '..' */
2735 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2736 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2737 continue;
2740 string fullpath;
2742 fullpath = dead_sound_dir;
2743 fullpath += '/';
2744 fullpath += dentry->d_name;
2746 if (stat (fullpath.c_str(), &statbuf)) {
2747 continue;
2750 if (!S_ISREG (statbuf.st_mode)) {
2751 continue;
2754 if (unlink (fullpath.c_str())) {
2755 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2756 fullpath, strerror (errno))
2757 << endmsg;
2760 rep.paths.push_back (dentry->d_name);
2761 rep.space += statbuf.st_size;
2764 closedir (dead);
2768 return 0;
2771 void
2772 Session::set_dirty ()
2774 bool was_dirty = dirty();
2776 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2779 if (!was_dirty) {
2780 DirtyChanged(); /* EMIT SIGNAL */
2785 void
2786 Session::set_clean ()
2788 bool was_dirty = dirty();
2790 _state_of_the_state = Clean;
2793 if (was_dirty) {
2794 DirtyChanged(); /* EMIT SIGNAL */
2798 void
2799 Session::set_deletion_in_progress ()
2801 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2804 void
2805 Session::clear_deletion_in_progress ()
2807 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2810 void
2811 Session::add_controllable (boost::shared_ptr<Controllable> c)
2813 /* this adds a controllable to the list managed by the Session.
2814 this is a subset of those managed by the Controllable class
2815 itself, and represents the only ones whose state will be saved
2816 as part of the session.
2819 Glib::Mutex::Lock lm (controllables_lock);
2820 controllables.insert (c);
2823 struct null_deleter { void operator()(void const *) const {} };
2825 void
2826 Session::remove_controllable (Controllable* c)
2828 if (_state_of_the_state | Deletion) {
2829 return;
2832 Glib::Mutex::Lock lm (controllables_lock);
2834 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2836 if (x != controllables.end()) {
2837 controllables.erase (x);
2841 boost::shared_ptr<Controllable>
2842 Session::controllable_by_id (const PBD::ID& id)
2844 Glib::Mutex::Lock lm (controllables_lock);
2846 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2847 if ((*i)->id() == id) {
2848 return *i;
2852 return boost::shared_ptr<Controllable>();
2855 boost::shared_ptr<Controllable>
2856 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2858 boost::shared_ptr<Controllable> c;
2859 boost::shared_ptr<Route> r;
2861 switch (desc.top_level_type()) {
2862 case ControllableDescriptor::NamedRoute:
2864 std::string str = desc.top_level_name();
2865 if (str == "master") {
2866 r = _master_out;
2867 } else if (str == "control" || str == "listen") {
2868 r = _monitor_out;
2869 } else {
2870 r = route_by_name (desc.top_level_name());
2872 break;
2875 case ControllableDescriptor::RemoteControlID:
2876 r = route_by_remote_id (desc.rid());
2877 break;
2880 if (!r) {
2881 return c;
2884 switch (desc.subtype()) {
2885 case ControllableDescriptor::Gain:
2886 c = r->gain_control ();
2887 break;
2889 case ControllableDescriptor::Solo:
2890 c = r->solo_control();
2891 break;
2893 case ControllableDescriptor::Mute:
2894 c = r->mute_control();
2895 break;
2897 case ControllableDescriptor::Recenable:
2899 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2901 if (t) {
2902 c = t->rec_enable_control ();
2904 break;
2907 case ControllableDescriptor::Pan:
2908 /* XXX pan control */
2909 break;
2911 case ControllableDescriptor::Balance:
2912 /* XXX simple pan control */
2913 break;
2915 case ControllableDescriptor::PluginParameter:
2917 uint32_t plugin = desc.target (0);
2918 uint32_t parameter_index = desc.target (1);
2920 /* revert to zero based counting */
2922 if (plugin > 0) {
2923 --plugin;
2926 if (parameter_index > 0) {
2927 --parameter_index;
2930 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2932 if (p) {
2933 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2934 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2936 break;
2939 case ControllableDescriptor::SendGain:
2941 uint32_t send = desc.target (0);
2943 /* revert to zero-based counting */
2945 if (send > 0) {
2946 --send;
2949 boost::shared_ptr<Processor> p = r->nth_send (send);
2951 if (p) {
2952 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2953 boost::shared_ptr<Amp> a = s->amp();
2955 if (a) {
2956 c = s->amp()->gain_control();
2959 break;
2962 default:
2963 /* relax and return a null pointer */
2964 break;
2967 return c;
2970 void
2971 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2973 if (_writable) {
2974 Stateful::add_instant_xml (node, _path);
2977 if (write_to_config) {
2978 Config->add_instant_xml (node);
2982 XMLNode*
2983 Session::instant_xml (const string& node_name)
2985 return Stateful::instant_xml (node_name, _path);
2989 Session::save_history (string snapshot_name)
2991 XMLTree tree;
2993 if (!_writable) {
2994 return 0;
2997 if (snapshot_name.empty()) {
2998 snapshot_name = _current_snapshot_name;
3001 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3002 const string backup_filename = history_filename + backup_suffix;
3003 const sys::path xml_path = _session_dir->root_path() / history_filename;
3004 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3006 if (sys::exists (xml_path)) {
3009 sys::rename (xml_path, backup_path);
3011 catch (const sys::filesystem_error& err)
3013 error << _("could not backup old history file, current history not saved") << endmsg;
3014 return -1;
3018 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3019 return 0;
3022 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3024 if (!tree.write (xml_path.to_string()))
3026 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3030 sys::remove (xml_path);
3031 sys::rename (backup_path, xml_path);
3033 catch (const sys::filesystem_error& err)
3035 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3036 backup_path.to_string(), err.what()) << endmsg;
3039 return -1;
3042 return 0;
3046 Session::restore_history (string snapshot_name)
3048 XMLTree tree;
3050 if (snapshot_name.empty()) {
3051 snapshot_name = _current_snapshot_name;
3054 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3055 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3057 info << "Loading history from " << xml_path.to_string() << endmsg;
3059 if (!sys::exists (xml_path)) {
3060 info << string_compose (_("%1: no history file \"%2\" for this session."),
3061 _name, xml_path.to_string()) << endmsg;
3062 return 1;
3065 if (!tree.read (xml_path.to_string())) {
3066 error << string_compose (_("Could not understand session history file \"%1\""),
3067 xml_path.to_string()) << endmsg;
3068 return -1;
3071 // replace history
3072 _history.clear();
3074 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3076 XMLNode *t = *it;
3077 UndoTransaction* ut = new UndoTransaction ();
3078 struct timeval tv;
3080 ut->set_name(t->property("name")->value());
3081 stringstream ss(t->property("tv-sec")->value());
3082 ss >> tv.tv_sec;
3083 ss.str(t->property("tv-usec")->value());
3084 ss >> tv.tv_usec;
3085 ut->set_timestamp(tv);
3087 for (XMLNodeConstIterator child_it = t->children().begin();
3088 child_it != t->children().end(); child_it++)
3090 XMLNode *n = *child_it;
3091 Command *c;
3093 if (n->name() == "MementoCommand" ||
3094 n->name() == "MementoUndoCommand" ||
3095 n->name() == "MementoRedoCommand") {
3097 if ((c = memento_command_factory(n))) {
3098 ut->add_command(c);
3101 } else if (n->name() == "DiffCommand") {
3102 PBD::ID id(n->property("midi-source")->value());
3103 boost::shared_ptr<MidiSource> midi_source =
3104 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3105 if (midi_source) {
3106 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3107 } else {
3108 error << _("Failed to downcast MidiSource for DiffCommand") << endmsg;
3111 } else if (n->name() == "StatefulDiffCommand") {
3112 if ((c = stateful_diff_command_factory (n))) {
3113 ut->add_command (c);
3115 } else {
3116 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3120 _history.add (ut);
3123 return 0;
3126 void
3127 Session::config_changed (std::string p, bool ours)
3129 if (ours) {
3130 set_dirty ();
3133 if (p == "seamless-loop") {
3135 } else if (p == "rf-speed") {
3137 } else if (p == "auto-loop") {
3139 } else if (p == "auto-input") {
3141 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3142 /* auto-input only makes a difference if we're rolling */
3144 boost::shared_ptr<RouteList> rl = routes.reader ();
3145 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3146 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3147 if (tr && tr->record_enabled ()) {
3148 tr->monitor_input (!config.get_auto_input());
3153 } else if (p == "punch-in") {
3155 Location* location;
3157 if ((location = _locations.auto_punch_location()) != 0) {
3159 if (config.get_punch_in ()) {
3160 replace_event (SessionEvent::PunchIn, location->start());
3161 } else {
3162 remove_event (location->start(), SessionEvent::PunchIn);
3166 } else if (p == "punch-out") {
3168 Location* location;
3170 if ((location = _locations.auto_punch_location()) != 0) {
3172 if (config.get_punch_out()) {
3173 replace_event (SessionEvent::PunchOut, location->end());
3174 } else {
3175 clear_events (SessionEvent::PunchOut);
3179 } else if (p == "edit-mode") {
3181 Glib::Mutex::Lock lm (playlists->lock);
3183 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3184 (*i)->set_edit_mode (Config->get_edit_mode ());
3187 } else if (p == "use-video-sync") {
3189 waiting_for_sync_offset = config.get_use_video_sync();
3191 } else if (p == "mmc-control") {
3193 //poke_midi_thread ();
3195 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3197 if (_mmc) {
3198 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3201 } else if (p == "mmc-send-id") {
3203 if (_mmc) {
3204 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3207 } else if (p == "midi-control") {
3209 //poke_midi_thread ();
3211 } else if (p == "raid-path") {
3213 setup_raid_path (config.get_raid_path());
3215 } else if (p == "timecode-format") {
3217 sync_time_vars ();
3219 } else if (p == "video-pullup") {
3221 sync_time_vars ();
3223 } else if (p == "seamless-loop") {
3225 if (play_loop && transport_rolling()) {
3226 // to reset diskstreams etc
3227 request_play_loop (true);
3230 } else if (p == "rf-speed") {
3232 cumulative_rf_motion = 0;
3233 reset_rf_scale (0);
3235 } else if (p == "click-sound") {
3237 setup_click_sounds (1);
3239 } else if (p == "click-emphasis-sound") {
3241 setup_click_sounds (-1);
3243 } else if (p == "clicking") {
3245 if (Config->get_clicking()) {
3246 if (_click_io && click_data) { // don't require emphasis data
3247 _clicking = true;
3249 } else {
3250 _clicking = false;
3253 } else if (p == "send-mtc") {
3255 /* only set the internal flag if we have
3256 a port.
3259 if (_mtc_port != 0) {
3260 session_send_mtc = Config->get_send_mtc();
3261 if (session_send_mtc) {
3262 /* mark us ready to send */
3263 next_quarter_frame_to_send = 0;
3265 } else {
3266 session_send_mtc = false;
3269 } else if (p == "send-mmc") {
3271 if (_mmc) {
3272 _mmc->enable_send (Config->get_send_mmc ());
3275 } else if (p == "midi-feedback") {
3277 /* only set the internal flag if we have
3278 a port.
3281 if (_mtc_port != 0) {
3282 session_midi_feedback = Config->get_midi_feedback();
3285 } else if (p == "jack-time-master") {
3287 engine().reset_timebase ();
3289 } else if (p == "native-file-header-format") {
3291 if (!first_file_header_format_reset) {
3292 reset_native_file_format ();
3295 first_file_header_format_reset = false;
3297 } else if (p == "native-file-data-format") {
3299 if (!first_file_data_format_reset) {
3300 reset_native_file_format ();
3303 first_file_data_format_reset = false;
3305 } else if (p == "external-sync") {
3306 if (!config.get_external_sync()) {
3307 drop_sync_source ();
3308 } else {
3309 switch_to_sync_source (config.get_sync_source());
3311 } else if (p == "remote-model") {
3312 set_remote_control_ids ();
3313 } else if (p == "denormal-model") {
3314 setup_fpu ();
3315 } else if (p == "history-depth") {
3316 set_history_depth (Config->get_history_depth());
3317 } else if (p == "sync-all-route-ordering") {
3318 sync_order_keys ("session");
3319 } else if (p == "initial-program-change") {
3321 if (_mmc && _mmc->port() && Config->get_initial_program_change() >= 0) {
3322 MIDI::byte buf[2];
3324 buf[0] = MIDI::program; // channel zero by default
3325 buf[1] = (Config->get_initial_program_change() & 0x7f);
3327 _mmc->port()->midimsg (buf, sizeof (buf), 0);
3329 } else if (p == "initial-program-change") {
3331 if (_mmc && _mmc->port() && Config->get_initial_program_change() >= 0) {
3332 MIDI::byte* buf = new MIDI::byte[2];
3334 buf[0] = MIDI::program; // channel zero by default
3335 buf[1] = (Config->get_initial_program_change() & 0x7f);
3336 // deliver_midi (_mmc_port, buf, 2);
3338 } else if (p == "solo-mute-override") {
3339 // catch_up_on_solo_mute_override ();
3340 } else if (p == "listen-position") {
3341 listen_position_changed ();
3342 } else if (p == "solo-control-is-listen-control") {
3343 solo_control_mode_changed ();
3347 set_dirty ();
3350 void
3351 Session::set_history_depth (uint32_t d)
3353 _history.set_depth (d);
3357 Session::load_diskstreams_2X (XMLNode const & node, int)
3359 XMLNodeList clist;
3360 XMLNodeConstIterator citer;
3362 clist = node.children();
3364 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3366 try {
3367 /* diskstreams added automatically by DiskstreamCreated handler */
3368 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3369 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3370 _diskstreams_2X.push_back (dsp);
3371 } else {
3372 error << _("Session: unknown diskstream type in XML") << endmsg;
3376 catch (failed_constructor& err) {
3377 error << _("Session: could not load diskstream via XML state") << endmsg;
3378 return -1;
3382 return 0;
3385 /** Create our MachineControl object and connect things to it */
3386 void
3387 Session::setup_midi_machine_control ()
3389 if (!default_mmc_port) {
3390 return;
3393 _mmc = new MIDI::MachineControl;
3394 _mmc->set_port (default_mmc_port);
3396 _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3397 _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3398 _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3399 _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3400 _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3401 _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3402 _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3403 _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3404 _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3405 _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3406 _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3407 _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3408 _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3410 /* also handle MIDI SPP because its so common */
3412 _mmc->port()->input()->start.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3413 _mmc->port()->input()->contineu.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3414 _mmc->port()->input()->stop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));