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