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