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