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