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