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