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