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