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