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