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