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