[Summary] For tracks when saving templates, we need stored the Auto Loop Range and...
[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         /* copy plugin state directory */
2056
2057         std::string template_plugin_state_path (Glib::build_filename (template_dir_path, X_("plugins")));
2058
2059         if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2060                 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2061                                 template_plugin_state_path, g_strerror (errno)) << endmsg;
2062                 return -1;
2063         }
2064
2065         copy_recurse (plugins_dir(), template_plugin_state_path);
2066
2067         return 0;
2068 }
2069
2070 void
2071 Session::refresh_disk_space ()
2072 {
2073 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2074         
2075         Glib::Threads::Mutex::Lock lm (space_lock);
2076
2077         /* get freespace on every FS that is part of the session path */
2078
2079         _total_free_4k_blocks = 0;
2080         _total_free_4k_blocks_uncertain = false;
2081
2082         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2083
2084                 struct statfs statfsbuf;
2085                 statfs (i->path.c_str(), &statfsbuf);
2086
2087                 double const scale = statfsbuf.f_bsize / 4096.0;
2088
2089                 /* See if this filesystem is read-only */
2090                 struct statvfs statvfsbuf;
2091                 statvfs (i->path.c_str(), &statvfsbuf);
2092
2093                 /* f_bavail can be 0 if it is undefined for whatever
2094                    filesystem we are looking at; Samba shares mounted
2095                    via GVFS are an example of this.
2096                 */
2097                 if (statfsbuf.f_bavail == 0) {
2098                         /* block count unknown */
2099                         i->blocks = 0;
2100                         i->blocks_unknown = true;
2101                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2102                         /* read-only filesystem */
2103                         i->blocks = 0;
2104                         i->blocks_unknown = false;
2105                 } else {
2106                         /* read/write filesystem with known space */
2107                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2108                         i->blocks_unknown = false;
2109                 }
2110
2111                 _total_free_4k_blocks += i->blocks;
2112                 if (i->blocks_unknown) {
2113                         _total_free_4k_blocks_uncertain = true;
2114                 }
2115         }
2116 #elif defined PLATFORM_WINDOWS
2117         vector<string> scanned_volumes;
2118         vector<string>::iterator j;
2119         vector<space_and_path>::iterator i;
2120     DWORD nSectorsPerCluster, nBytesPerSector,
2121           nFreeClusters, nTotalClusters;
2122     char disk_drive[4];
2123         bool volume_found;
2124
2125         _total_free_4k_blocks = 0;
2126
2127         for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2128                 strncpy (disk_drive, (*i).path.c_str(), 3);
2129                 disk_drive[3] = 0;
2130                 strupr(disk_drive);
2131
2132                 volume_found = false;
2133                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2134                 {
2135                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2136                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2137                         i->blocks = (uint32_t)(nFreeBytes / 4096);
2138
2139                         for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2140                                 if (0 == j->compare(disk_drive)) {
2141                                         volume_found = true;
2142                                         break;
2143                                 }
2144                         }
2145
2146                         if (!volume_found) {
2147                                 scanned_volumes.push_back(disk_drive);
2148                                 _total_free_4k_blocks += i->blocks;
2149                         }
2150                 }
2151         }
2152
2153         if (0 == _total_free_4k_blocks) {
2154                 strncpy (disk_drive, path().c_str(), 3);
2155                 disk_drive[3] = 0;
2156
2157                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2158                 {
2159                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2160                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2161                         _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2162                 }
2163         }
2164 #endif
2165 }
2166
2167 string
2168 Session::get_best_session_directory_for_new_audio ()
2169 {
2170         vector<space_and_path>::iterator i;
2171         string result = _session_dir->root_path();
2172
2173         /* handle common case without system calls */
2174
2175         if (session_dirs.size() == 1) {
2176                 return result;
2177         }
2178
2179         /* OK, here's the algorithm we're following here:
2180
2181         We want to select which directory to use for
2182         the next file source to be created. Ideally,
2183         we'd like to use a round-robin process so as to
2184         get maximum performance benefits from splitting
2185         the files across multiple disks.
2186
2187         However, in situations without much diskspace, an
2188         RR approach may end up filling up a filesystem
2189         with new files while others still have space.
2190         Its therefore important to pay some attention to
2191         the freespace in the filesystem holding each
2192         directory as well. However, if we did that by
2193         itself, we'd keep creating new files in the file
2194         system with the most space until it was as full
2195         as all others, thus negating any performance
2196         benefits of this RAID-1 like approach.
2197
2198         So, we use a user-configurable space threshold. If
2199         there are at least 2 filesystems with more than this
2200         much space available, we use RR selection between them.
2201         If not, then we pick the filesystem with the most space.
2202
2203         This gets a good balance between the two
2204         approaches.
2205         */
2206
2207         refresh_disk_space ();
2208
2209         int free_enough = 0;
2210
2211         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2212                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2213                         free_enough++;
2214                 }
2215         }
2216
2217         if (free_enough >= 2) {
2218                 /* use RR selection process, ensuring that the one
2219                    picked works OK.
2220                 */
2221
2222                 i = last_rr_session_dir;
2223
2224                 do {
2225                         if (++i == session_dirs.end()) {
2226                                 i = session_dirs.begin();
2227                         }
2228
2229                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2230                                 SessionDirectory sdir(i->path);
2231                                 if (sdir.create ()) {
2232                                         result = (*i).path;
2233                                         last_rr_session_dir = i;
2234                                         return result;
2235                                 }
2236                         }
2237
2238                 } while (i != last_rr_session_dir);
2239
2240         } else {
2241
2242                 /* pick FS with the most freespace (and that
2243                    seems to actually work ...)
2244                 */
2245
2246                 vector<space_and_path> sorted;
2247                 space_and_path_ascending_cmp cmp;
2248
2249                 sorted = session_dirs;
2250                 sort (sorted.begin(), sorted.end(), cmp);
2251
2252                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2253                         SessionDirectory sdir(i->path);
2254                         if (sdir.create ()) {
2255                                 result = (*i).path;
2256                                 last_rr_session_dir = i;
2257                                 return result;
2258                         }
2259                 }
2260         }
2261
2262         return result;
2263 }
2264
2265 string
2266 Session::automation_dir () const
2267 {
2268         return Glib::build_filename (_path, "automation");
2269 }
2270
2271 string
2272 Session::analysis_dir () const
2273 {
2274         return Glib::build_filename (_path, "analysis");
2275 }
2276
2277 string
2278 Session::plugins_dir () const
2279 {
2280         return Glib::build_filename (_path, "plugins");
2281 }
2282
2283 string
2284 Session::externals_dir () const
2285 {
2286         return Glib::build_filename (_path, "externals");
2287 }
2288
2289 int
2290 Session::load_bundles (XMLNode const & node)
2291 {
2292         XMLNodeList nlist = node.children();
2293         XMLNodeConstIterator niter;
2294
2295         set_dirty();
2296
2297         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2298                 if ((*niter)->name() == "InputBundle") {
2299                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2300                 } else if ((*niter)->name() == "OutputBundle") {
2301                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2302                 } else {
2303                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2304                         return -1;
2305                 }
2306         }
2307
2308         return 0;
2309 }
2310
2311 int
2312 Session::load_route_groups (const XMLNode& node, int version)
2313 {
2314         XMLNodeList nlist = node.children();
2315         XMLNodeConstIterator niter;
2316
2317         set_dirty ();
2318
2319         if (version >= 3000) {
2320
2321                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2322                         if ((*niter)->name() == "RouteGroup") {
2323                                 RouteGroup* rg = new RouteGroup (*this, "");
2324                                 add_route_group (rg);
2325                                 rg->set_state (**niter, version);
2326                         }
2327                 }
2328
2329         } else if (version < 3000) {
2330
2331                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2332                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2333                                 RouteGroup* rg = new RouteGroup (*this, "");
2334                                 add_route_group (rg);
2335                                 rg->set_state (**niter, version);
2336                         }
2337                 }
2338         }
2339
2340         return 0;
2341 }
2342
2343 static bool
2344 state_file_filter (const string &str, void* /*arg*/)
2345 {
2346         return (str.length() > strlen(statefile_suffix) &&
2347                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2348 }
2349
2350 static string
2351 remove_end(string state)
2352 {
2353         string statename(state);
2354
2355         string::size_type start,end;
2356         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2357                 statename = statename.substr (start+1);
2358         }
2359
2360         if ((end = statename.rfind(statefile_suffix)) == string::npos) {
2361                 end = statename.length();
2362         }
2363
2364         return string(statename.substr (0, end));
2365 }
2366
2367 vector<string>
2368 Session::possible_states (string path)
2369 {
2370         vector<string> states;
2371         find_files_matching_filter (states, path, state_file_filter, 0, false, false);
2372
2373         transform(states.begin(), states.end(), states.begin(), remove_end);
2374
2375         sort (states.begin(), states.end());
2376
2377         return states;
2378 }
2379
2380 vector<string>
2381 Session::possible_states () const
2382 {
2383         return possible_states(_path);
2384 }
2385
2386 void
2387 Session::add_route_group (RouteGroup* g)
2388 {
2389         _route_groups.push_back (g);
2390         route_group_added (g); /* EMIT SIGNAL */
2391
2392         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2393         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2394         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2395
2396         set_dirty ();
2397 }
2398
2399 void
2400 Session::remove_route_group (RouteGroup& rg)
2401 {
2402         list<RouteGroup*>::iterator i;
2403
2404         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2405                 _route_groups.erase (i);
2406                 delete &rg;
2407
2408                 route_group_removed (); /* EMIT SIGNAL */
2409         }
2410 }
2411
2412 /** Set a new order for our route groups, without adding or removing any.
2413  *  @param groups Route group list in the new order.
2414  */
2415 void
2416 Session::reorder_route_groups (list<RouteGroup*> groups)
2417 {
2418         _route_groups = groups;
2419
2420         route_groups_reordered (); /* EMIT SIGNAL */
2421         set_dirty ();
2422 }
2423
2424
2425 RouteGroup *
2426 Session::route_group_by_name (string name)
2427 {
2428         list<RouteGroup *>::iterator i;
2429
2430         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2431                 if ((*i)->name() == name) {
2432                         return* i;
2433                 }
2434         }
2435         return 0;
2436 }
2437
2438 RouteGroup&
2439 Session::all_route_group() const
2440 {
2441         return *_all_route_group;
2442 }
2443
2444 void
2445 Session::add_commands (vector<Command*> const & cmds)
2446 {
2447         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2448                 add_command (*i);
2449         }
2450 }
2451
2452 void
2453 Session::begin_reversible_command (const string& name)
2454 {
2455         begin_reversible_command (g_quark_from_string (name.c_str ()));
2456 }
2457
2458 /** Begin a reversible command using a GQuark to identify it.
2459  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2460  *  but there must be as many begin...()s as there are commit...()s.
2461  */
2462 void
2463 Session::begin_reversible_command (GQuark q)
2464 {
2465         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2466            to hold all the commands that are committed.  This keeps the order of
2467            commands correct in the history.
2468         */
2469
2470         if (_current_trans == 0) {
2471                 /* start a new transaction */
2472                 assert (_current_trans_quarks.empty ());
2473                 _current_trans = new UndoTransaction();
2474                 _current_trans->set_name (g_quark_to_string (q));
2475         }
2476
2477         _current_trans_quarks.push_front (q);
2478 }
2479
2480 void
2481 Session::abort_reversible_command ()
2482 {
2483         if (_current_trans != 0) {
2484                 _current_trans->clear();
2485                 delete _current_trans;
2486                 _current_trans = 0;
2487                 _current_trans_quarks.clear();
2488         }
2489 }
2490
2491 void
2492 Session::commit_reversible_command (Command *cmd)
2493 {
2494         assert (_current_trans);
2495         assert (!_current_trans_quarks.empty ());
2496
2497         struct timeval now;
2498
2499         if (cmd) {
2500                 _current_trans->add_command (cmd);
2501         }
2502
2503         _current_trans_quarks.pop_front ();
2504
2505         if (!_current_trans_quarks.empty ()) {
2506                 /* the transaction we're committing is not the top-level one */
2507                 return;
2508         }
2509
2510         if (_current_trans->empty()) {
2511                 /* no commands were added to the transaction, so just get rid of it */
2512                 delete _current_trans;
2513                 _current_trans = 0;
2514                 return;
2515         }
2516
2517         gettimeofday (&now, 0);
2518         _current_trans->set_timestamp (now);
2519
2520         _history.add (_current_trans);
2521         _current_trans = 0;
2522 }
2523
2524 static bool
2525 accept_all_audio_files (const string& path, void* /*arg*/)
2526 {
2527         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2528                 return false;
2529         }
2530
2531         if (!AudioFileSource::safe_audio_file_extension (path)) {
2532                 return false;
2533         }
2534
2535         return true;
2536 }
2537
2538 static bool
2539 accept_all_midi_files (const string& path, void* /*arg*/)
2540 {
2541         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2542                 return false;
2543         }
2544
2545         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2546                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2547                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2548 }
2549
2550 static bool
2551 accept_all_state_files (const string& path, void* /*arg*/)
2552 {
2553         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2554                 return false;
2555         }
2556
2557         std::string const statefile_ext (statefile_suffix);
2558         if (path.length() >= statefile_ext.length()) {
2559                 return (0 == path.compare (path.length() - statefile_ext.length(), statefile_ext.length(), statefile_ext));
2560         } else {
2561                 return false;
2562         }
2563 }
2564
2565 int
2566 Session::find_all_sources (string path, set<string>& result)
2567 {
2568         XMLTree tree;
2569         XMLNode* node;
2570
2571         if (!tree.read (path)) {
2572                 return -1;
2573         }
2574
2575         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2576                 return -2;
2577         }
2578
2579         XMLNodeList nlist;
2580         XMLNodeConstIterator niter;
2581
2582         nlist = node->children();
2583
2584         set_dirty();
2585
2586         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2587
2588                 XMLProperty* prop;
2589
2590                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2591                         continue;
2592                 }
2593
2594                 DataType type (prop->value());
2595
2596                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2597                         continue;
2598                 }
2599
2600                 if (Glib::path_is_absolute (prop->value())) {
2601                         /* external file, ignore */
2602                         continue;
2603                 }
2604
2605                 string found_path;
2606                 bool is_new;
2607                 uint16_t chan;
2608
2609                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2610                         result.insert (found_path);
2611                 }
2612         }
2613
2614         return 0;
2615 }
2616
2617 int
2618 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2619 {
2620         vector<string> state_files;
2621         string ripped;
2622         string this_snapshot_path;
2623
2624         result.clear ();
2625
2626         ripped = _path;
2627
2628         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2629                 ripped = ripped.substr (0, ripped.length() - 1);
2630         }
2631
2632         find_files_matching_filter (state_files, ripped, accept_all_state_files, (void *) 0, true, true);
2633
2634         if (state_files.empty()) {
2635                 /* impossible! */
2636                 return 0;
2637         }
2638
2639         this_snapshot_path = _path;
2640         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2641         this_snapshot_path += statefile_suffix;
2642
2643         for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
2644
2645                 if (exclude_this_snapshot && *i == this_snapshot_path) {
2646                         continue;
2647                 }
2648
2649                 if (find_all_sources (*i, result) < 0) {
2650                         return -1;
2651                 }
2652         }
2653
2654         return 0;
2655 }
2656
2657 struct RegionCounter {
2658     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2659     AudioSourceList::iterator iter;
2660     boost::shared_ptr<Region> region;
2661     uint32_t count;
2662
2663     RegionCounter() : count (0) {}
2664 };
2665
2666 int
2667 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2668 {
2669         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2670         return r.get_value_or (1);
2671 }
2672
2673 void
2674 Session::cleanup_regions ()
2675 {
2676         bool removed = false;
2677         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2678
2679         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2680
2681                 uint32_t used = playlists->region_use_count (i->second);
2682
2683                 if (used == 0 && !i->second->automatic ()) {
2684                         removed = true;
2685                         RegionFactory::map_remove (i->second);
2686                 }
2687         }
2688
2689         if (removed) {
2690                 // re-check to remove parent references of compound regions
2691                 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2692                         if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
2693                                 continue;
2694                         }
2695                         assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
2696                         if (0 == playlists->region_use_count (i->second)) {
2697                                 RegionFactory::map_remove (i->second);
2698                         }
2699                 }
2700         }
2701
2702         /* dump the history list */
2703         _history.clear ();
2704
2705         save_state ("");
2706 }
2707
2708 int
2709 Session::cleanup_sources (CleanupReport& rep)
2710 {
2711         // FIXME: needs adaptation to midi
2712
2713         vector<boost::shared_ptr<Source> > dead_sources;
2714         string audio_path;
2715         string midi_path;
2716         vector<string> candidates;
2717         vector<string> unused;
2718         set<string> all_sources;
2719         bool used;
2720         string spath;
2721         int ret = -1;
2722         string tmppath1;
2723         string tmppath2;
2724         Searchpath asp;
2725         Searchpath msp;
2726
2727         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2728
2729         /* consider deleting all unused playlists */
2730
2731         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2732                 ret = 0;
2733                 goto out;
2734         }
2735
2736         /* sync the "all regions" property of each playlist with its current state
2737          */
2738
2739         playlists->sync_all_regions_with_regions ();
2740
2741         /* find all un-used sources */
2742
2743         rep.paths.clear ();
2744         rep.space = 0;
2745
2746         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2747
2748                 SourceMap::iterator tmp;
2749
2750                 tmp = i;
2751                 ++tmp;
2752
2753                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2754                    capture files.
2755                 */
2756
2757                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2758                         dead_sources.push_back (i->second);
2759                         i->second->drop_references ();
2760                 }
2761
2762                 i = tmp;
2763         }
2764
2765         /* build a list of all the possible audio directories for the session */
2766
2767         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2768                 SessionDirectory sdir ((*i).path);
2769                 asp += sdir.sound_path();
2770         }
2771         audio_path += asp.to_string();
2772
2773
2774         /* build a list of all the possible midi directories for the session */
2775
2776         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2777                 SessionDirectory sdir ((*i).path);
2778                 msp += sdir.midi_path();
2779         }
2780         midi_path += msp.to_string();
2781
2782         find_files_matching_filter (candidates, audio_path, accept_all_audio_files, (void *) 0, true, true);
2783         find_files_matching_filter (candidates, midi_path, accept_all_midi_files, (void *) 0, true, true);
2784
2785         /* find all sources, but don't use this snapshot because the
2786            state file on disk still references sources we may have already
2787            dropped.
2788         */
2789
2790         find_all_sources_across_snapshots (all_sources, true);
2791
2792         /*  add our current source list
2793          */
2794
2795         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2796                 boost::shared_ptr<FileSource> fs;
2797                 SourceMap::iterator tmp = i;
2798                 ++tmp;
2799
2800                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2801
2802                         if (!fs->is_stub()) {
2803
2804                                 if (playlists->source_use_count (fs) != 0) {
2805                                         all_sources.insert (fs->path());
2806                                 } else {
2807                                         
2808                                         /* we might not remove this source from disk, because it may be used
2809                                            by other snapshots, but its not being used in this version
2810                                            so lets get rid of it now, along with any representative regions
2811                                            in the region list.
2812                                         */
2813                                         
2814                                         RegionFactory::remove_regions_using_source (i->second);
2815                                         sources.erase (i);
2816                                         
2817                                         // also remove source from all_sources
2818                                         
2819                                         for (set<string>::iterator j = all_sources.begin(); j != all_sources.end(); ++j) {
2820                                                 spath = Glib::path_get_basename (*j);
2821                                                 if ( spath == i->second->name () ) {
2822                                                         all_sources.erase (j);
2823                                                         break;
2824                                                 }
2825                                         }
2826                                 }
2827                         }
2828                 }
2829
2830                 i = tmp;
2831         }
2832
2833         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
2834
2835                 used = false;
2836                 spath = *x;
2837
2838                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2839
2840                         tmppath1 = canonical_path (spath);
2841                         tmppath2 = canonical_path ((*i));
2842
2843                         if (tmppath1 == tmppath2) {
2844                                 used = true;
2845                                 break;
2846                         }
2847                 }
2848
2849                 if (!used) {
2850                         unused.push_back (spath);
2851                 }
2852         }
2853
2854         /* now try to move all unused files into the "dead" directory(ies) */
2855
2856         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2857                 struct stat statbuf;
2858
2859                 string newpath;
2860
2861                 /* don't move the file across filesystems, just
2862                    stick it in the `dead_dir_name' directory
2863                    on whichever filesystem it was already on.
2864                 */
2865
2866                 if ((*x).find ("/sounds/") != string::npos) {
2867
2868                         /* old school, go up 1 level */
2869
2870                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2871                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2872
2873                 } else {
2874
2875                         /* new school, go up 4 levels */
2876
2877                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2878                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2879                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2880                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2881                 }
2882
2883                 newpath = Glib::build_filename (newpath, dead_dir_name);
2884
2885                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2886                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2887                         return -1;
2888                 }
2889
2890                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2891
2892                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2893
2894                         /* the new path already exists, try versioning */
2895
2896                         char buf[PATH_MAX+1];
2897                         int version = 1;
2898                         string newpath_v;
2899
2900                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2901                         newpath_v = buf;
2902
2903                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2904                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2905                                 newpath_v = buf;
2906                         }
2907
2908                         if (version == 999) {
2909                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2910                                                   newpath)
2911                                       << endmsg;
2912                         } else {
2913                                 newpath = newpath_v;
2914                         }
2915
2916                 } else {
2917
2918                         /* it doesn't exist, or we can't read it or something */
2919
2920                 }
2921
2922                 stat ((*x).c_str(), &statbuf);
2923
2924                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2925                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2926                                           (*x), newpath, strerror (errno))
2927                               << endmsg;
2928                         goto out;
2929                 }
2930
2931                 /* see if there an easy to find peakfile for this file, and remove it.
2932                  */
2933
2934                 string base = basename_nosuffix (*x);
2935                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2936                                  or for the first channel of embedded files. it will miss
2937                                  some peakfiles for other channels
2938                               */
2939                 string peakpath = peak_path (base);
2940
2941                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2942                         if (::g_unlink (peakpath.c_str()) != 0) {
2943                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2944                                                          peakpath, _path, strerror (errno))
2945                                       << endmsg;
2946                                 /* try to back out */
2947                                 ::rename (newpath.c_str(), _path.c_str());
2948                                 goto out;
2949                         }
2950                 }
2951
2952                 rep.paths.push_back (*x);
2953                 rep.space += statbuf.st_size;
2954         }
2955
2956         /* dump the history list */
2957
2958         _history.clear ();
2959
2960         /* save state so we don't end up a session file
2961            referring to non-existent sources.
2962         */
2963
2964         save_state ("");
2965         ret = 0;
2966
2967   out:
2968         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2969
2970         return ret;
2971 }
2972
2973 int
2974 Session::cleanup_trash_sources (CleanupReport& rep)
2975 {
2976         // FIXME: needs adaptation for MIDI
2977
2978         vector<space_and_path>::iterator i;
2979         string dead_dir;
2980
2981         rep.paths.clear ();
2982         rep.space = 0;
2983
2984         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2985
2986                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2987
2988                 clear_directory (dead_dir, &rep.space, &rep.paths);
2989         }
2990
2991         return 0;
2992 }
2993
2994 void
2995 Session::set_dirty ()
2996 {
2997         /* never mark session dirty during loading */
2998
2999         if (_state_of_the_state & Loading) {
3000                 return;
3001         }
3002
3003         bool was_dirty = dirty();
3004
3005         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3006
3007
3008         if (!was_dirty) {
3009                 DirtyChanged(); /* EMIT SIGNAL */
3010         }
3011 }
3012
3013
3014 void
3015 Session::set_clean ()
3016 {
3017         bool was_dirty = dirty();
3018
3019         _state_of_the_state = Clean;
3020
3021
3022         if (was_dirty) {
3023                 DirtyChanged(); /* EMIT SIGNAL */
3024         }
3025 }
3026
3027 void
3028 Session::set_deletion_in_progress ()
3029 {
3030         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3031 }
3032
3033 void
3034 Session::clear_deletion_in_progress ()
3035 {
3036         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3037 }
3038
3039 void
3040 Session::add_controllable (boost::shared_ptr<Controllable> c)
3041 {
3042         /* this adds a controllable to the list managed by the Session.
3043            this is a subset of those managed by the Controllable class
3044            itself, and represents the only ones whose state will be saved
3045            as part of the session.
3046         */
3047
3048         Glib::Threads::Mutex::Lock lm (controllables_lock);
3049         controllables.insert (c);
3050 }
3051
3052 struct null_deleter { void operator()(void const *) const {} };
3053
3054 void
3055 Session::remove_controllable (Controllable* c)
3056 {
3057         if (_state_of_the_state & Deletion) {
3058                 return;
3059         }
3060
3061         Glib::Threads::Mutex::Lock lm (controllables_lock);
3062
3063         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3064
3065         if (x != controllables.end()) {
3066                 controllables.erase (x);
3067         }
3068 }
3069
3070 boost::shared_ptr<Controllable>
3071 Session::controllable_by_id (const PBD::ID& id)
3072 {
3073         Glib::Threads::Mutex::Lock lm (controllables_lock);
3074
3075         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3076                 if ((*i)->id() == id) {
3077                         return *i;
3078                 }
3079         }
3080
3081         return boost::shared_ptr<Controllable>();
3082 }
3083
3084 boost::shared_ptr<Controllable>
3085 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3086 {
3087         boost::shared_ptr<Controllable> c;
3088         boost::shared_ptr<Route> r;
3089
3090         switch (desc.top_level_type()) {
3091         case ControllableDescriptor::NamedRoute:
3092         {
3093                 std::string str = desc.top_level_name();
3094                 if (str == "Master" || str == "master") {
3095                         r = _master_out;
3096                 } else if (str == "control" || str == "listen") {
3097                         r = _monitor_out;
3098                 } else {
3099                         r = route_by_name (desc.top_level_name());
3100                 }
3101                 break;
3102         }
3103
3104         case ControllableDescriptor::RemoteControlID:
3105                 r = route_by_remote_id (desc.rid());
3106                 break;
3107         }
3108
3109         if (!r) {
3110                 return c;
3111         }
3112
3113         switch (desc.subtype()) {
3114         case ControllableDescriptor::Gain:
3115                 c = r->gain_control ();
3116                 break;
3117
3118         case ControllableDescriptor::Trim:
3119                 c = r->trim()->gain_control ();
3120                 break;
3121
3122         case ControllableDescriptor::Solo:
3123                 c = r->solo_control();
3124                 break;
3125
3126         case ControllableDescriptor::Mute:
3127                 c = r->mute_control();
3128                 break;
3129
3130         case ControllableDescriptor::Recenable:
3131         {
3132                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3133
3134                 if (t) {
3135                         c = t->rec_enable_control ();
3136                 }
3137                 break;
3138         }
3139
3140         case ControllableDescriptor::PanDirection:
3141         {
3142                 c = r->pannable()->pan_azimuth_control;
3143                 break;
3144         }
3145
3146         case ControllableDescriptor::PanWidth:
3147         {
3148                 c = r->pannable()->pan_width_control;
3149                 break;
3150         }
3151
3152         case ControllableDescriptor::PanElevation:
3153         {
3154                 c = r->pannable()->pan_elevation_control;
3155                 break;
3156         }
3157
3158         case ControllableDescriptor::Balance:
3159                 /* XXX simple pan control */
3160                 break;
3161
3162         case ControllableDescriptor::PluginParameter:
3163         {
3164                 uint32_t plugin = desc.target (0);
3165                 uint32_t parameter_index = desc.target (1);
3166
3167                 /* revert to zero based counting */
3168
3169                 if (plugin > 0) {
3170                         --plugin;
3171                 }
3172
3173                 if (parameter_index > 0) {
3174                         --parameter_index;
3175                 }
3176
3177                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3178
3179                 if (p) {
3180                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3181                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3182                 }
3183                 break;
3184         }
3185
3186         case ControllableDescriptor::SendGain:
3187         {
3188                 uint32_t send = desc.target (0);
3189
3190                 /* revert to zero-based counting */
3191
3192                 if (send > 0) {
3193                         --send;
3194                 }
3195
3196                 boost::shared_ptr<Processor> p = r->nth_send (send);
3197
3198                 if (p) {
3199                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3200                         boost::shared_ptr<Amp> a = s->amp();
3201                         
3202                         if (a) {
3203                                 c = s->amp()->gain_control();
3204                         }
3205                 }
3206                 break;
3207         }
3208
3209         default:
3210                 /* relax and return a null pointer */
3211                 break;
3212         }
3213
3214         return c;
3215 }
3216
3217 void
3218 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3219 {
3220         if (_writable) {
3221                 Stateful::add_instant_xml (node, _path);
3222         }
3223
3224         if (write_to_config) {
3225                 Config->add_instant_xml (node);
3226         }
3227 }
3228
3229 XMLNode*
3230 Session::instant_xml (const string& node_name)
3231 {
3232         return Stateful::instant_xml (node_name, _path);
3233 }
3234
3235 int
3236 Session::save_history (string snapshot_name)
3237 {
3238         XMLTree tree;
3239
3240         if (!_writable) {
3241                 return 0;
3242         }
3243
3244         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 || 
3245             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3246                 return 0;
3247         }
3248
3249         if (snapshot_name.empty()) {
3250                 snapshot_name = _current_snapshot_name;
3251         }
3252
3253         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3254         const string backup_filename = history_filename + backup_suffix;
3255         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3256         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3257
3258         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3259                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3260                         error << _("could not backup old history file, current history not saved") << endmsg;
3261                         return -1;
3262                 }
3263         }
3264
3265         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3266
3267         if (!tree.write (xml_path))
3268         {
3269                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3270
3271                 if (g_remove (xml_path.c_str()) != 0) {
3272                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3273                                         xml_path, g_strerror (errno)) << endmsg;
3274                 }
3275                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3276                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3277                                         backup_path, g_strerror (errno)) << endmsg;
3278                 }
3279
3280                 return -1;
3281         }
3282
3283         return 0;
3284 }
3285
3286 int
3287 Session::restore_history (string snapshot_name)
3288 {
3289         XMLTree tree;
3290
3291         if (snapshot_name.empty()) {
3292                 snapshot_name = _current_snapshot_name;
3293         }
3294
3295         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3296         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3297
3298         info << "Loading history from " << xml_path << endmsg;
3299
3300         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3301                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3302                                 _name, xml_path) << endmsg;
3303                 return 1;
3304         }
3305
3306         if (!tree.read (xml_path)) {
3307                 error << string_compose (_("Could not understand session history file \"%1\""),
3308                                 xml_path) << endmsg;
3309                 return -1;
3310         }
3311
3312         // replace history
3313         _history.clear();
3314
3315         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3316
3317                 XMLNode *t = *it;
3318                 UndoTransaction* ut = new UndoTransaction ();
3319                 struct timeval tv;
3320
3321                 ut->set_name(t->property("name")->value());
3322                 stringstream ss(t->property("tv-sec")->value());
3323                 ss >> tv.tv_sec;
3324                 ss.str(t->property("tv-usec")->value());
3325                 ss >> tv.tv_usec;
3326                 ut->set_timestamp(tv);
3327
3328                 for (XMLNodeConstIterator child_it  = t->children().begin();
3329                                 child_it != t->children().end(); child_it++)
3330                 {
3331                         XMLNode *n = *child_it;
3332                         Command *c;
3333
3334                         if (n->name() == "MementoCommand" ||
3335                                         n->name() == "MementoUndoCommand" ||
3336                                         n->name() == "MementoRedoCommand") {
3337
3338                                 if ((c = memento_command_factory(n))) {
3339                                         ut->add_command(c);
3340                                 }
3341
3342                         } else if (n->name() == "NoteDiffCommand") {
3343                                 PBD::ID id (n->property("midi-source")->value());
3344                                 boost::shared_ptr<MidiSource> midi_source =
3345                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3346                                 if (midi_source) {
3347                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3348                                 } else {
3349                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3350                                 }
3351
3352                         } else if (n->name() == "SysExDiffCommand") {
3353
3354                                 PBD::ID id (n->property("midi-source")->value());
3355                                 boost::shared_ptr<MidiSource> midi_source =
3356                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3357                                 if (midi_source) {
3358                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3359                                 } else {
3360                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3361                                 }
3362
3363                         } else if (n->name() == "PatchChangeDiffCommand") {
3364
3365                                 PBD::ID id (n->property("midi-source")->value());
3366                                 boost::shared_ptr<MidiSource> midi_source =
3367                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3368                                 if (midi_source) {
3369                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3370                                 } else {
3371                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3372                                 }
3373
3374                         } else if (n->name() == "StatefulDiffCommand") {
3375                                 if ((c = stateful_diff_command_factory (n))) {
3376                                         ut->add_command (c);
3377                                 }
3378                         } else {
3379                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3380                         }
3381                 }
3382
3383                 _history.add (ut);
3384         }
3385
3386         return 0;
3387 }
3388
3389 void
3390 Session::config_changed (std::string p, bool ours)
3391 {
3392         if (ours) {
3393                 set_dirty ();
3394         }
3395
3396         if (p == "seamless-loop") {
3397
3398         } else if (p == "rf-speed") {
3399
3400         } else if (p == "auto-loop") {
3401
3402         } else if (p == "auto-input") {
3403
3404                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3405                         /* auto-input only makes a difference if we're rolling */
3406                         set_track_monitor_input_status (!config.get_auto_input());
3407                 }
3408
3409         } else if (p == "punch-in") {
3410
3411                 Location* location;
3412
3413                 if ((location = _locations->auto_punch_location()) != 0) {
3414
3415                         if (config.get_punch_in ()) {
3416                                 replace_event (SessionEvent::PunchIn, location->start());
3417                         } else {
3418                                 remove_event (location->start(), SessionEvent::PunchIn);
3419                         }
3420                 }
3421
3422         } else if (p == "punch-out") {
3423
3424                 Location* location;
3425
3426                 if ((location = _locations->auto_punch_location()) != 0) {
3427
3428                         if (config.get_punch_out()) {
3429                                 replace_event (SessionEvent::PunchOut, location->end());
3430                         } else {
3431                                 clear_events (SessionEvent::PunchOut);
3432                         }
3433                 }
3434
3435         } else if (p == "edit-mode") {
3436
3437                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3438
3439                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3440                         (*i)->set_edit_mode (Config->get_edit_mode ());
3441                 }
3442
3443         } else if (p == "use-video-sync") {
3444
3445                 waiting_for_sync_offset = config.get_use_video_sync();
3446
3447         } else if (p == "mmc-control") {
3448
3449                 //poke_midi_thread ();
3450
3451         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3452
3453                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3454
3455         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3456
3457                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3458
3459         } else if (p == "midi-control") {
3460
3461                 //poke_midi_thread ();
3462
3463         } else if (p == "raid-path") {
3464
3465                 setup_raid_path (config.get_raid_path());
3466
3467         } else if (p == "timecode-format") {
3468
3469                 sync_time_vars ();
3470
3471         } else if (p == "video-pullup") {
3472
3473                 sync_time_vars ();
3474
3475         } else if (p == "seamless-loop") {
3476
3477                 if (play_loop && transport_rolling()) {
3478                         // to reset diskstreams etc
3479                         request_play_loop (true);
3480                 }
3481
3482         } else if (p == "rf-speed") {
3483
3484                 cumulative_rf_motion = 0;
3485                 reset_rf_scale (0);
3486
3487         } else if (p == "click-sound") {
3488
3489                 setup_click_sounds (1);
3490
3491         } else if (p == "click-emphasis-sound") {
3492
3493                 setup_click_sounds (-1);
3494
3495         } else if (p == "clicking") {
3496
3497                 if (Config->get_clicking()) {
3498                         if (_click_io && click_data) { // don't require emphasis data
3499                                 _clicking = true;
3500                         }
3501                 } else {
3502                         _clicking = false;
3503                 }
3504
3505         } else if (p == "click-gain") {
3506                 
3507                 if (_click_gain) {
3508                         _click_gain->set_gain (Config->get_click_gain(), this);
3509                 }
3510
3511         } else if (p == "send-mtc") {
3512
3513                 if (Config->get_send_mtc ()) {
3514                         /* mark us ready to send */
3515                         next_quarter_frame_to_send = 0;
3516                 }
3517
3518         } else if (p == "send-mmc") {
3519
3520                 _mmc->enable_send (Config->get_send_mmc ());
3521
3522         } else if (p == "midi-feedback") {
3523
3524                 session_midi_feedback = Config->get_midi_feedback();
3525
3526         } else if (p == "jack-time-master") {
3527
3528                 engine().reset_timebase ();
3529
3530         } else if (p == "native-file-header-format") {
3531
3532                 if (!first_file_header_format_reset) {
3533                         reset_native_file_format ();
3534                 }
3535
3536                 first_file_header_format_reset = false;
3537
3538         } else if (p == "native-file-data-format") {
3539
3540                 if (!first_file_data_format_reset) {
3541                         reset_native_file_format ();
3542                 }
3543
3544                 first_file_data_format_reset = false;
3545
3546         } else if (p == "external-sync") {
3547                 if (!config.get_external_sync()) {
3548                         drop_sync_source ();
3549                 } else {
3550                         switch_to_sync_source (Config->get_sync_source());
3551                 }
3552         }  else if (p == "denormal-model") {
3553                 setup_fpu ();
3554         } else if (p == "history-depth") {
3555                 set_history_depth (Config->get_history_depth());
3556         } else if (p == "remote-model") {
3557                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3558                    TO SET REMOTE ID'S
3559                 */
3560         } else if (p == "initial-program-change") {
3561
3562                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3563                         MIDI::byte buf[2];
3564
3565                         buf[0] = MIDI::program; // channel zero by default
3566                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3567
3568                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3569                 }
3570         } else if (p == "solo-mute-override") {
3571                 // catch_up_on_solo_mute_override ();
3572         } else if (p == "listen-position" || p == "pfl-position") {
3573                 listen_position_changed ();
3574         } else if (p == "solo-control-is-listen-control") {
3575                 solo_control_mode_changed ();
3576         } else if (p == "solo-mute-gain") {
3577                 _solo_cut_control->Changed();
3578         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3579                 last_timecode_valid = false;
3580         } else if (p == "playback-buffer-seconds") {
3581                 AudioSource::allocate_working_buffers (frame_rate());
3582         } else if (p == "ltc-source-port") {
3583                 reconnect_ltc_input ();
3584         } else if (p == "ltc-sink-port") {
3585                 reconnect_ltc_output ();
3586         } else if (p == "timecode-generator-offset") {
3587                 ltc_tx_parse_offset();
3588         }
3589
3590         set_dirty ();
3591 }
3592
3593 void
3594 Session::set_history_depth (uint32_t d)
3595 {
3596         _history.set_depth (d);
3597 }
3598
3599 int
3600 Session::load_diskstreams_2X (XMLNode const & node, int)
3601 {
3602         XMLNodeList          clist;
3603         XMLNodeConstIterator citer;
3604
3605         clist = node.children();
3606
3607         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3608
3609                 try {
3610                         /* diskstreams added automatically by DiskstreamCreated handler */
3611                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3612                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3613                                 _diskstreams_2X.push_back (dsp);
3614                         } else {
3615                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3616                         }
3617                 }
3618
3619                 catch (failed_constructor& err) {
3620                         error << _("Session: could not load diskstream via XML state") << endmsg;
3621                         return -1;
3622                 }
3623         }
3624
3625         return 0;
3626 }
3627
3628 /** Connect things to the MMC object */
3629 void
3630 Session::setup_midi_machine_control ()
3631 {
3632         _mmc = new MIDI::MachineControl;
3633         _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3634
3635         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3636         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3637         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3638         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3639         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3640         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3641         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3642         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3643         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3644         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3645         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3646         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3647         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3648
3649         /* also handle MIDI SPP because its so common */
3650
3651         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3652         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3653         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3654 }
3655
3656 boost::shared_ptr<Controllable>
3657 Session::solo_cut_control() const
3658 {
3659         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3660            controls in Ardour that currently get presented to the user in the GUI that require
3661            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3662
3663            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3664            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3665            parameter.
3666         */
3667
3668         return _solo_cut_control;
3669 }
3670
3671 int
3672 Session::rename (const std::string& new_name)
3673 {
3674         string legal_name = legalize_for_path (new_name);
3675         string new_path;
3676         string oldstr;
3677         string newstr;
3678         bool first = true;
3679
3680         string const old_sources_root = _session_dir->sources_root();
3681
3682         if (!_writable || (_state_of_the_state & CannotSave)) {
3683                 error << _("Cannot rename read-only session.") << endmsg;
3684                 return 0; // don't show "messed up" warning
3685         }
3686         if (record_status() == Recording) {
3687                 error << _("Cannot rename session while recording") << endmsg;
3688                 return 0; // don't show "messed up" warning
3689         }
3690
3691         StateProtector stp (this);
3692
3693         /* Rename:
3694
3695          * session directory
3696          * interchange subdirectory
3697          * session file
3698          * session history
3699          
3700          * Backup files are left unchanged and not renamed.
3701          */
3702
3703         /* Windows requires that we close all files before attempting the
3704          * rename. This works on other platforms, but isn't necessary there.
3705          * Leave it in place for all platforms though, since it may help
3706          * catch issues that could arise if the way Source files work ever
3707          * change (since most developers are not using Windows).
3708          */
3709
3710         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3711                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3712                 if (fs) {
3713                         fs->close ();
3714                 }
3715         }
3716         
3717         /* pass one: not 100% safe check that the new directory names don't
3718          * already exist ...
3719          */
3720
3721         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3722                 
3723                 oldstr = (*i).path;
3724                 
3725                 /* this is a stupid hack because Glib::path_get_dirname() is
3726                  * lexical-only, and so passing it /a/b/c/ gives a different
3727                  * result than passing it /a/b/c ...
3728                  */
3729                 
3730                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3731                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3732                 }
3733                 
3734                 string base = Glib::path_get_dirname (oldstr);
3735                 
3736                 newstr = Glib::build_filename (base, legal_name);
3737                 
3738                 cerr << "Looking for " << newstr << endl;
3739                 
3740                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3741                         cerr << " exists\n";
3742                         return -1;
3743                 }
3744         }
3745
3746         /* Session dirs */
3747
3748         first = true;
3749         
3750         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3751
3752                 vector<string> v;
3753
3754                 oldstr = (*i).path;
3755                 
3756                 /* this is a stupid hack because Glib::path_get_dirname() is
3757                  * lexical-only, and so passing it /a/b/c/ gives a different
3758                  * result than passing it /a/b/c ...
3759                  */
3760                 
3761                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3762                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3763                 }
3764
3765                 string base = Glib::path_get_dirname (oldstr);
3766                 newstr = Glib::build_filename (base, legal_name);
3767
3768                 cerr << "for " << oldstr << " new dir = " << newstr << endl;
3769                 
3770                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3771                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3772                         cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3773                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3774                         return 1;
3775                 }
3776
3777                 /* Reset path in "session dirs" */
3778                 
3779                 (*i).path = newstr;
3780                 (*i).blocks = 0;
3781                 
3782                 /* reset primary SessionDirectory object */
3783                 
3784                 if (first) {
3785                         (*_session_dir) = newstr;
3786                         new_path = newstr;
3787                         first = false;
3788                 }
3789
3790                 /* now rename directory below session_dir/interchange */
3791
3792                 string old_interchange_dir;
3793                 string new_interchange_dir;
3794
3795                 /* use newstr here because we renamed the path
3796                  * (folder/directory) that used to be oldstr to newstr above 
3797                  */     
3798                 
3799                 v.push_back (newstr); 
3800                 v.push_back (interchange_dir_name);
3801                 v.push_back (Glib::path_get_basename (oldstr));
3802
3803                 old_interchange_dir = Glib::build_filename (v);
3804
3805                 v.clear ();
3806                 v.push_back (newstr);
3807                 v.push_back (interchange_dir_name);
3808                 v.push_back (legal_name);
3809                 
3810                 new_interchange_dir = Glib::build_filename (v);
3811                 
3812                 cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
3813                 
3814                 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
3815                         cerr << string_compose (_("renaming %s as %2 failed (%3)"),
3816                                                  old_interchange_dir, new_interchange_dir,
3817                                                  g_strerror (errno))
3818                               << endl;
3819                         error << string_compose (_("renaming %s as %2 failed (%3)"),
3820                                                  old_interchange_dir, new_interchange_dir,
3821                                                  g_strerror (errno))
3822                               << endmsg;
3823                         return 1;
3824                 }
3825         }
3826
3827         /* state file */
3828         
3829         oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
3830         newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
3831         
3832         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3833
3834         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3835                 cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3836                 error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3837                 return 1;
3838         }
3839
3840         /* history file */
3841         
3842         oldstr = Glib::build_filename (new_path, _current_snapshot_name) + history_suffix;
3843
3844         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3845                 newstr = Glib::build_filename (new_path, legal_name) + history_suffix;
3846                 
3847                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3848                 
3849                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3850                         cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3851                         error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3852                         return 1;
3853                 }
3854         }
3855
3856         /* remove old name from recent sessions */
3857         remove_recent_sessions (_path);
3858         _path = new_path;
3859         
3860         /* update file source paths */
3861         
3862         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3863                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3864                 if (fs) {
3865                         string p = fs->path ();
3866                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3867                         fs->set_path (p);
3868                         SourceFactory::setup_peakfile(i->second, true);
3869                 }
3870         }
3871
3872         _current_snapshot_name = new_name;
3873         _name = new_name;
3874         
3875         set_dirty ();
3876
3877         /* save state again to get everything just right */
3878
3879         save_state (_current_snapshot_name);
3880
3881         /* add to recent sessions */
3882
3883         store_recent_sessions (new_name, _path);
3884
3885         return 0;
3886 }
3887
3888 int
3889 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3890 {
3891         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3892                 return -1;
3893         }
3894
3895         if (!tree.read (xmlpath)) {
3896                 return -1;
3897         }
3898
3899         return 0;
3900 }
3901
3902 int
3903 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3904 {
3905         XMLTree tree;
3906         bool found_sr = false;
3907         bool found_data_format = false;
3908
3909         if (get_session_info_from_path (tree, xmlpath)) {
3910                 return -1;
3911         }
3912
3913         /* sample rate */
3914
3915         const XMLProperty* prop;
3916         if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
3917                 sample_rate = atoi (prop->value());
3918                 found_sr = true;
3919         }
3920
3921         const XMLNodeList& children (tree.root()->children());
3922         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3923                 const XMLNode* child = *c;
3924                 if (child->name() == "Config") {
3925                         const XMLNodeList& options (child->children());
3926                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3927                                 const XMLNode* option = *oc;
3928                                 const XMLProperty* name = option->property("name");
3929
3930                                 if (!name) {
3931                                         continue;
3932                                 }
3933
3934                                 if (name->value() == "native-file-data-format") {
3935                                         const XMLProperty* value = option->property ("value");
3936                                         if (value) {
3937                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3938                                                 data_format = fmt;
3939                                                 found_data_format = true;
3940                                                 break;
3941                                         }
3942                                 }
3943                         }
3944                 }
3945                 if (found_data_format) {
3946                         break;
3947                 }
3948         }
3949
3950         return !(found_sr && found_data_format); // zero if they are both found
3951 }
3952
3953 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
3954 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
3955
3956 int
3957 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
3958 {
3959         uint32_t total = 0;
3960         uint32_t n = 0;
3961         SourcePathMap source_path_map;
3962         string new_path;
3963         boost::shared_ptr<AudioFileSource> afs;
3964         int ret = 0;
3965
3966         {
3967
3968                 Glib::Threads::Mutex::Lock lm (source_lock);
3969                 
3970                 cerr << " total sources = " << sources.size();
3971                 
3972                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3973                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3974                         
3975                         if (!fs) {
3976                                 continue;
3977                         }
3978                         
3979                         if (fs->within_session()) {
3980                                 continue;
3981                         }
3982                         
3983                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
3984                                 source_path_map[fs->path()].push_back (fs);
3985                         } else {
3986                                 SeveralFileSources v;
3987                                 v.push_back (fs);
3988                                 source_path_map.insert (make_pair (fs->path(), v));
3989                         }
3990                         
3991                         total++;
3992                 }
3993                 
3994                 cerr << " fsources = " << total << endl;
3995                 
3996                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
3997                         
3998                         /* tell caller where we are */
3999                         
4000                         string old_path = i->first;
4001                         
4002                         callback (n, total, old_path);
4003                         
4004                         cerr << old_path << endl;
4005                         
4006                         new_path.clear ();
4007                         
4008                         switch (i->second.front()->type()) {
4009                         case DataType::AUDIO:
4010                                 new_path = new_audio_source_path_for_embedded (old_path);
4011                                 break;
4012                                 
4013                         case DataType::MIDI:
4014                                 /* XXX not implemented yet */
4015                                 break;
4016                         }
4017                         
4018                         if (new_path.empty()) {
4019                                 continue;
4020                         }
4021                         
4022                         cerr << "Move " << old_path << " => " << new_path << endl;
4023                         
4024                         if (!copy_file (old_path, new_path)) {
4025                                 cerr << "failed !\n";
4026                                 ret = -1;
4027                         }
4028                         
4029                         /* make sure we stop looking in the external
4030                            dir/folder. Remember, this is an all-or-nothing
4031                            operations, it doesn't merge just some files.
4032                         */
4033                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
4034
4035                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
4036                                 (*f)->set_path (new_path);
4037                         }
4038                 }
4039         }
4040
4041         save_state ("", false, false);
4042
4043         return ret;
4044 }
4045
4046 static
4047 bool accept_all_files (string const &, void *)
4048 {
4049         return true;
4050 }
4051
4052 void
4053 Session::save_as_bring_callback (uint32_t,uint32_t,string)
4054 {
4055         /* 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.
4056         */
4057 }
4058
4059 static string
4060 make_new_media_path (string old_path, string new_session_folder, string new_session_path)
4061 {
4062         /* typedir is the "midifiles" or "audiofiles" etc. part of the path. */
4063
4064         string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4065         vector<string> v;
4066         v.push_back (new_session_folder); /* full path */
4067         v.push_back (interchange_dir_name);
4068         v.push_back (new_session_path);   /* just one directory/folder */
4069         v.push_back (typedir);
4070         v.push_back (Glib::path_get_basename (old_path));
4071         
4072         return Glib::build_filename (v);
4073 }
4074
4075 int
4076 Session::save_as (SaveAs& saveas)
4077 {
4078         vector<string> files;
4079         string current_folder = Glib::path_get_dirname (_path);
4080         string new_folder = legalize_for_path (saveas.new_name);
4081         string to_dir = Glib::build_filename (saveas.new_parent_folder, new_folder);
4082         int64_t total_bytes = 0;
4083         int64_t copied = 0;
4084         int64_t cnt = 0;
4085         int64_t all = 0;
4086         int32_t internal_file_cnt = 0;
4087
4088         vector<string> do_not_copy_extensions;
4089         do_not_copy_extensions.push_back (statefile_suffix);
4090         do_not_copy_extensions.push_back (pending_suffix);
4091         do_not_copy_extensions.push_back (backup_suffix);
4092         do_not_copy_extensions.push_back (temp_suffix);
4093         do_not_copy_extensions.push_back (history_suffix);
4094
4095         /* get total size */
4096
4097         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4098                 
4099                 /* need to clear this because
4100                  * find_files_matching_filter() is cumulative
4101                  */
4102                 
4103                 files.clear ();
4104                 
4105                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4106                 
4107                 all += files.size();
4108
4109                 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4110                         GStatBuf gsb;
4111                         g_stat ((*i).c_str(), &gsb);
4112                         total_bytes += gsb.st_size;
4113                 }
4114         }
4115
4116         /* save old values so we can switch back if we are not switching to the new session */
4117         
4118         string old_path = _path;
4119         string old_name = _name;
4120         string old_snapshot = _current_snapshot_name;
4121         string old_sd = _session_dir->root_path();
4122         vector<string> old_search_path[DataType::num_types];
4123         string old_config_search_path[DataType::num_types];
4124
4125         old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4126         old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4127         old_config_search_path[DataType::AUDIO]  = config.get_audio_search_path ();     
4128         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();       
4129
4130         /* switch session directory */
4131         
4132         (*_session_dir) = to_dir;
4133
4134         /* create new tree */
4135         
4136         if (!_session_dir->create()) {
4137                 saveas.failure_message = string_compose (_("Cannot create new session folder %1"), to_dir);
4138                 return -1;
4139         }
4140
4141         try {
4142                 /* copy all relevant files. Find each location in session_dirs,
4143                  * and copy files from there to target.
4144                  */
4145                 
4146                 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4147                         
4148                         /* need to clear this because
4149                          * find_files_matching_filter() is cumulative
4150                          */
4151                         
4152                         files.clear ();
4153                         
4154                         const size_t prefix_len = (*sd).path.size();
4155                         
4156                         /* Work just on the files within this session dir */
4157                         
4158                         find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4159                         
4160                         /* add dir separator to protect against collisions with
4161                          * track names (e.g. track named "audiofiles" or
4162                          * "analysis".
4163                          */
4164
4165                         static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
4166                         static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
4167                         static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
4168
4169                         /* copy all the files. Handling is different for media files
4170                            than others because of the *silly* subtree we have below the interchange
4171                            folder. That really was a bad idea, but I'm not fixing it as part of
4172                            implementing ::save_as().
4173                         */
4174                         
4175                         for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4176
4177                                 std::string from = *i;
4178
4179                                 if ((*i).find (audiofile_dir_string) != string::npos) {
4180                                         
4181                                         /* audio file: only copy if asked */
4182
4183                                         if (saveas.include_media && saveas.copy_media) {
4184                                                 
4185                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4186
4187                                                 info << "media file copying from " << from << " to " << to << endmsg;
4188                                                 
4189                                                 if (!copy_file (from, to)) {
4190                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4191                                                 }
4192                                         }
4193                                         
4194                                         /* we found media files inside the session folder */
4195                                         
4196                                         internal_file_cnt++;
4197
4198                                 } else if ((*i).find (midifile_dir_string) != string::npos) {
4199
4200                                         /* midi file: always copy unless
4201                                          * creating an empty new session
4202                                          */
4203
4204                                         if (saveas.include_media) {
4205                                         
4206                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4207                                                 
4208                                                 info << "media file copying from " << from << " to " << to << endmsg;
4209                                                 
4210                                                 if (!copy_file (from, to)) {
4211                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4212                                                 }
4213                                         }
4214
4215                                         /* we found media files inside the session folder */
4216                                                 
4217                                         internal_file_cnt++;
4218                                         
4219                                 } else if ((*i).find (analysis_dir_string) != string::npos) {
4220
4221                                         /*  make sure analysis dir exists in
4222                                          *  new session folder, but we're not
4223                                          *  copying analysis files here, see
4224                                          *  below 
4225                                          */
4226                                         
4227                                         (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
4228                                         continue;
4229                                         
4230                                 } else {
4231                                         
4232                                         /* normal non-media file. Don't copy state, history, etc.
4233                                          */
4234                                         
4235                                         bool do_copy = true;
4236                                         
4237                                         for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4238                                                 if (((*i).length() > (*v).length()) && ((*i).find (*v) == (*i).length() - (*v).length())) {
4239                                                         /* end of filename matches extension, do not copy file */
4240                                                         do_copy = false;
4241                                                         break;
4242                                                 } 
4243                                         }
4244
4245                                         if (!saveas.copy_media && (*i).find (peakfile_suffix) != string::npos) {
4246                                                 /* don't copy peakfiles if
4247                                                  * we're not copying media
4248                                                  */
4249                                                 do_copy = false;
4250                                         }
4251                                         
4252                                         if (do_copy) {
4253                                                 string to = Glib::build_filename (to_dir, (*i).substr (prefix_len));
4254                                                 
4255                                                 info << "attempting to make directory/folder " << to << endmsg;
4256
4257                                                 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4258                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
4259                                                 }
4260
4261                                                 info << "attempting to copy " << from << " to " << to << endmsg;
4262                                                 
4263                                                 if (!copy_file (from, to)) {
4264                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4265                                                 }
4266                                         }
4267                                 }
4268                                 
4269                                 /* measure file size even if we're not going to copy so that our Progress
4270                                    signals are correct, since we included these do-not-copy files
4271                                    in the computation of the total size and file count.
4272                                 */
4273                                 
4274                                 GStatBuf gsb;
4275                                 g_stat ((*i).c_str(), &gsb);
4276                                 copied += gsb.st_size;
4277                                 cnt++;
4278                                 
4279                                 double fraction = (double) copied / total_bytes;
4280                                 
4281                                 bool keep_going = true;
4282
4283                                 if (saveas.copy_media) {
4284
4285                                         /* no need or expectation of this if
4286                                          * media is not being copied, because
4287                                          * it will be fast(ish).
4288                                          */
4289                                         
4290                                         /* tell someone "X percent, file M of N"; M is one-based */
4291                                         
4292                                         boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
4293                                         
4294                                         if (res) {
4295                                                 keep_going = *res;
4296                                         }
4297                                 }
4298
4299                                 if (!keep_going) {
4300                                         throw Glib::FileError (Glib::FileError::FAILED, "copy cancelled");
4301                                 }
4302                         }
4303
4304                 }
4305
4306                 /* copy optional folders, if any */
4307
4308                 string old = plugins_dir ();
4309                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4310                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4311                         copy_files (old, newdir);
4312                 }
4313
4314                 old = externals_dir ();
4315                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4316                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4317                         copy_files (old, newdir);
4318                 }
4319
4320                 old = automation_dir ();
4321                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4322                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4323                         copy_files (old, newdir);
4324                 }
4325
4326                 if (saveas.include_media) {
4327                 
4328                         if (saveas.copy_media) {
4329 #ifndef PLATFORM_WINDOWS
4330                                 /* There are problems with analysis files on
4331                                  * Windows, because they used a colon in their
4332                                  * names as late as 4.0. Colons are not legal
4333                                  * under Windows even if NTFS allows them.
4334                                  *
4335                                  * This is a tricky problem to solve so for
4336                                  * just don't copy these files. They will be
4337                                  * regenerated as-needed anyway, subject to the 
4338                                  * existing issue that the filenames will be
4339                                  * rejected by Windows, which is a separate
4340                                  * problem (though related).
4341                                  */
4342
4343                                 /* only needed if we are copying media, since the
4344                                  * analysis data refers to media data
4345                                  */
4346                                 
4347                                 old = analysis_dir ();
4348                                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4349                                         string newdir = Glib::build_filename (to_dir, "analysis");
4350                                         copy_files (old, newdir);
4351                                 }
4352 #endif /* PLATFORM_WINDOWS */                           
4353                         }
4354                 }
4355                         
4356                 
4357                 _path = to_dir;
4358                 _current_snapshot_name = saveas.new_name;
4359                 _name = saveas.new_name;
4360
4361                 if (saveas.include_media && !saveas.copy_media) {
4362
4363                         /* reset search paths of the new session (which we're pretending to be right now) to
4364                            include the original session search path, so we can still find all audio.
4365                         */
4366
4367                         if (internal_file_cnt) {
4368                                 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
4369                                         ensure_search_path_includes (*s, DataType::AUDIO);
4370                                 }
4371
4372                                 /* we do not do this for MIDI because we copy
4373                                    all MIDI files if saveas.include_media is
4374                                    true
4375                                 */
4376                         }
4377                 }
4378                 
4379                 bool was_dirty = dirty ();
4380
4381                 save_state ("", false, false, !saveas.include_media);
4382                 save_default_options ();
4383                 
4384                 if (saveas.copy_media && saveas.copy_external) {
4385                         if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback, this, _1, _2, _3))) {
4386                                 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT, "consolidate failed");
4387                         }
4388                 }
4389
4390                 saveas.final_session_folder_name = _path;
4391                 
4392                 if (!saveas.switch_to) {
4393
4394                         /* switch back to the way things were */
4395
4396                         _path = old_path;
4397                         _name = old_name;
4398                         _current_snapshot_name = old_snapshot;
4399
4400                         (*_session_dir) = old_sd;
4401
4402                         if (was_dirty) {
4403                                 set_dirty ();
4404                         }
4405
4406                         if (internal_file_cnt) {
4407                                 /* reset these to their original values */
4408                                 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
4409                                 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
4410                         }
4411                         
4412                 } else {
4413
4414                         /* prune session dirs, and update disk space statistics
4415                          */
4416
4417                         space_and_path sp;
4418                         sp.path = _path;
4419                         session_dirs.clear ();
4420                         session_dirs.push_back (sp);
4421                         refresh_disk_space ();
4422
4423                         /* ensure that all existing tracks reset their current capture source paths 
4424                          */
4425                         reset_write_sources (true, true);
4426
4427                         /* the copying above was based on actually discovering files, not just iterating over the sources list.
4428                            But if we're going to switch to the new (copied) session, we need to change the paths in the sources also.
4429                         */
4430
4431                         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4432                                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4433
4434                                 if (!fs) {
4435                                         continue;
4436                                 }
4437
4438                                 if (fs->within_session()) {
4439                                         string newpath = make_new_media_path (fs->path(), to_dir, new_folder);
4440                                         fs->set_path (newpath);
4441                                 }
4442                         }
4443                 }
4444
4445         } catch (Glib::FileError& e) {
4446
4447                 saveas.failure_message = e.what();
4448                 
4449                 /* recursively remove all the directories */
4450                 
4451                 remove_directory (to_dir);
4452                 
4453                 /* return error */
4454                 
4455                 return -1;
4456
4457         } catch (...) {
4458
4459                 saveas.failure_message = _("unknown reason");
4460                 
4461                 /* recursively remove all the directories */
4462                 
4463                 remove_directory (to_dir);
4464                 
4465                 /* return error */
4466                 
4467                 return -1;
4468         }
4469         
4470         return 0;
4471 }