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