Re-work layering in possibly debatable ways. Sketchy docs in doc/layering.
[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
978         /* Copy the node */
979         XMLNode node_copy = node;
980         
981         /* XXX: evil hack: fix up sessions from before the layering alterations
982            (during A3 beta)
983         */
984         
985         XMLNodeList children = node_copy.children ();
986         for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) {
987                 XMLProperty* p = (*i)->property (X_("name"));
988                 if (p && p->name() == X_("name") && p->value() == X_("layer-model") ) {
989                         p = (*i)->property (X_("value"));
990                         if (p && p->value() == X_("MoveAddHigher")) {
991                                 (*i)->add_property (X_("value"), X_("AddOrBoundsChangeHigher"));
992                         }
993                 }
994         }
995         
996         config.set_variables (node_copy);
997         
998         return 0;
999 }
1000
1001 XMLNode&
1002 Session::get_state()
1003 {
1004         return state(true);
1005 }
1006
1007 XMLNode&
1008 Session::get_template()
1009 {
1010         /* if we don't disable rec-enable, diskstreams
1011            will believe they need to store their capture
1012            sources in their state node.
1013         */
1014
1015         disable_record (false);
1016
1017         return state(false);
1018 }
1019
1020 XMLNode&
1021 Session::state(bool full_state)
1022 {
1023         XMLNode* node = new XMLNode("Session");
1024         XMLNode* child;
1025
1026         // store libardour version, just in case
1027         char buf[16];
1028         snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1029         node->add_property("version", string(buf));
1030
1031         /* store configuration settings */
1032
1033         if (full_state) {
1034
1035                 node->add_property ("name", _name);
1036                 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1037                 node->add_property ("sample-rate", buf);
1038
1039                 if (session_dirs.size() > 1) {
1040
1041                         string p;
1042
1043                         vector<space_and_path>::iterator i = session_dirs.begin();
1044                         vector<space_and_path>::iterator next;
1045
1046                         ++i; /* skip the first one */
1047                         next = i;
1048                         ++next;
1049
1050                         while (i != session_dirs.end()) {
1051
1052                                 p += (*i).path;
1053
1054                                 if (next != session_dirs.end()) {
1055                                         p += ':';
1056                                 } else {
1057                                         break;
1058                                 }
1059
1060                                 ++next;
1061                                 ++i;
1062                         }
1063
1064                         child = node->add_child ("Path");
1065                         child->add_content (p);
1066                 }
1067         }
1068
1069         /* save the ID counter */
1070
1071         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1072         node->add_property ("id-counter", buf);
1073
1074         /* save the event ID counter */
1075
1076         snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1077         node->add_property ("event-counter", buf);
1078
1079         /* various options */
1080
1081         node->add_child_nocopy (config.get_variables ());
1082
1083         node->add_child_nocopy (_metadata->get_state());
1084
1085         child = node->add_child ("Sources");
1086
1087         if (full_state) {
1088                 Glib::Mutex::Lock sl (source_lock);
1089
1090                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1091
1092                         /* Don't save information about non-file Sources, or
1093                          * about non-destructive file sources that are empty
1094                          * and unused by any regions.
1095                         */
1096
1097                         boost::shared_ptr<FileSource> fs;
1098
1099                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1100
1101                                 if (!fs->destructive()) {
1102                                         if (fs->empty() && !fs->used()) {
1103                                                 continue;
1104                                         }
1105                                 }
1106
1107                                 child->add_child_nocopy (siter->second->get_state());
1108                         }
1109                 }
1110         }
1111
1112         child = node->add_child ("Regions");
1113
1114         if (full_state) {
1115                 Glib::Mutex::Lock rl (region_lock);
1116                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1117                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1118                         boost::shared_ptr<Region> r = i->second;
1119                         /* only store regions not attached to playlists */
1120                         if (r->playlist() == 0) {
1121                                 child->add_child_nocopy (r->state ());
1122                         }
1123                 }
1124
1125                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1126
1127                 if (!cassocs.empty()) {
1128                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1129
1130                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1131                                 char buf[64];
1132                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1133                                 i->first->id().print (buf, sizeof (buf));
1134                                 can->add_property (X_("copy"), buf);
1135                                 i->second->id().print (buf, sizeof (buf));
1136                                 can->add_property (X_("original"), buf);
1137                                 ca->add_child_nocopy (*can);
1138                         }
1139                 }
1140         }
1141
1142         if (full_state) {
1143                 node->add_child_nocopy (_locations->get_state());
1144         } else {
1145                 // for a template, just create a new Locations, populate it
1146                 // with the default start and end, and get the state for that.
1147                 Locations loc (*this);
1148                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1149                 range->set (max_framepos, 0);
1150                 loc.add (range);
1151                 node->add_child_nocopy (loc.get_state());
1152         }
1153
1154         child = node->add_child ("Bundles");
1155         {
1156                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1157                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1158                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1159                         if (b) {
1160                                 child->add_child_nocopy (b->get_state());
1161                         }
1162                 }
1163         }
1164
1165         child = node->add_child ("Routes");
1166         {
1167                 boost::shared_ptr<RouteList> r = routes.reader ();
1168
1169                 RoutePublicOrderSorter cmp;
1170                 RouteList public_order (*r);
1171                 public_order.sort (cmp);
1172
1173                 /* the sort should have put control outs first */
1174
1175                 if (_monitor_out) {
1176                         assert (_monitor_out == public_order.front());
1177                 }
1178
1179                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1180                         if (!(*i)->is_hidden()) {
1181                                 if (full_state) {
1182                                         child->add_child_nocopy ((*i)->get_state());
1183                                 } else {
1184                                         child->add_child_nocopy ((*i)->get_template());
1185                                 }
1186                         }
1187                 }
1188         }
1189
1190         playlists->add_state (node, full_state);
1191
1192         child = node->add_child ("RouteGroups");
1193         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1194                 child->add_child_nocopy ((*i)->get_state());
1195         }
1196
1197         if (_click_io) {
1198                 child = node->add_child ("Click");
1199                 child->add_child_nocopy (_click_io->state (full_state));
1200         }
1201
1202         if (full_state) {
1203                 child = node->add_child ("NamedSelections");
1204                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1205                         if (full_state) {
1206                                 child->add_child_nocopy ((*i)->get_state());
1207                         }
1208                 }
1209         }
1210
1211         node->add_child_nocopy (_speakers->get_state());
1212         node->add_child_nocopy (_tempo_map->get_state());
1213         node->add_child_nocopy (get_control_protocol_state());
1214
1215         if (_extra_xml) {
1216                 node->add_child_copy (*_extra_xml);
1217         }
1218
1219         return *node;
1220 }
1221
1222 XMLNode&
1223 Session::get_control_protocol_state ()
1224 {
1225         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1226         return cpm.get_state();
1227 }
1228
1229 int
1230 Session::set_state (const XMLNode& node, int version)
1231 {
1232         XMLNodeList nlist;
1233         XMLNode* child;
1234         const XMLProperty* prop;
1235         int ret = -1;
1236
1237         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1238
1239         if (node.name() != X_("Session")) {
1240                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1241                 return -1;
1242         }
1243
1244         if ((prop = node.property ("version")) != 0) {
1245                 version = atoi (prop->value ()) * 1000;
1246         }
1247
1248         if ((prop = node.property ("name")) != 0) {
1249                 _name = prop->value ();
1250         }
1251
1252         if ((prop = node.property (X_("sample-rate"))) != 0) {
1253
1254                 _nominal_frame_rate = atoi (prop->value());
1255
1256                 if (_nominal_frame_rate != _current_frame_rate) {
1257                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1258                         if (r.get_value_or (0)) {
1259                                 return -1;
1260                         }
1261                 }
1262         }
1263
1264         setup_raid_path(_session_dir->root_path().to_string());
1265
1266         if ((prop = node.property (X_("id-counter"))) != 0) {
1267                 uint64_t x;
1268                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1269                 ID::init_counter (x);
1270         } else {
1271                 /* old sessions used a timebased counter, so fake
1272                    the startup ID counter based on a standard
1273                    timestamp.
1274                 */
1275                 time_t now;
1276                 time (&now);
1277                 ID::init_counter (now);
1278         }
1279
1280         if ((prop = node.property (X_("event-counter"))) != 0) {
1281                 Evoral::init_event_id_counter (atoi (prop->value()));
1282         }
1283
1284         IO::disable_connecting ();
1285
1286         Stateful::save_extra_xml (node);
1287
1288         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1289                 load_options (*child);
1290         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1291                 load_options (*child);
1292         } else {
1293                 error << _("Session: XML state has no options section") << endmsg;
1294         }
1295
1296         if (version >= 3000) {
1297                 if ((child = find_named_node (node, "Metadata")) == 0) {
1298                         warning << _("Session: XML state has no metadata section") << endmsg;
1299                 } else if (_metadata->set_state (*child, version)) {
1300                         goto out;
1301                 }
1302         }
1303
1304         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1305                 _speakers->set_state (*child, version);
1306         }
1307
1308         if ((child = find_named_node (node, "Sources")) == 0) {
1309                 error << _("Session: XML state has no sources section") << endmsg;
1310                 goto out;
1311         } else if (load_sources (*child)) {
1312                 goto out;
1313         }
1314
1315         if ((child = find_named_node (node, "TempoMap")) == 0) {
1316                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1317                 goto out;
1318         } else if (_tempo_map->set_state (*child, version)) {
1319                 goto out;
1320         }
1321
1322         if ((child = find_named_node (node, "Locations")) == 0) {
1323                 error << _("Session: XML state has no locations section") << endmsg;
1324                 goto out;
1325         } else if (_locations->set_state (*child, version)) {
1326                 goto out;
1327         }
1328
1329         Location* location;
1330
1331         if ((location = _locations->auto_loop_location()) != 0) {
1332                 set_auto_loop_location (location);
1333         }
1334
1335         if ((location = _locations->auto_punch_location()) != 0) {
1336                 set_auto_punch_location (location);
1337         }
1338
1339         if ((location = _locations->session_range_location()) != 0) {
1340                 delete _session_range_location;
1341                 _session_range_location = location;
1342         }
1343
1344         if (_session_range_location) {
1345                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1346         }
1347
1348         if ((child = find_named_node (node, "Regions")) == 0) {
1349                 error << _("Session: XML state has no Regions section") << endmsg;
1350                 goto out;
1351         } else if (load_regions (*child)) {
1352                 goto out;
1353         }
1354
1355         if ((child = find_named_node (node, "Playlists")) == 0) {
1356                 error << _("Session: XML state has no playlists section") << endmsg;
1357                 goto out;
1358         } else if (playlists->load (*this, *child)) {
1359                 goto out;
1360         }
1361
1362         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1363                 // this is OK
1364         } else if (playlists->load_unused (*this, *child)) {
1365                 goto out;
1366         }
1367
1368         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1369                 if (load_compounds (*child)) {
1370                         goto out;
1371                 }
1372         }
1373
1374         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1375                 if (load_named_selections (*child)) {
1376                         goto out;
1377                 }
1378         }
1379
1380         if (version >= 3000) {
1381                 if ((child = find_named_node (node, "Bundles")) == 0) {
1382                         warning << _("Session: XML state has no bundles section") << endmsg;
1383                         //goto out;
1384                 } else {
1385                         /* We can't load Bundles yet as they need to be able
1386                            to convert from port names to Port objects, which can't happen until
1387                            later */
1388                         _bundle_xml_node = new XMLNode (*child);
1389                 }
1390         }
1391
1392         if (version < 3000) {
1393                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1394                         error << _("Session: XML state has no diskstreams section") << endmsg;
1395                         goto out;
1396                 } else if (load_diskstreams_2X (*child, version)) {
1397                         goto out;
1398                 }
1399         }
1400
1401         if ((child = find_named_node (node, "Routes")) == 0) {
1402                 error << _("Session: XML state has no routes section") << endmsg;
1403                 goto out;
1404         } else if (load_routes (*child, version)) {
1405                 goto out;
1406         }
1407
1408         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1409         _diskstreams_2X.clear ();
1410
1411         if (version >= 3000) {
1412
1413                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1414                         error << _("Session: XML state has no route groups section") << endmsg;
1415                         goto out;
1416                 } else if (load_route_groups (*child, version)) {
1417                         goto out;
1418                 }
1419
1420         } else if (version < 3000) {
1421
1422                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1423                         error << _("Session: XML state has no edit groups section") << endmsg;
1424                         goto out;
1425                 } else if (load_route_groups (*child, version)) {
1426                         goto out;
1427                 }
1428
1429                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1430                         error << _("Session: XML state has no mix groups section") << endmsg;
1431                         goto out;
1432                 } else if (load_route_groups (*child, version)) {
1433                         goto out;
1434                 }
1435         }
1436
1437         if ((child = find_named_node (node, "Click")) == 0) {
1438                 warning << _("Session: XML state has no click section") << endmsg;
1439         } else if (_click_io) {
1440                 _click_io->set_state (*child, version);
1441         }
1442
1443         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1444                 ControlProtocolManager::instance().set_protocol_states (*child);
1445         }
1446
1447         /* here beginneth the second phase ... */
1448
1449         StateReady (); /* EMIT SIGNAL */
1450
1451         return 0;
1452
1453   out:
1454         return ret;
1455 }
1456
1457 int
1458 Session::load_routes (const XMLNode& node, int version)
1459 {
1460         XMLNodeList nlist;
1461         XMLNodeConstIterator niter;
1462         RouteList new_routes;
1463
1464         nlist = node.children();
1465
1466         set_dirty();
1467
1468         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1469
1470                 boost::shared_ptr<Route> route;
1471                 if (version < 3000) {
1472                         route = XMLRouteFactory_2X (**niter, version);
1473                 } else {
1474                         route = XMLRouteFactory (**niter, version);
1475                 }
1476
1477                 if (route == 0) {
1478                         error << _("Session: cannot create Route from XML description.") << endmsg;
1479                         return -1;
1480                 }
1481
1482                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1483
1484                 new_routes.push_back (route);
1485         }
1486
1487         add_routes (new_routes, false, false);
1488
1489         return 0;
1490 }
1491
1492 boost::shared_ptr<Route>
1493 Session::XMLRouteFactory (const XMLNode& node, int version)
1494 {
1495         boost::shared_ptr<Route> ret;
1496
1497         if (node.name() != "Route") {
1498                 return ret;
1499         }
1500
1501         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1502
1503         DataType type = DataType::AUDIO;
1504         const XMLProperty* prop = node.property("default-type");
1505
1506         if (prop) {
1507                 type = DataType (prop->value());
1508         }
1509
1510         assert (type != DataType::NIL);
1511
1512         if (ds_child) {
1513
1514                 boost::shared_ptr<Track> track;
1515
1516                 if (type == DataType::AUDIO) {
1517                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1518                 } else {
1519                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1520                 }
1521
1522                 if (track->init()) {
1523                         return ret;
1524                 }
1525
1526                 if (track->set_state (node, version)) {
1527                         return ret;
1528                 }
1529
1530 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1531                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1532 #endif
1533                 ret = track;
1534
1535         } else {
1536                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1537
1538                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1539 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1540                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1541 #endif
1542                         ret = r;
1543                 }
1544         }
1545
1546         return ret;
1547 }
1548
1549 boost::shared_ptr<Route>
1550 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1551 {
1552         boost::shared_ptr<Route> ret;
1553
1554         if (node.name() != "Route") {
1555                 return ret;
1556         }
1557
1558         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1559         if (!ds_prop) {
1560                 ds_prop = node.property (X_("diskstream"));
1561         }
1562
1563         DataType type = DataType::AUDIO;
1564         const XMLProperty* prop = node.property("default-type");
1565
1566         if (prop) {
1567                 type = DataType (prop->value());
1568         }
1569
1570         assert (type != DataType::NIL);
1571
1572         if (ds_prop) {
1573
1574                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1575                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1576                         ++i;
1577                 }
1578
1579                 if (i == _diskstreams_2X.end()) {
1580                         error << _("Could not find diskstream for route") << endmsg;
1581                         return boost::shared_ptr<Route> ();
1582                 }
1583
1584                 boost::shared_ptr<Track> track;
1585
1586                 if (type == DataType::AUDIO) {
1587                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1588                 } else {
1589                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1590                 }
1591
1592                 if (track->init()) {
1593                         return ret;
1594                 }
1595
1596                 if (track->set_state (node, version)) {
1597                         return ret;
1598                 }
1599
1600                 track->set_diskstream (*i);
1601
1602 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1603                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1604 #endif
1605                 ret = track;
1606
1607         } else {
1608                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1609
1610                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1611 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1612                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1613 #endif
1614                         ret = r;
1615                 }
1616         }
1617
1618         return ret;
1619 }
1620
1621 int
1622 Session::load_regions (const XMLNode& node)
1623 {
1624         XMLNodeList nlist;
1625         XMLNodeConstIterator niter;
1626         boost::shared_ptr<Region> region;
1627
1628         nlist = node.children();
1629
1630         set_dirty();
1631
1632         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1633                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1634                         error << _("Session: cannot create Region from XML description.");
1635                         const XMLProperty *name = (**niter).property("name");
1636
1637                         if (name) {
1638                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1639                         }
1640
1641                         error << endmsg;
1642                 }
1643         }
1644
1645         return 0;
1646 }
1647
1648 int
1649 Session::load_compounds (const XMLNode& node)
1650 {
1651         XMLNodeList calist = node.children();
1652         XMLNodeConstIterator caiter;
1653         XMLProperty *caprop;
1654
1655         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1656                 XMLNode* ca = *caiter;
1657                 ID orig_id;
1658                 ID copy_id;
1659
1660                 if ((caprop = ca->property (X_("original"))) == 0) {
1661                         continue;
1662                 }
1663                 orig_id = caprop->value();
1664
1665                 if ((caprop = ca->property (X_("copy"))) == 0) {
1666                         continue;
1667                 }
1668                 copy_id = caprop->value();
1669
1670                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1671                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1672
1673                 if (!orig || !copy) {
1674                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1675                                                    orig_id, copy_id)
1676                                 << endmsg;
1677                         continue;
1678                 }
1679
1680                 RegionFactory::add_compound_association (orig, copy);
1681         }
1682
1683         return 0;
1684 }
1685
1686 void
1687 Session::load_nested_sources (const XMLNode& node)
1688 {
1689         XMLNodeList nlist;
1690         XMLNodeConstIterator niter;
1691
1692         nlist = node.children();
1693
1694         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1695                 if ((*niter)->name() == "Source") {
1696
1697                         /* it may already exist, so don't recreate it unnecessarily 
1698                          */
1699
1700                         XMLProperty* prop = (*niter)->property (X_("id"));
1701                         if (!prop) {
1702                                 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1703                                 continue;
1704                         }
1705
1706                         ID source_id (prop->value());
1707
1708                         if (!source_by_id (source_id)) {
1709
1710                                 try {
1711                                         SourceFactory::create (*this, **niter, true);
1712                                 }
1713                                 catch (failed_constructor& err) {
1714                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1715                                 }
1716                         }
1717                 }
1718         }
1719 }
1720
1721 boost::shared_ptr<Region>
1722 Session::XMLRegionFactory (const XMLNode& node, bool full)
1723 {
1724         const XMLProperty* type = node.property("type");
1725
1726         try {
1727
1728                 const XMLNodeList& nlist = node.children();
1729
1730                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1731                         XMLNode *child = (*niter);
1732                         if (child->name() == "NestedSource") {
1733                                 load_nested_sources (*child);
1734                         }
1735                 }
1736
1737                 if (!type || type->value() == "audio") {
1738                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1739                 } else if (type->value() == "midi") {
1740                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1741                 }
1742
1743         } catch (failed_constructor& err) {
1744                 return boost::shared_ptr<Region> ();
1745         }
1746
1747         return boost::shared_ptr<Region> ();
1748 }
1749
1750 boost::shared_ptr<AudioRegion>
1751 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1752 {
1753         const XMLProperty* prop;
1754         boost::shared_ptr<Source> source;
1755         boost::shared_ptr<AudioSource> as;
1756         SourceList sources;
1757         SourceList master_sources;
1758         uint32_t nchans = 1;
1759         char buf[128];
1760
1761         if (node.name() != X_("Region")) {
1762                 return boost::shared_ptr<AudioRegion>();
1763         }
1764
1765         if ((prop = node.property (X_("channels"))) != 0) {
1766                 nchans = atoi (prop->value().c_str());
1767         }
1768
1769         if ((prop = node.property ("name")) == 0) {
1770                 cerr << "no name for this region\n";
1771                 abort ();
1772         }
1773
1774         if ((prop = node.property (X_("source-0"))) == 0) {
1775                 if ((prop = node.property ("source")) == 0) {
1776                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1777                         return boost::shared_ptr<AudioRegion>();
1778                 }
1779         }
1780
1781         PBD::ID s_id (prop->value());
1782
1783         if ((source = source_by_id (s_id)) == 0) {
1784                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1785                 return boost::shared_ptr<AudioRegion>();
1786         }
1787
1788         as = boost::dynamic_pointer_cast<AudioSource>(source);
1789         if (!as) {
1790                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1791                 return boost::shared_ptr<AudioRegion>();
1792         }
1793
1794         sources.push_back (as);
1795
1796         /* pickup other channels */
1797
1798         for (uint32_t n=1; n < nchans; ++n) {
1799                 snprintf (buf, sizeof(buf), X_("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                         sources.push_back (as);
1815                 }
1816         }
1817
1818         for (uint32_t n = 0; n < nchans; ++n) {
1819                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1820                 if ((prop = node.property (buf)) != 0) {
1821
1822                         PBD::ID id2 (prop->value());
1823
1824                         if ((source = source_by_id (id2)) == 0) {
1825                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1826                                 return boost::shared_ptr<AudioRegion>();
1827                         }
1828
1829                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1830                         if (!as) {
1831                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1832                                 return boost::shared_ptr<AudioRegion>();
1833                         }
1834                         master_sources.push_back (as);
1835                 }
1836         }
1837
1838         try {
1839                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1840
1841                 /* a final detail: this is the one and only place that we know how long missing files are */
1842
1843                 if (region->whole_file()) {
1844                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1845                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1846                                 if (sfp) {
1847                                         sfp->set_length (region->length());
1848                                 }
1849                         }
1850                 }
1851
1852                 if (!master_sources.empty()) {
1853                         if (master_sources.size() != nchans) {
1854                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1855                         } else {
1856                                 region->set_master_sources (master_sources);
1857                         }
1858                 }
1859
1860                 return region;
1861
1862         }
1863
1864         catch (failed_constructor& err) {
1865                 return boost::shared_ptr<AudioRegion>();
1866         }
1867 }
1868
1869 boost::shared_ptr<MidiRegion>
1870 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1871 {
1872         const XMLProperty* prop;
1873         boost::shared_ptr<Source> source;
1874         boost::shared_ptr<MidiSource> ms;
1875         SourceList sources;
1876
1877         if (node.name() != X_("Region")) {
1878                 return boost::shared_ptr<MidiRegion>();
1879         }
1880
1881         if ((prop = node.property ("name")) == 0) {
1882                 cerr << "no name for this region\n";
1883                 abort ();
1884         }
1885
1886         if ((prop = node.property (X_("source-0"))) == 0) {
1887                 if ((prop = node.property ("source")) == 0) {
1888                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1889                         return boost::shared_ptr<MidiRegion>();
1890                 }
1891         }
1892
1893         PBD::ID s_id (prop->value());
1894
1895         if ((source = source_by_id (s_id)) == 0) {
1896                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1897                 return boost::shared_ptr<MidiRegion>();
1898         }
1899
1900         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1901         if (!ms) {
1902                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1903                 return boost::shared_ptr<MidiRegion>();
1904         }
1905
1906         sources.push_back (ms);
1907
1908         try {
1909                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1910                 /* a final detail: this is the one and only place that we know how long missing files are */
1911
1912                 if (region->whole_file()) {
1913                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1914                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1915                                 if (sfp) {
1916                                         sfp->set_length (region->length());
1917                                 }
1918                         }
1919                 }
1920
1921                 return region;
1922         }
1923
1924         catch (failed_constructor& err) {
1925                 return boost::shared_ptr<MidiRegion>();
1926         }
1927 }
1928
1929 XMLNode&
1930 Session::get_sources_as_xml ()
1931
1932 {
1933         XMLNode* node = new XMLNode (X_("Sources"));
1934         Glib::Mutex::Lock lm (source_lock);
1935
1936         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1937                 node->add_child_nocopy (i->second->get_state());
1938         }
1939
1940         return *node;
1941 }
1942
1943 string
1944 Session::path_from_region_name (DataType type, string name, string identifier)
1945 {
1946         char buf[PATH_MAX+1];
1947         uint32_t n;
1948         SessionDirectory sdir(get_best_session_directory_for_new_source());
1949         sys::path source_dir = ((type == DataType::AUDIO)
1950                 ? sdir.sound_path() : sdir.midi_path());
1951
1952         string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1953
1954         for (n = 0; n < 999999; ++n) {
1955                 if (identifier.length()) {
1956                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1957                                   identifier.c_str(), n, ext.c_str());
1958                 } else {
1959                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1960                                         n, ext.c_str());
1961                 }
1962
1963                 sys::path source_path = source_dir / buf;
1964
1965                 if (!sys::exists (source_path)) {
1966                         return source_path.to_string();
1967                 }
1968         }
1969
1970         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1971                                  name, identifier)
1972               << endmsg;
1973
1974         return "";
1975 }
1976
1977
1978 int
1979 Session::load_sources (const XMLNode& node)
1980 {
1981         XMLNodeList nlist;
1982         XMLNodeConstIterator niter;
1983         boost::shared_ptr<Source> source;
1984
1985         nlist = node.children();
1986
1987         set_dirty();
1988
1989         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1990           retry:
1991                 try {
1992                         if ((source = XMLSourceFactory (**niter)) == 0) {
1993                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1994                         }
1995
1996                 } catch (MissingSource& err) {
1997
1998                         int user_choice;
1999
2000                         if (!no_questions_about_missing_files) {
2001                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
2002                         } else {
2003                                 user_choice = -2;
2004                         }
2005
2006                         switch (user_choice) {
2007                         case 0:
2008                                 /* user added a new search location, so try again */
2009                                 goto retry;
2010
2011
2012                         case 1:
2013                                 /* user asked to quit the entire session load
2014                                  */
2015                                 return -1;
2016
2017                         case 2:
2018                                 no_questions_about_missing_files = true;
2019                                 goto retry;
2020
2021                         case 3:
2022                                 no_questions_about_missing_files = true;
2023                                 /* fallthru */
2024
2025                         case -1:
2026                         default:
2027                                 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
2028                                 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2029                                 break;
2030                         }
2031                 }
2032         }
2033
2034         return 0;
2035 }
2036
2037 boost::shared_ptr<Source>
2038 Session::XMLSourceFactory (const XMLNode& node)
2039 {
2040         if (node.name() != "Source") {
2041                 return boost::shared_ptr<Source>();
2042         }
2043
2044         try {
2045                 /* note: do peak building in another thread when loading session state */
2046                 return SourceFactory::create (*this, node, true);
2047         }
2048
2049         catch (failed_constructor& err) {
2050                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2051                 return boost::shared_ptr<Source>();
2052         }
2053 }
2054
2055 int
2056 Session::save_template (string template_name)
2057 {
2058         XMLTree tree;
2059
2060         if (_state_of_the_state & CannotSave) {
2061                 return -1;
2062         }
2063
2064         sys::path user_template_dir(user_template_directory());
2065
2066         try
2067         {
2068                 sys::create_directories (user_template_dir);
2069         }
2070         catch(sys::filesystem_error& ex)
2071         {
2072                 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2073                                 user_template_dir.to_string(), ex.what()) << endmsg;
2074                 return -1;
2075         }
2076
2077         tree.set_root (&get_template());
2078
2079         sys::path template_dir_path(user_template_dir);
2080         
2081         /* directory to put the template in */
2082         template_dir_path /= template_name;
2083         if (sys::exists (template_dir_path))
2084         {
2085                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2086                                 template_dir_path.to_string()) << endmsg;
2087                 return -1;
2088         }
2089         
2090         sys::create_directories (template_dir_path);
2091
2092         /* file to write */
2093         sys::path template_file_path = template_dir_path;
2094         template_file_path /= template_name + template_suffix;
2095
2096         if (!tree.write (template_file_path.to_string())) {
2097                 error << _("template not saved") << endmsg;
2098                 return -1;
2099         }
2100
2101         /* copy plugin state directory */
2102
2103         sys::path template_plugin_state_path = template_dir_path;
2104         template_plugin_state_path /= X_("plugins");
2105         sys::create_directories (template_plugin_state_path);
2106         sys::copy_files (plugins_dir(), template_plugin_state_path);
2107
2108         return 0;
2109 }
2110
2111 void
2112 Session::refresh_disk_space ()
2113 {
2114 #if HAVE_SYS_VFS_H
2115         struct statfs statfsbuf;
2116         vector<space_and_path>::iterator i;
2117         Glib::Mutex::Lock lm (space_lock);
2118         double scale;
2119
2120         /* get freespace on every FS that is part of the session path */
2121
2122         _total_free_4k_blocks = 0;
2123
2124         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2125                 statfs ((*i).path.c_str(), &statfsbuf);
2126
2127                 scale = statfsbuf.f_bsize/4096.0;
2128
2129                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2130                 _total_free_4k_blocks += (*i).blocks;
2131         }
2132 #endif
2133 }
2134
2135 string
2136 Session::get_best_session_directory_for_new_source ()
2137 {
2138         vector<space_and_path>::iterator i;
2139         string result = _session_dir->root_path().to_string();
2140
2141         /* handle common case without system calls */
2142
2143         if (session_dirs.size() == 1) {
2144                 return result;
2145         }
2146
2147         /* OK, here's the algorithm we're following here:
2148
2149         We want to select which directory to use for
2150         the next file source to be created. Ideally,
2151         we'd like to use a round-robin process so as to
2152         get maximum performance benefits from splitting
2153         the files across multiple disks.
2154
2155         However, in situations without much diskspace, an
2156         RR approach may end up filling up a filesystem
2157         with new files while others still have space.
2158         Its therefore important to pay some attention to
2159         the freespace in the filesystem holding each
2160         directory as well. However, if we did that by
2161         itself, we'd keep creating new files in the file
2162         system with the most space until it was as full
2163         as all others, thus negating any performance
2164         benefits of this RAID-1 like approach.
2165
2166         So, we use a user-configurable space threshold. If
2167         there are at least 2 filesystems with more than this
2168         much space available, we use RR selection between them.
2169         If not, then we pick the filesystem with the most space.
2170
2171         This gets a good balance between the two
2172         approaches.
2173         */
2174
2175         refresh_disk_space ();
2176
2177         int free_enough = 0;
2178
2179         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2180                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2181                         free_enough++;
2182                 }
2183         }
2184
2185         if (free_enough >= 2) {
2186                 /* use RR selection process, ensuring that the one
2187                    picked works OK.
2188                 */
2189
2190                 i = last_rr_session_dir;
2191
2192                 do {
2193                         if (++i == session_dirs.end()) {
2194                                 i = session_dirs.begin();
2195                         }
2196
2197                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2198                                 if (create_session_directory ((*i).path)) {
2199                                         result = (*i).path;
2200                                         last_rr_session_dir = i;
2201                                         return result;
2202                                 }
2203                         }
2204
2205                 } while (i != last_rr_session_dir);
2206
2207         } else {
2208
2209                 /* pick FS with the most freespace (and that
2210                    seems to actually work ...)
2211                 */
2212
2213                 vector<space_and_path> sorted;
2214                 space_and_path_ascending_cmp cmp;
2215
2216                 sorted = session_dirs;
2217                 sort (sorted.begin(), sorted.end(), cmp);
2218
2219                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2220                         if (create_session_directory ((*i).path)) {
2221                                 result = (*i).path;
2222                                 last_rr_session_dir = i;
2223                                 return result;
2224                         }
2225                 }
2226         }
2227
2228         return result;
2229 }
2230
2231 int
2232 Session::load_named_selections (const XMLNode& node)
2233 {
2234         XMLNodeList nlist;
2235         XMLNodeConstIterator niter;
2236         NamedSelection *ns;
2237
2238         nlist = node.children();
2239
2240         set_dirty();
2241
2242         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2243
2244                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2245                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2246                 }
2247         }
2248
2249         return 0;
2250 }
2251
2252 NamedSelection *
2253 Session::XMLNamedSelectionFactory (const XMLNode& node)
2254 {
2255         try {
2256                 return new NamedSelection (*this, node);
2257         }
2258
2259         catch (failed_constructor& err) {
2260                 return 0;
2261         }
2262 }
2263
2264 string
2265 Session::automation_dir () const
2266 {
2267         return Glib::build_filename (_path, "automation");
2268 }
2269
2270 string
2271 Session::analysis_dir () const
2272 {
2273         return Glib::build_filename (_path, "analysis");
2274 }
2275
2276 string
2277 Session::plugins_dir () const
2278 {
2279         return Glib::build_filename (_path, "plugins");
2280 }
2281
2282 int
2283 Session::load_bundles (XMLNode const & node)
2284 {
2285         XMLNodeList nlist = node.children();
2286         XMLNodeConstIterator niter;
2287
2288         set_dirty();
2289
2290         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2291                 if ((*niter)->name() == "InputBundle") {
2292                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2293                 } else if ((*niter)->name() == "OutputBundle") {
2294                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2295                 } else {
2296                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2297                         return -1;
2298                 }
2299         }
2300
2301         return 0;
2302 }
2303
2304 int
2305 Session::load_route_groups (const XMLNode& node, int version)
2306 {
2307         XMLNodeList nlist = node.children();
2308         XMLNodeConstIterator niter;
2309
2310         set_dirty ();
2311
2312         if (version >= 3000) {
2313
2314                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2315                         if ((*niter)->name() == "RouteGroup") {
2316                                 RouteGroup* rg = new RouteGroup (*this, "");
2317                                 add_route_group (rg);
2318                                 rg->set_state (**niter, version);
2319                         }
2320                 }
2321
2322         } else if (version < 3000) {
2323
2324                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2325                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2326                                 RouteGroup* rg = new RouteGroup (*this, "");
2327                                 add_route_group (rg);
2328                                 rg->set_state (**niter, version);
2329                         }
2330                 }
2331         }
2332
2333         return 0;
2334 }
2335
2336 void
2337 Session::auto_save()
2338 {
2339         save_state (_current_snapshot_name);
2340 }
2341
2342 static bool
2343 state_file_filter (const string &str, void */*arg*/)
2344 {
2345         return (str.length() > strlen(statefile_suffix) &&
2346                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2347 }
2348
2349 struct string_cmp {
2350         bool operator()(const string* a, const string* b) {
2351                 return *a < *b;
2352         }
2353 };
2354
2355 static string*
2356 remove_end(string* state)
2357 {
2358         string statename(*state);
2359
2360         string::size_type start,end;
2361         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2362                 statename = statename.substr (start+1);
2363         }
2364
2365         if ((end = statename.rfind(".ardour")) == string::npos) {
2366                 end = statename.length();
2367         }
2368
2369         return new string(statename.substr (0, end));
2370 }
2371
2372 vector<string *> *
2373 Session::possible_states (string path)
2374 {
2375         PathScanner scanner;
2376         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2377
2378         transform(states->begin(), states->end(), states->begin(), remove_end);
2379
2380         string_cmp cmp;
2381         sort (states->begin(), states->end(), cmp);
2382
2383         return states;
2384 }
2385
2386 vector<string *> *
2387 Session::possible_states () const
2388 {
2389         return possible_states(_path);
2390 }
2391
2392 void
2393 Session::add_route_group (RouteGroup* g)
2394 {
2395         _route_groups.push_back (g);
2396         route_group_added (g); /* EMIT SIGNAL */
2397
2398         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2399         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2400         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2401
2402         set_dirty ();
2403 }
2404
2405 void
2406 Session::remove_route_group (RouteGroup& rg)
2407 {
2408         list<RouteGroup*>::iterator i;
2409
2410         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2411                 _route_groups.erase (i);
2412                 delete &rg;
2413
2414                 route_group_removed (); /* EMIT SIGNAL */
2415         }
2416 }
2417
2418 /** Set a new order for our route groups, without adding or removing any.
2419  *  @param groups Route group list in the new order.
2420  */
2421 void
2422 Session::reorder_route_groups (list<RouteGroup*> groups)
2423 {
2424         _route_groups = groups;
2425
2426         route_groups_reordered (); /* EMIT SIGNAL */
2427         set_dirty ();
2428 }
2429
2430
2431 RouteGroup *
2432 Session::route_group_by_name (string name)
2433 {
2434         list<RouteGroup *>::iterator i;
2435
2436         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2437                 if ((*i)->name() == name) {
2438                         return* i;
2439                 }
2440         }
2441         return 0;
2442 }
2443
2444 RouteGroup&
2445 Session::all_route_group() const
2446 {
2447         return *_all_route_group;
2448 }
2449
2450 void
2451 Session::add_commands (vector<Command*> const & cmds)
2452 {
2453         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2454                 add_command (*i);
2455         }
2456 }
2457
2458 void
2459 Session::begin_reversible_command (const string& name)
2460 {
2461         begin_reversible_command (g_quark_from_string (name.c_str ()));
2462 }
2463
2464 /** Begin a reversible command using a GQuark to identify it.
2465  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2466  *  but there must be as many begin...()s as there are commit...()s.
2467  */
2468 void
2469 Session::begin_reversible_command (GQuark q)
2470 {
2471         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2472            to hold all the commands that are committed.  This keeps the order of
2473            commands correct in the history.
2474         */
2475
2476         if (_current_trans == 0) {
2477                 /* start a new transaction */
2478                 assert (_current_trans_quarks.empty ());
2479                 _current_trans = new UndoTransaction();
2480                 _current_trans->set_name (g_quark_to_string (q));
2481         }
2482
2483         _current_trans_quarks.push_front (q);
2484 }
2485
2486 void
2487 Session::commit_reversible_command (Command *cmd)
2488 {
2489         assert (_current_trans);
2490         assert (!_current_trans_quarks.empty ());
2491
2492         struct timeval now;
2493
2494         if (cmd) {
2495                 _current_trans->add_command (cmd);
2496         }
2497
2498         _current_trans_quarks.pop_front ();
2499
2500         if (!_current_trans_quarks.empty ()) {
2501                 /* the transaction we're committing is not the top-level one */
2502                 return;
2503         }
2504
2505         if (_current_trans->empty()) {
2506                 /* no commands were added to the transaction, so just get rid of it */
2507                 delete _current_trans;
2508                 _current_trans = 0;
2509                 return;
2510         }
2511
2512         gettimeofday (&now, 0);
2513         _current_trans->set_timestamp (now);
2514
2515         _history.add (_current_trans);
2516         _current_trans = 0;
2517 }
2518
2519 static bool
2520 accept_all_audio_files (const string& path, void */*arg*/)
2521 {
2522         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2523                 return false;
2524         }
2525
2526         if (!AudioFileSource::safe_audio_file_extension (path)) {
2527                 return false;
2528         }
2529
2530         return true;
2531 }
2532
2533 static bool
2534 accept_all_midi_files (const string& path, void */*arg*/)
2535 {
2536         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2537                 return false;
2538         }
2539
2540         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2541                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2542                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2543 }
2544
2545 static bool
2546 accept_all_state_files (const string& path, void */*arg*/)
2547 {
2548         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2549                 return false;
2550         }
2551
2552         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2553 }
2554
2555 int
2556 Session::find_all_sources (string path, set<string>& result)
2557 {
2558         XMLTree tree;
2559         XMLNode* node;
2560
2561         if (!tree.read (path)) {
2562                 return -1;
2563         }
2564
2565         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2566                 return -2;
2567         }
2568
2569         XMLNodeList nlist;
2570         XMLNodeConstIterator niter;
2571
2572         nlist = node->children();
2573
2574         set_dirty();
2575
2576         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2577
2578                 XMLProperty* prop;
2579
2580                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2581                         continue;
2582                 }
2583
2584                 DataType type (prop->value());
2585
2586                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2587                         continue;
2588                 }
2589
2590                 if (Glib::path_is_absolute (prop->value())) {
2591                         /* external file, ignore */
2592                         continue;
2593                 }
2594
2595                 string found_path;
2596                 bool is_new;
2597                 uint16_t chan;
2598
2599                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2600                         result.insert (found_path);
2601                 }
2602         }
2603
2604         return 0;
2605 }
2606
2607 int
2608 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2609 {
2610         PathScanner scanner;
2611         vector<string*>* state_files;
2612         string ripped;
2613         string this_snapshot_path;
2614
2615         result.clear ();
2616
2617         ripped = _path;
2618
2619         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2620                 ripped = ripped.substr (0, ripped.length() - 1);
2621         }
2622
2623         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2624
2625         if (state_files == 0) {
2626                 /* impossible! */
2627                 return 0;
2628         }
2629
2630         this_snapshot_path = _path;
2631         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2632         this_snapshot_path += statefile_suffix;
2633
2634         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2635
2636                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2637                         continue;
2638                 }
2639
2640                 if (find_all_sources (**i, result) < 0) {
2641                         return -1;
2642                 }
2643         }
2644
2645         return 0;
2646 }
2647
2648 struct RegionCounter {
2649     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2650     AudioSourceList::iterator iter;
2651     boost::shared_ptr<Region> region;
2652     uint32_t count;
2653
2654     RegionCounter() : count (0) {}
2655 };
2656
2657 int
2658 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2659 {
2660         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2661         return r.get_value_or (1);
2662 }
2663
2664 void
2665 Session::cleanup_regions ()
2666 {
2667         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2668
2669         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2670
2671                 uint32_t used = playlists->region_use_count (i->second);
2672
2673                 if (used == 0 && !i->second->automatic ()) {
2674                         RegionFactory::map_remove (i->second);
2675                 }
2676         }
2677
2678         /* dump the history list */
2679         _history.clear ();
2680
2681         save_state ("");
2682 }
2683
2684 int
2685 Session::cleanup_sources (CleanupReport& rep)
2686 {
2687         // FIXME: needs adaptation to midi
2688
2689         vector<boost::shared_ptr<Source> > dead_sources;
2690         PathScanner scanner;
2691         string audio_path;
2692         string midi_path;
2693         vector<space_and_path>::iterator i;
2694         vector<space_and_path>::iterator nexti;
2695         vector<string*>* candidates;
2696         vector<string*>* candidates2;
2697         vector<string> unused;
2698         set<string> all_sources;
2699         bool used;
2700         string spath;
2701         int ret = -1;
2702
2703         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2704
2705         /* consider deleting all unused playlists */
2706
2707         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2708                 ret = 0;
2709                 goto out;
2710         }
2711
2712         /* sync the "all regions" property of each playlist with its current state
2713          */
2714
2715         playlists->sync_all_regions_with_regions ();
2716
2717         /* find all un-used sources */
2718
2719         rep.paths.clear ();
2720         rep.space = 0;
2721
2722         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2723
2724                 SourceMap::iterator tmp;
2725
2726                 tmp = i;
2727                 ++tmp;
2728
2729                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2730                    capture files.
2731                 */
2732
2733                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2734                         dead_sources.push_back (i->second);
2735                         i->second->drop_references ();
2736                 }
2737
2738                 i = tmp;
2739         }
2740
2741         /* build a list of all the possible audio directories for the session */
2742
2743         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2744
2745                 nexti = i;
2746                 ++nexti;
2747
2748                 SessionDirectory sdir ((*i).path);
2749                 audio_path += sdir.sound_path().to_string();
2750
2751                 if (nexti != session_dirs.end()) {
2752                         audio_path += ':';
2753                 }
2754
2755                 i = nexti;
2756         }
2757
2758
2759         /* build a list of all the possible midi directories for the session */
2760
2761         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2762
2763                 nexti = i;
2764                 ++nexti;
2765
2766                 SessionDirectory sdir ((*i).path);
2767                 midi_path += sdir.midi_path().to_string();
2768
2769                 if (nexti != session_dirs.end()) {
2770                         midi_path += ':';
2771                 }
2772
2773                 i = nexti;
2774         }
2775
2776         candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2777         candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2778
2779         /* merge them */
2780
2781         if (candidates) {
2782                 if (candidates2) {
2783                         for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2784                                 candidates->push_back (*i);
2785                         }
2786                         delete candidates2;
2787                 }
2788         } else {
2789                 candidates = candidates2; // might still be null
2790         }
2791
2792         /* find all sources, but don't use this snapshot because the
2793            state file on disk still references sources we may have already
2794            dropped.
2795         */
2796
2797         find_all_sources_across_snapshots (all_sources, true);
2798
2799         /*  add our current source list
2800          */
2801
2802         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2803                 boost::shared_ptr<FileSource> fs;
2804                 SourceMap::iterator tmp = i;
2805                 ++tmp;
2806
2807                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2808                         if (playlists->source_use_count (fs) != 0) {
2809                                 all_sources.insert (fs->path());
2810                         } else {
2811
2812                                 /* we might not remove this source from disk, because it may be used
2813                                    by other snapshots, but its not being used in this version
2814                                    so lets get rid of it now, along with any representative regions
2815                                    in the region list.
2816                                 */
2817
2818                                 RegionFactory::remove_regions_using_source (i->second);
2819                                 sources.erase (i);
2820                         }
2821                 }
2822
2823                 i = tmp;
2824         }
2825
2826         char tmppath1[PATH_MAX+1];
2827         char tmppath2[PATH_MAX+1];
2828
2829         if (candidates) {
2830                 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2831
2832                         used = false;
2833                         spath = **x;
2834
2835                         for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2836
2837                                 if (realpath(spath.c_str(), tmppath1) == 0) {
2838                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2839                                                                  spath, strerror (errno)) << endmsg;
2840                                         continue;
2841                                 }
2842
2843                                 if (realpath((*i).c_str(),  tmppath2) == 0) {
2844                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2845                                                                  (*i), strerror (errno)) << endmsg;
2846                                         continue;
2847                                 }
2848
2849                                 if (strcmp(tmppath1, tmppath2) == 0) {
2850                                         used = true;
2851                                         break;
2852                                 }
2853                         }
2854
2855                         if (!used) {
2856                                 unused.push_back (spath);
2857                         }
2858
2859                         delete *x;
2860                 }
2861
2862                 delete candidates;
2863         }
2864
2865         /* now try to move all unused files into the "dead" directory(ies) */
2866
2867         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2868                 struct stat statbuf;
2869
2870                 string newpath;
2871
2872                 /* don't move the file across filesystems, just
2873                    stick it in the `dead_dir_name' directory
2874                    on whichever filesystem it was already on.
2875                 */
2876
2877                 if ((*x).find ("/sounds/") != string::npos) {
2878
2879                         /* old school, go up 1 level */
2880
2881                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2882                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2883
2884                 } else {
2885
2886                         /* new school, go up 4 levels */
2887
2888                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2889                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2890                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2891                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2892                 }
2893
2894                 newpath = Glib::build_filename (newpath, dead_dir_name);
2895
2896                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2897                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2898                         return -1;
2899                 }
2900
2901                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2902
2903                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2904
2905                         /* the new path already exists, try versioning */
2906
2907                         char buf[PATH_MAX+1];
2908                         int version = 1;
2909                         string newpath_v;
2910
2911                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2912                         newpath_v = buf;
2913
2914                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2915                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2916                                 newpath_v = buf;
2917                         }
2918
2919                         if (version == 999) {
2920                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2921                                                   newpath)
2922                                       << endmsg;
2923                         } else {
2924                                 newpath = newpath_v;
2925                         }
2926
2927                 } else {
2928
2929                         /* it doesn't exist, or we can't read it or something */
2930
2931                 }
2932
2933                 stat ((*x).c_str(), &statbuf);
2934
2935                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2936                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2937                                           (*x), newpath, strerror (errno))
2938                               << endmsg;
2939                         goto out;
2940                 }
2941
2942                 /* see if there an easy to find peakfile for this file, and remove it.
2943                  */
2944
2945                 string base = basename_nosuffix (*x);
2946                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2947                                  or for the first channel of embedded files. it will miss
2948                                  some peakfiles for other channels
2949                               */
2950                 string peakpath = peak_path (base);
2951
2952                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2953                         if (::unlink (peakpath.c_str()) != 0) {
2954                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2955                                                          peakpath, _path, strerror (errno))
2956                                       << endmsg;
2957                                 /* try to back out */
2958                                 ::rename (newpath.c_str(), _path.c_str());
2959                                 goto out;
2960                         }
2961                 }
2962
2963                 rep.paths.push_back (*x);
2964                 rep.space += statbuf.st_size;
2965         }
2966
2967         /* dump the history list */
2968
2969         _history.clear ();
2970
2971         /* save state so we don't end up a session file
2972            referring to non-existent sources.
2973         */
2974
2975         save_state ("");
2976         ret = 0;
2977
2978   out:
2979         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2980
2981         return ret;
2982 }
2983
2984 int
2985 Session::cleanup_trash_sources (CleanupReport& rep)
2986 {
2987         // FIXME: needs adaptation for MIDI
2988
2989         vector<space_and_path>::iterator i;
2990         string dead_dir;
2991
2992         rep.paths.clear ();
2993         rep.space = 0;
2994
2995         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2996
2997                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2998
2999                 clear_directory (dead_dir, &rep.space, &rep.paths);
3000         }
3001
3002         return 0;
3003 }
3004
3005 void
3006 Session::set_dirty ()
3007 {
3008         bool was_dirty = dirty();
3009
3010         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3011
3012
3013         if (!was_dirty) {
3014                 DirtyChanged(); /* EMIT SIGNAL */
3015         }
3016 }
3017
3018
3019 void
3020 Session::set_clean ()
3021 {
3022         bool was_dirty = dirty();
3023
3024         _state_of_the_state = Clean;
3025
3026
3027         if (was_dirty) {
3028                 DirtyChanged(); /* EMIT SIGNAL */
3029         }
3030 }
3031
3032 void
3033 Session::set_deletion_in_progress ()
3034 {
3035         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3036 }
3037
3038 void
3039 Session::clear_deletion_in_progress ()
3040 {
3041         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3042 }
3043
3044 void
3045 Session::add_controllable (boost::shared_ptr<Controllable> c)
3046 {
3047         /* this adds a controllable to the list managed by the Session.
3048            this is a subset of those managed by the Controllable class
3049            itself, and represents the only ones whose state will be saved
3050            as part of the session.
3051         */
3052
3053         Glib::Mutex::Lock lm (controllables_lock);
3054         controllables.insert (c);
3055 }
3056
3057 struct null_deleter { void operator()(void const *) const {} };
3058
3059 void
3060 Session::remove_controllable (Controllable* c)
3061 {
3062         if (_state_of_the_state | Deletion) {
3063                 return;
3064         }
3065
3066         Glib::Mutex::Lock lm (controllables_lock);
3067
3068         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3069
3070         if (x != controllables.end()) {
3071                 controllables.erase (x);
3072         }
3073 }
3074
3075 boost::shared_ptr<Controllable>
3076 Session::controllable_by_id (const PBD::ID& id)
3077 {
3078         Glib::Mutex::Lock lm (controllables_lock);
3079
3080         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3081                 if ((*i)->id() == id) {
3082                         return *i;
3083                 }
3084         }
3085
3086         return boost::shared_ptr<Controllable>();
3087 }
3088
3089 boost::shared_ptr<Controllable>
3090 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3091 {
3092         boost::shared_ptr<Controllable> c;
3093         boost::shared_ptr<Route> r;
3094
3095         switch (desc.top_level_type()) {
3096         case ControllableDescriptor::NamedRoute:
3097         {
3098                 std::string str = desc.top_level_name();
3099                 if (str == "master") {
3100                         r = _master_out;
3101                 } else if (str == "control" || str == "listen") {
3102                         r = _monitor_out;
3103                 } else {
3104                         r = route_by_name (desc.top_level_name());
3105                 }
3106                 break;
3107         }
3108
3109         case ControllableDescriptor::RemoteControlID:
3110                 r = route_by_remote_id (desc.rid());
3111                 break;
3112         }
3113
3114         if (!r) {
3115                 return c;
3116         }
3117
3118         switch (desc.subtype()) {
3119         case ControllableDescriptor::Gain:
3120                 c = r->gain_control ();
3121                 break;
3122
3123         case ControllableDescriptor::Solo:
3124                 c = r->solo_control();
3125                 break;
3126
3127         case ControllableDescriptor::Mute:
3128                 c = r->mute_control();
3129                 break;
3130
3131         case ControllableDescriptor::Recenable:
3132         {
3133                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3134
3135                 if (t) {
3136                         c = t->rec_enable_control ();
3137                 }
3138                 break;
3139         }
3140
3141         case ControllableDescriptor::PanDirection:
3142         {
3143                 c = r->pannable()->pan_azimuth_control;
3144                 break;
3145         }
3146
3147         case ControllableDescriptor::PanWidth:
3148         {
3149                 c = r->pannable()->pan_width_control;
3150                 break;
3151         }
3152
3153         case ControllableDescriptor::PanElevation:
3154         {
3155                 c = r->pannable()->pan_elevation_control;
3156                 break;
3157         }
3158
3159         case ControllableDescriptor::Balance:
3160                 /* XXX simple pan control */
3161                 break;
3162
3163         case ControllableDescriptor::PluginParameter:
3164         {
3165                 uint32_t plugin = desc.target (0);
3166                 uint32_t parameter_index = desc.target (1);
3167
3168                 /* revert to zero based counting */
3169
3170                 if (plugin > 0) {
3171                         --plugin;
3172                 }
3173
3174                 if (parameter_index > 0) {
3175                         --parameter_index;
3176                 }
3177
3178                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3179
3180                 if (p) {
3181                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3182                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3183                 }
3184                 break;
3185         }
3186
3187         case ControllableDescriptor::SendGain:
3188         {
3189                 uint32_t send = desc.target (0);
3190
3191                 /* revert to zero-based counting */
3192
3193                 if (send > 0) {
3194                         --send;
3195                 }
3196
3197                 boost::shared_ptr<Processor> p = r->nth_send (send);
3198
3199                 if (p) {
3200                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3201                         boost::shared_ptr<Amp> a = s->amp();
3202
3203                         if (a) {
3204                                 c = s->amp()->gain_control();
3205                         }
3206                 }
3207                 break;
3208         }
3209
3210         default:
3211                 /* relax and return a null pointer */
3212                 break;
3213         }
3214
3215         return c;
3216 }
3217
3218 void
3219 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3220 {
3221         if (_writable) {
3222                 Stateful::add_instant_xml (node, _path);
3223         }
3224
3225         if (write_to_config) {
3226                 Config->add_instant_xml (node);
3227         }
3228 }
3229
3230 XMLNode*
3231 Session::instant_xml (const string& node_name)
3232 {
3233         return Stateful::instant_xml (node_name, _path);
3234 }
3235
3236 int
3237 Session::save_history (string snapshot_name)
3238 {
3239         XMLTree tree;
3240
3241         if (!_writable) {
3242                 return 0;
3243         }
3244
3245         if (snapshot_name.empty()) {
3246                 snapshot_name = _current_snapshot_name;
3247         }
3248
3249         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3250         const string backup_filename = history_filename + backup_suffix;
3251         const sys::path xml_path = _session_dir->root_path() / history_filename;
3252         const sys::path backup_path = _session_dir->root_path() / backup_filename;
3253
3254         if (sys::exists (xml_path)) {
3255                 try
3256                 {
3257                         sys::rename (xml_path, backup_path);
3258                 }
3259                 catch (const sys::filesystem_error& err)
3260                 {
3261                         error << _("could not backup old history file, current history not saved") << endmsg;
3262                         return -1;
3263                 }
3264         }
3265
3266         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3267                 return 0;
3268         }
3269
3270         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3271
3272         if (!tree.write (xml_path.to_string()))
3273         {
3274                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3275
3276                 try
3277                 {
3278                         sys::remove (xml_path);
3279                         sys::rename (backup_path, xml_path);
3280                 }
3281                 catch (const sys::filesystem_error& err)
3282                 {
3283                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3284                                         backup_path.to_string(), err.what()) << endmsg;
3285                 }
3286
3287                 return -1;
3288         }
3289
3290         return 0;
3291 }
3292
3293 int
3294 Session::restore_history (string snapshot_name)
3295 {
3296         XMLTree tree;
3297
3298         if (snapshot_name.empty()) {
3299                 snapshot_name = _current_snapshot_name;
3300         }
3301
3302         const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3303         const sys::path xml_path = _session_dir->root_path() / xml_filename;
3304
3305         info << "Loading history from " << xml_path.to_string() << endmsg;
3306
3307         if (!sys::exists (xml_path)) {
3308                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3309                                 _name, xml_path.to_string()) << endmsg;
3310                 return 1;
3311         }
3312
3313         if (!tree.read (xml_path.to_string())) {
3314                 error << string_compose (_("Could not understand session history file \"%1\""),
3315                                 xml_path.to_string()) << endmsg;
3316                 return -1;
3317         }
3318
3319         // replace history
3320         _history.clear();
3321
3322         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3323
3324                 XMLNode *t = *it;
3325                 UndoTransaction* ut = new UndoTransaction ();
3326                 struct timeval tv;
3327
3328                 ut->set_name(t->property("name")->value());
3329                 stringstream ss(t->property("tv-sec")->value());
3330                 ss >> tv.tv_sec;
3331                 ss.str(t->property("tv-usec")->value());
3332                 ss >> tv.tv_usec;
3333                 ut->set_timestamp(tv);
3334
3335                 for (XMLNodeConstIterator child_it  = t->children().begin();
3336                                 child_it != t->children().end(); child_it++)
3337                 {
3338                         XMLNode *n = *child_it;
3339                         Command *c;
3340
3341                         if (n->name() == "MementoCommand" ||
3342                                         n->name() == "MementoUndoCommand" ||
3343                                         n->name() == "MementoRedoCommand") {
3344
3345                                 if ((c = memento_command_factory(n))) {
3346                                         ut->add_command(c);
3347                                 }
3348
3349                         } else if (n->name() == "NoteDiffCommand") {
3350                                 PBD::ID id (n->property("midi-source")->value());
3351                                 boost::shared_ptr<MidiSource> midi_source =
3352                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3353                                 if (midi_source) {
3354                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3355                                 } else {
3356                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3357                                 }
3358
3359                         } else if (n->name() == "SysExDiffCommand") {
3360
3361                                 PBD::ID id (n->property("midi-source")->value());
3362                                 boost::shared_ptr<MidiSource> midi_source =
3363                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3364                                 if (midi_source) {
3365                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3366                                 } else {
3367                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3368                                 }
3369
3370                         } else if (n->name() == "PatchChangeDiffCommand") {
3371
3372                                 PBD::ID id (n->property("midi-source")->value());
3373                                 boost::shared_ptr<MidiSource> midi_source =
3374                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3375                                 if (midi_source) {
3376                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3377                                 } else {
3378                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3379                                 }
3380
3381                         } else if (n->name() == "StatefulDiffCommand") {
3382                                 if ((c = stateful_diff_command_factory (n))) {
3383                                         ut->add_command (c);
3384                                 }
3385                         } else {
3386                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3387                         }
3388                 }
3389
3390                 _history.add (ut);
3391         }
3392
3393         return 0;
3394 }
3395
3396 void
3397 Session::config_changed (std::string p, bool ours)
3398 {
3399         if (ours) {
3400                 set_dirty ();
3401         }
3402
3403         if (p == "seamless-loop") {
3404
3405         } else if (p == "rf-speed") {
3406
3407         } else if (p == "auto-loop") {
3408
3409         } else if (p == "auto-input") {
3410
3411                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3412                         /* auto-input only makes a difference if we're rolling */
3413                         set_track_monitor_input_status (!config.get_auto_input());
3414                 }
3415
3416         } else if (p == "punch-in") {
3417
3418                 Location* location;
3419
3420                 if ((location = _locations->auto_punch_location()) != 0) {
3421
3422                         if (config.get_punch_in ()) {
3423                                 replace_event (SessionEvent::PunchIn, location->start());
3424                         } else {
3425                                 remove_event (location->start(), SessionEvent::PunchIn);
3426                         }
3427                 }
3428
3429         } else if (p == "punch-out") {
3430
3431                 Location* location;
3432
3433                 if ((location = _locations->auto_punch_location()) != 0) {
3434
3435                         if (config.get_punch_out()) {
3436                                 replace_event (SessionEvent::PunchOut, location->end());
3437                         } else {
3438                                 clear_events (SessionEvent::PunchOut);
3439                         }
3440                 }
3441
3442         } else if (p == "edit-mode") {
3443
3444                 Glib::Mutex::Lock lm (playlists->lock);
3445
3446                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3447                         (*i)->set_edit_mode (Config->get_edit_mode ());
3448                 }
3449
3450         } else if (p == "use-video-sync") {
3451
3452                 waiting_for_sync_offset = config.get_use_video_sync();
3453
3454         } else if (p == "mmc-control") {
3455
3456                 //poke_midi_thread ();
3457
3458         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3459
3460                 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3461
3462         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3463
3464                 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3465
3466         } else if (p == "midi-control") {
3467
3468                 //poke_midi_thread ();
3469
3470         } else if (p == "raid-path") {
3471
3472                 setup_raid_path (config.get_raid_path());
3473
3474         } else if (p == "timecode-format") {
3475
3476                 sync_time_vars ();
3477
3478         } else if (p == "video-pullup") {
3479
3480                 sync_time_vars ();
3481
3482         } else if (p == "seamless-loop") {
3483
3484                 if (play_loop && transport_rolling()) {
3485                         // to reset diskstreams etc
3486                         request_play_loop (true);
3487                 }
3488
3489         } else if (p == "rf-speed") {
3490
3491                 cumulative_rf_motion = 0;
3492                 reset_rf_scale (0);
3493
3494         } else if (p == "click-sound") {
3495
3496                 setup_click_sounds (1);
3497
3498         } else if (p == "click-emphasis-sound") {
3499
3500                 setup_click_sounds (-1);
3501
3502         } else if (p == "clicking") {
3503
3504                 if (Config->get_clicking()) {
3505                         if (_click_io && click_data) { // don't require emphasis data
3506                                 _clicking = true;
3507                         }
3508                 } else {
3509                         _clicking = false;
3510                 }
3511
3512         } else if (p == "send-mtc") {
3513
3514                 if (Config->get_send_mtc ()) {
3515                         /* mark us ready to send */
3516                         next_quarter_frame_to_send = 0;
3517                 }
3518
3519         } else if (p == "send-mmc") {
3520
3521                 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3522
3523         } else if (p == "midi-feedback") {
3524
3525                 session_midi_feedback = Config->get_midi_feedback();
3526
3527         } else if (p == "jack-time-master") {
3528
3529                 engine().reset_timebase ();
3530
3531         } else if (p == "native-file-header-format") {
3532
3533                 if (!first_file_header_format_reset) {
3534                         reset_native_file_format ();
3535                 }
3536
3537                 first_file_header_format_reset = false;
3538
3539         } else if (p == "native-file-data-format") {
3540
3541                 if (!first_file_data_format_reset) {
3542                         reset_native_file_format ();
3543                 }
3544
3545                 first_file_data_format_reset = false;
3546
3547         } else if (p == "external-sync") {
3548                 if (!config.get_external_sync()) {
3549                         drop_sync_source ();
3550                 } else {
3551                         switch_to_sync_source (config.get_sync_source());
3552                 }
3553         } else if (p == "remote-model") {
3554                 set_remote_control_ids ();
3555         }  else if (p == "denormal-model") {
3556                 setup_fpu ();
3557         } else if (p == "history-depth") {
3558                 set_history_depth (Config->get_history_depth());
3559         } else if (p == "sync-all-route-ordering") {
3560                 sync_order_keys ("session");
3561         } else if (p == "initial-program-change") {
3562
3563                 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3564                         MIDI::byte buf[2];
3565
3566                         buf[0] = MIDI::program; // channel zero by default
3567                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3568
3569                         MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3570                 }
3571         } else if (p == "solo-mute-override") {
3572                 // catch_up_on_solo_mute_override ();
3573         } else if (p == "listen-position" || p == "pfl-position") {
3574                 listen_position_changed ();
3575         } else if (p == "solo-control-is-listen-control") {
3576                 solo_control_mode_changed ();
3577         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3578                 last_timecode_valid = false;
3579         } else if (p == "playback-buffer-seconds") {
3580                 AudioSource::allocate_working_buffers (frame_rate());
3581         }
3582
3583         set_dirty ();
3584 }
3585
3586 void
3587 Session::set_history_depth (uint32_t d)
3588 {
3589         _history.set_depth (d);
3590 }
3591
3592 int
3593 Session::load_diskstreams_2X (XMLNode const & node, int)
3594 {
3595         XMLNodeList          clist;
3596         XMLNodeConstIterator citer;
3597
3598         clist = node.children();
3599
3600         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3601
3602                 try {
3603                         /* diskstreams added automatically by DiskstreamCreated handler */
3604                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3605                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3606                                 _diskstreams_2X.push_back (dsp);
3607                         } else {
3608                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3609                         }
3610                 }
3611
3612                 catch (failed_constructor& err) {
3613                         error << _("Session: could not load diskstream via XML state") << endmsg;
3614                         return -1;
3615                 }
3616         }
3617
3618         return 0;
3619 }
3620
3621 /** Connect things to the MMC object */
3622 void
3623 Session::setup_midi_machine_control ()
3624 {
3625         MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3626
3627         mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3628         mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3629         mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3630         mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3631         mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3632         mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3633         mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3634         mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3635         mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3636         mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3637         mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3638         mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3639         mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3640
3641         /* also handle MIDI SPP because its so common */
3642
3643         mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3644         mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3645         mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3646 }
3647
3648 boost::shared_ptr<Controllable>
3649 Session::solo_cut_control() const
3650 {
3651         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3652            controls in Ardour that currently get presented to the user in the GUI that require
3653            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3654
3655            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3656            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3657            parameter.
3658         */
3659
3660         return _solo_cut_control;
3661 }
3662
3663 int
3664 Session::rename (const std::string& new_name)
3665 {
3666         string legal_name = legalize_for_path (new_name);
3667         string newpath;
3668         string oldstr;
3669         string newstr;
3670         bool first = true;
3671
3672         string const old_sources_root = _session_dir->sources_root().to_string ();
3673
3674 #define RENAME ::rename
3675
3676         /* Rename:
3677
3678          * session directory
3679          * interchange subdirectory
3680          * session file
3681          * session history
3682          
3683          * Backup files are left unchanged and not renamed.
3684          */
3685
3686         /* pass one: not 100% safe check that the new directory names don't
3687          * already exist ...
3688          */
3689
3690         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3691                 vector<string> v;
3692
3693                 oldstr = (*i).path;
3694
3695                 /* this is a stupid hack because Glib::path_get_dirname() is
3696                  * lexical-only, and so passing it /a/b/c/ gives a different
3697                  * result than passing it /a/b/c ...
3698                  */
3699
3700                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3701                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3702                 }
3703
3704                 string base = Glib::path_get_dirname (oldstr);
3705                 string p = Glib::path_get_basename (oldstr);
3706
3707                 newstr = Glib::build_filename (base, legal_name);
3708                 
3709                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3710                         return -1;
3711                 }
3712         }
3713
3714         /* Session dirs */
3715         
3716         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3717                 vector<string> v;
3718
3719                 oldstr = (*i).path;
3720
3721                 /* this is a stupid hack because Glib::path_get_dirname() is
3722                  * lexical-only, and so passing it /a/b/c/ gives a different
3723                  * result than passing it /a/b/c ...
3724                  */
3725
3726                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3727                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3728                 }
3729
3730                 string base = Glib::path_get_dirname (oldstr);
3731                 string p = Glib::path_get_basename (oldstr);
3732
3733                 newstr = Glib::build_filename (base, legal_name);
3734
3735                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3736
3737                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3738                         return 1;
3739                 }
3740
3741                 if (first) {
3742                         (*_session_dir) = newstr;
3743                         newpath = newstr;
3744                         first = 1;
3745                 }
3746
3747                 /* directory below interchange */
3748
3749                 v.push_back (newstr);
3750                 v.push_back (interchange_dir_name);
3751                 v.push_back (p);
3752
3753                 oldstr = Glib::build_filename (v);
3754
3755                 v.clear ();
3756                 v.push_back (newstr);
3757                 v.push_back (interchange_dir_name);
3758                 v.push_back (legal_name);
3759
3760                 newstr = Glib::build_filename (v);
3761                 
3762                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3763                 
3764                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3765                         return 1;
3766                 }
3767         }
3768
3769         /* state file */
3770         
3771         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3772         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3773         
3774         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3775
3776         if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3777                 return 1;
3778         }
3779
3780         /* history file */
3781
3782         
3783         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3784
3785         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3786                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3787                 
3788                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3789                 
3790                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3791                         return 1;
3792                 }
3793         }
3794
3795         /* update file source paths */
3796         
3797         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3798                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3799                 if (fs) {
3800                         string p = fs->path ();
3801                         boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3802                         fs->set_path (p);
3803                 }
3804         }
3805
3806         /* remove old name from recent sessions */
3807
3808         remove_recent_sessions (_path);
3809
3810         _path = newpath;
3811         _current_snapshot_name = new_name;
3812         _name = new_name;
3813
3814         set_dirty ();
3815
3816         /* save state again to get everything just right */
3817
3818         save_state (_current_snapshot_name);
3819
3820
3821         /* add to recent sessions */
3822
3823         store_recent_sessions (new_name, _path);
3824
3825         return 0;
3826
3827 #undef RENAME
3828 }