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