add debug-message to track down missing Sources
[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 #ifndef NDEBUG
983                                                 cerr << "DEBUG: source '"
984                                                         << fs->name() << "' id: "
985                                                         << fs->id() << " is marked as empty and unused and is not saved.\n";
986 #endif
987                                                 continue;
988                                         }
989                                 }
990 #ifndef NDEBUG
991                                 cerr << "DEBUG: saving source '"
992                                         << fs->name() << "' id: "
993                                         << fs->id() << ".\n";
994 #endif
995
996                                 child->add_child_nocopy (siter->second->get_state());
997                         }
998                 }
999         }
1000
1001         child = node->add_child ("Regions");
1002
1003         if (full_state) {
1004                 Glib::Threads::Mutex::Lock rl (region_lock);
1005                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1006                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1007                         boost::shared_ptr<Region> r = i->second;
1008                         /* only store regions not attached to playlists */
1009                         if (r->playlist() == 0) {
1010                                 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1011                                         child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1012                                 } else {
1013                                         child->add_child_nocopy (r->get_state ());
1014                                 }
1015                         }
1016                 }
1017
1018                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1019
1020                 if (!cassocs.empty()) {
1021                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1022
1023                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1024                                 char buf[64];
1025                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1026                                 i->first->id().print (buf, sizeof (buf));
1027                                 can->add_property (X_("copy"), buf);
1028                                 i->second->id().print (buf, sizeof (buf));
1029                                 can->add_property (X_("original"), buf);
1030                                 ca->add_child_nocopy (*can);
1031                         }
1032                 }
1033         }
1034
1035         if (full_state) {
1036                 node->add_child_nocopy (_locations->get_state());
1037         } else {
1038                 // for a template, just create a new Locations, populate it
1039                 // with the default start and end, and get the state for that.
1040                 Locations loc (*this);
1041                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1042                 range->set (max_framepos, 0);
1043                 loc.add (range);
1044                 node->add_child_nocopy (loc.get_state());
1045         }
1046
1047         child = node->add_child ("Bundles");
1048         {
1049                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1050                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1051                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1052                         if (b) {
1053                                 child->add_child_nocopy (b->get_state());
1054                         }
1055                 }
1056         }
1057
1058         child = node->add_child ("Routes");
1059         {
1060                 boost::shared_ptr<RouteList> r = routes.reader ();
1061
1062                 RoutePublicOrderSorter cmp;
1063                 RouteList public_order (*r);
1064                 public_order.sort (cmp);
1065
1066                 /* the sort should have put control outs first */
1067
1068                 if (_monitor_out) {
1069                         assert (_monitor_out == public_order.front());
1070                 }
1071
1072                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1073                         if (!(*i)->is_auditioner()) {
1074                                 if (full_state) {
1075                                         child->add_child_nocopy ((*i)->get_state());
1076                                 } else {
1077                                         child->add_child_nocopy ((*i)->get_template());
1078                                 }
1079                         }
1080                 }
1081         }
1082
1083         playlists->add_state (node, full_state);
1084
1085         child = node->add_child ("RouteGroups");
1086         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1087                 child->add_child_nocopy ((*i)->get_state());
1088         }
1089
1090         if (_click_io) {
1091                 XMLNode* gain_child = node->add_child ("Click");
1092                 gain_child->add_child_nocopy (_click_io->state (full_state));
1093                 gain_child->add_child_nocopy (_click_gain->state (full_state));
1094         }
1095
1096         if (_ltc_input) {
1097                 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1098                 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1099         }
1100
1101         if (_ltc_input) {
1102                 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1103                 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1104         }
1105
1106         node->add_child_nocopy (_speakers->get_state());
1107         node->add_child_nocopy (_tempo_map->get_state());
1108         node->add_child_nocopy (get_control_protocol_state());
1109
1110         if (_extra_xml) {
1111                 node->add_child_copy (*_extra_xml);
1112         }
1113
1114         return *node;
1115 }
1116
1117 XMLNode&
1118 Session::get_control_protocol_state ()
1119 {
1120         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1121         return cpm.get_state();
1122 }
1123
1124 int
1125 Session::set_state (const XMLNode& node, int version)
1126 {
1127         XMLNodeList nlist;
1128         XMLNode* child;
1129         const XMLProperty* prop;
1130         int ret = -1;
1131
1132         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1133
1134         if (node.name() != X_("Session")) {
1135                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1136                 return -1;
1137         }
1138
1139         if ((prop = node.property ("name")) != 0) {
1140                 _name = prop->value ();
1141         }
1142
1143         if ((prop = node.property (X_("sample-rate"))) != 0) {
1144
1145                 _nominal_frame_rate = atoi (prop->value());
1146
1147                 if (_nominal_frame_rate != _current_frame_rate) {
1148                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1149                         if (r.get_value_or (0)) {
1150                                 return -1;
1151                         }
1152                 }
1153         }
1154
1155         setup_raid_path(_session_dir->root_path());
1156
1157         if ((prop = node.property (X_("id-counter"))) != 0) {
1158                 uint64_t x;
1159                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1160                 ID::init_counter (x);
1161         } else {
1162                 /* old sessions used a timebased counter, so fake
1163                    the startup ID counter based on a standard
1164                    timestamp.
1165                 */
1166                 time_t now;
1167                 time (&now);
1168                 ID::init_counter (now);
1169         }
1170
1171         if ((prop = node.property (X_("event-counter"))) != 0) {
1172                 Evoral::init_event_id_counter (atoi (prop->value()));
1173         }
1174
1175
1176         if ((child = find_named_node (node, "MIDIPorts")) != 0) {
1177                 _midi_ports->set_midi_port_states (child->children());
1178         }
1179
1180         IO::disable_connecting ();
1181
1182         Stateful::save_extra_xml (node);
1183
1184         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1185                 load_options (*child);
1186         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1187                 load_options (*child);
1188         } else {
1189                 error << _("Session: XML state has no options section") << endmsg;
1190         }
1191
1192         if (version >= 3000) {
1193                 if ((child = find_named_node (node, "Metadata")) == 0) {
1194                         warning << _("Session: XML state has no metadata section") << endmsg;
1195                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1196                         goto out;
1197                 }
1198         }
1199
1200         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1201                 _speakers->set_state (*child, version);
1202         }
1203
1204         if ((child = find_named_node (node, "Sources")) == 0) {
1205                 error << _("Session: XML state has no sources section") << endmsg;
1206                 goto out;
1207         } else if (load_sources (*child)) {
1208                 goto out;
1209         }
1210
1211         if ((child = find_named_node (node, "TempoMap")) == 0) {
1212                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1213                 goto out;
1214         } else if (_tempo_map->set_state (*child, version)) {
1215                 goto out;
1216         }
1217
1218         if ((child = find_named_node (node, "Locations")) == 0) {
1219                 error << _("Session: XML state has no locations section") << endmsg;
1220                 goto out;
1221         } else if (_locations->set_state (*child, version)) {
1222                 goto out;
1223         }
1224
1225         Location* location;
1226
1227         if ((location = _locations->auto_loop_location()) != 0) {
1228                 set_auto_loop_location (location);
1229         }
1230
1231         if ((location = _locations->auto_punch_location()) != 0) {
1232                 set_auto_punch_location (location);
1233         }
1234
1235         if ((location = _locations->session_range_location()) != 0) {
1236                 delete _session_range_location;
1237                 _session_range_location = location;
1238         }
1239
1240         if (_session_range_location) {
1241                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1242         }
1243
1244         if ((child = find_named_node (node, "Regions")) == 0) {
1245                 error << _("Session: XML state has no Regions section") << endmsg;
1246                 goto out;
1247         } else if (load_regions (*child)) {
1248                 goto out;
1249         }
1250
1251         if ((child = find_named_node (node, "Playlists")) == 0) {
1252                 error << _("Session: XML state has no playlists section") << endmsg;
1253                 goto out;
1254         } else if (playlists->load (*this, *child)) {
1255                 goto out;
1256         }
1257
1258         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1259                 // this is OK
1260         } else if (playlists->load_unused (*this, *child)) {
1261                 goto out;
1262         }
1263
1264         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1265                 if (load_compounds (*child)) {
1266                         goto out;
1267                 }
1268         }
1269
1270         if (version >= 3000) {
1271                 if ((child = find_named_node (node, "Bundles")) == 0) {
1272                         warning << _("Session: XML state has no bundles section") << endmsg;
1273                         //goto out;
1274                 } else {
1275                         /* We can't load Bundles yet as they need to be able
1276                            to convert from port names to Port objects, which can't happen until
1277                            later */
1278                         _bundle_xml_node = new XMLNode (*child);
1279                 }
1280         }
1281
1282         if (version < 3000) {
1283                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1284                         error << _("Session: XML state has no diskstreams section") << endmsg;
1285                         goto out;
1286                 } else if (load_diskstreams_2X (*child, version)) {
1287                         goto out;
1288                 }
1289         }
1290
1291         if ((child = find_named_node (node, "Routes")) == 0) {
1292                 error << _("Session: XML state has no routes section") << endmsg;
1293                 goto out;
1294         } else if (load_routes (*child, version)) {
1295                 goto out;
1296         }
1297
1298         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1299         _diskstreams_2X.clear ();
1300
1301         if (version >= 3000) {
1302
1303                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1304                         error << _("Session: XML state has no route groups section") << endmsg;
1305                         goto out;
1306                 } else if (load_route_groups (*child, version)) {
1307                         goto out;
1308                 }
1309
1310         } else if (version < 3000) {
1311
1312                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1313                         error << _("Session: XML state has no edit groups section") << endmsg;
1314                         goto out;
1315                 } else if (load_route_groups (*child, version)) {
1316                         goto out;
1317                 }
1318
1319                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1320                         error << _("Session: XML state has no mix groups section") << endmsg;
1321                         goto out;
1322                 } else if (load_route_groups (*child, version)) {
1323                         goto out;
1324                 }
1325         }
1326
1327         if ((child = find_named_node (node, "Click")) == 0) {
1328                 warning << _("Session: XML state has no click section") << endmsg;
1329         } else if (_click_io) {
1330                 setup_click_state (&node);
1331         }
1332
1333         if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1334                 ControlProtocolManager::instance().set_state (*child, version);
1335         }
1336
1337         update_have_rec_enabled_track ();
1338
1339         /* here beginneth the second phase ... */
1340
1341         StateReady (); /* EMIT SIGNAL */
1342
1343         return 0;
1344
1345   out:
1346         return ret;
1347 }
1348
1349 int
1350 Session::load_routes (const XMLNode& node, int version)
1351 {
1352         XMLNodeList nlist;
1353         XMLNodeConstIterator niter;
1354         RouteList new_routes;
1355
1356         nlist = node.children();
1357
1358         set_dirty();
1359
1360         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1361
1362                 boost::shared_ptr<Route> route;
1363                 if (version < 3000) {
1364                         route = XMLRouteFactory_2X (**niter, version);
1365                 } else {
1366                         route = XMLRouteFactory (**niter, version);
1367                 }
1368
1369                 if (route == 0) {
1370                         error << _("Session: cannot create Route from XML description.") << endmsg;
1371                         return -1;
1372                 }
1373
1374                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1375
1376                 new_routes.push_back (route);
1377         }
1378
1379         add_routes (new_routes, false, false, false);
1380
1381         return 0;
1382 }
1383
1384 boost::shared_ptr<Route>
1385 Session::XMLRouteFactory (const XMLNode& node, int version)
1386 {
1387         boost::shared_ptr<Route> ret;
1388
1389         if (node.name() != "Route") {
1390                 return ret;
1391         }
1392
1393         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1394
1395         DataType type = DataType::AUDIO;
1396         const XMLProperty* prop = node.property("default-type");
1397
1398         if (prop) {
1399                 type = DataType (prop->value());
1400         }
1401
1402         assert (type != DataType::NIL);
1403
1404         if (ds_child) {
1405
1406                 boost::shared_ptr<Track> track;
1407
1408                 if (type == DataType::AUDIO) {
1409                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1410                 } else {
1411                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1412                 }
1413
1414                 if (track->init()) {
1415                         return ret;
1416                 }
1417
1418                 if (track->set_state (node, version)) {
1419                         return ret;
1420                 }
1421
1422 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1423                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1424 #endif
1425                 ret = track;
1426
1427         } else {
1428                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1429
1430                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1431 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1432                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1433 #endif
1434                         ret = r;
1435                 }
1436         }
1437
1438         return ret;
1439 }
1440
1441 boost::shared_ptr<Route>
1442 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1443 {
1444         boost::shared_ptr<Route> ret;
1445
1446         if (node.name() != "Route") {
1447                 return ret;
1448         }
1449
1450         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1451         if (!ds_prop) {
1452                 ds_prop = node.property (X_("diskstream"));
1453         }
1454
1455         DataType type = DataType::AUDIO;
1456         const XMLProperty* prop = node.property("default-type");
1457
1458         if (prop) {
1459                 type = DataType (prop->value());
1460         }
1461
1462         assert (type != DataType::NIL);
1463
1464         if (ds_prop) {
1465
1466                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1467                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1468                         ++i;
1469                 }
1470
1471                 if (i == _diskstreams_2X.end()) {
1472                         error << _("Could not find diskstream for route") << endmsg;
1473                         return boost::shared_ptr<Route> ();
1474                 }
1475
1476                 boost::shared_ptr<Track> track;
1477
1478                 if (type == DataType::AUDIO) {
1479                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1480                 } else {
1481                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1482                 }
1483
1484                 if (track->init()) {
1485                         return ret;
1486                 }
1487
1488                 if (track->set_state (node, version)) {
1489                         return ret;
1490                 }
1491
1492                 track->set_diskstream (*i);
1493
1494 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1495                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1496 #endif
1497                 ret = track;
1498
1499         } else {
1500                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1501
1502                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1503 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1504                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1505 #endif
1506                         ret = r;
1507                 }
1508         }
1509
1510         return ret;
1511 }
1512
1513 int
1514 Session::load_regions (const XMLNode& node)
1515 {
1516         XMLNodeList nlist;
1517         XMLNodeConstIterator niter;
1518         boost::shared_ptr<Region> region;
1519
1520         nlist = node.children();
1521
1522         set_dirty();
1523
1524         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1525                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1526                         error << _("Session: cannot create Region from XML description.");
1527                         const XMLProperty *name = (**niter).property("name");
1528
1529                         if (name) {
1530                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1531                         }
1532
1533                         error << endmsg;
1534                 }
1535         }
1536
1537         return 0;
1538 }
1539
1540 int
1541 Session::load_compounds (const XMLNode& node)
1542 {
1543         XMLNodeList calist = node.children();
1544         XMLNodeConstIterator caiter;
1545         XMLProperty *caprop;
1546
1547         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1548                 XMLNode* ca = *caiter;
1549                 ID orig_id;
1550                 ID copy_id;
1551
1552                 if ((caprop = ca->property (X_("original"))) == 0) {
1553                         continue;
1554                 }
1555                 orig_id = caprop->value();
1556
1557                 if ((caprop = ca->property (X_("copy"))) == 0) {
1558                         continue;
1559                 }
1560                 copy_id = caprop->value();
1561
1562                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1563                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1564
1565                 if (!orig || !copy) {
1566                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1567                                                    orig_id, copy_id)
1568                                 << endmsg;
1569                         continue;
1570                 }
1571
1572                 RegionFactory::add_compound_association (orig, copy);
1573         }
1574
1575         return 0;
1576 }
1577
1578 void
1579 Session::load_nested_sources (const XMLNode& node)
1580 {
1581         XMLNodeList nlist;
1582         XMLNodeConstIterator niter;
1583
1584         nlist = node.children();
1585
1586         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1587                 if ((*niter)->name() == "Source") {
1588
1589                         /* it may already exist, so don't recreate it unnecessarily 
1590                          */
1591
1592                         XMLProperty* prop = (*niter)->property (X_("id"));
1593                         if (!prop) {
1594                                 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1595                                 continue;
1596                         }
1597
1598                         ID source_id (prop->value());
1599
1600                         if (!source_by_id (source_id)) {
1601
1602                                 try {
1603                                         SourceFactory::create (*this, **niter, true);
1604                                 }
1605                                 catch (failed_constructor& err) {
1606                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1607                                 }
1608                         }
1609                 }
1610         }
1611 }
1612
1613 boost::shared_ptr<Region>
1614 Session::XMLRegionFactory (const XMLNode& node, bool full)
1615 {
1616         const XMLProperty* type = node.property("type");
1617
1618         try {
1619
1620                 const XMLNodeList& nlist = node.children();
1621
1622                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1623                         XMLNode *child = (*niter);
1624                         if (child->name() == "NestedSource") {
1625                                 load_nested_sources (*child);
1626                         }
1627                 }
1628
1629                 if (!type || type->value() == "audio") {
1630                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1631                 } else if (type->value() == "midi") {
1632                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1633                 }
1634
1635         } catch (failed_constructor& err) {
1636                 return boost::shared_ptr<Region> ();
1637         }
1638
1639         return boost::shared_ptr<Region> ();
1640 }
1641
1642 boost::shared_ptr<AudioRegion>
1643 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1644 {
1645         const XMLProperty* prop;
1646         boost::shared_ptr<Source> source;
1647         boost::shared_ptr<AudioSource> as;
1648         SourceList sources;
1649         SourceList master_sources;
1650         uint32_t nchans = 1;
1651         char buf[128];
1652
1653         if (node.name() != X_("Region")) {
1654                 return boost::shared_ptr<AudioRegion>();
1655         }
1656
1657         if ((prop = node.property (X_("channels"))) != 0) {
1658                 nchans = atoi (prop->value().c_str());
1659         }
1660
1661         if ((prop = node.property ("name")) == 0) {
1662                 cerr << "no name for this region\n";
1663                 abort ();
1664         }
1665
1666         if ((prop = node.property (X_("source-0"))) == 0) {
1667                 if ((prop = node.property ("source")) == 0) {
1668                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1669                         return boost::shared_ptr<AudioRegion>();
1670                 }
1671         }
1672
1673         PBD::ID s_id (prop->value());
1674
1675         if ((source = source_by_id (s_id)) == 0) {
1676                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1677                 return boost::shared_ptr<AudioRegion>();
1678         }
1679
1680         as = boost::dynamic_pointer_cast<AudioSource>(source);
1681         if (!as) {
1682                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1683                 return boost::shared_ptr<AudioRegion>();
1684         }
1685
1686         sources.push_back (as);
1687
1688         /* pickup other channels */
1689
1690         for (uint32_t n=1; n < nchans; ++n) {
1691                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1692                 if ((prop = node.property (buf)) != 0) {
1693
1694                         PBD::ID id2 (prop->value());
1695
1696                         if ((source = source_by_id (id2)) == 0) {
1697                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1698                                 return boost::shared_ptr<AudioRegion>();
1699                         }
1700
1701                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1702                         if (!as) {
1703                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1704                                 return boost::shared_ptr<AudioRegion>();
1705                         }
1706                         sources.push_back (as);
1707                 }
1708         }
1709
1710         for (uint32_t n = 0; n < nchans; ++n) {
1711                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1712                 if ((prop = node.property (buf)) != 0) {
1713
1714                         PBD::ID id2 (prop->value());
1715
1716                         if ((source = source_by_id (id2)) == 0) {
1717                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1718                                 return boost::shared_ptr<AudioRegion>();
1719                         }
1720
1721                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1722                         if (!as) {
1723                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1724                                 return boost::shared_ptr<AudioRegion>();
1725                         }
1726                         master_sources.push_back (as);
1727                 }
1728         }
1729
1730         try {
1731                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1732
1733                 /* a final detail: this is the one and only place that we know how long missing files are */
1734
1735                 if (region->whole_file()) {
1736                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1737                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1738                                 if (sfp) {
1739                                         sfp->set_length (region->length());
1740                                 }
1741                         }
1742                 }
1743
1744                 if (!master_sources.empty()) {
1745                         if (master_sources.size() != nchans) {
1746                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1747                         } else {
1748                                 region->set_master_sources (master_sources);
1749                         }
1750                 }
1751
1752                 return region;
1753
1754         }
1755
1756         catch (failed_constructor& err) {
1757                 return boost::shared_ptr<AudioRegion>();
1758         }
1759 }
1760
1761 boost::shared_ptr<MidiRegion>
1762 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1763 {
1764         const XMLProperty* prop;
1765         boost::shared_ptr<Source> source;
1766         boost::shared_ptr<MidiSource> ms;
1767         SourceList sources;
1768
1769         if (node.name() != X_("Region")) {
1770                 return boost::shared_ptr<MidiRegion>();
1771         }
1772
1773         if ((prop = node.property ("name")) == 0) {
1774                 cerr << "no name for this region\n";
1775                 abort ();
1776         }
1777
1778         if ((prop = node.property (X_("source-0"))) == 0) {
1779                 if ((prop = node.property ("source")) == 0) {
1780                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1781                         return boost::shared_ptr<MidiRegion>();
1782                 }
1783         }
1784
1785         PBD::ID s_id (prop->value());
1786
1787         if ((source = source_by_id (s_id)) == 0) {
1788                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1789                 return boost::shared_ptr<MidiRegion>();
1790         }
1791
1792         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1793         if (!ms) {
1794                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1795                 return boost::shared_ptr<MidiRegion>();
1796         }
1797
1798         sources.push_back (ms);
1799
1800         try {
1801                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1802                 /* a final detail: this is the one and only place that we know how long missing files are */
1803
1804                 if (region->whole_file()) {
1805                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1806                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1807                                 if (sfp) {
1808                                         sfp->set_length (region->length());
1809                                 }
1810                         }
1811                 }
1812
1813                 return region;
1814         }
1815
1816         catch (failed_constructor& err) {
1817                 return boost::shared_ptr<MidiRegion>();
1818         }
1819 }
1820
1821 XMLNode&
1822 Session::get_sources_as_xml ()
1823
1824 {
1825         XMLNode* node = new XMLNode (X_("Sources"));
1826         Glib::Threads::Mutex::Lock lm (source_lock);
1827
1828         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1829                 node->add_child_nocopy (i->second->get_state());
1830         }
1831
1832         return *node;
1833 }
1834
1835 string
1836 Session::path_from_region_name (DataType type, string name, string identifier)
1837 {
1838         char buf[PATH_MAX+1];
1839         uint32_t n;
1840         SessionDirectory sdir(get_best_session_directory_for_new_source());
1841         std::string source_dir = ((type == DataType::AUDIO)
1842                 ? sdir.sound_path() : sdir.midi_path());
1843
1844         string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1845
1846         for (n = 0; n < 999999; ++n) {
1847                 if (identifier.length()) {
1848                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1849                                   identifier.c_str(), n, ext.c_str());
1850                 } else {
1851                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1852                                         n, ext.c_str());
1853                 }
1854
1855                 std::string source_path = Glib::build_filename (source_dir, buf);
1856
1857                 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1858                         return source_path;
1859                 }
1860         }
1861
1862         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1863                                  name, identifier)
1864               << endmsg;
1865
1866         return "";
1867 }
1868
1869
1870 int
1871 Session::load_sources (const XMLNode& node)
1872 {
1873         XMLNodeList nlist;
1874         XMLNodeConstIterator niter;
1875         boost::shared_ptr<Source> source;
1876
1877         nlist = node.children();
1878
1879         set_dirty();
1880
1881         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1882           retry:
1883                 try {
1884                         if ((source = XMLSourceFactory (**niter)) == 0) {
1885                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1886                         }
1887
1888                 } catch (MissingSource& err) {
1889
1890                         int user_choice;
1891
1892                         if (!no_questions_about_missing_files) {
1893                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1894                         } else {
1895                                 user_choice = -2;
1896                         }
1897
1898                         switch (user_choice) {
1899                         case 0:
1900                                 /* user added a new search location, so try again */
1901                                 goto retry;
1902
1903
1904                         case 1:
1905                                 /* user asked to quit the entire session load
1906                                  */
1907                                 return -1;
1908
1909                         case 2:
1910                                 no_questions_about_missing_files = true;
1911                                 goto retry;
1912
1913                         case 3:
1914                                 no_questions_about_missing_files = true;
1915                                 /* fallthru */
1916
1917                         case -1:
1918                         default:
1919                                 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1920                                 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1921                                 break;
1922                         }
1923                 }
1924         }
1925
1926         return 0;
1927 }
1928
1929 boost::shared_ptr<Source>
1930 Session::XMLSourceFactory (const XMLNode& node)
1931 {
1932         if (node.name() != "Source") {
1933                 return boost::shared_ptr<Source>();
1934         }
1935
1936         try {
1937                 /* note: do peak building in another thread when loading session state */
1938                 return SourceFactory::create (*this, node, true);
1939         }
1940
1941         catch (failed_constructor& err) {
1942                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1943                 return boost::shared_ptr<Source>();
1944         }
1945 }
1946
1947 int
1948 Session::save_template (string template_name)
1949 {
1950         XMLTree tree;
1951
1952         if (_state_of_the_state & CannotSave) {
1953                 return -1;
1954         }
1955
1956         std::string user_template_dir(user_template_directory());
1957
1958         if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
1959                 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
1960                                 user_template_dir, g_strerror (errno)) << endmsg;
1961                 return -1;
1962         }
1963
1964         tree.set_root (&get_template());
1965
1966         std::string template_dir_path(user_template_dir);
1967         
1968         /* directory to put the template in */
1969         template_dir_path = Glib::build_filename (template_dir_path, template_name);
1970
1971         if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
1972                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1973                                 template_dir_path) << endmsg;
1974                 return -1;
1975         }
1976         
1977         if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
1978                 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
1979                                 template_dir_path, g_strerror (errno)) << endmsg;
1980                 return -1;
1981         }
1982
1983         /* file to write */
1984         std::string template_file_path(template_dir_path);
1985         template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
1986
1987         if (!tree.write (template_file_path)) {
1988                 error << _("template not saved") << endmsg;
1989                 return -1;
1990         }
1991
1992         /* copy plugin state directory */
1993
1994         std::string template_plugin_state_path(template_dir_path);
1995         template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
1996
1997         if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
1998                 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
1999                                 template_plugin_state_path, g_strerror (errno)) << endmsg;
2000                 return -1;
2001         }
2002
2003         copy_files (plugins_dir(), template_plugin_state_path);
2004
2005         return 0;
2006 }
2007
2008 void
2009 Session::refresh_disk_space ()
2010 {
2011 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2012         
2013         Glib::Threads::Mutex::Lock lm (space_lock);
2014
2015         /* get freespace on every FS that is part of the session path */
2016
2017         _total_free_4k_blocks = 0;
2018         _total_free_4k_blocks_uncertain = false;
2019
2020         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2021
2022                 struct statfs statfsbuf;
2023                 statfs (i->path.c_str(), &statfsbuf);
2024
2025                 double const scale = statfsbuf.f_bsize / 4096.0;
2026
2027                 /* See if this filesystem is read-only */
2028                 struct statvfs statvfsbuf;
2029                 statvfs (i->path.c_str(), &statvfsbuf);
2030
2031                 /* f_bavail can be 0 if it is undefined for whatever
2032                    filesystem we are looking at; Samba shares mounted
2033                    via GVFS are an example of this.
2034                 */
2035                 if (statfsbuf.f_bavail == 0) {
2036                         /* block count unknown */
2037                         i->blocks = 0;
2038                         i->blocks_unknown = true;
2039                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2040                         /* read-only filesystem */
2041                         i->blocks = 0;
2042                         i->blocks_unknown = false;
2043                 } else {
2044                         /* read/write filesystem with known space */
2045                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2046                         i->blocks_unknown = false;
2047                 }
2048
2049                 _total_free_4k_blocks += i->blocks;
2050                 if (i->blocks_unknown) {
2051                         _total_free_4k_blocks_uncertain = true;
2052                 }
2053         }
2054 #endif
2055 }
2056
2057 string
2058 Session::get_best_session_directory_for_new_source ()
2059 {
2060         vector<space_and_path>::iterator i;
2061         string result = _session_dir->root_path();
2062
2063         /* handle common case without system calls */
2064
2065         if (session_dirs.size() == 1) {
2066                 return result;
2067         }
2068
2069         /* OK, here's the algorithm we're following here:
2070
2071         We want to select which directory to use for
2072         the next file source to be created. Ideally,
2073         we'd like to use a round-robin process so as to
2074         get maximum performance benefits from splitting
2075         the files across multiple disks.
2076
2077         However, in situations without much diskspace, an
2078         RR approach may end up filling up a filesystem
2079         with new files while others still have space.
2080         Its therefore important to pay some attention to
2081         the freespace in the filesystem holding each
2082         directory as well. However, if we did that by
2083         itself, we'd keep creating new files in the file
2084         system with the most space until it was as full
2085         as all others, thus negating any performance
2086         benefits of this RAID-1 like approach.
2087
2088         So, we use a user-configurable space threshold. If
2089         there are at least 2 filesystems with more than this
2090         much space available, we use RR selection between them.
2091         If not, then we pick the filesystem with the most space.
2092
2093         This gets a good balance between the two
2094         approaches.
2095         */
2096
2097         refresh_disk_space ();
2098
2099         int free_enough = 0;
2100
2101         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2102                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2103                         free_enough++;
2104                 }
2105         }
2106
2107         if (free_enough >= 2) {
2108                 /* use RR selection process, ensuring that the one
2109                    picked works OK.
2110                 */
2111
2112                 i = last_rr_session_dir;
2113
2114                 do {
2115                         if (++i == session_dirs.end()) {
2116                                 i = session_dirs.begin();
2117                         }
2118
2119                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2120                                 SessionDirectory sdir(i->path);
2121                                 if (sdir.create ()) {
2122                                         result = (*i).path;
2123                                         last_rr_session_dir = i;
2124                                         return result;
2125                                 }
2126                         }
2127
2128                 } while (i != last_rr_session_dir);
2129
2130         } else {
2131
2132                 /* pick FS with the most freespace (and that
2133                    seems to actually work ...)
2134                 */
2135
2136                 vector<space_and_path> sorted;
2137                 space_and_path_ascending_cmp cmp;
2138
2139                 sorted = session_dirs;
2140                 sort (sorted.begin(), sorted.end(), cmp);
2141
2142                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2143                         SessionDirectory sdir(i->path);
2144                         if (sdir.create ()) {
2145                                 result = (*i).path;
2146                                 last_rr_session_dir = i;
2147                                 return result;
2148                         }
2149                 }
2150         }
2151
2152         return result;
2153 }
2154
2155 string
2156 Session::automation_dir () const
2157 {
2158         return Glib::build_filename (_path, "automation");
2159 }
2160
2161 string
2162 Session::analysis_dir () const
2163 {
2164         return Glib::build_filename (_path, "analysis");
2165 }
2166
2167 string
2168 Session::plugins_dir () const
2169 {
2170         return Glib::build_filename (_path, "plugins");
2171 }
2172
2173 string
2174 Session::externals_dir () const
2175 {
2176         return Glib::build_filename (_path, "externals");
2177 }
2178
2179 int
2180 Session::load_bundles (XMLNode const & node)
2181 {
2182         XMLNodeList nlist = node.children();
2183         XMLNodeConstIterator niter;
2184
2185         set_dirty();
2186
2187         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2188                 if ((*niter)->name() == "InputBundle") {
2189                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2190                 } else if ((*niter)->name() == "OutputBundle") {
2191                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2192                 } else {
2193                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2194                         return -1;
2195                 }
2196         }
2197
2198         return 0;
2199 }
2200
2201 int
2202 Session::load_route_groups (const XMLNode& node, int version)
2203 {
2204         XMLNodeList nlist = node.children();
2205         XMLNodeConstIterator niter;
2206
2207         set_dirty ();
2208
2209         if (version >= 3000) {
2210
2211                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2212                         if ((*niter)->name() == "RouteGroup") {
2213                                 RouteGroup* rg = new RouteGroup (*this, "");
2214                                 add_route_group (rg);
2215                                 rg->set_state (**niter, version);
2216                         }
2217                 }
2218
2219         } else if (version < 3000) {
2220
2221                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2222                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2223                                 RouteGroup* rg = new RouteGroup (*this, "");
2224                                 add_route_group (rg);
2225                                 rg->set_state (**niter, version);
2226                         }
2227                 }
2228         }
2229
2230         return 0;
2231 }
2232
2233 void
2234 Session::auto_save()
2235 {
2236         save_state (_current_snapshot_name);
2237 }
2238
2239 static bool
2240 state_file_filter (const string &str, void */*arg*/)
2241 {
2242         return (str.length() > strlen(statefile_suffix) &&
2243                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2244 }
2245
2246 struct string_cmp {
2247         bool operator()(const string* a, const string* b) {
2248                 return *a < *b;
2249         }
2250 };
2251
2252 static string*
2253 remove_end(string* state)
2254 {
2255         string statename(*state);
2256
2257         string::size_type start,end;
2258         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2259                 statename = statename.substr (start+1);
2260         }
2261
2262         if ((end = statename.rfind(".ardour")) == string::npos) {
2263                 end = statename.length();
2264         }
2265
2266         return new string(statename.substr (0, end));
2267 }
2268
2269 vector<string *> *
2270 Session::possible_states (string path)
2271 {
2272         PathScanner scanner;
2273         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2274
2275         transform(states->begin(), states->end(), states->begin(), remove_end);
2276
2277         string_cmp cmp;
2278         sort (states->begin(), states->end(), cmp);
2279
2280         return states;
2281 }
2282
2283 vector<string *> *
2284 Session::possible_states () const
2285 {
2286         return possible_states(_path);
2287 }
2288
2289 void
2290 Session::add_route_group (RouteGroup* g)
2291 {
2292         _route_groups.push_back (g);
2293         route_group_added (g); /* EMIT SIGNAL */
2294
2295         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2296         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2297         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2298
2299         set_dirty ();
2300 }
2301
2302 void
2303 Session::remove_route_group (RouteGroup& rg)
2304 {
2305         list<RouteGroup*>::iterator i;
2306
2307         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2308                 _route_groups.erase (i);
2309                 delete &rg;
2310
2311                 route_group_removed (); /* EMIT SIGNAL */
2312         }
2313 }
2314
2315 /** Set a new order for our route groups, without adding or removing any.
2316  *  @param groups Route group list in the new order.
2317  */
2318 void
2319 Session::reorder_route_groups (list<RouteGroup*> groups)
2320 {
2321         _route_groups = groups;
2322
2323         route_groups_reordered (); /* EMIT SIGNAL */
2324         set_dirty ();
2325 }
2326
2327
2328 RouteGroup *
2329 Session::route_group_by_name (string name)
2330 {
2331         list<RouteGroup *>::iterator i;
2332
2333         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2334                 if ((*i)->name() == name) {
2335                         return* i;
2336                 }
2337         }
2338         return 0;
2339 }
2340
2341 RouteGroup&
2342 Session::all_route_group() const
2343 {
2344         return *_all_route_group;
2345 }
2346
2347 void
2348 Session::add_commands (vector<Command*> const & cmds)
2349 {
2350         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2351                 add_command (*i);
2352         }
2353 }
2354
2355 void
2356 Session::begin_reversible_command (const string& name)
2357 {
2358         begin_reversible_command (g_quark_from_string (name.c_str ()));
2359 }
2360
2361 /** Begin a reversible command using a GQuark to identify it.
2362  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2363  *  but there must be as many begin...()s as there are commit...()s.
2364  */
2365 void
2366 Session::begin_reversible_command (GQuark q)
2367 {
2368         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2369            to hold all the commands that are committed.  This keeps the order of
2370            commands correct in the history.
2371         */
2372
2373         if (_current_trans == 0) {
2374                 /* start a new transaction */
2375                 assert (_current_trans_quarks.empty ());
2376                 _current_trans = new UndoTransaction();
2377                 _current_trans->set_name (g_quark_to_string (q));
2378         }
2379
2380         _current_trans_quarks.push_front (q);
2381 }
2382
2383 void
2384 Session::commit_reversible_command (Command *cmd)
2385 {
2386         assert (_current_trans);
2387         assert (!_current_trans_quarks.empty ());
2388
2389         struct timeval now;
2390
2391         if (cmd) {
2392                 _current_trans->add_command (cmd);
2393         }
2394
2395         _current_trans_quarks.pop_front ();
2396
2397         if (!_current_trans_quarks.empty ()) {
2398                 /* the transaction we're committing is not the top-level one */
2399                 return;
2400         }
2401
2402         if (_current_trans->empty()) {
2403                 /* no commands were added to the transaction, so just get rid of it */
2404                 delete _current_trans;
2405                 _current_trans = 0;
2406                 return;
2407         }
2408
2409         gettimeofday (&now, 0);
2410         _current_trans->set_timestamp (now);
2411
2412         _history.add (_current_trans);
2413         _current_trans = 0;
2414 }
2415
2416 static bool
2417 accept_all_audio_files (const string& path, void */*arg*/)
2418 {
2419         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2420                 return false;
2421         }
2422
2423         if (!AudioFileSource::safe_audio_file_extension (path)) {
2424                 return false;
2425         }
2426
2427         return true;
2428 }
2429
2430 static bool
2431 accept_all_midi_files (const string& path, void */*arg*/)
2432 {
2433         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2434                 return false;
2435         }
2436
2437         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2438                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2439                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2440 }
2441
2442 static bool
2443 accept_all_state_files (const string& path, void */*arg*/)
2444 {
2445         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2446                 return false;
2447         }
2448
2449         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2450 }
2451
2452 int
2453 Session::find_all_sources (string path, set<string>& result)
2454 {
2455         XMLTree tree;
2456         XMLNode* node;
2457
2458         if (!tree.read (path)) {
2459                 return -1;
2460         }
2461
2462         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2463                 return -2;
2464         }
2465
2466         XMLNodeList nlist;
2467         XMLNodeConstIterator niter;
2468
2469         nlist = node->children();
2470
2471         set_dirty();
2472
2473         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2474
2475                 XMLProperty* prop;
2476
2477                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2478                         continue;
2479                 }
2480
2481                 DataType type (prop->value());
2482
2483                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2484                         continue;
2485                 }
2486
2487                 if (Glib::path_is_absolute (prop->value())) {
2488                         /* external file, ignore */
2489                         continue;
2490                 }
2491
2492                 string found_path;
2493                 bool is_new;
2494                 uint16_t chan;
2495
2496                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2497                         result.insert (found_path);
2498                 }
2499         }
2500
2501         return 0;
2502 }
2503
2504 int
2505 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2506 {
2507         PathScanner scanner;
2508         vector<string*>* state_files;
2509         string ripped;
2510         string this_snapshot_path;
2511
2512         result.clear ();
2513
2514         ripped = _path;
2515
2516         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2517                 ripped = ripped.substr (0, ripped.length() - 1);
2518         }
2519
2520         state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2521
2522         if (state_files == 0) {
2523                 /* impossible! */
2524                 return 0;
2525         }
2526
2527         this_snapshot_path = _path;
2528         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2529         this_snapshot_path += statefile_suffix;
2530
2531         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2532
2533                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2534                         continue;
2535                 }
2536
2537                 if (find_all_sources (**i, result) < 0) {
2538                         return -1;
2539                 }
2540         }
2541
2542         return 0;
2543 }
2544
2545 struct RegionCounter {
2546     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2547     AudioSourceList::iterator iter;
2548     boost::shared_ptr<Region> region;
2549     uint32_t count;
2550
2551     RegionCounter() : count (0) {}
2552 };
2553
2554 int
2555 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2556 {
2557         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2558         return r.get_value_or (1);
2559 }
2560
2561 void
2562 Session::cleanup_regions ()
2563 {
2564         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2565
2566         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2567
2568                 uint32_t used = playlists->region_use_count (i->second);
2569
2570                 if (used == 0 && !i->second->automatic ()) {
2571                         RegionFactory::map_remove (i->second);
2572                 }
2573         }
2574
2575         /* dump the history list */
2576         _history.clear ();
2577
2578         save_state ("");
2579 }
2580
2581 int
2582 Session::cleanup_sources (CleanupReport& rep)
2583 {
2584         // FIXME: needs adaptation to midi
2585
2586         vector<boost::shared_ptr<Source> > dead_sources;
2587         PathScanner scanner;
2588         string audio_path;
2589         string midi_path;
2590         vector<space_and_path>::iterator i;
2591         vector<space_and_path>::iterator nexti;
2592         vector<string*>* candidates;
2593         vector<string*>* candidates2;
2594         vector<string> unused;
2595         set<string> all_sources;
2596         bool used;
2597         string spath;
2598         int ret = -1;
2599
2600         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2601
2602         /* consider deleting all unused playlists */
2603
2604         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2605                 ret = 0;
2606                 goto out;
2607         }
2608
2609         /* sync the "all regions" property of each playlist with its current state
2610          */
2611
2612         playlists->sync_all_regions_with_regions ();
2613
2614         /* find all un-used sources */
2615
2616         rep.paths.clear ();
2617         rep.space = 0;
2618
2619         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2620
2621                 SourceMap::iterator tmp;
2622
2623                 tmp = i;
2624                 ++tmp;
2625
2626                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2627                    capture files.
2628                 */
2629
2630                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2631                         dead_sources.push_back (i->second);
2632                         i->second->drop_references ();
2633                 }
2634
2635                 i = tmp;
2636         }
2637
2638         /* build a list of all the possible audio directories for the session */
2639
2640         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2641
2642                 nexti = i;
2643                 ++nexti;
2644
2645                 SessionDirectory sdir ((*i).path);
2646                 audio_path += sdir.sound_path();
2647
2648                 if (nexti != session_dirs.end()) {
2649                         audio_path += ':';
2650                 }
2651
2652                 i = nexti;
2653         }
2654
2655
2656         /* build a list of all the possible midi directories for the session */
2657
2658         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2659
2660                 nexti = i;
2661                 ++nexti;
2662
2663                 SessionDirectory sdir ((*i).path);
2664                 midi_path += sdir.midi_path();
2665
2666                 if (nexti != session_dirs.end()) {
2667                         midi_path += ':';
2668                 }
2669
2670                 i = nexti;
2671         }
2672
2673         candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2674         candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2675
2676         /* merge them */
2677
2678         if (candidates) {
2679                 if (candidates2) {
2680                         for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2681                                 candidates->push_back (*i);
2682                         }
2683                         delete candidates2;
2684                 }
2685         } else {
2686                 candidates = candidates2; // might still be null
2687         }
2688
2689         /* find all sources, but don't use this snapshot because the
2690            state file on disk still references sources we may have already
2691            dropped.
2692         */
2693
2694         find_all_sources_across_snapshots (all_sources, true);
2695
2696         /*  add our current source list
2697          */
2698
2699         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2700                 boost::shared_ptr<FileSource> fs;
2701                 SourceMap::iterator tmp = i;
2702                 ++tmp;
2703
2704                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2705                         if (playlists->source_use_count (fs) != 0) {
2706                                 all_sources.insert (fs->path());
2707                         } else {
2708
2709                                 /* we might not remove this source from disk, because it may be used
2710                                    by other snapshots, but its not being used in this version
2711                                    so lets get rid of it now, along with any representative regions
2712                                    in the region list.
2713                                 */
2714
2715                                 RegionFactory::remove_regions_using_source (i->second);
2716                                 sources.erase (i);
2717                         }
2718                 }
2719
2720                 i = tmp;
2721         }
2722
2723         char tmppath1[PATH_MAX+1];
2724         char tmppath2[PATH_MAX+1];
2725
2726         if (candidates) {
2727                 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2728
2729                         used = false;
2730                         spath = **x;
2731
2732                         for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2733
2734                                 if (realpath(spath.c_str(), tmppath1) == 0) {
2735                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2736                                                                  spath, strerror (errno)) << endmsg;
2737                                         continue;
2738                                 }
2739
2740                                 if (realpath((*i).c_str(),  tmppath2) == 0) {
2741                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2742                                                                  (*i), strerror (errno)) << endmsg;
2743                                         continue;
2744                                 }
2745
2746                                 if (strcmp(tmppath1, tmppath2) == 0) {
2747                                         used = true;
2748                                         break;
2749                                 }
2750                         }
2751
2752                         if (!used) {
2753                                 unused.push_back (spath);
2754                         }
2755
2756                         delete *x;
2757                 }
2758
2759                 delete candidates;
2760         }
2761
2762         /* now try to move all unused files into the "dead" directory(ies) */
2763
2764         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2765                 struct stat statbuf;
2766
2767                 string newpath;
2768
2769                 /* don't move the file across filesystems, just
2770                    stick it in the `dead_dir_name' directory
2771                    on whichever filesystem it was already on.
2772                 */
2773
2774                 if ((*x).find ("/sounds/") != string::npos) {
2775
2776                         /* old school, go up 1 level */
2777
2778                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2779                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2780
2781                 } else {
2782
2783                         /* new school, go up 4 levels */
2784
2785                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2786                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2787                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2788                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2789                 }
2790
2791                 newpath = Glib::build_filename (newpath, dead_dir_name);
2792
2793                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2794                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2795                         return -1;
2796                 }
2797
2798                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2799
2800                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2801
2802                         /* the new path already exists, try versioning */
2803
2804                         char buf[PATH_MAX+1];
2805                         int version = 1;
2806                         string newpath_v;
2807
2808                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2809                         newpath_v = buf;
2810
2811                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2812                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2813                                 newpath_v = buf;
2814                         }
2815
2816                         if (version == 999) {
2817                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2818                                                   newpath)
2819                                       << endmsg;
2820                         } else {
2821                                 newpath = newpath_v;
2822                         }
2823
2824                 } else {
2825
2826                         /* it doesn't exist, or we can't read it or something */
2827
2828                 }
2829
2830                 stat ((*x).c_str(), &statbuf);
2831
2832                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2833                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2834                                           (*x), newpath, strerror (errno))
2835                               << endmsg;
2836                         goto out;
2837                 }
2838
2839                 /* see if there an easy to find peakfile for this file, and remove it.
2840                  */
2841
2842                 string base = basename_nosuffix (*x);
2843                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2844                                  or for the first channel of embedded files. it will miss
2845                                  some peakfiles for other channels
2846                               */
2847                 string peakpath = peak_path (base);
2848
2849                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2850                         if (::unlink (peakpath.c_str()) != 0) {
2851                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2852                                                          peakpath, _path, strerror (errno))
2853                                       << endmsg;
2854                                 /* try to back out */
2855                                 ::rename (newpath.c_str(), _path.c_str());
2856                                 goto out;
2857                         }
2858                 }
2859
2860                 rep.paths.push_back (*x);
2861                 rep.space += statbuf.st_size;
2862         }
2863
2864         /* dump the history list */
2865
2866         _history.clear ();
2867
2868         /* save state so we don't end up a session file
2869            referring to non-existent sources.
2870         */
2871
2872         save_state ("");
2873         ret = 0;
2874
2875   out:
2876         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2877
2878         return ret;
2879 }
2880
2881 int
2882 Session::cleanup_trash_sources (CleanupReport& rep)
2883 {
2884         // FIXME: needs adaptation for MIDI
2885
2886         vector<space_and_path>::iterator i;
2887         string dead_dir;
2888
2889         rep.paths.clear ();
2890         rep.space = 0;
2891
2892         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2893
2894                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2895
2896                 clear_directory (dead_dir, &rep.space, &rep.paths);
2897         }
2898
2899         return 0;
2900 }
2901
2902 void
2903 Session::set_dirty ()
2904 {
2905         bool was_dirty = dirty();
2906
2907         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2908
2909
2910         if (!was_dirty) {
2911                 DirtyChanged(); /* EMIT SIGNAL */
2912         }
2913 }
2914
2915
2916 void
2917 Session::set_clean ()
2918 {
2919         bool was_dirty = dirty();
2920
2921         _state_of_the_state = Clean;
2922
2923
2924         if (was_dirty) {
2925                 DirtyChanged(); /* EMIT SIGNAL */
2926         }
2927 }
2928
2929 void
2930 Session::set_deletion_in_progress ()
2931 {
2932         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2933 }
2934
2935 void
2936 Session::clear_deletion_in_progress ()
2937 {
2938         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2939 }
2940
2941 void
2942 Session::add_controllable (boost::shared_ptr<Controllable> c)
2943 {
2944         /* this adds a controllable to the list managed by the Session.
2945            this is a subset of those managed by the Controllable class
2946            itself, and represents the only ones whose state will be saved
2947            as part of the session.
2948         */
2949
2950         Glib::Threads::Mutex::Lock lm (controllables_lock);
2951         controllables.insert (c);
2952 }
2953
2954 struct null_deleter { void operator()(void const *) const {} };
2955
2956 void
2957 Session::remove_controllable (Controllable* c)
2958 {
2959         if (_state_of_the_state & Deletion) {
2960                 return;
2961         }
2962
2963         Glib::Threads::Mutex::Lock lm (controllables_lock);
2964
2965         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2966
2967         if (x != controllables.end()) {
2968                 controllables.erase (x);
2969         }
2970 }
2971
2972 boost::shared_ptr<Controllable>
2973 Session::controllable_by_id (const PBD::ID& id)
2974 {
2975         Glib::Threads::Mutex::Lock lm (controllables_lock);
2976
2977         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2978                 if ((*i)->id() == id) {
2979                         return *i;
2980                 }
2981         }
2982
2983         return boost::shared_ptr<Controllable>();
2984 }
2985
2986 boost::shared_ptr<Controllable>
2987 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2988 {
2989         boost::shared_ptr<Controllable> c;
2990         boost::shared_ptr<Route> r;
2991
2992         switch (desc.top_level_type()) {
2993         case ControllableDescriptor::NamedRoute:
2994         {
2995                 std::string str = desc.top_level_name();
2996                 if (str == "master") {
2997                         r = _master_out;
2998                 } else if (str == "control" || str == "listen") {
2999                         r = _monitor_out;
3000                 } else {
3001                         r = route_by_name (desc.top_level_name());
3002                 }
3003                 break;
3004         }
3005
3006         case ControllableDescriptor::RemoteControlID:
3007                 r = route_by_remote_id (desc.rid());
3008                 break;
3009         }
3010
3011         if (!r) {
3012                 return c;
3013         }
3014
3015         switch (desc.subtype()) {
3016         case ControllableDescriptor::Gain:
3017                 c = r->gain_control ();
3018                 break;
3019
3020         case ControllableDescriptor::Solo:
3021                 c = r->solo_control();
3022                 break;
3023
3024         case ControllableDescriptor::Mute:
3025                 c = r->mute_control();
3026                 break;
3027
3028         case ControllableDescriptor::Recenable:
3029         {
3030                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3031
3032                 if (t) {
3033                         c = t->rec_enable_control ();
3034                 }
3035                 break;
3036         }
3037
3038         case ControllableDescriptor::PanDirection:
3039         {
3040                 c = r->pannable()->pan_azimuth_control;
3041                 break;
3042         }
3043
3044         case ControllableDescriptor::PanWidth:
3045         {
3046                 c = r->pannable()->pan_width_control;
3047                 break;
3048         }
3049
3050         case ControllableDescriptor::PanElevation:
3051         {
3052                 c = r->pannable()->pan_elevation_control;
3053                 break;
3054         }
3055
3056         case ControllableDescriptor::Balance:
3057                 /* XXX simple pan control */
3058                 break;
3059
3060         case ControllableDescriptor::PluginParameter:
3061         {
3062                 uint32_t plugin = desc.target (0);
3063                 uint32_t parameter_index = desc.target (1);
3064
3065                 /* revert to zero based counting */
3066
3067                 if (plugin > 0) {
3068                         --plugin;
3069                 }
3070
3071                 if (parameter_index > 0) {
3072                         --parameter_index;
3073                 }
3074
3075                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3076
3077                 if (p) {
3078                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3079                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3080                 }
3081                 break;
3082         }
3083
3084         case ControllableDescriptor::SendGain:
3085         {
3086                 uint32_t send = desc.target (0);
3087
3088                 /* revert to zero-based counting */
3089
3090                 if (send > 0) {
3091                         --send;
3092                 }
3093
3094                 boost::shared_ptr<Processor> p = r->nth_send (send);
3095
3096                 if (p) {
3097                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3098                         boost::shared_ptr<Amp> a = s->amp();
3099                         
3100                         if (a) {
3101                                 c = s->amp()->gain_control();
3102                         }
3103                 }
3104                 break;
3105         }
3106
3107         default:
3108                 /* relax and return a null pointer */
3109                 break;
3110         }
3111
3112         return c;
3113 }
3114
3115 void
3116 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3117 {
3118         if (_writable) {
3119                 Stateful::add_instant_xml (node, _path);
3120         }
3121
3122         if (write_to_config) {
3123                 Config->add_instant_xml (node);
3124         }
3125 }
3126
3127 XMLNode*
3128 Session::instant_xml (const string& node_name)
3129 {
3130         return Stateful::instant_xml (node_name, _path);
3131 }
3132
3133 int
3134 Session::save_history (string snapshot_name)
3135 {
3136         XMLTree tree;
3137
3138         if (!_writable) {
3139                 return 0;
3140         }
3141
3142         if (snapshot_name.empty()) {
3143                 snapshot_name = _current_snapshot_name;
3144         }
3145
3146         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3147         const string backup_filename = history_filename + backup_suffix;
3148         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3149         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3150
3151         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3152                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3153                         error << _("could not backup old history file, current history not saved") << endmsg;
3154                         return -1;
3155                 }
3156         }
3157
3158         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3159                 return 0;
3160         }
3161
3162         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3163
3164         if (!tree.write (xml_path))
3165         {
3166                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3167
3168                 if (g_remove (xml_path.c_str()) != 0) {
3169                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3170                                         xml_path, g_strerror (errno)) << endmsg;
3171                 }
3172                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3173                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3174                                         backup_path, g_strerror (errno)) << endmsg;
3175                 }
3176
3177                 return -1;
3178         }
3179
3180         return 0;
3181 }
3182
3183 int
3184 Session::restore_history (string snapshot_name)
3185 {
3186         XMLTree tree;
3187
3188         if (snapshot_name.empty()) {
3189                 snapshot_name = _current_snapshot_name;
3190         }
3191
3192         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3193         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3194
3195         info << "Loading history from " << xml_path << endmsg;
3196
3197         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3198                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3199                                 _name, xml_path) << endmsg;
3200                 return 1;
3201         }
3202
3203         if (!tree.read (xml_path)) {
3204                 error << string_compose (_("Could not understand session history file \"%1\""),
3205                                 xml_path) << endmsg;
3206                 return -1;
3207         }
3208
3209         // replace history
3210         _history.clear();
3211
3212         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3213
3214                 XMLNode *t = *it;
3215                 UndoTransaction* ut = new UndoTransaction ();
3216                 struct timeval tv;
3217
3218                 ut->set_name(t->property("name")->value());
3219                 stringstream ss(t->property("tv-sec")->value());
3220                 ss >> tv.tv_sec;
3221                 ss.str(t->property("tv-usec")->value());
3222                 ss >> tv.tv_usec;
3223                 ut->set_timestamp(tv);
3224
3225                 for (XMLNodeConstIterator child_it  = t->children().begin();
3226                                 child_it != t->children().end(); child_it++)
3227                 {
3228                         XMLNode *n = *child_it;
3229                         Command *c;
3230
3231                         if (n->name() == "MementoCommand" ||
3232                                         n->name() == "MementoUndoCommand" ||
3233                                         n->name() == "MementoRedoCommand") {
3234
3235                                 if ((c = memento_command_factory(n))) {
3236                                         ut->add_command(c);
3237                                 }
3238
3239                         } else if (n->name() == "NoteDiffCommand") {
3240                                 PBD::ID id (n->property("midi-source")->value());
3241                                 boost::shared_ptr<MidiSource> midi_source =
3242                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3243                                 if (midi_source) {
3244                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3245                                 } else {
3246                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3247                                 }
3248
3249                         } else if (n->name() == "SysExDiffCommand") {
3250
3251                                 PBD::ID id (n->property("midi-source")->value());
3252                                 boost::shared_ptr<MidiSource> midi_source =
3253                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3254                                 if (midi_source) {
3255                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3256                                 } else {
3257                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3258                                 }
3259
3260                         } else if (n->name() == "PatchChangeDiffCommand") {
3261
3262                                 PBD::ID id (n->property("midi-source")->value());
3263                                 boost::shared_ptr<MidiSource> midi_source =
3264                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3265                                 if (midi_source) {
3266                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3267                                 } else {
3268                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3269                                 }
3270
3271                         } else if (n->name() == "StatefulDiffCommand") {
3272                                 if ((c = stateful_diff_command_factory (n))) {
3273                                         ut->add_command (c);
3274                                 }
3275                         } else {
3276                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3277                         }
3278                 }
3279
3280                 _history.add (ut);
3281         }
3282
3283         return 0;
3284 }
3285
3286 void
3287 Session::config_changed (std::string p, bool ours)
3288 {
3289         if (ours) {
3290                 set_dirty ();
3291         }
3292
3293         if (p == "seamless-loop") {
3294
3295         } else if (p == "rf-speed") {
3296
3297         } else if (p == "auto-loop") {
3298
3299         } else if (p == "auto-input") {
3300
3301                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3302                         /* auto-input only makes a difference if we're rolling */
3303                         set_track_monitor_input_status (!config.get_auto_input());
3304                 }
3305
3306         } else if (p == "punch-in") {
3307
3308                 Location* location;
3309
3310                 if ((location = _locations->auto_punch_location()) != 0) {
3311
3312                         if (config.get_punch_in ()) {
3313                                 replace_event (SessionEvent::PunchIn, location->start());
3314                         } else {
3315                                 remove_event (location->start(), SessionEvent::PunchIn);
3316                         }
3317                 }
3318
3319         } else if (p == "punch-out") {
3320
3321                 Location* location;
3322
3323                 if ((location = _locations->auto_punch_location()) != 0) {
3324
3325                         if (config.get_punch_out()) {
3326                                 replace_event (SessionEvent::PunchOut, location->end());
3327                         } else {
3328                                 clear_events (SessionEvent::PunchOut);
3329                         }
3330                 }
3331
3332         } else if (p == "edit-mode") {
3333
3334                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3335
3336                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3337                         (*i)->set_edit_mode (Config->get_edit_mode ());
3338                 }
3339
3340         } else if (p == "use-video-sync") {
3341
3342                 waiting_for_sync_offset = config.get_use_video_sync();
3343
3344         } else if (p == "mmc-control") {
3345
3346                 //poke_midi_thread ();
3347
3348         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3349
3350                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3351
3352         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3353
3354                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3355
3356         } else if (p == "midi-control") {
3357
3358                 //poke_midi_thread ();
3359
3360         } else if (p == "raid-path") {
3361
3362                 setup_raid_path (config.get_raid_path());
3363
3364         } else if (p == "timecode-format") {
3365
3366                 sync_time_vars ();
3367
3368         } else if (p == "video-pullup") {
3369
3370                 sync_time_vars ();
3371
3372         } else if (p == "seamless-loop") {
3373
3374                 if (play_loop && transport_rolling()) {
3375                         // to reset diskstreams etc
3376                         request_play_loop (true);
3377                 }
3378
3379         } else if (p == "rf-speed") {
3380
3381                 cumulative_rf_motion = 0;
3382                 reset_rf_scale (0);
3383
3384         } else if (p == "click-sound") {
3385
3386                 setup_click_sounds (1);
3387
3388         } else if (p == "click-emphasis-sound") {
3389
3390                 setup_click_sounds (-1);
3391
3392         } else if (p == "clicking") {
3393
3394                 if (Config->get_clicking()) {
3395                         if (_click_io && click_data) { // don't require emphasis data
3396                                 _clicking = true;
3397                         }
3398                 } else {
3399                         _clicking = false;
3400                 }
3401
3402         } else if (p == "click-gain") {
3403                 
3404                 if (_click_gain) {
3405                         _click_gain->set_gain (Config->get_click_gain(), this);
3406                 }
3407
3408         } else if (p == "send-mtc") {
3409
3410                 if (Config->get_send_mtc ()) {
3411                         /* mark us ready to send */
3412                         next_quarter_frame_to_send = 0;
3413                 }
3414
3415         } else if (p == "send-mmc") {
3416
3417                 _mmc->enable_send (Config->get_send_mmc ());
3418
3419         } else if (p == "midi-feedback") {
3420
3421                 session_midi_feedback = Config->get_midi_feedback();
3422
3423         } else if (p == "jack-time-master") {
3424
3425                 engine().reset_timebase ();
3426
3427         } else if (p == "native-file-header-format") {
3428
3429                 if (!first_file_header_format_reset) {
3430                         reset_native_file_format ();
3431                 }
3432
3433                 first_file_header_format_reset = false;
3434
3435         } else if (p == "native-file-data-format") {
3436
3437                 if (!first_file_data_format_reset) {
3438                         reset_native_file_format ();
3439                 }
3440
3441                 first_file_data_format_reset = false;
3442
3443         } else if (p == "external-sync") {
3444                 if (!config.get_external_sync()) {
3445                         drop_sync_source ();
3446                 } else {
3447                         switch_to_sync_source (Config->get_sync_source());
3448                 }
3449         }  else if (p == "denormal-model") {
3450                 setup_fpu ();
3451         } else if (p == "history-depth") {
3452                 set_history_depth (Config->get_history_depth());
3453         } else if (p == "remote-model") {
3454                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3455                    TO SET REMOTE ID'S
3456                 */
3457         } else if (p == "initial-program-change") {
3458
3459                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3460                         MIDI::byte buf[2];
3461
3462                         buf[0] = MIDI::program; // channel zero by default
3463                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3464
3465                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3466                 }
3467         } else if (p == "solo-mute-override") {
3468                 // catch_up_on_solo_mute_override ();
3469         } else if (p == "listen-position" || p == "pfl-position") {
3470                 listen_position_changed ();
3471         } else if (p == "solo-control-is-listen-control") {
3472                 solo_control_mode_changed ();
3473         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3474                 last_timecode_valid = false;
3475         } else if (p == "playback-buffer-seconds") {
3476                 AudioSource::allocate_working_buffers (frame_rate());
3477         } else if (p == "automation-thinning-factor") {
3478                 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3479         } else if (p == "ltc-source-port") {
3480                 reconnect_ltc_input ();
3481         } else if (p == "ltc-sink-port") {
3482                 reconnect_ltc_output ();
3483         } else if (p == "timecode-generator-offset") {
3484                 ltc_tx_parse_offset();
3485         }
3486
3487         set_dirty ();
3488 }
3489
3490 void
3491 Session::set_history_depth (uint32_t d)
3492 {
3493         _history.set_depth (d);
3494 }
3495
3496 int
3497 Session::load_diskstreams_2X (XMLNode const & node, int)
3498 {
3499         XMLNodeList          clist;
3500         XMLNodeConstIterator citer;
3501
3502         clist = node.children();
3503
3504         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3505
3506                 try {
3507                         /* diskstreams added automatically by DiskstreamCreated handler */
3508                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3509                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3510                                 _diskstreams_2X.push_back (dsp);
3511                         } else {
3512                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3513                         }
3514                 }
3515
3516                 catch (failed_constructor& err) {
3517                         error << _("Session: could not load diskstream via XML state") << endmsg;
3518                         return -1;
3519                 }
3520         }
3521
3522         return 0;
3523 }
3524
3525 /** Connect things to the MMC object */
3526 void
3527 Session::setup_midi_machine_control ()
3528 {
3529         _mmc = new MIDI::MachineControl;
3530         _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3531
3532         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3533         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3534         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3535         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3536         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3537         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3538         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3539         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3540         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3541         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3542         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3543         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3544         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3545
3546         /* also handle MIDI SPP because its so common */
3547
3548         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3549         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3550         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3551 }
3552
3553 boost::shared_ptr<Controllable>
3554 Session::solo_cut_control() const
3555 {
3556         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3557            controls in Ardour that currently get presented to the user in the GUI that require
3558            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3559
3560            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3561            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3562            parameter.
3563         */
3564
3565         return _solo_cut_control;
3566 }
3567
3568 int
3569 Session::rename (const std::string& new_name)
3570 {
3571         string legal_name = legalize_for_path (new_name);
3572         string newpath;
3573         string oldstr;
3574         string newstr;
3575         bool first = true;
3576
3577         string const old_sources_root = _session_dir->sources_root();
3578
3579 #define RENAME ::rename
3580
3581         /* Rename:
3582
3583          * session directory
3584          * interchange subdirectory
3585          * session file
3586          * session history
3587          
3588          * Backup files are left unchanged and not renamed.
3589          */
3590
3591         /* pass one: not 100% safe check that the new directory names don't
3592          * already exist ...
3593          */
3594
3595         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3596                 vector<string> v;
3597
3598                 oldstr = (*i).path;
3599
3600                 /* this is a stupid hack because Glib::path_get_dirname() is
3601                  * lexical-only, and so passing it /a/b/c/ gives a different
3602                  * result than passing it /a/b/c ...
3603                  */
3604
3605                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3606                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3607                 }
3608
3609                 string base = Glib::path_get_dirname (oldstr);
3610                 string p = Glib::path_get_basename (oldstr);
3611
3612                 newstr = Glib::build_filename (base, legal_name);
3613                 
3614                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3615                         return -1;
3616                 }
3617         }
3618
3619         /* Session dirs */
3620         
3621         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3622                 vector<string> v;
3623
3624                 oldstr = (*i).path;
3625
3626                 /* this is a stupid hack because Glib::path_get_dirname() is
3627                  * lexical-only, and so passing it /a/b/c/ gives a different
3628                  * result than passing it /a/b/c ...
3629                  */
3630
3631                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3632                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3633                 }
3634
3635                 string base = Glib::path_get_dirname (oldstr);
3636                 string p = Glib::path_get_basename (oldstr);
3637
3638                 newstr = Glib::build_filename (base, legal_name);
3639
3640                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3641
3642                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3643                         return 1;
3644                 }
3645
3646                 if (first) {
3647                         (*_session_dir) = newstr;
3648                         newpath = newstr;
3649                         first = 1;
3650                 }
3651
3652                 /* directory below interchange */
3653
3654                 v.push_back (newstr);
3655                 v.push_back (interchange_dir_name);
3656                 v.push_back (p);
3657
3658                 oldstr = Glib::build_filename (v);
3659
3660                 v.clear ();
3661                 v.push_back (newstr);
3662                 v.push_back (interchange_dir_name);
3663                 v.push_back (legal_name);
3664
3665                 newstr = Glib::build_filename (v);
3666                 
3667                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3668                 
3669                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3670                         return 1;
3671                 }
3672         }
3673
3674         /* state file */
3675         
3676         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3677         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3678         
3679         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3680
3681         if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3682                 return 1;
3683         }
3684
3685         /* history file */
3686
3687         
3688         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3689
3690         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3691                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3692                 
3693                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3694                 
3695                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3696                         return 1;
3697                 }
3698         }
3699
3700         /* update file source paths */
3701         
3702         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3703                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3704                 if (fs) {
3705                         string p = fs->path ();
3706                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3707                         fs->set_path (p);
3708                 }
3709         }
3710
3711         /* remove old name from recent sessions */
3712
3713         remove_recent_sessions (_path);
3714
3715         _path = newpath;
3716         _current_snapshot_name = new_name;
3717         _name = new_name;
3718
3719         set_dirty ();
3720
3721         /* save state again to get everything just right */
3722
3723         save_state (_current_snapshot_name);
3724
3725
3726         /* add to recent sessions */
3727
3728         store_recent_sessions (new_name, _path);
3729
3730         return 0;
3731
3732 #undef RENAME
3733 }
3734
3735 int
3736 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3737 {
3738         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3739                 return -1;
3740         }
3741
3742         if (!tree.read (xmlpath)) {
3743                 return -1;
3744         }
3745
3746         return 0;
3747 }
3748
3749 int
3750 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3751 {
3752         XMLTree tree;
3753         bool found_sr = false;
3754         bool found_data_format = false;
3755
3756         if (get_session_info_from_path (tree, xmlpath)) {
3757                 return -1;
3758         }
3759
3760         /* sample rate */
3761
3762         const XMLProperty* prop;
3763         if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
3764                 sample_rate = atoi (prop->value());
3765                 found_sr = true;
3766         }
3767
3768         const XMLNodeList& children (tree.root()->children());
3769         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3770                 const XMLNode* child = *c;
3771                 if (child->name() == "Config") {
3772                         const XMLNodeList& options (child->children());
3773                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3774                                 const XMLNode* option = *oc;
3775                                 const XMLProperty* name = option->property("name");
3776
3777                                 if (!name) {
3778                                         continue;
3779                                 }
3780
3781                                 if (name->value() == "native-file-data-format") {
3782                                         const XMLProperty* value = option->property ("value");
3783                                         if (value) {
3784                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3785                                                 data_format = fmt;
3786                                                 found_data_format = true;
3787                                                 break;
3788                                         }
3789                                 }
3790                         }
3791                 }
3792                 if (found_data_format) {
3793                         break;
3794                 }
3795         }
3796
3797         return !(found_sr && found_data_format); // zero if they are both found
3798 }