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