Add path_is_within to decide if a path is within a given
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2002 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #include <stdint.h>
26
27 #include <algorithm>
28 #include <fstream>
29 #include <string>
30 #include <cerrno>
31 #include <cstdio> /* snprintf(3) ... grrr */
32 #include <cmath>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <climits>
36 #include <fcntl.h>
37 #include <poll.h>
38 #include <signal.h>
39 #include <sys/mman.h>
40 #include <sys/time.h>
41
42 #ifdef HAVE_SYS_VFS_H
43 #include <sys/vfs.h>
44 #else
45 #include <sys/param.h>
46 #include <sys/mount.h>
47 #endif
48
49 #include <glib.h>
50
51 #include <glibmm.h>
52 #include <glibmm/thread.h>
53
54 #include <boost/algorithm/string.hpp>
55
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
58 #include "midi++/manager.h"
59
60 #include "evoral/SMF.hpp"
61
62 #include "pbd/boost_debug.h"
63 #include "pbd/basename.h"
64 #include "pbd/controllable_descriptor.h"
65 #include "pbd/enumwriter.h"
66 #include "pbd/error.h"
67 #include "pbd/pathscanner.h"
68 #include "pbd/pthread_utils.h"
69 #include "pbd/search_path.h"
70 #include "pbd/stacktrace.h"
71 #include "pbd/convert.h"
72 #include "pbd/clear_dir.h"
73
74 #include "ardour/amp.h"
75 #include "ardour/audio_diskstream.h"
76 #include "ardour/audio_track.h"
77 #include "ardour/audioengine.h"
78 #include "ardour/audiofilesource.h"
79 #include "ardour/audioregion.h"
80 #include "ardour/automation_control.h"
81 #include "ardour/butler.h"
82 #include "ardour/control_protocol_manager.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/location.h"
86 #include "ardour/midi_model.h"
87 #include "ardour/midi_patch_manager.h"
88 #include "ardour/midi_region.h"
89 #include "ardour/midi_source.h"
90 #include "ardour/midi_track.h"
91 #include "ardour/named_selection.h"
92 #include "ardour/pannable.h"
93 #include "ardour/playlist_factory.h"
94 #include "ardour/port.h"
95 #include "ardour/processor.h"
96 #include "ardour/proxy_controllable.h"
97 #include "ardour/recent_sessions.h"
98 #include "ardour/region_factory.h"
99 #include "ardour/route_group.h"
100 #include "ardour/send.h"
101 #include "ardour/session.h"
102 #include "ardour/session_directory.h"
103 #include "ardour/session_metadata.h"
104 #include "ardour/session_playlists.h"
105 #include "ardour/session_state_utils.h"
106 #include "ardour/session_utils.h"
107 #include "ardour/silentfilesource.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/speakers.h"
111 #include "ardour/template_utils.h"
112 #include "ardour/tempo.h"
113 #include "ardour/ticker.h"
114 #include "ardour/user_bundle.h"
115
116 #include "control_protocol/control_protocol.h"
117
118 #include "i18n.h"
119 #include <locale.h>
120
121 using namespace std;
122 using namespace ARDOUR;
123 using namespace PBD;
124
125 /** @param snapshot_name Snapshot name, without the .ardour prefix */
126 void
127 Session::first_stage_init (string fullpath, string snapshot_name)
128 {
129         if (fullpath.length() == 0) {
130                 destroy ();
131                 throw failed_constructor();
132         }
133
134         char buf[PATH_MAX+1];
135         if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
136                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
137                 destroy ();
138                 throw failed_constructor();
139         }
140
141         _path = string(buf);
142
143         if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
144                 _path += G_DIR_SEPARATOR;
145         }
146
147         /* these two are just provisional settings. set_state()
148            will likely override them.
149         */
150
151         _name = _current_snapshot_name = snapshot_name;
152
153         set_history_depth (Config->get_history_depth());
154
155         _current_frame_rate = _engine.frame_rate ();
156         _nominal_frame_rate = _current_frame_rate;
157         _base_frame_rate = _current_frame_rate;
158
159         _tempo_map = new TempoMap (_current_frame_rate);
160         _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
161
162
163         _non_soloed_outs_muted = false;
164         _listen_cnt = 0;
165         _solo_isolated_cnt = 0;
166         g_atomic_int_set (&processing_prohibited, 0);
167         _transport_speed = 0;
168         _last_transport_speed = 0;
169         _target_transport_speed = 0;
170         auto_play_legal = false;
171         transport_sub_state = 0;
172         _transport_frame = 0;
173         _requested_return_frame = -1;
174         _session_range_location = 0;
175         g_atomic_int_set (&_record_status, Disabled);
176         loop_changing = false;
177         play_loop = false;
178         have_looped = false;
179         _last_roll_location = 0;
180         _last_roll_or_reversal_location = 0;
181         _last_record_location = 0;
182         pending_locate_frame = 0;
183         pending_locate_roll = false;
184         pending_locate_flush = false;
185         state_was_pending = false;
186         set_next_event ();
187         outbound_mtc_timecode_frame = 0;
188         next_quarter_frame_to_send = -1;
189         current_block_size = 0;
190         solo_update_disabled = false;
191         _have_captured = false;
192         _worst_output_latency = 0;
193         _worst_input_latency = 0;
194         _worst_track_latency = 0;
195         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
196         _was_seamless = Config->get_seamless_loop ();
197         _slave = 0;
198         _send_qf_mtc = false;
199         _pframes_since_last_mtc = 0;
200         g_atomic_int_set (&_playback_load, 100);
201         g_atomic_int_set (&_capture_load, 100);
202         _play_range = false;
203         _exporting = false;
204         pending_abort = false;
205         destructive_index = 0;
206         first_file_data_format_reset = true;
207         first_file_header_format_reset = true;
208         post_export_sync = false;
209         midi_control_ui = 0;
210         _step_editors = 0;
211         no_questions_about_missing_files = false;
212         _speakers.reset (new Speakers);
213         _clicks_cleared = 0;
214         ignore_route_processor_changes = false;
215         _pre_export_mmc_enabled = false;
216
217         AudioDiskstream::allocate_working_buffers();
218
219         /* default short fade = 15ms */
220
221         SndFileSource::setup_standard_crossfades (*this, frame_rate());
222
223         last_mmc_step.tv_sec = 0;
224         last_mmc_step.tv_usec = 0;
225         step_speed = 0.0;
226
227         /* click sounds are unset by default, which causes us to internal
228            waveforms for clicks.
229         */
230
231         click_length = 0;
232         click_emphasis_length = 0;
233         _clicking = false;
234
235         process_function = &Session::process_with_events;
236
237         if (config.get_use_video_sync()) {
238                 waiting_for_sync_offset = true;
239         } else {
240                 waiting_for_sync_offset = false;
241         }
242
243         last_timecode_when = 0;
244         last_timecode_valid = false;
245
246         sync_time_vars ();
247
248         last_rr_session_dir = session_dirs.begin();
249         refresh_disk_space ();
250
251         /* default: assume simple stereo speaker configuration */
252
253         _speakers->setup_default_speakers (2);
254
255         /* slave stuff */
256
257         average_slave_delta = 1800; // !!! why 1800 ????
258         have_first_delta_accumulator = false;
259         delta_accumulator_cnt = 0;
260         _slave_state = Stopped;
261
262         _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
263                                                         boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
264                                                         boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
265         add_controllable (_solo_cut_control);
266
267         _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
268
269         /* These are all static "per-class" signals */
270
271         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
272         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
273         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
274         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
275         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
276
277         /* stop IO objects from doing stuff until we're ready for them */
278
279         Delivery::disable_panners ();
280         IO::disable_connecting ();
281 }
282
283 int
284 Session::second_stage_init ()
285 {
286         AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
287
288         if (!_is_new) {
289                 if (load_state (_current_snapshot_name)) {
290                         return -1;
291                 }
292         }
293
294         if (_butler->start_thread()) {
295                 return -1;
296         }
297
298         if (start_midi_thread ()) {
299                 return -1;
300         }
301
302         setup_midi_machine_control ();
303
304         // set_state() will call setup_raid_path(), but if it's a new session we need
305         // to call setup_raid_path() here.
306
307         if (state_tree) {
308                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
309                         return -1;
310                 }
311         } else {
312                 setup_raid_path(_path);
313         }
314
315         /* we can't save till after ::when_engine_running() is called,
316            because otherwise we save state with no connections made.
317            therefore, we reset _state_of_the_state because ::set_state()
318            will have cleared it.
319
320            we also have to include Loading so that any events that get
321            generated between here and the end of ::when_engine_running()
322            will be processed directly rather than queued.
323         */
324
325         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
326
327         _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
328         _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
329         setup_click_sounds (0);
330         setup_midi_control ();
331
332         /* Pay attention ... */
333
334         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
335         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
336
337         midi_clock = new MidiClockTicker ();
338         midi_clock->set_session (this);
339
340         try {
341                 when_engine_running ();
342         }
343
344         /* handle this one in a different way than all others, so that its clear what happened */
345
346         catch (AudioEngine::PortRegistrationFailure& err) {
347                 error << err.what() << endmsg;
348                 return -1;
349         }
350
351         catch (...) {
352                 return -1;
353         }
354
355         BootMessage (_("Reset Remote Controls"));
356
357         send_full_time_code (0);
358         _engine.transport_locate (0);
359
360         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
361         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
362
363         MIDI::Name::MidiPatchManager::instance().set_session (this);
364
365         /* initial program change will be delivered later; see ::config_changed() */
366
367         _state_of_the_state = Clean;
368
369         Port::set_connecting_blocked (false);
370
371         DirtyChanged (); /* EMIT SIGNAL */
372
373         if (state_was_pending) {
374                 save_state (_current_snapshot_name);
375                 remove_pending_capture_state ();
376                 state_was_pending = false;
377         }
378
379         BootMessage (_("Session loading complete"));
380
381         return 0;
382 }
383
384 string
385 Session::raid_path () const
386 {
387         SearchPath raid_search_path;
388
389         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
390                 raid_search_path += sys::path((*i).path);
391         }
392
393         return raid_search_path.to_string ();
394 }
395
396 void
397 Session::setup_raid_path (string path)
398 {
399         if (path.empty()) {
400                 return;
401         }
402
403         space_and_path sp;
404         string fspath;
405
406         session_dirs.clear ();
407
408         SearchPath search_path(path);
409         SearchPath sound_search_path;
410         SearchPath midi_search_path;
411
412         for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
413                 sp.path = (*i).to_string ();
414                 sp.blocks = 0; // not needed
415                 session_dirs.push_back (sp);
416
417                 SessionDirectory sdir(sp.path);
418
419                 sound_search_path += sdir.sound_path ();
420                 midi_search_path += sdir.midi_path ();
421         }
422
423         // reset the round-robin soundfile path thingie
424         last_rr_session_dir = session_dirs.begin();
425 }
426
427 bool
428 Session::path_is_within_session (const std::string& path)
429 {
430         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
431                 if (PBD::sys::path_is_within (i->path, path)) {
432                         return true;
433                 }
434         }
435         return false;
436 }
437
438 int
439 Session::ensure_subdirs ()
440 {
441         string dir;
442
443         dir = session_directory().peak_path().to_string();
444
445         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
446                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
447                 return -1;
448         }
449
450         dir = session_directory().sound_path().to_string();
451
452         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454                 return -1;
455         }
456
457         dir = session_directory().midi_path().to_string();
458
459         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461                 return -1;
462         }
463
464         dir = session_directory().dead_path().to_string();
465
466         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468                 return -1;
469         }
470
471         dir = session_directory().export_path().to_string();
472
473         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475                 return -1;
476         }
477
478         dir = analysis_dir ();
479
480         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482                 return -1;
483         }
484
485         dir = plugins_dir ();
486
487         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488                 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
489                 return -1;
490         }
491
492         dir = externals_dir ();
493
494         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
495                 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
496                 return -1;
497         }
498
499         return 0;
500 }
501
502 /** @param session_template directory containing session template, or empty.
503  *  Caller must not hold process lock.
504  */
505 int
506 Session::create (const string& session_template, BusProfile* bus_profile)
507 {
508         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
509                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
510                 return -1;
511         }
512
513         if (ensure_subdirs ()) {
514                 return -1;
515         }
516
517         _writable = exists_and_writable (sys::path (_path));
518
519         if (!session_template.empty()) {
520                 std::string in_path = session_template_dir_to_file (session_template);
521
522                 ifstream in(in_path.c_str());
523
524                 if (in) {
525                         string out_path = _path;
526                         out_path += _name;
527                         out_path += statefile_suffix;
528
529                         ofstream out(out_path.c_str());
530
531                         if (out) {
532                                 out << in.rdbuf();
533                                 _is_new = false;
534
535                                 /* Copy plugin state files from template to new session */
536                                 sys::path template_plugins = session_template;
537                                 template_plugins /= X_("plugins");
538                                 sys::copy_files (template_plugins, plugins_dir ());
539                                 
540                                 return 0;
541
542                         } else {
543                                 error << string_compose (_("Could not open %1 for writing session template"), out_path)
544                                         << endmsg;
545                                 return -1;
546                         }
547
548                 } else {
549                         error << string_compose (_("Could not open session template %1 for reading"), in_path)
550                                 << endmsg;
551                         return -1;
552                 }
553
554         }
555
556         /* set initial start + end point */
557
558         _state_of_the_state = Clean;
559
560         /* set up Master Out and Control Out if necessary */
561
562         if (bus_profile) {
563
564                 RouteList rl;
565                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
566
567                 if (bus_profile->master_out_channels) {
568                         boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
569                         if (r->init ()) {
570                                 return -1;
571                         }
572 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
573                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
574 #endif
575                         {
576                                 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
577                                 r->input()->ensure_io (count, false, this);
578                                 r->output()->ensure_io (count, false, this);
579                         }
580
581                         rl.push_back (r);
582
583                 } else {
584                         /* prohibit auto-connect to master, because there isn't one */
585                         bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
586                 }
587
588                 if (!rl.empty()) {
589                         add_routes (rl, false, false, false);
590                 }
591
592                 /* this allows the user to override settings with an environment variable.
593                  */
594
595                 if (no_auto_connect()) {
596                         bus_profile->input_ac = AutoConnectOption (0);
597                         bus_profile->output_ac = AutoConnectOption (0);
598                 }
599
600                 Config->set_input_auto_connect (bus_profile->input_ac);
601                 Config->set_output_auto_connect (bus_profile->output_ac);
602         }
603
604         if (Config->get_use_monitor_bus() && bus_profile) {
605                 add_monitor_section ();
606         }
607
608         save_state ("");
609
610         return 0;
611 }
612
613 void
614 Session::maybe_write_autosave()
615 {
616         if (dirty() && record_status() != Recording) {
617                 save_state("", true);
618         }
619 }
620
621 void
622 Session::remove_pending_capture_state ()
623 {
624         sys::path pending_state_file_path(_session_dir->root_path());
625
626         pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
627
628         try
629         {
630                 sys::remove (pending_state_file_path);
631         }
632         catch(sys::filesystem_error& ex)
633         {
634                 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
635                                 pending_state_file_path.to_string(), ex.what()) << endmsg;
636         }
637 }
638
639 /** Rename a state file.
640  *  @param old_name Old snapshot name.
641  *  @param new_name New snapshot name.
642  */
643 void
644 Session::rename_state (string old_name, string new_name)
645 {
646         if (old_name == _current_snapshot_name || old_name == _name) {
647                 /* refuse to rename the current snapshot or the "main" one */
648                 return;
649         }
650
651         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
652         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
653
654         const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
655         const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
656
657         try
658         {
659                 sys::rename (old_xml_path, new_xml_path);
660         }
661         catch (const sys::filesystem_error& err)
662         {
663                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
664                                 old_name, new_name, err.what()) << endmsg;
665         }
666 }
667
668 /** Remove a state file.
669  *  @param snapshot_name Snapshot name.
670  */
671 void
672 Session::remove_state (string snapshot_name)
673 {
674         if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
675                 // refuse to remove the current snapshot or the "main" one
676                 return;
677         }
678
679         sys::path xml_path(_session_dir->root_path());
680
681         xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
682
683         if (!create_backup_file (xml_path)) {
684                 // don't remove it if a backup can't be made
685                 // create_backup_file will log the error.
686                 return;
687         }
688
689         // and delete it
690         sys::remove (xml_path);
691 }
692
693 #ifdef HAVE_JACK_SESSION
694 void
695 Session::jack_session_event (jack_session_event_t * event)
696 {
697         char timebuf[128];
698         time_t n;
699         struct tm local_time;
700
701         time (&n);
702         localtime_r (&n, &local_time);
703         strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
704
705         if (event->type == JackSessionSaveTemplate)
706         {
707                 if (save_template( timebuf )) {
708                         event->flags = JackSessionSaveError;
709                 } else {
710                         string cmd ("ardour3 -P -U ");
711                         cmd += event->client_uuid;
712                         cmd += " -T ";
713                         cmd += timebuf;
714
715                         event->command_line = strdup (cmd.c_str());
716                 }
717         }
718         else
719         {
720                 if (save_state (timebuf)) {
721                         event->flags = JackSessionSaveError;
722                 } else {
723                         sys::path xml_path (_session_dir->root_path());
724                         xml_path /= legalize_for_path (timebuf) + statefile_suffix;
725
726                         string cmd ("ardour3 -P -U ");
727                         cmd += event->client_uuid;
728                         cmd += " \"";
729                         cmd += xml_path.to_string();
730                         cmd += '\"';
731
732                         event->command_line = strdup (cmd.c_str());
733                 }
734         }
735
736         jack_session_reply (_engine.jack(), event);
737
738         if (event->type == JackSessionSaveAndQuit) {
739                 Quit (); /* EMIT SIGNAL */
740         }
741
742         jack_session_event_free( event );
743 }
744 #endif
745
746 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
747 int
748 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
749 {
750         XMLTree tree;
751         sys::path xml_path(_session_dir->root_path());
752
753         if (!_writable || (_state_of_the_state & CannotSave)) {
754                 return 1;
755         }
756
757         if (!_engine.connected ()) {
758                 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
759                                          PROGRAM_NAME)
760                       << endmsg;
761                 return 1;
762         }
763
764         /* tell sources we're saving first, in case they write out to a new file
765          * which should be saved with the state rather than the old one */
766         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
767                 try {
768                         i->second->session_saved();
769                 } catch (Evoral::SMF::FileError& e) {
770                         error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
771                 }
772         }
773
774         tree.set_root (&get_state());
775
776         if (snapshot_name.empty()) {
777                 snapshot_name = _current_snapshot_name;
778         } else if (switch_to_snapshot) {
779                 _current_snapshot_name = snapshot_name;
780         }
781
782         if (!pending) {
783
784                 /* proper save: use statefile_suffix (.ardour in English) */
785
786                 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
787
788                 /* make a backup copy of the old file */
789
790                 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
791                         // create_backup_file will log the error
792                         return -1;
793                 }
794
795         } else {
796
797                 /* pending save: use pending_suffix (.pending in English) */
798                 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
799         }
800
801         sys::path tmp_path(_session_dir->root_path());
802
803         tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
804
805         // cerr << "actually writing state to " << xml_path.to_string() << endl;
806
807         if (!tree.write (tmp_path.to_string())) {
808                 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
809                 sys::remove (tmp_path);
810                 return -1;
811
812         } else {
813
814                 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
815                         error << string_compose (_("could not rename temporary session file %1 to %2"),
816                                         tmp_path.to_string(), xml_path.to_string()) << endmsg;
817                         sys::remove (tmp_path);
818                         return -1;
819                 }
820         }
821
822         if (!pending) {
823
824                 save_history (snapshot_name);
825
826                 bool was_dirty = dirty();
827
828                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
829
830                 if (was_dirty) {
831                         DirtyChanged (); /* EMIT SIGNAL */
832                 }
833
834                 StateSaved (snapshot_name); /* EMIT SIGNAL */
835         }
836
837         return 0;
838 }
839
840 int
841 Session::restore_state (string snapshot_name)
842 {
843         if (load_state (snapshot_name) == 0) {
844                 set_state (*state_tree->root(), Stateful::loading_state_version);
845         }
846
847         return 0;
848 }
849
850 int
851 Session::load_state (string snapshot_name)
852 {
853         delete state_tree;
854         state_tree = 0;
855
856         state_was_pending = false;
857
858         /* check for leftover pending state from a crashed capture attempt */
859
860         sys::path xmlpath(_session_dir->root_path());
861         xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
862
863         if (sys::exists (xmlpath)) {
864
865                 /* there is pending state from a crashed capture attempt */
866
867                 boost::optional<int> r = AskAboutPendingState();
868                 if (r.get_value_or (1)) {
869                         state_was_pending = true;
870                 }
871         }
872
873         if (!state_was_pending) {
874                 xmlpath = _session_dir->root_path();
875                 xmlpath /= snapshot_name;
876         }
877
878         if (!sys::exists (xmlpath)) {
879                 xmlpath = _session_dir->root_path();
880                 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
881                 if (!sys::exists (xmlpath)) {
882                         error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
883                         return 1;
884                 }
885         }
886
887         state_tree = new XMLTree;
888
889         set_dirty();
890
891         _writable = exists_and_writable (xmlpath);
892
893         if (!state_tree->read (xmlpath.to_string())) {
894                 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
895                 delete state_tree;
896                 state_tree = 0;
897                 return -1;
898         }
899
900         XMLNode& root (*state_tree->root());
901
902         if (root.name() != X_("Session")) {
903                 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
904                 delete state_tree;
905                 state_tree = 0;
906                 return -1;
907         }
908
909         const XMLProperty* prop;
910
911         if ((prop = root.property ("version")) == 0) {
912                 /* no version implies very old version of Ardour */
913                 Stateful::loading_state_version = 1000;
914         } else {
915                 if (prop->value().find ('.') != string::npos) {
916                         /* old school version format */
917                         if (prop->value()[0] == '2') {
918                                 Stateful::loading_state_version = 2000;
919                         } else {
920                                 Stateful::loading_state_version = 3000;
921                         }
922                 } else {
923                         Stateful::loading_state_version = atoi (prop->value());
924                 }
925         }
926
927         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
928
929                 sys::path backup_path(_session_dir->root_path());
930
931                 backup_path /= string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
932
933                 // only create a backup for a given statefile version once
934
935                 if (!sys::exists (backup_path)) {
936                         
937                         info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
938                                                 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
939                              << endmsg;
940                         
941                         try {
942                                 sys::copy_file (xmlpath, backup_path);
943                                 
944                         } catch (sys::filesystem_error& ex) {
945                                 
946                                 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
947                                                          xmlpath.to_string(), ex.what())
948                                       << endmsg;
949                                 return -1;
950                         }
951                 }
952         }
953
954         return 0;
955 }
956
957 int
958 Session::load_options (const XMLNode& node)
959 {
960         LocaleGuard lg (X_("POSIX"));
961         config.set_variables (node);
962         return 0;
963 }
964
965 XMLNode&
966 Session::get_state()
967 {
968         return state(true);
969 }
970
971 XMLNode&
972 Session::get_template()
973 {
974         /* if we don't disable rec-enable, diskstreams
975            will believe they need to store their capture
976            sources in their state node.
977         */
978
979         disable_record (false);
980
981         return state(false);
982 }
983
984 XMLNode&
985 Session::state (bool full_state)
986 {
987         XMLNode* node = new XMLNode("Session");
988         XMLNode* child;
989
990         char buf[16];
991         snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
992         node->add_property("version", buf);
993
994         /* store configuration settings */
995
996         if (full_state) {
997
998                 node->add_property ("name", _name);
999                 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1000                 node->add_property ("sample-rate", buf);
1001
1002                 if (session_dirs.size() > 1) {
1003
1004                         string p;
1005
1006                         vector<space_and_path>::iterator i = session_dirs.begin();
1007                         vector<space_and_path>::iterator next;
1008
1009                         ++i; /* skip the first one */
1010                         next = i;
1011                         ++next;
1012
1013                         while (i != session_dirs.end()) {
1014
1015                                 p += (*i).path;
1016
1017                                 if (next != session_dirs.end()) {
1018                                         p += ':';
1019                                 } else {
1020                                         break;
1021                                 }
1022
1023                                 ++next;
1024                                 ++i;
1025                         }
1026
1027                         child = node->add_child ("Path");
1028                         child->add_content (p);
1029                 }
1030         }
1031
1032         /* save the ID counter */
1033
1034         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1035         node->add_property ("id-counter", buf);
1036
1037         /* save the event ID counter */
1038
1039         snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1040         node->add_property ("event-counter", buf);
1041
1042         /* various options */
1043
1044         node->add_child_nocopy (config.get_variables ());
1045
1046         node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1047
1048         child = node->add_child ("Sources");
1049
1050         if (full_state) {
1051                 Glib::Mutex::Lock sl (source_lock);
1052
1053                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1054
1055                         /* Don't save information about non-file Sources, or
1056                          * about non-destructive file sources that are empty
1057                          * and unused by any regions.
1058                         */
1059
1060                         boost::shared_ptr<FileSource> fs;
1061
1062                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1063
1064                                 if (!fs->destructive()) {
1065                                         if (fs->empty() && !fs->used()) {
1066                                                 continue;
1067                                         }
1068                                 }
1069
1070                                 child->add_child_nocopy (siter->second->get_state());
1071                         }
1072                 }
1073         }
1074
1075         child = node->add_child ("Regions");
1076
1077         if (full_state) {
1078                 Glib::Mutex::Lock rl (region_lock);
1079                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1080                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1081                         boost::shared_ptr<Region> r = i->second;
1082                         /* only store regions not attached to playlists */
1083                         if (r->playlist() == 0) {
1084                                 child->add_child_nocopy (r->state ());
1085                         }
1086                 }
1087
1088                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1089
1090                 if (!cassocs.empty()) {
1091                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1092
1093                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1094                                 char buf[64];
1095                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1096                                 i->first->id().print (buf, sizeof (buf));
1097                                 can->add_property (X_("copy"), buf);
1098                                 i->second->id().print (buf, sizeof (buf));
1099                                 can->add_property (X_("original"), buf);
1100                                 ca->add_child_nocopy (*can);
1101                         }
1102                 }
1103         }
1104
1105         if (full_state) {
1106                 node->add_child_nocopy (_locations->get_state());
1107         } else {
1108                 // for a template, just create a new Locations, populate it
1109                 // with the default start and end, and get the state for that.
1110                 Locations loc (*this);
1111                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1112                 range->set (max_framepos, 0);
1113                 loc.add (range);
1114                 node->add_child_nocopy (loc.get_state());
1115         }
1116
1117         child = node->add_child ("Bundles");
1118         {
1119                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1120                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1121                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1122                         if (b) {
1123                                 child->add_child_nocopy (b->get_state());
1124                         }
1125                 }
1126         }
1127
1128         child = node->add_child ("Routes");
1129         {
1130                 boost::shared_ptr<RouteList> r = routes.reader ();
1131
1132                 RoutePublicOrderSorter cmp;
1133                 RouteList public_order (*r);
1134                 public_order.sort (cmp);
1135
1136                 /* the sort should have put control outs first */
1137
1138                 if (_monitor_out) {
1139                         assert (_monitor_out == public_order.front());
1140                 }
1141
1142                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1143                         if (!(*i)->is_hidden()) {
1144                                 if (full_state) {
1145                                         child->add_child_nocopy ((*i)->get_state());
1146                                 } else {
1147                                         child->add_child_nocopy ((*i)->get_template());
1148                                 }
1149                         }
1150                 }
1151         }
1152
1153         playlists->add_state (node, full_state);
1154
1155         child = node->add_child ("RouteGroups");
1156         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1157                 child->add_child_nocopy ((*i)->get_state());
1158         }
1159
1160         if (_click_io) {
1161                 XMLNode* gain_child = node->add_child ("Click");
1162                 gain_child->add_child_nocopy (_click_io->state (full_state));
1163                 gain_child->add_child_nocopy (_click_gain->state (full_state));
1164         }
1165
1166         if (full_state) {
1167                 XMLNode* ns_child = node->add_child ("NamedSelections");
1168                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1169                         if (full_state) {
1170                                 ns_child->add_child_nocopy ((*i)->get_state());
1171                         }
1172                 }
1173         }
1174
1175         node->add_child_nocopy (_speakers->get_state());
1176         node->add_child_nocopy (_tempo_map->get_state());
1177         node->add_child_nocopy (get_control_protocol_state());
1178
1179         if (_extra_xml) {
1180                 node->add_child_copy (*_extra_xml);
1181         }
1182
1183         return *node;
1184 }
1185
1186 XMLNode&
1187 Session::get_control_protocol_state ()
1188 {
1189         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1190         return cpm.get_state();
1191 }
1192
1193 int
1194 Session::set_state (const XMLNode& node, int version)
1195 {
1196         XMLNodeList nlist;
1197         XMLNode* child;
1198         const XMLProperty* prop;
1199         int ret = -1;
1200
1201         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1202
1203         if (node.name() != X_("Session")) {
1204                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1205                 return -1;
1206         }
1207
1208         if ((prop = node.property ("name")) != 0) {
1209                 _name = prop->value ();
1210         }
1211
1212         if ((prop = node.property (X_("sample-rate"))) != 0) {
1213
1214                 _nominal_frame_rate = atoi (prop->value());
1215
1216                 if (_nominal_frame_rate != _current_frame_rate) {
1217                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1218                         if (r.get_value_or (0)) {
1219                                 return -1;
1220                         }
1221                 }
1222         }
1223
1224         setup_raid_path(_session_dir->root_path().to_string());
1225
1226         if ((prop = node.property (X_("id-counter"))) != 0) {
1227                 uint64_t x;
1228                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1229                 ID::init_counter (x);
1230         } else {
1231                 /* old sessions used a timebased counter, so fake
1232                    the startup ID counter based on a standard
1233                    timestamp.
1234                 */
1235                 time_t now;
1236                 time (&now);
1237                 ID::init_counter (now);
1238         }
1239
1240         if ((prop = node.property (X_("event-counter"))) != 0) {
1241                 Evoral::init_event_id_counter (atoi (prop->value()));
1242         }
1243
1244         IO::disable_connecting ();
1245
1246         Stateful::save_extra_xml (node);
1247
1248         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1249                 load_options (*child);
1250         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1251                 load_options (*child);
1252         } else {
1253                 error << _("Session: XML state has no options section") << endmsg;
1254         }
1255
1256         if (version >= 3000) {
1257                 if ((child = find_named_node (node, "Metadata")) == 0) {
1258                         warning << _("Session: XML state has no metadata section") << endmsg;
1259                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1260                         goto out;
1261                 }
1262         }
1263
1264         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1265                 _speakers->set_state (*child, version);
1266         }
1267
1268         if ((child = find_named_node (node, "Sources")) == 0) {
1269                 error << _("Session: XML state has no sources section") << endmsg;
1270                 goto out;
1271         } else if (load_sources (*child)) {
1272                 goto out;
1273         }
1274
1275         if ((child = find_named_node (node, "TempoMap")) == 0) {
1276                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1277                 goto out;
1278         } else if (_tempo_map->set_state (*child, version)) {
1279                 goto out;
1280         }
1281
1282         if ((child = find_named_node (node, "Locations")) == 0) {
1283                 error << _("Session: XML state has no locations section") << endmsg;
1284                 goto out;
1285         } else if (_locations->set_state (*child, version)) {
1286                 goto out;
1287         }
1288
1289         Location* location;
1290
1291         if ((location = _locations->auto_loop_location()) != 0) {
1292                 set_auto_loop_location (location);
1293         }
1294
1295         if ((location = _locations->auto_punch_location()) != 0) {
1296                 set_auto_punch_location (location);
1297         }
1298
1299         if ((location = _locations->session_range_location()) != 0) {
1300                 delete _session_range_location;
1301                 _session_range_location = location;
1302         }
1303
1304         if (_session_range_location) {
1305                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1306         }
1307
1308         if ((child = find_named_node (node, "Regions")) == 0) {
1309                 error << _("Session: XML state has no Regions section") << endmsg;
1310                 goto out;
1311         } else if (load_regions (*child)) {
1312                 goto out;
1313         }
1314
1315         if ((child = find_named_node (node, "Playlists")) == 0) {
1316                 error << _("Session: XML state has no playlists section") << endmsg;
1317                 goto out;
1318         } else if (playlists->load (*this, *child)) {
1319                 goto out;
1320         }
1321
1322         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1323                 // this is OK
1324         } else if (playlists->load_unused (*this, *child)) {
1325                 goto out;
1326         }
1327
1328         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1329                 if (load_compounds (*child)) {
1330                         goto out;
1331                 }
1332         }
1333
1334         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1335                 if (load_named_selections (*child)) {
1336                         goto out;
1337                 }
1338         }
1339
1340         if (version >= 3000) {
1341                 if ((child = find_named_node (node, "Bundles")) == 0) {
1342                         warning << _("Session: XML state has no bundles section") << endmsg;
1343                         //goto out;
1344                 } else {
1345                         /* We can't load Bundles yet as they need to be able
1346                            to convert from port names to Port objects, which can't happen until
1347                            later */
1348                         _bundle_xml_node = new XMLNode (*child);
1349                 }
1350         }
1351
1352         if (version < 3000) {
1353                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1354                         error << _("Session: XML state has no diskstreams section") << endmsg;
1355                         goto out;
1356                 } else if (load_diskstreams_2X (*child, version)) {
1357                         goto out;
1358                 }
1359         }
1360
1361         if ((child = find_named_node (node, "Routes")) == 0) {
1362                 error << _("Session: XML state has no routes section") << endmsg;
1363                 goto out;
1364         } else if (load_routes (*child, version)) {
1365                 goto out;
1366         }
1367
1368         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1369         _diskstreams_2X.clear ();
1370
1371         if (version >= 3000) {
1372
1373                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1374                         error << _("Session: XML state has no route groups section") << endmsg;
1375                         goto out;
1376                 } else if (load_route_groups (*child, version)) {
1377                         goto out;
1378                 }
1379
1380         } else if (version < 3000) {
1381
1382                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1383                         error << _("Session: XML state has no edit groups section") << endmsg;
1384                         goto out;
1385                 } else if (load_route_groups (*child, version)) {
1386                         goto out;
1387                 }
1388
1389                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1390                         error << _("Session: XML state has no mix groups section") << endmsg;
1391                         goto out;
1392                 } else if (load_route_groups (*child, version)) {
1393                         goto out;
1394                 }
1395         }
1396
1397         if ((child = find_named_node (node, "Click")) == 0) {
1398                 warning << _("Session: XML state has no click section") << endmsg;
1399         } else if (_click_io) {
1400                 const XMLNodeList& children (child->children());
1401                 XMLNodeList::const_iterator i = children.begin();
1402                 _click_io->set_state (**i, version);
1403                 ++i;
1404                 if (i != children.end()) {
1405                         _click_gain->set_state (**i, version);
1406                 }
1407         }
1408
1409         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1410                 ControlProtocolManager::instance().set_protocol_states (*child);
1411         }
1412
1413         update_have_rec_enabled_track ();
1414
1415         /* here beginneth the second phase ... */
1416
1417         StateReady (); /* EMIT SIGNAL */
1418
1419         return 0;
1420
1421   out:
1422         return ret;
1423 }
1424
1425 int
1426 Session::load_routes (const XMLNode& node, int version)
1427 {
1428         XMLNodeList nlist;
1429         XMLNodeConstIterator niter;
1430         RouteList new_routes;
1431
1432         nlist = node.children();
1433
1434         set_dirty();
1435
1436         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1437
1438                 boost::shared_ptr<Route> route;
1439                 if (version < 3000) {
1440                         route = XMLRouteFactory_2X (**niter, version);
1441                 } else {
1442                         route = XMLRouteFactory (**niter, version);
1443                 }
1444
1445                 if (route == 0) {
1446                         error << _("Session: cannot create Route from XML description.") << endmsg;
1447                         return -1;
1448                 }
1449
1450                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1451
1452                 new_routes.push_back (route);
1453         }
1454
1455         add_routes (new_routes, false, false, false);
1456
1457         return 0;
1458 }
1459
1460 boost::shared_ptr<Route>
1461 Session::XMLRouteFactory (const XMLNode& node, int version)
1462 {
1463         boost::shared_ptr<Route> ret;
1464
1465         if (node.name() != "Route") {
1466                 return ret;
1467         }
1468
1469         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1470
1471         DataType type = DataType::AUDIO;
1472         const XMLProperty* prop = node.property("default-type");
1473
1474         if (prop) {
1475                 type = DataType (prop->value());
1476         }
1477
1478         assert (type != DataType::NIL);
1479
1480         if (ds_child) {
1481
1482                 boost::shared_ptr<Track> track;
1483
1484                 if (type == DataType::AUDIO) {
1485                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1486                 } else {
1487                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1488                 }
1489
1490                 if (track->init()) {
1491                         return ret;
1492                 }
1493
1494                 if (track->set_state (node, version)) {
1495                         return ret;
1496                 }
1497
1498 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1499                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1500 #endif
1501                 ret = track;
1502
1503         } else {
1504                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1505
1506                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1507 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1508                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1509 #endif
1510                         ret = r;
1511                 }
1512         }
1513
1514         return ret;
1515 }
1516
1517 boost::shared_ptr<Route>
1518 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1519 {
1520         boost::shared_ptr<Route> ret;
1521
1522         if (node.name() != "Route") {
1523                 return ret;
1524         }
1525
1526         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1527         if (!ds_prop) {
1528                 ds_prop = node.property (X_("diskstream"));
1529         }
1530
1531         DataType type = DataType::AUDIO;
1532         const XMLProperty* prop = node.property("default-type");
1533
1534         if (prop) {
1535                 type = DataType (prop->value());
1536         }
1537
1538         assert (type != DataType::NIL);
1539
1540         if (ds_prop) {
1541
1542                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1543                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1544                         ++i;
1545                 }
1546
1547                 if (i == _diskstreams_2X.end()) {
1548                         error << _("Could not find diskstream for route") << endmsg;
1549                         return boost::shared_ptr<Route> ();
1550                 }
1551
1552                 boost::shared_ptr<Track> track;
1553
1554                 if (type == DataType::AUDIO) {
1555                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1556                 } else {
1557                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1558                 }
1559
1560                 if (track->init()) {
1561                         return ret;
1562                 }
1563
1564                 if (track->set_state (node, version)) {
1565                         return ret;
1566                 }
1567
1568                 track->set_diskstream (*i);
1569
1570 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1571                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1572 #endif
1573                 ret = track;
1574
1575         } else {
1576                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1577
1578                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1579 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1580                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1581 #endif
1582                         ret = r;
1583                 }
1584         }
1585
1586         return ret;
1587 }
1588
1589 int
1590 Session::load_regions (const XMLNode& node)
1591 {
1592         XMLNodeList nlist;
1593         XMLNodeConstIterator niter;
1594         boost::shared_ptr<Region> region;
1595
1596         nlist = node.children();
1597
1598         set_dirty();
1599
1600         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1601                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1602                         error << _("Session: cannot create Region from XML description.");
1603                         const XMLProperty *name = (**niter).property("name");
1604
1605                         if (name) {
1606                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1607                         }
1608
1609                         error << endmsg;
1610                 }
1611         }
1612
1613         return 0;
1614 }
1615
1616 int
1617 Session::load_compounds (const XMLNode& node)
1618 {
1619         XMLNodeList calist = node.children();
1620         XMLNodeConstIterator caiter;
1621         XMLProperty *caprop;
1622
1623         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1624                 XMLNode* ca = *caiter;
1625                 ID orig_id;
1626                 ID copy_id;
1627
1628                 if ((caprop = ca->property (X_("original"))) == 0) {
1629                         continue;
1630                 }
1631                 orig_id = caprop->value();
1632
1633                 if ((caprop = ca->property (X_("copy"))) == 0) {
1634                         continue;
1635                 }
1636                 copy_id = caprop->value();
1637
1638                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1639                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1640
1641                 if (!orig || !copy) {
1642                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1643                                                    orig_id, copy_id)
1644                                 << endmsg;
1645                         continue;
1646                 }
1647
1648                 RegionFactory::add_compound_association (orig, copy);
1649         }
1650
1651         return 0;
1652 }
1653
1654 void
1655 Session::load_nested_sources (const XMLNode& node)
1656 {
1657         XMLNodeList nlist;
1658         XMLNodeConstIterator niter;
1659
1660         nlist = node.children();
1661
1662         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1663                 if ((*niter)->name() == "Source") {
1664
1665                         /* it may already exist, so don't recreate it unnecessarily 
1666                          */
1667
1668                         XMLProperty* prop = (*niter)->property (X_("id"));
1669                         if (!prop) {
1670                                 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1671                                 continue;
1672                         }
1673
1674                         ID source_id (prop->value());
1675
1676                         if (!source_by_id (source_id)) {
1677
1678                                 try {
1679                                         SourceFactory::create (*this, **niter, true);
1680                                 }
1681                                 catch (failed_constructor& err) {
1682                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1683                                 }
1684                         }
1685                 }
1686         }
1687 }
1688
1689 boost::shared_ptr<Region>
1690 Session::XMLRegionFactory (const XMLNode& node, bool full)
1691 {
1692         const XMLProperty* type = node.property("type");
1693
1694         try {
1695
1696                 const XMLNodeList& nlist = node.children();
1697
1698                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1699                         XMLNode *child = (*niter);
1700                         if (child->name() == "NestedSource") {
1701                                 load_nested_sources (*child);
1702                         }
1703                 }
1704
1705                 if (!type || type->value() == "audio") {
1706                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1707                 } else if (type->value() == "midi") {
1708                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1709                 }
1710
1711         } catch (failed_constructor& err) {
1712                 return boost::shared_ptr<Region> ();
1713         }
1714
1715         return boost::shared_ptr<Region> ();
1716 }
1717
1718 boost::shared_ptr<AudioRegion>
1719 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1720 {
1721         const XMLProperty* prop;
1722         boost::shared_ptr<Source> source;
1723         boost::shared_ptr<AudioSource> as;
1724         SourceList sources;
1725         SourceList master_sources;
1726         uint32_t nchans = 1;
1727         char buf[128];
1728
1729         if (node.name() != X_("Region")) {
1730                 return boost::shared_ptr<AudioRegion>();
1731         }
1732
1733         if ((prop = node.property (X_("channels"))) != 0) {
1734                 nchans = atoi (prop->value().c_str());
1735         }
1736
1737         if ((prop = node.property ("name")) == 0) {
1738                 cerr << "no name for this region\n";
1739                 abort ();
1740         }
1741
1742         if ((prop = node.property (X_("source-0"))) == 0) {
1743                 if ((prop = node.property ("source")) == 0) {
1744                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1745                         return boost::shared_ptr<AudioRegion>();
1746                 }
1747         }
1748
1749         PBD::ID s_id (prop->value());
1750
1751         if ((source = source_by_id (s_id)) == 0) {
1752                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1753                 return boost::shared_ptr<AudioRegion>();
1754         }
1755
1756         as = boost::dynamic_pointer_cast<AudioSource>(source);
1757         if (!as) {
1758                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1759                 return boost::shared_ptr<AudioRegion>();
1760         }
1761
1762         sources.push_back (as);
1763
1764         /* pickup other channels */
1765
1766         for (uint32_t n=1; n < nchans; ++n) {
1767                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1768                 if ((prop = node.property (buf)) != 0) {
1769
1770                         PBD::ID id2 (prop->value());
1771
1772                         if ((source = source_by_id (id2)) == 0) {
1773                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1774                                 return boost::shared_ptr<AudioRegion>();
1775                         }
1776
1777                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1778                         if (!as) {
1779                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1780                                 return boost::shared_ptr<AudioRegion>();
1781                         }
1782                         sources.push_back (as);
1783                 }
1784         }
1785
1786         for (uint32_t n = 0; n < nchans; ++n) {
1787                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1788                 if ((prop = node.property (buf)) != 0) {
1789
1790                         PBD::ID id2 (prop->value());
1791
1792                         if ((source = source_by_id (id2)) == 0) {
1793                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1794                                 return boost::shared_ptr<AudioRegion>();
1795                         }
1796
1797                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1798                         if (!as) {
1799                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1800                                 return boost::shared_ptr<AudioRegion>();
1801                         }
1802                         master_sources.push_back (as);
1803                 }
1804         }
1805
1806         try {
1807                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1808
1809                 /* a final detail: this is the one and only place that we know how long missing files are */
1810
1811                 if (region->whole_file()) {
1812                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1813                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1814                                 if (sfp) {
1815                                         sfp->set_length (region->length());
1816                                 }
1817                         }
1818                 }
1819
1820                 if (!master_sources.empty()) {
1821                         if (master_sources.size() != nchans) {
1822                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1823                         } else {
1824                                 region->set_master_sources (master_sources);
1825                         }
1826                 }
1827
1828                 return region;
1829
1830         }
1831
1832         catch (failed_constructor& err) {
1833                 return boost::shared_ptr<AudioRegion>();
1834         }
1835 }
1836
1837 boost::shared_ptr<MidiRegion>
1838 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1839 {
1840         const XMLProperty* prop;
1841         boost::shared_ptr<Source> source;
1842         boost::shared_ptr<MidiSource> ms;
1843         SourceList sources;
1844
1845         if (node.name() != X_("Region")) {
1846                 return boost::shared_ptr<MidiRegion>();
1847         }
1848
1849         if ((prop = node.property ("name")) == 0) {
1850                 cerr << "no name for this region\n";
1851                 abort ();
1852         }
1853
1854         if ((prop = node.property (X_("source-0"))) == 0) {
1855                 if ((prop = node.property ("source")) == 0) {
1856                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1857                         return boost::shared_ptr<MidiRegion>();
1858                 }
1859         }
1860
1861         PBD::ID s_id (prop->value());
1862
1863         if ((source = source_by_id (s_id)) == 0) {
1864                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1865                 return boost::shared_ptr<MidiRegion>();
1866         }
1867
1868         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1869         if (!ms) {
1870                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1871                 return boost::shared_ptr<MidiRegion>();
1872         }
1873
1874         sources.push_back (ms);
1875
1876         try {
1877                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1878                 /* a final detail: this is the one and only place that we know how long missing files are */
1879
1880                 if (region->whole_file()) {
1881                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1882                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1883                                 if (sfp) {
1884                                         sfp->set_length (region->length());
1885                                 }
1886                         }
1887                 }
1888
1889                 return region;
1890         }
1891
1892         catch (failed_constructor& err) {
1893                 return boost::shared_ptr<MidiRegion>();
1894         }
1895 }
1896
1897 XMLNode&
1898 Session::get_sources_as_xml ()
1899
1900 {
1901         XMLNode* node = new XMLNode (X_("Sources"));
1902         Glib::Mutex::Lock lm (source_lock);
1903
1904         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1905                 node->add_child_nocopy (i->second->get_state());
1906         }
1907
1908         return *node;
1909 }
1910
1911 string
1912 Session::path_from_region_name (DataType type, string name, string identifier)
1913 {
1914         char buf[PATH_MAX+1];
1915         uint32_t n;
1916         SessionDirectory sdir(get_best_session_directory_for_new_source());
1917         sys::path source_dir = ((type == DataType::AUDIO)
1918                 ? sdir.sound_path() : sdir.midi_path());
1919
1920         string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1921
1922         for (n = 0; n < 999999; ++n) {
1923                 if (identifier.length()) {
1924                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1925                                   identifier.c_str(), n, ext.c_str());
1926                 } else {
1927                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1928                                         n, ext.c_str());
1929                 }
1930
1931                 sys::path source_path = source_dir / buf;
1932
1933                 if (!sys::exists (source_path)) {
1934                         return source_path.to_string();
1935                 }
1936         }
1937
1938         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1939                                  name, identifier)
1940               << endmsg;
1941
1942         return "";
1943 }
1944
1945
1946 int
1947 Session::load_sources (const XMLNode& node)
1948 {
1949         XMLNodeList nlist;
1950         XMLNodeConstIterator niter;
1951         boost::shared_ptr<Source> source;
1952
1953         nlist = node.children();
1954
1955         set_dirty();
1956
1957         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1958           retry:
1959                 try {
1960                         if ((source = XMLSourceFactory (**niter)) == 0) {
1961                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1962                         }
1963
1964                 } catch (MissingSource& err) {
1965
1966                         int user_choice;
1967
1968                         if (!no_questions_about_missing_files) {
1969                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1970                         } else {
1971                                 user_choice = -2;
1972                         }
1973
1974                         switch (user_choice) {
1975                         case 0:
1976                                 /* user added a new search location, so try again */
1977                                 goto retry;
1978
1979
1980                         case 1:
1981                                 /* user asked to quit the entire session load
1982                                  */
1983                                 return -1;
1984
1985                         case 2:
1986                                 no_questions_about_missing_files = true;
1987                                 goto retry;
1988
1989                         case 3:
1990                                 no_questions_about_missing_files = true;
1991                                 /* fallthru */
1992
1993                         case -1:
1994                         default:
1995                                 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1996                                 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1997                                 break;
1998                         }
1999                 }
2000         }
2001
2002         return 0;
2003 }
2004
2005 boost::shared_ptr<Source>
2006 Session::XMLSourceFactory (const XMLNode& node)
2007 {
2008         if (node.name() != "Source") {
2009                 return boost::shared_ptr<Source>();
2010         }
2011
2012         try {
2013                 /* note: do peak building in another thread when loading session state */
2014                 return SourceFactory::create (*this, node, true);
2015         }
2016
2017         catch (failed_constructor& err) {
2018                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2019                 return boost::shared_ptr<Source>();
2020         }
2021 }
2022
2023 int
2024 Session::save_template (string template_name)
2025 {
2026         XMLTree tree;
2027
2028         if (_state_of_the_state & CannotSave) {
2029                 return -1;
2030         }
2031
2032         sys::path user_template_dir(user_template_directory());
2033
2034         try
2035         {
2036                 sys::create_directories (user_template_dir);
2037         }
2038         catch(sys::filesystem_error& ex)
2039         {
2040                 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2041                                 user_template_dir.to_string(), ex.what()) << endmsg;
2042                 return -1;
2043         }
2044
2045         tree.set_root (&get_template());
2046
2047         sys::path template_dir_path(user_template_dir);
2048         
2049         /* directory to put the template in */
2050         template_dir_path /= template_name;
2051         if (sys::exists (template_dir_path))
2052         {
2053                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2054                                 template_dir_path.to_string()) << endmsg;
2055                 return -1;
2056         }
2057         
2058         sys::create_directories (template_dir_path);
2059
2060         /* file to write */
2061         sys::path template_file_path = template_dir_path;
2062         template_file_path /= template_name + template_suffix;
2063
2064         if (!tree.write (template_file_path.to_string())) {
2065                 error << _("template not saved") << endmsg;
2066                 return -1;
2067         }
2068
2069         /* copy plugin state directory */
2070
2071         sys::path template_plugin_state_path = template_dir_path;
2072         template_plugin_state_path /= X_("plugins");
2073         sys::create_directories (template_plugin_state_path);
2074         sys::copy_files (plugins_dir(), template_plugin_state_path);
2075
2076         return 0;
2077 }
2078
2079 void
2080 Session::refresh_disk_space ()
2081 {
2082 #if HAVE_SYS_VFS_H
2083         struct statfs statfsbuf;
2084         vector<space_and_path>::iterator i;
2085         Glib::Mutex::Lock lm (space_lock);
2086         double scale;
2087
2088         /* get freespace on every FS that is part of the session path */
2089
2090         _total_free_4k_blocks = 0;
2091
2092         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2093                 statfs ((*i).path.c_str(), &statfsbuf);
2094
2095                 scale = statfsbuf.f_bsize/4096.0;
2096
2097                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2098                 _total_free_4k_blocks += (*i).blocks;
2099         }
2100 #endif
2101 }
2102
2103 string
2104 Session::get_best_session_directory_for_new_source ()
2105 {
2106         vector<space_and_path>::iterator i;
2107         string result = _session_dir->root_path().to_string();
2108
2109         /* handle common case without system calls */
2110
2111         if (session_dirs.size() == 1) {
2112                 return result;
2113         }
2114
2115         /* OK, here's the algorithm we're following here:
2116
2117         We want to select which directory to use for
2118         the next file source to be created. Ideally,
2119         we'd like to use a round-robin process so as to
2120         get maximum performance benefits from splitting
2121         the files across multiple disks.
2122
2123         However, in situations without much diskspace, an
2124         RR approach may end up filling up a filesystem
2125         with new files while others still have space.
2126         Its therefore important to pay some attention to
2127         the freespace in the filesystem holding each
2128         directory as well. However, if we did that by
2129         itself, we'd keep creating new files in the file
2130         system with the most space until it was as full
2131         as all others, thus negating any performance
2132         benefits of this RAID-1 like approach.
2133
2134         So, we use a user-configurable space threshold. If
2135         there are at least 2 filesystems with more than this
2136         much space available, we use RR selection between them.
2137         If not, then we pick the filesystem with the most space.
2138
2139         This gets a good balance between the two
2140         approaches.
2141         */
2142
2143         refresh_disk_space ();
2144
2145         int free_enough = 0;
2146
2147         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2148                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2149                         free_enough++;
2150                 }
2151         }
2152
2153         if (free_enough >= 2) {
2154                 /* use RR selection process, ensuring that the one
2155                    picked works OK.
2156                 */
2157
2158                 i = last_rr_session_dir;
2159
2160                 do {
2161                         if (++i == session_dirs.end()) {
2162                                 i = session_dirs.begin();
2163                         }
2164
2165                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2166                                 if (create_session_directory ((*i).path)) {
2167                                         result = (*i).path;
2168                                         last_rr_session_dir = i;
2169                                         return result;
2170                                 }
2171                         }
2172
2173                 } while (i != last_rr_session_dir);
2174
2175         } else {
2176
2177                 /* pick FS with the most freespace (and that
2178                    seems to actually work ...)
2179                 */
2180
2181                 vector<space_and_path> sorted;
2182                 space_and_path_ascending_cmp cmp;
2183
2184                 sorted = session_dirs;
2185                 sort (sorted.begin(), sorted.end(), cmp);
2186
2187                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2188                         if (create_session_directory ((*i).path)) {
2189                                 result = (*i).path;
2190                                 last_rr_session_dir = i;
2191                                 return result;
2192                         }
2193                 }
2194         }
2195
2196         return result;
2197 }
2198
2199 int
2200 Session::load_named_selections (const XMLNode& node)
2201 {
2202         XMLNodeList nlist;
2203         XMLNodeConstIterator niter;
2204         NamedSelection *ns;
2205
2206         nlist = node.children();
2207
2208         set_dirty();
2209
2210         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2211
2212                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2213                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2214                 }
2215         }
2216
2217         return 0;
2218 }
2219
2220 NamedSelection *
2221 Session::XMLNamedSelectionFactory (const XMLNode& node)
2222 {
2223         try {
2224                 return new NamedSelection (*this, node);
2225         }
2226
2227         catch (failed_constructor& err) {
2228                 return 0;
2229         }
2230 }
2231
2232 string
2233 Session::automation_dir () const
2234 {
2235         return Glib::build_filename (_path, "automation");
2236 }
2237
2238 string
2239 Session::analysis_dir () const
2240 {
2241         return Glib::build_filename (_path, "analysis");
2242 }
2243
2244 string
2245 Session::plugins_dir () const
2246 {
2247         return Glib::build_filename (_path, "plugins");
2248 }
2249
2250 string
2251 Session::externals_dir () const
2252 {
2253         return Glib::build_filename (_path, "externals");
2254 }
2255
2256 int
2257 Session::load_bundles (XMLNode const & node)
2258 {
2259         XMLNodeList nlist = node.children();
2260         XMLNodeConstIterator niter;
2261
2262         set_dirty();
2263
2264         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2265                 if ((*niter)->name() == "InputBundle") {
2266                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2267                 } else if ((*niter)->name() == "OutputBundle") {
2268                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2269                 } else {
2270                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2271                         return -1;
2272                 }
2273         }
2274
2275         return 0;
2276 }
2277
2278 int
2279 Session::load_route_groups (const XMLNode& node, int version)
2280 {
2281         XMLNodeList nlist = node.children();
2282         XMLNodeConstIterator niter;
2283
2284         set_dirty ();
2285
2286         if (version >= 3000) {
2287
2288                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2289                         if ((*niter)->name() == "RouteGroup") {
2290                                 RouteGroup* rg = new RouteGroup (*this, "");
2291                                 add_route_group (rg);
2292                                 rg->set_state (**niter, version);
2293                         }
2294                 }
2295
2296         } else if (version < 3000) {
2297
2298                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2299                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2300                                 RouteGroup* rg = new RouteGroup (*this, "");
2301                                 add_route_group (rg);
2302                                 rg->set_state (**niter, version);
2303                         }
2304                 }
2305         }
2306
2307         return 0;
2308 }
2309
2310 void
2311 Session::auto_save()
2312 {
2313         save_state (_current_snapshot_name);
2314 }
2315
2316 static bool
2317 state_file_filter (const string &str, void */*arg*/)
2318 {
2319         return (str.length() > strlen(statefile_suffix) &&
2320                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2321 }
2322
2323 struct string_cmp {
2324         bool operator()(const string* a, const string* b) {
2325                 return *a < *b;
2326         }
2327 };
2328
2329 static string*
2330 remove_end(string* state)
2331 {
2332         string statename(*state);
2333
2334         string::size_type start,end;
2335         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2336                 statename = statename.substr (start+1);
2337         }
2338
2339         if ((end = statename.rfind(".ardour")) == string::npos) {
2340                 end = statename.length();
2341         }
2342
2343         return new string(statename.substr (0, end));
2344 }
2345
2346 vector<string *> *
2347 Session::possible_states (string path)
2348 {
2349         PathScanner scanner;
2350         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2351
2352         transform(states->begin(), states->end(), states->begin(), remove_end);
2353
2354         string_cmp cmp;
2355         sort (states->begin(), states->end(), cmp);
2356
2357         return states;
2358 }
2359
2360 vector<string *> *
2361 Session::possible_states () const
2362 {
2363         return possible_states(_path);
2364 }
2365
2366 void
2367 Session::add_route_group (RouteGroup* g)
2368 {
2369         _route_groups.push_back (g);
2370         route_group_added (g); /* EMIT SIGNAL */
2371
2372         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2373         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2374         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2375
2376         set_dirty ();
2377 }
2378
2379 void
2380 Session::remove_route_group (RouteGroup& rg)
2381 {
2382         list<RouteGroup*>::iterator i;
2383
2384         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2385                 _route_groups.erase (i);
2386                 delete &rg;
2387
2388                 route_group_removed (); /* EMIT SIGNAL */
2389         }
2390 }
2391
2392 /** Set a new order for our route groups, without adding or removing any.
2393  *  @param groups Route group list in the new order.
2394  */
2395 void
2396 Session::reorder_route_groups (list<RouteGroup*> groups)
2397 {
2398         _route_groups = groups;
2399
2400         route_groups_reordered (); /* EMIT SIGNAL */
2401         set_dirty ();
2402 }
2403
2404
2405 RouteGroup *
2406 Session::route_group_by_name (string name)
2407 {
2408         list<RouteGroup *>::iterator i;
2409
2410         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2411                 if ((*i)->name() == name) {
2412                         return* i;
2413                 }
2414         }
2415         return 0;
2416 }
2417
2418 RouteGroup&
2419 Session::all_route_group() const
2420 {
2421         return *_all_route_group;
2422 }
2423
2424 void
2425 Session::add_commands (vector<Command*> const & cmds)
2426 {
2427         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2428                 add_command (*i);
2429         }
2430 }
2431
2432 void
2433 Session::begin_reversible_command (const string& name)
2434 {
2435         begin_reversible_command (g_quark_from_string (name.c_str ()));
2436 }
2437
2438 /** Begin a reversible command using a GQuark to identify it.
2439  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2440  *  but there must be as many begin...()s as there are commit...()s.
2441  */
2442 void
2443 Session::begin_reversible_command (GQuark q)
2444 {
2445         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2446            to hold all the commands that are committed.  This keeps the order of
2447            commands correct in the history.
2448         */
2449
2450         if (_current_trans == 0) {
2451                 /* start a new transaction */
2452                 assert (_current_trans_quarks.empty ());
2453                 _current_trans = new UndoTransaction();
2454                 _current_trans->set_name (g_quark_to_string (q));
2455         }
2456
2457         _current_trans_quarks.push_front (q);
2458 }
2459
2460 void
2461 Session::commit_reversible_command (Command *cmd)
2462 {
2463         assert (_current_trans);
2464         assert (!_current_trans_quarks.empty ());
2465
2466         struct timeval now;
2467
2468         if (cmd) {
2469                 _current_trans->add_command (cmd);
2470         }
2471
2472         _current_trans_quarks.pop_front ();
2473
2474         if (!_current_trans_quarks.empty ()) {
2475                 /* the transaction we're committing is not the top-level one */
2476                 return;
2477         }
2478
2479         if (_current_trans->empty()) {
2480                 /* no commands were added to the transaction, so just get rid of it */
2481                 delete _current_trans;
2482                 _current_trans = 0;
2483                 return;
2484         }
2485
2486         gettimeofday (&now, 0);
2487         _current_trans->set_timestamp (now);
2488
2489         _history.add (_current_trans);
2490         _current_trans = 0;
2491 }
2492
2493 static bool
2494 accept_all_audio_files (const string& path, void */*arg*/)
2495 {
2496         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2497                 return false;
2498         }
2499
2500         if (!AudioFileSource::safe_audio_file_extension (path)) {
2501                 return false;
2502         }
2503
2504         return true;
2505 }
2506
2507 static bool
2508 accept_all_midi_files (const string& path, void */*arg*/)
2509 {
2510         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2511                 return false;
2512         }
2513
2514         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2515                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2516                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2517 }
2518
2519 static bool
2520 accept_all_state_files (const string& path, void */*arg*/)
2521 {
2522         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2523                 return false;
2524         }
2525
2526         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2527 }
2528
2529 int
2530 Session::find_all_sources (string path, set<string>& result)
2531 {
2532         XMLTree tree;
2533         XMLNode* node;
2534
2535         if (!tree.read (path)) {
2536                 return -1;
2537         }
2538
2539         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2540                 return -2;
2541         }
2542
2543         XMLNodeList nlist;
2544         XMLNodeConstIterator niter;
2545
2546         nlist = node->children();
2547
2548         set_dirty();
2549
2550         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2551
2552                 XMLProperty* prop;
2553
2554                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2555                         continue;
2556                 }
2557
2558                 DataType type (prop->value());
2559
2560                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2561                         continue;
2562                 }
2563
2564                 if (Glib::path_is_absolute (prop->value())) {
2565                         /* external file, ignore */
2566                         continue;
2567                 }
2568
2569                 string found_path;
2570                 bool is_new;
2571                 uint16_t chan;
2572
2573                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2574                         result.insert (found_path);
2575                 }
2576         }
2577
2578         return 0;
2579 }
2580
2581 int
2582 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2583 {
2584         PathScanner scanner;
2585         vector<string*>* state_files;
2586         string ripped;
2587         string this_snapshot_path;
2588
2589         result.clear ();
2590
2591         ripped = _path;
2592
2593         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2594                 ripped = ripped.substr (0, ripped.length() - 1);
2595         }
2596
2597         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2598
2599         if (state_files == 0) {
2600                 /* impossible! */
2601                 return 0;
2602         }
2603
2604         this_snapshot_path = _path;
2605         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2606         this_snapshot_path += statefile_suffix;
2607
2608         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2609
2610                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2611                         continue;
2612                 }
2613
2614                 if (find_all_sources (**i, result) < 0) {
2615                         return -1;
2616                 }
2617         }
2618
2619         return 0;
2620 }
2621
2622 struct RegionCounter {
2623     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2624     AudioSourceList::iterator iter;
2625     boost::shared_ptr<Region> region;
2626     uint32_t count;
2627
2628     RegionCounter() : count (0) {}
2629 };
2630
2631 int
2632 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2633 {
2634         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2635         return r.get_value_or (1);
2636 }
2637
2638 void
2639 Session::cleanup_regions ()
2640 {
2641         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2642
2643         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2644
2645                 uint32_t used = playlists->region_use_count (i->second);
2646
2647                 if (used == 0 && !i->second->automatic ()) {
2648                         RegionFactory::map_remove (i->second);
2649                 }
2650         }
2651
2652         /* dump the history list */
2653         _history.clear ();
2654
2655         save_state ("");
2656 }
2657
2658 int
2659 Session::cleanup_sources (CleanupReport& rep)
2660 {
2661         // FIXME: needs adaptation to midi
2662
2663         vector<boost::shared_ptr<Source> > dead_sources;
2664         PathScanner scanner;
2665         string audio_path;
2666         string midi_path;
2667         vector<space_and_path>::iterator i;
2668         vector<space_and_path>::iterator nexti;
2669         vector<string*>* candidates;
2670         vector<string*>* candidates2;
2671         vector<string> unused;
2672         set<string> all_sources;
2673         bool used;
2674         string spath;
2675         int ret = -1;
2676
2677         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2678
2679         /* consider deleting all unused playlists */
2680
2681         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2682                 ret = 0;
2683                 goto out;
2684         }
2685
2686         /* sync the "all regions" property of each playlist with its current state
2687          */
2688
2689         playlists->sync_all_regions_with_regions ();
2690
2691         /* find all un-used sources */
2692
2693         rep.paths.clear ();
2694         rep.space = 0;
2695
2696         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2697
2698                 SourceMap::iterator tmp;
2699
2700                 tmp = i;
2701                 ++tmp;
2702
2703                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2704                    capture files.
2705                 */
2706
2707                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2708                         dead_sources.push_back (i->second);
2709                         i->second->drop_references ();
2710                 }
2711
2712                 i = tmp;
2713         }
2714
2715         /* build a list of all the possible audio directories for the session */
2716
2717         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2718
2719                 nexti = i;
2720                 ++nexti;
2721
2722                 SessionDirectory sdir ((*i).path);
2723                 audio_path += sdir.sound_path().to_string();
2724
2725                 if (nexti != session_dirs.end()) {
2726                         audio_path += ':';
2727                 }
2728
2729                 i = nexti;
2730         }
2731
2732
2733         /* build a list of all the possible midi directories for the session */
2734
2735         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2736
2737                 nexti = i;
2738                 ++nexti;
2739
2740                 SessionDirectory sdir ((*i).path);
2741                 midi_path += sdir.midi_path().to_string();
2742
2743                 if (nexti != session_dirs.end()) {
2744                         midi_path += ':';
2745                 }
2746
2747                 i = nexti;
2748         }
2749
2750         candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2751         candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2752
2753         /* merge them */
2754
2755         if (candidates) {
2756                 if (candidates2) {
2757                         for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2758                                 candidates->push_back (*i);
2759                         }
2760                         delete candidates2;
2761                 }
2762         } else {
2763                 candidates = candidates2; // might still be null
2764         }
2765
2766         /* find all sources, but don't use this snapshot because the
2767            state file on disk still references sources we may have already
2768            dropped.
2769         */
2770
2771         find_all_sources_across_snapshots (all_sources, true);
2772
2773         /*  add our current source list
2774          */
2775
2776         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2777                 boost::shared_ptr<FileSource> fs;
2778                 SourceMap::iterator tmp = i;
2779                 ++tmp;
2780
2781                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2782                         if (playlists->source_use_count (fs) != 0) {
2783                                 all_sources.insert (fs->path());
2784                         } else {
2785
2786                                 /* we might not remove this source from disk, because it may be used
2787                                    by other snapshots, but its not being used in this version
2788                                    so lets get rid of it now, along with any representative regions
2789                                    in the region list.
2790                                 */
2791
2792                                 RegionFactory::remove_regions_using_source (i->second);
2793                                 sources.erase (i);
2794                         }
2795                 }
2796
2797                 i = tmp;
2798         }
2799
2800         char tmppath1[PATH_MAX+1];
2801         char tmppath2[PATH_MAX+1];
2802
2803         if (candidates) {
2804                 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2805
2806                         used = false;
2807                         spath = **x;
2808
2809                         for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2810
2811                                 if (realpath(spath.c_str(), tmppath1) == 0) {
2812                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2813                                                                  spath, strerror (errno)) << endmsg;
2814                                         continue;
2815                                 }
2816
2817                                 if (realpath((*i).c_str(),  tmppath2) == 0) {
2818                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2819                                                                  (*i), strerror (errno)) << endmsg;
2820                                         continue;
2821                                 }
2822
2823                                 if (strcmp(tmppath1, tmppath2) == 0) {
2824                                         used = true;
2825                                         break;
2826                                 }
2827                         }
2828
2829                         if (!used) {
2830                                 unused.push_back (spath);
2831                         }
2832
2833                         delete *x;
2834                 }
2835
2836                 delete candidates;
2837         }
2838
2839         /* now try to move all unused files into the "dead" directory(ies) */
2840
2841         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2842                 struct stat statbuf;
2843
2844                 string newpath;
2845
2846                 /* don't move the file across filesystems, just
2847                    stick it in the `dead_dir_name' directory
2848                    on whichever filesystem it was already on.
2849                 */
2850
2851                 if ((*x).find ("/sounds/") != string::npos) {
2852
2853                         /* old school, go up 1 level */
2854
2855                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2856                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2857
2858                 } else {
2859
2860                         /* new school, go up 4 levels */
2861
2862                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2863                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2864                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2865                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2866                 }
2867
2868                 newpath = Glib::build_filename (newpath, dead_dir_name);
2869
2870                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2871                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2872                         return -1;
2873                 }
2874
2875                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2876
2877                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2878
2879                         /* the new path already exists, try versioning */
2880
2881                         char buf[PATH_MAX+1];
2882                         int version = 1;
2883                         string newpath_v;
2884
2885                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2886                         newpath_v = buf;
2887
2888                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2889                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2890                                 newpath_v = buf;
2891                         }
2892
2893                         if (version == 999) {
2894                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2895                                                   newpath)
2896                                       << endmsg;
2897                         } else {
2898                                 newpath = newpath_v;
2899                         }
2900
2901                 } else {
2902
2903                         /* it doesn't exist, or we can't read it or something */
2904
2905                 }
2906
2907                 stat ((*x).c_str(), &statbuf);
2908
2909                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2910                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2911                                           (*x), newpath, strerror (errno))
2912                               << endmsg;
2913                         goto out;
2914                 }
2915
2916                 /* see if there an easy to find peakfile for this file, and remove it.
2917                  */
2918
2919                 string base = basename_nosuffix (*x);
2920                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2921                                  or for the first channel of embedded files. it will miss
2922                                  some peakfiles for other channels
2923                               */
2924                 string peakpath = peak_path (base);
2925
2926                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2927                         if (::unlink (peakpath.c_str()) != 0) {
2928                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2929                                                          peakpath, _path, strerror (errno))
2930                                       << endmsg;
2931                                 /* try to back out */
2932                                 ::rename (newpath.c_str(), _path.c_str());
2933                                 goto out;
2934                         }
2935                 }
2936
2937                 rep.paths.push_back (*x);
2938                 rep.space += statbuf.st_size;
2939         }
2940
2941         /* dump the history list */
2942
2943         _history.clear ();
2944
2945         /* save state so we don't end up a session file
2946            referring to non-existent sources.
2947         */
2948
2949         save_state ("");
2950         ret = 0;
2951
2952   out:
2953         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2954
2955         return ret;
2956 }
2957
2958 int
2959 Session::cleanup_trash_sources (CleanupReport& rep)
2960 {
2961         // FIXME: needs adaptation for MIDI
2962
2963         vector<space_and_path>::iterator i;
2964         string dead_dir;
2965
2966         rep.paths.clear ();
2967         rep.space = 0;
2968
2969         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2970
2971                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2972
2973                 clear_directory (dead_dir, &rep.space, &rep.paths);
2974         }
2975
2976         return 0;
2977 }
2978
2979 void
2980 Session::set_dirty ()
2981 {
2982         bool was_dirty = dirty();
2983
2984         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2985
2986
2987         if (!was_dirty) {
2988                 DirtyChanged(); /* EMIT SIGNAL */
2989         }
2990 }
2991
2992
2993 void
2994 Session::set_clean ()
2995 {
2996         bool was_dirty = dirty();
2997
2998         _state_of_the_state = Clean;
2999
3000
3001         if (was_dirty) {
3002                 DirtyChanged(); /* EMIT SIGNAL */
3003         }
3004 }
3005
3006 void
3007 Session::set_deletion_in_progress ()
3008 {
3009         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3010 }
3011
3012 void
3013 Session::clear_deletion_in_progress ()
3014 {
3015         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3016 }
3017
3018 void
3019 Session::add_controllable (boost::shared_ptr<Controllable> c)
3020 {
3021         /* this adds a controllable to the list managed by the Session.
3022            this is a subset of those managed by the Controllable class
3023            itself, and represents the only ones whose state will be saved
3024            as part of the session.
3025         */
3026
3027         Glib::Mutex::Lock lm (controllables_lock);
3028         controllables.insert (c);
3029 }
3030
3031 struct null_deleter { void operator()(void const *) const {} };
3032
3033 void
3034 Session::remove_controllable (Controllable* c)
3035 {
3036         if (_state_of_the_state & Deletion) {
3037                 return;
3038         }
3039
3040         Glib::Mutex::Lock lm (controllables_lock);
3041
3042         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3043
3044         if (x != controllables.end()) {
3045                 controllables.erase (x);
3046         }
3047 }
3048
3049 boost::shared_ptr<Controllable>
3050 Session::controllable_by_id (const PBD::ID& id)
3051 {
3052         Glib::Mutex::Lock lm (controllables_lock);
3053
3054         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3055                 if ((*i)->id() == id) {
3056                         return *i;
3057                 }
3058         }
3059
3060         return boost::shared_ptr<Controllable>();
3061 }
3062
3063 boost::shared_ptr<Controllable>
3064 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3065 {
3066         boost::shared_ptr<Controllable> c;
3067         boost::shared_ptr<Route> r;
3068
3069         switch (desc.top_level_type()) {
3070         case ControllableDescriptor::NamedRoute:
3071         {
3072                 std::string str = desc.top_level_name();
3073                 if (str == "master") {
3074                         r = _master_out;
3075                 } else if (str == "control" || str == "listen") {
3076                         r = _monitor_out;
3077                 } else {
3078                         r = route_by_name (desc.top_level_name());
3079                 }
3080                 break;
3081         }
3082
3083         case ControllableDescriptor::RemoteControlID:
3084                 r = route_by_remote_id (desc.rid());
3085                 break;
3086         }
3087
3088         if (!r) {
3089                 return c;
3090         }
3091
3092         switch (desc.subtype()) {
3093         case ControllableDescriptor::Gain:
3094                 c = r->gain_control ();
3095                 break;
3096
3097         case ControllableDescriptor::Solo:
3098                 c = r->solo_control();
3099                 break;
3100
3101         case ControllableDescriptor::Mute:
3102                 c = r->mute_control();
3103                 break;
3104
3105         case ControllableDescriptor::Recenable:
3106         {
3107                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3108
3109                 if (t) {
3110                         c = t->rec_enable_control ();
3111                 }
3112                 break;
3113         }
3114
3115         case ControllableDescriptor::PanDirection:
3116         {
3117                 c = r->pannable()->pan_azimuth_control;
3118                 break;
3119         }
3120
3121         case ControllableDescriptor::PanWidth:
3122         {
3123                 c = r->pannable()->pan_width_control;
3124                 break;
3125         }
3126
3127         case ControllableDescriptor::PanElevation:
3128         {
3129                 c = r->pannable()->pan_elevation_control;
3130                 break;
3131         }
3132
3133         case ControllableDescriptor::Balance:
3134                 /* XXX simple pan control */
3135                 break;
3136
3137         case ControllableDescriptor::PluginParameter:
3138         {
3139                 uint32_t plugin = desc.target (0);
3140                 uint32_t parameter_index = desc.target (1);
3141
3142                 /* revert to zero based counting */
3143
3144                 if (plugin > 0) {
3145                         --plugin;
3146                 }
3147
3148                 if (parameter_index > 0) {
3149                         --parameter_index;
3150                 }
3151
3152                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3153
3154                 if (p) {
3155                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3156                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3157                 }
3158                 break;
3159         }
3160
3161         case ControllableDescriptor::SendGain:
3162         {
3163                 uint32_t send = desc.target (0);
3164
3165                 /* revert to zero-based counting */
3166
3167                 if (send > 0) {
3168                         --send;
3169                 }
3170
3171                 boost::shared_ptr<Processor> p = r->nth_send (send);
3172
3173                 if (p) {
3174                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3175                         boost::shared_ptr<Amp> a = s->amp();
3176
3177                         if (a) {
3178                                 c = s->amp()->gain_control();
3179                         }
3180                 }
3181                 break;
3182         }
3183
3184         default:
3185                 /* relax and return a null pointer */
3186                 break;
3187         }
3188
3189         return c;
3190 }
3191
3192 void
3193 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3194 {
3195         if (_writable) {
3196                 Stateful::add_instant_xml (node, _path);
3197         }
3198
3199         if (write_to_config) {
3200                 Config->add_instant_xml (node);
3201         }
3202 }
3203
3204 XMLNode*
3205 Session::instant_xml (const string& node_name)
3206 {
3207         return Stateful::instant_xml (node_name, _path);
3208 }
3209
3210 int
3211 Session::save_history (string snapshot_name)
3212 {
3213         XMLTree tree;
3214
3215         if (!_writable) {
3216                 return 0;
3217         }
3218
3219         if (snapshot_name.empty()) {
3220                 snapshot_name = _current_snapshot_name;
3221         }
3222
3223         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3224         const string backup_filename = history_filename + backup_suffix;
3225         const sys::path xml_path = _session_dir->root_path() / history_filename;
3226         const sys::path backup_path = _session_dir->root_path() / backup_filename;
3227
3228         if (sys::exists (xml_path)) {
3229                 try
3230                 {
3231                         sys::rename (xml_path, backup_path);
3232                 }
3233                 catch (const sys::filesystem_error& err)
3234                 {
3235                         error << _("could not backup old history file, current history not saved") << endmsg;
3236                         return -1;
3237                 }
3238         }
3239
3240         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3241                 return 0;
3242         }
3243
3244         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3245
3246         if (!tree.write (xml_path.to_string()))
3247         {
3248                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3249
3250                 try
3251                 {
3252                         sys::remove (xml_path);
3253                         sys::rename (backup_path, xml_path);
3254                 }
3255                 catch (const sys::filesystem_error& err)
3256                 {
3257                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3258                                         backup_path.to_string(), err.what()) << endmsg;
3259                 }
3260
3261                 return -1;
3262         }
3263
3264         return 0;
3265 }
3266
3267 int
3268 Session::restore_history (string snapshot_name)
3269 {
3270         XMLTree tree;
3271
3272         if (snapshot_name.empty()) {
3273                 snapshot_name = _current_snapshot_name;
3274         }
3275
3276         const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3277         const sys::path xml_path = _session_dir->root_path() / xml_filename;
3278
3279         info << "Loading history from " << xml_path.to_string() << endmsg;
3280
3281         if (!sys::exists (xml_path)) {
3282                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3283                                 _name, xml_path.to_string()) << endmsg;
3284                 return 1;
3285         }
3286
3287         if (!tree.read (xml_path.to_string())) {
3288                 error << string_compose (_("Could not understand session history file \"%1\""),
3289                                 xml_path.to_string()) << endmsg;
3290                 return -1;
3291         }
3292
3293         // replace history
3294         _history.clear();
3295
3296         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3297
3298                 XMLNode *t = *it;
3299                 UndoTransaction* ut = new UndoTransaction ();
3300                 struct timeval tv;
3301
3302                 ut->set_name(t->property("name")->value());
3303                 stringstream ss(t->property("tv-sec")->value());
3304                 ss >> tv.tv_sec;
3305                 ss.str(t->property("tv-usec")->value());
3306                 ss >> tv.tv_usec;
3307                 ut->set_timestamp(tv);
3308
3309                 for (XMLNodeConstIterator child_it  = t->children().begin();
3310                                 child_it != t->children().end(); child_it++)
3311                 {
3312                         XMLNode *n = *child_it;
3313                         Command *c;
3314
3315                         if (n->name() == "MementoCommand" ||
3316                                         n->name() == "MementoUndoCommand" ||
3317                                         n->name() == "MementoRedoCommand") {
3318
3319                                 if ((c = memento_command_factory(n))) {
3320                                         ut->add_command(c);
3321                                 }
3322
3323                         } else if (n->name() == "NoteDiffCommand") {
3324                                 PBD::ID id (n->property("midi-source")->value());
3325                                 boost::shared_ptr<MidiSource> midi_source =
3326                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3327                                 if (midi_source) {
3328                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3329                                 } else {
3330                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3331                                 }
3332
3333                         } else if (n->name() == "SysExDiffCommand") {
3334
3335                                 PBD::ID id (n->property("midi-source")->value());
3336                                 boost::shared_ptr<MidiSource> midi_source =
3337                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3338                                 if (midi_source) {
3339                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3340                                 } else {
3341                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3342                                 }
3343
3344                         } else if (n->name() == "PatchChangeDiffCommand") {
3345
3346                                 PBD::ID id (n->property("midi-source")->value());
3347                                 boost::shared_ptr<MidiSource> midi_source =
3348                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3349                                 if (midi_source) {
3350                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3351                                 } else {
3352                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3353                                 }
3354
3355                         } else if (n->name() == "StatefulDiffCommand") {
3356                                 if ((c = stateful_diff_command_factory (n))) {
3357                                         ut->add_command (c);
3358                                 }
3359                         } else {
3360                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3361                         }
3362                 }
3363
3364                 _history.add (ut);
3365         }
3366
3367         return 0;
3368 }
3369
3370 void
3371 Session::config_changed (std::string p, bool ours)
3372 {
3373         if (ours) {
3374                 set_dirty ();
3375         }
3376
3377         if (p == "seamless-loop") {
3378
3379         } else if (p == "rf-speed") {
3380
3381         } else if (p == "auto-loop") {
3382
3383         } else if (p == "auto-input") {
3384
3385                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3386                         /* auto-input only makes a difference if we're rolling */
3387                         set_track_monitor_input_status (!config.get_auto_input());
3388                 }
3389
3390         } else if (p == "punch-in") {
3391
3392                 Location* location;
3393
3394                 if ((location = _locations->auto_punch_location()) != 0) {
3395
3396                         if (config.get_punch_in ()) {
3397                                 replace_event (SessionEvent::PunchIn, location->start());
3398                         } else {
3399                                 remove_event (location->start(), SessionEvent::PunchIn);
3400                         }
3401                 }
3402
3403         } else if (p == "punch-out") {
3404
3405                 Location* location;
3406
3407                 if ((location = _locations->auto_punch_location()) != 0) {
3408
3409                         if (config.get_punch_out()) {
3410                                 replace_event (SessionEvent::PunchOut, location->end());
3411                         } else {
3412                                 clear_events (SessionEvent::PunchOut);
3413                         }
3414                 }
3415
3416         } else if (p == "edit-mode") {
3417
3418                 Glib::Mutex::Lock lm (playlists->lock);
3419
3420                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3421                         (*i)->set_edit_mode (Config->get_edit_mode ());
3422                 }
3423
3424         } else if (p == "use-video-sync") {
3425
3426                 waiting_for_sync_offset = config.get_use_video_sync();
3427
3428         } else if (p == "mmc-control") {
3429
3430                 //poke_midi_thread ();
3431
3432         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3433
3434                 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3435
3436         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3437
3438                 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3439
3440         } else if (p == "midi-control") {
3441
3442                 //poke_midi_thread ();
3443
3444         } else if (p == "raid-path") {
3445
3446                 setup_raid_path (config.get_raid_path());
3447
3448         } else if (p == "timecode-format") {
3449
3450                 sync_time_vars ();
3451
3452         } else if (p == "video-pullup") {
3453
3454                 sync_time_vars ();
3455
3456         } else if (p == "seamless-loop") {
3457
3458                 if (play_loop && transport_rolling()) {
3459                         // to reset diskstreams etc
3460                         request_play_loop (true);
3461                 }
3462
3463         } else if (p == "rf-speed") {
3464
3465                 cumulative_rf_motion = 0;
3466                 reset_rf_scale (0);
3467
3468         } else if (p == "click-sound") {
3469
3470                 setup_click_sounds (1);
3471
3472         } else if (p == "click-emphasis-sound") {
3473
3474                 setup_click_sounds (-1);
3475
3476         } else if (p == "clicking") {
3477
3478                 if (Config->get_clicking()) {
3479                         if (_click_io && click_data) { // don't require emphasis data
3480                                 _clicking = true;
3481                         }
3482                 } else {
3483                         _clicking = false;
3484                 }
3485
3486         } else if (p == "click-gain") {
3487                 
3488                 if (_click_gain) {
3489                         _click_gain->set_gain (Config->get_click_gain(), this);
3490                 }
3491
3492         } else if (p == "send-mtc") {
3493
3494                 if (Config->get_send_mtc ()) {
3495                         /* mark us ready to send */
3496                         next_quarter_frame_to_send = 0;
3497                 }
3498
3499         } else if (p == "send-mmc") {
3500
3501                 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3502
3503         } else if (p == "midi-feedback") {
3504
3505                 session_midi_feedback = Config->get_midi_feedback();
3506
3507         } else if (p == "jack-time-master") {
3508
3509                 engine().reset_timebase ();
3510
3511         } else if (p == "native-file-header-format") {
3512
3513                 if (!first_file_header_format_reset) {
3514                         reset_native_file_format ();
3515                 }
3516
3517                 first_file_header_format_reset = false;
3518
3519         } else if (p == "native-file-data-format") {
3520
3521                 if (!first_file_data_format_reset) {
3522                         reset_native_file_format ();
3523                 }
3524
3525                 first_file_data_format_reset = false;
3526
3527         } else if (p == "external-sync") {
3528                 if (!config.get_external_sync()) {
3529                         drop_sync_source ();
3530                 } else {
3531                         switch_to_sync_source (config.get_sync_source());
3532                 }
3533         } else if (p == "remote-model") {
3534                 set_remote_control_ids ();
3535         }  else if (p == "denormal-model") {
3536                 setup_fpu ();
3537         } else if (p == "history-depth") {
3538                 set_history_depth (Config->get_history_depth());
3539         } else if (p == "sync-all-route-ordering") {
3540                 sync_order_keys ("session");
3541         } else if (p == "initial-program-change") {
3542
3543                 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3544                         MIDI::byte buf[2];
3545
3546                         buf[0] = MIDI::program; // channel zero by default
3547                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3548
3549                         MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3550                 }
3551         } else if (p == "solo-mute-override") {
3552                 // catch_up_on_solo_mute_override ();
3553         } else if (p == "listen-position" || p == "pfl-position") {
3554                 listen_position_changed ();
3555         } else if (p == "solo-control-is-listen-control") {
3556                 solo_control_mode_changed ();
3557         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3558                 last_timecode_valid = false;
3559         } else if (p == "playback-buffer-seconds") {
3560                 AudioSource::allocate_working_buffers (frame_rate());
3561         } else if (p == "automation-thinning-factor") {
3562                 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3563         }
3564
3565         set_dirty ();
3566 }
3567
3568 void
3569 Session::set_history_depth (uint32_t d)
3570 {
3571         _history.set_depth (d);
3572 }
3573
3574 int
3575 Session::load_diskstreams_2X (XMLNode const & node, int)
3576 {
3577         XMLNodeList          clist;
3578         XMLNodeConstIterator citer;
3579
3580         clist = node.children();
3581
3582         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3583
3584                 try {
3585                         /* diskstreams added automatically by DiskstreamCreated handler */
3586                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3587                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3588                                 _diskstreams_2X.push_back (dsp);
3589                         } else {
3590                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3591                         }
3592                 }
3593
3594                 catch (failed_constructor& err) {
3595                         error << _("Session: could not load diskstream via XML state") << endmsg;
3596                         return -1;
3597                 }
3598         }
3599
3600         return 0;
3601 }
3602
3603 /** Connect things to the MMC object */
3604 void
3605 Session::setup_midi_machine_control ()
3606 {
3607         MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3608
3609         mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3610         mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3611         mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3612         mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3613         mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3614         mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3615         mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3616         mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3617         mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3618         mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3619         mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3620         mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3621         mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3622
3623         /* also handle MIDI SPP because its so common */
3624
3625         mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3626         mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3627         mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3628 }
3629
3630 boost::shared_ptr<Controllable>
3631 Session::solo_cut_control() const
3632 {
3633         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3634            controls in Ardour that currently get presented to the user in the GUI that require
3635            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3636
3637            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3638            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3639            parameter.
3640         */
3641
3642         return _solo_cut_control;
3643 }
3644
3645 int
3646 Session::rename (const std::string& new_name)
3647 {
3648         string legal_name = legalize_for_path (new_name);
3649         string newpath;
3650         string oldstr;
3651         string newstr;
3652         bool first = true;
3653
3654         string const old_sources_root = _session_dir->sources_root().to_string ();
3655
3656 #define RENAME ::rename
3657
3658         /* Rename:
3659
3660          * session directory
3661          * interchange subdirectory
3662          * session file
3663          * session history
3664          
3665          * Backup files are left unchanged and not renamed.
3666          */
3667
3668         /* pass one: not 100% safe check that the new directory names don't
3669          * already exist ...
3670          */
3671
3672         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3673                 vector<string> v;
3674
3675                 oldstr = (*i).path;
3676
3677                 /* this is a stupid hack because Glib::path_get_dirname() is
3678                  * lexical-only, and so passing it /a/b/c/ gives a different
3679                  * result than passing it /a/b/c ...
3680                  */
3681
3682                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3683                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3684                 }
3685
3686                 string base = Glib::path_get_dirname (oldstr);
3687                 string p = Glib::path_get_basename (oldstr);
3688
3689                 newstr = Glib::build_filename (base, legal_name);
3690                 
3691                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3692                         return -1;
3693                 }
3694         }
3695
3696         /* Session dirs */
3697         
3698         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3699                 vector<string> v;
3700
3701                 oldstr = (*i).path;
3702
3703                 /* this is a stupid hack because Glib::path_get_dirname() is
3704                  * lexical-only, and so passing it /a/b/c/ gives a different
3705                  * result than passing it /a/b/c ...
3706                  */
3707
3708                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3709                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3710                 }
3711
3712                 string base = Glib::path_get_dirname (oldstr);
3713                 string p = Glib::path_get_basename (oldstr);
3714
3715                 newstr = Glib::build_filename (base, legal_name);
3716
3717                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3718
3719                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3720                         return 1;
3721                 }
3722
3723                 if (first) {
3724                         (*_session_dir) = newstr;
3725                         newpath = newstr;
3726                         first = 1;
3727                 }
3728
3729                 /* directory below interchange */
3730
3731                 v.push_back (newstr);
3732                 v.push_back (interchange_dir_name);
3733                 v.push_back (p);
3734
3735                 oldstr = Glib::build_filename (v);
3736
3737                 v.clear ();
3738                 v.push_back (newstr);
3739                 v.push_back (interchange_dir_name);
3740                 v.push_back (legal_name);
3741
3742                 newstr = Glib::build_filename (v);
3743                 
3744                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3745                 
3746                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3747                         return 1;
3748                 }
3749         }
3750
3751         /* state file */
3752         
3753         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3754         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3755         
3756         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3757
3758         if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3759                 return 1;
3760         }
3761
3762         /* history file */
3763
3764         
3765         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3766
3767         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3768                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3769                 
3770                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3771                 
3772                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3773                         return 1;
3774                 }
3775         }
3776
3777         /* update file source paths */
3778         
3779         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3780                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3781                 if (fs) {
3782                         string p = fs->path ();
3783                         boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3784                         fs->set_path (p);
3785                 }
3786         }
3787
3788         /* remove old name from recent sessions */
3789
3790         remove_recent_sessions (_path);
3791
3792         _path = newpath;
3793         _current_snapshot_name = new_name;
3794         _name = new_name;
3795
3796         set_dirty ();
3797
3798         /* save state again to get everything just right */
3799
3800         save_state (_current_snapshot_name);
3801
3802
3803         /* add to recent sessions */
3804
3805         store_recent_sessions (new_name, _path);
3806
3807         return 0;
3808
3809 #undef RENAME
3810 }