delete session XML object after loading and setting 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         } catch (AudioEngine::PortRegistrationFailure& err) {
322                 /* handle this one in a different way than all others, so that its clear what happened */
323                 error << err.what() << endmsg;
324                 return -1;
325         } catch (...) {
326                 return -1;
327         }
328
329         BootMessage (_("Reset Remote Controls"));
330
331         // send_full_time_code (0);
332         _engine.transport_locate (0);
333
334         _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
335         _mmc->send (MIDI::MachineControlCommand (Timecode::Time ()));
336
337         MIDI::Name::MidiPatchManager::instance().set_session (this);
338
339         ltc_tx_initialize();
340         /* initial program change will be delivered later; see ::config_changed() */
341
342         _state_of_the_state = Clean;
343
344         Port::set_connecting_blocked (false);
345
346         DirtyChanged (); /* EMIT SIGNAL */
347
348         if (_is_new) {
349                 save_state ("");
350         } else if (state_was_pending) {
351                 save_state ("");
352                 remove_pending_capture_state ();
353                 state_was_pending = false;
354         }
355
356         return 0;
357 }
358
359 string
360 Session::raid_path () const
361 {
362         Searchpath raid_search_path;
363
364         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
365                 raid_search_path += (*i).path;
366         }
367
368         return raid_search_path.to_string ();
369 }
370
371 void
372 Session::setup_raid_path (string path)
373 {
374         if (path.empty()) {
375                 return;
376         }
377
378         space_and_path sp;
379         string fspath;
380
381         session_dirs.clear ();
382
383         Searchpath search_path(path);
384         Searchpath sound_search_path;
385         Searchpath midi_search_path;
386
387         for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
388                 sp.path = *i;
389                 sp.blocks = 0; // not needed
390                 session_dirs.push_back (sp);
391
392                 SessionDirectory sdir(sp.path);
393
394                 sound_search_path += sdir.sound_path ();
395                 midi_search_path += sdir.midi_path ();
396         }
397
398         // reset the round-robin soundfile path thingie
399         last_rr_session_dir = session_dirs.begin();
400 }
401
402 bool
403 Session::path_is_within_session (const std::string& path)
404 {
405         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
406                 if (PBD::path_is_within (i->path, path)) {
407                         return true;
408                 }
409         }
410         return false;
411 }
412
413 int
414 Session::ensure_subdirs ()
415 {
416         string dir;
417
418         dir = session_directory().peak_path();
419
420         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
421                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
422                 return -1;
423         }
424
425         dir = session_directory().sound_path();
426
427         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
428                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
429                 return -1;
430         }
431
432         dir = session_directory().midi_path();
433
434         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
435                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
436                 return -1;
437         }
438
439         dir = session_directory().dead_path();
440
441         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
442                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
443                 return -1;
444         }
445
446         dir = session_directory().export_path();
447
448         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
449                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
450                 return -1;
451         }
452
453         dir = analysis_dir ();
454
455         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457                 return -1;
458         }
459
460         dir = plugins_dir ();
461
462         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463                 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464                 return -1;
465         }
466
467         dir = externals_dir ();
468
469         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470                 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471                 return -1;
472         }
473
474         return 0;
475 }
476
477 /** @param session_template directory containing session template, or empty.
478  *  Caller must not hold process lock.
479  */
480 int
481 Session::create (const string& session_template, BusProfile* bus_profile)
482 {
483         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
484                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
485                 return -1;
486         }
487
488         if (ensure_subdirs ()) {
489                 return -1;
490         }
491
492         _writable = exists_and_writable (_path);
493
494         if (!session_template.empty()) {
495                 std::string in_path = session_template_dir_to_file (session_template);
496
497                 ifstream in(in_path.c_str());
498
499                 if (in) {
500                         /* no need to call legalize_for_path() since the string
501                          * in session_template is already a legal path name
502                          */
503                         string out_path = Glib::build_filename (_session_dir->root_path(), _name + statefile_suffix);
504
505                         ofstream out(out_path.c_str());
506
507                         if (out) {
508                                 out << in.rdbuf();
509                                 _is_new = false;
510
511                                 /* Copy plugin state files from template to new session */
512                                 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
513                                 copy_files (template_plugins, plugins_dir ());
514                                 
515                                 return 0;
516
517                         } else {
518                                 error << string_compose (_("Could not open %1 for writing session template"), out_path)
519                                         << endmsg;
520                                 return -1;
521                         }
522
523                 } else {
524                         error << string_compose (_("Could not open session template %1 for reading"), in_path)
525                                 << endmsg;
526                         return -1;
527                 }
528
529         }
530
531         /* set initial start + end point */
532
533         _state_of_the_state = Clean;
534
535         /* set up Master Out and Control Out if necessary */
536
537         if (bus_profile) {
538
539                 RouteList rl;
540                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
541
542                 if (bus_profile->master_out_channels) {
543                         boost::shared_ptr<Route> r (new Route (*this, _("Master"), Route::MasterOut, DataType::AUDIO));
544                         if (r->init ()) {
545                                 return -1;
546                         }
547 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
548                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
549 #endif
550                         {
551                                 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
552                                 r->input()->ensure_io (count, false, this);
553                                 r->output()->ensure_io (count, false, this);
554                         }
555
556                         rl.push_back (r);
557
558                 } else {
559                         /* prohibit auto-connect to master, because there isn't one */
560                         bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
561                 }
562
563                 if (!rl.empty()) {
564                         add_routes (rl, false, false, false);
565                 }
566
567                 /* this allows the user to override settings with an environment variable.
568                  */
569
570                 if (no_auto_connect()) {
571                         bus_profile->input_ac = AutoConnectOption (0);
572                         bus_profile->output_ac = AutoConnectOption (0);
573                 }
574
575                 Config->set_input_auto_connect (bus_profile->input_ac);
576                 Config->set_output_auto_connect (bus_profile->output_ac);
577         }
578
579         if (Config->get_use_monitor_bus() && bus_profile) {
580                 add_monitor_section ();
581         }
582
583         return 0;
584 }
585
586 void
587 Session::maybe_write_autosave()
588 {
589         if (dirty() && record_status() != Recording) {
590                 save_state("", true);
591         }
592 }
593
594 void
595 Session::remove_pending_capture_state ()
596 {
597         std::string pending_state_file_path(_session_dir->root_path());
598
599         pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
600
601         if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
602
603         if (g_remove (pending_state_file_path.c_str()) != 0) {
604                 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
605                                 pending_state_file_path, g_strerror (errno)) << endmsg;
606         }
607 }
608
609 /** Rename a state file.
610  *  @param old_name Old snapshot name.
611  *  @param new_name New snapshot name.
612  */
613 void
614 Session::rename_state (string old_name, string new_name)
615 {
616         if (old_name == _current_snapshot_name || old_name == _name) {
617                 /* refuse to rename the current snapshot or the "main" one */
618                 return;
619         }
620
621         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
622         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
623
624         const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
625         const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
626
627         if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
628                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
629                                 old_name, new_name, g_strerror(errno)) << endmsg;
630         }
631 }
632
633 /** Remove a state file.
634  *  @param snapshot_name Snapshot name.
635  */
636 void
637 Session::remove_state (string snapshot_name)
638 {
639         if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
640                 // refuse to remove the current snapshot or the "main" one
641                 return;
642         }
643
644         std::string xml_path(_session_dir->root_path());
645
646         xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
647
648         if (!create_backup_file (xml_path)) {
649                 // don't remove it if a backup can't be made
650                 // create_backup_file will log the error.
651                 return;
652         }
653
654         // and delete it
655         if (g_remove (xml_path.c_str()) != 0) {
656                 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
657                                 xml_path, g_strerror (errno)) << endmsg;
658         }
659 }
660
661 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
662 int
663 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
664 {
665         XMLTree tree;
666         std::string xml_path(_session_dir->root_path());
667
668         /* prevent concurrent saves from different threads */
669
670         Glib::Threads::Mutex::Lock lm (save_state_lock);
671
672         if (!_writable || (_state_of_the_state & CannotSave)) {
673                 return 1;
674         }
675
676         if (g_atomic_int_get(&_suspend_save)) {
677                 _save_queued = true;
678                 return 1;
679         }
680         _save_queued = false;
681
682         if (!_engine.connected ()) {
683                 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
684                                          PROGRAM_NAME)
685                       << endmsg;
686                 return 1;
687         }
688
689         /* tell sources we're saving first, in case they write out to a new file
690          * which should be saved with the state rather than the old one */
691         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
692                 try {
693                         i->second->session_saved();
694                 } catch (Evoral::SMF::FileError& e) {
695                         error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
696                 }
697         }
698
699         SaveSession (); /* EMIT SIGNAL */
700
701         tree.set_root (&get_state());
702
703         if (snapshot_name.empty()) {
704                 snapshot_name = _current_snapshot_name;
705         } else if (switch_to_snapshot) {
706                 _current_snapshot_name = snapshot_name;
707         }
708
709         if (!pending) {
710
711                 /* proper save: use statefile_suffix (.ardour in English) */
712
713                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
714
715                 /* make a backup copy of the old file */
716
717                 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
718                         // create_backup_file will log the error
719                         return -1;
720                 }
721
722         } else {
723
724                 /* pending save: use pending_suffix (.pending in English) */
725                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
726         }
727
728         std::string tmp_path(_session_dir->root_path());
729         tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
730
731         // cerr << "actually writing state to " << xml_path << endl;
732
733         if (!tree.write (tmp_path)) {
734                 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
735                 if (g_remove (tmp_path.c_str()) != 0) {
736                         error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
737                                         tmp_path, g_strerror (errno)) << endmsg;
738                 }
739                 return -1;
740
741         } else {
742
743                 if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
744                         error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"),
745                                         tmp_path, xml_path, g_strerror(errno)) << endmsg;
746                         if (g_remove (tmp_path.c_str()) != 0) {
747                                 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
748                                                 tmp_path, g_strerror (errno)) << endmsg;
749                         }
750                         return -1;
751                 }
752         }
753
754         if (!pending) {
755
756                 save_history (snapshot_name);
757
758                 bool was_dirty = dirty();
759
760                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
761
762                 if (was_dirty) {
763                         DirtyChanged (); /* EMIT SIGNAL */
764                 }
765
766                 StateSaved (snapshot_name); /* EMIT SIGNAL */
767         }
768
769         return 0;
770 }
771
772 int
773 Session::restore_state (string snapshot_name)
774 {
775         if (load_state (snapshot_name) == 0) {
776                 set_state (*state_tree->root(), Stateful::loading_state_version);
777         }
778
779         return 0;
780 }
781
782 int
783 Session::load_state (string snapshot_name)
784 {
785         delete state_tree;
786         state_tree = 0;
787
788         state_was_pending = false;
789
790         /* check for leftover pending state from a crashed capture attempt */
791
792         std::string xmlpath(_session_dir->root_path());
793         xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
794
795         if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
796
797                 /* there is pending state from a crashed capture attempt */
798
799                 boost::optional<int> r = AskAboutPendingState();
800                 if (r.get_value_or (1)) {
801                         state_was_pending = true;
802                 }
803         }
804
805         if (!state_was_pending) {
806                 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
807         }
808
809         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
810                 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
811                 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
812                         error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
813                         return 1;
814                 }
815         }
816
817         state_tree = new XMLTree;
818
819         set_dirty();
820
821         _writable = exists_and_writable (xmlpath) && exists_and_writable(Glib::path_get_dirname(xmlpath));
822
823         if (!state_tree->read (xmlpath)) {
824                 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
825                 delete state_tree;
826                 state_tree = 0;
827                 return -1;
828         }
829
830         XMLNode& root (*state_tree->root());
831
832         if (root.name() != X_("Session")) {
833                 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
834                 delete state_tree;
835                 state_tree = 0;
836                 return -1;
837         }
838
839         const XMLProperty* prop;
840
841         if ((prop = root.property ("version")) == 0) {
842                 /* no version implies very old version of Ardour */
843                 Stateful::loading_state_version = 1000;
844         } else {
845                 if (prop->value().find ('.') != string::npos) {
846                         /* old school version format */
847                         if (prop->value()[0] == '2') {
848                                 Stateful::loading_state_version = 2000;
849                         } else {
850                                 Stateful::loading_state_version = 3000;
851                         }
852                 } else {
853                         Stateful::loading_state_version = atoi (prop->value());
854                 }
855         }
856
857         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
858
859                 std::string backup_path(_session_dir->root_path());
860                 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
861                 backup_path = Glib::build_filename (backup_path, backup_filename);
862
863                 // only create a backup for a given statefile version once
864
865                 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
866                         
867                         VersionMismatch (xmlpath, backup_path);
868                         
869                         if (!copy_file (xmlpath, backup_path)) {;
870                                 return -1;
871                         }
872                 }
873         }
874
875         return 0;
876 }
877
878 int
879 Session::load_options (const XMLNode& node)
880 {
881         LocaleGuard lg (X_("POSIX"));
882         config.set_variables (node);
883         return 0;
884 }
885
886 bool
887 Session::save_default_options ()
888 {
889         return config.save_state();
890 }
891
892 XMLNode&
893 Session::get_state()
894 {
895         return state(true);
896 }
897
898 XMLNode&
899 Session::get_template()
900 {
901         /* if we don't disable rec-enable, diskstreams
902            will believe they need to store their capture
903            sources in their state node.
904         */
905
906         disable_record (false);
907
908         return state(false);
909 }
910
911 XMLNode&
912 Session::state (bool full_state)
913 {
914         XMLNode* node = new XMLNode("Session");
915         XMLNode* child;
916
917         char buf[16];
918         snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
919         node->add_property("version", buf);
920
921         /* store configuration settings */
922
923         if (full_state) {
924
925                 node->add_property ("name", _name);
926                 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
927                 node->add_property ("sample-rate", buf);
928
929                 if (session_dirs.size() > 1) {
930
931                         string p;
932
933                         vector<space_and_path>::iterator i = session_dirs.begin();
934                         vector<space_and_path>::iterator next;
935
936                         ++i; /* skip the first one */
937                         next = i;
938                         ++next;
939
940                         while (i != session_dirs.end()) {
941
942                                 p += (*i).path;
943
944                                 if (next != session_dirs.end()) {
945                                         p += G_SEARCHPATH_SEPARATOR;
946                                 } else {
947                                         break;
948                                 }
949
950                                 ++next;
951                                 ++i;
952                         }
953
954                         child = node->add_child ("Path");
955                         child->add_content (p);
956                 }
957         }
958
959         /* save the ID counter */
960
961         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
962         node->add_property ("id-counter", buf);
963
964         /* save the event ID counter */
965
966         snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
967         node->add_property ("event-counter", buf);
968
969         /* various options */
970
971         list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
972         if (!midi_port_nodes.empty()) {
973                 XMLNode* midi_port_stuff = new XMLNode ("MIDIPorts");
974                 for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
975                         midi_port_stuff->add_child_nocopy (**n);
976                 }
977                 node->add_child_nocopy (*midi_port_stuff);
978         }
979
980         node->add_child_nocopy (config.get_variables ());
981
982         node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
983
984         child = node->add_child ("Sources");
985
986         if (full_state) {
987                 Glib::Threads::Mutex::Lock sl (source_lock);
988
989                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
990
991                         /* Don't save information about non-file Sources, or
992                          * about non-destructive file sources that are empty
993                          * and unused by any regions.
994                         */
995
996                         boost::shared_ptr<FileSource> fs;
997
998                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
999
1000                                 if (!fs->destructive()) {
1001                                         if (fs->empty() && !fs->used()) {
1002                                                 continue;
1003                                         }
1004                                 }
1005
1006                                 child->add_child_nocopy (siter->second->get_state());
1007                         }
1008                 }
1009         }
1010
1011         child = node->add_child ("Regions");
1012
1013         if (full_state) {
1014                 Glib::Threads::Mutex::Lock rl (region_lock);
1015                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1016                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1017                         boost::shared_ptr<Region> r = i->second;
1018                         /* only store regions not attached to playlists */
1019                         if (r->playlist() == 0) {
1020                                 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1021                                         child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1022                                 } else {
1023                                         child->add_child_nocopy (r->get_state ());
1024                                 }
1025                         }
1026                 }
1027
1028                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1029
1030                 if (!cassocs.empty()) {
1031                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1032
1033                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1034                                 char buf[64];
1035                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1036                                 i->first->id().print (buf, sizeof (buf));
1037                                 can->add_property (X_("copy"), buf);
1038                                 i->second->id().print (buf, sizeof (buf));
1039                                 can->add_property (X_("original"), buf);
1040                                 ca->add_child_nocopy (*can);
1041                         }
1042                 }
1043         }
1044
1045         if (full_state) {
1046                 node->add_child_nocopy (_locations->get_state());
1047         } else {
1048                 // for a template, just create a new Locations, populate it
1049                 // with the default start and end, and get the state for that.
1050                 Locations loc (*this);
1051                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1052                 range->set (max_framepos, 0);
1053                 loc.add (range);
1054                 node->add_child_nocopy (loc.get_state());
1055         }
1056
1057         child = node->add_child ("Bundles");
1058         {
1059                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1060                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1061                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1062                         if (b) {
1063                                 child->add_child_nocopy (b->get_state());
1064                         }
1065                 }
1066         }
1067
1068         child = node->add_child ("Routes");
1069         {
1070                 boost::shared_ptr<RouteList> r = routes.reader ();
1071
1072                 RoutePublicOrderSorter cmp;
1073                 RouteList public_order (*r);
1074                 public_order.sort (cmp);
1075
1076                 /* the sort should have put control outs first */
1077
1078                 if (_monitor_out) {
1079                         assert (_monitor_out == public_order.front());
1080                 }
1081
1082                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1083                         if (!(*i)->is_auditioner()) {
1084                                 if (full_state) {
1085                                         child->add_child_nocopy ((*i)->get_state());
1086                                 } else {
1087                                         child->add_child_nocopy ((*i)->get_template());
1088                                 }
1089                         }
1090                 }
1091         }
1092
1093         playlists->add_state (node, full_state);
1094
1095         child = node->add_child ("RouteGroups");
1096         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1097                 child->add_child_nocopy ((*i)->get_state());
1098         }
1099
1100         if (_click_io) {
1101                 XMLNode* gain_child = node->add_child ("Click");
1102                 gain_child->add_child_nocopy (_click_io->state (full_state));
1103                 gain_child->add_child_nocopy (_click_gain->state (full_state));
1104         }
1105
1106         if (_ltc_input) {
1107                 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1108                 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1109         }
1110
1111         if (_ltc_input) {
1112                 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1113                 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1114         }
1115
1116         node->add_child_nocopy (_speakers->get_state());
1117         node->add_child_nocopy (_tempo_map->get_state());
1118         node->add_child_nocopy (get_control_protocol_state());
1119
1120         if (_extra_xml) {
1121                 node->add_child_copy (*_extra_xml);
1122         }
1123
1124         return *node;
1125 }
1126
1127 XMLNode&
1128 Session::get_control_protocol_state ()
1129 {
1130         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1131         return cpm.get_state();
1132 }
1133
1134 int
1135 Session::set_state (const XMLNode& node, int version)
1136 {
1137         XMLNodeList nlist;
1138         XMLNode* child;
1139         const XMLProperty* prop;
1140         int ret = -1;
1141
1142         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1143
1144         if (node.name() != X_("Session")) {
1145                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1146                 goto out;
1147         }
1148
1149         if ((prop = node.property ("name")) != 0) {
1150                 _name = prop->value ();
1151         }
1152
1153         if ((prop = node.property (X_("sample-rate"))) != 0) {
1154
1155                 _nominal_frame_rate = atoi (prop->value());
1156
1157                 if (_nominal_frame_rate != _current_frame_rate) {
1158                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1159                         if (r.get_value_or (0)) {
1160                                 goto out;
1161                         }
1162                 }
1163         }
1164
1165         setup_raid_path(_session_dir->root_path());
1166
1167         if ((prop = node.property (X_("id-counter"))) != 0) {
1168                 uint64_t x;
1169                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1170                 ID::init_counter (x);
1171         } else {
1172                 /* old sessions used a timebased counter, so fake
1173                    the startup ID counter based on a standard
1174                    timestamp.
1175                 */
1176                 time_t now;
1177                 time (&now);
1178                 ID::init_counter (now);
1179         }
1180
1181         if ((prop = node.property (X_("event-counter"))) != 0) {
1182                 Evoral::init_event_id_counter (atoi (prop->value()));
1183         }
1184
1185
1186         if ((child = find_named_node (node, "MIDIPorts")) != 0) {
1187                 _midi_ports->set_midi_port_states (child->children());
1188         }
1189
1190         IO::disable_connecting ();
1191
1192         Stateful::save_extra_xml (node);
1193
1194         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1195                 load_options (*child);
1196         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1197                 load_options (*child);
1198         } else {
1199                 error << _("Session: XML state has no options section") << endmsg;
1200         }
1201
1202         if (version >= 3000) {
1203                 if ((child = find_named_node (node, "Metadata")) == 0) {
1204                         warning << _("Session: XML state has no metadata section") << endmsg;
1205                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1206                         goto out;
1207                 }
1208         }
1209
1210         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1211                 _speakers->set_state (*child, version);
1212         }
1213
1214         if ((child = find_named_node (node, "Sources")) == 0) {
1215                 error << _("Session: XML state has no sources section") << endmsg;
1216                 goto out;
1217         } else if (load_sources (*child)) {
1218                 goto out;
1219         }
1220
1221         if ((child = find_named_node (node, "TempoMap")) == 0) {
1222                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1223                 goto out;
1224         } else if (_tempo_map->set_state (*child, version)) {
1225                 goto out;
1226         }
1227
1228         if ((child = find_named_node (node, "Locations")) == 0) {
1229                 error << _("Session: XML state has no locations section") << endmsg;
1230                 goto out;
1231         } else if (_locations->set_state (*child, version)) {
1232                 goto out;
1233         }
1234
1235         Location* location;
1236
1237         if ((location = _locations->auto_loop_location()) != 0) {
1238                 set_auto_loop_location (location);
1239         }
1240
1241         if ((location = _locations->auto_punch_location()) != 0) {
1242                 set_auto_punch_location (location);
1243         }
1244
1245         if ((location = _locations->session_range_location()) != 0) {
1246                 delete _session_range_location;
1247                 _session_range_location = location;
1248         }
1249
1250         if (_session_range_location) {
1251                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1252         }
1253
1254         if ((child = find_named_node (node, "Regions")) == 0) {
1255                 error << _("Session: XML state has no Regions section") << endmsg;
1256                 goto out;
1257         } else if (load_regions (*child)) {
1258                 goto out;
1259         }
1260
1261         if ((child = find_named_node (node, "Playlists")) == 0) {
1262                 error << _("Session: XML state has no playlists section") << endmsg;
1263                 goto out;
1264         } else if (playlists->load (*this, *child)) {
1265                 goto out;
1266         }
1267
1268         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1269                 // this is OK
1270         } else if (playlists->load_unused (*this, *child)) {
1271                 goto out;
1272         }
1273
1274         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1275                 if (load_compounds (*child)) {
1276                         goto out;
1277                 }
1278         }
1279
1280         if (version >= 3000) {
1281                 if ((child = find_named_node (node, "Bundles")) == 0) {
1282                         warning << _("Session: XML state has no bundles section") << endmsg;
1283                         //goto out;
1284                 } else {
1285                         /* We can't load Bundles yet as they need to be able
1286                            to convert from port names to Port objects, which can't happen until
1287                            later */
1288                         _bundle_xml_node = new XMLNode (*child);
1289                 }
1290         }
1291
1292         if (version < 3000) {
1293                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1294                         error << _("Session: XML state has no diskstreams section") << endmsg;
1295                         goto out;
1296                 } else if (load_diskstreams_2X (*child, version)) {
1297                         goto out;
1298                 }
1299         }
1300
1301         if ((child = find_named_node (node, "Routes")) == 0) {
1302                 error << _("Session: XML state has no routes section") << endmsg;
1303                 goto out;
1304         } else if (load_routes (*child, version)) {
1305                 goto out;
1306         }
1307
1308         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1309         _diskstreams_2X.clear ();
1310
1311         if (version >= 3000) {
1312
1313                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1314                         error << _("Session: XML state has no route groups section") << endmsg;
1315                         goto out;
1316                 } else if (load_route_groups (*child, version)) {
1317                         goto out;
1318                 }
1319
1320         } else if (version < 3000) {
1321
1322                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1323                         error << _("Session: XML state has no edit groups section") << endmsg;
1324                         goto out;
1325                 } else if (load_route_groups (*child, version)) {
1326                         goto out;
1327                 }
1328
1329                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1330                         error << _("Session: XML state has no mix groups section") << endmsg;
1331                         goto out;
1332                 } else if (load_route_groups (*child, version)) {
1333                         goto out;
1334                 }
1335         }
1336
1337         if ((child = find_named_node (node, "Click")) == 0) {
1338                 warning << _("Session: XML state has no click section") << endmsg;
1339         } else if (_click_io) {
1340                 setup_click_state (&node);
1341         }
1342
1343         if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1344                 ControlProtocolManager::instance().set_state (*child, version);
1345         }
1346
1347         update_have_rec_enabled_track ();
1348
1349         /* here beginneth the second phase ... */
1350
1351         StateReady (); /* EMIT SIGNAL */
1352
1353         delete state_tree;
1354         state_tree = 0;
1355         return 0;
1356
1357   out:
1358         delete state_tree;
1359         state_tree = 0;
1360         return ret;
1361 }
1362
1363 int
1364 Session::load_routes (const XMLNode& node, int version)
1365 {
1366         XMLNodeList nlist;
1367         XMLNodeConstIterator niter;
1368         RouteList new_routes;
1369
1370         nlist = node.children();
1371
1372         set_dirty();
1373
1374         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1375
1376                 boost::shared_ptr<Route> route;
1377                 if (version < 3000) {
1378                         route = XMLRouteFactory_2X (**niter, version);
1379                 } else {
1380                         route = XMLRouteFactory (**niter, version);
1381                 }
1382
1383                 if (route == 0) {
1384                         error << _("Session: cannot create Route from XML description.") << endmsg;
1385                         return -1;
1386                 }
1387
1388                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1389
1390                 new_routes.push_back (route);
1391         }
1392
1393         add_routes (new_routes, false, false, false);
1394
1395         return 0;
1396 }
1397
1398 boost::shared_ptr<Route>
1399 Session::XMLRouteFactory (const XMLNode& node, int version)
1400 {
1401         boost::shared_ptr<Route> ret;
1402
1403         if (node.name() != "Route") {
1404                 return ret;
1405         }
1406
1407         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1408
1409         DataType type = DataType::AUDIO;
1410         const XMLProperty* prop = node.property("default-type");
1411
1412         if (prop) {
1413                 type = DataType (prop->value());
1414         }
1415
1416         assert (type != DataType::NIL);
1417
1418         if (ds_child) {
1419
1420                 boost::shared_ptr<Track> track;
1421
1422                 if (type == DataType::AUDIO) {
1423                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1424                 } else {
1425                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1426                 }
1427
1428                 if (track->init()) {
1429                         return ret;
1430                 }
1431
1432                 if (track->set_state (node, version)) {
1433                         return ret;
1434                 }
1435
1436 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1437                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1438 #endif
1439                 ret = track;
1440
1441         } else {
1442                 enum Route::Flag flags = Route::Flag(0);
1443                 const XMLProperty* prop = node.property("flags");
1444                 if (prop) {
1445                         flags = Route::Flag (string_2_enum (prop->value(), flags));
1446                 }
1447
1448                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1449
1450                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1451 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1452                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1453 #endif
1454                         ret = r;
1455                 }
1456         }
1457
1458         return ret;
1459 }
1460
1461 boost::shared_ptr<Route>
1462 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1463 {
1464         boost::shared_ptr<Route> ret;
1465
1466         if (node.name() != "Route") {
1467                 return ret;
1468         }
1469
1470         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1471         if (!ds_prop) {
1472                 ds_prop = node.property (X_("diskstream"));
1473         }
1474
1475         DataType type = DataType::AUDIO;
1476         const XMLProperty* prop = node.property("default-type");
1477
1478         if (prop) {
1479                 type = DataType (prop->value());
1480         }
1481
1482         assert (type != DataType::NIL);
1483
1484         if (ds_prop) {
1485
1486                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1487                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1488                         ++i;
1489                 }
1490
1491                 if (i == _diskstreams_2X.end()) {
1492                         error << _("Could not find diskstream for route") << endmsg;
1493                         return boost::shared_ptr<Route> ();
1494                 }
1495
1496                 boost::shared_ptr<Track> track;
1497
1498                 if (type == DataType::AUDIO) {
1499                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1500                 } else {
1501                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1502                 }
1503
1504                 if (track->init()) {
1505                         return ret;
1506                 }
1507
1508                 if (track->set_state (node, version)) {
1509                         return ret;
1510                 }
1511
1512                 track->set_diskstream (*i);
1513
1514 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1515                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1516 #endif
1517                 ret = track;
1518
1519         } else {
1520                 enum Route::Flag flags = Route::Flag(0);
1521                 const XMLProperty* prop = node.property("flags");
1522                 if (prop) {
1523                         flags = Route::Flag (string_2_enum (prop->value(), flags));
1524                 }
1525
1526                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1527
1528                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1529 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1530                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1531 #endif
1532                         ret = r;
1533                 }
1534         }
1535
1536         return ret;
1537 }
1538
1539 int
1540 Session::load_regions (const XMLNode& node)
1541 {
1542         XMLNodeList nlist;
1543         XMLNodeConstIterator niter;
1544         boost::shared_ptr<Region> region;
1545
1546         nlist = node.children();
1547
1548         set_dirty();
1549
1550         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1551                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1552                         error << _("Session: cannot create Region from XML description.");
1553                         const XMLProperty *name = (**niter).property("name");
1554
1555                         if (name) {
1556                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1557                         }
1558
1559                         error << endmsg;
1560                 }
1561         }
1562
1563         return 0;
1564 }
1565
1566 int
1567 Session::load_compounds (const XMLNode& node)
1568 {
1569         XMLNodeList calist = node.children();
1570         XMLNodeConstIterator caiter;
1571         XMLProperty *caprop;
1572
1573         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1574                 XMLNode* ca = *caiter;
1575                 ID orig_id;
1576                 ID copy_id;
1577
1578                 if ((caprop = ca->property (X_("original"))) == 0) {
1579                         continue;
1580                 }
1581                 orig_id = caprop->value();
1582
1583                 if ((caprop = ca->property (X_("copy"))) == 0) {
1584                         continue;
1585                 }
1586                 copy_id = caprop->value();
1587
1588                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1589                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1590
1591                 if (!orig || !copy) {
1592                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1593                                                    orig_id, copy_id)
1594                                 << endmsg;
1595                         continue;
1596                 }
1597
1598                 RegionFactory::add_compound_association (orig, copy);
1599         }
1600
1601         return 0;
1602 }
1603
1604 void
1605 Session::load_nested_sources (const XMLNode& node)
1606 {
1607         XMLNodeList nlist;
1608         XMLNodeConstIterator niter;
1609
1610         nlist = node.children();
1611
1612         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1613                 if ((*niter)->name() == "Source") {
1614
1615                         /* it may already exist, so don't recreate it unnecessarily 
1616                          */
1617
1618                         XMLProperty* prop = (*niter)->property (X_("id"));
1619                         if (!prop) {
1620                                 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1621                                 continue;
1622                         }
1623
1624                         ID source_id (prop->value());
1625
1626                         if (!source_by_id (source_id)) {
1627
1628                                 try {
1629                                         SourceFactory::create (*this, **niter, true);
1630                                 }
1631                                 catch (failed_constructor& err) {
1632                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1633                                 }
1634                         }
1635                 }
1636         }
1637 }
1638
1639 boost::shared_ptr<Region>
1640 Session::XMLRegionFactory (const XMLNode& node, bool full)
1641 {
1642         const XMLProperty* type = node.property("type");
1643
1644         try {
1645
1646                 const XMLNodeList& nlist = node.children();
1647
1648                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1649                         XMLNode *child = (*niter);
1650                         if (child->name() == "NestedSource") {
1651                                 load_nested_sources (*child);
1652                         }
1653                 }
1654
1655                 if (!type || type->value() == "audio") {
1656                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1657                 } else if (type->value() == "midi") {
1658                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1659                 }
1660
1661         } catch (failed_constructor& err) {
1662                 return boost::shared_ptr<Region> ();
1663         }
1664
1665         return boost::shared_ptr<Region> ();
1666 }
1667
1668 boost::shared_ptr<AudioRegion>
1669 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1670 {
1671         const XMLProperty* prop;
1672         boost::shared_ptr<Source> source;
1673         boost::shared_ptr<AudioSource> as;
1674         SourceList sources;
1675         SourceList master_sources;
1676         uint32_t nchans = 1;
1677         char buf[128];
1678
1679         if (node.name() != X_("Region")) {
1680                 return boost::shared_ptr<AudioRegion>();
1681         }
1682
1683         if ((prop = node.property (X_("channels"))) != 0) {
1684                 nchans = atoi (prop->value().c_str());
1685         }
1686
1687         if ((prop = node.property ("name")) == 0) {
1688                 cerr << "no name for this region\n";
1689                 abort ();
1690         }
1691
1692         if ((prop = node.property (X_("source-0"))) == 0) {
1693                 if ((prop = node.property ("source")) == 0) {
1694                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1695                         return boost::shared_ptr<AudioRegion>();
1696                 }
1697         }
1698
1699         PBD::ID s_id (prop->value());
1700
1701         if ((source = source_by_id (s_id)) == 0) {
1702                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1703                 return boost::shared_ptr<AudioRegion>();
1704         }
1705
1706         as = boost::dynamic_pointer_cast<AudioSource>(source);
1707         if (!as) {
1708                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1709                 return boost::shared_ptr<AudioRegion>();
1710         }
1711
1712         sources.push_back (as);
1713
1714         /* pickup other channels */
1715
1716         for (uint32_t n=1; n < nchans; ++n) {
1717                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1718                 if ((prop = node.property (buf)) != 0) {
1719
1720                         PBD::ID id2 (prop->value());
1721
1722                         if ((source = source_by_id (id2)) == 0) {
1723                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1724                                 return boost::shared_ptr<AudioRegion>();
1725                         }
1726
1727                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1728                         if (!as) {
1729                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1730                                 return boost::shared_ptr<AudioRegion>();
1731                         }
1732                         sources.push_back (as);
1733                 }
1734         }
1735
1736         for (uint32_t n = 0; n < nchans; ++n) {
1737                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1738                 if ((prop = node.property (buf)) != 0) {
1739
1740                         PBD::ID id2 (prop->value());
1741
1742                         if ((source = source_by_id (id2)) == 0) {
1743                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1744                                 return boost::shared_ptr<AudioRegion>();
1745                         }
1746
1747                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1748                         if (!as) {
1749                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1750                                 return boost::shared_ptr<AudioRegion>();
1751                         }
1752                         master_sources.push_back (as);
1753                 }
1754         }
1755
1756         try {
1757                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1758
1759                 /* a final detail: this is the one and only place that we know how long missing files are */
1760
1761                 if (region->whole_file()) {
1762                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1763                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1764                                 if (sfp) {
1765                                         sfp->set_length (region->length());
1766                                 }
1767                         }
1768                 }
1769
1770                 if (!master_sources.empty()) {
1771                         if (master_sources.size() != nchans) {
1772                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1773                         } else {
1774                                 region->set_master_sources (master_sources);
1775                         }
1776                 }
1777
1778                 return region;
1779
1780         }
1781
1782         catch (failed_constructor& err) {
1783                 return boost::shared_ptr<AudioRegion>();
1784         }
1785 }
1786
1787 boost::shared_ptr<MidiRegion>
1788 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1789 {
1790         const XMLProperty* prop;
1791         boost::shared_ptr<Source> source;
1792         boost::shared_ptr<MidiSource> ms;
1793         SourceList sources;
1794
1795         if (node.name() != X_("Region")) {
1796                 return boost::shared_ptr<MidiRegion>();
1797         }
1798
1799         if ((prop = node.property ("name")) == 0) {
1800                 cerr << "no name for this region\n";
1801                 abort ();
1802         }
1803
1804         if ((prop = node.property (X_("source-0"))) == 0) {
1805                 if ((prop = node.property ("source")) == 0) {
1806                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1807                         return boost::shared_ptr<MidiRegion>();
1808                 }
1809         }
1810
1811         PBD::ID s_id (prop->value());
1812
1813         if ((source = source_by_id (s_id)) == 0) {
1814                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1815                 return boost::shared_ptr<MidiRegion>();
1816         }
1817
1818         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1819         if (!ms) {
1820                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1821                 return boost::shared_ptr<MidiRegion>();
1822         }
1823
1824         sources.push_back (ms);
1825
1826         try {
1827                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1828                 /* a final detail: this is the one and only place that we know how long missing files are */
1829
1830                 if (region->whole_file()) {
1831                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1832                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1833                                 if (sfp) {
1834                                         sfp->set_length (region->length());
1835                                 }
1836                         }
1837                 }
1838
1839                 return region;
1840         }
1841
1842         catch (failed_constructor& err) {
1843                 return boost::shared_ptr<MidiRegion>();
1844         }
1845 }
1846
1847 XMLNode&
1848 Session::get_sources_as_xml ()
1849
1850 {
1851         XMLNode* node = new XMLNode (X_("Sources"));
1852         Glib::Threads::Mutex::Lock lm (source_lock);
1853
1854         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1855                 node->add_child_nocopy (i->second->get_state());
1856         }
1857
1858         return *node;
1859 }
1860
1861 int
1862 Session::load_sources (const XMLNode& node)
1863 {
1864         XMLNodeList nlist;
1865         XMLNodeConstIterator niter;
1866         boost::shared_ptr<Source> source;
1867
1868         nlist = node.children();
1869
1870         set_dirty();
1871
1872         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1873           retry:
1874                 try {
1875                         if ((source = XMLSourceFactory (**niter)) == 0) {
1876                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1877                         }
1878
1879                 } catch (MissingSource& err) {
1880
1881                         int user_choice;
1882
1883                         if (!no_questions_about_missing_files) {
1884                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1885                         } else {
1886                                 user_choice = -2;
1887                         }
1888
1889                         switch (user_choice) {
1890                         case 0:
1891                                 /* user added a new search location, so try again */
1892                                 goto retry;
1893
1894
1895                         case 1:
1896                                 /* user asked to quit the entire session load
1897                                  */
1898                                 return -1;
1899
1900                         case 2:
1901                                 no_questions_about_missing_files = true;
1902                                 goto retry;
1903
1904                         case 3:
1905                                 no_questions_about_missing_files = true;
1906                                 /* fallthru */
1907
1908                         case -1:
1909                         default:
1910                                 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1911                                 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
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         bool was_dirty = dirty();
2886
2887         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2888
2889
2890         if (!was_dirty) {
2891                 DirtyChanged(); /* EMIT SIGNAL */
2892         }
2893 }
2894
2895
2896 void
2897 Session::set_clean ()
2898 {
2899         bool was_dirty = dirty();
2900
2901         _state_of_the_state = Clean;
2902
2903
2904         if (was_dirty) {
2905                 DirtyChanged(); /* EMIT SIGNAL */
2906         }
2907 }
2908
2909 void
2910 Session::set_deletion_in_progress ()
2911 {
2912         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2913 }
2914
2915 void
2916 Session::clear_deletion_in_progress ()
2917 {
2918         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2919 }
2920
2921 void
2922 Session::add_controllable (boost::shared_ptr<Controllable> c)
2923 {
2924         /* this adds a controllable to the list managed by the Session.
2925            this is a subset of those managed by the Controllable class
2926            itself, and represents the only ones whose state will be saved
2927            as part of the session.
2928         */
2929
2930         Glib::Threads::Mutex::Lock lm (controllables_lock);
2931         controllables.insert (c);
2932 }
2933
2934 struct null_deleter { void operator()(void const *) const {} };
2935
2936 void
2937 Session::remove_controllable (Controllable* c)
2938 {
2939         if (_state_of_the_state & Deletion) {
2940                 return;
2941         }
2942
2943         Glib::Threads::Mutex::Lock lm (controllables_lock);
2944
2945         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2946
2947         if (x != controllables.end()) {
2948                 controllables.erase (x);
2949         }
2950 }
2951
2952 boost::shared_ptr<Controllable>
2953 Session::controllable_by_id (const PBD::ID& id)
2954 {
2955         Glib::Threads::Mutex::Lock lm (controllables_lock);
2956
2957         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2958                 if ((*i)->id() == id) {
2959                         return *i;
2960                 }
2961         }
2962
2963         return boost::shared_ptr<Controllable>();
2964 }
2965
2966 boost::shared_ptr<Controllable>
2967 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2968 {
2969         boost::shared_ptr<Controllable> c;
2970         boost::shared_ptr<Route> r;
2971
2972         switch (desc.top_level_type()) {
2973         case ControllableDescriptor::NamedRoute:
2974         {
2975                 std::string str = desc.top_level_name();
2976                 if (str == "Master" || str == "master") {
2977                         r = _master_out;
2978                 } else if (str == "control" || str == "listen") {
2979                         r = _monitor_out;
2980                 } else {
2981                         r = route_by_name (desc.top_level_name());
2982                 }
2983                 break;
2984         }
2985
2986         case ControllableDescriptor::RemoteControlID:
2987                 r = route_by_remote_id (desc.rid());
2988                 break;
2989         }
2990
2991         if (!r) {
2992                 return c;
2993         }
2994
2995         switch (desc.subtype()) {
2996         case ControllableDescriptor::Gain:
2997                 c = r->gain_control ();
2998                 break;
2999
3000         case ControllableDescriptor::Solo:
3001                 c = r->solo_control();
3002                 break;
3003
3004         case ControllableDescriptor::Mute:
3005                 c = r->mute_control();
3006                 break;
3007
3008         case ControllableDescriptor::Recenable:
3009         {
3010                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3011
3012                 if (t) {
3013                         c = t->rec_enable_control ();
3014                 }
3015                 break;
3016         }
3017
3018         case ControllableDescriptor::PanDirection:
3019         {
3020                 c = r->pannable()->pan_azimuth_control;
3021                 break;
3022         }
3023
3024         case ControllableDescriptor::PanWidth:
3025         {
3026                 c = r->pannable()->pan_width_control;
3027                 break;
3028         }
3029
3030         case ControllableDescriptor::PanElevation:
3031         {
3032                 c = r->pannable()->pan_elevation_control;
3033                 break;
3034         }
3035
3036         case ControllableDescriptor::Balance:
3037                 /* XXX simple pan control */
3038                 break;
3039
3040         case ControllableDescriptor::PluginParameter:
3041         {
3042                 uint32_t plugin = desc.target (0);
3043                 uint32_t parameter_index = desc.target (1);
3044
3045                 /* revert to zero based counting */
3046
3047                 if (plugin > 0) {
3048                         --plugin;
3049                 }
3050
3051                 if (parameter_index > 0) {
3052                         --parameter_index;
3053                 }
3054
3055                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3056
3057                 if (p) {
3058                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3059                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3060                 }
3061                 break;
3062         }
3063
3064         case ControllableDescriptor::SendGain:
3065         {
3066                 uint32_t send = desc.target (0);
3067
3068                 /* revert to zero-based counting */
3069
3070                 if (send > 0) {
3071                         --send;
3072                 }
3073
3074                 boost::shared_ptr<Processor> p = r->nth_send (send);
3075
3076                 if (p) {
3077                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3078                         boost::shared_ptr<Amp> a = s->amp();
3079                         
3080                         if (a) {
3081                                 c = s->amp()->gain_control();
3082                         }
3083                 }
3084                 break;
3085         }
3086
3087         default:
3088                 /* relax and return a null pointer */
3089                 break;
3090         }
3091
3092         return c;
3093 }
3094
3095 void
3096 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3097 {
3098         if (_writable) {
3099                 Stateful::add_instant_xml (node, _path);
3100         }
3101
3102         if (write_to_config) {
3103                 Config->add_instant_xml (node);
3104         }
3105 }
3106
3107 XMLNode*
3108 Session::instant_xml (const string& node_name)
3109 {
3110         return Stateful::instant_xml (node_name, _path);
3111 }
3112
3113 int
3114 Session::save_history (string snapshot_name)
3115 {
3116         XMLTree tree;
3117
3118         if (!_writable) {
3119                 return 0;
3120         }
3121
3122         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 || 
3123             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3124                 return 0;
3125         }
3126
3127         if (snapshot_name.empty()) {
3128                 snapshot_name = _current_snapshot_name;
3129         }
3130
3131         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3132         const string backup_filename = history_filename + backup_suffix;
3133         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3134         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3135
3136         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3137                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3138                         error << _("could not backup old history file, current history not saved") << endmsg;
3139                         return -1;
3140                 }
3141         }
3142
3143         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3144
3145         if (!tree.write (xml_path))
3146         {
3147                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3148
3149                 if (g_remove (xml_path.c_str()) != 0) {
3150                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3151                                         xml_path, g_strerror (errno)) << endmsg;
3152                 }
3153                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3154                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3155                                         backup_path, g_strerror (errno)) << endmsg;
3156                 }
3157
3158                 return -1;
3159         }
3160
3161         return 0;
3162 }
3163
3164 int
3165 Session::restore_history (string snapshot_name)
3166 {
3167         XMLTree tree;
3168
3169         if (snapshot_name.empty()) {
3170                 snapshot_name = _current_snapshot_name;
3171         }
3172
3173         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3174         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3175
3176         info << "Loading history from " << xml_path << endmsg;
3177
3178         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3179                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3180                                 _name, xml_path) << endmsg;
3181                 return 1;
3182         }
3183
3184         if (!tree.read (xml_path)) {
3185                 error << string_compose (_("Could not understand session history file \"%1\""),
3186                                 xml_path) << endmsg;
3187                 return -1;
3188         }
3189
3190         // replace history
3191         _history.clear();
3192
3193         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3194
3195                 XMLNode *t = *it;
3196                 UndoTransaction* ut = new UndoTransaction ();
3197                 struct timeval tv;
3198
3199                 ut->set_name(t->property("name")->value());
3200                 stringstream ss(t->property("tv-sec")->value());
3201                 ss >> tv.tv_sec;
3202                 ss.str(t->property("tv-usec")->value());
3203                 ss >> tv.tv_usec;
3204                 ut->set_timestamp(tv);
3205
3206                 for (XMLNodeConstIterator child_it  = t->children().begin();
3207                                 child_it != t->children().end(); child_it++)
3208                 {
3209                         XMLNode *n = *child_it;
3210                         Command *c;
3211
3212                         if (n->name() == "MementoCommand" ||
3213                                         n->name() == "MementoUndoCommand" ||
3214                                         n->name() == "MementoRedoCommand") {
3215
3216                                 if ((c = memento_command_factory(n))) {
3217                                         ut->add_command(c);
3218                                 }
3219
3220                         } else if (n->name() == "NoteDiffCommand") {
3221                                 PBD::ID id (n->property("midi-source")->value());
3222                                 boost::shared_ptr<MidiSource> midi_source =
3223                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3224                                 if (midi_source) {
3225                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3226                                 } else {
3227                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3228                                 }
3229
3230                         } else if (n->name() == "SysExDiffCommand") {
3231
3232                                 PBD::ID id (n->property("midi-source")->value());
3233                                 boost::shared_ptr<MidiSource> midi_source =
3234                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3235                                 if (midi_source) {
3236                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3237                                 } else {
3238                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3239                                 }
3240
3241                         } else if (n->name() == "PatchChangeDiffCommand") {
3242
3243                                 PBD::ID id (n->property("midi-source")->value());
3244                                 boost::shared_ptr<MidiSource> midi_source =
3245                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3246                                 if (midi_source) {
3247                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3248                                 } else {
3249                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3250                                 }
3251
3252                         } else if (n->name() == "StatefulDiffCommand") {
3253                                 if ((c = stateful_diff_command_factory (n))) {
3254                                         ut->add_command (c);
3255                                 }
3256                         } else {
3257                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3258                         }
3259                 }
3260
3261                 _history.add (ut);
3262         }
3263
3264         return 0;
3265 }
3266
3267 void
3268 Session::config_changed (std::string p, bool ours)
3269 {
3270         if (ours) {
3271                 set_dirty ();
3272         }
3273
3274         if (p == "seamless-loop") {
3275
3276         } else if (p == "rf-speed") {
3277
3278         } else if (p == "auto-loop") {
3279
3280         } else if (p == "auto-input") {
3281
3282                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3283                         /* auto-input only makes a difference if we're rolling */
3284                         set_track_monitor_input_status (!config.get_auto_input());
3285                 }
3286
3287         } else if (p == "punch-in") {
3288
3289                 Location* location;
3290
3291                 if ((location = _locations->auto_punch_location()) != 0) {
3292
3293                         if (config.get_punch_in ()) {
3294                                 replace_event (SessionEvent::PunchIn, location->start());
3295                         } else {
3296                                 remove_event (location->start(), SessionEvent::PunchIn);
3297                         }
3298                 }
3299
3300         } else if (p == "punch-out") {
3301
3302                 Location* location;
3303
3304                 if ((location = _locations->auto_punch_location()) != 0) {
3305
3306                         if (config.get_punch_out()) {
3307                                 replace_event (SessionEvent::PunchOut, location->end());
3308                         } else {
3309                                 clear_events (SessionEvent::PunchOut);
3310                         }
3311                 }
3312
3313         } else if (p == "edit-mode") {
3314
3315                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3316
3317                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3318                         (*i)->set_edit_mode (Config->get_edit_mode ());
3319                 }
3320
3321         } else if (p == "use-video-sync") {
3322
3323                 waiting_for_sync_offset = config.get_use_video_sync();
3324
3325         } else if (p == "mmc-control") {
3326
3327                 //poke_midi_thread ();
3328
3329         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3330
3331                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3332
3333         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3334
3335                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3336
3337         } else if (p == "midi-control") {
3338
3339                 //poke_midi_thread ();
3340
3341         } else if (p == "raid-path") {
3342
3343                 setup_raid_path (config.get_raid_path());
3344
3345         } else if (p == "timecode-format") {
3346
3347                 sync_time_vars ();
3348
3349         } else if (p == "video-pullup") {
3350
3351                 sync_time_vars ();
3352
3353         } else if (p == "seamless-loop") {
3354
3355                 if (play_loop && transport_rolling()) {
3356                         // to reset diskstreams etc
3357                         request_play_loop (true);
3358                 }
3359
3360         } else if (p == "rf-speed") {
3361
3362                 cumulative_rf_motion = 0;
3363                 reset_rf_scale (0);
3364
3365         } else if (p == "click-sound") {
3366
3367                 setup_click_sounds (1);
3368
3369         } else if (p == "click-emphasis-sound") {
3370
3371                 setup_click_sounds (-1);
3372
3373         } else if (p == "clicking") {
3374
3375                 if (Config->get_clicking()) {
3376                         if (_click_io && click_data) { // don't require emphasis data
3377                                 _clicking = true;
3378                         }
3379                 } else {
3380                         _clicking = false;
3381                 }
3382
3383         } else if (p == "click-gain") {
3384                 
3385                 if (_click_gain) {
3386                         _click_gain->set_gain (Config->get_click_gain(), this);
3387                 }
3388
3389         } else if (p == "send-mtc") {
3390
3391                 if (Config->get_send_mtc ()) {
3392                         /* mark us ready to send */
3393                         next_quarter_frame_to_send = 0;
3394                 }
3395
3396         } else if (p == "send-mmc") {
3397
3398                 _mmc->enable_send (Config->get_send_mmc ());
3399
3400         } else if (p == "midi-feedback") {
3401
3402                 session_midi_feedback = Config->get_midi_feedback();
3403
3404         } else if (p == "jack-time-master") {
3405
3406                 engine().reset_timebase ();
3407
3408         } else if (p == "native-file-header-format") {
3409
3410                 if (!first_file_header_format_reset) {
3411                         reset_native_file_format ();
3412                 }
3413
3414                 first_file_header_format_reset = false;
3415
3416         } else if (p == "native-file-data-format") {
3417
3418                 if (!first_file_data_format_reset) {
3419                         reset_native_file_format ();
3420                 }
3421
3422                 first_file_data_format_reset = false;
3423
3424         } else if (p == "external-sync") {
3425                 if (!config.get_external_sync()) {
3426                         drop_sync_source ();
3427                 } else {
3428                         switch_to_sync_source (Config->get_sync_source());
3429                 }
3430         }  else if (p == "denormal-model") {
3431                 setup_fpu ();
3432         } else if (p == "history-depth") {
3433                 set_history_depth (Config->get_history_depth());
3434         } else if (p == "remote-model") {
3435                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3436                    TO SET REMOTE ID'S
3437                 */
3438         } else if (p == "initial-program-change") {
3439
3440                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3441                         MIDI::byte buf[2];
3442
3443                         buf[0] = MIDI::program; // channel zero by default
3444                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3445
3446                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3447                 }
3448         } else if (p == "solo-mute-override") {
3449                 // catch_up_on_solo_mute_override ();
3450         } else if (p == "listen-position" || p == "pfl-position") {
3451                 listen_position_changed ();
3452         } else if (p == "solo-control-is-listen-control") {
3453                 solo_control_mode_changed ();
3454         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3455                 last_timecode_valid = false;
3456         } else if (p == "playback-buffer-seconds") {
3457                 AudioSource::allocate_working_buffers (frame_rate());
3458         } else if (p == "automation-thinning-factor") {
3459                 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3460         } else if (p == "ltc-source-port") {
3461                 reconnect_ltc_input ();
3462         } else if (p == "ltc-sink-port") {
3463                 reconnect_ltc_output ();
3464         } else if (p == "timecode-generator-offset") {
3465                 ltc_tx_parse_offset();
3466         }
3467
3468         set_dirty ();
3469 }
3470
3471 void
3472 Session::set_history_depth (uint32_t d)
3473 {
3474         _history.set_depth (d);
3475 }
3476
3477 int
3478 Session::load_diskstreams_2X (XMLNode const & node, int)
3479 {
3480         XMLNodeList          clist;
3481         XMLNodeConstIterator citer;
3482
3483         clist = node.children();
3484
3485         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3486
3487                 try {
3488                         /* diskstreams added automatically by DiskstreamCreated handler */
3489                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3490                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3491                                 _diskstreams_2X.push_back (dsp);
3492                         } else {
3493                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3494                         }
3495                 }
3496
3497                 catch (failed_constructor& err) {
3498                         error << _("Session: could not load diskstream via XML state") << endmsg;
3499                         return -1;
3500                 }
3501         }
3502
3503         return 0;
3504 }
3505
3506 /** Connect things to the MMC object */
3507 void
3508 Session::setup_midi_machine_control ()
3509 {
3510         _mmc = new MIDI::MachineControl;
3511         _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3512
3513         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3514         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3515         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3516         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3517         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3518         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3519         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3520         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3521         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3522         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3523         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3524         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3525         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3526
3527         /* also handle MIDI SPP because its so common */
3528
3529         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3530         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3531         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3532 }
3533
3534 boost::shared_ptr<Controllable>
3535 Session::solo_cut_control() const
3536 {
3537         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3538            controls in Ardour that currently get presented to the user in the GUI that require
3539            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3540
3541            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3542            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3543            parameter.
3544         */
3545
3546         return _solo_cut_control;
3547 }
3548
3549 int
3550 Session::rename (const std::string& new_name)
3551 {
3552         string legal_name = legalize_for_path (new_name);
3553         string newpath;
3554         string oldstr;
3555         string newstr;
3556         bool first = true;
3557
3558         string const old_sources_root = _session_dir->sources_root();
3559
3560         /* Rename:
3561
3562          * session directory
3563          * interchange subdirectory
3564          * session file
3565          * session history
3566          
3567          * Backup files are left unchanged and not renamed.
3568          */
3569
3570         /* pass one: not 100% safe check that the new directory names don't
3571          * already exist ...
3572          */
3573
3574         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3575                 vector<string> v;
3576
3577                 oldstr = (*i).path;
3578
3579                 /* this is a stupid hack because Glib::path_get_dirname() is
3580                  * lexical-only, and so passing it /a/b/c/ gives a different
3581                  * result than passing it /a/b/c ...
3582                  */
3583
3584                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3585                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3586                 }
3587
3588                 string base = Glib::path_get_dirname (oldstr);
3589                 string p = Glib::path_get_basename (oldstr);
3590
3591                 newstr = Glib::build_filename (base, legal_name);
3592                 
3593                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3594                         return -1;
3595                 }
3596         }
3597
3598         /* Session dirs */
3599         
3600         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3601                 vector<string> v;
3602
3603                 oldstr = (*i).path;
3604
3605                 /* this is a stupid hack because Glib::path_get_dirname() is
3606                  * lexical-only, and so passing it /a/b/c/ gives a different
3607                  * result than passing it /a/b/c ...
3608                  */
3609
3610                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3611                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3612                 }
3613
3614                 string base = Glib::path_get_dirname (oldstr);
3615                 string p = Glib::path_get_basename (oldstr);
3616
3617                 newstr = Glib::build_filename (base, legal_name);
3618
3619                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3620
3621                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3622                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3623                         return 1;
3624                 }
3625
3626                 if (first) {
3627                         (*_session_dir) = newstr;
3628                         newpath = newstr;
3629                         first = 1;
3630                 }
3631
3632                 /* directory below interchange */
3633
3634                 v.push_back (newstr);
3635                 v.push_back (interchange_dir_name);
3636                 v.push_back (p);
3637
3638                 oldstr = Glib::build_filename (v);
3639
3640                 v.clear ();
3641                 v.push_back (newstr);
3642                 v.push_back (interchange_dir_name);
3643                 v.push_back (legal_name);
3644
3645                 newstr = Glib::build_filename (v);
3646                 
3647                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3648                 
3649                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3650                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3651                         return 1;
3652                 }
3653         }
3654
3655         /* state file */
3656         
3657         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3658         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3659         
3660         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3661
3662         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3663                 error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3664                 return 1;
3665         }
3666
3667         /* history file */
3668
3669         
3670         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3671
3672         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3673                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3674                 
3675                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3676                 
3677                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3678                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3679                         return 1;
3680                 }
3681         }
3682
3683         /* update file source paths */
3684         
3685         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3686                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3687                 if (fs) {
3688                         string p = fs->path ();
3689                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3690                         fs->set_path (p);
3691                 }
3692         }
3693
3694         /* remove old name from recent sessions */
3695
3696         remove_recent_sessions (_path);
3697
3698         _path = newpath;
3699         _current_snapshot_name = new_name;
3700         _name = new_name;
3701
3702         /* re-add directory separator - reverse hack to oldstr above */
3703         if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
3704                 _path += G_DIR_SEPARATOR;
3705         }
3706
3707         set_dirty ();
3708
3709         /* save state again to get everything just right */
3710
3711         save_state (_current_snapshot_name);
3712
3713
3714         /* add to recent sessions */
3715
3716         store_recent_sessions (new_name, _path);
3717
3718         return 0;
3719 }
3720
3721 int
3722 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3723 {
3724         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3725                 return -1;
3726         }
3727
3728         if (!tree.read (xmlpath)) {
3729                 return -1;
3730         }
3731
3732         return 0;
3733 }
3734
3735 int
3736 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3737 {
3738         XMLTree tree;
3739         bool found_sr = false;
3740         bool found_data_format = false;
3741
3742         if (get_session_info_from_path (tree, xmlpath)) {
3743                 return -1;
3744         }
3745
3746         /* sample rate */
3747
3748         const XMLProperty* prop;
3749         if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
3750                 sample_rate = atoi (prop->value());
3751                 found_sr = true;
3752         }
3753
3754         const XMLNodeList& children (tree.root()->children());
3755         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3756                 const XMLNode* child = *c;
3757                 if (child->name() == "Config") {
3758                         const XMLNodeList& options (child->children());
3759                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3760                                 const XMLNode* option = *oc;
3761                                 const XMLProperty* name = option->property("name");
3762
3763                                 if (!name) {
3764                                         continue;
3765                                 }
3766
3767                                 if (name->value() == "native-file-data-format") {
3768                                         const XMLProperty* value = option->property ("value");
3769                                         if (value) {
3770                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3771                                                 data_format = fmt;
3772                                                 found_data_format = true;
3773                                                 break;
3774                                         }
3775                                 }
3776                         }
3777                 }
3778                 if (found_data_format) {
3779                         break;
3780                 }
3781         }
3782
3783         return !(found_sr && found_data_format); // zero if they are both found
3784 }
3785
3786 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
3787 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
3788
3789 int
3790 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
3791 {
3792         uint32_t total = 0;
3793         uint32_t n = 0;
3794         SourcePathMap source_path_map;
3795         string new_path;
3796         boost::shared_ptr<AudioFileSource> afs;
3797         int ret = 0;
3798
3799         {
3800
3801                 Glib::Threads::Mutex::Lock lm (source_lock);
3802                 
3803                 cerr << " total sources = " << sources.size();
3804                 
3805                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3806                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3807                         
3808                         if (!fs) {
3809                                 continue;
3810                         }
3811                         
3812                         if (fs->within_session()) {
3813                                 cerr << "skip " << fs->name() << endl;
3814                                 continue;
3815                         }
3816                         
3817                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
3818                                 source_path_map[fs->path()].push_back (fs);
3819                         } else {
3820                                 SeveralFileSources v;
3821                                 v.push_back (fs);
3822                                 source_path_map.insert (make_pair (fs->path(), v));
3823                         }
3824                         
3825                         total++;
3826                 }
3827                 
3828                 cerr << " fsources = " << total << endl;
3829                 
3830                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
3831                         
3832                         /* tell caller where we are */
3833                         
3834                         string old_path = i->first;
3835                         
3836                         callback (n, total, old_path);
3837                         
3838                         cerr << old_path << endl;
3839                         
3840                         new_path.clear ();
3841                         
3842                         switch (i->second.front()->type()) {
3843                         case DataType::AUDIO:
3844                                 new_path = new_audio_source_path_for_embedded (old_path);
3845                                 break;
3846                                 
3847                         case DataType::MIDI:
3848                                 break;
3849                         }
3850                         
3851                         cerr << "Move " << old_path << " => " << new_path << endl;
3852                         
3853                         if (!copy_file (old_path, new_path)) {
3854                                 cerr << "failed !\n";
3855                                 ret = -1;
3856                         }
3857                         
3858                         /* make sure we stop looking in the external
3859                            dir/folder. Remember, this is an all-or-nothing
3860                            operations, it doesn't merge just some files.
3861                         */
3862                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
3863
3864                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
3865                                 (*f)->set_path (new_path);
3866                         }
3867                 }
3868         }
3869
3870         save_state ("", false, false);
3871
3872         return ret;
3873 }