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