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