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