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