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