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