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