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