5729c889bd8380bfc88cd506284b03eadaa87a79
[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 (0 == g_stat ((*x).c_str(), &statbuf)) {
3308
3309                         if (::g_rename ((*x).c_str(), newpath.c_str()) != 0) {
3310                                 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"), (*x), newpath, g_strerror (errno)) << endmsg;
3311                                 continue;
3312                         }
3313
3314                         /* see if there an easy to find peakfile for this file, and remove it.
3315                          */
3316
3317                                         string base = Glib::path_get_basename (*x);
3318                                         base += "%A"; /* this is what we add for the channel suffix of all native files,
3319                                                                          or for the first channel of embedded files. it will miss
3320                                                                          some peakfiles for other channels
3321                                                                   */
3322                         string peakpath = construct_peak_filepath (base);
3323
3324                         if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
3325                                 if (::g_unlink (peakpath.c_str()) != 0) {
3326                                         error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3327                                                                                                                          peakpath, _path, g_strerror (errno))
3328                                                   << endmsg;
3329                                         /* try to back out */
3330                                         ::g_rename (newpath.c_str(), _path.c_str());
3331                                         goto out;
3332                                 }
3333                         }
3334
3335                         rep.paths.push_back (*x);
3336                         rep.space += statbuf.st_size;
3337                 }
3338         }
3339
3340         /* dump the history list */
3341
3342         _history.clear ();
3343
3344         /* save state so we don't end up a session file
3345            referring to non-existent sources.
3346         */
3347
3348         save_state ("");
3349         ret = 0;
3350
3351   out:
3352         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3353
3354         return ret;
3355 }
3356
3357 int
3358 Session::cleanup_trash_sources (CleanupReport& rep)
3359 {
3360         // FIXME: needs adaptation for MIDI
3361
3362         vector<space_and_path>::iterator i;
3363         string dead_dir;
3364
3365         rep.paths.clear ();
3366         rep.space = 0;
3367
3368         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3369
3370                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3371
3372                 clear_directory (dead_dir, &rep.space, &rep.paths);
3373         }
3374
3375         return 0;
3376 }
3377
3378 void
3379 Session::set_dirty ()
3380 {
3381         /* never mark session dirty during loading */
3382
3383         if (_state_of_the_state & Loading) {
3384                 return;
3385         }
3386
3387         bool was_dirty = dirty();
3388
3389         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3390
3391
3392         if (!was_dirty) {
3393                 DirtyChanged(); /* EMIT SIGNAL */
3394         }
3395 }
3396
3397
3398 void
3399 Session::set_clean ()
3400 {
3401         bool was_dirty = dirty();
3402
3403         _state_of_the_state = Clean;
3404
3405
3406         if (was_dirty) {
3407                 DirtyChanged(); /* EMIT SIGNAL */
3408         }
3409 }
3410
3411 void
3412 Session::set_deletion_in_progress ()
3413 {
3414         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3415 }
3416
3417 void
3418 Session::clear_deletion_in_progress ()
3419 {
3420         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3421 }
3422
3423 void
3424 Session::add_controllable (boost::shared_ptr<Controllable> c)
3425 {
3426         /* this adds a controllable to the list managed by the Session.
3427            this is a subset of those managed by the Controllable class
3428            itself, and represents the only ones whose state will be saved
3429            as part of the session.
3430         */
3431
3432         Glib::Threads::Mutex::Lock lm (controllables_lock);
3433         controllables.insert (c);
3434 }
3435
3436 struct null_deleter { void operator()(void const *) const {} };
3437
3438 void
3439 Session::remove_controllable (Controllable* c)
3440 {
3441         if (_state_of_the_state & Deletion) {
3442                 return;
3443         }
3444
3445         Glib::Threads::Mutex::Lock lm (controllables_lock);
3446
3447         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3448
3449         if (x != controllables.end()) {
3450                 controllables.erase (x);
3451         }
3452 }
3453
3454 boost::shared_ptr<Controllable>
3455 Session::controllable_by_id (const PBD::ID& id)
3456 {
3457         Glib::Threads::Mutex::Lock lm (controllables_lock);
3458
3459         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3460                 if ((*i)->id() == id) {
3461                         return *i;
3462                 }
3463         }
3464
3465         return boost::shared_ptr<Controllable>();
3466 }
3467
3468 boost::shared_ptr<Controllable>
3469 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3470 {
3471         boost::shared_ptr<Controllable> c;
3472         boost::shared_ptr<Stripable> s;
3473         boost::shared_ptr<Route> r;
3474
3475         switch (desc.top_level_type()) {
3476         case ControllableDescriptor::NamedRoute:
3477         {
3478                 std::string str = desc.top_level_name();
3479
3480                 if (str == "Master" || str == "master") {
3481                         s = _master_out;
3482                 } else if (str == "control" || str == "listen" || str == "monitor" || str == "Monitor") {
3483                         s = _monitor_out;
3484                 } else if (str == "auditioner") {
3485                         s = auditioner;
3486                 } else {
3487                         s = route_by_name (desc.top_level_name());
3488                 }
3489
3490                 break;
3491         }
3492
3493         case ControllableDescriptor::PresentationOrderRoute:
3494                 s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Route);
3495                 break;
3496
3497         case ControllableDescriptor::PresentationOrderTrack:
3498                 s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Track);
3499                 break;
3500
3501         case ControllableDescriptor::PresentationOrderBus:
3502                 s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Bus);
3503                 break;
3504
3505         case ControllableDescriptor::PresentationOrderVCA:
3506                 s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::VCA);
3507                 break;
3508
3509         case ControllableDescriptor::SelectionCount:
3510                 s = route_by_selected_count (desc.selection_id());
3511                 break;
3512         }
3513
3514         if (!s) {
3515                 return c;
3516         }
3517
3518         r = boost::dynamic_pointer_cast<Route> (s);
3519
3520         switch (desc.subtype()) {
3521         case ControllableDescriptor::Gain:
3522                 c = s->gain_control ();
3523                 break;
3524
3525         case ControllableDescriptor::Trim:
3526                 c = s->trim_control ();
3527                 break;
3528
3529         case ControllableDescriptor::Solo:
3530                 c = s->solo_control();
3531                 break;
3532
3533         case ControllableDescriptor::Mute:
3534                 c = s->mute_control();
3535                 break;
3536
3537         case ControllableDescriptor::Recenable:
3538                 c = s->rec_enable_control ();
3539                 break;
3540
3541         case ControllableDescriptor::PanDirection:
3542                 c = s->pan_azimuth_control();
3543                 break;
3544
3545         case ControllableDescriptor::PanWidth:
3546                 c = s->pan_width_control();
3547                 break;
3548
3549         case ControllableDescriptor::PanElevation:
3550                 c = s->pan_elevation_control();
3551                 break;
3552
3553         case ControllableDescriptor::Balance:
3554                 /* XXX simple pan control */
3555                 break;
3556
3557         case ControllableDescriptor::PluginParameter:
3558         {
3559                 uint32_t plugin = desc.target (0);
3560                 uint32_t parameter_index = desc.target (1);
3561
3562                 /* revert to zero based counting */
3563
3564                 if (plugin > 0) {
3565                         --plugin;
3566                 }
3567
3568                 if (parameter_index > 0) {
3569                         --parameter_index;
3570                 }
3571
3572                 if (!r) {
3573                         return c;
3574                 }
3575
3576                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3577
3578                 if (p) {
3579                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3580                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3581                 }
3582                 break;
3583         }
3584
3585         case ControllableDescriptor::SendGain: {
3586                 uint32_t send = desc.target (0);
3587                 if (send > 0) {
3588                         --send;
3589                 }
3590                 if (!r) {
3591                         return c;
3592                 }
3593                 c = r->send_level_controllable (send);
3594                 break;
3595         }
3596
3597         default:
3598                 /* relax and return a null pointer */
3599                 break;
3600         }
3601
3602         return c;
3603 }
3604
3605 void
3606 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3607 {
3608         if (_writable) {
3609                 Stateful::add_instant_xml (node, _path);
3610         }
3611
3612         if (write_to_config) {
3613                 Config->add_instant_xml (node);
3614         }
3615 }
3616
3617 XMLNode*
3618 Session::instant_xml (const string& node_name)
3619 {
3620         return Stateful::instant_xml (node_name, _path);
3621 }
3622
3623 int
3624 Session::save_history (string snapshot_name)
3625 {
3626         XMLTree tree;
3627
3628         if (!_writable) {
3629                 return 0;
3630         }
3631
3632         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 ||
3633             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3634                 return 0;
3635         }
3636
3637         if (snapshot_name.empty()) {
3638                 snapshot_name = _current_snapshot_name;
3639         }
3640
3641         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3642         const string backup_filename = history_filename + backup_suffix;
3643         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3644         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3645
3646         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3647                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3648                         error << _("could not backup old history file, current history not saved") << endmsg;
3649                         return -1;
3650                 }
3651         }
3652
3653         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3654
3655         if (!tree.write (xml_path))
3656         {
3657                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3658
3659                 if (g_remove (xml_path.c_str()) != 0) {
3660                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3661                                         xml_path, g_strerror (errno)) << endmsg;
3662                 }
3663                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3664                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3665                                         backup_path, g_strerror (errno)) << endmsg;
3666                 }
3667
3668                 return -1;
3669         }
3670
3671         return 0;
3672 }
3673
3674 int
3675 Session::restore_history (string snapshot_name)
3676 {
3677         XMLTree tree;
3678
3679         if (snapshot_name.empty()) {
3680                 snapshot_name = _current_snapshot_name;
3681         }
3682
3683         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3684         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3685
3686         info << "Loading history from " << xml_path << endmsg;
3687
3688         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3689                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3690                                 _name, xml_path) << endmsg;
3691                 return 1;
3692         }
3693
3694         if (!tree.read (xml_path)) {
3695                 error << string_compose (_("Could not understand session history file \"%1\""),
3696                                 xml_path) << endmsg;
3697                 return -1;
3698         }
3699
3700         // replace history
3701         _history.clear();
3702
3703         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3704
3705                 XMLNode *t = *it;
3706                 UndoTransaction* ut = new UndoTransaction ();
3707                 struct timeval tv;
3708
3709                 ut->set_name(t->property("name")->value());
3710                 stringstream ss(t->property("tv-sec")->value());
3711                 ss >> tv.tv_sec;
3712                 ss.str(t->property("tv-usec")->value());
3713                 ss >> tv.tv_usec;
3714                 ut->set_timestamp(tv);
3715
3716                 for (XMLNodeConstIterator child_it  = t->children().begin();
3717                                 child_it != t->children().end(); child_it++)
3718                 {
3719                         XMLNode *n = *child_it;
3720                         Command *c;
3721
3722                         if (n->name() == "MementoCommand" ||
3723                                         n->name() == "MementoUndoCommand" ||
3724                                         n->name() == "MementoRedoCommand") {
3725
3726                                 if ((c = memento_command_factory(n))) {
3727                                         ut->add_command(c);
3728                                 }
3729
3730                         } else if (n->name() == "NoteDiffCommand") {
3731                                 PBD::ID id (n->property("midi-source")->value());
3732                                 boost::shared_ptr<MidiSource> midi_source =
3733                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3734                                 if (midi_source) {
3735                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3736                                 } else {
3737                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3738                                 }
3739
3740                         } else if (n->name() == "SysExDiffCommand") {
3741
3742                                 PBD::ID id (n->property("midi-source")->value());
3743                                 boost::shared_ptr<MidiSource> midi_source =
3744                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3745                                 if (midi_source) {
3746                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3747                                 } else {
3748                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3749                                 }
3750
3751                         } else if (n->name() == "PatchChangeDiffCommand") {
3752
3753                                 PBD::ID id (n->property("midi-source")->value());
3754                                 boost::shared_ptr<MidiSource> midi_source =
3755                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3756                                 if (midi_source) {
3757                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3758                                 } else {
3759                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3760                                 }
3761
3762                         } else if (n->name() == "StatefulDiffCommand") {
3763                                 if ((c = stateful_diff_command_factory (n))) {
3764                                         ut->add_command (c);
3765                                 }
3766                         } else {
3767                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3768                         }
3769                 }
3770
3771                 _history.add (ut);
3772         }
3773
3774         return 0;
3775 }
3776
3777 void
3778 Session::config_changed (std::string p, bool ours)
3779 {
3780         if (ours) {
3781                 set_dirty ();
3782         }
3783
3784         if (p == "seamless-loop") {
3785
3786         } else if (p == "rf-speed") {
3787
3788         } else if (p == "auto-loop") {
3789
3790         } else if (p == "auto-input") {
3791
3792                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3793                         /* auto-input only makes a difference if we're rolling */
3794                         set_track_monitor_input_status (!config.get_auto_input());
3795                 }
3796
3797         } else if (p == "punch-in") {
3798
3799                 Location* location;
3800
3801                 if ((location = _locations->auto_punch_location()) != 0) {
3802
3803                         if (config.get_punch_in ()) {
3804                                 replace_event (SessionEvent::PunchIn, location->start());
3805                         } else {
3806                                 remove_event (location->start(), SessionEvent::PunchIn);
3807                         }
3808                 }
3809
3810         } else if (p == "punch-out") {
3811
3812                 Location* location;
3813
3814                 if ((location = _locations->auto_punch_location()) != 0) {
3815
3816                         if (config.get_punch_out()) {
3817                                 replace_event (SessionEvent::PunchOut, location->end());
3818                         } else {
3819                                 clear_events (SessionEvent::PunchOut);
3820                         }
3821                 }
3822
3823         } else if (p == "edit-mode") {
3824
3825                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3826
3827                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3828                         (*i)->set_edit_mode (Config->get_edit_mode ());
3829                 }
3830
3831         } else if (p == "use-video-sync") {
3832
3833                 waiting_for_sync_offset = config.get_use_video_sync();
3834
3835         } else if (p == "mmc-control") {
3836
3837                 //poke_midi_thread ();
3838
3839         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3840
3841                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3842
3843         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3844
3845                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3846
3847         } else if (p == "midi-control") {
3848
3849                 //poke_midi_thread ();
3850
3851         } else if (p == "raid-path") {
3852
3853                 setup_raid_path (config.get_raid_path());
3854
3855         } else if (p == "timecode-format") {
3856
3857                 sync_time_vars ();
3858
3859         } else if (p == "video-pullup") {
3860
3861                 sync_time_vars ();
3862
3863         } else if (p == "seamless-loop") {
3864
3865                 if (play_loop && transport_rolling()) {
3866                         // to reset diskstreams etc
3867                         request_play_loop (true);
3868                 }
3869
3870         } else if (p == "rf-speed") {
3871
3872                 cumulative_rf_motion = 0;
3873                 reset_rf_scale (0);
3874
3875         } else if (p == "click-sound") {
3876
3877                 setup_click_sounds (1);
3878
3879         } else if (p == "click-emphasis-sound") {
3880
3881                 setup_click_sounds (-1);
3882
3883         } else if (p == "clicking") {
3884
3885                 if (Config->get_clicking()) {
3886                         if (_click_io && click_data) { // don't require emphasis data
3887                                 _clicking = true;
3888                         }
3889                 } else {
3890                         _clicking = false;
3891                 }
3892
3893         } else if (p == "click-gain") {
3894
3895                 if (_click_gain) {
3896                         _click_gain->gain_control()->set_value (Config->get_click_gain(), Controllable::NoGroup);
3897                 }
3898
3899         } else if (p == "send-mtc") {
3900
3901                 if (Config->get_send_mtc ()) {
3902                         /* mark us ready to send */
3903                         next_quarter_frame_to_send = 0;
3904                 }
3905
3906         } else if (p == "send-mmc") {
3907
3908                 _mmc->enable_send (Config->get_send_mmc ());
3909
3910         } else if (p == "midi-feedback") {
3911
3912                 session_midi_feedback = Config->get_midi_feedback();
3913
3914         } else if (p == "jack-time-master") {
3915
3916                 engine().reset_timebase ();
3917
3918         } else if (p == "native-file-header-format") {
3919
3920                 if (!first_file_header_format_reset) {
3921                         reset_native_file_format ();
3922                 }
3923
3924                 first_file_header_format_reset = false;
3925
3926         } else if (p == "native-file-data-format") {
3927
3928                 if (!first_file_data_format_reset) {
3929                         reset_native_file_format ();
3930                 }
3931
3932                 first_file_data_format_reset = false;
3933
3934         } else if (p == "external-sync") {
3935                 if (!config.get_external_sync()) {
3936                         drop_sync_source ();
3937                 } else {
3938                         switch_to_sync_source (Config->get_sync_source());
3939                 }
3940         }  else if (p == "denormal-model") {
3941                 setup_fpu ();
3942         } else if (p == "history-depth") {
3943                 set_history_depth (Config->get_history_depth());
3944         } else if (p == "remote-model") {
3945                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3946                    TO SET REMOTE ID'S
3947                 */
3948         } else if (p == "initial-program-change") {
3949
3950                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3951                         MIDI::byte buf[2];
3952
3953                         buf[0] = MIDI::program; // channel zero by default
3954                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3955
3956                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3957                 }
3958         } else if (p == "solo-mute-override") {
3959                 // catch_up_on_solo_mute_override ();
3960         } else if (p == "listen-position" || p == "pfl-position") {
3961                 listen_position_changed ();
3962         } else if (p == "solo-control-is-listen-control") {
3963                 solo_control_mode_changed ();
3964         } else if (p == "solo-mute-gain") {
3965                 _solo_cut_control->Changed (true, Controllable::NoGroup);
3966         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3967                 last_timecode_valid = false;
3968         } else if (p == "playback-buffer-seconds") {
3969                 AudioSource::allocate_working_buffers (frame_rate());
3970         } else if (p == "ltc-source-port") {
3971                 reconnect_ltc_input ();
3972         } else if (p == "ltc-sink-port") {
3973                 reconnect_ltc_output ();
3974         } else if (p == "timecode-generator-offset") {
3975                 ltc_tx_parse_offset();
3976         } else if (p == "auto-return-target-list") {
3977                 follow_playhead_priority ();
3978         }
3979
3980         set_dirty ();
3981 }
3982
3983 void
3984 Session::set_history_depth (uint32_t d)
3985 {
3986         _history.set_depth (d);
3987 }
3988
3989 int
3990 Session::load_diskstreams_2X (XMLNode const & node, int)
3991 {
3992         XMLNodeList          clist;
3993         XMLNodeConstIterator citer;
3994
3995         clist = node.children();
3996
3997         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3998
3999                 try {
4000                         /* diskstreams added automatically by DiskstreamCreated handler */
4001                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
4002                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
4003                                 _diskstreams_2X.push_back (dsp);
4004                         } else {
4005                                 error << _("Session: unknown diskstream type in XML") << endmsg;
4006                         }
4007                 }
4008
4009                 catch (failed_constructor& err) {
4010                         error << _("Session: could not load diskstream via XML state") << endmsg;
4011                         return -1;
4012                 }
4013         }
4014
4015         return 0;
4016 }
4017
4018 /** Connect things to the MMC object */
4019 void
4020 Session::setup_midi_machine_control ()
4021 {
4022         _mmc = new MIDI::MachineControl;
4023
4024         boost::shared_ptr<AsyncMIDIPort> async_in = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_input_port());
4025         boost::shared_ptr<AsyncMIDIPort> async_out = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_output_port());
4026
4027         if (!async_out || !async_out) {
4028                 return;
4029         }
4030
4031         /* XXXX argh, passing raw pointers back into libmidi++ */
4032
4033         MIDI::Port* mmc_in = async_in.get();
4034         MIDI::Port* mmc_out = async_out.get();
4035
4036         _mmc->set_ports (mmc_in, mmc_out);
4037
4038         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
4039         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
4040         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
4041         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
4042         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
4043         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
4044         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
4045         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
4046         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
4047         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
4048         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
4049         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
4050         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
4051
4052         /* also handle MIDI SPP because its so common */
4053
4054         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
4055         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
4056         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
4057 }
4058
4059 boost::shared_ptr<Controllable>
4060 Session::solo_cut_control() const
4061 {
4062         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
4063            controls in Ardour that currently get presented to the user in the GUI that require
4064            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
4065
4066            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
4067            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
4068            parameter.
4069         */
4070
4071         return _solo_cut_control;
4072 }
4073
4074 void
4075 Session::save_snapshot_name (const std::string & n)
4076 {
4077         /* assure Stateful::_instant_xml is loaded
4078          * add_instant_xml() only adds to existing data and defaults
4079          * to use an empty Tree otherwise
4080          */
4081         instant_xml ("LastUsedSnapshot");
4082
4083         XMLNode* last_used_snapshot = new XMLNode ("LastUsedSnapshot");
4084         last_used_snapshot->add_property ("name", string(n));
4085         add_instant_xml (*last_used_snapshot, false);
4086 }
4087
4088 void
4089 Session::set_snapshot_name (const std::string & n)
4090 {
4091         _current_snapshot_name = n;
4092         save_snapshot_name (n);
4093 }
4094
4095 int
4096 Session::rename (const std::string& new_name)
4097 {
4098         string legal_name = legalize_for_path (new_name);
4099         string new_path;
4100         string oldstr;
4101         string newstr;
4102         bool first = true;
4103
4104         string const old_sources_root = _session_dir->sources_root();
4105
4106         if (!_writable || (_state_of_the_state & CannotSave)) {
4107                 error << _("Cannot rename read-only session.") << endmsg;
4108                 return 0; // don't show "messed up" warning
4109         }
4110         if (record_status() == Recording) {
4111                 error << _("Cannot rename session while recording") << endmsg;
4112                 return 0; // don't show "messed up" warning
4113         }
4114
4115         StateProtector stp (this);
4116
4117         /* Rename:
4118
4119          * session directory
4120          * interchange subdirectory
4121          * session file
4122          * session history
4123
4124          * Backup files are left unchanged and not renamed.
4125          */
4126
4127         /* Windows requires that we close all files before attempting the
4128          * rename. This works on other platforms, but isn't necessary there.
4129          * Leave it in place for all platforms though, since it may help
4130          * catch issues that could arise if the way Source files work ever
4131          * change (since most developers are not using Windows).
4132          */
4133
4134         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4135                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4136                 if (fs) {
4137                         fs->close ();
4138                 }
4139         }
4140
4141         /* pass one: not 100% safe check that the new directory names don't
4142          * already exist ...
4143          */
4144
4145         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4146
4147                 oldstr = (*i).path;
4148
4149                 /* this is a stupid hack because Glib::path_get_dirname() is
4150                  * lexical-only, and so passing it /a/b/c/ gives a different
4151                  * result than passing it /a/b/c ...
4152                  */
4153
4154                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
4155                         oldstr = oldstr.substr (0, oldstr.length() - 1);
4156                 }
4157
4158                 string base = Glib::path_get_dirname (oldstr);
4159
4160                 newstr = Glib::build_filename (base, legal_name);
4161
4162                 cerr << "Looking for " << newstr << endl;
4163
4164                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
4165                         cerr << " exists\n";
4166                         return -1;
4167                 }
4168         }
4169
4170         /* Session dirs */
4171
4172         first = true;
4173
4174         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4175
4176                 vector<string> v;
4177
4178                 oldstr = (*i).path;
4179
4180                 /* this is a stupid hack because Glib::path_get_dirname() is
4181                  * lexical-only, and so passing it /a/b/c/ gives a different
4182                  * result than passing it /a/b/c ...
4183                  */
4184
4185                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
4186                         oldstr = oldstr.substr (0, oldstr.length() - 1);
4187                 }
4188
4189                 string base = Glib::path_get_dirname (oldstr);
4190                 newstr = Glib::build_filename (base, legal_name);
4191
4192                 cerr << "for " << oldstr << " new dir = " << newstr << endl;
4193
4194                 cerr << "Rename " << oldstr << " => " << newstr << endl;
4195                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4196                         cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4197                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4198                         return 1;
4199                 }
4200
4201                 /* Reset path in "session dirs" */
4202
4203                 (*i).path = newstr;
4204                 (*i).blocks = 0;
4205
4206                 /* reset primary SessionDirectory object */
4207
4208                 if (first) {
4209                         (*_session_dir) = newstr;
4210                         new_path = newstr;
4211                         first = false;
4212                 }
4213
4214                 /* now rename directory below session_dir/interchange */
4215
4216                 string old_interchange_dir;
4217                 string new_interchange_dir;
4218
4219                 /* use newstr here because we renamed the path
4220                  * (folder/directory) that used to be oldstr to newstr above
4221                  */
4222
4223                 v.push_back (newstr);
4224                 v.push_back (interchange_dir_name);
4225                 v.push_back (Glib::path_get_basename (oldstr));
4226
4227                 old_interchange_dir = Glib::build_filename (v);
4228
4229                 v.clear ();
4230                 v.push_back (newstr);
4231                 v.push_back (interchange_dir_name);
4232                 v.push_back (legal_name);
4233
4234                 new_interchange_dir = Glib::build_filename (v);
4235
4236                 cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
4237
4238                 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
4239                         cerr << string_compose (_("renaming %s as %2 failed (%3)"),
4240                                                  old_interchange_dir, new_interchange_dir,
4241                                                  g_strerror (errno))
4242                               << endl;
4243                         error << string_compose (_("renaming %s as %2 failed (%3)"),
4244                                                  old_interchange_dir, new_interchange_dir,
4245                                                  g_strerror (errno))
4246                               << endmsg;
4247                         return 1;
4248                 }
4249         }
4250
4251         /* state file */
4252
4253         oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
4254         newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
4255
4256         cerr << "Rename " << oldstr << " => " << newstr << endl;
4257
4258         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4259                 cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4260                 error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4261                 return 1;
4262         }
4263
4264         /* history file */
4265
4266         oldstr = Glib::build_filename (new_path, _current_snapshot_name) + history_suffix;
4267
4268         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
4269                 newstr = Glib::build_filename (new_path, legal_name) + history_suffix;
4270
4271                 cerr << "Rename " << oldstr << " => " << newstr << endl;
4272
4273                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4274                         cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4275                         error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4276                         return 1;
4277                 }
4278         }
4279
4280         /* remove old name from recent sessions */
4281         remove_recent_sessions (_path);
4282         _path = new_path;
4283
4284         /* update file source paths */
4285
4286         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
4287                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4288                 if (fs) {
4289                         string p = fs->path ();
4290                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
4291                         fs->set_path (p);
4292                         SourceFactory::setup_peakfile(i->second, true);
4293                 }
4294         }
4295
4296         set_snapshot_name (new_name);
4297         _name = new_name;
4298
4299         set_dirty ();
4300
4301         /* save state again to get everything just right */
4302
4303         save_state (_current_snapshot_name);
4304
4305         /* add to recent sessions */
4306
4307         store_recent_sessions (new_name, _path);
4308
4309         return 0;
4310 }
4311
4312 int
4313 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
4314 {
4315         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
4316                 return -1;
4317         }
4318
4319         if (!tree.read (xmlpath)) {
4320                 return -1;
4321         }
4322
4323         return 0;
4324 }
4325
4326 int
4327 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
4328 {
4329         XMLTree tree;
4330         bool found_sr = false;
4331         bool found_data_format = false;
4332
4333         if (get_session_info_from_path (tree, xmlpath)) {
4334                 return -1;
4335         }
4336
4337         /* sample rate */
4338
4339         XMLProperty const * prop;
4340         XMLNode const * root (tree.root());
4341
4342         if ((prop = root->property (X_("sample-rate"))) != 0) {
4343                 sample_rate = atoi (prop->value());
4344                 found_sr = true;
4345         }
4346
4347         const XMLNodeList& children (root->children());
4348         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
4349                 const XMLNode* child = *c;
4350                 if (child->name() == "Config") {
4351                         const XMLNodeList& options (child->children());
4352                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
4353                                 XMLNode const * option = *oc;
4354                                 XMLProperty const * name = option->property("name");
4355
4356                                 if (!name) {
4357                                         continue;
4358                                 }
4359
4360                                 if (name->value() == "native-file-data-format") {
4361                                         XMLProperty const * value = option->property ("value");
4362                                         if (value) {
4363                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
4364                                                 data_format = fmt;
4365                                                 found_data_format = true;
4366                                                 break;
4367                                         }
4368                                 }
4369                         }
4370                 }
4371                 if (found_data_format) {
4372                         break;
4373                 }
4374         }
4375
4376         return !(found_sr && found_data_format); // zero if they are both found
4377 }
4378
4379 std::string
4380 Session::get_snapshot_from_instant (const std::string& session_dir)
4381 {
4382         std::string instant_xml_path = Glib::build_filename (session_dir, "instant.xml");
4383
4384         if (!Glib::file_test (instant_xml_path, Glib::FILE_TEST_EXISTS)) {
4385                 return "";
4386         }
4387
4388         XMLTree tree;
4389         if (!tree.read (instant_xml_path)) {
4390                 return "";
4391         }
4392
4393         XMLProperty const * prop;
4394         XMLNode *last_used_snapshot = tree.root()->child("LastUsedSnapshot");
4395         if (last_used_snapshot && (prop = last_used_snapshot->property ("name")) != 0) {
4396                 return prop->value();
4397         }
4398
4399         return "";
4400 }
4401
4402 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
4403 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
4404
4405 int
4406 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
4407 {
4408         uint32_t total = 0;
4409         uint32_t n = 0;
4410         SourcePathMap source_path_map;
4411         string new_path;
4412         boost::shared_ptr<AudioFileSource> afs;
4413         int ret = 0;
4414
4415         {
4416
4417                 Glib::Threads::Mutex::Lock lm (source_lock);
4418
4419                 cerr << " total sources = " << sources.size();
4420
4421                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4422                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4423
4424                         if (!fs) {
4425                                 continue;
4426                         }
4427
4428                         if (fs->within_session()) {
4429                                 continue;
4430                         }
4431
4432                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
4433                                 source_path_map[fs->path()].push_back (fs);
4434                         } else {
4435                                 SeveralFileSources v;
4436                                 v.push_back (fs);
4437                                 source_path_map.insert (make_pair (fs->path(), v));
4438                         }
4439
4440                         total++;
4441                 }
4442
4443                 cerr << " fsources = " << total << endl;
4444
4445                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
4446
4447                         /* tell caller where we are */
4448
4449                         string old_path = i->first;
4450
4451                         callback (n, total, old_path);
4452
4453                         cerr << old_path << endl;
4454
4455                         new_path.clear ();
4456
4457                         switch (i->second.front()->type()) {
4458                         case DataType::AUDIO:
4459                                 new_path = new_audio_source_path_for_embedded (old_path);
4460                                 break;
4461
4462                         case DataType::MIDI:
4463                                 /* XXX not implemented yet */
4464                                 break;
4465                         }
4466
4467                         if (new_path.empty()) {
4468                                 continue;
4469                         }
4470
4471                         cerr << "Move " << old_path << " => " << new_path << endl;
4472
4473                         if (!copy_file (old_path, new_path)) {
4474                                 cerr << "failed !\n";
4475                                 ret = -1;
4476                         }
4477
4478                         /* make sure we stop looking in the external
4479                            dir/folder. Remember, this is an all-or-nothing
4480                            operations, it doesn't merge just some files.
4481                         */
4482                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
4483
4484                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
4485                                 (*f)->set_path (new_path);
4486                         }
4487                 }
4488         }
4489
4490         save_state ("", false, false);
4491
4492         return ret;
4493 }
4494
4495 static
4496 bool accept_all_files (string const &, void *)
4497 {
4498         return true;
4499 }
4500
4501 void
4502 Session::save_as_bring_callback (uint32_t,uint32_t,string)
4503 {
4504         /* 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.
4505         */
4506 }
4507
4508 static string
4509 make_new_media_path (string old_path, string new_session_folder, string new_session_path)
4510 {
4511         /* typedir is the "midifiles" or "audiofiles" etc. part of the path. */
4512
4513         string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4514         vector<string> v;
4515         v.push_back (new_session_folder); /* full path */
4516         v.push_back (interchange_dir_name);
4517         v.push_back (new_session_path);   /* just one directory/folder */
4518         v.push_back (typedir);
4519         v.push_back (Glib::path_get_basename (old_path));
4520
4521         return Glib::build_filename (v);
4522 }
4523
4524 int
4525 Session::save_as (SaveAs& saveas)
4526 {
4527         vector<string> files;
4528         string current_folder = Glib::path_get_dirname (_path);
4529         string new_folder = legalize_for_path (saveas.new_name);
4530         string to_dir = Glib::build_filename (saveas.new_parent_folder, new_folder);
4531         int64_t total_bytes = 0;
4532         int64_t copied = 0;
4533         int64_t cnt = 0;
4534         int64_t all = 0;
4535         int32_t internal_file_cnt = 0;
4536
4537         vector<string> do_not_copy_extensions;
4538         do_not_copy_extensions.push_back (statefile_suffix);
4539         do_not_copy_extensions.push_back (pending_suffix);
4540         do_not_copy_extensions.push_back (backup_suffix);
4541         do_not_copy_extensions.push_back (temp_suffix);
4542         do_not_copy_extensions.push_back (history_suffix);
4543
4544         /* get total size */
4545
4546         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4547
4548                 /* need to clear this because
4549                  * find_files_matching_filter() is cumulative
4550                  */
4551
4552                 files.clear ();
4553
4554                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4555
4556                 all += files.size();
4557
4558                 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4559                         GStatBuf gsb;
4560                         g_stat ((*i).c_str(), &gsb);
4561                         total_bytes += gsb.st_size;
4562                 }
4563         }
4564
4565         /* save old values so we can switch back if we are not switching to the new session */
4566
4567         string old_path = _path;
4568         string old_name = _name;
4569         string old_snapshot = _current_snapshot_name;
4570         string old_sd = _session_dir->root_path();
4571         vector<string> old_search_path[DataType::num_types];
4572         string old_config_search_path[DataType::num_types];
4573
4574         old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4575         old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4576         old_config_search_path[DataType::AUDIO]  = config.get_audio_search_path ();
4577         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();
4578
4579         /* switch session directory */
4580
4581         (*_session_dir) = to_dir;
4582
4583         /* create new tree */
4584
4585         if (!_session_dir->create()) {
4586                 saveas.failure_message = string_compose (_("Cannot create new session folder %1"), to_dir);
4587                 return -1;
4588         }
4589
4590         try {
4591                 /* copy all relevant files. Find each location in session_dirs,
4592                  * and copy files from there to target.
4593                  */
4594
4595                 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4596
4597                         /* need to clear this because
4598                          * find_files_matching_filter() is cumulative
4599                          */
4600
4601                         files.clear ();
4602
4603                         const size_t prefix_len = (*sd).path.size();
4604
4605                         /* Work just on the files within this session dir */
4606
4607                         find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4608
4609                         /* add dir separator to protect against collisions with
4610                          * track names (e.g. track named "audiofiles" or
4611                          * "analysis".
4612                          */
4613
4614                         static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
4615                         static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
4616                         static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
4617
4618                         /* copy all the files. Handling is different for media files
4619                            than others because of the *silly* subtree we have below the interchange
4620                            folder. That really was a bad idea, but I'm not fixing it as part of
4621                            implementing ::save_as().
4622                         */
4623
4624                         for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4625
4626                                 std::string from = *i;
4627
4628 #ifdef __APPLE__
4629                                 string filename = Glib::path_get_basename (from);
4630                                 std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
4631                                 if (filename == ".DS_STORE") {
4632                                         continue;
4633                                 }
4634 #endif
4635
4636                                 if (from.find (audiofile_dir_string) != string::npos) {
4637
4638                                         /* audio file: only copy if asked */
4639
4640                                         if (saveas.include_media && saveas.copy_media) {
4641
4642                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4643
4644                                                 info << "media file copying from " << from << " to " << to << endmsg;
4645
4646                                                 if (!copy_file (from, to)) {
4647                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4648                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4649                                                 }
4650                                         }
4651
4652                                         /* we found media files inside the session folder */
4653
4654                                         internal_file_cnt++;
4655
4656                                 } else if (from.find (midifile_dir_string) != string::npos) {
4657
4658                                         /* midi file: always copy unless
4659                                          * creating an empty new session
4660                                          */
4661
4662                                         if (saveas.include_media) {
4663
4664                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4665
4666                                                 info << "media file copying from " << from << " to " << to << endmsg;
4667
4668                                                 if (!copy_file (from, to)) {
4669                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4670                                                 }
4671                                         }
4672
4673                                         /* we found media files inside the session folder */
4674
4675                                         internal_file_cnt++;
4676
4677                                 } else if (from.find (analysis_dir_string) != string::npos) {
4678
4679                                         /*  make sure analysis dir exists in
4680                                          *  new session folder, but we're not
4681                                          *  copying analysis files here, see
4682                                          *  below
4683                                          */
4684
4685                                         (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
4686                                         continue;
4687
4688                                 } else {
4689
4690                                         /* normal non-media file. Don't copy state, history, etc.
4691                                          */
4692
4693                                         bool do_copy = true;
4694
4695                                         for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4696                                                 if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
4697                                                         /* end of filename matches extension, do not copy file */
4698                                                         do_copy = false;
4699                                                         break;
4700                                                 }
4701                                         }
4702
4703                                         if (!saveas.copy_media && from.find (peakfile_suffix) != string::npos) {
4704                                                 /* don't copy peakfiles if
4705                                                  * we're not copying media
4706                                                  */
4707                                                 do_copy = false;
4708                                         }
4709
4710                                         if (do_copy) {
4711                                                 string to = Glib::build_filename (to_dir, from.substr (prefix_len));
4712
4713                                                 info << "attempting to make directory/folder " << to << endmsg;
4714
4715                                                 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4716                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
4717                                                 }
4718
4719                                                 info << "attempting to copy " << from << " to " << to << endmsg;
4720
4721                                                 if (!copy_file (from, to)) {
4722                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4723                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4724                                                 }
4725                                         }
4726                                 }
4727
4728                                 /* measure file size even if we're not going to copy so that our Progress
4729                                    signals are correct, since we included these do-not-copy files
4730                                    in the computation of the total size and file count.
4731                                 */
4732
4733                                 GStatBuf gsb;
4734                                 g_stat (from.c_str(), &gsb);
4735                                 copied += gsb.st_size;
4736                                 cnt++;
4737
4738                                 double fraction = (double) copied / total_bytes;
4739
4740                                 bool keep_going = true;
4741
4742                                 if (saveas.copy_media) {
4743
4744                                         /* no need or expectation of this if
4745                                          * media is not being copied, because
4746                                          * it will be fast(ish).
4747                                          */
4748
4749                                         /* tell someone "X percent, file M of N"; M is one-based */
4750
4751                                         boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
4752
4753                                         if (res) {
4754                                                 keep_going = *res;
4755                                         }
4756                                 }
4757
4758                                 if (!keep_going) {
4759                                         throw Glib::FileError (Glib::FileError::FAILED, "copy cancelled");
4760                                 }
4761                         }
4762
4763                 }
4764
4765                 /* copy optional folders, if any */
4766
4767                 string old = plugins_dir ();
4768                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4769                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4770                         copy_files (old, newdir);
4771                 }
4772
4773                 old = externals_dir ();
4774                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4775                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4776                         copy_files (old, newdir);
4777                 }
4778
4779                 old = automation_dir ();
4780                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4781                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4782                         copy_files (old, newdir);
4783                 }
4784
4785                 if (saveas.include_media) {
4786
4787                         if (saveas.copy_media) {
4788 #ifndef PLATFORM_WINDOWS
4789                                 /* There are problems with analysis files on
4790                                  * Windows, because they used a colon in their
4791                                  * names as late as 4.0. Colons are not legal
4792                                  * under Windows even if NTFS allows them.
4793                                  *
4794                                  * This is a tricky problem to solve so for
4795                                  * just don't copy these files. They will be
4796                                  * regenerated as-needed anyway, subject to the
4797                                  * existing issue that the filenames will be
4798                                  * rejected by Windows, which is a separate
4799                                  * problem (though related).
4800                                  */
4801
4802                                 /* only needed if we are copying media, since the
4803                                  * analysis data refers to media data
4804                                  */
4805
4806                                 old = analysis_dir ();
4807                                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4808                                         string newdir = Glib::build_filename (to_dir, "analysis");
4809                                         copy_files (old, newdir);
4810                                 }
4811 #endif /* PLATFORM_WINDOWS */
4812                         }
4813                 }
4814
4815
4816                 _path = to_dir;
4817                 set_snapshot_name (saveas.new_name);
4818                 _name = saveas.new_name;
4819
4820                 if (saveas.include_media && !saveas.copy_media) {
4821
4822                         /* reset search paths of the new session (which we're pretending to be right now) to
4823                            include the original session search path, so we can still find all audio.
4824                         */
4825
4826                         if (internal_file_cnt) {
4827                                 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
4828                                         ensure_search_path_includes (*s, DataType::AUDIO);
4829                                         cerr << "be sure to include " << *s << "  for audio" << endl;
4830                                 }
4831
4832                                 /* we do not do this for MIDI because we copy
4833                                    all MIDI files if saveas.include_media is
4834                                    true
4835                                 */
4836                         }
4837                 }
4838
4839                 bool was_dirty = dirty ();
4840
4841                 save_state ("", false, false, !saveas.include_media);
4842                 save_default_options ();
4843
4844                 if (saveas.copy_media && saveas.copy_external) {
4845                         if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback, this, _1, _2, _3))) {
4846                                 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT, "consolidate failed");
4847                         }
4848                 }
4849
4850                 saveas.final_session_folder_name = _path;
4851
4852                 store_recent_sessions (_name, _path);
4853
4854                 if (!saveas.switch_to) {
4855
4856                         /* switch back to the way things were */
4857
4858                         _path = old_path;
4859                         _name = old_name;
4860                         set_snapshot_name (old_snapshot);
4861
4862                         (*_session_dir) = old_sd;
4863
4864                         if (was_dirty) {
4865                                 set_dirty ();
4866                         }
4867
4868                         if (internal_file_cnt) {
4869                                 /* reset these to their original values */
4870                                 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
4871                                 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
4872                         }
4873
4874                 } else {
4875
4876                         /* prune session dirs, and update disk space statistics
4877                          */
4878
4879                         space_and_path sp;
4880                         sp.path = _path;
4881                         session_dirs.clear ();
4882                         session_dirs.push_back (sp);
4883                         refresh_disk_space ();
4884
4885                         /* ensure that all existing tracks reset their current capture source paths
4886                          */
4887                         reset_write_sources (true, true);
4888
4889                         /* the copying above was based on actually discovering files, not just iterating over the sources list.
4890                            But if we're going to switch to the new (copied) session, we need to change the paths in the sources also.
4891                         */
4892
4893                         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4894                                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4895
4896                                 if (!fs) {
4897                                         continue;
4898                                 }
4899
4900                                 if (fs->within_session()) {
4901                                         string newpath = make_new_media_path (fs->path(), to_dir, new_folder);
4902                                         fs->set_path (newpath);
4903                                 }
4904                         }
4905                 }
4906
4907         } catch (Glib::FileError& e) {
4908
4909                 saveas.failure_message = e.what();
4910
4911                 /* recursively remove all the directories */
4912
4913                 remove_directory (to_dir);
4914
4915                 /* return error */
4916
4917                 return -1;
4918
4919         } catch (...) {
4920
4921                 saveas.failure_message = _("unknown reason");
4922
4923                 /* recursively remove all the directories */
4924
4925                 remove_directory (to_dir);
4926
4927                 /* return error */
4928
4929                 return -1;
4930         }
4931
4932         return 0;
4933 }
4934
4935 void
4936 Session::undo (uint32_t n)
4937 {
4938         if (actively_recording()) {
4939                 return;
4940         }
4941
4942         _history.undo (n);
4943 }
4944
4945 void
4946 Session::redo (uint32_t n)
4947 {
4948         if (actively_recording()) {
4949                 return;
4950         }
4951
4952         _history.redo (n);
4953 }