Fix lingering references to old persist extension.
[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 mix 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                 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2667
2668                 if (!audio_region) {
2669                         continue;
2670                 }
2671
2672                 uint32_t used = playlists->region_use_count (audio_region);
2673
2674                 if (used == 0 && !audio_region->automatic()) {
2675                         RegionFactory::map_remove(i->second);
2676                 }
2677         }
2678
2679         /* dump the history list */
2680         _history.clear ();
2681
2682         save_state ("");
2683 }
2684
2685 int
2686 Session::cleanup_sources (CleanupReport& rep)
2687 {
2688         // FIXME: needs adaptation to midi
2689
2690         vector<boost::shared_ptr<Source> > dead_sources;
2691         PathScanner scanner;
2692         string audio_path;
2693         string midi_path;
2694         vector<space_and_path>::iterator i;
2695         vector<space_and_path>::iterator nexti;
2696         vector<string*>* candidates;
2697         vector<string*>* candidates2;
2698         vector<string> unused;
2699         set<string> all_sources;
2700         bool used;
2701         string spath;
2702         int ret = -1;
2703
2704         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2705
2706         /* consider deleting all unused playlists */
2707
2708         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2709                 ret = 0;
2710                 goto out;
2711         }
2712
2713         /* sync the "all regions" property of each playlist with its current state
2714          */
2715
2716         playlists->sync_all_regions_with_regions ();
2717
2718         /* find all un-used sources */
2719
2720         rep.paths.clear ();
2721         rep.space = 0;
2722
2723         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2724
2725                 SourceMap::iterator tmp;
2726
2727                 tmp = i;
2728                 ++tmp;
2729
2730                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2731                    capture files.
2732                 */
2733
2734                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2735                         dead_sources.push_back (i->second);
2736                         i->second->drop_references ();
2737                 }
2738
2739                 i = tmp;
2740         }
2741
2742         /* build a list of all the possible audio directories for the session */
2743
2744         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2745
2746                 nexti = i;
2747                 ++nexti;
2748
2749                 SessionDirectory sdir ((*i).path);
2750                 audio_path += sdir.sound_path().to_string();
2751
2752                 if (nexti != session_dirs.end()) {
2753                         audio_path += ':';
2754                 }
2755
2756                 i = nexti;
2757         }
2758
2759
2760         /* build a list of all the possible midi directories for the session */
2761
2762         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2763
2764                 nexti = i;
2765                 ++nexti;
2766
2767                 SessionDirectory sdir ((*i).path);
2768                 midi_path += sdir.midi_path().to_string();
2769
2770                 if (nexti != session_dirs.end()) {
2771                         midi_path += ':';
2772                 }
2773
2774                 i = nexti;
2775         }
2776
2777         candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2778         candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2779
2780         /* merge them */
2781
2782         if (candidates) {
2783                 if (candidates2) {
2784                         for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2785                                 candidates->push_back (*i);
2786                         }
2787                         delete candidates2;
2788                 }
2789         } else {
2790                 candidates = candidates2; // might still be null
2791         }
2792
2793         /* find all sources, but don't use this snapshot because the
2794            state file on disk still references sources we may have already
2795            dropped.
2796         */
2797
2798         find_all_sources_across_snapshots (all_sources, true);
2799
2800         /*  add our current source list
2801          */
2802
2803         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2804                 boost::shared_ptr<FileSource> fs;
2805                 SourceMap::iterator tmp = i;
2806                 ++tmp;
2807
2808                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2809                         if (playlists->source_use_count (fs) != 0) {
2810                                 all_sources.insert (fs->path());
2811                         } else {
2812
2813                                 /* we might not remove this source from disk, because it may be used
2814                                    by other snapshots, but its not being used in this version
2815                                    so lets get rid of it now, along with any representative regions
2816                                    in the region list.
2817                                 */
2818
2819                                 RegionFactory::remove_regions_using_source (i->second);
2820                                 sources.erase (i);
2821                         }
2822                 }
2823
2824                 i = tmp;
2825         }
2826
2827         char tmppath1[PATH_MAX+1];
2828         char tmppath2[PATH_MAX+1];
2829
2830         if (candidates) {
2831                 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2832
2833                         used = false;
2834                         spath = **x;
2835
2836                         for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2837
2838                                 if (realpath(spath.c_str(), tmppath1) == 0) {
2839                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2840                                                                  spath, strerror (errno)) << endmsg;
2841                                         continue;
2842                                 }
2843
2844                                 if (realpath((*i).c_str(),  tmppath2) == 0) {
2845                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2846                                                                  (*i), strerror (errno)) << endmsg;
2847                                         continue;
2848                                 }
2849
2850                                 if (strcmp(tmppath1, tmppath2) == 0) {
2851                                         used = true;
2852                                         break;
2853                                 }
2854                         }
2855
2856                         if (!used) {
2857                                 unused.push_back (spath);
2858                         }
2859
2860                         delete *x;
2861                 }
2862
2863                 delete candidates;
2864         }
2865
2866         /* now try to move all unused files into the "dead" directory(ies) */
2867
2868         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2869                 struct stat statbuf;
2870
2871                 string newpath;
2872
2873                 /* don't move the file across filesystems, just
2874                    stick it in the `dead_dir_name' directory
2875                    on whichever filesystem it was already on.
2876                 */
2877
2878                 if ((*x).find ("/sounds/") != string::npos) {
2879
2880                         /* old school, go up 1 level */
2881
2882                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2883                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2884
2885                 } else {
2886
2887                         /* new school, go up 4 levels */
2888
2889                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2890                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2891                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2892                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2893                 }
2894
2895                 newpath = Glib::build_filename (newpath, dead_dir_name);
2896
2897                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2898                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2899                         return -1;
2900                 }
2901
2902                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2903
2904                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2905
2906                         /* the new path already exists, try versioning */
2907
2908                         char buf[PATH_MAX+1];
2909                         int version = 1;
2910                         string newpath_v;
2911
2912                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2913                         newpath_v = buf;
2914
2915                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2916                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2917                                 newpath_v = buf;
2918                         }
2919
2920                         if (version == 999) {
2921                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2922                                                   newpath)
2923                                       << endmsg;
2924                         } else {
2925                                 newpath = newpath_v;
2926                         }
2927
2928                 } else {
2929
2930                         /* it doesn't exist, or we can't read it or something */
2931
2932                 }
2933
2934                 stat ((*x).c_str(), &statbuf);
2935
2936                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2937                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2938                                           (*x), newpath, strerror (errno))
2939                               << endmsg;
2940                         goto out;
2941                 }
2942
2943                 /* see if there an easy to find peakfile for this file, and remove it.
2944                  */
2945
2946                 string base = basename_nosuffix (*x);
2947                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2948                                  or for the first channel of embedded files. it will miss
2949                                  some peakfiles for other channels
2950                               */
2951                 string peakpath = peak_path (base);
2952
2953                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2954                         if (::unlink (peakpath.c_str()) != 0) {
2955                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2956                                                          peakpath, _path, strerror (errno))
2957                                       << endmsg;
2958                                 /* try to back out */
2959                                 ::rename (newpath.c_str(), _path.c_str());
2960                                 goto out;
2961                         }
2962                 }
2963
2964                 rep.paths.push_back (*x);
2965                 rep.space += statbuf.st_size;
2966         }
2967
2968         /* dump the history list */
2969
2970         _history.clear ();
2971
2972         /* save state so we don't end up a session file
2973            referring to non-existent sources.
2974         */
2975
2976         save_state ("");
2977         ret = 0;
2978
2979   out:
2980         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2981
2982         return ret;
2983 }
2984
2985 int
2986 Session::cleanup_trash_sources (CleanupReport& rep)
2987 {
2988         // FIXME: needs adaptation for MIDI
2989
2990         vector<space_and_path>::iterator i;
2991         string dead_dir;
2992
2993         rep.paths.clear ();
2994         rep.space = 0;
2995
2996         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2997
2998                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2999
3000                 clear_directory (dead_dir, &rep.space, &rep.paths);
3001         }
3002
3003         return 0;
3004 }
3005
3006 void
3007 Session::set_dirty ()
3008 {
3009         bool was_dirty = dirty();
3010
3011         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3012
3013
3014         if (!was_dirty) {
3015                 DirtyChanged(); /* EMIT SIGNAL */
3016         }
3017 }
3018
3019
3020 void
3021 Session::set_clean ()
3022 {
3023         bool was_dirty = dirty();
3024
3025         _state_of_the_state = Clean;
3026
3027
3028         if (was_dirty) {
3029                 DirtyChanged(); /* EMIT SIGNAL */
3030         }
3031 }
3032
3033 void
3034 Session::set_deletion_in_progress ()
3035 {
3036         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3037 }
3038
3039 void
3040 Session::clear_deletion_in_progress ()
3041 {
3042         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3043 }
3044
3045 void
3046 Session::add_controllable (boost::shared_ptr<Controllable> c)
3047 {
3048         /* this adds a controllable to the list managed by the Session.
3049            this is a subset of those managed by the Controllable class
3050            itself, and represents the only ones whose state will be saved
3051            as part of the session.
3052         */
3053
3054         Glib::Mutex::Lock lm (controllables_lock);
3055         controllables.insert (c);
3056 }
3057
3058 struct null_deleter { void operator()(void const *) const {} };
3059
3060 void
3061 Session::remove_controllable (Controllable* c)
3062 {
3063         if (_state_of_the_state | Deletion) {
3064                 return;
3065         }
3066
3067         Glib::Mutex::Lock lm (controllables_lock);
3068
3069         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3070
3071         if (x != controllables.end()) {
3072                 controllables.erase (x);
3073         }
3074 }
3075
3076 boost::shared_ptr<Controllable>
3077 Session::controllable_by_id (const PBD::ID& id)
3078 {
3079         Glib::Mutex::Lock lm (controllables_lock);
3080
3081         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3082                 if ((*i)->id() == id) {
3083                         return *i;
3084                 }
3085         }
3086
3087         return boost::shared_ptr<Controllable>();
3088 }
3089
3090 boost::shared_ptr<Controllable>
3091 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3092 {
3093         boost::shared_ptr<Controllable> c;
3094         boost::shared_ptr<Route> r;
3095
3096         switch (desc.top_level_type()) {
3097         case ControllableDescriptor::NamedRoute:
3098         {
3099                 std::string str = desc.top_level_name();
3100                 if (str == "master") {
3101                         r = _master_out;
3102                 } else if (str == "control" || str == "listen") {
3103                         r = _monitor_out;
3104                 } else {
3105                         r = route_by_name (desc.top_level_name());
3106                 }
3107                 break;
3108         }
3109
3110         case ControllableDescriptor::RemoteControlID:
3111                 r = route_by_remote_id (desc.rid());
3112                 break;
3113         }
3114
3115         if (!r) {
3116                 return c;
3117         }
3118
3119         switch (desc.subtype()) {
3120         case ControllableDescriptor::Gain:
3121                 c = r->gain_control ();
3122                 break;
3123
3124         case ControllableDescriptor::Solo:
3125                 c = r->solo_control();
3126                 break;
3127
3128         case ControllableDescriptor::Mute:
3129                 c = r->mute_control();
3130                 break;
3131
3132         case ControllableDescriptor::Recenable:
3133         {
3134                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3135
3136                 if (t) {
3137                         c = t->rec_enable_control ();
3138                 }
3139                 break;
3140         }
3141
3142         case ControllableDescriptor::PanDirection:
3143         {
3144                 c = r->pannable()->pan_azimuth_control;
3145                 break;
3146         }
3147
3148         case ControllableDescriptor::PanWidth:
3149         {
3150                 c = r->pannable()->pan_width_control;
3151                 break;
3152         }
3153
3154         case ControllableDescriptor::PanElevation:
3155         {
3156                 c = r->pannable()->pan_elevation_control;
3157                 break;
3158         }
3159
3160         case ControllableDescriptor::Balance:
3161                 /* XXX simple pan control */
3162                 break;
3163
3164         case ControllableDescriptor::PluginParameter:
3165         {
3166                 uint32_t plugin = desc.target (0);
3167                 uint32_t parameter_index = desc.target (1);
3168
3169                 /* revert to zero based counting */
3170
3171                 if (plugin > 0) {
3172                         --plugin;
3173                 }
3174
3175                 if (parameter_index > 0) {
3176                         --parameter_index;
3177                 }
3178
3179                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3180
3181                 if (p) {
3182                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3183                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3184                 }
3185                 break;
3186         }
3187
3188         case ControllableDescriptor::SendGain:
3189         {
3190                 uint32_t send = desc.target (0);
3191
3192                 /* revert to zero-based counting */
3193
3194                 if (send > 0) {
3195                         --send;
3196                 }
3197
3198                 boost::shared_ptr<Processor> p = r->nth_send (send);
3199
3200                 if (p) {
3201                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3202                         boost::shared_ptr<Amp> a = s->amp();
3203
3204                         if (a) {
3205                                 c = s->amp()->gain_control();
3206                         }
3207                 }
3208                 break;
3209         }
3210
3211         default:
3212                 /* relax and return a null pointer */
3213                 break;
3214         }
3215
3216         return c;
3217 }
3218
3219 void
3220 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3221 {
3222         if (_writable) {
3223                 Stateful::add_instant_xml (node, _path);
3224         }
3225
3226         if (write_to_config) {
3227                 Config->add_instant_xml (node);
3228         }
3229 }
3230
3231 XMLNode*
3232 Session::instant_xml (const string& node_name)
3233 {
3234         return Stateful::instant_xml (node_name, _path);
3235 }
3236
3237 int
3238 Session::save_history (string snapshot_name)
3239 {
3240         XMLTree tree;
3241
3242         if (!_writable) {
3243                 return 0;
3244         }
3245
3246         if (snapshot_name.empty()) {
3247                 snapshot_name = _current_snapshot_name;
3248         }
3249
3250         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3251         const string backup_filename = history_filename + backup_suffix;
3252         const sys::path xml_path = _session_dir->root_path() / history_filename;
3253         const sys::path backup_path = _session_dir->root_path() / backup_filename;
3254
3255         if (sys::exists (xml_path)) {
3256                 try
3257                 {
3258                         sys::rename (xml_path, backup_path);
3259                 }
3260                 catch (const sys::filesystem_error& err)
3261                 {
3262                         error << _("could not backup old history file, current history not saved") << endmsg;
3263                         return -1;
3264                 }
3265         }
3266
3267         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3268                 return 0;
3269         }
3270
3271         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3272
3273         if (!tree.write (xml_path.to_string()))
3274         {
3275                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3276
3277                 try
3278                 {
3279                         sys::remove (xml_path);
3280                         sys::rename (backup_path, xml_path);
3281                 }
3282                 catch (const sys::filesystem_error& err)
3283                 {
3284                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3285                                         backup_path.to_string(), err.what()) << endmsg;
3286                 }
3287
3288                 return -1;
3289         }
3290
3291         return 0;
3292 }
3293
3294 int
3295 Session::restore_history (string snapshot_name)
3296 {
3297         XMLTree tree;
3298
3299         if (snapshot_name.empty()) {
3300                 snapshot_name = _current_snapshot_name;
3301         }
3302
3303         const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3304         const sys::path xml_path = _session_dir->root_path() / xml_filename;
3305
3306         info << "Loading history from " << xml_path.to_string() << endmsg;
3307
3308         if (!sys::exists (xml_path)) {
3309                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3310                                 _name, xml_path.to_string()) << endmsg;
3311                 return 1;
3312         }
3313
3314         if (!tree.read (xml_path.to_string())) {
3315                 error << string_compose (_("Could not understand session history file \"%1\""),
3316                                 xml_path.to_string()) << endmsg;
3317                 return -1;
3318         }
3319
3320         // replace history
3321         _history.clear();
3322
3323         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3324
3325                 XMLNode *t = *it;
3326                 UndoTransaction* ut = new UndoTransaction ();
3327                 struct timeval tv;
3328
3329                 ut->set_name(t->property("name")->value());
3330                 stringstream ss(t->property("tv-sec")->value());
3331                 ss >> tv.tv_sec;
3332                 ss.str(t->property("tv-usec")->value());
3333                 ss >> tv.tv_usec;
3334                 ut->set_timestamp(tv);
3335
3336                 for (XMLNodeConstIterator child_it  = t->children().begin();
3337                                 child_it != t->children().end(); child_it++)
3338                 {
3339                         XMLNode *n = *child_it;
3340                         Command *c;
3341
3342                         if (n->name() == "MementoCommand" ||
3343                                         n->name() == "MementoUndoCommand" ||
3344                                         n->name() == "MementoRedoCommand") {
3345
3346                                 if ((c = memento_command_factory(n))) {
3347                                         ut->add_command(c);
3348                                 }
3349
3350                         } else if (n->name() == "NoteDiffCommand") {
3351                                 PBD::ID id (n->property("midi-source")->value());
3352                                 boost::shared_ptr<MidiSource> midi_source =
3353                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3354                                 if (midi_source) {
3355                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3356                                 } else {
3357                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3358                                 }
3359
3360                         } else if (n->name() == "SysExDiffCommand") {
3361
3362                                 PBD::ID id (n->property("midi-source")->value());
3363                                 boost::shared_ptr<MidiSource> midi_source =
3364                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3365                                 if (midi_source) {
3366                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3367                                 } else {
3368                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3369                                 }
3370
3371                         } else if (n->name() == "PatchChangeDiffCommand") {
3372
3373                                 PBD::ID id (n->property("midi-source")->value());
3374                                 boost::shared_ptr<MidiSource> midi_source =
3375                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3376                                 if (midi_source) {
3377                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3378                                 } else {
3379                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3380                                 }
3381
3382                         } else if (n->name() == "StatefulDiffCommand") {
3383                                 if ((c = stateful_diff_command_factory (n))) {
3384                                         ut->add_command (c);
3385                                 }
3386                         } else {
3387                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3388                         }
3389                 }
3390
3391                 _history.add (ut);
3392         }
3393
3394         return 0;
3395 }
3396
3397 void
3398 Session::config_changed (std::string p, bool ours)
3399 {
3400         if (ours) {
3401                 set_dirty ();
3402         }
3403
3404         if (p == "seamless-loop") {
3405
3406         } else if (p == "rf-speed") {
3407
3408         } else if (p == "auto-loop") {
3409
3410         } else if (p == "auto-input") {
3411
3412                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3413                         /* auto-input only makes a difference if we're rolling */
3414                         set_track_monitor_input_status (!config.get_auto_input());
3415                 }
3416
3417         } else if (p == "punch-in") {
3418
3419                 Location* location;
3420
3421                 if ((location = _locations->auto_punch_location()) != 0) {
3422
3423                         if (config.get_punch_in ()) {
3424                                 replace_event (SessionEvent::PunchIn, location->start());
3425                         } else {
3426                                 remove_event (location->start(), SessionEvent::PunchIn);
3427                         }
3428                 }
3429
3430         } else if (p == "punch-out") {
3431
3432                 Location* location;
3433
3434                 if ((location = _locations->auto_punch_location()) != 0) {
3435
3436                         if (config.get_punch_out()) {
3437                                 replace_event (SessionEvent::PunchOut, location->end());
3438                         } else {
3439                                 clear_events (SessionEvent::PunchOut);
3440                         }
3441                 }
3442
3443         } else if (p == "edit-mode") {
3444
3445                 Glib::Mutex::Lock lm (playlists->lock);
3446
3447                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3448                         (*i)->set_edit_mode (Config->get_edit_mode ());
3449                 }
3450
3451         } else if (p == "use-video-sync") {
3452
3453                 waiting_for_sync_offset = config.get_use_video_sync();
3454
3455         } else if (p == "mmc-control") {
3456
3457                 //poke_midi_thread ();
3458
3459         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3460
3461                 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3462
3463         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3464
3465                 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3466
3467         } else if (p == "midi-control") {
3468
3469                 //poke_midi_thread ();
3470
3471         } else if (p == "raid-path") {
3472
3473                 setup_raid_path (config.get_raid_path());
3474
3475         } else if (p == "timecode-format") {
3476
3477                 sync_time_vars ();
3478
3479         } else if (p == "video-pullup") {
3480
3481                 sync_time_vars ();
3482
3483         } else if (p == "seamless-loop") {
3484
3485                 if (play_loop && transport_rolling()) {
3486                         // to reset diskstreams etc
3487                         request_play_loop (true);
3488                 }
3489
3490         } else if (p == "rf-speed") {
3491
3492                 cumulative_rf_motion = 0;
3493                 reset_rf_scale (0);
3494
3495         } else if (p == "click-sound") {
3496
3497                 setup_click_sounds (1);
3498
3499         } else if (p == "click-emphasis-sound") {
3500
3501                 setup_click_sounds (-1);
3502
3503         } else if (p == "clicking") {
3504
3505                 if (Config->get_clicking()) {
3506                         if (_click_io && click_data) { // don't require emphasis data
3507                                 _clicking = true;
3508                         }
3509                 } else {
3510                         _clicking = false;
3511                 }
3512
3513         } else if (p == "send-mtc") {
3514
3515                 if (Config->get_send_mtc ()) {
3516                         /* mark us ready to send */
3517                         next_quarter_frame_to_send = 0;
3518                 }
3519
3520         } else if (p == "send-mmc") {
3521
3522                 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3523
3524         } else if (p == "midi-feedback") {
3525
3526                 session_midi_feedback = Config->get_midi_feedback();
3527
3528         } else if (p == "jack-time-master") {
3529
3530                 engine().reset_timebase ();
3531
3532         } else if (p == "native-file-header-format") {
3533
3534                 if (!first_file_header_format_reset) {
3535                         reset_native_file_format ();
3536                 }
3537
3538                 first_file_header_format_reset = false;
3539
3540         } else if (p == "native-file-data-format") {
3541
3542                 if (!first_file_data_format_reset) {
3543                         reset_native_file_format ();
3544                 }
3545
3546                 first_file_data_format_reset = false;
3547
3548         } else if (p == "external-sync") {
3549                 if (!config.get_external_sync()) {
3550                         drop_sync_source ();
3551                 } else {
3552                         switch_to_sync_source (config.get_sync_source());
3553                 }
3554         } else if (p == "remote-model") {
3555                 set_remote_control_ids ();
3556         }  else if (p == "denormal-model") {
3557                 setup_fpu ();
3558         } else if (p == "history-depth") {
3559                 set_history_depth (Config->get_history_depth());
3560         } else if (p == "sync-all-route-ordering") {
3561                 sync_order_keys ("session");
3562         } else if (p == "initial-program-change") {
3563
3564                 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3565                         MIDI::byte buf[2];
3566
3567                         buf[0] = MIDI::program; // channel zero by default
3568                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3569
3570                         MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3571                 }
3572         } else if (p == "solo-mute-override") {
3573                 // catch_up_on_solo_mute_override ();
3574         } else if (p == "listen-position" || p == "pfl-position") {
3575                 listen_position_changed ();
3576         } else if (p == "solo-control-is-listen-control") {
3577                 solo_control_mode_changed ();
3578         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3579                 last_timecode_valid = false;
3580         } else if (p == "playback-buffer-seconds") {
3581                 AudioSource::allocate_working_buffers (frame_rate());
3582         }
3583
3584         set_dirty ();
3585 }
3586
3587 void
3588 Session::set_history_depth (uint32_t d)
3589 {
3590         _history.set_depth (d);
3591 }
3592
3593 int
3594 Session::load_diskstreams_2X (XMLNode const & node, int)
3595 {
3596         XMLNodeList          clist;
3597         XMLNodeConstIterator citer;
3598
3599         clist = node.children();
3600
3601         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3602
3603                 try {
3604                         /* diskstreams added automatically by DiskstreamCreated handler */
3605                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3606                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3607                                 _diskstreams_2X.push_back (dsp);
3608                         } else {
3609                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3610                         }
3611                 }
3612
3613                 catch (failed_constructor& err) {
3614                         error << _("Session: could not load diskstream via XML state") << endmsg;
3615                         return -1;
3616                 }
3617         }
3618
3619         return 0;
3620 }
3621
3622 /** Connect things to the MMC object */
3623 void
3624 Session::setup_midi_machine_control ()
3625 {
3626         MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3627
3628         mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3629         mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3630         mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3631         mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3632         mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3633         mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3634         mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3635         mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3636         mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3637         mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3638         mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3639         mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3640         mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3641
3642         /* also handle MIDI SPP because its so common */
3643
3644         mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3645         mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3646         mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3647 }
3648
3649 boost::shared_ptr<Controllable>
3650 Session::solo_cut_control() const
3651 {
3652         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3653            controls in Ardour that currently get presented to the user in the GUI that require
3654            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3655
3656            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3657            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3658            parameter.
3659         */
3660
3661         return _solo_cut_control;
3662 }
3663
3664 int
3665 Session::rename (const std::string& new_name)
3666 {
3667         string legal_name = legalize_for_path (new_name);
3668         string newpath;
3669         string oldstr;
3670         string newstr;
3671         bool first = true;
3672
3673         string const old_sources_root = _session_dir->sources_root().to_string ();
3674
3675 #define RENAME ::rename
3676
3677         /* Rename:
3678
3679          * session directory
3680          * interchange subdirectory
3681          * session file
3682          * session history
3683          
3684          * Backup files are left unchanged and not renamed.
3685          */
3686
3687         /* pass one: not 100% safe check that the new directory names don't
3688          * already exist ...
3689          */
3690
3691         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3692                 vector<string> v;
3693
3694                 oldstr = (*i).path;
3695
3696                 /* this is a stupid hack because Glib::path_get_dirname() is
3697                  * lexical-only, and so passing it /a/b/c/ gives a different
3698                  * result than passing it /a/b/c ...
3699                  */
3700
3701                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3702                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3703                 }
3704
3705                 string base = Glib::path_get_dirname (oldstr);
3706                 string p = Glib::path_get_basename (oldstr);
3707
3708                 newstr = Glib::build_filename (base, legal_name);
3709                 
3710                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3711                         return -1;
3712                 }
3713         }
3714
3715         /* Session dirs */
3716         
3717         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3718                 vector<string> v;
3719
3720                 oldstr = (*i).path;
3721
3722                 /* this is a stupid hack because Glib::path_get_dirname() is
3723                  * lexical-only, and so passing it /a/b/c/ gives a different
3724                  * result than passing it /a/b/c ...
3725                  */
3726
3727                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3728                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3729                 }
3730
3731                 string base = Glib::path_get_dirname (oldstr);
3732                 string p = Glib::path_get_basename (oldstr);
3733
3734                 newstr = Glib::build_filename (base, legal_name);
3735
3736                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3737
3738                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3739                         return 1;
3740                 }
3741
3742                 if (first) {
3743                         (*_session_dir) = newstr;
3744                         newpath = newstr;
3745                         first = 1;
3746                 }
3747
3748                 /* directory below interchange */
3749
3750                 v.push_back (newstr);
3751                 v.push_back (interchange_dir_name);
3752                 v.push_back (p);
3753
3754                 oldstr = Glib::build_filename (v);
3755
3756                 v.clear ();
3757                 v.push_back (newstr);
3758                 v.push_back (interchange_dir_name);
3759                 v.push_back (legal_name);
3760
3761                 newstr = Glib::build_filename (v);
3762                 
3763                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3764                 
3765                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3766                         return 1;
3767                 }
3768         }
3769
3770         /* state file */
3771         
3772         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3773         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3774         
3775         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3776
3777         if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3778                 return 1;
3779         }
3780
3781         /* history file */
3782
3783         
3784         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3785
3786         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3787                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3788                 
3789                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3790                 
3791                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3792                         return 1;
3793                 }
3794         }
3795
3796         /* update file source paths */
3797         
3798         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3799                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3800                 if (fs) {
3801                         string p = fs->path ();
3802                         boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3803                         fs->set_path (p);
3804                 }
3805         }
3806
3807         /* remove old name from recent sessions */
3808
3809         remove_recent_sessions (_path);
3810
3811         _path = newpath;
3812         _current_snapshot_name = new_name;
3813         _name = new_name;
3814
3815         set_dirty ();
3816
3817         /* save state again to get everything just right */
3818
3819         save_state (_current_snapshot_name);
3820
3821
3822         /* add to recent sessions */
3823
3824         store_recent_sessions (new_name, _path);
3825
3826         return 0;
3827
3828 #undef RENAME
3829 }