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