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