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