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