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