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