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