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