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