Use SessionDirectory class directly rather than ARDOUR::create_session_directory
[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                 r = route_by_remote_id (desc.rid());
3113                 break;
3114         }
3115
3116         if (!r) {
3117                 return c;
3118         }
3119
3120         switch (desc.subtype()) {
3121         case ControllableDescriptor::Gain:
3122                 c = r->gain_control ();
3123                 break;
3124
3125         case ControllableDescriptor::Solo:
3126                 c = r->solo_control();
3127                 break;
3128
3129         case ControllableDescriptor::Mute:
3130                 c = r->mute_control();
3131                 break;
3132
3133         case ControllableDescriptor::Recenable:
3134         {
3135                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3136
3137                 if (t) {
3138                         c = t->rec_enable_control ();
3139                 }
3140                 break;
3141         }
3142
3143         case ControllableDescriptor::PanDirection:
3144         {
3145                 c = r->pannable()->pan_azimuth_control;
3146                 break;
3147         }
3148
3149         case ControllableDescriptor::PanWidth:
3150         {
3151                 c = r->pannable()->pan_width_control;
3152                 break;
3153         }
3154
3155         case ControllableDescriptor::PanElevation:
3156         {
3157                 c = r->pannable()->pan_elevation_control;
3158                 break;
3159         }
3160
3161         case ControllableDescriptor::Balance:
3162                 /* XXX simple pan control */
3163                 break;
3164
3165         case ControllableDescriptor::PluginParameter:
3166         {
3167                 uint32_t plugin = desc.target (0);
3168                 uint32_t parameter_index = desc.target (1);
3169
3170                 /* revert to zero based counting */
3171
3172                 if (plugin > 0) {
3173                         --plugin;
3174                 }
3175
3176                 if (parameter_index > 0) {
3177                         --parameter_index;
3178                 }
3179
3180                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3181
3182                 if (p) {
3183                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3184                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3185                 }
3186                 break;
3187         }
3188
3189         case ControllableDescriptor::SendGain:
3190         {
3191                 uint32_t send = desc.target (0);
3192
3193                 /* revert to zero-based counting */
3194
3195                 if (send > 0) {
3196                         --send;
3197                 }
3198
3199                 boost::shared_ptr<Processor> p = r->nth_send (send);
3200
3201                 if (p) {
3202                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3203                         boost::shared_ptr<Amp> a = s->amp();
3204
3205                         if (a) {
3206                                 c = s->amp()->gain_control();
3207                         }
3208                 }
3209                 break;
3210         }
3211
3212         default:
3213                 /* relax and return a null pointer */
3214                 break;
3215         }
3216
3217         return c;
3218 }
3219
3220 void
3221 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3222 {
3223         if (_writable) {
3224                 Stateful::add_instant_xml (node, _path);
3225         }
3226
3227         if (write_to_config) {
3228                 Config->add_instant_xml (node);
3229         }
3230 }
3231
3232 XMLNode*
3233 Session::instant_xml (const string& node_name)
3234 {
3235         return Stateful::instant_xml (node_name, _path);
3236 }
3237
3238 int
3239 Session::save_history (string snapshot_name)
3240 {
3241         XMLTree tree;
3242
3243         if (!_writable) {
3244                 return 0;
3245         }
3246
3247         if (snapshot_name.empty()) {
3248                 snapshot_name = _current_snapshot_name;
3249         }
3250
3251         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3252         const string backup_filename = history_filename + backup_suffix;
3253         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3254         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3255
3256         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3257                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3258                         error << _("could not backup old history file, current history not saved") << endmsg;
3259                         return -1;
3260                 }
3261         }
3262
3263         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3264                 return 0;
3265         }
3266
3267         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3268
3269         if (!tree.write (xml_path))
3270         {
3271                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3272
3273                 if (g_remove (xml_path.c_str()) != 0) {
3274                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3275                                         xml_path, g_strerror (errno)) << endmsg;
3276                 }
3277                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3278                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3279                                         backup_path, g_strerror (errno)) << endmsg;
3280                 }
3281
3282                 return -1;
3283         }
3284
3285         return 0;
3286 }
3287
3288 int
3289 Session::restore_history (string snapshot_name)
3290 {
3291         XMLTree tree;
3292
3293         if (snapshot_name.empty()) {
3294                 snapshot_name = _current_snapshot_name;
3295         }
3296
3297         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3298         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3299
3300         info << "Loading history from " << xml_path << endmsg;
3301
3302         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3303                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3304                                 _name, xml_path) << endmsg;
3305                 return 1;
3306         }
3307
3308         if (!tree.read (xml_path)) {
3309                 error << string_compose (_("Could not understand session history file \"%1\""),
3310                                 xml_path) << endmsg;
3311                 return -1;
3312         }
3313
3314         // replace history
3315         _history.clear();
3316
3317         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3318
3319                 XMLNode *t = *it;
3320                 UndoTransaction* ut = new UndoTransaction ();
3321                 struct timeval tv;
3322
3323                 ut->set_name(t->property("name")->value());
3324                 stringstream ss(t->property("tv-sec")->value());
3325                 ss >> tv.tv_sec;
3326                 ss.str(t->property("tv-usec")->value());
3327                 ss >> tv.tv_usec;
3328                 ut->set_timestamp(tv);
3329
3330                 for (XMLNodeConstIterator child_it  = t->children().begin();
3331                                 child_it != t->children().end(); child_it++)
3332                 {
3333                         XMLNode *n = *child_it;
3334                         Command *c;
3335
3336                         if (n->name() == "MementoCommand" ||
3337                                         n->name() == "MementoUndoCommand" ||
3338                                         n->name() == "MementoRedoCommand") {
3339
3340                                 if ((c = memento_command_factory(n))) {
3341                                         ut->add_command(c);
3342                                 }
3343
3344                         } else if (n->name() == "NoteDiffCommand") {
3345                                 PBD::ID id (n->property("midi-source")->value());
3346                                 boost::shared_ptr<MidiSource> midi_source =
3347                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3348                                 if (midi_source) {
3349                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3350                                 } else {
3351                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3352                                 }
3353
3354                         } else if (n->name() == "SysExDiffCommand") {
3355
3356                                 PBD::ID id (n->property("midi-source")->value());
3357                                 boost::shared_ptr<MidiSource> midi_source =
3358                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3359                                 if (midi_source) {
3360                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3361                                 } else {
3362                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3363                                 }
3364
3365                         } else if (n->name() == "PatchChangeDiffCommand") {
3366
3367                                 PBD::ID id (n->property("midi-source")->value());
3368                                 boost::shared_ptr<MidiSource> midi_source =
3369                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3370                                 if (midi_source) {
3371                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3372                                 } else {
3373                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3374                                 }
3375
3376                         } else if (n->name() == "StatefulDiffCommand") {
3377                                 if ((c = stateful_diff_command_factory (n))) {
3378                                         ut->add_command (c);
3379                                 }
3380                         } else {
3381                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3382                         }
3383                 }
3384
3385                 _history.add (ut);
3386         }
3387
3388         return 0;
3389 }
3390
3391 void
3392 Session::config_changed (std::string p, bool ours)
3393 {
3394         if (ours) {
3395                 set_dirty ();
3396         }
3397
3398         if (p == "seamless-loop") {
3399
3400         } else if (p == "rf-speed") {
3401
3402         } else if (p == "auto-loop") {
3403
3404         } else if (p == "auto-input") {
3405
3406                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3407                         /* auto-input only makes a difference if we're rolling */
3408                         set_track_monitor_input_status (!config.get_auto_input());
3409                 }
3410
3411         } else if (p == "punch-in") {
3412
3413                 Location* location;
3414
3415                 if ((location = _locations->auto_punch_location()) != 0) {
3416
3417                         if (config.get_punch_in ()) {
3418                                 replace_event (SessionEvent::PunchIn, location->start());
3419                         } else {
3420                                 remove_event (location->start(), SessionEvent::PunchIn);
3421                         }
3422                 }
3423
3424         } else if (p == "punch-out") {
3425
3426                 Location* location;
3427
3428                 if ((location = _locations->auto_punch_location()) != 0) {
3429
3430                         if (config.get_punch_out()) {
3431                                 replace_event (SessionEvent::PunchOut, location->end());
3432                         } else {
3433                                 clear_events (SessionEvent::PunchOut);
3434                         }
3435                 }
3436
3437         } else if (p == "edit-mode") {
3438
3439                 Glib::Mutex::Lock lm (playlists->lock);
3440
3441                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3442                         (*i)->set_edit_mode (Config->get_edit_mode ());
3443                 }
3444
3445         } else if (p == "use-video-sync") {
3446
3447                 waiting_for_sync_offset = config.get_use_video_sync();
3448
3449         } else if (p == "mmc-control") {
3450
3451                 //poke_midi_thread ();
3452
3453         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3454
3455                 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3456
3457         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3458
3459                 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3460
3461         } else if (p == "midi-control") {
3462
3463                 //poke_midi_thread ();
3464
3465         } else if (p == "raid-path") {
3466
3467                 setup_raid_path (config.get_raid_path());
3468
3469         } else if (p == "timecode-format") {
3470
3471                 sync_time_vars ();
3472
3473         } else if (p == "video-pullup") {
3474
3475                 sync_time_vars ();
3476
3477         } else if (p == "seamless-loop") {
3478
3479                 if (play_loop && transport_rolling()) {
3480                         // to reset diskstreams etc
3481                         request_play_loop (true);
3482                 }
3483
3484         } else if (p == "rf-speed") {
3485
3486                 cumulative_rf_motion = 0;
3487                 reset_rf_scale (0);
3488
3489         } else if (p == "click-sound") {
3490
3491                 setup_click_sounds (1);
3492
3493         } else if (p == "click-emphasis-sound") {
3494
3495                 setup_click_sounds (-1);
3496
3497         } else if (p == "clicking") {
3498
3499                 if (Config->get_clicking()) {
3500                         if (_click_io && click_data) { // don't require emphasis data
3501                                 _clicking = true;
3502                         }
3503                 } else {
3504                         _clicking = false;
3505                 }
3506
3507         } else if (p == "click-gain") {
3508                 
3509                 if (_click_gain) {
3510                         _click_gain->set_gain (Config->get_click_gain(), this);
3511                 }
3512
3513         } else if (p == "send-mtc") {
3514
3515                 if (Config->get_send_mtc ()) {
3516                         /* mark us ready to send */
3517                         next_quarter_frame_to_send = 0;
3518                 }
3519
3520         } else if (p == "send-mmc") {
3521
3522                 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3523
3524         } else if (p == "midi-feedback") {
3525
3526                 session_midi_feedback = Config->get_midi_feedback();
3527
3528         } else if (p == "jack-time-master") {
3529
3530                 engine().reset_timebase ();
3531
3532         } else if (p == "native-file-header-format") {
3533
3534                 if (!first_file_header_format_reset) {
3535                         reset_native_file_format ();
3536                 }
3537
3538                 first_file_header_format_reset = false;
3539
3540         } else if (p == "native-file-data-format") {
3541
3542                 if (!first_file_data_format_reset) {
3543                         reset_native_file_format ();
3544                 }
3545
3546                 first_file_data_format_reset = false;
3547
3548         } else if (p == "external-sync") {
3549                 if (!config.get_external_sync()) {
3550                         drop_sync_source ();
3551                 } else {
3552                         switch_to_sync_source (config.get_sync_source());
3553                 }
3554         } else if (p == "remote-model") {
3555                 set_remote_control_ids ();
3556         }  else if (p == "denormal-model") {
3557                 setup_fpu ();
3558         } else if (p == "history-depth") {
3559                 set_history_depth (Config->get_history_depth());
3560         } else if (p == "sync-all-route-ordering") {
3561                 sync_order_keys ("session");
3562         } else if (p == "initial-program-change") {
3563
3564                 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3565                         MIDI::byte buf[2];
3566
3567                         buf[0] = MIDI::program; // channel zero by default
3568                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3569
3570                         MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3571                 }
3572         } else if (p == "solo-mute-override") {
3573                 // catch_up_on_solo_mute_override ();
3574         } else if (p == "listen-position" || p == "pfl-position") {
3575                 listen_position_changed ();
3576         } else if (p == "solo-control-is-listen-control") {
3577                 solo_control_mode_changed ();
3578         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3579                 last_timecode_valid = false;
3580         } else if (p == "playback-buffer-seconds") {
3581                 AudioSource::allocate_working_buffers (frame_rate());
3582         } else if (p == "automation-thinning-factor") {
3583                 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3584         }
3585
3586         set_dirty ();
3587 }
3588
3589 void
3590 Session::set_history_depth (uint32_t d)
3591 {
3592         _history.set_depth (d);
3593 }
3594
3595 int
3596 Session::load_diskstreams_2X (XMLNode const & node, int)
3597 {
3598         XMLNodeList          clist;
3599         XMLNodeConstIterator citer;
3600
3601         clist = node.children();
3602
3603         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3604
3605                 try {
3606                         /* diskstreams added automatically by DiskstreamCreated handler */
3607                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3608                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3609                                 _diskstreams_2X.push_back (dsp);
3610                         } else {
3611                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3612                         }
3613                 }
3614
3615                 catch (failed_constructor& err) {
3616                         error << _("Session: could not load diskstream via XML state") << endmsg;
3617                         return -1;
3618                 }
3619         }
3620
3621         return 0;
3622 }
3623
3624 /** Connect things to the MMC object */
3625 void
3626 Session::setup_midi_machine_control ()
3627 {
3628         MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3629
3630         mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3631         mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3632         mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3633         mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3634         mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3635         mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3636         mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3637         mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3638         mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3639         mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3640         mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3641         mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3642         mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3643
3644         /* also handle MIDI SPP because its so common */
3645
3646         mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3647         mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3648         mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3649 }
3650
3651 boost::shared_ptr<Controllable>
3652 Session::solo_cut_control() const
3653 {
3654         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3655            controls in Ardour that currently get presented to the user in the GUI that require
3656            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3657
3658            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3659            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3660            parameter.
3661         */
3662
3663         return _solo_cut_control;
3664 }
3665
3666 int
3667 Session::rename (const std::string& new_name)
3668 {
3669         string legal_name = legalize_for_path (new_name);
3670         string newpath;
3671         string oldstr;
3672         string newstr;
3673         bool first = true;
3674
3675         string const old_sources_root = _session_dir->sources_root();
3676
3677 #define RENAME ::rename
3678
3679         /* Rename:
3680
3681          * session directory
3682          * interchange subdirectory
3683          * session file
3684          * session history
3685          
3686          * Backup files are left unchanged and not renamed.
3687          */
3688
3689         /* pass one: not 100% safe check that the new directory names don't
3690          * already exist ...
3691          */
3692
3693         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3694                 vector<string> v;
3695
3696                 oldstr = (*i).path;
3697
3698                 /* this is a stupid hack because Glib::path_get_dirname() is
3699                  * lexical-only, and so passing it /a/b/c/ gives a different
3700                  * result than passing it /a/b/c ...
3701                  */
3702
3703                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3704                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3705                 }
3706
3707                 string base = Glib::path_get_dirname (oldstr);
3708                 string p = Glib::path_get_basename (oldstr);
3709
3710                 newstr = Glib::build_filename (base, legal_name);
3711                 
3712                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3713                         return -1;
3714                 }
3715         }
3716
3717         /* Session dirs */
3718         
3719         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3720                 vector<string> v;
3721
3722                 oldstr = (*i).path;
3723
3724                 /* this is a stupid hack because Glib::path_get_dirname() is
3725                  * lexical-only, and so passing it /a/b/c/ gives a different
3726                  * result than passing it /a/b/c ...
3727                  */
3728
3729                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3730                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3731                 }
3732
3733                 string base = Glib::path_get_dirname (oldstr);
3734                 string p = Glib::path_get_basename (oldstr);
3735
3736                 newstr = Glib::build_filename (base, legal_name);
3737
3738                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3739
3740                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3741                         return 1;
3742                 }
3743
3744                 if (first) {
3745                         (*_session_dir) = newstr;
3746                         newpath = newstr;
3747                         first = 1;
3748                 }
3749
3750                 /* directory below interchange */
3751
3752                 v.push_back (newstr);
3753                 v.push_back (interchange_dir_name);
3754                 v.push_back (p);
3755
3756                 oldstr = Glib::build_filename (v);
3757
3758                 v.clear ();
3759                 v.push_back (newstr);
3760                 v.push_back (interchange_dir_name);
3761                 v.push_back (legal_name);
3762
3763                 newstr = Glib::build_filename (v);
3764                 
3765                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3766                 
3767                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3768                         return 1;
3769                 }
3770         }
3771
3772         /* state file */
3773         
3774         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3775         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3776         
3777         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3778
3779         if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3780                 return 1;
3781         }
3782
3783         /* history file */
3784
3785         
3786         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3787
3788         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3789                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3790                 
3791                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3792                 
3793                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3794                         return 1;
3795                 }
3796         }
3797
3798         /* update file source paths */
3799         
3800         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3801                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3802                 if (fs) {
3803                         string p = fs->path ();
3804                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3805                         fs->set_path (p);
3806                 }
3807         }
3808
3809         /* remove old name from recent sessions */
3810
3811         remove_recent_sessions (_path);
3812
3813         _path = newpath;
3814         _current_snapshot_name = new_name;
3815         _name = new_name;
3816
3817         set_dirty ();
3818
3819         /* save state again to get everything just right */
3820
3821         save_state (_current_snapshot_name);
3822
3823
3824         /* add to recent sessions */
3825
3826         store_recent_sessions (new_name, _path);
3827
3828         return 0;
3829
3830 #undef RENAME
3831 }