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