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