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