do not mark session dirty during loading process; sync with loaded locations state...
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2013 Paul Davis
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #include <stdint.h>
26
27 #include <algorithm>
28 #include <fstream>
29 #include <string>
30 #include <cerrno>
31 #include <cstdio> /* snprintf(3) ... grrr */
32 #include <cmath>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <climits>
36 #include <signal.h>
37 #include <sys/time.h>
38
39 #ifdef HAVE_SYS_VFS_H
40 #include <sys/vfs.h>
41 #endif
42
43 #ifdef __APPLE__
44 #include <sys/param.h>
45 #include <sys/mount.h>
46 #endif
47
48 #ifdef HAVE_SYS_STATVFS_H
49 #include <sys/statvfs.h>
50 #endif
51
52 #include <glib.h>
53 #include <glib/gstdio.h>
54
55 #include <glibmm.h>
56 #include <glibmm/threads.h>
57
58 #include <boost/algorithm/string.hpp>
59
60 #include "midi++/mmc.h"
61 #include "midi++/port.h"
62
63 #include "evoral/SMF.hpp"
64
65 #include "pbd/boost_debug.h"
66 #include "pbd/basename.h"
67 #include "pbd/controllable_descriptor.h"
68 #include "pbd/enumwriter.h"
69 #include "pbd/error.h"
70 #include "pbd/file_utils.h"
71 #include "pbd/pathexpand.h"
72 #include "pbd/pthread_utils.h"
73 #include "pbd/stacktrace.h"
74 #include "pbd/convert.h"
75 #include "pbd/localtime_r.h"
76
77 #include "ardour/amp.h"
78 #include "ardour/async_midi_port.h"
79 #include "ardour/audio_diskstream.h"
80 #include "ardour/audio_track.h"
81 #include "ardour/audioengine.h"
82 #include "ardour/audiofilesource.h"
83 #include "ardour/audioregion.h"
84 #include "ardour/automation_control.h"
85 #include "ardour/butler.h"
86 #include "ardour/control_protocol_manager.h"
87 #include "ardour/directory_names.h"
88 #include "ardour/filename_extensions.h"
89 #include "ardour/graph.h"
90 #include "ardour/location.h"
91 #include "ardour/midi_model.h"
92 #include "ardour/midi_patch_manager.h"
93 #include "ardour/midi_region.h"
94 #include "ardour/midi_scene_changer.h"
95 #include "ardour/midi_source.h"
96 #include "ardour/midi_track.h"
97 #include "ardour/pannable.h"
98 #include "ardour/playlist_factory.h"
99 #include "ardour/port.h"
100 #include "ardour/processor.h"
101 #include "ardour/proxy_controllable.h"
102 #include "ardour/recent_sessions.h"
103 #include "ardour/region_factory.h"
104 #include "ardour/route_group.h"
105 #include "ardour/send.h"
106 #include "ardour/session.h"
107 #include "ardour/session_directory.h"
108 #include "ardour/session_metadata.h"
109 #include "ardour/session_playlists.h"
110 #include "ardour/session_state_utils.h"
111 #include "ardour/silentfilesource.h"
112 #include "ardour/sndfilesource.h"
113 #include "ardour/source_factory.h"
114 #include "ardour/speakers.h"
115 #include "ardour/template_utils.h"
116 #include "ardour/tempo.h"
117 #include "ardour/ticker.h"
118 #include "ardour/user_bundle.h"
119
120 #include "control_protocol/control_protocol.h"
121
122 #include "i18n.h"
123 #include <locale.h>
124
125 using namespace std;
126 using namespace ARDOUR;
127 using namespace PBD;
128
129 void
130 Session::pre_engine_init (string fullpath)
131 {
132         if (fullpath.empty()) {
133                 destroy ();
134                 throw failed_constructor();
135         }
136
137         /* discover canonical fullpath */
138
139         _path = canonical_path(fullpath);
140
141         /* we require _path to end with a dir separator */
142
143         if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
144                 _path += G_DIR_SEPARATOR;
145         }
146
147         /* is it new ? */
148
149         _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
150
151         /* finish initialization that can't be done in a normal C++ constructor
152            definition.
153         */
154
155         timerclear (&last_mmc_step);
156         g_atomic_int_set (&processing_prohibited, 0);
157         g_atomic_int_set (&_record_status, Disabled);
158         g_atomic_int_set (&_playback_load, 100);
159         g_atomic_int_set (&_capture_load, 100);
160         set_next_event ();
161         _all_route_group->set_active (true, this);
162         interpolation.add_channel_to (0, 0);
163
164         if (config.get_use_video_sync()) {
165                 waiting_for_sync_offset = true;
166         } else {
167                 waiting_for_sync_offset = false;
168         }
169
170         last_rr_session_dir = session_dirs.begin();
171
172         set_history_depth (Config->get_history_depth());
173         
174         /* default: assume simple stereo speaker configuration */
175
176         _speakers->setup_default_speakers (2);
177
178         _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
179                                                         boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
180                                                         boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
181         add_controllable (_solo_cut_control);
182
183         /* These are all static "per-class" signals */
184
185         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
186         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
187         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
188         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
189         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
190
191         /* stop IO objects from doing stuff until we're ready for them */
192
193         Delivery::disable_panners ();
194         IO::disable_connecting ();
195
196         AudioFileSource::set_peak_dir (_session_dir->peak_path());
197 }
198
199 int
200 Session::post_engine_init ()
201 {
202         BootMessage (_("Set block size and sample rate"));
203
204         set_block_size (_engine.samples_per_cycle());
205         set_frame_rate (_engine.sample_rate());
206
207         BootMessage (_("Using configuration"));
208
209         _midi_ports = new MidiPortManager;
210         
211         MIDISceneChanger* msc;
212
213         _scene_changer = msc = new MIDISceneChanger (*this);
214         msc->set_input_port (scene_input_port());
215         msc->set_output_port (scene_out());
216
217         boost::function<framecnt_t(void)> timer_func (boost::bind (&Session::audible_frame, this));
218         boost::dynamic_pointer_cast<AsyncMIDIPort>(scene_in())->set_timer (timer_func);
219
220         setup_midi_machine_control ();
221         
222         if (_butler->start_thread()) {
223                 return -1;
224         }
225         
226         if (start_midi_thread ()) {
227                 return -1;
228         }
229         
230         setup_click_sounds (0);
231         setup_midi_control ();
232
233         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
234         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
235
236         try {
237                 /* tempo map requires sample rate knowledge */
238
239                 _tempo_map = new TempoMap (_current_frame_rate);
240                 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
241                 
242                 /* MidiClock requires a tempo map */
243
244                 midi_clock = new MidiClockTicker ();
245                 midi_clock->set_session (this);
246
247                 /* crossfades require sample rate knowledge */
248
249                 SndFileSource::setup_standard_crossfades (*this, frame_rate());
250                 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
251                 
252                 AudioDiskstream::allocate_working_buffers();
253                 refresh_disk_space ();
254                 
255                 /* we're finally ready to call set_state() ... all objects have
256                  * been created, the engine is running.
257                  */
258                 
259                 if (state_tree) {
260                         if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
261                                 return -1;
262                         }
263                 } else {
264                         // set_state() will call setup_raid_path(), but if it's a new session we need
265                         // to call setup_raid_path() here.
266                         setup_raid_path (_path);
267                 }
268
269                 /* ENGINE */
270
271                 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
272                 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
273                 
274                 Config->map_parameters (ff);
275                 config.map_parameters (ft);
276
277                 /* Reset all panners */
278                 
279                 Delivery::reset_panners ();
280                 
281                 /* this will cause the CPM to instantiate any protocols that are in use
282                  * (or mandatory), which will pass it this Session, and then call
283                  * set_state() on each instantiated protocol to match stored state.
284                  */
285                 
286                 ControlProtocolManager::instance().set_session (this);
287                 
288                 /* This must be done after the ControlProtocolManager set_session above,
289                    as it will set states for ports which the ControlProtocolManager creates.
290                 */
291                 
292                 // XXX set state of MIDI::Port's
293                 // MidiPortManager::instance()->set_port_states (Config->midi_port_states ());
294                 
295                 /* And this must be done after the MIDI::Manager::set_port_states as
296                  * it will try to make connections whose details are loaded by set_port_states.
297                  */
298                 
299                 hookup_io ();
300                 
301                 /* Let control protocols know that we are now all connected, so they
302                  * could start talking to surfaces if they want to.
303                  */
304                 
305                 ControlProtocolManager::instance().midi_connectivity_established ();
306                 
307                 if (_is_new && !no_auto_connect()) {
308                         Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
309                         auto_connect_master_bus ();
310                 }
311                 
312                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
313                 
314                 /* update latencies */
315                 
316                 initialize_latencies ();
317                 
318                 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
319                 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
320                 
321                 
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         _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
337         _mmc->send (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_files (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;
1856
1857         nlist = node.children();
1858
1859         set_dirty();
1860
1861         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1862           retry:
1863                 try {
1864                         if ((source = XMLSourceFactory (**niter)) == 0) {
1865                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1866                         }
1867
1868                 } catch (MissingSource& err) {
1869
1870                         int user_choice;
1871
1872                         if (!no_questions_about_missing_files) {
1873                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1874                         } else {
1875                                 user_choice = -2;
1876                         }
1877
1878                         switch (user_choice) {
1879                         case 0:
1880                                 /* user added a new search location, so try again */
1881                                 goto retry;
1882
1883
1884                         case 1:
1885                                 /* user asked to quit the entire session load
1886                                  */
1887                                 return -1;
1888
1889                         case 2:
1890                                 no_questions_about_missing_files = true;
1891                                 goto retry;
1892
1893                         case 3:
1894                                 no_questions_about_missing_files = true;
1895                                 /* fallthru */
1896
1897                         case -1:
1898                         default:
1899                                 switch (err.type) {
1900
1901                                 case DataType::AUDIO:
1902                                         warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1903                                         source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1904                                         break;
1905
1906                                 case DataType::MIDI:
1907                                         warning << string_compose (_("A MIDI file is missing. %1 cannot currently recover from missing MIDI files"),
1908                                                                      PROGRAM_NAME) << endmsg;
1909                                         return -1;
1910                                         break;
1911                                 }
1912                                 break;
1913                         }
1914                 }
1915         }
1916
1917         return 0;
1918 }
1919
1920 boost::shared_ptr<Source>
1921 Session::XMLSourceFactory (const XMLNode& node)
1922 {
1923         if (node.name() != "Source") {
1924                 return boost::shared_ptr<Source>();
1925         }
1926
1927         try {
1928                 /* note: do peak building in another thread when loading session state */
1929                 return SourceFactory::create (*this, node, true);
1930         }
1931
1932         catch (failed_constructor& err) {
1933                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1934                 return boost::shared_ptr<Source>();
1935         }
1936 }
1937
1938 int
1939 Session::save_template (string template_name)
1940 {
1941         XMLTree tree;
1942
1943         if (_state_of_the_state & CannotSave) {
1944                 return -1;
1945         }
1946
1947         std::string user_template_dir(user_template_directory());
1948
1949         if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
1950                 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
1951                                 user_template_dir, g_strerror (errno)) << endmsg;
1952                 return -1;
1953         }
1954
1955         tree.set_root (&get_template());
1956
1957         std::string template_dir_path(user_template_dir);
1958         
1959         /* directory to put the template in */
1960         template_dir_path = Glib::build_filename (template_dir_path, template_name);
1961
1962         if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
1963                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1964                                 template_dir_path) << endmsg;
1965                 return -1;
1966         }
1967         
1968         if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
1969                 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
1970                                 template_dir_path, g_strerror (errno)) << endmsg;
1971                 return -1;
1972         }
1973
1974         /* file to write */
1975         std::string template_file_path(template_dir_path);
1976         template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
1977
1978         if (!tree.write (template_file_path)) {
1979                 error << _("template not saved") << endmsg;
1980                 return -1;
1981         }
1982
1983         /* copy plugin state directory */
1984
1985         std::string template_plugin_state_path(template_dir_path);
1986         template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
1987
1988         if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
1989                 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
1990                                 template_plugin_state_path, g_strerror (errno)) << endmsg;
1991                 return -1;
1992         }
1993
1994         copy_files (plugins_dir(), template_plugin_state_path);
1995
1996         return 0;
1997 }
1998
1999 void
2000 Session::refresh_disk_space ()
2001 {
2002 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2003         
2004         Glib::Threads::Mutex::Lock lm (space_lock);
2005
2006         /* get freespace on every FS that is part of the session path */
2007
2008         _total_free_4k_blocks = 0;
2009         _total_free_4k_blocks_uncertain = false;
2010
2011         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2012
2013                 struct statfs statfsbuf;
2014                 statfs (i->path.c_str(), &statfsbuf);
2015
2016                 double const scale = statfsbuf.f_bsize / 4096.0;
2017
2018                 /* See if this filesystem is read-only */
2019                 struct statvfs statvfsbuf;
2020                 statvfs (i->path.c_str(), &statvfsbuf);
2021
2022                 /* f_bavail can be 0 if it is undefined for whatever
2023                    filesystem we are looking at; Samba shares mounted
2024                    via GVFS are an example of this.
2025                 */
2026                 if (statfsbuf.f_bavail == 0) {
2027                         /* block count unknown */
2028                         i->blocks = 0;
2029                         i->blocks_unknown = true;
2030                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2031                         /* read-only filesystem */
2032                         i->blocks = 0;
2033                         i->blocks_unknown = false;
2034                 } else {
2035                         /* read/write filesystem with known space */
2036                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2037                         i->blocks_unknown = false;
2038                 }
2039
2040                 _total_free_4k_blocks += i->blocks;
2041                 if (i->blocks_unknown) {
2042                         _total_free_4k_blocks_uncertain = true;
2043                 }
2044         }
2045 #elif defined (COMPILER_MSVC)
2046         vector<string> scanned_volumes;
2047         vector<string>::iterator j;
2048         vector<space_and_path>::iterator i;
2049     DWORD nSectorsPerCluster, nBytesPerSector,
2050           nFreeClusters, nTotalClusters;
2051     char disk_drive[4];
2052         bool volume_found;
2053
2054         _total_free_4k_blocks = 0;
2055
2056         for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2057                 strncpy (disk_drive, (*i).path.c_str(), 3);
2058                 disk_drive[3] = 0;
2059                 strupr(disk_drive);
2060
2061                 volume_found = false;
2062                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2063                 {
2064                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2065                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2066                         i->blocks = (uint32_t)(nFreeBytes / 4096);
2067
2068                         for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2069                                 if (0 == j->compare(disk_drive)) {
2070                                         volume_found = true;
2071                                         break;
2072                                 }
2073                         }
2074
2075                         if (!volume_found) {
2076                                 scanned_volumes.push_back(disk_drive);
2077                                 _total_free_4k_blocks += i->blocks;
2078                         }
2079                 }
2080         }
2081
2082         if (0 == _total_free_4k_blocks) {
2083                 strncpy (disk_drive, path().c_str(), 3);
2084                 disk_drive[3] = 0;
2085
2086                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2087                 {
2088                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2089                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2090                         _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2091                 }
2092         }
2093 #endif
2094 }
2095
2096 string
2097 Session::get_best_session_directory_for_new_audio ()
2098 {
2099         vector<space_and_path>::iterator i;
2100         string result = _session_dir->root_path();
2101
2102         /* handle common case without system calls */
2103
2104         if (session_dirs.size() == 1) {
2105                 return result;
2106         }
2107
2108         /* OK, here's the algorithm we're following here:
2109
2110         We want to select which directory to use for
2111         the next file source to be created. Ideally,
2112         we'd like to use a round-robin process so as to
2113         get maximum performance benefits from splitting
2114         the files across multiple disks.
2115
2116         However, in situations without much diskspace, an
2117         RR approach may end up filling up a filesystem
2118         with new files while others still have space.
2119         Its therefore important to pay some attention to
2120         the freespace in the filesystem holding each
2121         directory as well. However, if we did that by
2122         itself, we'd keep creating new files in the file
2123         system with the most space until it was as full
2124         as all others, thus negating any performance
2125         benefits of this RAID-1 like approach.
2126
2127         So, we use a user-configurable space threshold. If
2128         there are at least 2 filesystems with more than this
2129         much space available, we use RR selection between them.
2130         If not, then we pick the filesystem with the most space.
2131
2132         This gets a good balance between the two
2133         approaches.
2134         */
2135
2136         refresh_disk_space ();
2137
2138         int free_enough = 0;
2139
2140         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2141                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2142                         free_enough++;
2143                 }
2144         }
2145
2146         if (free_enough >= 2) {
2147                 /* use RR selection process, ensuring that the one
2148                    picked works OK.
2149                 */
2150
2151                 i = last_rr_session_dir;
2152
2153                 do {
2154                         if (++i == session_dirs.end()) {
2155                                 i = session_dirs.begin();
2156                         }
2157
2158                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2159                                 SessionDirectory sdir(i->path);
2160                                 if (sdir.create ()) {
2161                                         result = (*i).path;
2162                                         last_rr_session_dir = i;
2163                                         return result;
2164                                 }
2165                         }
2166
2167                 } while (i != last_rr_session_dir);
2168
2169         } else {
2170
2171                 /* pick FS with the most freespace (and that
2172                    seems to actually work ...)
2173                 */
2174
2175                 vector<space_and_path> sorted;
2176                 space_and_path_ascending_cmp cmp;
2177
2178                 sorted = session_dirs;
2179                 sort (sorted.begin(), sorted.end(), cmp);
2180
2181                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2182                         SessionDirectory sdir(i->path);
2183                         if (sdir.create ()) {
2184                                 result = (*i).path;
2185                                 last_rr_session_dir = i;
2186                                 return result;
2187                         }
2188                 }
2189         }
2190
2191         return result;
2192 }
2193
2194 string
2195 Session::automation_dir () const
2196 {
2197         return Glib::build_filename (_path, "automation");
2198 }
2199
2200 string
2201 Session::analysis_dir () const
2202 {
2203         return Glib::build_filename (_path, "analysis");
2204 }
2205
2206 string
2207 Session::plugins_dir () const
2208 {
2209         return Glib::build_filename (_path, "plugins");
2210 }
2211
2212 string
2213 Session::externals_dir () const
2214 {
2215         return Glib::build_filename (_path, "externals");
2216 }
2217
2218 int
2219 Session::load_bundles (XMLNode const & node)
2220 {
2221         XMLNodeList nlist = node.children();
2222         XMLNodeConstIterator niter;
2223
2224         set_dirty();
2225
2226         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2227                 if ((*niter)->name() == "InputBundle") {
2228                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2229                 } else if ((*niter)->name() == "OutputBundle") {
2230                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2231                 } else {
2232                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2233                         return -1;
2234                 }
2235         }
2236
2237         return 0;
2238 }
2239
2240 int
2241 Session::load_route_groups (const XMLNode& node, int version)
2242 {
2243         XMLNodeList nlist = node.children();
2244         XMLNodeConstIterator niter;
2245
2246         set_dirty ();
2247
2248         if (version >= 3000) {
2249
2250                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2251                         if ((*niter)->name() == "RouteGroup") {
2252                                 RouteGroup* rg = new RouteGroup (*this, "");
2253                                 add_route_group (rg);
2254                                 rg->set_state (**niter, version);
2255                         }
2256                 }
2257
2258         } else if (version < 3000) {
2259
2260                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2261                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2262                                 RouteGroup* rg = new RouteGroup (*this, "");
2263                                 add_route_group (rg);
2264                                 rg->set_state (**niter, version);
2265                         }
2266                 }
2267         }
2268
2269         return 0;
2270 }
2271
2272 static bool
2273 state_file_filter (const string &str, void* /*arg*/)
2274 {
2275         return (str.length() > strlen(statefile_suffix) &&
2276                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2277 }
2278
2279 static string
2280 remove_end(string state)
2281 {
2282         string statename(state);
2283
2284         string::size_type start,end;
2285         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2286                 statename = statename.substr (start+1);
2287         }
2288
2289         if ((end = statename.rfind(".ardour")) == string::npos) {
2290                 end = statename.length();
2291         }
2292
2293         return string(statename.substr (0, end));
2294 }
2295
2296 vector<string>
2297 Session::possible_states (string path)
2298 {
2299         vector<string> states;
2300         find_files_matching_filter (states, path, state_file_filter, 0, false, false);
2301
2302         transform(states.begin(), states.end(), states.begin(), remove_end);
2303
2304         sort (states.begin(), states.end());
2305
2306         return states;
2307 }
2308
2309 vector<string>
2310 Session::possible_states () const
2311 {
2312         return possible_states(_path);
2313 }
2314
2315 void
2316 Session::add_route_group (RouteGroup* g)
2317 {
2318         _route_groups.push_back (g);
2319         route_group_added (g); /* EMIT SIGNAL */
2320
2321         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2322         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2323         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2324
2325         set_dirty ();
2326 }
2327
2328 void
2329 Session::remove_route_group (RouteGroup& rg)
2330 {
2331         list<RouteGroup*>::iterator i;
2332
2333         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2334                 _route_groups.erase (i);
2335                 delete &rg;
2336
2337                 route_group_removed (); /* EMIT SIGNAL */
2338         }
2339 }
2340
2341 /** Set a new order for our route groups, without adding or removing any.
2342  *  @param groups Route group list in the new order.
2343  */
2344 void
2345 Session::reorder_route_groups (list<RouteGroup*> groups)
2346 {
2347         _route_groups = groups;
2348
2349         route_groups_reordered (); /* EMIT SIGNAL */
2350         set_dirty ();
2351 }
2352
2353
2354 RouteGroup *
2355 Session::route_group_by_name (string name)
2356 {
2357         list<RouteGroup *>::iterator i;
2358
2359         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2360                 if ((*i)->name() == name) {
2361                         return* i;
2362                 }
2363         }
2364         return 0;
2365 }
2366
2367 RouteGroup&
2368 Session::all_route_group() const
2369 {
2370         return *_all_route_group;
2371 }
2372
2373 void
2374 Session::add_commands (vector<Command*> const & cmds)
2375 {
2376         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2377                 add_command (*i);
2378         }
2379 }
2380
2381 void
2382 Session::begin_reversible_command (const string& name)
2383 {
2384         begin_reversible_command (g_quark_from_string (name.c_str ()));
2385 }
2386
2387 /** Begin a reversible command using a GQuark to identify it.
2388  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2389  *  but there must be as many begin...()s as there are commit...()s.
2390  */
2391 void
2392 Session::begin_reversible_command (GQuark q)
2393 {
2394         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2395            to hold all the commands that are committed.  This keeps the order of
2396            commands correct in the history.
2397         */
2398
2399         if (_current_trans == 0) {
2400                 /* start a new transaction */
2401                 assert (_current_trans_quarks.empty ());
2402                 _current_trans = new UndoTransaction();
2403                 _current_trans->set_name (g_quark_to_string (q));
2404         }
2405
2406         _current_trans_quarks.push_front (q);
2407 }
2408
2409 void
2410 Session::commit_reversible_command (Command *cmd)
2411 {
2412         assert (_current_trans);
2413         assert (!_current_trans_quarks.empty ());
2414
2415         struct timeval now;
2416
2417         if (cmd) {
2418                 _current_trans->add_command (cmd);
2419         }
2420
2421         _current_trans_quarks.pop_front ();
2422
2423         if (!_current_trans_quarks.empty ()) {
2424                 /* the transaction we're committing is not the top-level one */
2425                 return;
2426         }
2427
2428         if (_current_trans->empty()) {
2429                 /* no commands were added to the transaction, so just get rid of it */
2430                 delete _current_trans;
2431                 _current_trans = 0;
2432                 return;
2433         }
2434
2435         gettimeofday (&now, 0);
2436         _current_trans->set_timestamp (now);
2437
2438         _history.add (_current_trans);
2439         _current_trans = 0;
2440 }
2441
2442 static bool
2443 accept_all_audio_files (const string& path, void* /*arg*/)
2444 {
2445         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2446                 return false;
2447         }
2448
2449         if (!AudioFileSource::safe_audio_file_extension (path)) {
2450                 return false;
2451         }
2452
2453         return true;
2454 }
2455
2456 static bool
2457 accept_all_midi_files (const string& path, void* /*arg*/)
2458 {
2459         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2460                 return false;
2461         }
2462
2463         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2464                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2465                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2466 }
2467
2468 static bool
2469 accept_all_state_files (const string& path, void* /*arg*/)
2470 {
2471         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2472                 return false;
2473         }
2474
2475         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2476 }
2477
2478 int
2479 Session::find_all_sources (string path, set<string>& result)
2480 {
2481         XMLTree tree;
2482         XMLNode* node;
2483
2484         if (!tree.read (path)) {
2485                 return -1;
2486         }
2487
2488         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2489                 return -2;
2490         }
2491
2492         XMLNodeList nlist;
2493         XMLNodeConstIterator niter;
2494
2495         nlist = node->children();
2496
2497         set_dirty();
2498
2499         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2500
2501                 XMLProperty* prop;
2502
2503                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2504                         continue;
2505                 }
2506
2507                 DataType type (prop->value());
2508
2509                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2510                         continue;
2511                 }
2512
2513                 if (Glib::path_is_absolute (prop->value())) {
2514                         /* external file, ignore */
2515                         continue;
2516                 }
2517
2518                 string found_path;
2519                 bool is_new;
2520                 uint16_t chan;
2521
2522                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2523                         result.insert (found_path);
2524                 }
2525         }
2526
2527         return 0;
2528 }
2529
2530 int
2531 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2532 {
2533         vector<string> state_files;
2534         string ripped;
2535         string this_snapshot_path;
2536
2537         result.clear ();
2538
2539         ripped = _path;
2540
2541         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2542                 ripped = ripped.substr (0, ripped.length() - 1);
2543         }
2544
2545         find_files_matching_filter (state_files, ripped, accept_all_state_files, (void *) 0, true, true);
2546
2547         if (state_files.empty()) {
2548                 /* impossible! */
2549                 return 0;
2550         }
2551
2552         this_snapshot_path = _path;
2553         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2554         this_snapshot_path += statefile_suffix;
2555
2556         for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
2557
2558                 if (exclude_this_snapshot && *i == this_snapshot_path) {
2559                         continue;
2560                 }
2561
2562                 if (find_all_sources (*i, result) < 0) {
2563                         return -1;
2564                 }
2565         }
2566
2567         return 0;
2568 }
2569
2570 struct RegionCounter {
2571     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2572     AudioSourceList::iterator iter;
2573     boost::shared_ptr<Region> region;
2574     uint32_t count;
2575
2576     RegionCounter() : count (0) {}
2577 };
2578
2579 int
2580 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2581 {
2582         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2583         return r.get_value_or (1);
2584 }
2585
2586 void
2587 Session::cleanup_regions ()
2588 {
2589         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2590
2591         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2592
2593                 uint32_t used = playlists->region_use_count (i->second);
2594
2595                 if (used == 0 && !i->second->automatic ()) {
2596                         RegionFactory::map_remove (i->second);
2597                 }
2598         }
2599
2600         /* dump the history list */
2601         _history.clear ();
2602
2603         save_state ("");
2604 }
2605
2606 int
2607 Session::cleanup_sources (CleanupReport& rep)
2608 {
2609         // FIXME: needs adaptation to midi
2610
2611         vector<boost::shared_ptr<Source> > dead_sources;
2612         string audio_path;
2613         string midi_path;
2614         vector<string> candidates;
2615         vector<string> unused;
2616         set<string> all_sources;
2617         bool used;
2618         string spath;
2619         int ret = -1;
2620         string tmppath1;
2621         string tmppath2;
2622         Searchpath asp;
2623         Searchpath msp;
2624
2625         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2626
2627         /* consider deleting all unused playlists */
2628
2629         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2630                 ret = 0;
2631                 goto out;
2632         }
2633
2634         /* sync the "all regions" property of each playlist with its current state
2635          */
2636
2637         playlists->sync_all_regions_with_regions ();
2638
2639         /* find all un-used sources */
2640
2641         rep.paths.clear ();
2642         rep.space = 0;
2643
2644         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2645
2646                 SourceMap::iterator tmp;
2647
2648                 tmp = i;
2649                 ++tmp;
2650
2651                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2652                    capture files.
2653                 */
2654
2655                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2656                         dead_sources.push_back (i->second);
2657                         i->second->drop_references ();
2658                 }
2659
2660                 i = tmp;
2661         }
2662
2663         /* build a list of all the possible audio directories for the session */
2664
2665         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2666                 SessionDirectory sdir ((*i).path);
2667                 asp += sdir.sound_path();
2668         }
2669         audio_path += asp.to_string();
2670
2671
2672         /* build a list of all the possible midi directories for the session */
2673
2674         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2675                 SessionDirectory sdir ((*i).path);
2676                 msp += sdir.midi_path();
2677         }
2678         midi_path += msp.to_string();
2679
2680         find_files_matching_filter (candidates, audio_path, accept_all_audio_files, (void *) 0, true, true);
2681         find_files_matching_filter (candidates, midi_path, accept_all_midi_files, (void *) 0, true, true);
2682
2683         /* find all sources, but don't use this snapshot because the
2684            state file on disk still references sources we may have already
2685            dropped.
2686         */
2687
2688         find_all_sources_across_snapshots (all_sources, true);
2689
2690         /*  add our current source list
2691          */
2692
2693         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2694                 boost::shared_ptr<FileSource> fs;
2695                 SourceMap::iterator tmp = i;
2696                 ++tmp;
2697
2698                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2699
2700                         if (!fs->is_stub()) {
2701
2702                                 if (playlists->source_use_count (fs) != 0) {
2703                                         all_sources.insert (fs->path());
2704                                 } else {
2705                                         
2706                                         /* we might not remove this source from disk, because it may be used
2707                                            by other snapshots, but its not being used in this version
2708                                            so lets get rid of it now, along with any representative regions
2709                                            in the region list.
2710                                         */
2711                                         
2712                                         RegionFactory::remove_regions_using_source (i->second);
2713                                         sources.erase (i);
2714                                 }
2715                         }
2716                 }
2717
2718                 i = tmp;
2719         }
2720
2721         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
2722
2723                 used = false;
2724                 spath = *x;
2725
2726                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2727
2728                         tmppath1 = canonical_path (spath);
2729                         tmppath2 = canonical_path ((*i));
2730
2731                         if (tmppath1 == tmppath2) {
2732                                 used = true;
2733                                 break;
2734                         }
2735                 }
2736
2737                 if (!used) {
2738                         unused.push_back (spath);
2739                 }
2740         }
2741
2742         /* now try to move all unused files into the "dead" directory(ies) */
2743
2744         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2745                 struct stat statbuf;
2746
2747                 string newpath;
2748
2749                 /* don't move the file across filesystems, just
2750                    stick it in the `dead_dir_name' directory
2751                    on whichever filesystem it was already on.
2752                 */
2753
2754                 if ((*x).find ("/sounds/") != string::npos) {
2755
2756                         /* old school, go up 1 level */
2757
2758                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2759                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2760
2761                 } else {
2762
2763                         /* new school, go up 4 levels */
2764
2765                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2766                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2767                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2768                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2769                 }
2770
2771                 newpath = Glib::build_filename (newpath, dead_dir_name);
2772
2773                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2774                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2775                         return -1;
2776                 }
2777
2778                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2779
2780                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2781
2782                         /* the new path already exists, try versioning */
2783
2784                         char buf[PATH_MAX+1];
2785                         int version = 1;
2786                         string newpath_v;
2787
2788                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2789                         newpath_v = buf;
2790
2791                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2792                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2793                                 newpath_v = buf;
2794                         }
2795
2796                         if (version == 999) {
2797                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2798                                                   newpath)
2799                                       << endmsg;
2800                         } else {
2801                                 newpath = newpath_v;
2802                         }
2803
2804                 } else {
2805
2806                         /* it doesn't exist, or we can't read it or something */
2807
2808                 }
2809
2810                 stat ((*x).c_str(), &statbuf);
2811
2812                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2813                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2814                                           (*x), newpath, strerror (errno))
2815                               << endmsg;
2816                         goto out;
2817                 }
2818
2819                 /* see if there an easy to find peakfile for this file, and remove it.
2820                  */
2821
2822                 string base = basename_nosuffix (*x);
2823                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2824                                  or for the first channel of embedded files. it will miss
2825                                  some peakfiles for other channels
2826                               */
2827                 string peakpath = peak_path (base);
2828
2829                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2830                         if (::g_unlink (peakpath.c_str()) != 0) {
2831                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2832                                                          peakpath, _path, strerror (errno))
2833                                       << endmsg;
2834                                 /* try to back out */
2835                                 ::rename (newpath.c_str(), _path.c_str());
2836                                 goto out;
2837                         }
2838                 }
2839
2840                 rep.paths.push_back (*x);
2841                 rep.space += statbuf.st_size;
2842         }
2843
2844         /* dump the history list */
2845
2846         _history.clear ();
2847
2848         /* save state so we don't end up a session file
2849            referring to non-existent sources.
2850         */
2851
2852         save_state ("");
2853         ret = 0;
2854
2855   out:
2856         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2857
2858         return ret;
2859 }
2860
2861 int
2862 Session::cleanup_trash_sources (CleanupReport& rep)
2863 {
2864         // FIXME: needs adaptation for MIDI
2865
2866         vector<space_and_path>::iterator i;
2867         string dead_dir;
2868
2869         rep.paths.clear ();
2870         rep.space = 0;
2871
2872         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2873
2874                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2875
2876                 clear_directory (dead_dir, &rep.space, &rep.paths);
2877         }
2878
2879         return 0;
2880 }
2881
2882 void
2883 Session::set_dirty ()
2884 {
2885         /* never mark session dirty during loading */
2886
2887         if (_state_of_the_state & Loading) {
2888                 return;
2889         }
2890
2891         bool was_dirty = dirty();
2892
2893         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2894
2895
2896         if (!was_dirty) {
2897                 DirtyChanged(); /* EMIT SIGNAL */
2898         }
2899 }
2900
2901
2902 void
2903 Session::set_clean ()
2904 {
2905         bool was_dirty = dirty();
2906
2907         _state_of_the_state = Clean;
2908
2909
2910         if (was_dirty) {
2911                 DirtyChanged(); /* EMIT SIGNAL */
2912         }
2913 }
2914
2915 void
2916 Session::set_deletion_in_progress ()
2917 {
2918         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2919 }
2920
2921 void
2922 Session::clear_deletion_in_progress ()
2923 {
2924         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2925 }
2926
2927 void
2928 Session::add_controllable (boost::shared_ptr<Controllable> c)
2929 {
2930         /* this adds a controllable to the list managed by the Session.
2931            this is a subset of those managed by the Controllable class
2932            itself, and represents the only ones whose state will be saved
2933            as part of the session.
2934         */
2935
2936         Glib::Threads::Mutex::Lock lm (controllables_lock);
2937         controllables.insert (c);
2938 }
2939
2940 struct null_deleter { void operator()(void const *) const {} };
2941
2942 void
2943 Session::remove_controllable (Controllable* c)
2944 {
2945         if (_state_of_the_state & Deletion) {
2946                 return;
2947         }
2948
2949         Glib::Threads::Mutex::Lock lm (controllables_lock);
2950
2951         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2952
2953         if (x != controllables.end()) {
2954                 controllables.erase (x);
2955         }
2956 }
2957
2958 boost::shared_ptr<Controllable>
2959 Session::controllable_by_id (const PBD::ID& id)
2960 {
2961         Glib::Threads::Mutex::Lock lm (controllables_lock);
2962
2963         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2964                 if ((*i)->id() == id) {
2965                         return *i;
2966                 }
2967         }
2968
2969         return boost::shared_ptr<Controllable>();
2970 }
2971
2972 boost::shared_ptr<Controllable>
2973 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2974 {
2975         boost::shared_ptr<Controllable> c;
2976         boost::shared_ptr<Route> r;
2977
2978         switch (desc.top_level_type()) {
2979         case ControllableDescriptor::NamedRoute:
2980         {
2981                 std::string str = desc.top_level_name();
2982                 if (str == "Master" || str == "master") {
2983                         r = _master_out;
2984                 } else if (str == "control" || str == "listen") {
2985                         r = _monitor_out;
2986                 } else {
2987                         r = route_by_name (desc.top_level_name());
2988                 }
2989                 break;
2990         }
2991
2992         case ControllableDescriptor::RemoteControlID:
2993                 r = route_by_remote_id (desc.rid());
2994                 break;
2995         }
2996
2997         if (!r) {
2998                 return c;
2999         }
3000
3001         switch (desc.subtype()) {
3002         case ControllableDescriptor::Gain:
3003                 c = r->gain_control ();
3004                 break;
3005
3006         case ControllableDescriptor::Solo:
3007                 c = r->solo_control();
3008                 break;
3009
3010         case ControllableDescriptor::Mute:
3011                 c = r->mute_control();
3012                 break;
3013
3014         case ControllableDescriptor::Recenable:
3015         {
3016                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3017
3018                 if (t) {
3019                         c = t->rec_enable_control ();
3020                 }
3021                 break;
3022         }
3023
3024         case ControllableDescriptor::PanDirection:
3025         {
3026                 c = r->pannable()->pan_azimuth_control;
3027                 break;
3028         }
3029
3030         case ControllableDescriptor::PanWidth:
3031         {
3032                 c = r->pannable()->pan_width_control;
3033                 break;
3034         }
3035
3036         case ControllableDescriptor::PanElevation:
3037         {
3038                 c = r->pannable()->pan_elevation_control;
3039                 break;
3040         }
3041
3042         case ControllableDescriptor::Balance:
3043                 /* XXX simple pan control */
3044                 break;
3045
3046         case ControllableDescriptor::PluginParameter:
3047         {
3048                 uint32_t plugin = desc.target (0);
3049                 uint32_t parameter_index = desc.target (1);
3050
3051                 /* revert to zero based counting */
3052
3053                 if (plugin > 0) {
3054                         --plugin;
3055                 }
3056
3057                 if (parameter_index > 0) {
3058                         --parameter_index;
3059                 }
3060
3061                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3062
3063                 if (p) {
3064                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3065                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3066                 }
3067                 break;
3068         }
3069
3070         case ControllableDescriptor::SendGain:
3071         {
3072                 uint32_t send = desc.target (0);
3073
3074                 /* revert to zero-based counting */
3075
3076                 if (send > 0) {
3077                         --send;
3078                 }
3079
3080                 boost::shared_ptr<Processor> p = r->nth_send (send);
3081
3082                 if (p) {
3083                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3084                         boost::shared_ptr<Amp> a = s->amp();
3085                         
3086                         if (a) {
3087                                 c = s->amp()->gain_control();
3088                         }
3089                 }
3090                 break;
3091         }
3092
3093         default:
3094                 /* relax and return a null pointer */
3095                 break;
3096         }
3097
3098         return c;
3099 }
3100
3101 void
3102 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3103 {
3104         if (_writable) {
3105                 Stateful::add_instant_xml (node, _path);
3106         }
3107
3108         if (write_to_config) {
3109                 Config->add_instant_xml (node);
3110         }
3111 }
3112
3113 XMLNode*
3114 Session::instant_xml (const string& node_name)
3115 {
3116         return Stateful::instant_xml (node_name, _path);
3117 }
3118
3119 int
3120 Session::save_history (string snapshot_name)
3121 {
3122         XMLTree tree;
3123
3124         if (!_writable) {
3125                 return 0;
3126         }
3127
3128         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 || 
3129             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3130                 return 0;
3131         }
3132
3133         if (snapshot_name.empty()) {
3134                 snapshot_name = _current_snapshot_name;
3135         }
3136
3137         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3138         const string backup_filename = history_filename + backup_suffix;
3139         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3140         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3141
3142         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3143                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3144                         error << _("could not backup old history file, current history not saved") << endmsg;
3145                         return -1;
3146                 }
3147         }
3148
3149         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3150
3151         if (!tree.write (xml_path))
3152         {
3153                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3154
3155                 if (g_remove (xml_path.c_str()) != 0) {
3156                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3157                                         xml_path, g_strerror (errno)) << endmsg;
3158                 }
3159                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3160                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3161                                         backup_path, g_strerror (errno)) << endmsg;
3162                 }
3163
3164                 return -1;
3165         }
3166
3167         return 0;
3168 }
3169
3170 int
3171 Session::restore_history (string snapshot_name)
3172 {
3173         XMLTree tree;
3174
3175         if (snapshot_name.empty()) {
3176                 snapshot_name = _current_snapshot_name;
3177         }
3178
3179         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3180         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3181
3182         info << "Loading history from " << xml_path << endmsg;
3183
3184         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3185                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3186                                 _name, xml_path) << endmsg;
3187                 return 1;
3188         }
3189
3190         if (!tree.read (xml_path)) {
3191                 error << string_compose (_("Could not understand session history file \"%1\""),
3192                                 xml_path) << endmsg;
3193                 return -1;
3194         }
3195
3196         // replace history
3197         _history.clear();
3198
3199         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3200
3201                 XMLNode *t = *it;
3202                 UndoTransaction* ut = new UndoTransaction ();
3203                 struct timeval tv;
3204
3205                 ut->set_name(t->property("name")->value());
3206                 stringstream ss(t->property("tv-sec")->value());
3207                 ss >> tv.tv_sec;
3208                 ss.str(t->property("tv-usec")->value());
3209                 ss >> tv.tv_usec;
3210                 ut->set_timestamp(tv);
3211
3212                 for (XMLNodeConstIterator child_it  = t->children().begin();
3213                                 child_it != t->children().end(); child_it++)
3214                 {
3215                         XMLNode *n = *child_it;
3216                         Command *c;
3217
3218                         if (n->name() == "MementoCommand" ||
3219                                         n->name() == "MementoUndoCommand" ||
3220                                         n->name() == "MementoRedoCommand") {
3221
3222                                 if ((c = memento_command_factory(n))) {
3223                                         ut->add_command(c);
3224                                 }
3225
3226                         } else if (n->name() == "NoteDiffCommand") {
3227                                 PBD::ID id (n->property("midi-source")->value());
3228                                 boost::shared_ptr<MidiSource> midi_source =
3229                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3230                                 if (midi_source) {
3231                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3232                                 } else {
3233                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3234                                 }
3235
3236                         } else if (n->name() == "SysExDiffCommand") {
3237
3238                                 PBD::ID id (n->property("midi-source")->value());
3239                                 boost::shared_ptr<MidiSource> midi_source =
3240                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3241                                 if (midi_source) {
3242                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3243                                 } else {
3244                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3245                                 }
3246
3247                         } else if (n->name() == "PatchChangeDiffCommand") {
3248
3249                                 PBD::ID id (n->property("midi-source")->value());
3250                                 boost::shared_ptr<MidiSource> midi_source =
3251                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3252                                 if (midi_source) {
3253                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3254                                 } else {
3255                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3256                                 }
3257
3258                         } else if (n->name() == "StatefulDiffCommand") {
3259                                 if ((c = stateful_diff_command_factory (n))) {
3260                                         ut->add_command (c);
3261                                 }
3262                         } else {
3263                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3264                         }
3265                 }
3266
3267                 _history.add (ut);
3268         }
3269
3270         return 0;
3271 }
3272
3273 void
3274 Session::config_changed (std::string p, bool ours)
3275 {
3276         if (ours) {
3277                 set_dirty ();
3278         }
3279
3280         if (p == "seamless-loop") {
3281
3282         } else if (p == "rf-speed") {
3283
3284         } else if (p == "auto-loop") {
3285
3286         } else if (p == "auto-input") {
3287
3288                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3289                         /* auto-input only makes a difference if we're rolling */
3290                         set_track_monitor_input_status (!config.get_auto_input());
3291                 }
3292
3293         } else if (p == "punch-in") {
3294
3295                 Location* location;
3296
3297                 if ((location = _locations->auto_punch_location()) != 0) {
3298
3299                         if (config.get_punch_in ()) {
3300                                 replace_event (SessionEvent::PunchIn, location->start());
3301                         } else {
3302                                 remove_event (location->start(), SessionEvent::PunchIn);
3303                         }
3304                 }
3305
3306         } else if (p == "punch-out") {
3307
3308                 Location* location;
3309
3310                 if ((location = _locations->auto_punch_location()) != 0) {
3311
3312                         if (config.get_punch_out()) {
3313                                 replace_event (SessionEvent::PunchOut, location->end());
3314                         } else {
3315                                 clear_events (SessionEvent::PunchOut);
3316                         }
3317                 }
3318
3319         } else if (p == "edit-mode") {
3320
3321                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3322
3323                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3324                         (*i)->set_edit_mode (Config->get_edit_mode ());
3325                 }
3326
3327         } else if (p == "use-video-sync") {
3328
3329                 waiting_for_sync_offset = config.get_use_video_sync();
3330
3331         } else if (p == "mmc-control") {
3332
3333                 //poke_midi_thread ();
3334
3335         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3336
3337                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3338
3339         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3340
3341                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3342
3343         } else if (p == "midi-control") {
3344
3345                 //poke_midi_thread ();
3346
3347         } else if (p == "raid-path") {
3348
3349                 setup_raid_path (config.get_raid_path());
3350
3351         } else if (p == "timecode-format") {
3352
3353                 sync_time_vars ();
3354
3355         } else if (p == "video-pullup") {
3356
3357                 sync_time_vars ();
3358
3359         } else if (p == "seamless-loop") {
3360
3361                 if (play_loop && transport_rolling()) {
3362                         // to reset diskstreams etc
3363                         request_play_loop (true);
3364                 }
3365
3366         } else if (p == "rf-speed") {
3367
3368                 cumulative_rf_motion = 0;
3369                 reset_rf_scale (0);
3370
3371         } else if (p == "click-sound") {
3372
3373                 setup_click_sounds (1);
3374
3375         } else if (p == "click-emphasis-sound") {
3376
3377                 setup_click_sounds (-1);
3378
3379         } else if (p == "clicking") {
3380
3381                 if (Config->get_clicking()) {
3382                         if (_click_io && click_data) { // don't require emphasis data
3383                                 _clicking = true;
3384                         }
3385                 } else {
3386                         _clicking = false;
3387                 }
3388
3389         } else if (p == "click-gain") {
3390                 
3391                 if (_click_gain) {
3392                         _click_gain->set_gain (Config->get_click_gain(), this);
3393                 }
3394
3395         } else if (p == "send-mtc") {
3396
3397                 if (Config->get_send_mtc ()) {
3398                         /* mark us ready to send */
3399                         next_quarter_frame_to_send = 0;
3400                 }
3401
3402         } else if (p == "send-mmc") {
3403
3404                 _mmc->enable_send (Config->get_send_mmc ());
3405
3406         } else if (p == "midi-feedback") {
3407
3408                 session_midi_feedback = Config->get_midi_feedback();
3409
3410         } else if (p == "jack-time-master") {
3411
3412                 engine().reset_timebase ();
3413
3414         } else if (p == "native-file-header-format") {
3415
3416                 if (!first_file_header_format_reset) {
3417                         reset_native_file_format ();
3418                 }
3419
3420                 first_file_header_format_reset = false;
3421
3422         } else if (p == "native-file-data-format") {
3423
3424                 if (!first_file_data_format_reset) {
3425                         reset_native_file_format ();
3426                 }
3427
3428                 first_file_data_format_reset = false;
3429
3430         } else if (p == "external-sync") {
3431                 if (!config.get_external_sync()) {
3432                         drop_sync_source ();
3433                 } else {
3434                         switch_to_sync_source (Config->get_sync_source());
3435                 }
3436         }  else if (p == "denormal-model") {
3437                 setup_fpu ();
3438         } else if (p == "history-depth") {
3439                 set_history_depth (Config->get_history_depth());
3440         } else if (p == "remote-model") {
3441                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3442                    TO SET REMOTE ID'S
3443                 */
3444         } else if (p == "initial-program-change") {
3445
3446                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3447                         MIDI::byte buf[2];
3448
3449                         buf[0] = MIDI::program; // channel zero by default
3450                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3451
3452                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3453                 }
3454         } else if (p == "solo-mute-override") {
3455                 // catch_up_on_solo_mute_override ();
3456         } else if (p == "listen-position" || p == "pfl-position") {
3457                 listen_position_changed ();
3458         } else if (p == "solo-control-is-listen-control") {
3459                 solo_control_mode_changed ();
3460         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3461                 last_timecode_valid = false;
3462         } else if (p == "playback-buffer-seconds") {
3463                 AudioSource::allocate_working_buffers (frame_rate());
3464         } else if (p == "automation-thinning-factor") {
3465                 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3466         } else if (p == "ltc-source-port") {
3467                 reconnect_ltc_input ();
3468         } else if (p == "ltc-sink-port") {
3469                 reconnect_ltc_output ();
3470         } else if (p == "timecode-generator-offset") {
3471                 ltc_tx_parse_offset();
3472         }
3473
3474         set_dirty ();
3475 }
3476
3477 void
3478 Session::set_history_depth (uint32_t d)
3479 {
3480         _history.set_depth (d);
3481 }
3482
3483 int
3484 Session::load_diskstreams_2X (XMLNode const & node, int)
3485 {
3486         XMLNodeList          clist;
3487         XMLNodeConstIterator citer;
3488
3489         clist = node.children();
3490
3491         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3492
3493                 try {
3494                         /* diskstreams added automatically by DiskstreamCreated handler */
3495                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3496                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3497                                 _diskstreams_2X.push_back (dsp);
3498                         } else {
3499                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3500                         }
3501                 }
3502
3503                 catch (failed_constructor& err) {
3504                         error << _("Session: could not load diskstream via XML state") << endmsg;
3505                         return -1;
3506                 }
3507         }
3508
3509         return 0;
3510 }
3511
3512 /** Connect things to the MMC object */
3513 void
3514 Session::setup_midi_machine_control ()
3515 {
3516         _mmc = new MIDI::MachineControl;
3517         _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3518
3519         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3520         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3521         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3522         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3523         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3524         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3525         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3526         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3527         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3528         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3529         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3530         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3531         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3532
3533         /* also handle MIDI SPP because its so common */
3534
3535         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3536         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3537         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3538 }
3539
3540 boost::shared_ptr<Controllable>
3541 Session::solo_cut_control() const
3542 {
3543         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3544            controls in Ardour that currently get presented to the user in the GUI that require
3545            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3546
3547            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3548            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3549            parameter.
3550         */
3551
3552         return _solo_cut_control;
3553 }
3554
3555 int
3556 Session::rename (const std::string& new_name)
3557 {
3558         string legal_name = legalize_for_path (new_name);
3559         string newpath;
3560         string oldstr;
3561         string newstr;
3562         bool first = true;
3563
3564         string const old_sources_root = _session_dir->sources_root();
3565
3566         /* Rename:
3567
3568          * session directory
3569          * interchange subdirectory
3570          * session file
3571          * session history
3572          
3573          * Backup files are left unchanged and not renamed.
3574          */
3575
3576         /* pass one: not 100% safe check that the new directory names don't
3577          * already exist ...
3578          */
3579
3580         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3581                 vector<string> v;
3582
3583                 oldstr = (*i).path;
3584
3585                 /* this is a stupid hack because Glib::path_get_dirname() is
3586                  * lexical-only, and so passing it /a/b/c/ gives a different
3587                  * result than passing it /a/b/c ...
3588                  */
3589
3590                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3591                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3592                 }
3593
3594                 string base = Glib::path_get_dirname (oldstr);
3595                 string p = Glib::path_get_basename (oldstr);
3596
3597                 newstr = Glib::build_filename (base, legal_name);
3598                 
3599                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3600                         return -1;
3601                 }
3602         }
3603
3604         /* Session dirs */
3605         
3606         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3607                 vector<string> v;
3608
3609                 oldstr = (*i).path;
3610
3611                 /* this is a stupid hack because Glib::path_get_dirname() is
3612                  * lexical-only, and so passing it /a/b/c/ gives a different
3613                  * result than passing it /a/b/c ...
3614                  */
3615
3616                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3617                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3618                 }
3619
3620                 string base = Glib::path_get_dirname (oldstr);
3621                 string p = Glib::path_get_basename (oldstr);
3622
3623                 newstr = Glib::build_filename (base, legal_name);
3624
3625                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3626
3627                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3628                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3629                         return 1;
3630                 }
3631
3632                 if (first) {
3633                         (*_session_dir) = newstr;
3634                         newpath = newstr;
3635                         first = 1;
3636                 }
3637
3638                 /* directory below interchange */
3639
3640                 v.push_back (newstr);
3641                 v.push_back (interchange_dir_name);
3642                 v.push_back (p);
3643
3644                 oldstr = Glib::build_filename (v);
3645
3646                 v.clear ();
3647                 v.push_back (newstr);
3648                 v.push_back (interchange_dir_name);
3649                 v.push_back (legal_name);
3650
3651                 newstr = Glib::build_filename (v);
3652                 
3653                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3654                 
3655                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3656                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3657                         return 1;
3658                 }
3659         }
3660
3661         /* state file */
3662         
3663         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3664         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3665         
3666         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3667
3668         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3669                 error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3670                 return 1;
3671         }
3672
3673         /* history file */
3674
3675         
3676         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3677
3678         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3679                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3680                 
3681                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3682                 
3683                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3684                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3685                         return 1;
3686                 }
3687         }
3688
3689         /* update file source paths */
3690         
3691         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3692                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3693                 if (fs) {
3694                         string p = fs->path ();
3695                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3696                         fs->set_path (p);
3697                 }
3698         }
3699
3700         /* remove old name from recent sessions */
3701
3702         remove_recent_sessions (_path);
3703
3704         _path = newpath;
3705         _current_snapshot_name = new_name;
3706         _name = new_name;
3707
3708         /* re-add directory separator - reverse hack to oldstr above */
3709         if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
3710                 _path += G_DIR_SEPARATOR;
3711         }
3712
3713         set_dirty ();
3714
3715         /* save state again to get everything just right */
3716
3717         save_state (_current_snapshot_name);
3718
3719
3720         /* add to recent sessions */
3721
3722         store_recent_sessions (new_name, _path);
3723
3724         return 0;
3725 }
3726
3727 int
3728 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3729 {
3730         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3731                 return -1;
3732         }
3733
3734         if (!tree.read (xmlpath)) {
3735                 return -1;
3736         }
3737
3738         return 0;
3739 }
3740
3741 int
3742 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3743 {
3744         XMLTree tree;
3745         bool found_sr = false;
3746         bool found_data_format = false;
3747
3748         if (get_session_info_from_path (tree, xmlpath)) {
3749                 return -1;
3750         }
3751
3752         /* sample rate */
3753
3754         const XMLProperty* prop;
3755         if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
3756                 sample_rate = atoi (prop->value());
3757                 found_sr = true;
3758         }
3759
3760         const XMLNodeList& children (tree.root()->children());
3761         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3762                 const XMLNode* child = *c;
3763                 if (child->name() == "Config") {
3764                         const XMLNodeList& options (child->children());
3765                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3766                                 const XMLNode* option = *oc;
3767                                 const XMLProperty* name = option->property("name");
3768
3769                                 if (!name) {
3770                                         continue;
3771                                 }
3772
3773                                 if (name->value() == "native-file-data-format") {
3774                                         const XMLProperty* value = option->property ("value");
3775                                         if (value) {
3776                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3777                                                 data_format = fmt;
3778                                                 found_data_format = true;
3779                                                 break;
3780                                         }
3781                                 }
3782                         }
3783                 }
3784                 if (found_data_format) {
3785                         break;
3786                 }
3787         }
3788
3789         return !(found_sr && found_data_format); // zero if they are both found
3790 }
3791
3792 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
3793 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
3794
3795 int
3796 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
3797 {
3798         uint32_t total = 0;
3799         uint32_t n = 0;
3800         SourcePathMap source_path_map;
3801         string new_path;
3802         boost::shared_ptr<AudioFileSource> afs;
3803         int ret = 0;
3804
3805         {
3806
3807                 Glib::Threads::Mutex::Lock lm (source_lock);
3808                 
3809                 cerr << " total sources = " << sources.size();
3810                 
3811                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3812                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3813                         
3814                         if (!fs) {
3815                                 continue;
3816                         }
3817                         
3818                         if (fs->within_session()) {
3819                                 cerr << "skip " << fs->name() << endl;
3820                                 continue;
3821                         }
3822                         
3823                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
3824                                 source_path_map[fs->path()].push_back (fs);
3825                         } else {
3826                                 SeveralFileSources v;
3827                                 v.push_back (fs);
3828                                 source_path_map.insert (make_pair (fs->path(), v));
3829                         }
3830                         
3831                         total++;
3832                 }
3833                 
3834                 cerr << " fsources = " << total << endl;
3835                 
3836                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
3837                         
3838                         /* tell caller where we are */
3839                         
3840                         string old_path = i->first;
3841                         
3842                         callback (n, total, old_path);
3843                         
3844                         cerr << old_path << endl;
3845                         
3846                         new_path.clear ();
3847                         
3848                         switch (i->second.front()->type()) {
3849                         case DataType::AUDIO:
3850                                 new_path = new_audio_source_path_for_embedded (old_path);
3851                                 break;
3852                                 
3853                         case DataType::MIDI:
3854                                 break;
3855                         }
3856                         
3857                         cerr << "Move " << old_path << " => " << new_path << endl;
3858                         
3859                         if (!copy_file (old_path, new_path)) {
3860                                 cerr << "failed !\n";
3861                                 ret = -1;
3862                         }
3863                         
3864                         /* make sure we stop looking in the external
3865                            dir/folder. Remember, this is an all-or-nothing
3866                            operations, it doesn't merge just some files.
3867                         */
3868                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
3869
3870                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
3871                                 (*f)->set_path (new_path);
3872                         }
3873                 }
3874         }
3875
3876         save_state ("", false, false);
3877
3878         return ret;
3879 }