API change: expose session-archive compression-level
[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 <string>
29 #include <cerrno>
30 #include <cstdio> /* snprintf(3) ... grrr */
31 #include <cmath>
32
33 #include <unistd.h>
34 #include <climits>
35 #include <signal.h>
36 #include <sys/time.h>
37
38 #ifdef HAVE_SYS_VFS_H
39 #include <sys/vfs.h>
40 #endif
41
42 #if defined(__APPLE__) || defined(__FreeBSD__)
43 #include <sys/param.h>
44 #include <sys/mount.h>
45 #endif
46
47 #ifdef HAVE_SYS_STATVFS_H
48 #include <sys/statvfs.h>
49 #endif
50
51 #include <glib.h>
52 #include "pbd/gstdio_compat.h"
53 #include "pbd/locale_guard.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/basename.h"
67 #include "pbd/debug.h"
68 #include "pbd/enumwriter.h"
69 #include "pbd/error.h"
70 #include "pbd/file_utils.h"
71 #include "pbd/pathexpand.h"
72 #include "pbd/pthread_utils.h"
73 #include "pbd/stacktrace.h"
74 #include "pbd/types_convert.h"
75 #include "pbd/localtime_r.h"
76 #include "pbd/unwind.h"
77
78 #include "ardour/amp.h"
79 #include "ardour/async_midi_port.h"
80 #include "ardour/audio_track.h"
81 #include "ardour/audioengine.h"
82 #include "ardour/audiofilesource.h"
83 #include "ardour/audioregion.h"
84 #include "ardour/auditioner.h"
85 #include "ardour/automation_control.h"
86 #include "ardour/boost_debug.h"
87 #include "ardour/butler.h"
88 #include "ardour/controllable_descriptor.h"
89 #include "ardour/control_protocol_manager.h"
90 #include "ardour/directory_names.h"
91 #include "ardour/disk_reader.h"
92 #include "ardour/filename_extensions.h"
93 #include "ardour/graph.h"
94 #include "ardour/location.h"
95 #ifdef LV2_SUPPORT
96 #include "ardour/lv2_plugin.h"
97 #endif
98 #include "ardour/midi_model.h"
99 #include "ardour/midi_patch_manager.h"
100 #include "ardour/midi_region.h"
101 #include "ardour/midi_scene_changer.h"
102 #include "ardour/midi_source.h"
103 #include "ardour/midi_track.h"
104 #include "ardour/pannable.h"
105 #include "ardour/playlist_factory.h"
106 #include "ardour/playlist_source.h"
107 #include "ardour/port.h"
108 #include "ardour/processor.h"
109 #include "ardour/progress.h"
110 #include "ardour/profile.h"
111 #include "ardour/proxy_controllable.h"
112 #include "ardour/recent_sessions.h"
113 #include "ardour/region_factory.h"
114 #include "ardour/revision.h"
115 #include "ardour/route_group.h"
116 #include "ardour/send.h"
117 #include "ardour/selection.h"
118 #include "ardour/session.h"
119 #include "ardour/session_directory.h"
120 #include "ardour/session_metadata.h"
121 #include "ardour/session_playlists.h"
122 #include "ardour/session_state_utils.h"
123 #include "ardour/silentfilesource.h"
124 #include "ardour/smf_source.h"
125 #include "ardour/sndfilesource.h"
126 #include "ardour/source_factory.h"
127 #include "ardour/speakers.h"
128 #include "ardour/template_utils.h"
129 #include "ardour/tempo.h"
130 #include "ardour/ticker.h"
131 #include "ardour/types_convert.h"
132 #include "ardour/user_bundle.h"
133 #include "ardour/vca.h"
134 #include "ardour/vca_manager.h"
135
136 #include "control_protocol/control_protocol.h"
137
138 #include "LuaBridge/LuaBridge.h"
139
140 #include "pbd/i18n.h"
141 #include <locale.h>
142
143 using namespace std;
144 using namespace ARDOUR;
145 using namespace PBD;
146
147 #define DEBUG_UNDO_HISTORY(msg) DEBUG_TRACE (PBD::DEBUG::UndoHistory, string_compose ("%1: %2\n", __LINE__, msg));
148
149 void
150 Session::pre_engine_init (string fullpath)
151 {
152         if (fullpath.empty()) {
153                 destroy ();
154                 throw failed_constructor();
155         }
156
157         /* discover canonical fullpath */
158
159         _path = canonical_path(fullpath);
160
161         /* is it new ? */
162         if (Profile->get_trx() ) {
163                 // Waves TracksLive has a usecase of session replacement with a new one.
164                 // We should check session state file (<session_name>.ardour) existance
165                 // to determine if the session is new or not
166
167                 string full_session_name = Glib::build_filename( fullpath, _name );
168                 full_session_name += statefile_suffix;
169
170                 _is_new = !Glib::file_test (full_session_name, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
171         } else {
172                 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
173         }
174
175         /* finish initialization that can't be done in a normal C++ constructor
176            definition.
177         */
178
179         timerclear (&last_mmc_step);
180         g_atomic_int_set (&processing_prohibited, 0);
181         g_atomic_int_set (&_record_status, Disabled);
182         g_atomic_int_set (&_playback_load, 100);
183         g_atomic_int_set (&_capture_load, 100);
184         set_next_event ();
185         _all_route_group->set_active (true, this);
186         interpolation.add_channel ();
187
188         if (config.get_use_video_sync()) {
189                 waiting_for_sync_offset = true;
190         } else {
191                 waiting_for_sync_offset = false;
192         }
193
194         last_rr_session_dir = session_dirs.begin();
195
196         set_history_depth (Config->get_history_depth());
197
198         /* default: assume simple stereo speaker configuration */
199
200         _speakers->setup_default_speakers (2);
201
202         _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
203                                 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
204                                 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
205         add_controllable (_solo_cut_control);
206
207         /* These are all static "per-class" signals */
208
209         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
210         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
211         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
212         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
213         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
214
215         /* stop IO objects from doing stuff until we're ready for them */
216
217         Delivery::disable_panners ();
218         IO::disable_connecting ();
219 }
220
221 int
222 Session::post_engine_init ()
223 {
224         BootMessage (_("Set block size and sample rate"));
225
226         set_block_size (_engine.samples_per_cycle());
227         set_sample_rate (_engine.sample_rate());
228
229         BootMessage (_("Using configuration"));
230
231         _midi_ports = new MidiPortManager;
232
233         MIDISceneChanger* msc;
234
235         _scene_changer = msc = new MIDISceneChanger (*this);
236         msc->set_input_port (boost::dynamic_pointer_cast<MidiPort>(scene_input_port()));
237         msc->set_output_port (boost::dynamic_pointer_cast<MidiPort>(scene_output_port()));
238
239         boost::function<samplecnt_t(void)> timer_func (boost::bind (&Session::audible_sample, this, (bool*)(0)));
240         boost::dynamic_pointer_cast<AsyncMIDIPort>(scene_input_port())->set_timer (timer_func);
241
242         setup_midi_machine_control ();
243
244         if (_butler->start_thread()) {
245                 error << _("Butler did not start") << endmsg;
246                 return -1;
247         }
248
249         if (start_midi_thread ()) {
250                 error << _("MIDI I/O thread did not start") << endmsg;
251                 return -1;
252         }
253
254         setup_click_sounds (0);
255         setup_midi_control ();
256
257         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
258         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
259
260         try {
261                 /* tempo map requires sample rate knowledge */
262
263                 delete _tempo_map;
264                 _tempo_map = new TempoMap (_current_sample_rate);
265                 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
266                 _tempo_map->MetricPositionChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
267         } catch (std::exception const & e) {
268                 error << _("Unexpected exception during session setup: ") << e.what() << endmsg;
269                 return -2;
270         } catch (...) {
271                 error << _("Unknown exception during session setup") << endmsg;
272                 return -3;
273         }
274
275         try {
276                 /* MidiClock requires a tempo map */
277
278                 delete midi_clock;
279                 midi_clock = new MidiClockTicker ();
280                 midi_clock->set_session (this);
281
282                 /* crossfades require sample rate knowledge */
283
284                 SndFileSource::setup_standard_crossfades (*this, sample_rate());
285                 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
286                 _engine.MidiSelectionPortsChanged.connect_same_thread (*this, boost::bind (&Session::rewire_midi_selection_ports, this));
287
288                 DiskReader::allocate_working_buffers();
289                 refresh_disk_space ();
290
291                 /* we're finally ready to call set_state() ... all objects have
292                  * been created, the engine is running.
293                  */
294
295                 if (state_tree) {
296                         try {
297                                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
298                                         error << _("Could not set session state from XML") << endmsg;
299                                         return -4;
300                                 }
301                         } catch (PBD::unknown_enumeration& e) {
302                                 error << _("Session state: ") << e.what() << endmsg;
303                                 return -4;
304                         }
305                 } else {
306                         // set_state() will call setup_raid_path(), but if it's a new session we need
307                         // to call setup_raid_path() here.
308                         setup_raid_path (_path);
309                 }
310
311                 /* ENGINE */
312
313                 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
314                 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
315
316                 Config->map_parameters (ff);
317                 config.map_parameters (ft);
318                 _butler->map_parameters ();
319
320                 /* Reset all panners */
321
322                 Delivery::reset_panners ();
323
324                 /* this will cause the CPM to instantiate any protocols that are in use
325                  * (or mandatory), which will pass it this Session, and then call
326                  * set_state() on each instantiated protocol to match stored state.
327                  */
328
329                 ControlProtocolManager::instance().set_session (this);
330
331                 /* This must be done after the ControlProtocolManager set_session above,
332                    as it will set states for ports which the ControlProtocolManager creates.
333                 */
334
335                 // XXX set state of MIDI::Port's
336                 // MidiPortManager::instance()->set_port_states (Config->midi_port_states ());
337
338                 /* And this must be done after the MIDI::Manager::set_port_states as
339                  * it will try to make connections whose details are loaded by set_port_states.
340                  */
341
342                 hookup_io ();
343
344                 /* Let control protocols know that we are now all connected, so they
345                  * could start talking to surfaces if they want to.
346                  */
347
348                 ControlProtocolManager::instance().midi_connectivity_established ();
349
350                 if (_is_new && !no_auto_connect()) {
351                         Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
352                         auto_connect_master_bus ();
353                 }
354
355                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
356
357                 /* update latencies */
358
359                 initialize_latencies ();
360
361                 _locations->added.connect_same_thread (*this, boost::bind (&Session::location_added, this, _1));
362                 _locations->removed.connect_same_thread (*this, boost::bind (&Session::location_removed, this, _1));
363                 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
364
365         } catch (AudioEngine::PortRegistrationFailure& err) {
366                 error << err.what() << endmsg;
367                 return -5;
368         } catch (std::exception const & e) {
369                 error << _("Unexpected exception during session setup: ") << e.what() << endmsg;
370                 return -6;
371         } catch (...) {
372                 error << _("Unknown exception during session setup") << endmsg;
373                 return -7;
374         }
375
376         BootMessage (_("Reset Remote Controls"));
377
378         // send_full_time_code (0);
379         _engine.transport_locate (0);
380
381         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
382         send_immediate_mmc (MIDI::MachineControlCommand (Timecode::Time ()));
383
384         MIDI::Name::MidiPatchManager::instance().add_search_path (session_directory().midi_patch_path() );
385
386         ltc_tx_initialize();
387         /* initial program change will be delivered later; see ::config_changed() */
388
389         _state_of_the_state = Clean;
390
391         Port::set_connecting_blocked (false);
392
393         DirtyChanged (); /* EMIT SIGNAL */
394
395         if (_is_new) {
396                 save_state ("");
397         } else if (state_was_pending) {
398                 save_state ("");
399                 remove_pending_capture_state ();
400                 state_was_pending = false;
401         }
402
403         /* Now, finally, we can fill the playback buffers */
404
405         BootMessage (_("Filling playback buffers"));
406
407         boost::shared_ptr<RouteList> rl = routes.reader();
408         for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
409                 boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (*r);
410                 if (trk && !trk->is_private_route()) {
411                         trk->seek (_transport_sample, true);
412                 }
413         }
414
415         return 0;
416 }
417
418 void
419 Session::session_loaded ()
420 {
421         SessionLoaded();
422
423         _state_of_the_state = Clean;
424
425         DirtyChanged (); /* EMIT SIGNAL */
426
427         if (_is_new) {
428                 save_state ("");
429         } else if (state_was_pending) {
430                 save_state ("");
431                 remove_pending_capture_state ();
432                 state_was_pending = false;
433         }
434
435         /* Now, finally, we can fill the playback buffers */
436
437         BootMessage (_("Filling playback buffers"));
438         force_locate (_transport_sample, false);
439 }
440
441 string
442 Session::raid_path () const
443 {
444         Searchpath raid_search_path;
445
446         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
447                 raid_search_path += (*i).path;
448         }
449
450         return raid_search_path.to_string ();
451 }
452
453 void
454 Session::setup_raid_path (string path)
455 {
456         if (path.empty()) {
457                 return;
458         }
459
460         space_and_path sp;
461         string fspath;
462
463         session_dirs.clear ();
464
465         Searchpath search_path(path);
466         Searchpath sound_search_path;
467         Searchpath midi_search_path;
468
469         for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
470                 sp.path = *i;
471                 sp.blocks = 0; // not needed
472                 session_dirs.push_back (sp);
473
474                 SessionDirectory sdir(sp.path);
475
476                 sound_search_path += sdir.sound_path ();
477                 midi_search_path += sdir.midi_path ();
478         }
479
480         // reset the round-robin soundfile path thingie
481         last_rr_session_dir = session_dirs.begin();
482 }
483
484 bool
485 Session::path_is_within_session (const std::string& path)
486 {
487         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
488                 if (PBD::path_is_within (i->path, path)) {
489                         return true;
490                 }
491         }
492         return false;
493 }
494
495 int
496 Session::ensure_subdirs ()
497 {
498         string dir;
499
500         dir = session_directory().peak_path();
501
502         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
503                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
504                 return -1;
505         }
506
507         dir = session_directory().sound_path();
508
509         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
510                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
511                 return -1;
512         }
513
514         dir = session_directory().midi_path();
515
516         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
517                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
518                 return -1;
519         }
520
521         dir = session_directory().dead_path();
522
523         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
524                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
525                 return -1;
526         }
527
528         dir = session_directory().export_path();
529
530         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
531                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
532                 return -1;
533         }
534
535         dir = analysis_dir ();
536
537         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
538                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
539                 return -1;
540         }
541
542         dir = plugins_dir ();
543
544         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
545                 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
546                 return -1;
547         }
548
549         dir = externals_dir ();
550
551         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
552                 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
553                 return -1;
554         }
555
556         return 0;
557 }
558
559 /** @param session_template directory containing session template, or empty.
560  *  Caller must not hold process lock.
561  */
562 int
563 Session::create (const string& session_template, BusProfile* bus_profile)
564 {
565         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
566                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
567                 return -1;
568         }
569
570         if (ensure_subdirs ()) {
571                 return -1;
572         }
573
574         _writable = exists_and_writable (_path);
575
576         if (!session_template.empty()) {
577                 string in_path = (ARDOUR::Profile->get_trx () ? session_template : session_template_dir_to_file (session_template));
578
579                 FILE* in = g_fopen (in_path.c_str(), "rb");
580
581                 if (in) {
582                         /* no need to call legalize_for_path() since the string
583                          * in session_template is already a legal path name
584                          */
585                         string out_path = Glib::build_filename (_session_dir->root_path(), _name + statefile_suffix);
586
587                         FILE* out = g_fopen (out_path.c_str(), "wb");
588
589                         if (out) {
590                                 char buf[1024];
591                                 stringstream new_session;
592
593                                 while (!feof (in)) {
594                                         size_t charsRead = fread (buf, sizeof(char), 1024, in);
595
596                                         if (ferror (in)) {
597                                                 error << string_compose (_("Error reading session template file %1 (%2)"), in_path, strerror (errno)) << endmsg;
598                                                 fclose (in);
599                                                 fclose (out);
600                                                 return -1;
601                                         }
602                                         if (charsRead == 0) {
603                                                 break;
604                                         }
605                                         new_session.write (buf, charsRead);
606                                 }
607                                 fclose (in);
608
609                                 string file_contents = new_session.str();
610                                 size_t writeSize = file_contents.length();
611                                 if (fwrite (file_contents.c_str(), sizeof(char), writeSize, out) != writeSize) {
612                                         error << string_compose (_("Error writing session template file %1 (%2)"), out_path, strerror (errno)) << endmsg;
613                                         fclose (out);
614                                         return -1;
615                                 }
616                                 fclose (out);
617
618                                 _is_new = false;
619
620                                 if (!ARDOUR::Profile->get_trx()) {
621                                         /* Copy plugin state files from template to new session */
622                                         std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
623                                         copy_recurse (template_plugins, plugins_dir ());
624                                 }
625
626                                 return 0;
627
628                         } else {
629                                 error << string_compose (_("Could not open %1 for writing session template"), out_path)
630                                         << endmsg;
631                                 fclose(in);
632                                 return -1;
633                         }
634
635                 } else {
636                         error << string_compose (_("Could not open session template %1 for reading"), in_path)
637                                 << endmsg;
638                         return -1;
639                 }
640
641         }
642
643         if (Profile->get_trx()) {
644
645                 /* set initial start + end point : ARDOUR::Session::session_end_shift long.
646                  * Remember that this is a brand new session. Sessions
647                  * loaded from saved state will get this range from the saved state.
648                  */
649
650                 set_session_range_location (0, 0);
651
652                 /* Initial loop location, from absolute zero, length 10 seconds  */
653
654                 Location* loc = new Location (*this, 0, 10.0 * _engine.sample_rate(), _("Loop"),  Location::IsAutoLoop, 0);
655                 _locations->add (loc, true);
656                 set_auto_loop_location (loc);
657         }
658
659         _state_of_the_state = Clean;
660
661         /* set up Master Out and Monitor Out if necessary */
662
663         if (bus_profile) {
664                 RouteList rl;
665                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
666                 if (bus_profile->master_out_channels) {
667                         int rv = add_master_bus (count);
668
669                         if (rv) {
670                                 return rv;
671                         }
672
673                         if (Config->get_use_monitor_bus())
674                                 add_monitor_section ();
675                 }
676         }
677
678         return 0;
679 }
680
681 void
682 Session::maybe_write_autosave()
683 {
684         if (dirty() && record_status() != Recording) {
685                 save_state("", true);
686         }
687 }
688
689 void
690 Session::remove_pending_capture_state ()
691 {
692         std::string pending_state_file_path(_session_dir->root_path());
693
694         pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
695
696         if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
697
698         if (g_remove (pending_state_file_path.c_str()) != 0) {
699                 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
700                                 pending_state_file_path, g_strerror (errno)) << endmsg;
701         }
702 }
703
704 /** Rename a state file.
705  *  @param old_name Old snapshot name.
706  *  @param new_name New snapshot name.
707  */
708 void
709 Session::rename_state (string old_name, string new_name)
710 {
711         if (old_name == _current_snapshot_name || old_name == _name) {
712                 /* refuse to rename the current snapshot or the "main" one */
713                 return;
714         }
715
716         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
717         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
718
719         const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
720         const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
721
722         if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
723                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
724                                 old_name, new_name, g_strerror(errno)) << endmsg;
725         }
726 }
727
728 /** Remove a state file.
729  *  @param snapshot_name Snapshot name.
730  */
731 void
732 Session::remove_state (string snapshot_name)
733 {
734         if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
735                 // refuse to remove the current snapshot or the "main" one
736                 return;
737         }
738
739         std::string xml_path(_session_dir->root_path());
740
741         xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
742
743         if (!create_backup_file (xml_path)) {
744                 // don't remove it if a backup can't be made
745                 // create_backup_file will log the error.
746                 return;
747         }
748
749         // and delete it
750         if (g_remove (xml_path.c_str()) != 0) {
751                 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
752                                 xml_path, g_strerror (errno)) << endmsg;
753         }
754 }
755
756 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
757 int
758 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot, bool template_only)
759 {
760         DEBUG_TRACE (DEBUG::Locale, string_compose ("Session::save_state locale '%1'\n", setlocale (LC_NUMERIC, NULL)));
761
762         XMLTree tree;
763         std::string xml_path(_session_dir->root_path());
764
765         /* prevent concurrent saves from different threads */
766
767         Glib::Threads::Mutex::Lock lm (save_state_lock);
768
769         if (!_writable || (_state_of_the_state & CannotSave)) {
770                 return 1;
771         }
772
773         if (g_atomic_int_get(&_suspend_save)) {
774                 _save_queued = true;
775                 return 1;
776         }
777         _save_queued = false;
778
779         snapshot_t fork_state = NormalSave;
780         if (!snapshot_name.empty() && snapshot_name != _current_snapshot_name && !template_only && !pending) {
781                 /* snapshot, close midi */
782                 fork_state = switch_to_snapshot ? SwitchToSnapshot : SnapshotKeep;
783         }
784
785 #ifndef NDEBUG
786         const int64_t save_start_time = g_get_monotonic_time();
787 #endif
788
789         /* tell sources we're saving first, in case they write out to a new file
790          * which should be saved with the state rather than the old one */
791         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
792                 try {
793                         i->second->session_saved();
794                 } catch (Evoral::SMF::FileError& e) {
795                         error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
796                 }
797         }
798
799         SessionSaveUnderway (); /* EMIT SIGNAL */
800
801         bool mark_as_clean = true;
802
803         if (!snapshot_name.empty() && !switch_to_snapshot) {
804                 mark_as_clean = false;
805         }
806
807         if (template_only) {
808                 mark_as_clean = false;
809                 tree.set_root (&get_template());
810         } else {
811                 tree.set_root (&state (true, fork_state));
812         }
813
814         if (snapshot_name.empty()) {
815                 snapshot_name = _current_snapshot_name;
816         } else if (switch_to_snapshot) {
817                 set_snapshot_name (snapshot_name);
818         }
819
820         assert (!snapshot_name.empty());
821
822         if (!pending) {
823
824                 /* proper save: use statefile_suffix (.ardour in English) */
825
826                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
827
828                 /* make a backup copy of the old file */
829
830                 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
831                         // create_backup_file will log the error
832                         return -1;
833                 }
834
835         } else {
836
837                 /* pending save: use pending_suffix (.pending in English) */
838                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
839         }
840
841         std::string tmp_path(_session_dir->root_path());
842         tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
843
844 #ifndef NDEBUG
845         cerr << "actually writing state to " << tmp_path << endl;
846 #endif
847
848         if (!tree.write (tmp_path)) {
849                 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
850                 if (g_remove (tmp_path.c_str()) != 0) {
851                         error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
852                                         tmp_path, g_strerror (errno)) << endmsg;
853                 }
854                 return -1;
855
856         } else {
857
858 #ifndef NDEBUG
859                 cerr << "renaming state to " << xml_path << endl;
860 #endif
861
862                 if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
863                         error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"),
864                                         tmp_path, xml_path, g_strerror(errno)) << endmsg;
865                         if (g_remove (tmp_path.c_str()) != 0) {
866                                 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
867                                                 tmp_path, g_strerror (errno)) << endmsg;
868                         }
869                         return -1;
870                 }
871         }
872
873         if (!pending) {
874
875                 save_history (snapshot_name);
876
877                 if (mark_as_clean) {
878                         bool was_dirty = dirty();
879
880                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
881
882                         if (was_dirty) {
883                                 DirtyChanged (); /* EMIT SIGNAL */
884                         }
885                 }
886
887                 StateSaved (snapshot_name); /* EMIT SIGNAL */
888         }
889
890 #ifndef NDEBUG
891         const int64_t elapsed_time_us = g_get_monotonic_time() - save_start_time;
892         cerr << "saved state in " << fixed << setprecision (1) << elapsed_time_us / 1000. << " ms\n";
893 #endif
894         return 0;
895 }
896
897 int
898 Session::restore_state (string snapshot_name)
899 {
900         try {
901                 if (load_state (snapshot_name) == 0) {
902                         set_state (*state_tree->root(), Stateful::loading_state_version);
903                 }
904         } catch (...) {
905                 // SessionException
906                 // unknown_enumeration
907                 return -1;
908         }
909
910         return 0;
911 }
912
913 int
914 Session::load_state (string snapshot_name)
915 {
916         delete state_tree;
917         state_tree = 0;
918
919         state_was_pending = false;
920
921         /* check for leftover pending state from a crashed capture attempt */
922
923         std::string xmlpath(_session_dir->root_path());
924         xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
925
926         if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
927
928                 /* there is pending state from a crashed capture attempt */
929
930                 boost::optional<int> r = AskAboutPendingState();
931                 if (r.get_value_or (1)) {
932                         state_was_pending = true;
933                 }
934         }
935
936         if (!state_was_pending) {
937                 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
938         }
939
940         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
941                 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
942                 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
943                         error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
944                         return 1;
945                 }
946         }
947
948         state_tree = new XMLTree;
949
950         set_dirty();
951
952         _writable = exists_and_writable (xmlpath) && exists_and_writable(Glib::path_get_dirname(xmlpath));
953
954         if (!state_tree->read (xmlpath)) {
955                 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
956                 delete state_tree;
957                 state_tree = 0;
958                 return -1;
959         }
960
961         XMLNode const & root (*state_tree->root());
962
963         if (root.name() != X_("Session")) {
964                 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
965                 delete state_tree;
966                 state_tree = 0;
967                 return -1;
968         }
969
970         std::string version;
971         root.get_property ("version", version);
972         Stateful::loading_state_version = parse_stateful_loading_version (version);
973
974         if ((Stateful::loading_state_version / 1000L) > (CURRENT_SESSION_FILE_VERSION / 1000L)) {
975                 cerr << "Session-version: " << Stateful::loading_state_version << " is not supported. Current: " << CURRENT_SESSION_FILE_VERSION << "\n";
976                 throw SessionException (string_compose (_("Incomatible Session Version. That session was created with a newer version of %1"), PROGRAM_NAME));
977         }
978
979         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
980
981                 std::string backup_path(_session_dir->root_path());
982                 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
983                 backup_path = Glib::build_filename (backup_path, backup_filename);
984
985                 // only create a backup for a given statefile version once
986
987                 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
988
989                         VersionMismatch (xmlpath, backup_path);
990
991                         if (!copy_file (xmlpath, backup_path)) {;
992                                 return -1;
993                         }
994                 }
995         }
996
997         save_snapshot_name (snapshot_name);
998
999         return 0;
1000 }
1001
1002 int
1003 Session::load_options (const XMLNode& node)
1004 {
1005         config.set_variables (node);
1006         return 0;
1007 }
1008
1009 bool
1010 Session::save_default_options ()
1011 {
1012         return config.save_state();
1013 }
1014
1015 XMLNode&
1016 Session::get_state()
1017 {
1018         return state(true);
1019 }
1020
1021 XMLNode&
1022 Session::get_template()
1023 {
1024         /* if we don't disable rec-enable, diskstreams
1025            will believe they need to store their capture
1026            sources in their state node.
1027         */
1028
1029         disable_record (false);
1030
1031         return state(false);
1032 }
1033
1034 typedef std::set<boost::shared_ptr<Playlist> > PlaylistSet;
1035 typedef std::set<boost::shared_ptr<Source> > SourceSet;
1036
1037 bool
1038 Session::export_track_state (boost::shared_ptr<RouteList> rl, const string& path)
1039 {
1040         if (Glib::file_test (path, Glib::FILE_TEST_EXISTS))  {
1041                 return false;
1042         }
1043         if (g_mkdir_with_parents (path.c_str(), 0755) != 0) {
1044                 return false;
1045         }
1046
1047         PBD::Unwinder<std::string> uw (_template_state_dir, path);
1048
1049         LocaleGuard lg;
1050         XMLNode* node = new XMLNode("TrackState"); // XXX
1051         XMLNode* child;
1052
1053         PlaylistSet playlists; // SessionPlaylists
1054         SourceSet sources;
1055
1056         // these will work with  new_route_from_template()
1057         // TODO: LV2 plugin-state-dir needs to be relative (on load?)
1058         child = node->add_child ("Routes");
1059         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1060                 if ((*i)->is_auditioner()) {
1061                         continue;
1062                 }
1063                 if ((*i)->is_master() || (*i)->is_monitor()) {
1064                         continue;
1065                 }
1066                 child->add_child_nocopy ((*i)->get_state());
1067                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (*i);
1068                 if (track) {
1069                         playlists.insert (track->playlist ());
1070                 }
1071         }
1072
1073         // on load, Regions in the playlists need to resolve and map Source-IDs
1074         // also playlist needs to be merged or created with new-name..
1075         // ... and Diskstream in tracks adjusted to use the correct playlist
1076         child = node->add_child ("Playlists"); // SessionPlaylists::add_state
1077         for (PlaylistSet::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
1078                 child->add_child_nocopy ((*i)->get_state ());
1079                 boost::shared_ptr<RegionList> prl = (*i)->region_list ();
1080                 for (RegionList::const_iterator s = prl->begin(); s != prl->end(); ++s) {
1081                         const Region::SourceList& sl = (*s)->sources ();
1082                         for (Region::SourceList::const_iterator sli = sl.begin(); sli != sl.end(); ++sli) {
1083                                 sources.insert (*sli);
1084                         }
1085                 }
1086         }
1087
1088         child = node->add_child ("Sources");
1089         for (SourceSet::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1090                 child->add_child_nocopy ((*i)->get_state ());
1091                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (*i);
1092                 if (fs) {
1093 #ifdef PLATFORM_WINDOWS
1094                         fs->close ();
1095 #endif
1096                         string p = fs->path ();
1097                         PBD::copy_file (p, Glib::build_filename (path, Glib::path_get_basename (p)));
1098                 }
1099         }
1100
1101         std::string sn = Glib::build_filename (path, "share.axml");
1102
1103         XMLTree tree;
1104         tree.set_root (node);
1105         return tree.write (sn.c_str());
1106 }
1107
1108 namespace
1109 {
1110 struct route_id_compare {
1111         bool
1112         operator() (const boost::shared_ptr<Route>& r1, const boost::shared_ptr<Route>& r2)
1113         {
1114                 return r1->id () < r2->id ();
1115         }
1116 };
1117 } // anon namespace
1118
1119 XMLNode&
1120 Session::state (bool full_state, snapshot_t snapshot_type)
1121 {
1122         LocaleGuard lg;
1123         XMLNode* node = new XMLNode("Session");
1124         XMLNode* child;
1125
1126         node->set_property("version", CURRENT_SESSION_FILE_VERSION);
1127
1128         child = node->add_child ("ProgramVersion");
1129         child->set_property("created-with", created_with);
1130
1131         std::string modified_with = string_compose ("%1 %2", PROGRAM_NAME, revision);
1132         child->set_property("modified-with", modified_with);
1133
1134         /* store configuration settings */
1135
1136         if (full_state) {
1137
1138                 node->set_property ("name", _name);
1139                 node->set_property ("sample-rate", _base_sample_rate);
1140
1141                 if (session_dirs.size() > 1) {
1142
1143                         string p;
1144
1145                         vector<space_and_path>::iterator i = session_dirs.begin();
1146                         vector<space_and_path>::iterator next;
1147
1148                         ++i; /* skip the first one */
1149                         next = i;
1150                         ++next;
1151
1152                         while (i != session_dirs.end()) {
1153
1154                                 p += (*i).path;
1155
1156                                 if (next != session_dirs.end()) {
1157                                         p += G_SEARCHPATH_SEPARATOR;
1158                                 } else {
1159                                         break;
1160                                 }
1161
1162                                 ++next;
1163                                 ++i;
1164                         }
1165
1166                         child = node->add_child ("Path");
1167                         child->add_content (p);
1168                 }
1169                 node->set_property ("end-is-free", _session_range_end_is_free);
1170         }
1171
1172         /* save the ID counter */
1173
1174         node->set_property ("id-counter", ID::counter());
1175
1176         node->set_property ("name-counter", name_id_counter ());
1177
1178         /* save the event ID counter */
1179
1180         node->set_property ("event-counter", Evoral::event_id_counter());
1181
1182         /* save the VCA counter */
1183
1184         node->set_property ("vca-counter", VCA::get_next_vca_number());
1185
1186         /* various options */
1187
1188         list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
1189         if (!midi_port_nodes.empty()) {
1190                 XMLNode* midi_port_stuff = new XMLNode ("MIDIPorts");
1191                 for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
1192                         midi_port_stuff->add_child_nocopy (**n);
1193                 }
1194                 node->add_child_nocopy (*midi_port_stuff);
1195         }
1196
1197         XMLNode& cfgxml (config.get_variables ());
1198         if (!full_state) {
1199                 /* exclude search-paths from template */
1200                 cfgxml.remove_nodes_and_delete ("name", "audio-search-path");
1201                 cfgxml.remove_nodes_and_delete ("name", "midi-search-path");
1202                 cfgxml.remove_nodes_and_delete ("name", "raid-path");
1203         }
1204         node->add_child_nocopy (cfgxml);
1205
1206         node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1207
1208         child = node->add_child ("Sources");
1209
1210         if (full_state) {
1211                 Glib::Threads::Mutex::Lock sl (source_lock);
1212
1213                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1214
1215                         /* Don't save information about non-file Sources, or
1216                          * about non-destructive file sources that are empty
1217                          * and unused by any regions.
1218                          */
1219                         boost::shared_ptr<FileSource> fs;
1220
1221                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) == 0) {
1222                                 continue;
1223                         }
1224
1225                         if (!fs->destructive()) {
1226                                 if (fs->empty() && !fs->used()) {
1227                                         continue;
1228                                 }
1229                         }
1230
1231                         if (snapshot_type != NormalSave && fs->within_session ()) {
1232                                 /* copy MIDI sources to new file
1233                                  *
1234                                  * We cannot replace the midi-source and MidiRegion::clobber_sources,
1235                                  * because the GUI (midi_region) has a direct pointer to the midi-model
1236                                  * of the source, as does UndoTransaction.
1237                                  *
1238                                  * On the upside, .mid files are not kept open. The file is only open
1239                                  * when reading the model initially and when flushing the model to disk:
1240                                  * source->session_saved () or export.
1241                                  *
1242                                  * We can change the _path of the existing source under the hood, keeping
1243                                  * all IDs, references and pointers intact.
1244                                  * */
1245                                 boost::shared_ptr<SMFSource> ms;
1246                                 if ((ms = boost::dynamic_pointer_cast<SMFSource> (siter->second)) != 0) {
1247                                         const std::string ancestor_name = ms->ancestor_name();
1248                                         const std::string base          = PBD::basename_nosuffix(ancestor_name);
1249                                         const string path               = new_midi_source_path (base, false);
1250
1251                                         /* use SMF-API to clone data (use the midi_model, not data on disk) */
1252                                         boost::shared_ptr<SMFSource> newsrc (new SMFSource (*this, path, SndFileSource::default_writable_flags));
1253                                         Source::Lock lm (ms->mutex());
1254
1255                                         // TODO special-case empty, removable() files: just create a new removable.
1256                                         // (load + write flushes the model and creates the file)
1257                                         if (!ms->model()) {
1258                                                 ms->load_model (lm);
1259                                         }
1260                                         if (ms->write_to (lm, newsrc, Temporal::Beats(), std::numeric_limits<Temporal::Beats>::max())) {
1261                                                 error << string_compose (_("Session-Save: Failed to copy MIDI Source '%1' for snapshot"), ancestor_name) << endmsg;
1262                                         } else {
1263                                                 if (snapshot_type == SnapshotKeep) {
1264                                                         /* keep working on current session.
1265                                                          *
1266                                                          * Save snapshot-state with the original filename.
1267                                                          * Switch to use new path for future saves of the main session.
1268                                                          */
1269                                                         child->add_child_nocopy (ms->get_state());
1270                                                 }
1271
1272                                                 /* swap file-paths.
1273                                                  * ~SMFSource  unlinks removable() files.
1274                                                  */
1275                                                 std::string npath (ms->path ());
1276                                                 ms->replace_file (newsrc->path ());
1277                                                 newsrc->replace_file (npath);
1278
1279                                                 if (snapshot_type == SwitchToSnapshot) {
1280                                                         /* save and switch to snapshot.
1281                                                          *
1282                                                          * Leave the old file in place (as is).
1283                                                          * Snapshot uses new source directly
1284                                                          */
1285                                                         child->add_child_nocopy (ms->get_state());
1286                                                 }
1287                                                 continue;
1288                                         }
1289                                 }
1290                         }
1291
1292                         child->add_child_nocopy (siter->second->get_state());
1293                 }
1294         }
1295
1296         child = node->add_child ("Regions");
1297
1298         if (full_state) {
1299                 Glib::Threads::Mutex::Lock rl (region_lock);
1300                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1301                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1302                         boost::shared_ptr<Region> r = i->second;
1303                         /* only store regions not attached to playlists */
1304                         if (r->playlist() == 0) {
1305                                 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1306                                         child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1307                                 } else {
1308                                         child->add_child_nocopy (r->get_state ());
1309                                 }
1310                         }
1311                 }
1312
1313                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1314
1315                 if (!cassocs.empty()) {
1316                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1317
1318                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1319                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1320                                 can->set_property (X_("copy"), i->first->id());
1321                                 can->set_property (X_("original"), i->second->id());
1322                                 ca->add_child_nocopy (*can);
1323                         }
1324                 }
1325         }
1326
1327         if (full_state) {
1328
1329                 node->add_child_nocopy (_selection->get_state());
1330
1331                 if (_locations) {
1332                         node->add_child_nocopy (_locations->get_state());
1333                 }
1334         } else {
1335                 Locations loc (*this);
1336                 const bool was_dirty = dirty();
1337                 // for a template, just create a new Locations, populate it
1338                 // with the default start and end, and get the state for that.
1339                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange, 0);
1340                 range->set (max_samplepos, 0);
1341                 loc.add (range);
1342                 XMLNode& locations_state = loc.get_state();
1343
1344                 if (ARDOUR::Profile->get_trx() && _locations) {
1345                         // For tracks we need stored the Auto Loop Range and all MIDI markers.
1346                         for (Locations::LocationList::const_iterator i = _locations->list ().begin (); i != _locations->list ().end (); ++i) {
1347                                 if ((*i)->is_mark () || (*i)->is_auto_loop ()) {
1348                                         locations_state.add_child_nocopy ((*i)->get_state ());
1349                                 }
1350                         }
1351                 }
1352                 node->add_child_nocopy (locations_state);
1353
1354                 /* adding a location above will have marked the session
1355                  * dirty. This is an artifact, so fix it if the session wasn't
1356                  * already dirty
1357                  */
1358
1359                 if (!was_dirty) {
1360                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
1361                 }
1362         }
1363
1364         child = node->add_child ("Bundles");
1365         {
1366                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1367                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1368                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1369                         if (b) {
1370                                 child->add_child_nocopy (b->get_state());
1371                         }
1372                 }
1373         }
1374
1375         node->add_child_nocopy (_vca_manager->get_state());
1376
1377         child = node->add_child ("Routes");
1378         {
1379                 boost::shared_ptr<RouteList> r = routes.reader ();
1380
1381                 route_id_compare cmp;
1382                 RouteList xml_node_order (*r);
1383                 xml_node_order.sort (cmp);
1384
1385                 for (RouteList::const_iterator i = xml_node_order.begin(); i != xml_node_order.end(); ++i) {
1386                         if (!(*i)->is_auditioner()) {
1387                                 if (full_state) {
1388                                         child->add_child_nocopy ((*i)->get_state());
1389                                 } else {
1390                                         child->add_child_nocopy ((*i)->get_template());
1391                                 }
1392                         }
1393                 }
1394         }
1395
1396         playlists->add_state (node, full_state);
1397
1398         child = node->add_child ("RouteGroups");
1399         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1400                 child->add_child_nocopy ((*i)->get_state());
1401         }
1402
1403         if (_click_io) {
1404                 XMLNode* gain_child = node->add_child ("Click");
1405                 gain_child->add_child_nocopy (_click_io->state (full_state));
1406                 gain_child->add_child_nocopy (_click_gain->state (full_state));
1407         }
1408
1409         if (_ltc_input) {
1410                 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1411                 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1412         }
1413
1414         if (_ltc_input) {
1415                 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1416                 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1417         }
1418
1419         node->add_child_nocopy (_speakers->get_state());
1420         node->add_child_nocopy (_tempo_map->get_state());
1421         node->add_child_nocopy (get_control_protocol_state());
1422
1423         if (_extra_xml) {
1424                 node->add_child_copy (*_extra_xml);
1425         }
1426
1427         {
1428                 Glib::Threads::Mutex::Lock lm (lua_lock);
1429                 std::string saved;
1430                 {
1431                         luabridge::LuaRef savedstate ((*_lua_save)());
1432                         saved = savedstate.cast<std::string>();
1433                 }
1434                 lua.collect_garbage ();
1435                 lm.release ();
1436
1437                 gchar* b64 = g_base64_encode ((const guchar*)saved.c_str (), saved.size ());
1438                 std::string b64s (b64);
1439                 g_free (b64);
1440
1441                 XMLNode* script_node = new XMLNode (X_("Script"));
1442                 script_node->set_property (X_("lua"), LUA_VERSION);
1443                 script_node->add_content (b64s);
1444                 node->add_child_nocopy (*script_node);
1445         }
1446
1447         return *node;
1448 }
1449
1450 XMLNode&
1451 Session::get_control_protocol_state ()
1452 {
1453         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1454         return cpm.get_state();
1455 }
1456
1457 int
1458 Session::set_state (const XMLNode& node, int version)
1459 {
1460         LocaleGuard lg;
1461         XMLNodeList nlist;
1462         XMLNode* child;
1463         int ret = -1;
1464
1465         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1466
1467         if (node.name() != X_("Session")) {
1468                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1469                 goto out;
1470         }
1471
1472         node.get_property ("name", _name);
1473
1474         if (node.get_property (X_("sample-rate"), _base_sample_rate)) {
1475
1476                 _nominal_sample_rate = _base_sample_rate;
1477
1478                 assert (AudioEngine::instance()->running ());
1479                 if (_base_sample_rate != AudioEngine::instance()->sample_rate ()) {
1480                         boost::optional<int> r = AskAboutSampleRateMismatch (_base_sample_rate, _current_sample_rate);
1481                         if (r.get_value_or (0)) {
1482                                 goto out;
1483                         }
1484                 }
1485         }
1486
1487         created_with = "unknown";
1488         if ((child = find_named_node (node, "ProgramVersion")) != 0) {
1489                 child->get_property (X_("created-with"), created_with);
1490         }
1491
1492         setup_raid_path(_session_dir->root_path());
1493
1494         node.get_property (X_("end-is-free"), _session_range_end_is_free);
1495
1496         uint64_t counter;
1497         if (node.get_property (X_("id-counter"), counter)) {
1498                 ID::init_counter (counter);
1499         } else {
1500                 /* old sessions used a timebased counter, so fake
1501                  * the startup ID counter based on a standard
1502                  * timestamp.
1503                  */
1504                 time_t now;
1505                 time (&now);
1506                 ID::init_counter (now);
1507         }
1508
1509         if (node.get_property (X_("name-counter"), counter)) {
1510                 init_name_id_counter (counter);
1511         }
1512
1513         if (node.get_property (X_("event-counter"), counter)) {
1514                 Evoral::init_event_id_counter (counter);
1515         }
1516
1517         if (node.get_property (X_("vca-counter"), counter)) {
1518                 VCA::set_next_vca_number (counter);
1519         } else {
1520                 VCA::set_next_vca_number (1);
1521         }
1522
1523         if ((child = find_named_node (node, "MIDIPorts")) != 0) {
1524                 _midi_ports->set_midi_port_states (child->children());
1525         }
1526
1527         IO::disable_connecting ();
1528
1529         Stateful::save_extra_xml (node);
1530
1531         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1532                 load_options (*child);
1533         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1534                 load_options (*child);
1535         } else {
1536                 error << _("Session: XML state has no options section") << endmsg;
1537         }
1538
1539         if (version >= 3000) {
1540                 if ((child = find_named_node (node, "Metadata")) == 0) {
1541                         warning << _("Session: XML state has no metadata section") << endmsg;
1542                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1543                         goto out;
1544                 }
1545         }
1546
1547         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1548                 _speakers->set_state (*child, version);
1549         }
1550
1551         if ((child = find_named_node (node, "Sources")) == 0) {
1552                 error << _("Session: XML state has no sources section") << endmsg;
1553                 goto out;
1554         } else if (load_sources (*child)) {
1555                 goto out;
1556         }
1557
1558         if ((child = find_named_node (node, "TempoMap")) == 0) {
1559                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1560                 goto out;
1561         } else if (_tempo_map->set_state (*child, version)) {
1562                 goto out;
1563         }
1564
1565         if ((child = find_named_node (node, "Locations")) == 0) {
1566                 error << _("Session: XML state has no locations section") << endmsg;
1567                 goto out;
1568         } else if (_locations->set_state (*child, version)) {
1569                 goto out;
1570         }
1571
1572         locations_changed ();
1573
1574         if (_session_range_location) {
1575                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1576         }
1577
1578         if ((child = find_named_node (node, "Regions")) == 0) {
1579                 error << _("Session: XML state has no Regions section") << endmsg;
1580                 goto out;
1581         } else if (load_regions (*child)) {
1582                 goto out;
1583         }
1584
1585         if ((child = find_named_node (node, "Playlists")) == 0) {
1586                 error << _("Session: XML state has no playlists section") << endmsg;
1587                 goto out;
1588         } else if (playlists->load (*this, *child)) {
1589                 goto out;
1590         }
1591
1592         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1593                 // this is OK
1594         } else if (playlists->load_unused (*this, *child)) {
1595                 goto out;
1596         }
1597
1598         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1599                 if (load_compounds (*child)) {
1600                         goto out;
1601                 }
1602         }
1603
1604         if (version >= 3000) {
1605                 if ((child = find_named_node (node, "Bundles")) == 0) {
1606                         warning << _("Session: XML state has no bundles section") << endmsg;
1607                         //goto out;
1608                 } else {
1609                         /* We can't load Bundles yet as they need to be able
1610                          * to convert from port names to Port objects, which can't happen until
1611                          * later */
1612                         _bundle_xml_node = new XMLNode (*child);
1613                 }
1614         }
1615
1616         if ((child = find_named_node (node, VCAManager::xml_node_name)) != 0) {
1617                 _vca_manager->set_state (*child, version);
1618         }
1619
1620         if ((child = find_named_node (node, "Routes")) == 0) {
1621                 error << _("Session: XML state has no routes section") << endmsg;
1622                 goto out;
1623         } else if (load_routes (*child, version)) {
1624                 goto out;
1625         }
1626
1627         /* Now that we have Routes and masters loaded, connect them if appropriate */
1628
1629         Slavable::Assign (_vca_manager); /* EMIT SIGNAL */
1630
1631         if (version >= 3000) {
1632
1633                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1634                         error << _("Session: XML state has no route groups section") << endmsg;
1635                         goto out;
1636                 } else if (load_route_groups (*child, version)) {
1637                         goto out;
1638                 }
1639
1640         } else if (version < 3000) {
1641
1642                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1643                         error << _("Session: XML state has no edit groups section") << endmsg;
1644                         goto out;
1645                 } else if (load_route_groups (*child, version)) {
1646                         goto out;
1647                 }
1648
1649                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1650                         error << _("Session: XML state has no mix groups section") << endmsg;
1651                         goto out;
1652                 } else if (load_route_groups (*child, version)) {
1653                         goto out;
1654                 }
1655         }
1656
1657         if ((child = find_named_node (node, "Click")) == 0) {
1658                 warning << _("Session: XML state has no click section") << endmsg;
1659         } else if (_click_io) {
1660                 setup_click_state (&node);
1661         }
1662
1663         if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1664                 ControlProtocolManager::instance().set_state (*child, version);
1665         }
1666
1667         if ((child = find_named_node (node, "Script"))) {
1668                 for (XMLNodeList::const_iterator n = child->children ().begin (); n != child->children ().end (); ++n) {
1669                         if (!(*n)->is_content ()) { continue; }
1670                         gsize size;
1671                         guchar* buf = g_base64_decode ((*n)->content ().c_str (), &size);
1672                         try {
1673                                 Glib::Threads::Mutex::Lock lm (lua_lock);
1674                                 (*_lua_load)(std::string ((const char*)buf, size));
1675                         } catch (luabridge::LuaException const& e) {
1676                                 cerr << "LuaException:" << e.what () << endl;
1677                         } catch (...) { }
1678                         g_free (buf);
1679                 }
1680         }
1681
1682         if ((child = find_named_node (node, X_("Selection")))) {
1683                 _selection->set_state (*child, version);
1684         }
1685
1686         update_route_record_state ();
1687
1688         /* here beginneth the second phase ... */
1689         set_snapshot_name (_current_snapshot_name);
1690
1691         StateReady (); /* EMIT SIGNAL */
1692
1693         delete state_tree;
1694         state_tree = 0;
1695         return 0;
1696
1697 out:
1698         delete state_tree;
1699         state_tree = 0;
1700         return ret;
1701 }
1702
1703 int
1704 Session::load_routes (const XMLNode& node, int version)
1705 {
1706         XMLNodeList nlist;
1707         XMLNodeConstIterator niter;
1708         RouteList new_routes;
1709
1710         nlist = node.children();
1711
1712         set_dirty();
1713
1714         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1715
1716                 boost::shared_ptr<Route> route;
1717
1718                 if (version < 3000) {
1719                         route = XMLRouteFactory_2X (**niter, version);
1720                 } else if (version < 5000) {
1721                         route = XMLRouteFactory_3X (**niter, version);
1722                 } else {
1723                         route = XMLRouteFactory (**niter, version);
1724                 }
1725
1726                 if (route == 0) {
1727                         error << _("Session: cannot create Route from XML description.") << endmsg;
1728                         return -1;
1729                 }
1730
1731                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1732
1733                 new_routes.push_back (route);
1734         }
1735
1736         BootMessage (_("Tracks/busses loaded;  Adding to Session"));
1737
1738         add_routes (new_routes, false, false, false, PresentationInfo::max_order);
1739
1740         BootMessage (_("Finished adding tracks/busses"));
1741
1742         return 0;
1743 }
1744
1745 boost::shared_ptr<Route>
1746 Session::XMLRouteFactory (const XMLNode& node, int version)
1747 {
1748         boost::shared_ptr<Route> ret;
1749
1750         if (node.name() != "Route") {
1751                 return ret;
1752         }
1753
1754         XMLProperty const * pl_prop = node.property (X_("audio-playlist"));
1755
1756         if (!pl_prop) {
1757                 pl_prop = node.property (X_("midi-playlist"));
1758         }
1759
1760         DataType type = DataType::AUDIO;
1761         node.get_property("default-type", type);
1762
1763         assert (type != DataType::NIL);
1764
1765         if (pl_prop) {
1766
1767                 /* has at least 1 playlist, therefore a track ... */
1768
1769                 boost::shared_ptr<Track> track;
1770
1771                 if (type == DataType::AUDIO) {
1772                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1773                 } else {
1774                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1775                 }
1776
1777                 if (track->init()) {
1778                         return ret;
1779                 }
1780
1781                 if (track->set_state (node, version)) {
1782                         return ret;
1783                 }
1784
1785                 BOOST_MARK_TRACK (track);
1786                 ret = track;
1787
1788         } else {
1789                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1790                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1791
1792
1793                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1794                         BOOST_MARK_ROUTE (r);
1795                         ret = r;
1796                 }
1797         }
1798
1799         return ret;
1800 }
1801
1802 boost::shared_ptr<Route>
1803 Session::XMLRouteFactory_3X (const XMLNode& node, int version)
1804 {
1805         boost::shared_ptr<Route> ret;
1806
1807         if (node.name() != "Route") {
1808                 return ret;
1809         }
1810
1811         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1812
1813         DataType type = DataType::AUDIO;
1814         node.get_property("default-type", type);
1815
1816         assert (type != DataType::NIL);
1817
1818         if (ds_child) {
1819
1820                 boost::shared_ptr<Track> track;
1821
1822                 if (type == DataType::AUDIO) {
1823                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1824                 } else {
1825                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1826                 }
1827
1828                 if (track->init()) {
1829                         return ret;
1830                 }
1831
1832                 if (track->set_state (node, version)) {
1833                         return ret;
1834                 }
1835
1836                 BOOST_MARK_TRACK (track);
1837                 ret = track;
1838
1839         } else {
1840                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1841                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1842
1843                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1844                         BOOST_MARK_ROUTE (r);
1845                         ret = r;
1846                 }
1847         }
1848
1849         return ret;
1850 }
1851
1852 boost::shared_ptr<Route>
1853 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1854 {
1855         boost::shared_ptr<Route> ret;
1856
1857         if (node.name() != "Route") {
1858                 return ret;
1859         }
1860
1861         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1862         if (!ds_prop) {
1863                 ds_prop = node.property (X_("diskstream"));
1864         }
1865
1866         DataType type = DataType::AUDIO;
1867         node.get_property("default-type", type);
1868
1869         assert (type != DataType::NIL);
1870
1871         if (ds_prop) {
1872
1873                 /* see comment in current ::set_state() regarding diskstream
1874                  * state and DiskReader/DiskWRiter.
1875                  */
1876
1877                 error << _("Could not find diskstream for route") << endmsg;
1878                 return boost::shared_ptr<Route> ();
1879
1880                 boost::shared_ptr<Track> track;
1881
1882                 if (type == DataType::AUDIO) {
1883                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1884                 } else {
1885                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1886                 }
1887
1888                 if (track->init()) {
1889                         return ret;
1890                 }
1891
1892                 if (track->set_state (node, version)) {
1893                         return ret;
1894                 }
1895
1896                 BOOST_MARK_TRACK (track);
1897                 ret = track;
1898
1899         } else {
1900                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1901                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1902
1903                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1904                         BOOST_MARK_ROUTE (r);
1905                         ret = r;
1906                 }
1907         }
1908
1909         return ret;
1910 }
1911
1912 int
1913 Session::load_regions (const XMLNode& node)
1914 {
1915         XMLNodeList nlist;
1916         XMLNodeConstIterator niter;
1917         boost::shared_ptr<Region> region;
1918
1919         nlist = node.children();
1920
1921         set_dirty();
1922
1923         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1924                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1925                         error << _("Session: cannot create Region from XML description.");
1926                         XMLProperty const * name = (**niter).property("name");
1927
1928                         if (name) {
1929                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1930                         }
1931
1932                         error << endmsg;
1933                 }
1934         }
1935
1936         return 0;
1937 }
1938
1939 int
1940 Session::load_compounds (const XMLNode& node)
1941 {
1942         XMLNodeList calist = node.children();
1943         XMLNodeConstIterator caiter;
1944         XMLProperty const * caprop;
1945
1946         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1947                 XMLNode* ca = *caiter;
1948                 ID orig_id;
1949                 ID copy_id;
1950
1951                 if ((caprop = ca->property (X_("original"))) == 0) {
1952                         continue;
1953                 }
1954                 orig_id = caprop->value();
1955
1956                 if ((caprop = ca->property (X_("copy"))) == 0) {
1957                         continue;
1958                 }
1959                 copy_id = caprop->value();
1960
1961                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1962                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1963
1964                 if (!orig || !copy) {
1965                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1966                                                    orig_id, copy_id)
1967                                 << endmsg;
1968                         continue;
1969                 }
1970
1971                 RegionFactory::add_compound_association (orig, copy);
1972         }
1973
1974         return 0;
1975 }
1976
1977 void
1978 Session::load_nested_sources (const XMLNode& node)
1979 {
1980         XMLNodeList nlist;
1981         XMLNodeConstIterator niter;
1982
1983         nlist = node.children();
1984
1985         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1986                 if ((*niter)->name() == "Source") {
1987
1988                         /* it may already exist, so don't recreate it unnecessarily
1989                          */
1990
1991                         XMLProperty const * prop = (*niter)->property (X_("id"));
1992                         if (!prop) {
1993                                 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1994                                 continue;
1995                         }
1996
1997                         ID source_id (prop->value());
1998
1999                         if (!source_by_id (source_id)) {
2000
2001                                 try {
2002                                         SourceFactory::create (*this, **niter, true);
2003                                 }
2004                                 catch (failed_constructor& err) {
2005                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
2006                                 }
2007                         }
2008                 }
2009         }
2010 }
2011
2012 boost::shared_ptr<Region>
2013 Session::XMLRegionFactory (const XMLNode& node, bool full)
2014 {
2015         XMLProperty const * type = node.property("type");
2016
2017         try {
2018
2019                 const XMLNodeList& nlist = node.children();
2020
2021                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
2022                         XMLNode *child = (*niter);
2023                         if (child->name() == "NestedSource") {
2024                                 load_nested_sources (*child);
2025                         }
2026                 }
2027
2028                 if (!type || type->value() == "audio") {
2029                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
2030                 } else if (type->value() == "midi") {
2031                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
2032                 }
2033
2034         } catch (failed_constructor& err) {
2035                 return boost::shared_ptr<Region> ();
2036         }
2037
2038         return boost::shared_ptr<Region> ();
2039 }
2040
2041 boost::shared_ptr<AudioRegion>
2042 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
2043 {
2044         XMLProperty const * prop;
2045         boost::shared_ptr<Source> source;
2046         boost::shared_ptr<AudioSource> as;
2047         SourceList sources;
2048         SourceList master_sources;
2049         uint32_t nchans = 1;
2050         char buf[128];
2051
2052         if (node.name() != X_("Region")) {
2053                 return boost::shared_ptr<AudioRegion>();
2054         }
2055
2056         node.get_property (X_("channels"), nchans);
2057
2058         if ((prop = node.property ("name")) == 0) {
2059                 cerr << "no name for this region\n";
2060                 abort ();
2061         }
2062
2063         if ((prop = node.property (X_("source-0"))) == 0) {
2064                 if ((prop = node.property ("source")) == 0) {
2065                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
2066                         return boost::shared_ptr<AudioRegion>();
2067                 }
2068         }
2069
2070         PBD::ID s_id (prop->value());
2071
2072         if ((source = source_by_id (s_id)) == 0) {
2073                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
2074                 return boost::shared_ptr<AudioRegion>();
2075         }
2076
2077         as = boost::dynamic_pointer_cast<AudioSource>(source);
2078         if (!as) {
2079                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
2080                 return boost::shared_ptr<AudioRegion>();
2081         }
2082
2083         sources.push_back (as);
2084
2085         /* pickup other channels */
2086
2087         for (uint32_t n=1; n < nchans; ++n) {
2088                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
2089                 if ((prop = node.property (buf)) != 0) {
2090
2091                         PBD::ID id2 (prop->value());
2092
2093                         if ((source = source_by_id (id2)) == 0) {
2094                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
2095                                 return boost::shared_ptr<AudioRegion>();
2096                         }
2097
2098                         as = boost::dynamic_pointer_cast<AudioSource>(source);
2099                         if (!as) {
2100                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
2101                                 return boost::shared_ptr<AudioRegion>();
2102                         }
2103                         sources.push_back (as);
2104                 }
2105         }
2106
2107         for (uint32_t n = 0; n < nchans; ++n) {
2108                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
2109                 if ((prop = node.property (buf)) != 0) {
2110
2111                         PBD::ID id2 (prop->value());
2112
2113                         if ((source = source_by_id (id2)) == 0) {
2114                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
2115                                 return boost::shared_ptr<AudioRegion>();
2116                         }
2117
2118                         as = boost::dynamic_pointer_cast<AudioSource>(source);
2119                         if (!as) {
2120                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
2121                                 return boost::shared_ptr<AudioRegion>();
2122                         }
2123                         master_sources.push_back (as);
2124                 }
2125         }
2126
2127         try {
2128                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
2129
2130                 /* a final detail: this is the one and only place that we know how long missing files are */
2131
2132                 if (region->whole_file()) {
2133                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
2134                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
2135                                 if (sfp) {
2136                                         sfp->set_length (region->length());
2137                                 }
2138                         }
2139                 }
2140
2141                 if (!master_sources.empty()) {
2142                         if (master_sources.size() != nchans) {
2143                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
2144                         } else {
2145                                 region->set_master_sources (master_sources);
2146                         }
2147                 }
2148
2149                 return region;
2150
2151         }
2152
2153         catch (failed_constructor& err) {
2154                 return boost::shared_ptr<AudioRegion>();
2155         }
2156 }
2157
2158 boost::shared_ptr<MidiRegion>
2159 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
2160 {
2161         XMLProperty const * prop;
2162         boost::shared_ptr<Source> source;
2163         boost::shared_ptr<MidiSource> ms;
2164         SourceList sources;
2165
2166         if (node.name() != X_("Region")) {
2167                 return boost::shared_ptr<MidiRegion>();
2168         }
2169
2170         if ((prop = node.property ("name")) == 0) {
2171                 cerr << "no name for this region\n";
2172                 abort ();
2173         }
2174
2175         if ((prop = node.property (X_("source-0"))) == 0) {
2176                 if ((prop = node.property ("source")) == 0) {
2177                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
2178                         return boost::shared_ptr<MidiRegion>();
2179                 }
2180         }
2181
2182         PBD::ID s_id (prop->value());
2183
2184         if ((source = source_by_id (s_id)) == 0) {
2185                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
2186                 return boost::shared_ptr<MidiRegion>();
2187         }
2188
2189         ms = boost::dynamic_pointer_cast<MidiSource>(source);
2190         if (!ms) {
2191                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
2192                 return boost::shared_ptr<MidiRegion>();
2193         }
2194
2195         sources.push_back (ms);
2196
2197         try {
2198                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
2199                 /* a final detail: this is the one and only place that we know how long missing files are */
2200
2201                 if (region->whole_file()) {
2202                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
2203                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
2204                                 if (sfp) {
2205                                         sfp->set_length (region->length());
2206                                 }
2207                         }
2208                 }
2209
2210                 return region;
2211         }
2212
2213         catch (failed_constructor& err) {
2214                 return boost::shared_ptr<MidiRegion>();
2215         }
2216 }
2217
2218 XMLNode&
2219 Session::get_sources_as_xml ()
2220
2221 {
2222         XMLNode* node = new XMLNode (X_("Sources"));
2223         Glib::Threads::Mutex::Lock lm (source_lock);
2224
2225         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2226                 node->add_child_nocopy (i->second->get_state());
2227         }
2228
2229         return *node;
2230 }
2231
2232 void
2233 Session::reset_write_sources (bool mark_write_complete, bool force)
2234 {
2235         boost::shared_ptr<RouteList> rl = routes.reader();
2236         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2237                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2238                 if (tr) {
2239                         _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
2240                         tr->reset_write_sources(mark_write_complete, force);
2241                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
2242                 }
2243         }
2244 }
2245
2246 int
2247 Session::load_sources (const XMLNode& node)
2248 {
2249         XMLNodeList nlist;
2250         XMLNodeConstIterator niter;
2251         /* don't need this but it stops some
2252          * versions of gcc complaining about
2253          * discarded return values.
2254          */
2255         boost::shared_ptr<Source> source;
2256
2257         nlist = node.children();
2258
2259         set_dirty();
2260         std::map<std::string, std::string> relocation;
2261
2262         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2263 #ifdef PLATFORM_WINDOWS
2264                 int old_mode = 0;
2265 #endif
2266
2267                 XMLNode srcnode (**niter);
2268                 bool try_replace_abspath = true;
2269
2270 retry:
2271                 try {
2272 #ifdef PLATFORM_WINDOWS
2273                         // do not show "insert media" popups (files embedded from removable media).
2274                         old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
2275 #endif
2276                         if ((source = XMLSourceFactory (srcnode)) == 0) {
2277                                 error << _("Session: cannot create Source from XML description.") << endmsg;
2278                         }
2279 #ifdef PLATFORM_WINDOWS
2280                         SetErrorMode(old_mode);
2281 #endif
2282
2283                 } catch (MissingSource& err) {
2284 #ifdef PLATFORM_WINDOWS
2285                         SetErrorMode(old_mode);
2286 #endif
2287
2288                         /* try previous abs path replacements first */
2289                         if (try_replace_abspath && Glib::path_is_absolute (err.path)) {
2290                                 std::string dir = Glib::path_get_dirname (err.path);
2291                                 std::map<std::string, std::string>::const_iterator rl = relocation.find (dir);
2292                                 if (rl != relocation.end ()) {
2293                                         std::string newpath = Glib::build_filename (rl->second, Glib::path_get_basename (err.path));
2294                                         if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2295                                                 srcnode.set_property ("origin", newpath);
2296                                                 try_replace_abspath = false;
2297                                                 goto retry;
2298                                         }
2299                                 }
2300                         }
2301
2302                         int user_choice;
2303                         _missing_file_replacement = "";
2304
2305                         if (err.type == DataType::MIDI && Glib::path_is_absolute (err.path)) {
2306                                 error << string_compose (_("An external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
2307                                                 PROGRAM_NAME) << endmsg;
2308                                 return -1;
2309                         }
2310
2311                         if (!no_questions_about_missing_files) {
2312                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
2313                         } else {
2314                                 user_choice = -2;
2315                         }
2316
2317                         switch (user_choice) {
2318                                 case 0:
2319                                         /* user added a new search location
2320                                          * or selected a new absolute path,
2321                                          * so try again */
2322                                         if (Glib::path_is_absolute (err.path)) {
2323                                                 if (!_missing_file_replacement.empty ()) {
2324                                                         /* replace origin, in XML */
2325                                                         std::string newpath = Glib::build_filename (
2326                                                                         _missing_file_replacement, Glib::path_get_basename (err.path));
2327                                                         srcnode.set_property ("origin", newpath);
2328                                                         relocation[Glib::path_get_dirname (err.path)] = _missing_file_replacement;
2329                                                         _missing_file_replacement = "";
2330                                                 }
2331                                         }
2332                                         goto retry;
2333
2334
2335                                 case 1:
2336                                         /* user asked to quit the entire session load */
2337                                         return -1;
2338
2339                                 case 2:
2340                                         no_questions_about_missing_files = true;
2341                                         goto retry;
2342
2343                                 case 3:
2344                                         no_questions_about_missing_files = true;
2345                                         /* fallthru */
2346
2347                                 case -1:
2348                                 default:
2349                                         switch (err.type) {
2350
2351                                                 case DataType::AUDIO:
2352                                                         source = SourceFactory::createSilent (*this, **niter, max_samplecnt, _current_sample_rate);
2353                                                         break;
2354
2355                                                 case DataType::MIDI:
2356                                                         /* The MIDI file is actually missing so
2357                                                          * just create a new one in the same
2358                                                          * location. Do not announce its
2359                                                          */
2360                                                         string fullpath;
2361
2362                                                         if (!Glib::path_is_absolute (err.path)) {
2363                                                                 fullpath = Glib::build_filename (source_search_path (DataType::MIDI).front(), err.path);
2364                                                         } else {
2365                                                                 /* this should be an unrecoverable error: we would be creating a MIDI file outside
2366                                                                  * the session tree.
2367                                                                  */
2368                                                                 return -1;
2369                                                         }
2370                                                         /* Note that we do not announce the source just yet - we need to reset its ID before we do that */
2371                                                         source = SourceFactory::createWritable (DataType::MIDI, *this, fullpath, false, _current_sample_rate, false, false);
2372                                                         /* reset ID to match the missing one */
2373                                                         source->set_id (**niter);
2374                                                         /* Now we can announce it */
2375                                                         SourceFactory::SourceCreated (source);
2376                                                         break;
2377                                         }
2378                                         break;
2379                         }
2380                 }
2381         }
2382
2383         return 0;
2384 }
2385
2386 boost::shared_ptr<Source>
2387 Session::XMLSourceFactory (const XMLNode& node)
2388 {
2389         if (node.name() != "Source") {
2390                 return boost::shared_ptr<Source>();
2391         }
2392
2393         try {
2394                 /* note: do peak building in another thread when loading session state */
2395                 return SourceFactory::create (*this, node, true);
2396         }
2397
2398         catch (failed_constructor& err) {
2399                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the programmers."), PROGRAM_NAME) << endmsg;
2400                 return boost::shared_ptr<Source>();
2401         }
2402 }
2403
2404 int
2405 Session::save_template (const string& template_name, const string& description, bool replace_existing)
2406 {
2407         if ((_state_of_the_state & CannotSave) || template_name.empty ()) {
2408                 return -1;
2409         }
2410
2411         bool absolute_path = Glib::path_is_absolute (template_name);
2412
2413         /* directory to put the template in */
2414         std::string template_dir_path;
2415
2416         if (!absolute_path) {
2417                 std::string user_template_dir(user_template_directory());
2418
2419                 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2420                         error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2421                                         user_template_dir, g_strerror (errno)) << endmsg;
2422                         return -1;
2423                 }
2424
2425                 template_dir_path = Glib::build_filename (user_template_dir, template_name);
2426         } else {
2427                 template_dir_path = template_name;
2428         }
2429
2430         if (!ARDOUR::Profile->get_trx()) {
2431                 if (!replace_existing && Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2432                         warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2433                                                                           template_dir_path) << endmsg;
2434                         return -2;
2435                 }
2436
2437                 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2438                         error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2439                                                                         template_dir_path, g_strerror (errno)) << endmsg;
2440                         return -1;
2441                 }
2442         }
2443
2444         /* file to write */
2445         std::string template_file_path;
2446
2447         if (ARDOUR::Profile->get_trx()) {
2448                 template_file_path = template_name;
2449         } else {
2450                 if (absolute_path) {
2451                         template_file_path = Glib::build_filename (template_dir_path, Glib::path_get_basename (template_dir_path) + template_suffix);
2452                 } else {
2453                         template_file_path = Glib::build_filename (template_dir_path, template_name + template_suffix);
2454                 }
2455         }
2456
2457         SessionSaveUnderway (); /* EMIT SIGNAL */
2458
2459         XMLTree tree;
2460         XMLNode* root;
2461         {
2462                 PBD::Unwinder<std::string> uw (_template_state_dir, template_dir_path);
2463                 root = &get_template ();
2464         }
2465
2466         root->remove_nodes_and_delete (X_("description"));
2467
2468         if (!description.empty()) {
2469                 XMLNode* desc = new XMLNode (X_("description"));
2470                 XMLNode* desc_cont = new XMLNode (X_("content"), description);
2471                 desc->add_child_nocopy (*desc_cont);
2472
2473                 root->add_child_nocopy (*desc);
2474         }
2475
2476         tree.set_root (root);
2477
2478         if (!tree.write (template_file_path)) {
2479                 error << _("template not saved") << endmsg;
2480                 return -1;
2481         }
2482
2483         store_recent_templates (template_file_path);
2484
2485         return 0;
2486 }
2487
2488 void
2489 Session::refresh_disk_space ()
2490 {
2491 #if __APPLE__ || __FreeBSD__ || __NetBSD__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2492
2493         Glib::Threads::Mutex::Lock lm (space_lock);
2494
2495         /* get freespace on every FS that is part of the session path */
2496
2497         _total_free_4k_blocks = 0;
2498         _total_free_4k_blocks_uncertain = false;
2499
2500         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2501 #if defined(__NetBSD__)
2502                 struct statvfs statfsbuf;
2503
2504                 statvfs (i->path.c_str(), &statfsbuf);
2505 #else
2506                 struct statfs statfsbuf;
2507
2508                 statfs (i->path.c_str(), &statfsbuf);
2509 #endif
2510                 double const scale = statfsbuf.f_bsize / 4096.0;
2511
2512                 /* See if this filesystem is read-only */
2513                 struct statvfs statvfsbuf;
2514                 statvfs (i->path.c_str(), &statvfsbuf);
2515
2516                 /* f_bavail can be 0 if it is undefined for whatever
2517                    filesystem we are looking at; Samba shares mounted
2518                    via GVFS are an example of this.
2519                 */
2520                 if (statfsbuf.f_bavail == 0) {
2521                         /* block count unknown */
2522                         i->blocks = 0;
2523                         i->blocks_unknown = true;
2524                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2525                         /* read-only filesystem */
2526                         i->blocks = 0;
2527                         i->blocks_unknown = false;
2528                 } else {
2529                         /* read/write filesystem with known space */
2530                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2531                         i->blocks_unknown = false;
2532                 }
2533
2534                 _total_free_4k_blocks += i->blocks;
2535                 if (i->blocks_unknown) {
2536                         _total_free_4k_blocks_uncertain = true;
2537                 }
2538         }
2539 #elif defined PLATFORM_WINDOWS
2540         vector<string> scanned_volumes;
2541         vector<string>::iterator j;
2542         vector<space_and_path>::iterator i;
2543         DWORD nSectorsPerCluster, nBytesPerSector,
2544               nFreeClusters, nTotalClusters;
2545         char disk_drive[4];
2546         bool volume_found;
2547
2548         _total_free_4k_blocks = 0;
2549
2550         for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2551                 strncpy (disk_drive, (*i).path.c_str(), 3);
2552                 disk_drive[3] = 0;
2553                 strupr(disk_drive);
2554
2555                 volume_found = false;
2556                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2557                 {
2558                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2559                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2560                         i->blocks = (uint32_t)(nFreeBytes / 4096);
2561
2562                         for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2563                                 if (0 == j->compare(disk_drive)) {
2564                                         volume_found = true;
2565                                         break;
2566                                 }
2567                         }
2568
2569                         if (!volume_found) {
2570                                 scanned_volumes.push_back(disk_drive);
2571                                 _total_free_4k_blocks += i->blocks;
2572                         }
2573                 }
2574         }
2575
2576         if (0 == _total_free_4k_blocks) {
2577                 strncpy (disk_drive, path().c_str(), 3);
2578                 disk_drive[3] = 0;
2579
2580                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2581                 {
2582                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2583                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2584                         _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2585                 }
2586         }
2587 #endif
2588 }
2589
2590 string
2591 Session::get_best_session_directory_for_new_audio ()
2592 {
2593         vector<space_and_path>::iterator i;
2594         string result = _session_dir->root_path();
2595
2596         /* handle common case without system calls */
2597
2598         if (session_dirs.size() == 1) {
2599                 return result;
2600         }
2601
2602         /* OK, here's the algorithm we're following here:
2603
2604         We want to select which directory to use for
2605         the next file source to be created. Ideally,
2606         we'd like to use a round-robin process so as to
2607         get maximum performance benefits from splitting
2608         the files across multiple disks.
2609
2610         However, in situations without much diskspace, an
2611         RR approach may end up filling up a filesystem
2612         with new files while others still have space.
2613         Its therefore important to pay some attention to
2614         the freespace in the filesystem holding each
2615         directory as well. However, if we did that by
2616         itself, we'd keep creating new files in the file
2617         system with the most space until it was as full
2618         as all others, thus negating any performance
2619         benefits of this RAID-1 like approach.
2620
2621         So, we use a user-configurable space threshold. If
2622         there are at least 2 filesystems with more than this
2623         much space available, we use RR selection between them.
2624         If not, then we pick the filesystem with the most space.
2625
2626         This gets a good balance between the two
2627         approaches.
2628         */
2629
2630         refresh_disk_space ();
2631
2632         int free_enough = 0;
2633
2634         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2635                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2636                         free_enough++;
2637                 }
2638         }
2639
2640         if (free_enough >= 2) {
2641                 /* use RR selection process, ensuring that the one
2642                    picked works OK.
2643                 */
2644
2645                 i = last_rr_session_dir;
2646
2647                 do {
2648                         if (++i == session_dirs.end()) {
2649                                 i = session_dirs.begin();
2650                         }
2651
2652                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2653                                 SessionDirectory sdir(i->path);
2654                                 if (sdir.create ()) {
2655                                         result = (*i).path;
2656                                         last_rr_session_dir = i;
2657                                         return result;
2658                                 }
2659                         }
2660
2661                 } while (i != last_rr_session_dir);
2662
2663         } else {
2664
2665                 /* pick FS with the most freespace (and that
2666                    seems to actually work ...)
2667                 */
2668
2669                 vector<space_and_path> sorted;
2670                 space_and_path_ascending_cmp cmp;
2671
2672                 sorted = session_dirs;
2673                 sort (sorted.begin(), sorted.end(), cmp);
2674
2675                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2676                         SessionDirectory sdir(i->path);
2677                         if (sdir.create ()) {
2678                                 result = (*i).path;
2679                                 last_rr_session_dir = i;
2680                                 return result;
2681                         }
2682                 }
2683         }
2684
2685         return result;
2686 }
2687
2688 string
2689 Session::automation_dir () const
2690 {
2691         return Glib::build_filename (_path, automation_dir_name);
2692 }
2693
2694 string
2695 Session::analysis_dir () const
2696 {
2697         return Glib::build_filename (_path, analysis_dir_name);
2698 }
2699
2700 string
2701 Session::plugins_dir () const
2702 {
2703         return Glib::build_filename (_path, plugins_dir_name);
2704 }
2705
2706 string
2707 Session::externals_dir () const
2708 {
2709         return Glib::build_filename (_path, externals_dir_name);
2710 }
2711
2712 int
2713 Session::load_bundles (XMLNode const & node)
2714 {
2715         XMLNodeList nlist = node.children();
2716         XMLNodeConstIterator niter;
2717
2718         set_dirty();
2719
2720         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2721                 if ((*niter)->name() == "InputBundle") {
2722                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2723                 } else if ((*niter)->name() == "OutputBundle") {
2724                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2725                 } else {
2726                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2727                         return -1;
2728                 }
2729         }
2730
2731         return 0;
2732 }
2733
2734 int
2735 Session::load_route_groups (const XMLNode& node, int version)
2736 {
2737         XMLNodeList nlist = node.children();
2738         XMLNodeConstIterator niter;
2739
2740         set_dirty ();
2741
2742         if (version >= 3000) {
2743
2744                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2745                         if ((*niter)->name() == "RouteGroup") {
2746                                 RouteGroup* rg = new RouteGroup (*this, "");
2747                                 add_route_group (rg);
2748                                 rg->set_state (**niter, version);
2749                         }
2750                 }
2751
2752         } else if (version < 3000) {
2753
2754                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2755                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2756                                 RouteGroup* rg = new RouteGroup (*this, "");
2757                                 add_route_group (rg);
2758                                 rg->set_state (**niter, version);
2759                         }
2760                 }
2761         }
2762
2763         return 0;
2764 }
2765
2766 static bool
2767 state_file_filter (const string &str, void* /*arg*/)
2768 {
2769         return (str.length() > strlen(statefile_suffix) &&
2770                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2771 }
2772
2773 static string
2774 remove_end(string state)
2775 {
2776         string statename(state);
2777
2778         string::size_type start,end;
2779         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2780                 statename = statename.substr (start+1);
2781         }
2782
2783         if ((end = statename.rfind(statefile_suffix)) == string::npos) {
2784                 end = statename.length();
2785         }
2786
2787         return string(statename.substr (0, end));
2788 }
2789
2790 vector<string>
2791 Session::possible_states (string path)
2792 {
2793         vector<string> states;
2794         find_files_matching_filter (states, path, state_file_filter, 0, false, false);
2795
2796         transform(states.begin(), states.end(), states.begin(), remove_end);
2797
2798         sort (states.begin(), states.end());
2799
2800         return states;
2801 }
2802
2803 vector<string>
2804 Session::possible_states () const
2805 {
2806         return possible_states(_path);
2807 }
2808
2809 RouteGroup*
2810 Session::new_route_group (const std::string& name)
2811 {
2812         RouteGroup* rg = NULL;
2813
2814         for (std::list<RouteGroup*>::const_iterator i = _route_groups.begin (); i != _route_groups.end (); ++i) {
2815                 if ((*i)->name () == name) {
2816                         rg = *i;
2817                         break;
2818                 }
2819         }
2820
2821         if (!rg) {
2822                 rg = new RouteGroup (*this, name);
2823                 add_route_group (rg);
2824         }
2825         return (rg);
2826 }
2827
2828 void
2829 Session::add_route_group (RouteGroup* g)
2830 {
2831         _route_groups.push_back (g);
2832         route_group_added (g); /* EMIT SIGNAL */
2833
2834         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2835         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2836         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2837
2838         set_dirty ();
2839 }
2840
2841 void
2842 Session::remove_route_group (RouteGroup& rg)
2843 {
2844         list<RouteGroup*>::iterator i;
2845
2846         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2847                 _route_groups.erase (i);
2848                 delete &rg;
2849
2850                 route_group_removed (); /* EMIT SIGNAL */
2851         }
2852 }
2853
2854 /** Set a new order for our route groups, without adding or removing any.
2855  *  @param groups Route group list in the new order.
2856  */
2857 void
2858 Session::reorder_route_groups (list<RouteGroup*> groups)
2859 {
2860         _route_groups = groups;
2861
2862         route_groups_reordered (); /* EMIT SIGNAL */
2863         set_dirty ();
2864 }
2865
2866
2867 RouteGroup *
2868 Session::route_group_by_name (string name)
2869 {
2870         list<RouteGroup *>::iterator i;
2871
2872         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2873                 if ((*i)->name() == name) {
2874                         return* i;
2875                 }
2876         }
2877         return 0;
2878 }
2879
2880 RouteGroup&
2881 Session::all_route_group() const
2882 {
2883         return *_all_route_group;
2884 }
2885
2886 void
2887 Session::add_commands (vector<Command*> const & cmds)
2888 {
2889         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2890                 add_command (*i);
2891         }
2892 }
2893
2894 void
2895 Session::add_command (Command* const cmd)
2896 {
2897         assert (_current_trans);
2898         DEBUG_UNDO_HISTORY (
2899             string_compose ("Current Undo Transaction %1, adding command: %2",
2900                             _current_trans->name (),
2901                             cmd->name ()));
2902         _current_trans->add_command (cmd);
2903 }
2904
2905 PBD::StatefulDiffCommand*
2906 Session::add_stateful_diff_command (boost::shared_ptr<PBD::StatefulDestructible> sfd)
2907 {
2908         PBD::StatefulDiffCommand* cmd = new PBD::StatefulDiffCommand (sfd);
2909         add_command (cmd);
2910         return cmd;
2911 }
2912
2913 void
2914 Session::begin_reversible_command (const string& name)
2915 {
2916         begin_reversible_command (g_quark_from_string (name.c_str ()));
2917 }
2918
2919 /** Begin a reversible command using a GQuark to identify it.
2920  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2921  *  but there must be as many begin...()s as there are commit...()s.
2922  */
2923 void
2924 Session::begin_reversible_command (GQuark q)
2925 {
2926         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2927            to hold all the commands that are committed.  This keeps the order of
2928            commands correct in the history.
2929         */
2930
2931         if (_current_trans == 0) {
2932                 DEBUG_UNDO_HISTORY (string_compose (
2933                     "Begin Reversible Command, new transaction: %1", g_quark_to_string (q)));
2934
2935                 /* start a new transaction */
2936                 assert (_current_trans_quarks.empty ());
2937                 _current_trans = new UndoTransaction();
2938                 _current_trans->set_name (g_quark_to_string (q));
2939         } else {
2940                 DEBUG_UNDO_HISTORY (
2941                     string_compose ("Begin Reversible Command, current transaction: %1",
2942                                     _current_trans->name ()));
2943         }
2944
2945         _current_trans_quarks.push_front (q);
2946 }
2947
2948 void
2949 Session::abort_reversible_command ()
2950 {
2951         if (_current_trans != 0) {
2952                 DEBUG_UNDO_HISTORY (
2953                     string_compose ("Abort Reversible Command: %1", _current_trans->name ()));
2954                 _current_trans->clear();
2955                 delete _current_trans;
2956                 _current_trans = 0;
2957                 _current_trans_quarks.clear();
2958         }
2959 }
2960
2961 void
2962 Session::commit_reversible_command (Command *cmd)
2963 {
2964         assert (_current_trans);
2965         assert (!_current_trans_quarks.empty ());
2966
2967         struct timeval now;
2968
2969         if (cmd) {
2970                 DEBUG_UNDO_HISTORY (
2971                     string_compose ("Current Undo Transaction %1, adding command: %2",
2972                                     _current_trans->name (),
2973                                     cmd->name ()));
2974                 _current_trans->add_command (cmd);
2975         }
2976
2977         DEBUG_UNDO_HISTORY (
2978             string_compose ("Commit Reversible Command, current transaction: %1",
2979                             _current_trans->name ()));
2980
2981         _current_trans_quarks.pop_front ();
2982
2983         if (!_current_trans_quarks.empty ()) {
2984                 DEBUG_UNDO_HISTORY (
2985                     string_compose ("Commit Reversible Command, transaction is not "
2986                                     "top-level, current transaction: %1",
2987                                     _current_trans->name ()));
2988                 /* the transaction we're committing is not the top-level one */
2989                 return;
2990         }
2991
2992         if (_current_trans->empty()) {
2993                 /* no commands were added to the transaction, so just get rid of it */
2994                 DEBUG_UNDO_HISTORY (
2995                     string_compose ("Commit Reversible Command, No commands were "
2996                                     "added to current transaction: %1",
2997                                     _current_trans->name ()));
2998                 delete _current_trans;
2999                 _current_trans = 0;
3000                 return;
3001         }
3002
3003         gettimeofday (&now, 0);
3004         _current_trans->set_timestamp (now);
3005
3006         _history.add (_current_trans);
3007         _current_trans = 0;
3008 }
3009
3010 static bool
3011 accept_all_audio_files (const string& path, void* /*arg*/)
3012 {
3013         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
3014                 return false;
3015         }
3016
3017         if (!AudioFileSource::safe_audio_file_extension (path)) {
3018                 return false;
3019         }
3020
3021         return true;
3022 }
3023
3024 static bool
3025 accept_all_midi_files (const string& path, void* /*arg*/)
3026 {
3027         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
3028                 return false;
3029         }
3030
3031         return (   (path.length() > 4 && path.find (".mid") != (path.length() - 4))
3032                 || (path.length() > 4 && path.find (".smf") != (path.length() - 4))
3033                 || (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
3034 }
3035
3036 static bool
3037 accept_all_state_files (const string& path, void* /*arg*/)
3038 {
3039         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
3040                 return false;
3041         }
3042
3043         std::string const statefile_ext (statefile_suffix);
3044         if (path.length() >= statefile_ext.length()) {
3045                 return (0 == path.compare (path.length() - statefile_ext.length(), statefile_ext.length(), statefile_ext));
3046         } else {
3047                 return false;
3048         }
3049 }
3050
3051 int
3052 Session::find_all_sources (string path, set<string>& result)
3053 {
3054         XMLTree tree;
3055         XMLNode* node;
3056
3057         if (!tree.read (path)) {
3058                 return -1;
3059         }
3060
3061         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
3062                 return -2;
3063         }
3064
3065         XMLNodeList nlist;
3066         XMLNodeConstIterator niter;
3067
3068         nlist = node->children();
3069
3070         set_dirty();
3071
3072         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
3073
3074                 XMLProperty const * prop;
3075
3076                 if ((prop = (*niter)->property (X_("type"))) == 0) {
3077                         continue;
3078                 }
3079
3080                 DataType type (prop->value());
3081
3082                 if ((prop = (*niter)->property (X_("name"))) == 0) {
3083                         continue;
3084                 }
3085
3086                 if (Glib::path_is_absolute (prop->value())) {
3087                         /* external file, ignore */
3088                         continue;
3089                 }
3090
3091                 string found_path;
3092                 bool is_new;
3093                 uint16_t chan;
3094
3095                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
3096                         result.insert (found_path);
3097                 }
3098         }
3099
3100         return 0;
3101 }
3102
3103 int
3104 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
3105 {
3106         vector<string> state_files;
3107         string ripped;
3108         string this_snapshot_path;
3109
3110         result.clear ();
3111
3112         ripped = _path;
3113
3114         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
3115                 ripped = ripped.substr (0, ripped.length() - 1);
3116         }
3117
3118         find_files_matching_filter (state_files, ripped, accept_all_state_files, (void *) 0, true, true);
3119
3120         if (state_files.empty()) {
3121                 /* impossible! */
3122                 return 0;
3123         }
3124
3125         this_snapshot_path = Glib::build_filename (_path, legalize_for_path (_current_snapshot_name));
3126         this_snapshot_path += statefile_suffix;
3127
3128         for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
3129
3130                 cerr << "Looking at snapshot " << (*i) << " ( with this = [" << this_snapshot_path << "])\n";
3131
3132                 if (exclude_this_snapshot && *i == this_snapshot_path) {
3133                         cerr << "\texcluded\n";
3134                         continue;
3135
3136                 }
3137
3138                 if (find_all_sources (*i, result) < 0) {
3139                         return -1;
3140                 }
3141         }
3142
3143         return 0;
3144 }
3145
3146 struct RegionCounter {
3147         typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
3148         AudioSourceList::iterator iter;
3149         boost::shared_ptr<Region> region;
3150         uint32_t count;
3151
3152         RegionCounter() : count (0) {}
3153 };
3154
3155 int
3156 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
3157 {
3158         boost::optional<int> r = AskAboutPlaylistDeletion (p);
3159         return r.get_value_or (1);
3160 }
3161
3162 void
3163 Session::cleanup_regions ()
3164 {
3165         bool removed = false;
3166         const RegionFactory::RegionMap& regions (RegionFactory::regions());
3167
3168         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
3169
3170                 uint32_t used = playlists->region_use_count (i->second);
3171
3172                 if (used == 0 && !i->second->automatic ()) {
3173                         boost::weak_ptr<Region> w = i->second;
3174                         ++i;
3175                         removed = true;
3176                         RegionFactory::map_remove (w);
3177                 } else {
3178                         ++i;
3179                 }
3180         }
3181
3182         if (removed) {
3183                 // re-check to remove parent references of compound regions
3184                 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
3185                         if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
3186                                 ++i;
3187                                 continue;
3188                         }
3189                         assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
3190                         if (0 == playlists->region_use_count (i->second)) {
3191                                 boost::weak_ptr<Region> w = i->second;
3192                                 ++i;
3193                                 RegionFactory::map_remove (w);
3194                         } else {
3195                                 ++i;
3196                         }
3197                 }
3198         }
3199
3200         /* dump the history list */
3201         _history.clear ();
3202
3203         save_state ("");
3204 }
3205
3206 bool
3207 Session::can_cleanup_peakfiles () const
3208 {
3209         if (deletion_in_progress()) {
3210                 return false;
3211         }
3212         if (!_writable || (_state_of_the_state & CannotSave)) {
3213                 warning << _("Cannot cleanup peak-files for read-only session.") << endmsg;
3214                 return false;
3215         }
3216         if (record_status() == Recording) {
3217                 error << _("Cannot cleanup peak-files while recording") << endmsg;
3218                 return false;
3219         }
3220         return true;
3221 }
3222
3223 int
3224 Session::cleanup_peakfiles ()
3225 {
3226         Glib::Threads::Mutex::Lock lm (peak_cleanup_lock, Glib::Threads::TRY_LOCK);
3227         if (!lm.locked()) {
3228                 return -1;
3229         }
3230
3231         assert (can_cleanup_peakfiles ());
3232         assert (!peaks_cleanup_in_progres());
3233
3234         _state_of_the_state = StateOfTheState (_state_of_the_state | PeakCleanup);
3235
3236         int timeout = 5000; // 5 seconds
3237         while (!SourceFactory::files_with_peaks.empty()) {
3238                 Glib::usleep (1000);
3239                 if (--timeout < 0) {
3240                         warning << _("Timeout waiting for peak-file creation to terminate before cleanup, please try again later.") << endmsg;
3241                         _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
3242                         return -1;
3243                 }
3244         }
3245
3246         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3247                 boost::shared_ptr<AudioSource> as;
3248                 if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
3249                         as->close_peakfile();
3250                 }
3251         }
3252
3253         PBD::clear_directory (session_directory().peak_path());
3254
3255         _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
3256
3257         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3258                 boost::shared_ptr<AudioSource> as;
3259                 if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
3260                         SourceFactory::setup_peakfile(as, true);
3261                 }
3262         }
3263         return 0;
3264 }
3265
3266 static void
3267 merge_all_sources (boost::shared_ptr<const Playlist> pl, std::set<boost::shared_ptr<Source> >* all_sources)
3268 {
3269         pl->deep_sources (*all_sources);
3270 }
3271
3272 int
3273 Session::cleanup_sources (CleanupReport& rep)
3274 {
3275         // FIXME: needs adaptation to midi
3276
3277         vector<boost::shared_ptr<Source> > dead_sources;
3278         string audio_path;
3279         string midi_path;
3280         vector<string> candidates;
3281         vector<string> unused;
3282         set<string> sources_used_by_all_snapshots;
3283         string spath;
3284         int ret = -1;
3285         string tmppath1;
3286         string tmppath2;
3287         Searchpath asp;
3288         Searchpath msp;
3289         set<boost::shared_ptr<Source> > sources_used_by_this_snapshot;
3290
3291         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
3292
3293         /* this is mostly for windows which doesn't allow file
3294          * renaming if the file is in use. But we don't special
3295          * case it because we need to know if this causes
3296          * problems, and the easiest way to notice that is to
3297          * keep it in place for all platforms.
3298          */
3299
3300         request_stop (false);
3301         _butler->summon ();
3302         _butler->wait_until_finished ();
3303
3304         /* consider deleting all unused playlists */
3305
3306         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
3307                 ret = 0;
3308                 goto out;
3309         }
3310
3311         /* sync the "all regions" property of each playlist with its current state */
3312
3313         playlists->sync_all_regions_with_regions ();
3314
3315         /* find all un-used sources */
3316
3317         rep.paths.clear ();
3318         rep.space = 0;
3319
3320         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
3321
3322                 SourceMap::iterator tmp;
3323
3324                 tmp = i;
3325                 ++tmp;
3326
3327                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
3328                  * capture files.
3329                  */
3330
3331                 if (!i->second->used() && (i->second->length(i->second->timeline_position()) > 0)) {
3332                         dead_sources.push_back (i->second);
3333                         i->second->drop_references ();
3334                 }
3335
3336                 i = tmp;
3337         }
3338
3339         /* build a list of all the possible audio directories for the session */
3340
3341         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3342                 SessionDirectory sdir ((*i).path);
3343                 asp += sdir.sound_path();
3344         }
3345         audio_path += asp.to_string();
3346
3347
3348         /* build a list of all the possible midi directories for the session */
3349
3350         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3351                 SessionDirectory sdir ((*i).path);
3352                 msp += sdir.midi_path();
3353         }
3354         midi_path += msp.to_string();
3355
3356         find_files_matching_filter (candidates, audio_path, accept_all_audio_files, (void *) 0, true, true);
3357         find_files_matching_filter (candidates, midi_path, accept_all_midi_files, (void *) 0, true, true);
3358
3359         /* add sources from all other snapshots as "used", but don't use this
3360                  snapshot because the state file on disk still references sources we
3361                  may have already dropped.
3362                  */
3363
3364         find_all_sources_across_snapshots (sources_used_by_all_snapshots, true);
3365
3366         /* Although the region factory has a list of all regions ever created
3367          * for this session, we're only interested in regions actually in
3368          * playlists right now. So merge all playlist regions lists together.
3369          *
3370          * This will include the playlists used within compound regions.
3371          */
3372
3373         playlists->foreach (boost::bind (merge_all_sources, _1, &sources_used_by_this_snapshot));
3374
3375         /*  add our current source list
3376         */
3377
3378         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
3379                 boost::shared_ptr<FileSource> fs;
3380                 SourceMap::iterator tmp = i;
3381                 ++tmp;
3382
3383                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) == 0) {
3384                         /* not a file */
3385                         i = tmp;
3386                         continue;
3387                 }
3388
3389                 /* this is mostly for windows which doesn't allow file
3390                  * renaming if the file is in use. But we do not special
3391                  * case it because we need to know if this causes
3392                  * problems, and the easiest way to notice that is to
3393                  * keep it in place for all platforms.
3394                  */
3395
3396                 fs->close ();
3397
3398                 if (!fs->is_stub()) {
3399
3400                         /* Note that we're checking a list of all
3401                          * sources across all snapshots with the list
3402                          * of sources used by this snapshot.
3403                          */
3404
3405                         if (sources_used_by_this_snapshot.find (i->second) != sources_used_by_this_snapshot.end()) {
3406                                 /* this source is in use by this snapshot */
3407                                 sources_used_by_all_snapshots.insert (fs->path());
3408                                 cerr << "Source from source list found in used_by_this_snapshot (" << fs->path() << ")\n";
3409                         } else {
3410                                 cerr << "Source from source list NOT found in used_by_this_snapshot (" << fs->path() << ")\n";
3411                                 /* this source is NOT in use by this snapshot */
3412
3413                                 /* remove all related regions from RegionFactory master list */
3414
3415                                 RegionFactory::remove_regions_using_source (i->second);
3416
3417                                 /* remove from our current source list
3418                                  * also. We may not remove it from
3419                                  * disk, because it may be used by
3420                                  * other snapshots, but it isn't used inside this
3421                                  * snapshot anymore, so we don't need a
3422                                  * reference to it.
3423                                  */
3424
3425                                 sources.erase (i);
3426                         }
3427                 }
3428
3429                 i = tmp;
3430         }
3431
3432         /* now check each candidate source to see if it exists in the list of
3433          * sources_used_by_all_snapshots. If it doesn't, put it into "unused".
3434          */
3435
3436         cerr << "Candidates: " << candidates.size() << endl;
3437         cerr << "Used by others: " << sources_used_by_all_snapshots.size() << endl;
3438
3439         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
3440
3441                 bool used = false;
3442                 spath = *x;
3443
3444                 for (set<string>::iterator i = sources_used_by_all_snapshots.begin(); i != sources_used_by_all_snapshots.end(); ++i) {
3445
3446                         tmppath1 = canonical_path (spath);
3447                         tmppath2 = canonical_path ((*i));
3448
3449                         cerr << "\t => " << tmppath2 << endl;
3450
3451                         if (tmppath1 == tmppath2) {
3452                                 used = true;
3453                                 break;
3454                         }
3455                 }
3456
3457                 if (!used) {
3458                         unused.push_back (spath);
3459                 }
3460         }
3461
3462         cerr << "Actually unused: " << unused.size() << endl;
3463
3464         if (unused.empty()) {
3465                 /* Nothing to do */
3466                 ret = 0;
3467                 goto out;
3468         }
3469
3470         /* now try to move all unused files into the "dead" directory(ies) */
3471
3472         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3473                 GStatBuf statbuf;
3474
3475                 string newpath;
3476
3477                 /* don't move the file across filesystems, just
3478                  * stick it in the `dead_dir_name' directory
3479                  * on whichever filesystem it was already on.
3480                  */
3481
3482                 if ((*x).find ("/sounds/") != string::npos) {
3483
3484                         /* old school, go up 1 level */
3485
3486                         newpath = Glib::path_get_dirname (*x);      // "sounds"
3487                         newpath = Glib::path_get_dirname (newpath); // "session-name"
3488
3489                 } else {
3490
3491                         /* new school, go up 4 levels */
3492
3493                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
3494                         newpath = Glib::path_get_dirname (newpath); // "session-name"
3495                         newpath = Glib::path_get_dirname (newpath); // "interchange"
3496                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
3497                 }
3498
3499                 newpath = Glib::build_filename (newpath, dead_dir_name);
3500
3501                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
3502                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
3503                         return -1;
3504                 }
3505
3506                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
3507
3508                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3509
3510                         /* the new path already exists, try versioning */
3511
3512                         char buf[PATH_MAX+1];
3513                         int version = 1;
3514                         string newpath_v;
3515
3516                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3517                         newpath_v = buf;
3518
3519                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
3520                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3521                                 newpath_v = buf;
3522                         }
3523
3524                         if (version == 999) {
3525                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3526                                                 newpath)
3527                                         << endmsg;
3528                         } else {
3529                                 newpath = newpath_v;
3530                         }
3531
3532                 }
3533
3534                 if ((g_stat ((*x).c_str(), &statbuf) != 0) || (::g_rename ((*x).c_str(), newpath.c_str()) != 0)) {
3535                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"), (*x),
3536                                         newpath, g_strerror (errno)) << endmsg;
3537                         continue;
3538                 }
3539
3540                 /* see if there an easy to find peakfile for this file, and remove it.  */
3541
3542                 string base = Glib::path_get_basename (*x);
3543                 base += "%A"; /* this is what we add for the channel suffix of all native files,
3544                                                                          * or for the first channel of embedded files. it will miss
3545                                                                          * some peakfiles for other channels
3546                                                                          */
3547                 string peakpath = construct_peak_filepath (base);
3548
3549                 if (Glib::file_test (peakpath.c_str (), Glib::FILE_TEST_EXISTS)) {
3550                         if (::g_unlink (peakpath.c_str ()) != 0) {
3551                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"), peakpath, _path,
3552                                                 g_strerror (errno)) << endmsg;
3553                                 /* try to back out */
3554                                 ::g_rename (newpath.c_str (), _path.c_str ());
3555                                 goto out;
3556                         }
3557                 }
3558
3559                 rep.paths.push_back (*x);
3560                 rep.space += statbuf.st_size;
3561         }
3562
3563         /* dump the history list */
3564
3565         _history.clear ();
3566
3567         /* save state so we don't end up a session file
3568          * referring to non-existent sources.
3569          */
3570
3571         save_state ("");
3572         ret = 0;
3573
3574 out:
3575         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3576
3577         return ret;
3578 }
3579
3580 int
3581 Session::cleanup_trash_sources (CleanupReport& rep)
3582 {
3583         // FIXME: needs adaptation for MIDI
3584
3585         vector<space_and_path>::iterator i;
3586         string dead_dir;
3587
3588         rep.paths.clear ();
3589         rep.space = 0;
3590
3591         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3592
3593                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3594
3595                 clear_directory (dead_dir, &rep.space, &rep.paths);
3596         }
3597
3598         return 0;
3599 }
3600
3601 void
3602 Session::set_dirty ()
3603 {
3604         /* return early if there's nothing to do */
3605         if (dirty ()) {
3606                 return;
3607         }
3608
3609         /* never mark session dirty during loading */
3610         if (_state_of_the_state & Loading) {
3611                 return;
3612         }
3613
3614         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3615         DirtyChanged(); /* EMIT SIGNAL */
3616 }
3617
3618 void
3619 Session::set_clean ()
3620 {
3621         bool was_dirty = dirty();
3622
3623         _state_of_the_state = Clean;
3624
3625         if (was_dirty) {
3626                 DirtyChanged(); /* EMIT SIGNAL */
3627         }
3628 }
3629
3630 void
3631 Session::set_deletion_in_progress ()
3632 {
3633         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3634 }
3635
3636 void
3637 Session::clear_deletion_in_progress ()
3638 {
3639         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3640 }
3641
3642 void
3643 Session::add_controllable (boost::shared_ptr<Controllable> c)
3644 {
3645         /* this adds a controllable to the list managed by the Session.
3646            this is a subset of those managed by the Controllable class
3647            itself, and represents the only ones whose state will be saved
3648            as part of the session.
3649         */
3650
3651         Glib::Threads::Mutex::Lock lm (controllables_lock);
3652         controllables.insert (c);
3653 }
3654
3655 struct null_deleter { void operator()(void const *) const {} };
3656
3657 void
3658 Session::remove_controllable (Controllable* c)
3659 {
3660         if (_state_of_the_state & Deletion) {
3661                 return;
3662         }
3663
3664         Glib::Threads::Mutex::Lock lm (controllables_lock);
3665
3666         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3667
3668         if (x != controllables.end()) {
3669                 controllables.erase (x);
3670         }
3671 }
3672
3673 boost::shared_ptr<Controllable>
3674 Session::controllable_by_id (const PBD::ID& id)
3675 {
3676         Glib::Threads::Mutex::Lock lm (controllables_lock);
3677
3678         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3679                 if ((*i)->id() == id) {
3680                         return *i;
3681                 }
3682         }
3683
3684         return boost::shared_ptr<Controllable>();
3685 }
3686
3687 boost::shared_ptr<AutomationControl>
3688 Session::automation_control_by_id (const PBD::ID& id)
3689 {
3690         return boost::dynamic_pointer_cast<AutomationControl> (controllable_by_id (id));
3691 }
3692
3693 boost::shared_ptr<Controllable>
3694 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3695 {
3696         boost::shared_ptr<Controllable> c;
3697         boost::shared_ptr<Stripable> s;
3698         boost::shared_ptr<Route> r;
3699
3700         switch (desc.top_level_type()) {
3701         case ControllableDescriptor::NamedRoute:
3702         {
3703                 std::string str = desc.top_level_name();
3704
3705                 if (str == "Master" || str == "master") {
3706                         s = _master_out;
3707                 } else if (str == "control" || str == "listen" || str == "monitor" || str == "Monitor") {
3708                         s = _monitor_out;
3709                 } else if (str == "auditioner") {
3710                         s = auditioner;
3711                 } else {
3712                         s = route_by_name (desc.top_level_name());
3713                 }
3714
3715                 break;
3716         }
3717
3718         case ControllableDescriptor::PresentationOrderRoute:
3719                 s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Route);
3720                 break;
3721
3722         case ControllableDescriptor::PresentationOrderTrack:
3723                 s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Track);
3724                 break;
3725
3726         case ControllableDescriptor::PresentationOrderBus:
3727                 s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Bus);
3728                 break;
3729
3730         case ControllableDescriptor::PresentationOrderVCA:
3731                 s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::VCA);
3732                 break;
3733
3734         case ControllableDescriptor::SelectionCount:
3735                 s = route_by_selected_count (desc.selection_id());
3736                 break;
3737         }
3738
3739         if (!s) {
3740                 return c;
3741         }
3742
3743         r = boost::dynamic_pointer_cast<Route> (s);
3744
3745         switch (desc.subtype()) {
3746         case ControllableDescriptor::Gain:
3747                 c = s->gain_control ();
3748                 break;
3749
3750         case ControllableDescriptor::Trim:
3751                 c = s->trim_control ();
3752                 break;
3753
3754         case ControllableDescriptor::Solo:
3755                 c = s->solo_control();
3756                 break;
3757
3758         case ControllableDescriptor::Mute:
3759                 c = s->mute_control();
3760                 break;
3761
3762         case ControllableDescriptor::Recenable:
3763                 c = s->rec_enable_control ();
3764                 break;
3765
3766         case ControllableDescriptor::PanDirection:
3767                 c = s->pan_azimuth_control();
3768                 break;
3769
3770         case ControllableDescriptor::PanWidth:
3771                 c = s->pan_width_control();
3772                 break;
3773
3774         case ControllableDescriptor::PanElevation:
3775                 c = s->pan_elevation_control();
3776                 break;
3777
3778         case ControllableDescriptor::Balance:
3779                 /* XXX simple pan control */
3780                 break;
3781
3782         case ControllableDescriptor::PluginParameter:
3783         {
3784                 uint32_t plugin = desc.target (0);
3785                 uint32_t parameter_index = desc.target (1);
3786
3787                 /* revert to zero based counting */
3788
3789                 if (plugin > 0) {
3790                         --plugin;
3791                 }
3792
3793                 if (parameter_index > 0) {
3794                         --parameter_index;
3795                 }
3796
3797                 if (!r) {
3798                         return c;
3799                 }
3800
3801                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3802
3803                 if (p) {
3804                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3805                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3806                 }
3807                 break;
3808         }
3809
3810         case ControllableDescriptor::SendGain: {
3811                 uint32_t send = desc.target (0);
3812                 if (send > 0) {
3813                         --send;
3814                 }
3815                 if (!r) {
3816                         return c;
3817                 }
3818                 c = r->send_level_controllable (send);
3819                 break;
3820         }
3821
3822         default:
3823                 /* relax and return a null pointer */
3824                 break;
3825         }
3826
3827         return c;
3828 }
3829
3830 void
3831 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3832 {
3833         if (_writable) {
3834                 Stateful::add_instant_xml (node, _path);
3835         }
3836
3837         if (write_to_config) {
3838                 Config->add_instant_xml (node);
3839         }
3840 }
3841
3842 XMLNode*
3843 Session::instant_xml (const string& node_name)
3844 {
3845 #ifdef MIXBUS // "Safe Mode" (shift + click open) -> also ignore instant.xml
3846         if (get_disable_all_loaded_plugins ()) {
3847                 return NULL;
3848         }
3849 #endif
3850         return Stateful::instant_xml (node_name, _path);
3851 }
3852
3853 int
3854 Session::save_history (string snapshot_name)
3855 {
3856         XMLTree tree;
3857
3858         if (!_writable) {
3859                 return 0;
3860         }
3861
3862         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 ||
3863             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3864                 return 0;
3865         }
3866
3867         if (snapshot_name.empty()) {
3868                 snapshot_name = _current_snapshot_name;
3869         }
3870
3871         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3872         const string backup_filename = history_filename + backup_suffix;
3873         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3874         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3875
3876         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3877                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3878                         error << _("could not backup old history file, current history not saved") << endmsg;
3879                         return -1;
3880                 }
3881         }
3882
3883         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3884
3885         if (!tree.write (xml_path))
3886         {
3887                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3888
3889                 if (g_remove (xml_path.c_str()) != 0) {
3890                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3891                                         xml_path, g_strerror (errno)) << endmsg;
3892                 }
3893                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3894                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3895                                         backup_path, g_strerror (errno)) << endmsg;
3896                 }
3897
3898                 return -1;
3899         }
3900
3901         return 0;
3902 }
3903
3904 int
3905 Session::restore_history (string snapshot_name)
3906 {
3907         XMLTree tree;
3908
3909         if (snapshot_name.empty()) {
3910                 snapshot_name = _current_snapshot_name;
3911         }
3912
3913         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3914         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3915
3916         info << "Loading history from " << xml_path << endmsg;
3917
3918         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3919                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3920                                 _name, xml_path) << endmsg;
3921                 return 1;
3922         }
3923
3924         if (!tree.read (xml_path)) {
3925                 error << string_compose (_("Could not understand session history file \"%1\""),
3926                                 xml_path) << endmsg;
3927                 return -1;
3928         }
3929
3930         // replace history
3931         _history.clear();
3932
3933         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); ++it) {
3934
3935                 XMLNode *t = *it;
3936                 UndoTransaction* ut = new UndoTransaction ();
3937
3938                 std::string name;
3939                 int64_t tv_sec;
3940                 int64_t tv_usec;
3941
3942                 if (!t->get_property ("name", name) || !t->get_property ("tv-sec", tv_sec) ||
3943                     !t->get_property ("tv-usec", tv_usec)) {
3944                         continue;
3945                 }
3946
3947                 ut->set_name (name);
3948
3949                 struct timeval tv;
3950                 tv.tv_sec = tv_sec;
3951                 tv.tv_usec = tv_usec;
3952                 ut->set_timestamp(tv);
3953
3954                 for (XMLNodeConstIterator child_it  = t->children().begin();
3955                                 child_it != t->children().end(); child_it++)
3956                 {
3957                         XMLNode *n = *child_it;
3958                         Command *c;
3959
3960                         if (n->name() == "MementoCommand" ||
3961                                         n->name() == "MementoUndoCommand" ||
3962                                         n->name() == "MementoRedoCommand") {
3963
3964                                 if ((c = memento_command_factory(n))) {
3965                                         ut->add_command(c);
3966                                 }
3967
3968                         } else if (n->name() == "NoteDiffCommand") {
3969                                 PBD::ID id (n->property("midi-source")->value());
3970                                 boost::shared_ptr<MidiSource> midi_source =
3971                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3972                                 if (midi_source) {
3973                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3974                                 } else {
3975                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3976                                 }
3977
3978                         } else if (n->name() == "SysExDiffCommand") {
3979
3980                                 PBD::ID id (n->property("midi-source")->value());
3981                                 boost::shared_ptr<MidiSource> midi_source =
3982                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3983                                 if (midi_source) {
3984                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3985                                 } else {
3986                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3987                                 }
3988
3989                         } else if (n->name() == "PatchChangeDiffCommand") {
3990
3991                                 PBD::ID id (n->property("midi-source")->value());
3992                                 boost::shared_ptr<MidiSource> midi_source =
3993                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3994                                 if (midi_source) {
3995                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3996                                 } else {
3997                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3998                                 }
3999
4000                         } else if (n->name() == "StatefulDiffCommand") {
4001                                 if ((c = stateful_diff_command_factory (n))) {
4002                                         ut->add_command (c);
4003                                 }
4004                         } else {
4005                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
4006                         }
4007                 }
4008
4009                 _history.add (ut);
4010         }
4011
4012         return 0;
4013 }
4014
4015 void
4016 Session::config_changed (std::string p, bool ours)
4017 {
4018         if (ours) {
4019                 set_dirty ();
4020         }
4021
4022         if (p == "seamless-loop") {
4023
4024         } else if (p == "rf-speed") {
4025
4026         } else if (p == "auto-loop") {
4027
4028         } else if (p == "session-monitoring") {
4029
4030         } else if (p == "auto-input") {
4031
4032                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
4033                         /* auto-input only makes a difference if we're rolling */
4034                         set_track_monitor_input_status (!config.get_auto_input());
4035                 }
4036
4037         } else if (p == "punch-in") {
4038
4039                 Location* location;
4040
4041                 if ((location = _locations->auto_punch_location()) != 0) {
4042
4043                         if (config.get_punch_in ()) {
4044                                 auto_punch_start_changed (location);
4045                         } else {
4046                                 clear_events (SessionEvent::PunchIn);
4047                         }
4048                 }
4049
4050         } else if (p == "punch-out") {
4051
4052                 Location* location;
4053
4054                 if ((location = _locations->auto_punch_location()) != 0) {
4055
4056                         if (config.get_punch_out()) {
4057                                 auto_punch_end_changed (location);
4058                         } else {
4059                                 clear_events (SessionEvent::PunchOut);
4060                         }
4061                 }
4062
4063         } else if (p == "edit-mode") {
4064
4065                 Glib::Threads::Mutex::Lock lm (playlists->lock);
4066
4067                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
4068                         (*i)->set_edit_mode (Config->get_edit_mode ());
4069                 }
4070
4071         } else if (p == "use-video-sync") {
4072
4073                 waiting_for_sync_offset = config.get_use_video_sync();
4074
4075         } else if (p == "mmc-control") {
4076
4077                 //poke_midi_thread ();
4078
4079         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
4080
4081                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
4082
4083         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
4084
4085                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
4086
4087         } else if (p == "midi-control") {
4088
4089                 //poke_midi_thread ();
4090
4091         } else if (p == "raid-path") {
4092
4093                 setup_raid_path (config.get_raid_path());
4094
4095         } else if (p == "timecode-format") {
4096
4097                 sync_time_vars ();
4098
4099         } else if (p == "video-pullup") {
4100
4101                 sync_time_vars ();
4102
4103         } else if (p == "seamless-loop") {
4104
4105                 if (play_loop && transport_rolling()) {
4106                         // to reset diskstreams etc
4107                         request_play_loop (true);
4108                 }
4109
4110         } else if (p == "rf-speed") {
4111
4112                 cumulative_rf_motion = 0;
4113                 reset_rf_scale (0);
4114
4115         } else if (p == "click-sound") {
4116
4117                 setup_click_sounds (1);
4118
4119         } else if (p == "click-emphasis-sound") {
4120
4121                 setup_click_sounds (-1);
4122
4123         } else if (p == "clicking") {
4124
4125                 if (Config->get_clicking()) {
4126                         if (_click_io && click_data) { // don't require emphasis data
4127                                 _clicking = true;
4128                         }
4129                 } else {
4130                         _clicking = false;
4131                 }
4132
4133         } else if (p == "click-record-only") {
4134
4135                         _click_rec_only = Config->get_click_record_only();
4136
4137         } else if (p == "click-gain") {
4138
4139                 if (_click_gain) {
4140                         _click_gain->gain_control()->set_value (Config->get_click_gain(), Controllable::NoGroup);
4141                 }
4142
4143         } else if (p == "send-mtc") {
4144
4145                 if (Config->get_send_mtc ()) {
4146                         /* mark us ready to send */
4147                         next_quarter_frame_to_send = 0;
4148                 }
4149
4150         } else if (p == "send-mmc") {
4151
4152                 _mmc->enable_send (Config->get_send_mmc ());
4153                 if (Config->get_send_mmc ()) {
4154                         /* re-initialize MMC */
4155                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
4156                         send_immediate_mmc (MIDI::MachineControlCommand (Timecode::Time ()));
4157                 }
4158
4159         } else if (p == "jack-time-master") {
4160
4161                 engine().reset_timebase ();
4162
4163         } else if (p == "native-file-header-format") {
4164
4165                 if (!first_file_header_format_reset) {
4166                         reset_native_file_format ();
4167                 }
4168
4169                 first_file_header_format_reset = false;
4170
4171         } else if (p == "native-file-data-format") {
4172
4173                 if (!first_file_data_format_reset) {
4174                         reset_native_file_format ();
4175                 }
4176
4177                 first_file_data_format_reset = false;
4178
4179         } else if (p == "external-sync") {
4180                 if (!config.get_external_sync()) {
4181                         drop_sync_source ();
4182                 } else {
4183                         switch_to_sync_source (Config->get_sync_source());
4184                 }
4185         }  else if (p == "denormal-model") {
4186                 setup_fpu ();
4187         } else if (p == "history-depth") {
4188                 set_history_depth (Config->get_history_depth());
4189         } else if (p == "remote-model") {
4190                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
4191                    TO SET REMOTE ID'S
4192                 */
4193         } else if (p == "initial-program-change") {
4194
4195                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
4196                         MIDI::byte buf[2];
4197
4198                         buf[0] = MIDI::program; // channel zero by default
4199                         buf[1] = (Config->get_initial_program_change() & 0x7f);
4200
4201                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
4202                 }
4203         } else if (p == "solo-mute-override") {
4204                 // catch_up_on_solo_mute_override ();
4205         } else if (p == "listen-position" || p == "pfl-position") {
4206                 listen_position_changed ();
4207         } else if (p == "solo-control-is-listen-control") {
4208                 solo_control_mode_changed ();
4209         } else if (p == "solo-mute-gain") {
4210                 _solo_cut_control->Changed (true, Controllable::NoGroup);
4211         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
4212                 last_timecode_valid = false;
4213         } else if (p == "playback-buffer-seconds") {
4214                 AudioSource::allocate_working_buffers (sample_rate());
4215         } else if (p == "ltc-source-port") {
4216                 reconnect_ltc_input ();
4217         } else if (p == "ltc-sink-port") {
4218                 reconnect_ltc_output ();
4219         } else if (p == "timecode-generator-offset") {
4220                 ltc_tx_parse_offset();
4221         } else if (p == "auto-return-target-list") {
4222                 follow_playhead_priority ();
4223         }
4224
4225         set_dirty ();
4226 }
4227
4228 void
4229 Session::set_history_depth (uint32_t d)
4230 {
4231         _history.set_depth (d);
4232 }
4233
4234 /** Connect things to the MMC object */
4235 void
4236 Session::setup_midi_machine_control ()
4237 {
4238         _mmc = new MIDI::MachineControl;
4239
4240         boost::shared_ptr<AsyncMIDIPort> async_in = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_input_port());
4241         boost::shared_ptr<AsyncMIDIPort> async_out = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_output_port());
4242
4243         if (!async_out || !async_out) {
4244                 return;
4245         }
4246
4247         /* XXXX argh, passing raw pointers back into libmidi++ */
4248
4249         MIDI::Port* mmc_in = async_in.get();
4250         MIDI::Port* mmc_out = async_out.get();
4251
4252         _mmc->set_ports (mmc_in, mmc_out);
4253
4254         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
4255         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
4256         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
4257         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
4258         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
4259         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
4260         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
4261         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
4262         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
4263         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
4264         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
4265         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
4266         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
4267
4268         /* also handle MIDI SPP because its so common */
4269
4270         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
4271         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
4272         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
4273 }
4274
4275 boost::shared_ptr<Controllable>
4276 Session::solo_cut_control() const
4277 {
4278         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
4279          * controls in Ardour that currently get presented to the user in the GUI that require
4280          * access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
4281          *
4282          * its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
4283          * it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
4284          * parameter.
4285          */
4286         return _solo_cut_control;
4287 }
4288
4289 void
4290 Session::save_snapshot_name (const std::string & n)
4291 {
4292         /* assure Stateful::_instant_xml is loaded
4293          * add_instant_xml() only adds to existing data and defaults
4294          * to use an empty Tree otherwise
4295          */
4296         instant_xml ("LastUsedSnapshot");
4297
4298         XMLNode* last_used_snapshot = new XMLNode ("LastUsedSnapshot");
4299         last_used_snapshot->set_property ("name", n);
4300         add_instant_xml (*last_used_snapshot, false);
4301 }
4302
4303 void
4304 Session::set_snapshot_name (const std::string & n)
4305 {
4306         _current_snapshot_name = n;
4307         save_snapshot_name (n);
4308 }
4309
4310 int
4311 Session::rename (const std::string& new_name)
4312 {
4313         string legal_name = legalize_for_path (new_name);
4314         string new_path;
4315         string oldstr;
4316         string newstr;
4317         bool first = true;
4318
4319         string const old_sources_root = _session_dir->sources_root();
4320
4321         if (!_writable || (_state_of_the_state & CannotSave)) {
4322                 error << _("Cannot rename read-only session.") << endmsg;
4323                 return 0; // don't show "messed up" warning
4324         }
4325         if (record_status() == Recording) {
4326                 error << _("Cannot rename session while recording") << endmsg;
4327                 return 0; // don't show "messed up" warning
4328         }
4329
4330         StateProtector stp (this);
4331
4332         /* Rename:
4333
4334          * session directory
4335          * interchange subdirectory
4336          * session file
4337          * session history
4338
4339          * Backup files are left unchanged and not renamed.
4340          */
4341
4342         /* Windows requires that we close all files before attempting the
4343          * rename. This works on other platforms, but isn't necessary there.
4344          * Leave it in place for all platforms though, since it may help
4345          * catch issues that could arise if the way Source files work ever
4346          * change (since most developers are not using Windows).
4347          */
4348
4349         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4350                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4351                 if (fs) {
4352                         fs->close ();
4353                 }
4354         }
4355
4356         /* pass one: not 100% safe check that the new directory names don't
4357          * already exist ...
4358          */
4359
4360         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4361
4362                 oldstr = (*i).path;
4363
4364                 /* this is a stupid hack because Glib::path_get_dirname() is
4365                  * lexical-only, and so passing it /a/b/c/ gives a different
4366                  * result than passing it /a/b/c ...
4367                  */
4368
4369                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
4370                         oldstr = oldstr.substr (0, oldstr.length() - 1);
4371                 }
4372
4373                 string base = Glib::path_get_dirname (oldstr);
4374
4375                 newstr = Glib::build_filename (base, legal_name);
4376
4377                 cerr << "Looking for " << newstr << endl;
4378
4379                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
4380                         cerr << " exists\n";
4381                         return -1;
4382                 }
4383         }
4384
4385         /* Session dirs */
4386
4387         first = true;
4388
4389         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4390
4391                 vector<string> v;
4392
4393                 oldstr = (*i).path;
4394
4395                 /* this is a stupid hack because Glib::path_get_dirname() is
4396                  * lexical-only, and so passing it /a/b/c/ gives a different
4397                  * result than passing it /a/b/c ...
4398                  */
4399
4400                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
4401                         oldstr = oldstr.substr (0, oldstr.length() - 1);
4402                 }
4403
4404                 string base = Glib::path_get_dirname (oldstr);
4405                 newstr = Glib::build_filename (base, legal_name);
4406
4407                 cerr << "for " << oldstr << " new dir = " << newstr << endl;
4408
4409                 cerr << "Rename " << oldstr << " => " << newstr << endl;
4410                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4411                         cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4412                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4413                         return 1;
4414                 }
4415
4416                 /* Reset path in "session dirs" */
4417
4418                 (*i).path = newstr;
4419                 (*i).blocks = 0;
4420
4421                 /* reset primary SessionDirectory object */
4422
4423                 if (first) {
4424                         (*_session_dir) = newstr;
4425                         new_path = newstr;
4426                         first = false;
4427                 }
4428
4429                 /* now rename directory below session_dir/interchange */
4430
4431                 string old_interchange_dir;
4432                 string new_interchange_dir;
4433
4434                 /* use newstr here because we renamed the path
4435                  * (folder/directory) that used to be oldstr to newstr above
4436                  */
4437
4438                 v.push_back (newstr);
4439                 v.push_back (interchange_dir_name);
4440                 v.push_back (Glib::path_get_basename (oldstr));
4441
4442                 old_interchange_dir = Glib::build_filename (v);
4443
4444                 v.clear ();
4445                 v.push_back (newstr);
4446                 v.push_back (interchange_dir_name);
4447                 v.push_back (legal_name);
4448
4449                 new_interchange_dir = Glib::build_filename (v);
4450
4451                 cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
4452
4453                 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
4454                         cerr << string_compose (_("renaming %s as %2 failed (%3)"),
4455                                                 old_interchange_dir, new_interchange_dir,
4456                                                 g_strerror (errno))
4457                              << endl;
4458                         error << string_compose (_("renaming %s as %2 failed (%3)"),
4459                                                  old_interchange_dir, new_interchange_dir,
4460                                                  g_strerror (errno))
4461                               << endmsg;
4462                         return 1;
4463                 }
4464         }
4465
4466         /* state file */
4467
4468         oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
4469         newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
4470
4471         cerr << "Rename " << oldstr << " => " << newstr << endl;
4472
4473         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4474                 cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4475                 error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4476                 return 1;
4477         }
4478
4479         /* history file */
4480
4481         oldstr = Glib::build_filename (new_path, _current_snapshot_name) + history_suffix;
4482
4483         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
4484                 newstr = Glib::build_filename (new_path, legal_name) + history_suffix;
4485
4486                 cerr << "Rename " << oldstr << " => " << newstr << endl;
4487
4488                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4489                         cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4490                         error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4491                         return 1;
4492                 }
4493         }
4494
4495         /* remove old name from recent sessions */
4496         remove_recent_sessions (_path);
4497         _path = new_path;
4498
4499         /* update file source paths */
4500
4501         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
4502                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4503                 if (fs) {
4504                         string p = fs->path ();
4505                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
4506                         fs->set_path (p);
4507                         SourceFactory::setup_peakfile(i->second, true);
4508                 }
4509         }
4510
4511         set_snapshot_name (new_name);
4512         _name = new_name;
4513
4514         set_dirty ();
4515
4516         /* save state again to get everything just right */
4517
4518         save_state (_current_snapshot_name);
4519
4520         /* add to recent sessions */
4521
4522         store_recent_sessions (new_name, _path);
4523
4524         return 0;
4525 }
4526
4527 int
4528 Session::parse_stateful_loading_version (const std::string& version)
4529 {
4530         if (version.empty ()) {
4531                 /* no version implies very old version of Ardour */
4532                 return 1000;
4533         }
4534
4535         if (version.find ('.') != string::npos) {
4536                 /* old school version format */
4537                 if (version[0] == '2') {
4538                         return 2000;
4539                 } else {
4540                         return 3000;
4541                 }
4542         } else {
4543                 return string_to<int32_t>(version);
4544         }
4545 }
4546
4547 int
4548 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format, std::string& program_version)
4549 {
4550         bool found_sr = false;
4551         bool found_data_format = false;
4552         std::string version;
4553         program_version = "";
4554
4555         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
4556                 return -1;
4557         }
4558
4559         xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
4560         if (ctxt == NULL) {
4561                 return -1;
4562         }
4563         xmlDocPtr doc = xmlCtxtReadFile (ctxt, xmlpath.c_str(), NULL, XML_PARSE_HUGE);
4564
4565         if (doc == NULL) {
4566                 xmlFreeParserCtxt(ctxt);
4567                 return -1;
4568         }
4569
4570         xmlNodePtr node = xmlDocGetRootElement(doc);
4571
4572         if (node == NULL) {
4573                 xmlFreeParserCtxt(ctxt);
4574                 xmlFreeDoc (doc);
4575                 return -1;
4576         }
4577
4578         /* sample rate & version*/
4579
4580         xmlAttrPtr attr;
4581         for (attr = node->properties; attr; attr = attr->next) {
4582                 if (!strcmp ((const char*)attr->name, "version") && attr->children) {
4583                         version = std::string ((char*)attr->children->content);
4584                 }
4585                 if (!strcmp ((const char*)attr->name, "sample-rate") && attr->children) {
4586                         sample_rate = atoi ((char*)attr->children->content);
4587                         found_sr = true;
4588                 }
4589         }
4590
4591         if ((parse_stateful_loading_version(version) / 1000L) > (CURRENT_SESSION_FILE_VERSION / 1000L)) {
4592                 return -1;
4593         }
4594
4595         node = node->children;
4596         while (node != NULL) {
4597                  if (!strcmp((const char*) node->name, "ProgramVersion")) {
4598                          xmlChar* val = xmlGetProp (node, (const xmlChar*)"modified-with");
4599                          if (val) {
4600                                  program_version = string ((const char*)val);
4601                                  size_t sep = program_version.find_first_of("-");
4602                                  if (sep != string::npos) {
4603                                          program_version = program_version.substr (0, sep);
4604                                  }
4605                          }
4606                          xmlFree (val);
4607                  }
4608                  if (strcmp((const char*) node->name, "Config")) {
4609                          node = node->next;
4610                          continue;
4611                  }
4612                  for (node = node->children; node; node = node->next) {
4613                          xmlChar* pv = xmlGetProp (node, (const xmlChar*)"name");
4614                          if (pv && !strcmp ((const char*)pv, "native-file-data-format")) {
4615                                  xmlFree (pv);
4616                                  xmlChar* val = xmlGetProp (node, (const xmlChar*)"value");
4617                                  if (val) {
4618                                          try {
4619                                                  SampleFormat fmt = (SampleFormat) string_2_enum (string ((const char*)val), fmt);
4620                                                  data_format = fmt;
4621                                                  found_data_format = true;
4622                                          } catch (PBD::unknown_enumeration& e) {}
4623                                  }
4624                                  xmlFree (val);
4625                                  break;
4626                          }
4627                          xmlFree (pv);
4628                  }
4629                  break;
4630         }
4631
4632         xmlFreeParserCtxt(ctxt);
4633         xmlFreeDoc (doc);
4634
4635         return (found_sr && found_data_format) ? 0 : 1;
4636 }
4637
4638 std::string
4639 Session::get_snapshot_from_instant (const std::string& session_dir)
4640 {
4641         std::string instant_xml_path = Glib::build_filename (session_dir, "instant.xml");
4642
4643         if (!Glib::file_test (instant_xml_path, Glib::FILE_TEST_EXISTS)) {
4644                 return "";
4645         }
4646
4647         XMLTree tree;
4648         if (!tree.read (instant_xml_path)) {
4649                 return "";
4650         }
4651
4652         XMLProperty const * prop;
4653         XMLNode *last_used_snapshot = tree.root()->child("LastUsedSnapshot");
4654         if (last_used_snapshot && (prop = last_used_snapshot->property ("name")) != 0) {
4655                 return prop->value();
4656         }
4657
4658         return "";
4659 }
4660
4661 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
4662 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
4663
4664 int
4665 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
4666 {
4667         uint32_t total = 0;
4668         uint32_t n = 0;
4669         SourcePathMap source_path_map;
4670         string new_path;
4671         boost::shared_ptr<AudioFileSource> afs;
4672         int ret = 0;
4673
4674         {
4675
4676                 Glib::Threads::Mutex::Lock lm (source_lock);
4677
4678                 cerr << " total sources = " << sources.size();
4679
4680                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4681                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4682
4683                         if (!fs) {
4684                                 continue;
4685                         }
4686
4687                         if (fs->within_session()) {
4688                                 continue;
4689                         }
4690
4691                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
4692                                 source_path_map[fs->path()].push_back (fs);
4693                         } else {
4694                                 SeveralFileSources v;
4695                                 v.push_back (fs);
4696                                 source_path_map.insert (make_pair (fs->path(), v));
4697                         }
4698
4699                         total++;
4700                 }
4701
4702                 cerr << " fsources = " << total << endl;
4703
4704                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
4705
4706                         /* tell caller where we are */
4707
4708                         string old_path = i->first;
4709
4710                         callback (n, total, old_path);
4711
4712                         cerr << old_path << endl;
4713
4714                         new_path.clear ();
4715
4716                         switch (i->second.front()->type()) {
4717                         case DataType::AUDIO:
4718                                 new_path = new_audio_source_path_for_embedded (old_path);
4719                                 break;
4720
4721                         case DataType::MIDI:
4722                                 /* XXX not implemented yet */
4723                                 break;
4724                         }
4725
4726                         if (new_path.empty()) {
4727                                 continue;
4728                         }
4729
4730                         cerr << "Move " << old_path << " => " << new_path << endl;
4731
4732                         if (!copy_file (old_path, new_path)) {
4733                                 cerr << "failed !\n";
4734                                 ret = -1;
4735                         }
4736
4737                         /* make sure we stop looking in the external
4738                            dir/folder. Remember, this is an all-or-nothing
4739                            operations, it doesn't merge just some files.
4740                         */
4741                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
4742
4743                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
4744                                 (*f)->set_path (new_path);
4745                         }
4746                 }
4747         }
4748
4749         save_state ("", false, false);
4750
4751         return ret;
4752 }
4753
4754 static
4755 bool accept_all_files (string const &, void *)
4756 {
4757         return true;
4758 }
4759
4760 void
4761 Session::save_as_bring_callback (uint32_t,uint32_t,string)
4762 {
4763         /* 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.
4764         */
4765 }
4766
4767 static string
4768 make_new_media_path (string old_path, string new_session_folder, string new_session_path)
4769 {
4770         /* typedir is the "midifiles" or "audiofiles" etc. part of the path. */
4771
4772         string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4773         vector<string> v;
4774         v.push_back (new_session_folder); /* full path */
4775         v.push_back (interchange_dir_name);
4776         v.push_back (new_session_path);   /* just one directory/folder */
4777         v.push_back (typedir);
4778         v.push_back (Glib::path_get_basename (old_path));
4779
4780         return Glib::build_filename (v);
4781 }
4782
4783 int
4784 Session::save_as (SaveAs& saveas)
4785 {
4786         vector<string> files;
4787         string current_folder = Glib::path_get_dirname (_path);
4788         string new_folder = legalize_for_path (saveas.new_name);
4789         string to_dir = Glib::build_filename (saveas.new_parent_folder, new_folder);
4790         int64_t total_bytes = 0;
4791         int64_t copied = 0;
4792         int64_t cnt = 0;
4793         int64_t all = 0;
4794         int32_t internal_file_cnt = 0;
4795
4796         vector<string> do_not_copy_extensions;
4797         do_not_copy_extensions.push_back (statefile_suffix);
4798         do_not_copy_extensions.push_back (pending_suffix);
4799         do_not_copy_extensions.push_back (backup_suffix);
4800         do_not_copy_extensions.push_back (temp_suffix);
4801         do_not_copy_extensions.push_back (history_suffix);
4802
4803         /* get total size */
4804
4805         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4806
4807                 /* need to clear this because
4808                  * find_files_matching_filter() is cumulative
4809                  */
4810
4811                 files.clear ();
4812
4813                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4814
4815                 all += files.size();
4816
4817                 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4818                         GStatBuf gsb;
4819                         g_stat ((*i).c_str(), &gsb);
4820                         total_bytes += gsb.st_size;
4821                 }
4822         }
4823
4824         /* save old values so we can switch back if we are not switching to the new session */
4825
4826         string old_path = _path;
4827         string old_name = _name;
4828         string old_snapshot = _current_snapshot_name;
4829         string old_sd = _session_dir->root_path();
4830         vector<string> old_search_path[DataType::num_types];
4831         string old_config_search_path[DataType::num_types];
4832
4833         old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4834         old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4835         old_config_search_path[DataType::AUDIO]  = config.get_audio_search_path ();
4836         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();
4837
4838         /* switch session directory */
4839
4840         (*_session_dir) = to_dir;
4841
4842         /* create new tree */
4843
4844         if (!_session_dir->create()) {
4845                 saveas.failure_message = string_compose (_("Cannot create new session folder %1"), to_dir);
4846                 return -1;
4847         }
4848
4849         try {
4850                 /* copy all relevant files. Find each location in session_dirs,
4851                  * and copy files from there to target.
4852                  */
4853
4854                 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4855
4856                         /* need to clear this because
4857                          * find_files_matching_filter() is cumulative
4858                          */
4859
4860                         files.clear ();
4861
4862                         const size_t prefix_len = (*sd).path.size();
4863
4864                         /* Work just on the files within this session dir */
4865
4866                         find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4867
4868                         /* add dir separator to protect against collisions with
4869                          * track names (e.g. track named "audiofiles" or
4870                          * "analysis".
4871                          */
4872
4873                         static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
4874                         static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
4875                         static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
4876
4877                         /* copy all the files. Handling is different for media files
4878                            than others because of the *silly* subtree we have below the interchange
4879                            folder. That really was a bad idea, but I'm not fixing it as part of
4880                            implementing ::save_as().
4881                         */
4882
4883                         for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4884
4885                                 std::string from = *i;
4886
4887 #ifdef __APPLE__
4888                                 string filename = Glib::path_get_basename (from);
4889                                 std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
4890                                 if (filename == ".DS_STORE") {
4891                                         continue;
4892                                 }
4893 #endif
4894
4895                                 if (from.find (audiofile_dir_string) != string::npos) {
4896
4897                                         /* audio file: only copy if asked */
4898
4899                                         if (saveas.include_media && saveas.copy_media) {
4900
4901                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4902
4903                                                 info << "media file copying from " << from << " to " << to << endmsg;
4904
4905                                                 if (!copy_file (from, to)) {
4906                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4907                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4908                                                 }
4909                                         }
4910
4911                                         /* we found media files inside the session folder */
4912
4913                                         internal_file_cnt++;
4914
4915                                 } else if (from.find (midifile_dir_string) != string::npos) {
4916
4917                                         /* midi file: always copy unless
4918                                          * creating an empty new session
4919                                          */
4920
4921                                         if (saveas.include_media) {
4922
4923                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4924
4925                                                 info << "media file copying from " << from << " to " << to << endmsg;
4926
4927                                                 if (!copy_file (from, to)) {
4928                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4929                                                 }
4930                                         }
4931
4932                                         /* we found media files inside the session folder */
4933
4934                                         internal_file_cnt++;
4935
4936                                 } else if (from.find (analysis_dir_string) != string::npos) {
4937
4938                                         /*  make sure analysis dir exists in
4939                                          *  new session folder, but we're not
4940                                          *  copying analysis files here, see
4941                                          *  below
4942                                          */
4943
4944                                         (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
4945                                         continue;
4946
4947                                 } else {
4948
4949                                         /* normal non-media file. Don't copy state, history, etc.
4950                                          */
4951
4952                                         bool do_copy = true;
4953
4954                                         for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4955                                                 if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
4956                                                         /* end of filename matches extension, do not copy file */
4957                                                         do_copy = false;
4958                                                         break;
4959                                                 }
4960                                         }
4961
4962                                         if (!saveas.copy_media && from.find (peakfile_suffix) != string::npos) {
4963                                                 /* don't copy peakfiles if
4964                                                  * we're not copying media
4965                                                  */
4966                                                 do_copy = false;
4967                                         }
4968
4969                                         if (do_copy) {
4970                                                 string to = Glib::build_filename (to_dir, from.substr (prefix_len));
4971
4972                                                 info << "attempting to make directory/folder " << to << endmsg;
4973
4974                                                 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4975                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
4976                                                 }
4977
4978                                                 info << "attempting to copy " << from << " to " << to << endmsg;
4979
4980                                                 if (!copy_file (from, to)) {
4981                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4982                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4983                                                 }
4984                                         }
4985                                 }
4986
4987                                 /* measure file size even if we're not going to copy so that our Progress
4988                                    signals are correct, since we included these do-not-copy files
4989                                    in the computation of the total size and file count.
4990                                 */
4991
4992                                 GStatBuf gsb;
4993                                 g_stat (from.c_str(), &gsb);
4994                                 copied += gsb.st_size;
4995                                 cnt++;
4996
4997                                 double fraction = (double) copied / total_bytes;
4998
4999                                 bool keep_going = true;
5000
5001                                 if (saveas.copy_media) {
5002
5003                                         /* no need or expectation of this if
5004                                          * media is not being copied, because
5005                                          * it will be fast(ish).
5006                                          */
5007
5008                                         /* tell someone "X percent, file M of N"; M is one-based */
5009
5010                                         boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
5011
5012                                         if (res) {
5013                                                 keep_going = *res;
5014                                         }
5015                                 }
5016
5017                                 if (!keep_going) {
5018                                         throw Glib::FileError (Glib::FileError::FAILED, "copy cancelled");
5019                                 }
5020                         }
5021
5022                 }
5023
5024                 /* copy optional folders, if any */
5025
5026                 string old = plugins_dir ();
5027                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
5028                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
5029                         copy_files (old, newdir);
5030                 }
5031
5032                 old = externals_dir ();
5033                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
5034                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
5035                         copy_files (old, newdir);
5036                 }
5037
5038                 old = automation_dir ();
5039                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
5040                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
5041                         copy_files (old, newdir);
5042                 }
5043
5044                 if (saveas.include_media) {
5045
5046                         if (saveas.copy_media) {
5047 #ifndef PLATFORM_WINDOWS
5048                                 /* There are problems with analysis files on
5049                                  * Windows, because they used a colon in their
5050                                  * names as late as 4.0. Colons are not legal
5051                                  * under Windows even if NTFS allows them.
5052                                  *
5053                                  * This is a tricky problem to solve so for
5054                                  * just don't copy these files. They will be
5055                                  * regenerated as-needed anyway, subject to the
5056                                  * existing issue that the filenames will be
5057                                  * rejected by Windows, which is a separate
5058                                  * problem (though related).
5059                                  */
5060
5061                                 /* only needed if we are copying media, since the
5062                                  * analysis data refers to media data
5063                                  */
5064
5065                                 old = analysis_dir ();
5066                                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
5067                                         string newdir = Glib::build_filename (to_dir, "analysis");
5068                                         copy_files (old, newdir);
5069                                 }
5070 #endif /* PLATFORM_WINDOWS */
5071                         }
5072                 }
5073
5074                 _path = to_dir;
5075                 set_snapshot_name (saveas.new_name);
5076                 _name = saveas.new_name;
5077
5078                 if (saveas.include_media && !saveas.copy_media) {
5079
5080                         /* reset search paths of the new session (which we're pretending to be right now) to
5081                            include the original session search path, so we can still find all audio.
5082                         */
5083
5084                         if (internal_file_cnt) {
5085                                 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
5086                                         ensure_search_path_includes (*s, DataType::AUDIO);
5087                                         cerr << "be sure to include " << *s << "  for audio" << endl;
5088                                 }
5089
5090                                 /* we do not do this for MIDI because we copy
5091                                    all MIDI files if saveas.include_media is
5092                                    true
5093                                 */
5094                         }
5095                 }
5096
5097                 bool was_dirty = dirty ();
5098
5099                 save_default_options ();
5100
5101                 if (saveas.copy_media && saveas.copy_external) {
5102                         if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback, this, _1, _2, _3))) {
5103                                 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT, "consolidate failed");
5104                         }
5105                 }
5106
5107                 saveas.final_session_folder_name = _path;
5108
5109                 store_recent_sessions (_name, _path);
5110
5111                 if (!saveas.switch_to) {
5112
5113                         /* save the new state */
5114
5115                         save_state ("", false, false, !saveas.include_media);
5116
5117                         /* switch back to the way things were */
5118
5119                         _path = old_path;
5120                         _name = old_name;
5121                         set_snapshot_name (old_snapshot);
5122
5123                         (*_session_dir) = old_sd;
5124
5125                         if (was_dirty) {
5126                                 set_dirty ();
5127                         }
5128
5129                         if (internal_file_cnt) {
5130                                 /* reset these to their original values */
5131                                 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
5132                                 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
5133                         }
5134
5135                 } else {
5136
5137                         /* prune session dirs, and update disk space statistics
5138                          */
5139
5140                         space_and_path sp;
5141                         sp.path = _path;
5142                         session_dirs.clear ();
5143                         session_dirs.push_back (sp);
5144                         refresh_disk_space ();
5145
5146                         _writable = exists_and_writable (_path);
5147
5148                         /* ensure that all existing tracks reset their current capture source paths
5149                          */
5150                         reset_write_sources (true, true);
5151
5152                         /* creating new write sources marks the session as
5153                            dirty. If the new session is empty, then
5154                            save_state() thinks we're saving a template and will
5155                            not mark the session as clean. So do that here,
5156                            before we save state.
5157                         */
5158
5159                         if (!saveas.include_media) {
5160                                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
5161                         }
5162
5163                         save_state ("", false, false, !saveas.include_media);
5164
5165                         /* the copying above was based on actually discovering files, not just iterating over the sources list.
5166                            But if we're going to switch to the new (copied) session, we need to change the paths in the sources also.
5167                         */
5168
5169                         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
5170                                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
5171
5172                                 if (!fs) {
5173                                         continue;
5174                                 }
5175
5176                                 if (fs->within_session()) {
5177                                         string newpath = make_new_media_path (fs->path(), to_dir, new_folder);
5178                                         fs->set_path (newpath);
5179                                 }
5180                         }
5181                 }
5182
5183         } catch (Glib::FileError& e) {
5184
5185                 saveas.failure_message = e.what();
5186
5187                 /* recursively remove all the directories */
5188
5189                 remove_directory (to_dir);
5190
5191                 /* return error */
5192
5193                 return -1;
5194
5195         } catch (...) {
5196
5197                 saveas.failure_message = _("unknown reason");
5198
5199                 /* recursively remove all the directories */
5200
5201                 remove_directory (to_dir);
5202
5203                 /* return error */
5204
5205                 return -1;
5206         }
5207
5208         return 0;
5209 }
5210
5211 static void set_progress (Progress* p, size_t n, size_t t)
5212 {
5213         p->set_progress (float (n) / float(t));
5214 }
5215
5216 int
5217 Session::archive_session (const std::string& dest,
5218                           const std::string& name,
5219                           ArchiveEncode compress_audio,
5220                           FileArchive::CompressionLevel compression_level,
5221                           bool only_used_sources,
5222                           Progress* progress)
5223 {
5224         if (dest.empty () || name.empty ()) {
5225                 return -1;
5226         }
5227
5228         /* save current values */
5229         bool was_dirty = dirty ();
5230         string old_path = _path;
5231         string old_name = _name;
5232         string old_snapshot = _current_snapshot_name;
5233         string old_sd = _session_dir->root_path();
5234         string old_config_search_path[DataType::num_types];
5235         old_config_search_path[DataType::AUDIO] = config.get_audio_search_path ();
5236         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();
5237
5238         /* ensure that session-path is included in search-path */
5239         bool ok = false;
5240         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
5241                 if ((*sd).path == old_path) {
5242                         ok = true;
5243                 }
5244         }
5245         if (!ok) {
5246                 return -1;
5247         }
5248
5249         /* create temporary dir to save session to */
5250 #ifdef PLATFORM_WINDOWS
5251         char tmp[256] = "C:\\TEMP\\";
5252         GetTempPath (sizeof (tmp), tmp);
5253 #else
5254         char const* tmp = getenv("TMPDIR");
5255         if (!tmp) {
5256                 tmp = "/tmp/";
5257         }
5258 #endif
5259         if ((strlen (tmp) + 21) > 1024) {
5260                 return -1;
5261         }
5262
5263         char tmptpl[1024];
5264         strcpy (tmptpl, tmp);
5265         strcat (tmptpl, "ardourarchive-XXXXXX");
5266         char*  tmpdir = g_mkdtemp (tmptpl);
5267
5268         if (!tmpdir) {
5269                 return -1;
5270         }
5271
5272         std::string to_dir = std::string (tmpdir);
5273
5274         /* switch session directory temporarily */
5275         (*_session_dir) = to_dir;
5276
5277         if (!_session_dir->create()) {
5278                 (*_session_dir) = old_sd;
5279                 remove_directory (to_dir);
5280                 return -1;
5281         }
5282
5283         /* prepare archive */
5284         string archive = Glib::build_filename (dest, name + session_archive_suffix);
5285
5286         PBD::ScopedConnectionList progress_connection;
5287         PBD::FileArchive ar (archive);
5288         if (progress) {
5289                 ar.progress.connect_same_thread (progress_connection, boost::bind (&set_progress, progress, _1, _2));
5290         }
5291
5292         /* collect files to archive */
5293         std::map<string,string> filemap;
5294
5295         vector<string> do_not_copy_extensions;
5296         do_not_copy_extensions.push_back (statefile_suffix);
5297         do_not_copy_extensions.push_back (pending_suffix);
5298         do_not_copy_extensions.push_back (backup_suffix);
5299         do_not_copy_extensions.push_back (temp_suffix);
5300         do_not_copy_extensions.push_back (history_suffix);
5301
5302         vector<string> blacklist_dirs;
5303         blacklist_dirs.push_back (string (peak_dir_name) + G_DIR_SEPARATOR);
5304         blacklist_dirs.push_back (string (analysis_dir_name) + G_DIR_SEPARATOR);
5305         blacklist_dirs.push_back (string (dead_dir_name) + G_DIR_SEPARATOR);
5306         blacklist_dirs.push_back (string (export_dir_name) + G_DIR_SEPARATOR);
5307         blacklist_dirs.push_back (string (externals_dir_name) + G_DIR_SEPARATOR);
5308         blacklist_dirs.push_back (string (plugins_dir_name) + G_DIR_SEPARATOR);
5309
5310         std::map<boost::shared_ptr<AudioFileSource>, std::string> orig_sources;
5311         std::map<boost::shared_ptr<AudioFileSource>, float> orig_gain;
5312
5313         set<boost::shared_ptr<Source> > sources_used_by_this_snapshot;
5314         if (only_used_sources) {
5315                 playlists->sync_all_regions_with_regions ();
5316                 playlists->foreach (boost::bind (merge_all_sources, _1, &sources_used_by_this_snapshot), false);
5317         }
5318
5319         // collect audio sources for this session, calc total size for encoding
5320         // add option to only include *used* sources (see Session::cleanup_sources)
5321         size_t total_size = 0;
5322         {
5323                 Glib::Threads::Mutex::Lock lm (source_lock);
5324                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
5325                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (i->second);
5326                         if (!afs || afs->readable_length () == 0) {
5327                                 continue;
5328                         }
5329
5330                         if (only_used_sources) {
5331                                 if (!afs->used()) {
5332                                         continue;
5333                                 }
5334                                 if (sources_used_by_this_snapshot.find (afs) == sources_used_by_this_snapshot.end ()) {
5335                                         continue;
5336                                 }
5337                         }
5338
5339                         std::string from = afs->path();
5340
5341                         if (compress_audio != NO_ENCODE) {
5342                                 total_size += afs->readable_length ();
5343                         } else {
5344                                 if (afs->within_session()) {
5345                                         filemap[from] = make_new_media_path (from, name, name);
5346                                 } else {
5347                                         filemap[from] = make_new_media_path (from, name, name);
5348                                         remove_dir_from_search_path (Glib::path_get_dirname (from), DataType::AUDIO);
5349                                 }
5350                         }
5351                 }
5352         }
5353
5354         /* encode audio */
5355         if (compress_audio != NO_ENCODE) {
5356                 if (progress) {
5357                         progress->set_progress (2); // set to "encoding"
5358                         progress->set_progress (0);
5359                 }
5360
5361                 Glib::Threads::Mutex::Lock lm (source_lock);
5362                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
5363                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (i->second);
5364                         if (!afs || afs->readable_length () == 0) {
5365                                 continue;
5366                         }
5367
5368                         if (only_used_sources) {
5369                                 if (!afs->used()) {
5370                                         continue;
5371                                 }
5372                                 if (sources_used_by_this_snapshot.find (afs) == sources_used_by_this_snapshot.end ()) {
5373                                         continue;
5374                                 }
5375                         }
5376
5377                         orig_sources[afs] = afs->path();
5378                         orig_gain[afs]    = afs->gain();
5379
5380                         std::string new_path = make_new_media_path (afs->path (), to_dir, name);
5381
5382                         std::string channelsuffix = "";
5383                         if (afs->channel() > 0) {  /* n_channels() is /wrongly/ 1. */
5384                                 /* embedded external multi-channel files are converted to multiple-mono */
5385                                 channelsuffix = string_compose ("-c%1", afs->channel ());
5386                         }
5387                         new_path = Glib::build_filename (Glib::path_get_dirname (new_path), PBD::basename_nosuffix (new_path) + channelsuffix + ".flac");
5388                         g_mkdir_with_parents (Glib::path_get_dirname (new_path).c_str (), 0755);
5389
5390
5391                         if (progress) {
5392                                 progress->descend ((float)afs->readable_length () / total_size);
5393                         }
5394
5395                         try {
5396                                 SndFileSource* ns = new SndFileSource (*this, *(afs.get()), new_path, compress_audio == FLAC_16BIT, progress);
5397                                 afs->replace_file (new_path);
5398                                 afs->set_gain (ns->gain(), true);
5399                                 delete ns;
5400                         } catch (...) {
5401                                 cerr << "failed to encode " << afs->path() << " to " << new_path << "\n";
5402                         }
5403
5404                         if (progress) {
5405                                 progress->ascend ();
5406                         }
5407                 }
5408         }
5409
5410         if (progress) {
5411                 progress->set_progress (-1); // set to "archiving"
5412                 progress->set_progress (0);
5413         }
5414
5415         /* index files relevant for this session */
5416         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
5417                 vector<string> files;
5418
5419                 size_t prefix_len = (*sd).path.size();
5420                 if (prefix_len > 0 && (*sd).path.at (prefix_len - 1) != G_DIR_SEPARATOR) {
5421                         ++prefix_len;
5422                 }
5423
5424                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
5425
5426                 static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
5427                 static const std::string videofile_dir_string = string (video_dir_name) + G_DIR_SEPARATOR;
5428                 static const std::string midifile_dir_string  = string (midi_dir_name)  + G_DIR_SEPARATOR;
5429
5430                 for (vector<string>::const_iterator i = files.begin (); i != files.end (); ++i) {
5431                         std::string from = *i;
5432
5433 #ifdef __APPLE__
5434                         string filename = Glib::path_get_basename (from);
5435                         std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
5436                         if (filename == ".DS_STORE") {
5437                                 continue;
5438                         }
5439 #endif
5440
5441                         if (from.find (audiofile_dir_string) != string::npos) {
5442                                 ; // handled above
5443                         } else if (from.find (midifile_dir_string) != string::npos) {
5444                                 filemap[from] = make_new_media_path (from, name, name);
5445                         } else if (from.find (videofile_dir_string) != string::npos) {
5446                                 filemap[from] = make_new_media_path (from, name, name);
5447                         } else {
5448                                 bool do_copy = true;
5449                                 for (vector<string>::iterator v = blacklist_dirs.begin(); v != blacklist_dirs.end(); ++v) {
5450                                         if (from.find (*v) != string::npos) {
5451                                                 do_copy = false;
5452                                                 break;
5453                                         }
5454                                 }
5455                                 for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
5456                                         if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
5457                                                 do_copy = false;
5458                                                 break;
5459                                         }
5460                                 }
5461
5462                                 if (do_copy) {
5463                                         filemap[from] = name + G_DIR_SEPARATOR + from.substr (prefix_len);
5464                                 }
5465                         }
5466                 }
5467         }
5468
5469         /* write session file */
5470         _path = to_dir;
5471         g_mkdir_with_parents (externals_dir ().c_str (), 0755);
5472 #ifdef LV2_SUPPORT
5473         PBD::Unwinder<bool> uw (LV2Plugin::force_state_save, true);
5474 #endif
5475         save_state (name, /*pending, don't fork MIDI, don't mark clean */ true);
5476
5477 #ifndef NDEBUG
5478         cerr << "archiving state from "
5479                 << Glib::build_filename (to_dir, legalize_for_path (name) + pending_suffix)
5480                 << " to "
5481                 << Glib::build_filename (to_dir, legalize_for_path (name) + statefile_suffix)
5482                 << endl;
5483 #endif
5484
5485         ::g_rename (
5486                         Glib::build_filename (to_dir, legalize_for_path (name) + pending_suffix).c_str(),
5487                         Glib::build_filename (to_dir, legalize_for_path (name) + statefile_suffix).c_str());
5488
5489         save_default_options ();
5490
5491         size_t prefix_len = _path.size();
5492         if (prefix_len > 0 && _path.at (prefix_len - 1) != G_DIR_SEPARATOR) {
5493                 ++prefix_len;
5494         }
5495
5496         /* collect session-state files */
5497         vector<string> files;
5498         do_not_copy_extensions.clear ();
5499         do_not_copy_extensions.push_back (history_suffix);
5500
5501         blacklist_dirs.clear ();
5502         blacklist_dirs.push_back (string (externals_dir_name) + G_DIR_SEPARATOR);
5503
5504         find_files_matching_filter (files, to_dir, accept_all_files, 0, false, true, true);
5505         for (vector<string>::const_iterator i = files.begin (); i != files.end (); ++i) {
5506                 std::string from = *i;
5507                 bool do_copy = true;
5508                 for (vector<string>::iterator v = blacklist_dirs.begin(); v != blacklist_dirs.end(); ++v) {
5509                         if (from.find (*v) != string::npos) {
5510                                 do_copy = false;
5511                                 break;
5512                         }
5513                 }
5514                 for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
5515                         if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
5516                                 do_copy = false;
5517                                 break;
5518                         }
5519                 }
5520                 if (do_copy) {
5521                         filemap[from] = name + G_DIR_SEPARATOR + from.substr (prefix_len);
5522                 }
5523         }
5524
5525         /* restore original values */
5526         _path = old_path;
5527         _name = old_name;
5528         set_snapshot_name (old_snapshot);
5529         (*_session_dir) = old_sd;
5530         if (was_dirty) {
5531                 set_dirty ();
5532         }
5533         config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
5534         config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
5535
5536         for (std::map<boost::shared_ptr<AudioFileSource>, std::string>::iterator i = orig_sources.begin (); i != orig_sources.end (); ++i) {
5537                 i->first->replace_file (i->second);
5538         }
5539         for (std::map<boost::shared_ptr<AudioFileSource>, float>::iterator i = orig_gain.begin (); i != orig_gain.end (); ++i) {
5540                 i->first->set_gain (i->second, true);
5541         }
5542
5543         int rv = ar.create (filemap, compression_level);
5544         remove_directory (to_dir);
5545
5546         return rv;
5547 }
5548
5549 void
5550 Session::undo (uint32_t n)
5551 {
5552         if (actively_recording()) {
5553                 return;
5554         }
5555
5556         _history.undo (n);
5557 }
5558
5559 void
5560 Session::redo (uint32_t n)
5561 {
5562         if (actively_recording()) {
5563                 return;
5564         }
5565
5566         _history.redo (n);
5567 }