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