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