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