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