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