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