fix cherry-pick logic failure with Session::save_template() - Tracks case already...
[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         
1050
1051         if (full_state) {
1052                 
1053                 if (_locations) {
1054                         node->add_child_nocopy (_locations->get_state());       
1055                 }
1056         } else {
1057                 Locations loc (*this);
1058                 // for a template, just create a new Locations, populate it
1059                 // with the default start and end, and get the state for that.
1060                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1061                 range->set (max_framepos, 0);
1062                 loc.add (range);
1063                 XMLNode& locations_state = loc.get_state();
1064                 
1065                 if (ARDOUR::Profile->get_trx() && _locations) {
1066                         for (Locations::LocationList::const_iterator i = _locations->list ().begin (); i != _locations->list ().end (); ++i) {
1067                                 if ((*i)->is_mark () || (*i)->is_auto_loop ()) {
1068                                         locations_state.add_child_nocopy ((*i)->get_state ());
1069                                 }
1070                         }
1071                 }
1072                 node->add_child_nocopy (locations_state);
1073         }
1074
1075         child = node->add_child ("Bundles");
1076         {
1077                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1078                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1079                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1080                         if (b) {
1081                                 child->add_child_nocopy (b->get_state());
1082                         }
1083                 }
1084         }
1085
1086         child = node->add_child ("Routes");
1087         {
1088                 boost::shared_ptr<RouteList> r = routes.reader ();
1089
1090                 RoutePublicOrderSorter cmp;
1091                 RouteList public_order (*r);
1092                 public_order.sort (cmp);
1093                 
1094                 /* the sort should have put control outs first */
1095                 
1096                 if (_monitor_out) {
1097                         assert (_monitor_out == public_order.front());
1098                 }
1099
1100                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1101                         if (!(*i)->is_auditioner()) {
1102                                 if (full_state) {
1103                                         child->add_child_nocopy ((*i)->get_state());
1104                                 } else {
1105                                         child->add_child_nocopy ((*i)->get_template());
1106                                 }
1107                         }
1108                 }
1109         }
1110
1111         playlists->add_state (node, full_state);
1112
1113         child = node->add_child ("RouteGroups");
1114         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1115                 child->add_child_nocopy ((*i)->get_state());
1116         }
1117
1118         if (_click_io) {
1119                 XMLNode* gain_child = node->add_child ("Click");
1120                 gain_child->add_child_nocopy (_click_io->state (full_state));
1121                 gain_child->add_child_nocopy (_click_gain->state (full_state));
1122         }
1123
1124         if (_ltc_input) {
1125                 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1126                 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1127         }
1128
1129         if (_ltc_input) {
1130                 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1131                 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1132         }
1133
1134         node->add_child_nocopy (_speakers->get_state());
1135         node->add_child_nocopy (_tempo_map->get_state());
1136         node->add_child_nocopy (get_control_protocol_state());
1137
1138         if (_extra_xml) {
1139                 node->add_child_copy (*_extra_xml);
1140         }
1141
1142         return *node;
1143 }
1144
1145 XMLNode&
1146 Session::get_control_protocol_state ()
1147 {
1148         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1149         return cpm.get_state();
1150 }
1151
1152 int
1153 Session::set_state (const XMLNode& node, int version)
1154 {
1155         XMLNodeList nlist;
1156         XMLNode* child;
1157         const XMLProperty* prop;
1158         int ret = -1;
1159
1160         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1161
1162         if (node.name() != X_("Session")) {
1163                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1164                 goto out;
1165         }
1166
1167         if ((prop = node.property ("name")) != 0) {
1168                 _name = prop->value ();
1169         }
1170
1171         if ((prop = node.property (X_("sample-rate"))) != 0) {
1172
1173                 _nominal_frame_rate = atoi (prop->value());
1174
1175                 if (_nominal_frame_rate != _current_frame_rate) {
1176                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1177                         if (r.get_value_or (0)) {
1178                                 goto out;
1179                         }
1180                 }
1181         }
1182
1183         setup_raid_path(_session_dir->root_path());
1184
1185         if ((prop = node.property (X_("id-counter"))) != 0) {
1186                 uint64_t x;
1187                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1188                 ID::init_counter (x);
1189         } else {
1190                 /* old sessions used a timebased counter, so fake
1191                    the startup ID counter based on a standard
1192                    timestamp.
1193                 */
1194                 time_t now;
1195                 time (&now);
1196                 ID::init_counter (now);
1197         }
1198
1199         if ((prop = node.property (X_("event-counter"))) != 0) {
1200                 Evoral::init_event_id_counter (atoi (prop->value()));
1201         }
1202
1203
1204         if ((child = find_named_node (node, "MIDIPorts")) != 0) {
1205                 _midi_ports->set_midi_port_states (child->children());
1206         }
1207
1208         IO::disable_connecting ();
1209
1210         Stateful::save_extra_xml (node);
1211
1212         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1213                 load_options (*child);
1214         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1215                 load_options (*child);
1216         } else {
1217                 error << _("Session: XML state has no options section") << endmsg;
1218         }
1219
1220         if (version >= 3000) {
1221                 if ((child = find_named_node (node, "Metadata")) == 0) {
1222                         warning << _("Session: XML state has no metadata section") << endmsg;
1223                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1224                         goto out;
1225                 }
1226         }
1227
1228         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1229                 _speakers->set_state (*child, version);
1230         }
1231
1232         if ((child = find_named_node (node, "Sources")) == 0) {
1233                 error << _("Session: XML state has no sources section") << endmsg;
1234                 goto out;
1235         } else if (load_sources (*child)) {
1236                 goto out;
1237         }
1238
1239         if ((child = find_named_node (node, "TempoMap")) == 0) {
1240                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1241                 goto out;
1242         } else if (_tempo_map->set_state (*child, version)) {
1243                 goto out;
1244         }
1245
1246         if ((child = find_named_node (node, "Locations")) == 0) {
1247                 error << _("Session: XML state has no locations section") << endmsg;
1248                 goto out;
1249         } else if (_locations->set_state (*child, version)) {
1250                 goto out;
1251         }
1252
1253         locations_changed ();
1254
1255         if (_session_range_location) {
1256                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1257         }
1258
1259         if ((child = find_named_node (node, "Regions")) == 0) {
1260                 error << _("Session: XML state has no Regions section") << endmsg;
1261                 goto out;
1262         } else if (load_regions (*child)) {
1263                 goto out;
1264         }
1265
1266         if ((child = find_named_node (node, "Playlists")) == 0) {
1267                 error << _("Session: XML state has no playlists section") << endmsg;
1268                 goto out;
1269         } else if (playlists->load (*this, *child)) {
1270                 goto out;
1271         }
1272
1273         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1274                 // this is OK
1275         } else if (playlists->load_unused (*this, *child)) {
1276                 goto out;
1277         }
1278
1279         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1280                 if (load_compounds (*child)) {
1281                         goto out;
1282                 }
1283         }
1284
1285         if (version >= 3000) {
1286                 if ((child = find_named_node (node, "Bundles")) == 0) {
1287                         warning << _("Session: XML state has no bundles section") << endmsg;
1288                         //goto out;
1289                 } else {
1290                         /* We can't load Bundles yet as they need to be able
1291                            to convert from port names to Port objects, which can't happen until
1292                            later */
1293                         _bundle_xml_node = new XMLNode (*child);
1294                 }
1295         }
1296
1297         if (version < 3000) {
1298                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1299                         error << _("Session: XML state has no diskstreams section") << endmsg;
1300                         goto out;
1301                 } else if (load_diskstreams_2X (*child, version)) {
1302                         goto out;
1303                 }
1304         }
1305
1306         if ((child = find_named_node (node, "Routes")) == 0) {
1307                 error << _("Session: XML state has no routes section") << endmsg;
1308                 goto out;
1309         } else if (load_routes (*child, version)) {
1310                 goto out;
1311         }
1312
1313         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1314         _diskstreams_2X.clear ();
1315
1316         if (version >= 3000) {
1317
1318                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1319                         error << _("Session: XML state has no route groups section") << endmsg;
1320                         goto out;
1321                 } else if (load_route_groups (*child, version)) {
1322                         goto out;
1323                 }
1324
1325         } else if (version < 3000) {
1326
1327                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1328                         error << _("Session: XML state has no edit groups section") << endmsg;
1329                         goto out;
1330                 } else if (load_route_groups (*child, version)) {
1331                         goto out;
1332                 }
1333
1334                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1335                         error << _("Session: XML state has no mix groups section") << endmsg;
1336                         goto out;
1337                 } else if (load_route_groups (*child, version)) {
1338                         goto out;
1339                 }
1340         }
1341
1342         if ((child = find_named_node (node, "Click")) == 0) {
1343                 warning << _("Session: XML state has no click section") << endmsg;
1344         } else if (_click_io) {
1345                 setup_click_state (&node);
1346         }
1347
1348         if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1349                 ControlProtocolManager::instance().set_state (*child, version);
1350         }
1351
1352         update_have_rec_enabled_track ();
1353
1354         /* here beginneth the second phase ... */
1355
1356         StateReady (); /* EMIT SIGNAL */
1357
1358         delete state_tree;
1359         state_tree = 0;
1360         return 0;
1361
1362   out:
1363         delete state_tree;
1364         state_tree = 0;
1365         return ret;
1366 }
1367
1368 int
1369 Session::load_routes (const XMLNode& node, int version)
1370 {
1371         XMLNodeList nlist;
1372         XMLNodeConstIterator niter;
1373         RouteList new_routes;
1374
1375         nlist = node.children();
1376
1377         set_dirty();
1378
1379         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1380
1381                 boost::shared_ptr<Route> route;
1382                 if (version < 3000) {
1383                         route = XMLRouteFactory_2X (**niter, version);
1384                 } else {
1385                         route = XMLRouteFactory (**niter, version);
1386                 }
1387
1388                 if (route == 0) {
1389                         error << _("Session: cannot create Route from XML description.") << endmsg;
1390                         return -1;
1391                 }
1392
1393                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1394
1395                 new_routes.push_back (route);
1396         }
1397
1398         BootMessage (_("Tracks/busses loaded;  Adding to Session"));
1399
1400         add_routes (new_routes, false, false, false);
1401
1402         BootMessage (_("Finished adding tracks/busses"));
1403
1404         return 0;
1405 }
1406
1407 boost::shared_ptr<Route>
1408 Session::XMLRouteFactory (const XMLNode& node, int version)
1409 {
1410         boost::shared_ptr<Route> ret;
1411
1412         if (node.name() != "Route") {
1413                 return ret;
1414         }
1415
1416         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1417
1418         DataType type = DataType::AUDIO;
1419         const XMLProperty* prop = node.property("default-type");
1420
1421         if (prop) {
1422                 type = DataType (prop->value());
1423         }
1424
1425         assert (type != DataType::NIL);
1426
1427         if (ds_child) {
1428
1429                 boost::shared_ptr<Track> track;
1430
1431                 if (type == DataType::AUDIO) {
1432                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1433                 } else {
1434                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1435                 }
1436
1437                 if (track->init()) {
1438                         return ret;
1439                 }
1440
1441                 if (track->set_state (node, version)) {
1442                         return ret;
1443                 }
1444
1445 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1446                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1447 #endif
1448                 ret = track;
1449
1450         } else {
1451                 enum Route::Flag flags = Route::Flag(0);
1452                 const XMLProperty* prop = node.property("flags");
1453                 if (prop) {
1454                         flags = Route::Flag (string_2_enum (prop->value(), flags));
1455                 }
1456
1457                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1458
1459                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1460 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1461                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1462 #endif
1463                         ret = r;
1464                 }
1465         }
1466
1467         return ret;
1468 }
1469
1470 boost::shared_ptr<Route>
1471 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1472 {
1473         boost::shared_ptr<Route> ret;
1474
1475         if (node.name() != "Route") {
1476                 return ret;
1477         }
1478
1479         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1480         if (!ds_prop) {
1481                 ds_prop = node.property (X_("diskstream"));
1482         }
1483
1484         DataType type = DataType::AUDIO;
1485         const XMLProperty* prop = node.property("default-type");
1486
1487         if (prop) {
1488                 type = DataType (prop->value());
1489         }
1490
1491         assert (type != DataType::NIL);
1492
1493         if (ds_prop) {
1494
1495                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1496                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1497                         ++i;
1498                 }
1499
1500                 if (i == _diskstreams_2X.end()) {
1501                         error << _("Could not find diskstream for route") << endmsg;
1502                         return boost::shared_ptr<Route> ();
1503                 }
1504
1505                 boost::shared_ptr<Track> track;
1506
1507                 if (type == DataType::AUDIO) {
1508                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1509                 } else {
1510                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1511                 }
1512
1513                 if (track->init()) {
1514                         return ret;
1515                 }
1516
1517                 if (track->set_state (node, version)) {
1518                         return ret;
1519                 }
1520
1521                 track->set_diskstream (*i);
1522
1523 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1524                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1525 #endif
1526                 ret = track;
1527
1528         } else {
1529                 enum Route::Flag flags = Route::Flag(0);
1530                 const XMLProperty* prop = node.property("flags");
1531                 if (prop) {
1532                         flags = Route::Flag (string_2_enum (prop->value(), flags));
1533                 }
1534
1535                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1536
1537                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1538 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1539                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1540 #endif
1541                         ret = r;
1542                 }
1543         }
1544
1545         return ret;
1546 }
1547
1548 int
1549 Session::load_regions (const XMLNode& node)
1550 {
1551         XMLNodeList nlist;
1552         XMLNodeConstIterator niter;
1553         boost::shared_ptr<Region> region;
1554
1555         nlist = node.children();
1556
1557         set_dirty();
1558
1559         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1560                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1561                         error << _("Session: cannot create Region from XML description.");
1562                         const XMLProperty *name = (**niter).property("name");
1563
1564                         if (name) {
1565                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1566                         }
1567
1568                         error << endmsg;
1569                 }
1570         }
1571
1572         return 0;
1573 }
1574
1575 int
1576 Session::load_compounds (const XMLNode& node)
1577 {
1578         XMLNodeList calist = node.children();
1579         XMLNodeConstIterator caiter;
1580         XMLProperty *caprop;
1581
1582         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1583                 XMLNode* ca = *caiter;
1584                 ID orig_id;
1585                 ID copy_id;
1586
1587                 if ((caprop = ca->property (X_("original"))) == 0) {
1588                         continue;
1589                 }
1590                 orig_id = caprop->value();
1591
1592                 if ((caprop = ca->property (X_("copy"))) == 0) {
1593                         continue;
1594                 }
1595                 copy_id = caprop->value();
1596
1597                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1598                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1599
1600                 if (!orig || !copy) {
1601                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1602                                                    orig_id, copy_id)
1603                                 << endmsg;
1604                         continue;
1605                 }
1606
1607                 RegionFactory::add_compound_association (orig, copy);
1608         }
1609
1610         return 0;
1611 }
1612
1613 void
1614 Session::load_nested_sources (const XMLNode& node)
1615 {
1616         XMLNodeList nlist;
1617         XMLNodeConstIterator niter;
1618
1619         nlist = node.children();
1620
1621         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1622                 if ((*niter)->name() == "Source") {
1623
1624                         /* it may already exist, so don't recreate it unnecessarily 
1625                          */
1626
1627                         XMLProperty* prop = (*niter)->property (X_("id"));
1628                         if (!prop) {
1629                                 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1630                                 continue;
1631                         }
1632
1633                         ID source_id (prop->value());
1634
1635                         if (!source_by_id (source_id)) {
1636
1637                                 try {
1638                                         SourceFactory::create (*this, **niter, true);
1639                                 }
1640                                 catch (failed_constructor& err) {
1641                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1642                                 }
1643                         }
1644                 }
1645         }
1646 }
1647
1648 boost::shared_ptr<Region>
1649 Session::XMLRegionFactory (const XMLNode& node, bool full)
1650 {
1651         const XMLProperty* type = node.property("type");
1652
1653         try {
1654
1655                 const XMLNodeList& nlist = node.children();
1656
1657                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1658                         XMLNode *child = (*niter);
1659                         if (child->name() == "NestedSource") {
1660                                 load_nested_sources (*child);
1661                         }
1662                 }
1663
1664                 if (!type || type->value() == "audio") {
1665                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1666                 } else if (type->value() == "midi") {
1667                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1668                 }
1669
1670         } catch (failed_constructor& err) {
1671                 return boost::shared_ptr<Region> ();
1672         }
1673
1674         return boost::shared_ptr<Region> ();
1675 }
1676
1677 boost::shared_ptr<AudioRegion>
1678 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1679 {
1680         const XMLProperty* prop;
1681         boost::shared_ptr<Source> source;
1682         boost::shared_ptr<AudioSource> as;
1683         SourceList sources;
1684         SourceList master_sources;
1685         uint32_t nchans = 1;
1686         char buf[128];
1687
1688         if (node.name() != X_("Region")) {
1689                 return boost::shared_ptr<AudioRegion>();
1690         }
1691
1692         if ((prop = node.property (X_("channels"))) != 0) {
1693                 nchans = atoi (prop->value().c_str());
1694         }
1695
1696         if ((prop = node.property ("name")) == 0) {
1697                 cerr << "no name for this region\n";
1698                 abort ();
1699         }
1700
1701         if ((prop = node.property (X_("source-0"))) == 0) {
1702                 if ((prop = node.property ("source")) == 0) {
1703                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1704                         return boost::shared_ptr<AudioRegion>();
1705                 }
1706         }
1707
1708         PBD::ID s_id (prop->value());
1709
1710         if ((source = source_by_id (s_id)) == 0) {
1711                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1712                 return boost::shared_ptr<AudioRegion>();
1713         }
1714
1715         as = boost::dynamic_pointer_cast<AudioSource>(source);
1716         if (!as) {
1717                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1718                 return boost::shared_ptr<AudioRegion>();
1719         }
1720
1721         sources.push_back (as);
1722
1723         /* pickup other channels */
1724
1725         for (uint32_t n=1; n < nchans; ++n) {
1726                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1727                 if ((prop = node.property (buf)) != 0) {
1728
1729                         PBD::ID id2 (prop->value());
1730
1731                         if ((source = source_by_id (id2)) == 0) {
1732                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1733                                 return boost::shared_ptr<AudioRegion>();
1734                         }
1735
1736                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1737                         if (!as) {
1738                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1739                                 return boost::shared_ptr<AudioRegion>();
1740                         }
1741                         sources.push_back (as);
1742                 }
1743         }
1744
1745         for (uint32_t n = 0; n < nchans; ++n) {
1746                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1747                 if ((prop = node.property (buf)) != 0) {
1748
1749                         PBD::ID id2 (prop->value());
1750
1751                         if ((source = source_by_id (id2)) == 0) {
1752                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1753                                 return boost::shared_ptr<AudioRegion>();
1754                         }
1755
1756                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1757                         if (!as) {
1758                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1759                                 return boost::shared_ptr<AudioRegion>();
1760                         }
1761                         master_sources.push_back (as);
1762                 }
1763         }
1764
1765         try {
1766                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1767
1768                 /* a final detail: this is the one and only place that we know how long missing files are */
1769
1770                 if (region->whole_file()) {
1771                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1772                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1773                                 if (sfp) {
1774                                         sfp->set_length (region->length());
1775                                 }
1776                         }
1777                 }
1778
1779                 if (!master_sources.empty()) {
1780                         if (master_sources.size() != nchans) {
1781                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1782                         } else {
1783                                 region->set_master_sources (master_sources);
1784                         }
1785                 }
1786
1787                 return region;
1788
1789         }
1790
1791         catch (failed_constructor& err) {
1792                 return boost::shared_ptr<AudioRegion>();
1793         }
1794 }
1795
1796 boost::shared_ptr<MidiRegion>
1797 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1798 {
1799         const XMLProperty* prop;
1800         boost::shared_ptr<Source> source;
1801         boost::shared_ptr<MidiSource> ms;
1802         SourceList sources;
1803
1804         if (node.name() != X_("Region")) {
1805                 return boost::shared_ptr<MidiRegion>();
1806         }
1807
1808         if ((prop = node.property ("name")) == 0) {
1809                 cerr << "no name for this region\n";
1810                 abort ();
1811         }
1812
1813         if ((prop = node.property (X_("source-0"))) == 0) {
1814                 if ((prop = node.property ("source")) == 0) {
1815                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1816                         return boost::shared_ptr<MidiRegion>();
1817                 }
1818         }
1819
1820         PBD::ID s_id (prop->value());
1821
1822         if ((source = source_by_id (s_id)) == 0) {
1823                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1824                 return boost::shared_ptr<MidiRegion>();
1825         }
1826
1827         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1828         if (!ms) {
1829                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1830                 return boost::shared_ptr<MidiRegion>();
1831         }
1832
1833         sources.push_back (ms);
1834
1835         try {
1836                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1837                 /* a final detail: this is the one and only place that we know how long missing files are */
1838
1839                 if (region->whole_file()) {
1840                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1841                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1842                                 if (sfp) {
1843                                         sfp->set_length (region->length());
1844                                 }
1845                         }
1846                 }
1847
1848                 return region;
1849         }
1850
1851         catch (failed_constructor& err) {
1852                 return boost::shared_ptr<MidiRegion>();
1853         }
1854 }
1855
1856 XMLNode&
1857 Session::get_sources_as_xml ()
1858
1859 {
1860         XMLNode* node = new XMLNode (X_("Sources"));
1861         Glib::Threads::Mutex::Lock lm (source_lock);
1862
1863         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1864                 node->add_child_nocopy (i->second->get_state());
1865         }
1866
1867         return *node;
1868 }
1869
1870 void
1871 Session::reset_write_sources (bool mark_write_complete, bool force)
1872 {
1873     boost::shared_ptr<RouteList> rl = routes.reader();
1874     for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1875         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1876         if (tr) {
1877                         
1878                         // block state saving
1879                         _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
1880                         tr->reset_write_sources(mark_write_complete, force);
1881                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
1882         }
1883     }
1884 }
1885
1886 int
1887 Session::load_sources (const XMLNode& node)
1888 {
1889         XMLNodeList nlist;
1890         XMLNodeConstIterator niter;
1891         boost::shared_ptr<Source> source; /* don't need this but it stops some
1892                                            * versions of gcc complaining about
1893                                            * discarded return values.
1894                                            */
1895
1896         nlist = node.children();
1897
1898         set_dirty();
1899
1900         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1901           retry:
1902                 try {
1903                         if ((source = XMLSourceFactory (**niter)) == 0) {
1904                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1905                         }
1906
1907                 } catch (MissingSource& err) {
1908
1909                         int user_choice;
1910
1911                         if (err.type == DataType::MIDI && Glib::path_is_absolute (err.path)) {
1912                                 error << string_compose (_("A external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
1913                                                          PROGRAM_NAME) << endmsg;
1914                                 return -1;
1915                         }
1916
1917                         if (!no_questions_about_missing_files) {
1918                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1919                         } else {
1920                                 user_choice = -2;
1921                         }
1922
1923                         switch (user_choice) {
1924                         case 0:
1925                                 /* user added a new search location, so try again */
1926                                 goto retry;
1927
1928
1929                         case 1:
1930                                 /* user asked to quit the entire session load
1931                                  */
1932                                 return -1;
1933
1934                         case 2:
1935                                 no_questions_about_missing_files = true;
1936                                 goto retry;
1937
1938                         case 3:
1939                                 no_questions_about_missing_files = true;
1940                                 /* fallthru */
1941
1942                         case -1:
1943                         default:
1944                                 switch (err.type) {
1945
1946                                 case DataType::AUDIO:
1947                                         source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1948                                         break;
1949
1950                                 case DataType::MIDI:
1951                                         /* The MIDI file is actually missing so
1952                                          * just create a new one in the same
1953                                          * location. Do not announce its
1954                                          */
1955                                         string fullpath;
1956
1957                                         if (!Glib::path_is_absolute (err.path)) {
1958                                                 fullpath = Glib::build_filename (source_search_path (DataType::MIDI).front(), err.path);
1959                                         } else {
1960                                                 /* this should be an unrecoverable error: we would be creating a MIDI file outside
1961                                                    the session tree.
1962                                                 */
1963                                                 return -1;
1964                                         }
1965                                         /* Note that we do not announce the source just yet - we need to reset its ID before we do that */
1966                                         source = SourceFactory::createWritable (DataType::MIDI, *this, fullpath, false, _current_frame_rate, false, false);
1967                                         /* reset ID to match the missing one */
1968                                         source->set_id (**niter);
1969                                         /* Now we can announce it */
1970                                         SourceFactory::SourceCreated (source);
1971                                         break;
1972                                 }
1973                                 break;
1974                         }
1975                 }
1976         }
1977
1978         return 0;
1979 }
1980
1981 boost::shared_ptr<Source>
1982 Session::XMLSourceFactory (const XMLNode& node)
1983 {
1984         if (node.name() != "Source") {
1985                 return boost::shared_ptr<Source>();
1986         }
1987
1988         try {
1989                 /* note: do peak building in another thread when loading session state */
1990                 return SourceFactory::create (*this, node, true);
1991         }
1992
1993         catch (failed_constructor& err) {
1994                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the programmers."), PROGRAM_NAME) << endmsg;
1995                 return boost::shared_ptr<Source>();
1996         }
1997 }
1998
1999 int
2000 Session::save_template (string template_name)
2001 {
2002         if ((_state_of_the_state & CannotSave) || template_name.empty ()) {
2003                 return -1;
2004         }
2005
2006         bool absolute_path = Glib::path_is_absolute (template_name);
2007
2008         /* directory to put the template in */
2009         std::string template_dir_path;
2010
2011         if (!absolute_path) {
2012                 std::string user_template_dir(user_template_directory());
2013
2014                 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2015                         error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2016                                         user_template_dir, g_strerror (errno)) << endmsg;
2017                         return -1;
2018                 }
2019
2020                 template_dir_path = Glib::build_filename (user_template_dir, template_name);
2021         } else {
2022                 template_dir_path = template_name;
2023         }
2024
2025         if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2026                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2027                                 template_dir_path) << endmsg;
2028                 return -1;
2029         }
2030         
2031         if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2032                 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2033                                 template_dir_path, g_strerror (errno)) << endmsg;
2034                 return -1;
2035         }
2036
2037         /* file to write */
2038         std::string template_file_path;
2039         if (absolute_path) {
2040                 template_file_path = Glib::build_filename (template_dir_path, Glib::path_get_basename (template_dir_path) + template_suffix);
2041         } else {
2042                 template_file_path = Glib::build_filename (template_dir_path, template_name + template_suffix);
2043         }
2044
2045         SessionSaveUnderway (); /* EMIT SIGNAL */
2046         
2047         XMLTree tree;
2048
2049         tree.set_root (&get_template());
2050         if (!tree.write (template_file_path)) {
2051                 error << _("template not saved") << endmsg;
2052                 return -1;
2053         }
2054
2055         if (!ARDOUR::Profile->get_trx()) {
2056                 /* copy plugin state directory */
2057
2058                 std::string template_plugin_state_path (Glib::build_filename (template_dir_path, X_("plugins")));
2059
2060                 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2061                         error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2062                                                                         template_plugin_state_path, g_strerror (errno)) << endmsg;
2063                         return -1;
2064                 }
2065                 copy_files (plugins_dir(), template_plugin_state_path);
2066         }
2067
2068         return 0;
2069 }
2070
2071 void
2072 Session::refresh_disk_space ()
2073 {
2074 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2075         
2076         Glib::Threads::Mutex::Lock lm (space_lock);
2077
2078         /* get freespace on every FS that is part of the session path */
2079
2080         _total_free_4k_blocks = 0;
2081         _total_free_4k_blocks_uncertain = false;
2082
2083         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2084
2085                 struct statfs statfsbuf;
2086                 statfs (i->path.c_str(), &statfsbuf);
2087
2088                 double const scale = statfsbuf.f_bsize / 4096.0;
2089
2090                 /* See if this filesystem is read-only */
2091                 struct statvfs statvfsbuf;
2092                 statvfs (i->path.c_str(), &statvfsbuf);
2093
2094                 /* f_bavail can be 0 if it is undefined for whatever
2095                    filesystem we are looking at; Samba shares mounted
2096                    via GVFS are an example of this.
2097                 */
2098                 if (statfsbuf.f_bavail == 0) {
2099                         /* block count unknown */
2100                         i->blocks = 0;
2101                         i->blocks_unknown = true;
2102                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2103                         /* read-only filesystem */
2104                         i->blocks = 0;
2105                         i->blocks_unknown = false;
2106                 } else {
2107                         /* read/write filesystem with known space */
2108                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2109                         i->blocks_unknown = false;
2110                 }
2111
2112                 _total_free_4k_blocks += i->blocks;
2113                 if (i->blocks_unknown) {
2114                         _total_free_4k_blocks_uncertain = true;
2115                 }
2116         }
2117 #elif defined PLATFORM_WINDOWS
2118         vector<string> scanned_volumes;
2119         vector<string>::iterator j;
2120         vector<space_and_path>::iterator i;
2121     DWORD nSectorsPerCluster, nBytesPerSector,
2122           nFreeClusters, nTotalClusters;
2123     char disk_drive[4];
2124         bool volume_found;
2125
2126         _total_free_4k_blocks = 0;
2127
2128         for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2129                 strncpy (disk_drive, (*i).path.c_str(), 3);
2130                 disk_drive[3] = 0;
2131                 strupr(disk_drive);
2132
2133                 volume_found = false;
2134                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2135                 {
2136                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2137                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2138                         i->blocks = (uint32_t)(nFreeBytes / 4096);
2139
2140                         for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2141                                 if (0 == j->compare(disk_drive)) {
2142                                         volume_found = true;
2143                                         break;
2144                                 }
2145                         }
2146
2147                         if (!volume_found) {
2148                                 scanned_volumes.push_back(disk_drive);
2149                                 _total_free_4k_blocks += i->blocks;
2150                         }
2151                 }
2152         }
2153
2154         if (0 == _total_free_4k_blocks) {
2155                 strncpy (disk_drive, path().c_str(), 3);
2156                 disk_drive[3] = 0;
2157
2158                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2159                 {
2160                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2161                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2162                         _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2163                 }
2164         }
2165 #endif
2166 }
2167
2168 string
2169 Session::get_best_session_directory_for_new_audio ()
2170 {
2171         vector<space_and_path>::iterator i;
2172         string result = _session_dir->root_path();
2173
2174         /* handle common case without system calls */
2175
2176         if (session_dirs.size() == 1) {
2177                 return result;
2178         }
2179
2180         /* OK, here's the algorithm we're following here:
2181
2182         We want to select which directory to use for
2183         the next file source to be created. Ideally,
2184         we'd like to use a round-robin process so as to
2185         get maximum performance benefits from splitting
2186         the files across multiple disks.
2187
2188         However, in situations without much diskspace, an
2189         RR approach may end up filling up a filesystem
2190         with new files while others still have space.
2191         Its therefore important to pay some attention to
2192         the freespace in the filesystem holding each
2193         directory as well. However, if we did that by
2194         itself, we'd keep creating new files in the file
2195         system with the most space until it was as full
2196         as all others, thus negating any performance
2197         benefits of this RAID-1 like approach.
2198
2199         So, we use a user-configurable space threshold. If
2200         there are at least 2 filesystems with more than this
2201         much space available, we use RR selection between them.
2202         If not, then we pick the filesystem with the most space.
2203
2204         This gets a good balance between the two
2205         approaches.
2206         */
2207
2208         refresh_disk_space ();
2209
2210         int free_enough = 0;
2211
2212         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2213                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2214                         free_enough++;
2215                 }
2216         }
2217
2218         if (free_enough >= 2) {
2219                 /* use RR selection process, ensuring that the one
2220                    picked works OK.
2221                 */
2222
2223                 i = last_rr_session_dir;
2224
2225                 do {
2226                         if (++i == session_dirs.end()) {
2227                                 i = session_dirs.begin();
2228                         }
2229
2230                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2231                                 SessionDirectory sdir(i->path);
2232                                 if (sdir.create ()) {
2233                                         result = (*i).path;
2234                                         last_rr_session_dir = i;
2235                                         return result;
2236                                 }
2237                         }
2238
2239                 } while (i != last_rr_session_dir);
2240
2241         } else {
2242
2243                 /* pick FS with the most freespace (and that
2244                    seems to actually work ...)
2245                 */
2246
2247                 vector<space_and_path> sorted;
2248                 space_and_path_ascending_cmp cmp;
2249
2250                 sorted = session_dirs;
2251                 sort (sorted.begin(), sorted.end(), cmp);
2252
2253                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2254                         SessionDirectory sdir(i->path);
2255                         if (sdir.create ()) {
2256                                 result = (*i).path;
2257                                 last_rr_session_dir = i;
2258                                 return result;
2259                         }
2260                 }
2261         }
2262
2263         return result;
2264 }
2265
2266 string
2267 Session::automation_dir () const
2268 {
2269         return Glib::build_filename (_path, "automation");
2270 }
2271
2272 string
2273 Session::analysis_dir () const
2274 {
2275         return Glib::build_filename (_path, "analysis");
2276 }
2277
2278 string
2279 Session::plugins_dir () const
2280 {
2281         return Glib::build_filename (_path, "plugins");
2282 }
2283
2284 string
2285 Session::externals_dir () const
2286 {
2287         return Glib::build_filename (_path, "externals");
2288 }
2289
2290 int
2291 Session::load_bundles (XMLNode const & node)
2292 {
2293         XMLNodeList nlist = node.children();
2294         XMLNodeConstIterator niter;
2295
2296         set_dirty();
2297
2298         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2299                 if ((*niter)->name() == "InputBundle") {
2300                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2301                 } else if ((*niter)->name() == "OutputBundle") {
2302                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2303                 } else {
2304                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2305                         return -1;
2306                 }
2307         }
2308
2309         return 0;
2310 }
2311
2312 int
2313 Session::load_route_groups (const XMLNode& node, int version)
2314 {
2315         XMLNodeList nlist = node.children();
2316         XMLNodeConstIterator niter;
2317
2318         set_dirty ();
2319
2320         if (version >= 3000) {
2321
2322                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2323                         if ((*niter)->name() == "RouteGroup") {
2324                                 RouteGroup* rg = new RouteGroup (*this, "");
2325                                 add_route_group (rg);
2326                                 rg->set_state (**niter, version);
2327                         }
2328                 }
2329
2330         } else if (version < 3000) {
2331
2332                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2333                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2334                                 RouteGroup* rg = new RouteGroup (*this, "");
2335                                 add_route_group (rg);
2336                                 rg->set_state (**niter, version);
2337                         }
2338                 }
2339         }
2340
2341         return 0;
2342 }
2343
2344 static bool
2345 state_file_filter (const string &str, void* /*arg*/)
2346 {
2347         return (str.length() > strlen(statefile_suffix) &&
2348                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2349 }
2350
2351 static string
2352 remove_end(string state)
2353 {
2354         string statename(state);
2355
2356         string::size_type start,end;
2357         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2358                 statename = statename.substr (start+1);
2359         }
2360
2361         if ((end = statename.rfind(statefile_suffix)) == string::npos) {
2362                 end = statename.length();
2363         }
2364
2365         return string(statename.substr (0, end));
2366 }
2367
2368 vector<string>
2369 Session::possible_states (string path)
2370 {
2371         vector<string> states;
2372         find_files_matching_filter (states, path, state_file_filter, 0, false, false);
2373
2374         transform(states.begin(), states.end(), states.begin(), remove_end);
2375
2376         sort (states.begin(), states.end());
2377
2378         return states;
2379 }
2380
2381 vector<string>
2382 Session::possible_states () const
2383 {
2384         return possible_states(_path);
2385 }
2386
2387 void
2388 Session::add_route_group (RouteGroup* g)
2389 {
2390         _route_groups.push_back (g);
2391         route_group_added (g); /* EMIT SIGNAL */
2392
2393         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2394         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2395         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2396
2397         set_dirty ();
2398 }
2399
2400 void
2401 Session::remove_route_group (RouteGroup& rg)
2402 {
2403         list<RouteGroup*>::iterator i;
2404
2405         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2406                 _route_groups.erase (i);
2407                 delete &rg;
2408
2409                 route_group_removed (); /* EMIT SIGNAL */
2410         }
2411 }
2412
2413 /** Set a new order for our route groups, without adding or removing any.
2414  *  @param groups Route group list in the new order.
2415  */
2416 void
2417 Session::reorder_route_groups (list<RouteGroup*> groups)
2418 {
2419         _route_groups = groups;
2420
2421         route_groups_reordered (); /* EMIT SIGNAL */
2422         set_dirty ();
2423 }
2424
2425
2426 RouteGroup *
2427 Session::route_group_by_name (string name)
2428 {
2429         list<RouteGroup *>::iterator i;
2430
2431         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2432                 if ((*i)->name() == name) {
2433                         return* i;
2434                 }
2435         }
2436         return 0;
2437 }
2438
2439 RouteGroup&
2440 Session::all_route_group() const
2441 {
2442         return *_all_route_group;
2443 }
2444
2445 void
2446 Session::add_commands (vector<Command*> const & cmds)
2447 {
2448         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2449                 add_command (*i);
2450         }
2451 }
2452
2453 void
2454 Session::begin_reversible_command (const string& name)
2455 {
2456         begin_reversible_command (g_quark_from_string (name.c_str ()));
2457 }
2458
2459 /** Begin a reversible command using a GQuark to identify it.
2460  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2461  *  but there must be as many begin...()s as there are commit...()s.
2462  */
2463 void
2464 Session::begin_reversible_command (GQuark q)
2465 {
2466         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2467            to hold all the commands that are committed.  This keeps the order of
2468            commands correct in the history.
2469         */
2470
2471         if (_current_trans == 0) {
2472                 /* start a new transaction */
2473                 assert (_current_trans_quarks.empty ());
2474                 _current_trans = new UndoTransaction();
2475                 _current_trans->set_name (g_quark_to_string (q));
2476         }
2477
2478         _current_trans_quarks.push_front (q);
2479 }
2480
2481 void
2482 Session::abort_reversible_command ()
2483 {
2484         if (_current_trans != 0) {
2485                 _current_trans->clear();
2486                 delete _current_trans;
2487                 _current_trans = 0;
2488                 _current_trans_quarks.clear();
2489         }
2490 }
2491
2492 void
2493 Session::commit_reversible_command (Command *cmd)
2494 {
2495         assert (_current_trans);
2496         assert (!_current_trans_quarks.empty ());
2497
2498         struct timeval now;
2499
2500         if (cmd) {
2501                 _current_trans->add_command (cmd);
2502         }
2503
2504         _current_trans_quarks.pop_front ();
2505
2506         if (!_current_trans_quarks.empty ()) {
2507                 /* the transaction we're committing is not the top-level one */
2508                 return;
2509         }
2510
2511         if (_current_trans->empty()) {
2512                 /* no commands were added to the transaction, so just get rid of it */
2513                 delete _current_trans;
2514                 _current_trans = 0;
2515                 return;
2516         }
2517
2518         gettimeofday (&now, 0);
2519         _current_trans->set_timestamp (now);
2520
2521         _history.add (_current_trans);
2522         _current_trans = 0;
2523 }
2524
2525 static bool
2526 accept_all_audio_files (const string& path, void* /*arg*/)
2527 {
2528         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2529                 return false;
2530         }
2531
2532         if (!AudioFileSource::safe_audio_file_extension (path)) {
2533                 return false;
2534         }
2535
2536         return true;
2537 }
2538
2539 static bool
2540 accept_all_midi_files (const string& path, void* /*arg*/)
2541 {
2542         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2543                 return false;
2544         }
2545
2546         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2547                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2548                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2549 }
2550
2551 static bool
2552 accept_all_state_files (const string& path, void* /*arg*/)
2553 {
2554         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2555                 return false;
2556         }
2557
2558         std::string const statefile_ext (statefile_suffix);
2559         if (path.length() >= statefile_ext.length()) {
2560                 return (0 == path.compare (path.length() - statefile_ext.length(), statefile_ext.length(), statefile_ext));
2561         } else {
2562                 return false;
2563         }
2564 }
2565
2566 int
2567 Session::find_all_sources (string path, set<string>& result)
2568 {
2569         XMLTree tree;
2570         XMLNode* node;
2571
2572         if (!tree.read (path)) {
2573                 return -1;
2574         }
2575
2576         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2577                 return -2;
2578         }
2579
2580         XMLNodeList nlist;
2581         XMLNodeConstIterator niter;
2582
2583         nlist = node->children();
2584
2585         set_dirty();
2586
2587         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2588
2589                 XMLProperty* prop;
2590
2591                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2592                         continue;
2593                 }
2594
2595                 DataType type (prop->value());
2596
2597                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2598                         continue;
2599                 }
2600
2601                 if (Glib::path_is_absolute (prop->value())) {
2602                         /* external file, ignore */
2603                         continue;
2604                 }
2605
2606                 string found_path;
2607                 bool is_new;
2608                 uint16_t chan;
2609
2610                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2611                         result.insert (found_path);
2612                 }
2613         }
2614
2615         return 0;
2616 }
2617
2618 int
2619 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2620 {
2621         vector<string> state_files;
2622         string ripped;
2623         string this_snapshot_path;
2624
2625         result.clear ();
2626
2627         ripped = _path;
2628
2629         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2630                 ripped = ripped.substr (0, ripped.length() - 1);
2631         }
2632
2633         find_files_matching_filter (state_files, ripped, accept_all_state_files, (void *) 0, true, true);
2634
2635         if (state_files.empty()) {
2636                 /* impossible! */
2637                 return 0;
2638         }
2639
2640         this_snapshot_path = _path;
2641         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2642         this_snapshot_path += statefile_suffix;
2643
2644         for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
2645
2646                 if (exclude_this_snapshot && *i == this_snapshot_path) {
2647                         continue;
2648                 }
2649
2650                 if (find_all_sources (*i, result) < 0) {
2651                         return -1;
2652                 }
2653         }
2654
2655         return 0;
2656 }
2657
2658 struct RegionCounter {
2659     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2660     AudioSourceList::iterator iter;
2661     boost::shared_ptr<Region> region;
2662     uint32_t count;
2663
2664     RegionCounter() : count (0) {}
2665 };
2666
2667 int
2668 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2669 {
2670         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2671         return r.get_value_or (1);
2672 }
2673
2674 void
2675 Session::cleanup_regions ()
2676 {
2677         bool removed = false;
2678         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2679
2680         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2681
2682                 uint32_t used = playlists->region_use_count (i->second);
2683
2684                 if (used == 0 && !i->second->automatic ()) {
2685                         removed = true;
2686                         RegionFactory::map_remove (i->second);
2687                 }
2688         }
2689
2690         if (removed) {
2691                 // re-check to remove parent references of compound regions
2692                 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2693                         if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
2694                                 continue;
2695                         }
2696                         assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
2697                         if (0 == playlists->region_use_count (i->second)) {
2698                                 RegionFactory::map_remove (i->second);
2699                         }
2700                 }
2701         }
2702
2703         /* dump the history list */
2704         _history.clear ();
2705
2706         save_state ("");
2707 }
2708
2709 int
2710 Session::cleanup_sources (CleanupReport& rep)
2711 {
2712         // FIXME: needs adaptation to midi
2713
2714         vector<boost::shared_ptr<Source> > dead_sources;
2715         string audio_path;
2716         string midi_path;
2717         vector<string> candidates;
2718         vector<string> unused;
2719         set<string> all_sources;
2720         bool used;
2721         string spath;
2722         int ret = -1;
2723         string tmppath1;
2724         string tmppath2;
2725         Searchpath asp;
2726         Searchpath msp;
2727
2728         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2729
2730         /* consider deleting all unused playlists */
2731
2732         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2733                 ret = 0;
2734                 goto out;
2735         }
2736
2737         /* sync the "all regions" property of each playlist with its current state
2738          */
2739
2740         playlists->sync_all_regions_with_regions ();
2741
2742         /* find all un-used sources */
2743
2744         rep.paths.clear ();
2745         rep.space = 0;
2746
2747         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2748
2749                 SourceMap::iterator tmp;
2750
2751                 tmp = i;
2752                 ++tmp;
2753
2754                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2755                    capture files.
2756                 */
2757
2758                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2759                         dead_sources.push_back (i->second);
2760                         i->second->drop_references ();
2761                 }
2762
2763                 i = tmp;
2764         }
2765
2766         /* build a list of all the possible audio directories for the session */
2767
2768         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2769                 SessionDirectory sdir ((*i).path);
2770                 asp += sdir.sound_path();
2771         }
2772         audio_path += asp.to_string();
2773
2774
2775         /* build a list of all the possible midi directories for the session */
2776
2777         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2778                 SessionDirectory sdir ((*i).path);
2779                 msp += sdir.midi_path();
2780         }
2781         midi_path += msp.to_string();
2782
2783         find_files_matching_filter (candidates, audio_path, accept_all_audio_files, (void *) 0, true, true);
2784         find_files_matching_filter (candidates, midi_path, accept_all_midi_files, (void *) 0, true, true);
2785
2786         /* find all sources, but don't use this snapshot because the
2787            state file on disk still references sources we may have already
2788            dropped.
2789         */
2790
2791         find_all_sources_across_snapshots (all_sources, true);
2792
2793         /*  add our current source list
2794          */
2795
2796         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2797                 boost::shared_ptr<FileSource> fs;
2798                 SourceMap::iterator tmp = i;
2799                 ++tmp;
2800
2801                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2802
2803                         if (!fs->is_stub()) {
2804
2805                                 if (playlists->source_use_count (fs) != 0) {
2806                                         all_sources.insert (fs->path());
2807                                 } else {
2808                                         
2809                                         /* we might not remove this source from disk, because it may be used
2810                                            by other snapshots, but its not being used in this version
2811                                            so lets get rid of it now, along with any representative regions
2812                                            in the region list.
2813                                         */
2814                                         
2815                                         RegionFactory::remove_regions_using_source (i->second);
2816                                         sources.erase (i);
2817                                         
2818                                         // also remove source from all_sources
2819                                         
2820                                         for (set<string>::iterator j = all_sources.begin(); j != all_sources.end(); ++j) {
2821                                                 spath = Glib::path_get_basename (*j);
2822                                                 if ( spath == i->second->name () ) {
2823                                                         all_sources.erase (j);
2824                                                         break;
2825                                                 }
2826                                         }
2827                                 }
2828                         }
2829                 }
2830
2831                 i = tmp;
2832         }
2833
2834         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
2835
2836                 used = false;
2837                 spath = *x;
2838
2839                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2840
2841                         tmppath1 = canonical_path (spath);
2842                         tmppath2 = canonical_path ((*i));
2843
2844                         if (tmppath1 == tmppath2) {
2845                                 used = true;
2846                                 break;
2847                         }
2848                 }
2849
2850                 if (!used) {
2851                         unused.push_back (spath);
2852                 }
2853         }
2854
2855         /* now try to move all unused files into the "dead" directory(ies) */
2856
2857         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2858                 struct stat statbuf;
2859
2860                 string newpath;
2861
2862                 /* don't move the file across filesystems, just
2863                    stick it in the `dead_dir_name' directory
2864                    on whichever filesystem it was already on.
2865                 */
2866
2867                 if ((*x).find ("/sounds/") != string::npos) {
2868
2869                         /* old school, go up 1 level */
2870
2871                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2872                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2873
2874                 } else {
2875
2876                         /* new school, go up 4 levels */
2877
2878                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2879                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2880                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2881                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2882                 }
2883
2884                 newpath = Glib::build_filename (newpath, dead_dir_name);
2885
2886                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2887                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2888                         return -1;
2889                 }
2890
2891                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2892
2893                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2894
2895                         /* the new path already exists, try versioning */
2896
2897                         char buf[PATH_MAX+1];
2898                         int version = 1;
2899                         string newpath_v;
2900
2901                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2902                         newpath_v = buf;
2903
2904                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2905                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2906                                 newpath_v = buf;
2907                         }
2908
2909                         if (version == 999) {
2910                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2911                                                   newpath)
2912                                       << endmsg;
2913                         } else {
2914                                 newpath = newpath_v;
2915                         }
2916
2917                 } else {
2918
2919                         /* it doesn't exist, or we can't read it or something */
2920
2921                 }
2922
2923                 stat ((*x).c_str(), &statbuf);
2924
2925                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2926                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2927                                           (*x), newpath, strerror (errno))
2928                               << endmsg;
2929                         goto out;
2930                 }
2931
2932                 /* see if there an easy to find peakfile for this file, and remove it.
2933                  */
2934
2935                 string base = basename_nosuffix (*x);
2936                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2937                                  or for the first channel of embedded files. it will miss
2938                                  some peakfiles for other channels
2939                               */
2940                 string peakpath = peak_path (base);
2941
2942                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2943                         if (::g_unlink (peakpath.c_str()) != 0) {
2944                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2945                                                          peakpath, _path, strerror (errno))
2946                                       << endmsg;
2947                                 /* try to back out */
2948                                 ::rename (newpath.c_str(), _path.c_str());
2949                                 goto out;
2950                         }
2951                 }
2952
2953                 rep.paths.push_back (*x);
2954                 rep.space += statbuf.st_size;
2955         }
2956
2957         /* dump the history list */
2958
2959         _history.clear ();
2960
2961         /* save state so we don't end up a session file
2962            referring to non-existent sources.
2963         */
2964
2965         save_state ("");
2966         ret = 0;
2967
2968   out:
2969         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2970
2971         return ret;
2972 }
2973
2974 int
2975 Session::cleanup_trash_sources (CleanupReport& rep)
2976 {
2977         // FIXME: needs adaptation for MIDI
2978
2979         vector<space_and_path>::iterator i;
2980         string dead_dir;
2981
2982         rep.paths.clear ();
2983         rep.space = 0;
2984
2985         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2986
2987                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2988
2989                 clear_directory (dead_dir, &rep.space, &rep.paths);
2990         }
2991
2992         return 0;
2993 }
2994
2995 void
2996 Session::set_dirty ()
2997 {
2998         /* never mark session dirty during loading */
2999
3000         if (_state_of_the_state & Loading) {
3001                 return;
3002         }
3003
3004         bool was_dirty = dirty();
3005
3006         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3007
3008
3009         if (!was_dirty) {
3010                 DirtyChanged(); /* EMIT SIGNAL */
3011         }
3012 }
3013
3014
3015 void
3016 Session::set_clean ()
3017 {
3018         bool was_dirty = dirty();
3019
3020         _state_of_the_state = Clean;
3021
3022
3023         if (was_dirty) {
3024                 DirtyChanged(); /* EMIT SIGNAL */
3025         }
3026 }
3027
3028 void
3029 Session::set_deletion_in_progress ()
3030 {
3031         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3032 }
3033
3034 void
3035 Session::clear_deletion_in_progress ()
3036 {
3037         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3038 }
3039
3040 void
3041 Session::add_controllable (boost::shared_ptr<Controllable> c)
3042 {
3043         /* this adds a controllable to the list managed by the Session.
3044            this is a subset of those managed by the Controllable class
3045            itself, and represents the only ones whose state will be saved
3046            as part of the session.
3047         */
3048
3049         Glib::Threads::Mutex::Lock lm (controllables_lock);
3050         controllables.insert (c);
3051 }
3052
3053 struct null_deleter { void operator()(void const *) const {} };
3054
3055 void
3056 Session::remove_controllable (Controllable* c)
3057 {
3058         if (_state_of_the_state & Deletion) {
3059                 return;
3060         }
3061
3062         Glib::Threads::Mutex::Lock lm (controllables_lock);
3063
3064         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3065
3066         if (x != controllables.end()) {
3067                 controllables.erase (x);
3068         }
3069 }
3070
3071 boost::shared_ptr<Controllable>
3072 Session::controllable_by_id (const PBD::ID& id)
3073 {
3074         Glib::Threads::Mutex::Lock lm (controllables_lock);
3075
3076         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3077                 if ((*i)->id() == id) {
3078                         return *i;
3079                 }
3080         }
3081
3082         return boost::shared_ptr<Controllable>();
3083 }
3084
3085 boost::shared_ptr<Controllable>
3086 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3087 {
3088         boost::shared_ptr<Controllable> c;
3089         boost::shared_ptr<Route> r;
3090
3091         switch (desc.top_level_type()) {
3092         case ControllableDescriptor::NamedRoute:
3093         {
3094                 std::string str = desc.top_level_name();
3095                 if (str == "Master" || str == "master") {
3096                         r = _master_out;
3097                 } else if (str == "control" || str == "listen") {
3098                         r = _monitor_out;
3099                 } else {
3100                         r = route_by_name (desc.top_level_name());
3101                 }
3102                 break;
3103         }
3104
3105         case ControllableDescriptor::RemoteControlID:
3106                 r = route_by_remote_id (desc.rid());
3107                 break;
3108         }
3109
3110         if (!r) {
3111                 return c;
3112         }
3113
3114         switch (desc.subtype()) {
3115         case ControllableDescriptor::Gain:
3116                 c = r->gain_control ();
3117                 break;
3118
3119         case ControllableDescriptor::Trim:
3120                 c = r->trim()->gain_control ();
3121                 break;
3122
3123         case ControllableDescriptor::Solo:
3124                 c = r->solo_control();
3125                 break;
3126
3127         case ControllableDescriptor::Mute:
3128                 c = r->mute_control();
3129                 break;
3130
3131         case ControllableDescriptor::Recenable:
3132         {
3133                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3134
3135                 if (t) {
3136                         c = t->rec_enable_control ();
3137                 }
3138                 break;
3139         }
3140
3141         case ControllableDescriptor::PanDirection:
3142         {
3143                 c = r->pannable()->pan_azimuth_control;
3144                 break;
3145         }
3146
3147         case ControllableDescriptor::PanWidth:
3148         {
3149                 c = r->pannable()->pan_width_control;
3150                 break;
3151         }
3152
3153         case ControllableDescriptor::PanElevation:
3154         {
3155                 c = r->pannable()->pan_elevation_control;
3156                 break;
3157         }
3158
3159         case ControllableDescriptor::Balance:
3160                 /* XXX simple pan control */
3161                 break;
3162
3163         case ControllableDescriptor::PluginParameter:
3164         {
3165                 uint32_t plugin = desc.target (0);
3166                 uint32_t parameter_index = desc.target (1);
3167
3168                 /* revert to zero based counting */
3169
3170                 if (plugin > 0) {
3171                         --plugin;
3172                 }
3173
3174                 if (parameter_index > 0) {
3175                         --parameter_index;
3176                 }
3177
3178                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3179
3180                 if (p) {
3181                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3182                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3183                 }
3184                 break;
3185         }
3186
3187         case ControllableDescriptor::SendGain:
3188         {
3189                 uint32_t send = desc.target (0);
3190
3191                 /* revert to zero-based counting */
3192
3193                 if (send > 0) {
3194                         --send;
3195                 }
3196
3197                 boost::shared_ptr<Processor> p = r->nth_send (send);
3198
3199                 if (p) {
3200                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3201                         boost::shared_ptr<Amp> a = s->amp();
3202                         
3203                         if (a) {
3204                                 c = s->amp()->gain_control();
3205                         }
3206                 }
3207                 break;
3208         }
3209
3210         default:
3211                 /* relax and return a null pointer */
3212                 break;
3213         }
3214
3215         return c;
3216 }
3217
3218 void
3219 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3220 {
3221         if (_writable) {
3222                 Stateful::add_instant_xml (node, _path);
3223         }
3224
3225         if (write_to_config) {
3226                 Config->add_instant_xml (node);
3227         }
3228 }
3229
3230 XMLNode*
3231 Session::instant_xml (const string& node_name)
3232 {
3233         return Stateful::instant_xml (node_name, _path);
3234 }
3235
3236 int
3237 Session::save_history (string snapshot_name)
3238 {
3239         XMLTree tree;
3240
3241         if (!_writable) {
3242                 return 0;
3243         }
3244
3245         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 || 
3246             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3247                 return 0;
3248         }
3249
3250         if (snapshot_name.empty()) {
3251                 snapshot_name = _current_snapshot_name;
3252         }
3253
3254         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3255         const string backup_filename = history_filename + backup_suffix;
3256         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3257         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3258
3259         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3260                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3261                         error << _("could not backup old history file, current history not saved") << endmsg;
3262                         return -1;
3263                 }
3264         }
3265
3266         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3267
3268         if (!tree.write (xml_path))
3269         {
3270                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3271
3272                 if (g_remove (xml_path.c_str()) != 0) {
3273                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3274                                         xml_path, g_strerror (errno)) << endmsg;
3275                 }
3276                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3277                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3278                                         backup_path, g_strerror (errno)) << endmsg;
3279                 }
3280
3281                 return -1;
3282         }
3283
3284         return 0;
3285 }
3286
3287 int
3288 Session::restore_history (string snapshot_name)
3289 {
3290         XMLTree tree;
3291
3292         if (snapshot_name.empty()) {
3293                 snapshot_name = _current_snapshot_name;
3294         }
3295
3296         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3297         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3298
3299         info << "Loading history from " << xml_path << endmsg;
3300
3301         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3302                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3303                                 _name, xml_path) << endmsg;
3304                 return 1;
3305         }
3306
3307         if (!tree.read (xml_path)) {
3308                 error << string_compose (_("Could not understand session history file \"%1\""),
3309                                 xml_path) << endmsg;
3310                 return -1;
3311         }
3312
3313         // replace history
3314         _history.clear();
3315
3316         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3317
3318                 XMLNode *t = *it;
3319                 UndoTransaction* ut = new UndoTransaction ();
3320                 struct timeval tv;
3321
3322                 ut->set_name(t->property("name")->value());
3323                 stringstream ss(t->property("tv-sec")->value());
3324                 ss >> tv.tv_sec;
3325                 ss.str(t->property("tv-usec")->value());
3326                 ss >> tv.tv_usec;
3327                 ut->set_timestamp(tv);
3328
3329                 for (XMLNodeConstIterator child_it  = t->children().begin();
3330                                 child_it != t->children().end(); child_it++)
3331                 {
3332                         XMLNode *n = *child_it;
3333                         Command *c;
3334
3335                         if (n->name() == "MementoCommand" ||
3336                                         n->name() == "MementoUndoCommand" ||
3337                                         n->name() == "MementoRedoCommand") {
3338
3339                                 if ((c = memento_command_factory(n))) {
3340                                         ut->add_command(c);
3341                                 }
3342
3343                         } else if (n->name() == "NoteDiffCommand") {
3344                                 PBD::ID id (n->property("midi-source")->value());
3345                                 boost::shared_ptr<MidiSource> midi_source =
3346                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3347                                 if (midi_source) {
3348                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3349                                 } else {
3350                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3351                                 }
3352
3353                         } else if (n->name() == "SysExDiffCommand") {
3354
3355                                 PBD::ID id (n->property("midi-source")->value());
3356                                 boost::shared_ptr<MidiSource> midi_source =
3357                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3358                                 if (midi_source) {
3359                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3360                                 } else {
3361                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3362                                 }
3363
3364                         } else if (n->name() == "PatchChangeDiffCommand") {
3365
3366                                 PBD::ID id (n->property("midi-source")->value());
3367                                 boost::shared_ptr<MidiSource> midi_source =
3368                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3369                                 if (midi_source) {
3370                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3371                                 } else {
3372                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3373                                 }
3374
3375                         } else if (n->name() == "StatefulDiffCommand") {
3376                                 if ((c = stateful_diff_command_factory (n))) {
3377                                         ut->add_command (c);
3378                                 }
3379                         } else {
3380                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3381                         }
3382                 }
3383
3384                 _history.add (ut);
3385         }
3386
3387         return 0;
3388 }
3389
3390 void
3391 Session::config_changed (std::string p, bool ours)
3392 {
3393         if (ours) {
3394                 set_dirty ();
3395         }
3396
3397         if (p == "seamless-loop") {
3398
3399         } else if (p == "rf-speed") {
3400
3401         } else if (p == "auto-loop") {
3402
3403         } else if (p == "auto-input") {
3404
3405                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3406                         /* auto-input only makes a difference if we're rolling */
3407                         set_track_monitor_input_status (!config.get_auto_input());
3408                 }
3409
3410         } else if (p == "punch-in") {
3411
3412                 Location* location;
3413
3414                 if ((location = _locations->auto_punch_location()) != 0) {
3415
3416                         if (config.get_punch_in ()) {
3417                                 replace_event (SessionEvent::PunchIn, location->start());
3418                         } else {
3419                                 remove_event (location->start(), SessionEvent::PunchIn);
3420                         }
3421                 }
3422
3423         } else if (p == "punch-out") {
3424
3425                 Location* location;
3426
3427                 if ((location = _locations->auto_punch_location()) != 0) {
3428
3429                         if (config.get_punch_out()) {
3430                                 replace_event (SessionEvent::PunchOut, location->end());
3431                         } else {
3432                                 clear_events (SessionEvent::PunchOut);
3433                         }
3434                 }
3435
3436         } else if (p == "edit-mode") {
3437
3438                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3439
3440                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3441                         (*i)->set_edit_mode (Config->get_edit_mode ());
3442                 }
3443
3444         } else if (p == "use-video-sync") {
3445
3446                 waiting_for_sync_offset = config.get_use_video_sync();
3447
3448         } else if (p == "mmc-control") {
3449
3450                 //poke_midi_thread ();
3451
3452         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3453
3454                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3455
3456         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3457
3458                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3459
3460         } else if (p == "midi-control") {
3461
3462                 //poke_midi_thread ();
3463
3464         } else if (p == "raid-path") {
3465
3466                 setup_raid_path (config.get_raid_path());
3467
3468         } else if (p == "timecode-format") {
3469
3470                 sync_time_vars ();
3471
3472         } else if (p == "video-pullup") {
3473
3474                 sync_time_vars ();
3475
3476         } else if (p == "seamless-loop") {
3477
3478                 if (play_loop && transport_rolling()) {
3479                         // to reset diskstreams etc
3480                         request_play_loop (true);
3481                 }
3482
3483         } else if (p == "rf-speed") {
3484
3485                 cumulative_rf_motion = 0;
3486                 reset_rf_scale (0);
3487
3488         } else if (p == "click-sound") {
3489
3490                 setup_click_sounds (1);
3491
3492         } else if (p == "click-emphasis-sound") {
3493
3494                 setup_click_sounds (-1);
3495
3496         } else if (p == "clicking") {
3497
3498                 if (Config->get_clicking()) {
3499                         if (_click_io && click_data) { // don't require emphasis data
3500                                 _clicking = true;
3501                         }
3502                 } else {
3503                         _clicking = false;
3504                 }
3505
3506         } else if (p == "click-gain") {
3507                 
3508                 if (_click_gain) {
3509                         _click_gain->set_gain (Config->get_click_gain(), this);
3510                 }
3511
3512         } else if (p == "send-mtc") {
3513
3514                 if (Config->get_send_mtc ()) {
3515                         /* mark us ready to send */
3516                         next_quarter_frame_to_send = 0;
3517                 }
3518
3519         } else if (p == "send-mmc") {
3520
3521                 _mmc->enable_send (Config->get_send_mmc ());
3522
3523         } else if (p == "midi-feedback") {
3524
3525                 session_midi_feedback = Config->get_midi_feedback();
3526
3527         } else if (p == "jack-time-master") {
3528
3529                 engine().reset_timebase ();
3530
3531         } else if (p == "native-file-header-format") {
3532
3533                 if (!first_file_header_format_reset) {
3534                         reset_native_file_format ();
3535                 }
3536
3537                 first_file_header_format_reset = false;
3538
3539         } else if (p == "native-file-data-format") {
3540
3541                 if (!first_file_data_format_reset) {
3542                         reset_native_file_format ();
3543                 }
3544
3545                 first_file_data_format_reset = false;
3546
3547         } else if (p == "external-sync") {
3548                 if (!config.get_external_sync()) {
3549                         drop_sync_source ();
3550                 } else {
3551                         switch_to_sync_source (Config->get_sync_source());
3552                 }
3553         }  else if (p == "denormal-model") {
3554                 setup_fpu ();
3555         } else if (p == "history-depth") {
3556                 set_history_depth (Config->get_history_depth());
3557         } else if (p == "remote-model") {
3558                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3559                    TO SET REMOTE ID'S
3560                 */
3561         } else if (p == "initial-program-change") {
3562
3563                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3564                         MIDI::byte buf[2];
3565
3566                         buf[0] = MIDI::program; // channel zero by default
3567                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3568
3569                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3570                 }
3571         } else if (p == "solo-mute-override") {
3572                 // catch_up_on_solo_mute_override ();
3573         } else if (p == "listen-position" || p == "pfl-position") {
3574                 listen_position_changed ();
3575         } else if (p == "solo-control-is-listen-control") {
3576                 solo_control_mode_changed ();
3577         } else if (p == "solo-mute-gain") {
3578                 _solo_cut_control->Changed();
3579         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3580                 last_timecode_valid = false;
3581         } else if (p == "playback-buffer-seconds") {
3582                 AudioSource::allocate_working_buffers (frame_rate());
3583         } else if (p == "ltc-source-port") {
3584                 reconnect_ltc_input ();
3585         } else if (p == "ltc-sink-port") {
3586                 reconnect_ltc_output ();
3587         } else if (p == "timecode-generator-offset") {
3588                 ltc_tx_parse_offset();
3589         }
3590
3591         set_dirty ();
3592 }
3593
3594 void
3595 Session::set_history_depth (uint32_t d)
3596 {
3597         _history.set_depth (d);
3598 }
3599
3600 int
3601 Session::load_diskstreams_2X (XMLNode const & node, int)
3602 {
3603         XMLNodeList          clist;
3604         XMLNodeConstIterator citer;
3605
3606         clist = node.children();
3607
3608         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3609
3610                 try {
3611                         /* diskstreams added automatically by DiskstreamCreated handler */
3612                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3613                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3614                                 _diskstreams_2X.push_back (dsp);
3615                         } else {
3616                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3617                         }
3618                 }
3619
3620                 catch (failed_constructor& err) {
3621                         error << _("Session: could not load diskstream via XML state") << endmsg;
3622                         return -1;
3623                 }
3624         }
3625
3626         return 0;
3627 }
3628
3629 /** Connect things to the MMC object */
3630 void
3631 Session::setup_midi_machine_control ()
3632 {
3633         _mmc = new MIDI::MachineControl;
3634         _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3635
3636         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3637         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3638         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3639         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3640         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3641         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3642         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3643         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3644         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3645         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3646         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3647         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3648         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3649
3650         /* also handle MIDI SPP because its so common */
3651
3652         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3653         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3654         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3655 }
3656
3657 boost::shared_ptr<Controllable>
3658 Session::solo_cut_control() const
3659 {
3660         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3661            controls in Ardour that currently get presented to the user in the GUI that require
3662            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3663
3664            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3665            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3666            parameter.
3667         */
3668
3669         return _solo_cut_control;
3670 }
3671
3672 int
3673 Session::rename (const std::string& new_name)
3674 {
3675         string legal_name = legalize_for_path (new_name);
3676         string new_path;
3677         string oldstr;
3678         string newstr;
3679         bool first = true;
3680
3681         string const old_sources_root = _session_dir->sources_root();
3682
3683         if (!_writable || (_state_of_the_state & CannotSave)) {
3684                 error << _("Cannot rename read-only session.") << endmsg;
3685                 return 0; // don't show "messed up" warning
3686         }
3687         if (record_status() == Recording) {
3688                 error << _("Cannot rename session while recording") << endmsg;
3689                 return 0; // don't show "messed up" warning
3690         }
3691
3692         StateProtector stp (this);
3693
3694         /* Rename:
3695
3696          * session directory
3697          * interchange subdirectory
3698          * session file
3699          * session history
3700          
3701          * Backup files are left unchanged and not renamed.
3702          */
3703
3704         /* Windows requires that we close all files before attempting the
3705          * rename. This works on other platforms, but isn't necessary there.
3706          * Leave it in place for all platforms though, since it may help
3707          * catch issues that could arise if the way Source files work ever
3708          * change (since most developers are not using Windows).
3709          */
3710
3711         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3712                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3713                 if (fs) {
3714                         fs->close ();
3715                 }
3716         }
3717         
3718         /* pass one: not 100% safe check that the new directory names don't
3719          * already exist ...
3720          */
3721
3722         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3723                 
3724                 oldstr = (*i).path;
3725                 
3726                 /* this is a stupid hack because Glib::path_get_dirname() is
3727                  * lexical-only, and so passing it /a/b/c/ gives a different
3728                  * result than passing it /a/b/c ...
3729                  */
3730                 
3731                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3732                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3733                 }
3734                 
3735                 string base = Glib::path_get_dirname (oldstr);
3736                 
3737                 newstr = Glib::build_filename (base, legal_name);
3738                 
3739                 cerr << "Looking for " << newstr << endl;
3740                 
3741                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3742                         cerr << " exists\n";
3743                         return -1;
3744                 }
3745         }
3746
3747         /* Session dirs */
3748
3749         first = true;
3750         
3751         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3752
3753                 vector<string> v;
3754
3755                 oldstr = (*i).path;
3756                 
3757                 /* this is a stupid hack because Glib::path_get_dirname() is
3758                  * lexical-only, and so passing it /a/b/c/ gives a different
3759                  * result than passing it /a/b/c ...
3760                  */
3761                 
3762                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3763                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3764                 }
3765
3766                 string base = Glib::path_get_dirname (oldstr);
3767                 newstr = Glib::build_filename (base, legal_name);
3768
3769                 cerr << "for " << oldstr << " new dir = " << newstr << endl;
3770                 
3771                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3772                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3773                         cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3774                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3775                         return 1;
3776                 }
3777
3778                 /* Reset path in "session dirs" */
3779                 
3780                 (*i).path = newstr;
3781                 (*i).blocks = 0;
3782                 
3783                 /* reset primary SessionDirectory object */
3784                 
3785                 if (first) {
3786                         (*_session_dir) = newstr;
3787                         new_path = newstr;
3788                         first = false;
3789                 }
3790
3791                 /* now rename directory below session_dir/interchange */
3792
3793                 string old_interchange_dir;
3794                 string new_interchange_dir;
3795
3796                 /* use newstr here because we renamed the path
3797                  * (folder/directory) that used to be oldstr to newstr above 
3798                  */     
3799                 
3800                 v.push_back (newstr); 
3801                 v.push_back (interchange_dir_name);
3802                 v.push_back (Glib::path_get_basename (oldstr));
3803
3804                 old_interchange_dir = Glib::build_filename (v);
3805
3806                 v.clear ();
3807                 v.push_back (newstr);
3808                 v.push_back (interchange_dir_name);
3809                 v.push_back (legal_name);
3810                 
3811                 new_interchange_dir = Glib::build_filename (v);
3812                 
3813                 cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
3814                 
3815                 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
3816                         cerr << string_compose (_("renaming %s as %2 failed (%3)"),
3817                                                  old_interchange_dir, new_interchange_dir,
3818                                                  g_strerror (errno))
3819                               << endl;
3820                         error << string_compose (_("renaming %s as %2 failed (%3)"),
3821                                                  old_interchange_dir, new_interchange_dir,
3822                                                  g_strerror (errno))
3823                               << endmsg;
3824                         return 1;
3825                 }
3826         }
3827
3828         /* state file */
3829         
3830         oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
3831         newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
3832         
3833         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3834
3835         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3836                 cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3837                 error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3838                 return 1;
3839         }
3840
3841         /* history file */
3842         
3843         oldstr = Glib::build_filename (new_path, _current_snapshot_name) + history_suffix;
3844
3845         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3846                 newstr = Glib::build_filename (new_path, legal_name) + history_suffix;
3847                 
3848                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3849                 
3850                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3851                         cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3852                         error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3853                         return 1;
3854                 }
3855         }
3856
3857         /* remove old name from recent sessions */
3858         remove_recent_sessions (_path);
3859         _path = new_path;
3860         
3861         /* update file source paths */
3862         
3863         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3864                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3865                 if (fs) {
3866                         string p = fs->path ();
3867                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3868                         fs->set_path (p);
3869                         SourceFactory::setup_peakfile(i->second, true);
3870                 }
3871         }
3872
3873         _current_snapshot_name = new_name;
3874         _name = new_name;
3875         
3876         set_dirty ();
3877
3878         /* save state again to get everything just right */
3879
3880         save_state (_current_snapshot_name);
3881
3882         /* add to recent sessions */
3883
3884         store_recent_sessions (new_name, _path);
3885
3886         return 0;
3887 }
3888
3889 int
3890 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3891 {
3892         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3893                 return -1;
3894         }
3895
3896         if (!tree.read (xmlpath)) {
3897                 return -1;
3898         }
3899
3900         return 0;
3901 }
3902
3903 int
3904 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3905 {
3906         XMLTree tree;
3907         bool found_sr = false;
3908         bool found_data_format = false;
3909
3910         if (get_session_info_from_path (tree, xmlpath)) {
3911                 return -1;
3912         }
3913
3914         /* sample rate */
3915
3916         const XMLProperty* prop;
3917         if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
3918                 sample_rate = atoi (prop->value());
3919                 found_sr = true;
3920         }
3921
3922         const XMLNodeList& children (tree.root()->children());
3923         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3924                 const XMLNode* child = *c;
3925                 if (child->name() == "Config") {
3926                         const XMLNodeList& options (child->children());
3927                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3928                                 const XMLNode* option = *oc;
3929                                 const XMLProperty* name = option->property("name");
3930
3931                                 if (!name) {
3932                                         continue;
3933                                 }
3934
3935                                 if (name->value() == "native-file-data-format") {
3936                                         const XMLProperty* value = option->property ("value");
3937                                         if (value) {
3938                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3939                                                 data_format = fmt;
3940                                                 found_data_format = true;
3941                                                 break;
3942                                         }
3943                                 }
3944                         }
3945                 }
3946                 if (found_data_format) {
3947                         break;
3948                 }
3949         }
3950
3951         return !(found_sr && found_data_format); // zero if they are both found
3952 }
3953
3954 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
3955 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
3956
3957 int
3958 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
3959 {
3960         uint32_t total = 0;
3961         uint32_t n = 0;
3962         SourcePathMap source_path_map;
3963         string new_path;
3964         boost::shared_ptr<AudioFileSource> afs;
3965         int ret = 0;
3966
3967         {
3968
3969                 Glib::Threads::Mutex::Lock lm (source_lock);
3970                 
3971                 cerr << " total sources = " << sources.size();
3972                 
3973                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3974                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3975                         
3976                         if (!fs) {
3977                                 continue;
3978                         }
3979                         
3980                         if (fs->within_session()) {
3981                                 continue;
3982                         }
3983                         
3984                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
3985                                 source_path_map[fs->path()].push_back (fs);
3986                         } else {
3987                                 SeveralFileSources v;
3988                                 v.push_back (fs);
3989                                 source_path_map.insert (make_pair (fs->path(), v));
3990                         }
3991                         
3992                         total++;
3993                 }
3994                 
3995                 cerr << " fsources = " << total << endl;
3996                 
3997                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
3998                         
3999                         /* tell caller where we are */
4000                         
4001                         string old_path = i->first;
4002                         
4003                         callback (n, total, old_path);
4004                         
4005                         cerr << old_path << endl;
4006                         
4007                         new_path.clear ();
4008                         
4009                         switch (i->second.front()->type()) {
4010                         case DataType::AUDIO:
4011                                 new_path = new_audio_source_path_for_embedded (old_path);
4012                                 break;
4013                                 
4014                         case DataType::MIDI:
4015                                 /* XXX not implemented yet */
4016                                 break;
4017                         }
4018                         
4019                         if (new_path.empty()) {
4020                                 continue;
4021                         }
4022                         
4023                         cerr << "Move " << old_path << " => " << new_path << endl;
4024                         
4025                         if (!copy_file (old_path, new_path)) {
4026                                 cerr << "failed !\n";
4027                                 ret = -1;
4028                         }
4029                         
4030                         /* make sure we stop looking in the external
4031                            dir/folder. Remember, this is an all-or-nothing
4032                            operations, it doesn't merge just some files.
4033                         */
4034                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
4035
4036                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
4037                                 (*f)->set_path (new_path);
4038                         }
4039                 }
4040         }
4041
4042         save_state ("", false, false);
4043
4044         return ret;
4045 }
4046
4047 static
4048 bool accept_all_files (string const &, void *)
4049 {
4050         return true;
4051 }
4052
4053 void
4054 Session::save_as_bring_callback (uint32_t,uint32_t,string)
4055 {
4056         /* 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.
4057         */
4058 }
4059
4060 static string
4061 make_new_media_path (string old_path, string new_session_folder, string new_session_path)
4062 {
4063         /* typedir is the "midifiles" or "audiofiles" etc. part of the path. */
4064
4065         string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4066         vector<string> v;
4067         v.push_back (new_session_folder); /* full path */
4068         v.push_back (interchange_dir_name);
4069         v.push_back (new_session_path);   /* just one directory/folder */
4070         v.push_back (typedir);
4071         v.push_back (Glib::path_get_basename (old_path));
4072         
4073         return Glib::build_filename (v);
4074 }
4075
4076 int
4077 Session::save_as (SaveAs& saveas)
4078 {
4079         vector<string> files;
4080         string current_folder = Glib::path_get_dirname (_path);
4081         string new_folder = legalize_for_path (saveas.new_name);
4082         string to_dir = Glib::build_filename (saveas.new_parent_folder, new_folder);
4083         int64_t total_bytes = 0;
4084         int64_t copied = 0;
4085         int64_t cnt = 0;
4086         int64_t all = 0;
4087         int32_t internal_file_cnt = 0;
4088
4089         vector<string> do_not_copy_extensions;
4090         do_not_copy_extensions.push_back (statefile_suffix);
4091         do_not_copy_extensions.push_back (pending_suffix);
4092         do_not_copy_extensions.push_back (backup_suffix);
4093         do_not_copy_extensions.push_back (temp_suffix);
4094         do_not_copy_extensions.push_back (history_suffix);
4095
4096         /* get total size */
4097
4098         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4099                 
4100                 /* need to clear this because
4101                  * find_files_matching_filter() is cumulative
4102                  */
4103                 
4104                 files.clear ();
4105                 
4106                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4107                 
4108                 all += files.size();
4109
4110                 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4111                         GStatBuf gsb;
4112                         g_stat ((*i).c_str(), &gsb);
4113                         total_bytes += gsb.st_size;
4114                 }
4115         }
4116
4117         /* save old values so we can switch back if we are not switching to the new session */
4118         
4119         string old_path = _path;
4120         string old_name = _name;
4121         string old_snapshot = _current_snapshot_name;
4122         string old_sd = _session_dir->root_path();
4123         vector<string> old_search_path[DataType::num_types];
4124         string old_config_search_path[DataType::num_types];
4125
4126         old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4127         old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4128         old_config_search_path[DataType::AUDIO]  = config.get_audio_search_path ();     
4129         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();       
4130
4131         /* switch session directory */
4132         
4133         (*_session_dir) = to_dir;
4134
4135         /* create new tree */
4136         
4137         if (!_session_dir->create()) {
4138                 saveas.failure_message = string_compose (_("Cannot create new session folder %1"), to_dir);
4139                 return -1;
4140         }
4141
4142         try {
4143                 /* copy all relevant files. Find each location in session_dirs,
4144                  * and copy files from there to target.
4145                  */
4146                 
4147                 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4148                         
4149                         /* need to clear this because
4150                          * find_files_matching_filter() is cumulative
4151                          */
4152                         
4153                         files.clear ();
4154                         
4155                         const size_t prefix_len = (*sd).path.size();
4156                         
4157                         /* Work just on the files within this session dir */
4158                         
4159                         find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4160                         
4161                         /* add dir separator to protect against collisions with
4162                          * track names (e.g. track named "audiofiles" or
4163                          * "analysis".
4164                          */
4165
4166                         static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
4167                         static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
4168                         static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
4169
4170                         /* copy all the files. Handling is different for media files
4171                            than others because of the *silly* subtree we have below the interchange
4172                            folder. That really was a bad idea, but I'm not fixing it as part of
4173                            implementing ::save_as().
4174                         */
4175                         
4176                         for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4177
4178                                 std::string from = *i;
4179
4180 #ifdef __APPLE__
4181                                 string filename = Glib::path_get_basename (from);
4182                                 std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
4183                                 if (filename == ".DS_STORE") {
4184                                         continue;
4185                                 }
4186 #endif
4187                                 
4188                                 if (from.find (audiofile_dir_string) != string::npos) {
4189                                         
4190                                         /* audio file: only copy if asked */
4191
4192                                         if (saveas.include_media && saveas.copy_media) {
4193                                                 
4194                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4195
4196                                                 info << "media file copying from " << from << " to " << to << endmsg;
4197                                                 
4198                                                 if (!copy_file (from, to)) {
4199                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4200                                                 }
4201                                         }
4202                                         
4203                                         /* we found media files inside the session folder */
4204                                         
4205                                         internal_file_cnt++;
4206
4207                                 } else if (from.find (midifile_dir_string) != string::npos) {
4208
4209                                         /* midi file: always copy unless
4210                                          * creating an empty new session
4211                                          */
4212
4213                                         if (saveas.include_media) {
4214                                         
4215                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4216                                                 
4217                                                 info << "media file copying from " << from << " to " << to << endmsg;
4218                                                 
4219                                                 if (!copy_file (from, to)) {
4220                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4221                                                 }
4222                                         }
4223
4224                                         /* we found media files inside the session folder */
4225                                                 
4226                                         internal_file_cnt++;
4227                                         
4228                                 } else if (from.find (analysis_dir_string) != string::npos) {
4229
4230                                         /*  make sure analysis dir exists in
4231                                          *  new session folder, but we're not
4232                                          *  copying analysis files here, see
4233                                          *  below 
4234                                          */
4235                                         
4236                                         (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
4237                                         continue;
4238                                         
4239                                 } else {
4240                                         
4241                                         /* normal non-media file. Don't copy state, history, etc.
4242                                          */
4243                                         
4244                                         bool do_copy = true;
4245                                         
4246                                         for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4247                                                 if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
4248                                                         /* end of filename matches extension, do not copy file */
4249                                                         do_copy = false;
4250                                                         break;
4251                                                 } 
4252                                         }
4253
4254                                         if (!saveas.copy_media && from.find (peakfile_suffix) != string::npos) {
4255                                                 /* don't copy peakfiles if
4256                                                  * we're not copying media
4257                                                  */
4258                                                 do_copy = false;
4259                                         }
4260                                         
4261                                         if (do_copy) {
4262                                                 string to = Glib::build_filename (to_dir, from.substr (prefix_len));
4263                                                 
4264                                                 info << "attempting to make directory/folder " << to << endmsg;
4265
4266                                                 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4267                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
4268                                                 }
4269
4270                                                 info << "attempting to copy " << from << " to " << to << endmsg;
4271                                                 
4272                                                 if (!copy_file (from, to)) {
4273                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4274                                                 }
4275                                         }
4276                                 }
4277                                 
4278                                 /* measure file size even if we're not going to copy so that our Progress
4279                                    signals are correct, since we included these do-not-copy files
4280                                    in the computation of the total size and file count.
4281                                 */
4282                                 
4283                                 GStatBuf gsb;
4284                                 g_stat (from.c_str(), &gsb);
4285                                 copied += gsb.st_size;
4286                                 cnt++;
4287                                 
4288                                 double fraction = (double) copied / total_bytes;
4289                                 
4290                                 bool keep_going = true;
4291
4292                                 if (saveas.copy_media) {
4293
4294                                         /* no need or expectation of this if
4295                                          * media is not being copied, because
4296                                          * it will be fast(ish).
4297                                          */
4298                                         
4299                                         /* tell someone "X percent, file M of N"; M is one-based */
4300                                         
4301                                         boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
4302                                         
4303                                         if (res) {
4304                                                 keep_going = *res;
4305                                         }
4306                                 }
4307
4308                                 if (!keep_going) {
4309                                         throw Glib::FileError (Glib::FileError::FAILED, "copy cancelled");
4310                                 }
4311                         }
4312
4313                 }
4314
4315                 /* copy optional folders, if any */
4316
4317                 string old = plugins_dir ();
4318                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4319                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4320                         copy_files (old, newdir);
4321                 }
4322
4323                 old = externals_dir ();
4324                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4325                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4326                         copy_files (old, newdir);
4327                 }
4328
4329                 old = automation_dir ();
4330                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4331                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4332                         copy_files (old, newdir);
4333                 }
4334
4335                 if (saveas.include_media) {
4336                 
4337                         if (saveas.copy_media) {
4338 #ifndef PLATFORM_WINDOWS
4339                                 /* There are problems with analysis files on
4340                                  * Windows, because they used a colon in their
4341                                  * names as late as 4.0. Colons are not legal
4342                                  * under Windows even if NTFS allows them.
4343                                  *
4344                                  * This is a tricky problem to solve so for
4345                                  * just don't copy these files. They will be
4346                                  * regenerated as-needed anyway, subject to the 
4347                                  * existing issue that the filenames will be
4348                                  * rejected by Windows, which is a separate
4349                                  * problem (though related).
4350                                  */
4351
4352                                 /* only needed if we are copying media, since the
4353                                  * analysis data refers to media data
4354                                  */
4355                                 
4356                                 old = analysis_dir ();
4357                                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4358                                         string newdir = Glib::build_filename (to_dir, "analysis");
4359                                         copy_files (old, newdir);
4360                                 }
4361 #endif /* PLATFORM_WINDOWS */                           
4362                         }
4363                 }
4364                         
4365                 
4366                 _path = to_dir;
4367                 _current_snapshot_name = saveas.new_name;
4368                 _name = saveas.new_name;
4369
4370                 if (saveas.include_media && !saveas.copy_media) {
4371
4372                         /* reset search paths of the new session (which we're pretending to be right now) to
4373                            include the original session search path, so we can still find all audio.
4374                         */
4375
4376                         if (internal_file_cnt) {
4377                                 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
4378                                         ensure_search_path_includes (*s, DataType::AUDIO);
4379                                 }
4380
4381                                 /* we do not do this for MIDI because we copy
4382                                    all MIDI files if saveas.include_media is
4383                                    true
4384                                 */
4385                         }
4386                 }
4387                 
4388                 bool was_dirty = dirty ();
4389
4390                 save_state ("", false, false, !saveas.include_media);
4391                 save_default_options ();
4392                 
4393                 if (saveas.copy_media && saveas.copy_external) {
4394                         if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback, this, _1, _2, _3))) {
4395                                 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT, "consolidate failed");
4396                         }
4397                 }
4398
4399                 saveas.final_session_folder_name = _path;
4400                 
4401                 if (!saveas.switch_to) {
4402
4403                         /* switch back to the way things were */
4404
4405                         _path = old_path;
4406                         _name = old_name;
4407                         _current_snapshot_name = old_snapshot;
4408
4409                         (*_session_dir) = old_sd;
4410
4411                         if (was_dirty) {
4412                                 set_dirty ();
4413                         }
4414
4415                         if (internal_file_cnt) {
4416                                 /* reset these to their original values */
4417                                 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
4418                                 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
4419                         }
4420                         
4421                 } else {
4422
4423                         /* prune session dirs, and update disk space statistics
4424                          */
4425
4426                         space_and_path sp;
4427                         sp.path = _path;
4428                         session_dirs.clear ();
4429                         session_dirs.push_back (sp);
4430                         refresh_disk_space ();
4431
4432                         /* ensure that all existing tracks reset their current capture source paths 
4433                          */
4434                         reset_write_sources (true, true);
4435
4436                         /* the copying above was based on actually discovering files, not just iterating over the sources list.
4437                            But if we're going to switch to the new (copied) session, we need to change the paths in the sources also.
4438                         */
4439
4440                         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4441                                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4442
4443                                 if (!fs) {
4444                                         continue;
4445                                 }
4446
4447                                 if (fs->within_session()) {
4448                                         string newpath = make_new_media_path (fs->path(), to_dir, new_folder);
4449                                         fs->set_path (newpath);
4450                                 }
4451                         }
4452                 }
4453
4454         } catch (Glib::FileError& e) {
4455
4456                 saveas.failure_message = e.what();
4457                 
4458                 /* recursively remove all the directories */
4459                 
4460                 remove_directory (to_dir);
4461                 
4462                 /* return error */
4463                 
4464                 return -1;
4465
4466         } catch (...) {
4467
4468                 saveas.failure_message = _("unknown reason");
4469                 
4470                 /* recursively remove all the directories */
4471                 
4472                 remove_directory (to_dir);
4473                 
4474                 /* return error */
4475                 
4476                 return -1;
4477         }
4478         
4479         return 0;
4480 }