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