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