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