Add option to flac encode audio when archiving
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2013 Paul Davis
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #include <stdint.h>
26
27 #include <algorithm>
28 #include <string>
29 #include <cerrno>
30 #include <cstdio> /* snprintf(3) ... grrr */
31 #include <cmath>
32
33 #include <unistd.h>
34 #include <climits>
35 #include <signal.h>
36 #include <sys/time.h>
37
38 #ifdef HAVE_SYS_VFS_H
39 #include <sys/vfs.h>
40 #endif
41
42 #if defined(__APPLE__) || defined(__FreeBSD__)
43 #include <sys/param.h>
44 #include <sys/mount.h>
45 #endif
46
47 #ifdef HAVE_SYS_STATVFS_H
48 #include <sys/statvfs.h>
49 #endif
50
51 #include <glib.h>
52 #include "pbd/gstdio_compat.h"
53
54 #include <glibmm.h>
55 #include <glibmm/threads.h>
56 #include <glibmm/fileutils.h>
57
58 #include <boost/algorithm/string.hpp>
59
60 #include "midi++/mmc.h"
61 #include "midi++/port.h"
62
63 #include "evoral/SMF.hpp"
64
65 #include "pbd/basename.h"
66 #include "pbd/debug.h"
67 #include "pbd/enumwriter.h"
68 #include "pbd/error.h"
69 #include "pbd/file_archive.h"
70 #include "pbd/file_utils.h"
71 #include "pbd/pathexpand.h"
72 #include "pbd/pthread_utils.h"
73 #include "pbd/stacktrace.h"
74 #include "pbd/convert.h"
75 #include "pbd/localtime_r.h"
76 #include "pbd/unwind.h"
77
78 #include "ardour/amp.h"
79 #include "ardour/async_midi_port.h"
80 #include "ardour/audio_diskstream.h"
81 #include "ardour/audio_track.h"
82 #include "ardour/audioengine.h"
83 #include "ardour/audiofilesource.h"
84 #include "ardour/audioregion.h"
85 #include "ardour/auditioner.h"
86 #include "ardour/automation_control.h"
87 #include "ardour/boost_debug.h"
88 #include "ardour/butler.h"
89 #include "ardour/controllable_descriptor.h"
90 #include "ardour/control_protocol_manager.h"
91 #include "ardour/directory_names.h"
92 #include "ardour/filename_extensions.h"
93 #include "ardour/graph.h"
94 #include "ardour/location.h"
95 #include "ardour/lv2_plugin.h"
96 #include "ardour/midi_model.h"
97 #include "ardour/midi_patch_manager.h"
98 #include "ardour/midi_region.h"
99 #include "ardour/midi_scene_changer.h"
100 #include "ardour/midi_source.h"
101 #include "ardour/midi_track.h"
102 #include "ardour/pannable.h"
103 #include "ardour/playlist_factory.h"
104 #include "ardour/playlist_source.h"
105 #include "ardour/port.h"
106 #include "ardour/processor.h"
107 #include "ardour/progress.h"
108 #include "ardour/profile.h"
109 #include "ardour/proxy_controllable.h"
110 #include "ardour/recent_sessions.h"
111 #include "ardour/region_factory.h"
112 #include "ardour/revision.h"
113 #include "ardour/route_group.h"
114 #include "ardour/send.h"
115 #include "ardour/session.h"
116 #include "ardour/session_directory.h"
117 #include "ardour/session_metadata.h"
118 #include "ardour/session_playlists.h"
119 #include "ardour/session_state_utils.h"
120 #include "ardour/silentfilesource.h"
121 #include "ardour/sndfilesource.h"
122 #include "ardour/source_factory.h"
123 #include "ardour/speakers.h"
124 #include "ardour/template_utils.h"
125 #include "ardour/tempo.h"
126 #include "ardour/ticker.h"
127 #include "ardour/user_bundle.h"
128 #include "ardour/vca.h"
129 #include "ardour/vca_manager.h"
130
131 #include "control_protocol/control_protocol.h"
132
133 #include "LuaBridge/LuaBridge.h"
134
135 #include "pbd/i18n.h"
136 #include <locale.h>
137
138 using namespace std;
139 using namespace ARDOUR;
140 using namespace PBD;
141
142 #define DEBUG_UNDO_HISTORY(msg) DEBUG_TRACE (PBD::DEBUG::UndoHistory, string_compose ("%1: %2\n", __LINE__, msg));
143
144 void
145 Session::pre_engine_init (string fullpath)
146 {
147         if (fullpath.empty()) {
148                 destroy ();
149                 throw failed_constructor();
150         }
151
152         /* discover canonical fullpath */
153
154         _path = canonical_path(fullpath);
155
156         /* is it new ? */
157         if (Profile->get_trx() ) {
158                 // Waves TracksLive has a usecase of session replacement with a new one.
159                 // We should check session state file (<session_name>.ardour) existance
160                 // to determine if the session is new or not
161
162                 string full_session_name = Glib::build_filename( fullpath, _name );
163                 full_session_name += statefile_suffix;
164
165                 _is_new = !Glib::file_test (full_session_name, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
166         } else {
167                 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
168         }
169
170         /* finish initialization that can't be done in a normal C++ constructor
171            definition.
172         */
173
174         timerclear (&last_mmc_step);
175         g_atomic_int_set (&processing_prohibited, 0);
176         g_atomic_int_set (&_record_status, Disabled);
177         g_atomic_int_set (&_playback_load, 100);
178         g_atomic_int_set (&_capture_load, 100);
179         set_next_event ();
180         _all_route_group->set_active (true, this);
181         interpolation.add_channel_to (0, 0);
182
183         if (config.get_use_video_sync()) {
184                 waiting_for_sync_offset = true;
185         } else {
186                 waiting_for_sync_offset = false;
187         }
188
189         last_rr_session_dir = session_dirs.begin();
190
191         set_history_depth (Config->get_history_depth());
192
193         /* default: assume simple stereo speaker configuration */
194
195         _speakers->setup_default_speakers (2);
196
197         _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
198                                                         boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
199                                                         boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
200         add_controllable (_solo_cut_control);
201
202         /* These are all static "per-class" signals */
203
204         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
205         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
206         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
207         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
208         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
209
210         /* stop IO objects from doing stuff until we're ready for them */
211
212         Delivery::disable_panners ();
213         IO::disable_connecting ();
214 }
215
216 int
217 Session::post_engine_init ()
218 {
219         BootMessage (_("Set block size and sample rate"));
220
221         set_block_size (_engine.samples_per_cycle());
222         set_frame_rate (_engine.sample_rate());
223
224         BootMessage (_("Using configuration"));
225
226         _midi_ports = new MidiPortManager;
227
228         MIDISceneChanger* msc;
229
230         _scene_changer = msc = new MIDISceneChanger (*this);
231         msc->set_input_port (boost::dynamic_pointer_cast<MidiPort>(scene_input_port()));
232         msc->set_output_port (boost::dynamic_pointer_cast<MidiPort>(scene_output_port()));
233
234         boost::function<framecnt_t(void)> timer_func (boost::bind (&Session::audible_frame, this));
235         boost::dynamic_pointer_cast<AsyncMIDIPort>(scene_input_port())->set_timer (timer_func);
236
237         setup_midi_machine_control ();
238
239         if (_butler->start_thread()) {
240                 return -1;
241         }
242
243         if (start_midi_thread ()) {
244                 return -1;
245         }
246
247         setup_click_sounds (0);
248         setup_midi_control ();
249
250         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
251         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
252
253         try {
254                 /* tempo map requires sample rate knowledge */
255
256                 delete _tempo_map;
257                 _tempo_map = new TempoMap (_current_frame_rate);
258                 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
259                 _tempo_map->MetricPositionChanged.connect_same_thread (*this, boost::bind (&Session::gui_tempo_map_changed, this));
260
261                 /* MidiClock requires a tempo map */
262
263                 delete midi_clock;
264                 midi_clock = new MidiClockTicker ();
265                 midi_clock->set_session (this);
266
267                 /* crossfades require sample rate knowledge */
268
269                 SndFileSource::setup_standard_crossfades (*this, frame_rate());
270                 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
271
272                 AudioDiskstream::allocate_working_buffers();
273                 refresh_disk_space ();
274
275                 /* we're finally ready to call set_state() ... all objects have
276                  * been created, the engine is running.
277                  */
278
279                 if (state_tree) {
280                         if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
281                                 return -1;
282                         }
283                 } else {
284                         // set_state() will call setup_raid_path(), but if it's a new session we need
285                         // to call setup_raid_path() here.
286                         setup_raid_path (_path);
287                 }
288
289                 /* ENGINE */
290
291                 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
292                 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
293
294                 Config->map_parameters (ff);
295                 config.map_parameters (ft);
296                 _butler->map_parameters ();
297
298                 /* Reset all panners */
299
300                 Delivery::reset_panners ();
301
302                 /* this will cause the CPM to instantiate any protocols that are in use
303                  * (or mandatory), which will pass it this Session, and then call
304                  * set_state() on each instantiated protocol to match stored state.
305                  */
306
307                 ControlProtocolManager::instance().set_session (this);
308
309                 /* This must be done after the ControlProtocolManager set_session above,
310                    as it will set states for ports which the ControlProtocolManager creates.
311                 */
312
313                 // XXX set state of MIDI::Port's
314                 // MidiPortManager::instance()->set_port_states (Config->midi_port_states ());
315
316                 /* And this must be done after the MIDI::Manager::set_port_states as
317                  * it will try to make connections whose details are loaded by set_port_states.
318                  */
319
320                 hookup_io ();
321
322                 /* Let control protocols know that we are now all connected, so they
323                  * could start talking to surfaces if they want to.
324                  */
325
326                 ControlProtocolManager::instance().midi_connectivity_established ();
327
328                 if (_is_new && !no_auto_connect()) {
329                         Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
330                         auto_connect_master_bus ();
331                 }
332
333                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
334
335                 /* update latencies */
336
337                 initialize_latencies ();
338
339                 _locations->added.connect_same_thread (*this, boost::bind (&Session::location_added, this, _1));
340                 _locations->removed.connect_same_thread (*this, boost::bind (&Session::location_removed, this, _1));
341                 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
342
343         } catch (AudioEngine::PortRegistrationFailure& err) {
344                 /* handle this one in a different way than all others, so that its clear what happened */
345                 error << err.what() << endmsg;
346                 return -1;
347         } catch (...) {
348                 return -1;
349         }
350
351         BootMessage (_("Reset Remote Controls"));
352
353         // send_full_time_code (0);
354         _engine.transport_locate (0);
355
356         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
357         send_immediate_mmc (MIDI::MachineControlCommand (Timecode::Time ()));
358
359         MIDI::Name::MidiPatchManager::instance().add_search_path (session_directory().midi_patch_path() );
360
361         ltc_tx_initialize();
362         /* initial program change will be delivered later; see ::config_changed() */
363
364         _state_of_the_state = Clean;
365
366         Port::set_connecting_blocked (false);
367
368         DirtyChanged (); /* EMIT SIGNAL */
369
370         if (_is_new) {
371                 save_state ("");
372         } else if (state_was_pending) {
373                 save_state ("");
374                 remove_pending_capture_state ();
375                 state_was_pending = false;
376         }
377
378         /* Now, finally, we can fill the playback buffers */
379
380         BootMessage (_("Filling playback buffers"));
381
382         boost::shared_ptr<RouteList> rl = routes.reader();
383         for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
384                 boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (*r);
385                 if (trk && !trk->hidden()) {
386                         trk->seek (_transport_frame, true);
387                 }
388         }
389
390         return 0;
391 }
392
393 void
394 Session::session_loaded ()
395 {
396         SessionLoaded();
397
398         _state_of_the_state = Clean;
399
400         DirtyChanged (); /* EMIT SIGNAL */
401
402         if (_is_new) {
403                 save_state ("");
404         } else if (state_was_pending) {
405                 save_state ("");
406                 remove_pending_capture_state ();
407                 state_was_pending = false;
408         }
409
410         /* Now, finally, we can fill the playback buffers */
411
412         BootMessage (_("Filling playback buffers"));
413         force_locate (_transport_frame, false);
414 }
415
416 string
417 Session::raid_path () const
418 {
419         Searchpath raid_search_path;
420
421         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
422                 raid_search_path += (*i).path;
423         }
424
425         return raid_search_path.to_string ();
426 }
427
428 void
429 Session::setup_raid_path (string path)
430 {
431         if (path.empty()) {
432                 return;
433         }
434
435         space_and_path sp;
436         string fspath;
437
438         session_dirs.clear ();
439
440         Searchpath search_path(path);
441         Searchpath sound_search_path;
442         Searchpath midi_search_path;
443
444         for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
445                 sp.path = *i;
446                 sp.blocks = 0; // not needed
447                 session_dirs.push_back (sp);
448
449                 SessionDirectory sdir(sp.path);
450
451                 sound_search_path += sdir.sound_path ();
452                 midi_search_path += sdir.midi_path ();
453         }
454
455         // reset the round-robin soundfile path thingie
456         last_rr_session_dir = session_dirs.begin();
457 }
458
459 bool
460 Session::path_is_within_session (const std::string& path)
461 {
462         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
463                 if (PBD::path_is_within (i->path, path)) {
464                         return true;
465                 }
466         }
467         return false;
468 }
469
470 int
471 Session::ensure_subdirs ()
472 {
473         string dir;
474
475         dir = session_directory().peak_path();
476
477         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479                 return -1;
480         }
481
482         dir = session_directory().sound_path();
483
484         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
485                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
486                 return -1;
487         }
488
489         dir = session_directory().midi_path();
490
491         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
492                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493                 return -1;
494         }
495
496         dir = session_directory().dead_path();
497
498         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
499                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
500                 return -1;
501         }
502
503         dir = session_directory().export_path();
504
505         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
506                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
507                 return -1;
508         }
509
510         dir = analysis_dir ();
511
512         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
513                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
514                 return -1;
515         }
516
517         dir = plugins_dir ();
518
519         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
520                 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
521                 return -1;
522         }
523
524         dir = externals_dir ();
525
526         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
527                 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
528                 return -1;
529         }
530
531         return 0;
532 }
533
534 /** @param session_template directory containing session template, or empty.
535  *  Caller must not hold process lock.
536  */
537 int
538 Session::create (const string& session_template, BusProfile* bus_profile)
539 {
540         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
541                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
542                 return -1;
543         }
544
545         if (ensure_subdirs ()) {
546                 return -1;
547         }
548
549         _writable = exists_and_writable (_path);
550
551         if (!session_template.empty()) {
552                 string in_path = (ARDOUR::Profile->get_trx () ? session_template : session_template_dir_to_file (session_template));
553
554                 FILE* in = g_fopen (in_path.c_str(), "rb");
555
556                 if (in) {
557                         /* no need to call legalize_for_path() since the string
558                          * in session_template is already a legal path name
559                          */
560                         string out_path = Glib::build_filename (_session_dir->root_path(), _name + statefile_suffix);
561
562                         FILE* out = g_fopen (out_path.c_str(), "wb");
563
564                         if (out) {
565                                 char buf[1024];
566                                 stringstream new_session;
567
568                                 while (!feof (in)) {
569                                         size_t charsRead = fread (buf, sizeof(char), 1024, in);
570
571                                         if (ferror (in)) {
572                                                 error << string_compose (_("Error reading session template file %1 (%2)"), in_path, strerror (errno)) << endmsg;
573                                                 fclose (in);
574                                                 fclose (out);
575                                                 return -1;
576                                         }
577                                         if (charsRead == 0) {
578                                                 break;
579                                         }
580                                         new_session.write (buf, charsRead);
581                                 }
582                                 fclose (in);
583
584                                 string file_contents = new_session.str();
585                                 size_t writeSize = file_contents.length();
586                                 if (fwrite (file_contents.c_str(), sizeof(char), writeSize, out) != writeSize) {
587                                         error << string_compose (_("Error writing session template file %1 (%2)"), out_path, strerror (errno)) << endmsg;
588                                         fclose (out);
589                                         return -1;
590                                 }
591                                 fclose (out);
592
593                                 _is_new = false;
594
595                                 if (!ARDOUR::Profile->get_trx()) {
596                                         /* Copy plugin state files from template to new session */
597                                         std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
598                                         copy_recurse (template_plugins, plugins_dir ());
599                                 }
600
601                                 return 0;
602
603                         } else {
604                                 error << string_compose (_("Could not open %1 for writing session template"), out_path)
605                                         << endmsg;
606                                 fclose(in);
607                                 return -1;
608                         }
609
610                 } else {
611                         error << string_compose (_("Could not open session template %1 for reading"), in_path)
612                                 << endmsg;
613                         return -1;
614                 }
615
616         }
617
618         if (Profile->get_trx()) {
619
620                 /* set initial start + end point : ARDOUR::Session::session_end_shift long.
621                    Remember that this is a brand new session. Sessions
622                    loaded from saved state will get this range from the saved state.
623                 */
624
625                 set_session_range_location (0, 0);
626
627                 /* Initial loop location, from absolute zero, length 10 seconds  */
628
629                 Location* loc = new Location (*this, 0, 10.0 * _engine.sample_rate(), _("Loop"),  Location::IsAutoLoop);
630                 _locations->add (loc, true);
631                 set_auto_loop_location (loc);
632         }
633
634         _state_of_the_state = Clean;
635
636         /* set up Master Out and Monitor Out if necessary */
637
638         if (bus_profile) {
639
640                 RouteList rl;
641                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
642
643                 // Waves Tracks: always create master bus for Tracks
644                 if (ARDOUR::Profile->get_trx() || bus_profile->master_out_channels) {
645                         boost::shared_ptr<Route> r (new Route (*this, _("Master"), PresentationInfo::MasterOut, DataType::AUDIO));
646                         if (r->init ()) {
647                                 return -1;
648                         }
649
650                         BOOST_MARK_ROUTE(r);
651
652                         {
653                                 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
654                                 r->input()->ensure_io (count, false, this);
655                                 r->output()->ensure_io (count, false, this);
656                         }
657
658                         rl.push_back (r);
659
660                 } else {
661                         /* prohibit auto-connect to master, because there isn't one */
662                         bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
663                 }
664
665                 if (!rl.empty()) {
666                         add_routes (rl, false, false, false, PresentationInfo::max_order);
667                 }
668
669                 // Waves Tracks: Skip this. Always use autoconnection for Tracks
670                 if (!ARDOUR::Profile->get_trx()) {
671
672                         /* this allows the user to override settings with an environment variable.
673                          */
674
675                         if (no_auto_connect()) {
676                                 bus_profile->input_ac = AutoConnectOption (0);
677                                 bus_profile->output_ac = AutoConnectOption (0);
678                         }
679
680                         Config->set_input_auto_connect (bus_profile->input_ac);
681                         Config->set_output_auto_connect (bus_profile->output_ac);
682                 }
683         }
684
685         if (Config->get_use_monitor_bus() && bus_profile) {
686                 add_monitor_section ();
687         }
688
689         return 0;
690 }
691
692 void
693 Session::maybe_write_autosave()
694 {
695         if (dirty() && record_status() != Recording) {
696                 save_state("", true);
697         }
698 }
699
700 void
701 Session::remove_pending_capture_state ()
702 {
703         std::string pending_state_file_path(_session_dir->root_path());
704
705         pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
706
707         if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
708
709         if (g_remove (pending_state_file_path.c_str()) != 0) {
710                 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
711                                 pending_state_file_path, g_strerror (errno)) << endmsg;
712         }
713 }
714
715 /** Rename a state file.
716  *  @param old_name Old snapshot name.
717  *  @param new_name New snapshot name.
718  */
719 void
720 Session::rename_state (string old_name, string new_name)
721 {
722         if (old_name == _current_snapshot_name || old_name == _name) {
723                 /* refuse to rename the current snapshot or the "main" one */
724                 return;
725         }
726
727         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
728         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
729
730         const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
731         const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
732
733         if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
734                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
735                                 old_name, new_name, g_strerror(errno)) << endmsg;
736         }
737 }
738
739 /** Remove a state file.
740  *  @param snapshot_name Snapshot name.
741  */
742 void
743 Session::remove_state (string snapshot_name)
744 {
745         if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
746                 // refuse to remove the current snapshot or the "main" one
747                 return;
748         }
749
750         std::string xml_path(_session_dir->root_path());
751
752         xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
753
754         if (!create_backup_file (xml_path)) {
755                 // don't remove it if a backup can't be made
756                 // create_backup_file will log the error.
757                 return;
758         }
759
760         // and delete it
761         if (g_remove (xml_path.c_str()) != 0) {
762                 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
763                                 xml_path, g_strerror (errno)) << endmsg;
764         }
765 }
766
767 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
768 int
769 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot, bool template_only)
770 {
771         DEBUG_TRACE (DEBUG::Locale, string_compose ("Session::save_state locale '%1'\n", setlocale (LC_NUMERIC, NULL)));
772
773         XMLTree tree;
774         std::string xml_path(_session_dir->root_path());
775
776         /* prevent concurrent saves from different threads */
777
778         Glib::Threads::Mutex::Lock lm (save_state_lock);
779
780         if (!_writable || (_state_of_the_state & CannotSave)) {
781                 return 1;
782         }
783
784         if (g_atomic_int_get(&_suspend_save)) {
785                 _save_queued = true;
786                 return 1;
787         }
788         _save_queued = false;
789
790         if (!_engine.connected ()) {
791                 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
792                                          PROGRAM_NAME)
793                       << endmsg;
794                 return 1;
795         }
796
797 #ifndef NDEBUG
798         const int64_t save_start_time = g_get_monotonic_time();
799 #endif
800
801         /* tell sources we're saving first, in case they write out to a new file
802          * which should be saved with the state rather than the old one */
803         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
804                 try {
805                         i->second->session_saved();
806                 } catch (Evoral::SMF::FileError& e) {
807                         error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
808                 }
809         }
810
811         SessionSaveUnderway (); /* EMIT SIGNAL */
812
813         bool mark_as_clean = true;
814
815         if (!snapshot_name.empty() && !switch_to_snapshot) {
816                 mark_as_clean = false;
817         }
818
819         if (template_only) {
820                 mark_as_clean = false;
821                 tree.set_root (&get_template());
822         } else {
823                 tree.set_root (&get_state());
824         }
825
826         if (snapshot_name.empty()) {
827                 snapshot_name = _current_snapshot_name;
828         } else if (switch_to_snapshot) {
829                 set_snapshot_name (snapshot_name);
830         }
831
832         assert (!snapshot_name.empty());
833
834         if (!pending) {
835
836                 /* proper save: use statefile_suffix (.ardour in English) */
837
838                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
839
840                 /* make a backup copy of the old file */
841
842                 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
843                         // create_backup_file will log the error
844                         return -1;
845                 }
846
847         } else {
848
849                 /* pending save: use pending_suffix (.pending in English) */
850                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
851         }
852
853         std::string tmp_path(_session_dir->root_path());
854         tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
855
856         cerr << "actually writing state to " << tmp_path << endl;
857
858         if (!tree.write (tmp_path)) {
859                 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
860                 if (g_remove (tmp_path.c_str()) != 0) {
861                         error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
862                                         tmp_path, g_strerror (errno)) << endmsg;
863                 }
864                 return -1;
865
866         } else {
867
868                 cerr << "renaming state to " << xml_path << endl;
869
870                 if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
871                         error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"),
872                                         tmp_path, xml_path, g_strerror(errno)) << endmsg;
873                         if (g_remove (tmp_path.c_str()) != 0) {
874                                 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
875                                                 tmp_path, g_strerror (errno)) << endmsg;
876                         }
877                         return -1;
878                 }
879         }
880
881         if (!pending) {
882
883                 save_history (snapshot_name);
884
885                 if (mark_as_clean) {
886                         bool was_dirty = dirty();
887
888                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
889
890                         if (was_dirty) {
891                                 DirtyChanged (); /* EMIT SIGNAL */
892                         }
893                 }
894
895                 StateSaved (snapshot_name); /* EMIT SIGNAL */
896         }
897
898 #ifndef NDEBUG
899         const int64_t elapsed_time_us = g_get_monotonic_time() - save_start_time;
900         cerr << "saved state in " << fixed << setprecision (1) << elapsed_time_us / 1000. << " ms\n";
901 #endif
902         return 0;
903 }
904
905 int
906 Session::restore_state (string snapshot_name)
907 {
908         if (load_state (snapshot_name) == 0) {
909                 set_state (*state_tree->root(), Stateful::loading_state_version);
910         }
911
912         return 0;
913 }
914
915 int
916 Session::load_state (string snapshot_name)
917 {
918         delete state_tree;
919         state_tree = 0;
920
921         state_was_pending = false;
922
923         /* check for leftover pending state from a crashed capture attempt */
924
925         std::string xmlpath(_session_dir->root_path());
926         xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
927
928         if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
929
930                 /* there is pending state from a crashed capture attempt */
931
932                 boost::optional<int> r = AskAboutPendingState();
933                 if (r.get_value_or (1)) {
934                         state_was_pending = true;
935                 }
936         }
937
938         if (!state_was_pending) {
939                 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
940         }
941
942         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
943                 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
944                 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
945                         error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
946                         return 1;
947                 }
948         }
949
950         state_tree = new XMLTree;
951
952         set_dirty();
953
954         _writable = exists_and_writable (xmlpath) && exists_and_writable(Glib::path_get_dirname(xmlpath));
955
956         if (!state_tree->read (xmlpath)) {
957                 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
958                 delete state_tree;
959                 state_tree = 0;
960                 return -1;
961         }
962
963         XMLNode const & root (*state_tree->root());
964
965         if (root.name() != X_("Session")) {
966                 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
967                 delete state_tree;
968                 state_tree = 0;
969                 return -1;
970         }
971
972         XMLProperty const * prop;
973
974         if ((prop = root.property ("version")) == 0) {
975                 /* no version implies very old version of Ardour */
976                 Stateful::loading_state_version = 1000;
977         } else {
978                 if (prop->value().find ('.') != string::npos) {
979                         /* old school version format */
980                         if (prop->value()[0] == '2') {
981                                 Stateful::loading_state_version = 2000;
982                         } else {
983                                 Stateful::loading_state_version = 3000;
984                         }
985                 } else {
986                         Stateful::loading_state_version = atoi (prop->value());
987                 }
988         }
989
990         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
991
992                 std::string backup_path(_session_dir->root_path());
993                 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
994                 backup_path = Glib::build_filename (backup_path, backup_filename);
995
996                 // only create a backup for a given statefile version once
997
998                 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
999
1000                         VersionMismatch (xmlpath, backup_path);
1001
1002                         if (!copy_file (xmlpath, backup_path)) {;
1003                                 return -1;
1004                         }
1005                 }
1006         } else {
1007                 XMLNode* child;
1008                 if ((child = find_named_node (root, "ProgramVersion")) != 0) {
1009                         if ((prop = child->property ("modified-with")) != 0) {
1010                                 std::string modified_with = prop->value ();
1011
1012                                 const double modified_with_version = atof (modified_with.substr ( modified_with.find(" ", 0) + 1, string::npos).c_str());
1013                                 const int modified_with_revision = atoi (modified_with.substr (modified_with.find("-", 0) + 1, string::npos).c_str());
1014
1015                                 if (modified_with_version <= 5.3 && !(modified_with_version == 5.3 && modified_with_revision > 42)) {
1016                                         _midi_regions_use_bbt_beats = true;
1017                                 }
1018                         }
1019                 }
1020         }
1021
1022         save_snapshot_name (snapshot_name);
1023
1024         return 0;
1025 }
1026
1027 int
1028 Session::load_options (const XMLNode& node)
1029 {
1030         LocaleGuard lg;
1031         config.set_variables (node);
1032         return 0;
1033 }
1034
1035 bool
1036 Session::save_default_options ()
1037 {
1038         return config.save_state();
1039 }
1040
1041 XMLNode&
1042 Session::get_state()
1043 {
1044         return state(true);
1045 }
1046
1047 XMLNode&
1048 Session::get_template()
1049 {
1050         /* if we don't disable rec-enable, diskstreams
1051            will believe they need to store their capture
1052            sources in their state node.
1053         */
1054
1055         disable_record (false);
1056
1057         return state(false);
1058 }
1059
1060 XMLNode&
1061 Session::state (bool full_state)
1062 {
1063         LocaleGuard lg;
1064         XMLNode* node = new XMLNode("Session");
1065         XMLNode* child;
1066
1067         char buf[16];
1068         snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
1069         node->add_property("version", buf);
1070
1071         child = node->add_child ("ProgramVersion");
1072         child->add_property("created-with", created_with);
1073
1074         std::string modified_with = string_compose ("%1 %2", PROGRAM_NAME, revision);
1075         child->add_property("modified-with", modified_with);
1076
1077         /* store configuration settings */
1078
1079         if (full_state) {
1080
1081                 node->add_property ("name", _name);
1082                 snprintf (buf, sizeof (buf), "%" PRId64, _base_frame_rate);
1083                 node->add_property ("sample-rate", buf);
1084
1085                 if (session_dirs.size() > 1) {
1086
1087                         string p;
1088
1089                         vector<space_and_path>::iterator i = session_dirs.begin();
1090                         vector<space_and_path>::iterator next;
1091
1092                         ++i; /* skip the first one */
1093                         next = i;
1094                         ++next;
1095
1096                         while (i != session_dirs.end()) {
1097
1098                                 p += (*i).path;
1099
1100                                 if (next != session_dirs.end()) {
1101                                         p += G_SEARCHPATH_SEPARATOR;
1102                                 } else {
1103                                         break;
1104                                 }
1105
1106                                 ++next;
1107                                 ++i;
1108                         }
1109
1110                         child = node->add_child ("Path");
1111                         child->add_content (p);
1112                 }
1113         }
1114
1115         node->add_property ("end-is-free", _session_range_end_is_free ? X_("yes") : X_("no"));
1116
1117         /* save the ID counter */
1118
1119         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1120         node->add_property ("id-counter", buf);
1121
1122         snprintf (buf, sizeof (buf), "%u", name_id_counter ());
1123         node->add_property ("name-counter", buf);
1124
1125         /* save the event ID counter */
1126
1127         snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1128         node->add_property ("event-counter", buf);
1129
1130         /* save the VCA counter */
1131
1132         snprintf (buf, sizeof (buf), "%" PRIu32, VCA::get_next_vca_number());
1133         node->add_property ("vca-counter", buf);
1134
1135         /* various options */
1136
1137         list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
1138         if (!midi_port_nodes.empty()) {
1139                 XMLNode* midi_port_stuff = new XMLNode ("MIDIPorts");
1140                 for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
1141                         midi_port_stuff->add_child_nocopy (**n);
1142                 }
1143                 node->add_child_nocopy (*midi_port_stuff);
1144         }
1145
1146         node->add_child_nocopy (config.get_variables ());
1147
1148         node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1149
1150         child = node->add_child ("Sources");
1151
1152         if (full_state) {
1153                 Glib::Threads::Mutex::Lock sl (source_lock);
1154
1155                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1156
1157                         /* Don't save information about non-file Sources, or
1158                          * about non-destructive file sources that are empty
1159                          * and unused by any regions.
1160                         */
1161
1162                         boost::shared_ptr<FileSource> fs;
1163
1164                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1165
1166                                 if (!fs->destructive()) {
1167                                         if (fs->empty() && !fs->used()) {
1168                                                 continue;
1169                                         }
1170                                 }
1171
1172                                 child->add_child_nocopy (siter->second->get_state());
1173                         }
1174                 }
1175         }
1176
1177         child = node->add_child ("Regions");
1178
1179         if (full_state) {
1180                 Glib::Threads::Mutex::Lock rl (region_lock);
1181                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1182                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1183                         boost::shared_ptr<Region> r = i->second;
1184                         /* only store regions not attached to playlists */
1185                         if (r->playlist() == 0) {
1186                                 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1187                                         child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1188                                 } else {
1189                                         child->add_child_nocopy (r->get_state ());
1190                                 }
1191                         }
1192                 }
1193
1194                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1195
1196                 if (!cassocs.empty()) {
1197                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1198
1199                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1200                                 char buf[64];
1201                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1202                                 i->first->id().print (buf, sizeof (buf));
1203                                 can->add_property (X_("copy"), buf);
1204                                 i->second->id().print (buf, sizeof (buf));
1205                                 can->add_property (X_("original"), buf);
1206                                 ca->add_child_nocopy (*can);
1207                         }
1208                 }
1209         }
1210
1211
1212
1213         if (full_state) {
1214
1215                 if (_locations) {
1216                         node->add_child_nocopy (_locations->get_state());
1217                 }
1218         } else {
1219                 Locations loc (*this);
1220                 // for a template, just create a new Locations, populate it
1221                 // with the default start and end, and get the state for that.
1222                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1223                 range->set (max_framepos, 0);
1224                 loc.add (range);
1225                 XMLNode& locations_state = loc.get_state();
1226
1227                 if (ARDOUR::Profile->get_trx() && _locations) {
1228                         // For tracks we need stored the Auto Loop Range and all MIDI markers.
1229                         for (Locations::LocationList::const_iterator i = _locations->list ().begin (); i != _locations->list ().end (); ++i) {
1230                                 if ((*i)->is_mark () || (*i)->is_auto_loop ()) {
1231                                         locations_state.add_child_nocopy ((*i)->get_state ());
1232                                 }
1233                         }
1234                 }
1235                 node->add_child_nocopy (locations_state);
1236         }
1237
1238         child = node->add_child ("Bundles");
1239         {
1240                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1241                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1242                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1243                         if (b) {
1244                                 child->add_child_nocopy (b->get_state());
1245                         }
1246                 }
1247         }
1248
1249         node->add_child_nocopy (_vca_manager->get_state());
1250
1251         child = node->add_child ("Routes");
1252         {
1253                 boost::shared_ptr<RouteList> r = routes.reader ();
1254
1255                 RoutePublicOrderSorter cmp;
1256                 RouteList public_order (*r);
1257                 public_order.sort (cmp);
1258
1259                 /* the sort should have put the monitor out first */
1260
1261                 if (_monitor_out) {
1262                         assert (_monitor_out == public_order.front());
1263                 }
1264
1265                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1266                         if (!(*i)->is_auditioner()) {
1267                                 if (full_state) {
1268                                         child->add_child_nocopy ((*i)->get_state());
1269                                 } else {
1270                                         child->add_child_nocopy ((*i)->get_template());
1271                                 }
1272                         }
1273                 }
1274         }
1275
1276         playlists->add_state (node, full_state);
1277
1278         child = node->add_child ("RouteGroups");
1279         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1280                 child->add_child_nocopy ((*i)->get_state());
1281         }
1282
1283         if (_click_io) {
1284                 XMLNode* gain_child = node->add_child ("Click");
1285                 gain_child->add_child_nocopy (_click_io->state (full_state));
1286                 gain_child->add_child_nocopy (_click_gain->state (full_state));
1287         }
1288
1289         if (_ltc_input) {
1290                 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1291                 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1292         }
1293
1294         if (_ltc_input) {
1295                 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1296                 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1297         }
1298
1299         node->add_child_nocopy (_speakers->get_state());
1300         node->add_child_nocopy (_tempo_map->get_state());
1301         node->add_child_nocopy (get_control_protocol_state());
1302
1303         if (_extra_xml) {
1304                 node->add_child_copy (*_extra_xml);
1305         }
1306
1307         {
1308                 Glib::Threads::Mutex::Lock lm (lua_lock);
1309                 std::string saved;
1310                 {
1311                         luabridge::LuaRef savedstate ((*_lua_save)());
1312                         saved = savedstate.cast<std::string>();
1313                 }
1314                 lua.collect_garbage ();
1315                 lm.release ();
1316
1317                 gchar* b64 = g_base64_encode ((const guchar*)saved.c_str (), saved.size ());
1318                 std::string b64s (b64);
1319                 g_free (b64);
1320
1321                 XMLNode* script_node = new XMLNode (X_("Script"));
1322                 script_node->add_property (X_("lua"), LUA_VERSION);
1323                 script_node->add_content (b64s);
1324                 node->add_child_nocopy (*script_node);
1325         }
1326
1327         return *node;
1328 }
1329
1330 XMLNode&
1331 Session::get_control_protocol_state ()
1332 {
1333         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1334         return cpm.get_state();
1335 }
1336
1337 int
1338 Session::set_state (const XMLNode& node, int version)
1339 {
1340         LocaleGuard lg;
1341         XMLNodeList nlist;
1342         XMLNode* child;
1343         XMLProperty const * prop;
1344         int ret = -1;
1345
1346         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1347
1348         if (node.name() != X_("Session")) {
1349                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1350                 goto out;
1351         }
1352
1353         if ((prop = node.property ("name")) != 0) {
1354                 _name = prop->value ();
1355         }
1356
1357         if ((prop = node.property (X_("sample-rate"))) != 0) {
1358
1359                 _base_frame_rate = atoi (prop->value());
1360                 _nominal_frame_rate = _base_frame_rate;
1361
1362                 assert (AudioEngine::instance()->running ());
1363                 if (_base_frame_rate != AudioEngine::instance()->sample_rate ()) {
1364                         boost::optional<int> r = AskAboutSampleRateMismatch (_base_frame_rate, _current_frame_rate);
1365                         if (r.get_value_or (0)) {
1366                                 goto out;
1367                         }
1368                 }
1369         }
1370
1371         created_with = "unknown";
1372         if ((child = find_named_node (node, "ProgramVersion")) != 0) {
1373                 if ((prop = child->property (X_("created-with"))) != 0) {
1374                         created_with = prop->value ();
1375                 }
1376         }
1377
1378         setup_raid_path(_session_dir->root_path());
1379
1380         if ((prop = node.property (X_("end-is-free"))) != 0) {
1381                 _session_range_end_is_free = string_is_affirmative (prop->value());
1382         }
1383
1384         if ((prop = node.property (X_("id-counter"))) != 0) {
1385                 uint64_t x;
1386                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1387                 ID::init_counter (x);
1388         } else {
1389                 /* old sessions used a timebased counter, so fake
1390                    the startup ID counter based on a standard
1391                    timestamp.
1392                 */
1393                 time_t now;
1394                 time (&now);
1395                 ID::init_counter (now);
1396         }
1397
1398         if ((prop = node.property (X_("name-counter"))) != 0) {
1399                 init_name_id_counter (atoi (prop->value()));
1400         }
1401
1402         if ((prop = node.property (X_("event-counter"))) != 0) {
1403                 Evoral::init_event_id_counter (atoi (prop->value()));
1404         }
1405
1406         if ((prop = node.property (X_("vca-counter"))) != 0) {
1407                 uint32_t x;
1408                 sscanf (prop->value().c_str(), "%" PRIu32, &x);
1409                 VCA::set_next_vca_number (x);
1410         } else {
1411                 VCA::set_next_vca_number (1);
1412         }
1413
1414         if ((child = find_named_node (node, "MIDIPorts")) != 0) {
1415                 _midi_ports->set_midi_port_states (child->children());
1416         }
1417
1418         IO::disable_connecting ();
1419
1420         Stateful::save_extra_xml (node);
1421
1422         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1423                 load_options (*child);
1424         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1425                 load_options (*child);
1426         } else {
1427                 error << _("Session: XML state has no options section") << endmsg;
1428         }
1429
1430         if (version >= 3000) {
1431                 if ((child = find_named_node (node, "Metadata")) == 0) {
1432                         warning << _("Session: XML state has no metadata section") << endmsg;
1433                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1434                         goto out;
1435                 }
1436         }
1437
1438         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1439                 _speakers->set_state (*child, version);
1440         }
1441
1442         if ((child = find_named_node (node, "Sources")) == 0) {
1443                 error << _("Session: XML state has no sources section") << endmsg;
1444                 goto out;
1445         } else if (load_sources (*child)) {
1446                 goto out;
1447         }
1448
1449         if ((child = find_named_node (node, "TempoMap")) == 0) {
1450                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1451                 goto out;
1452         } else if (_tempo_map->set_state (*child, version)) {
1453                 goto out;
1454         }
1455
1456         if ((child = find_named_node (node, "Locations")) == 0) {
1457                 error << _("Session: XML state has no locations section") << endmsg;
1458                 goto out;
1459         } else if (_locations->set_state (*child, version)) {
1460                 goto out;
1461         }
1462
1463         locations_changed ();
1464
1465         if (_session_range_location) {
1466                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1467         }
1468
1469         if ((child = find_named_node (node, "Regions")) == 0) {
1470                 error << _("Session: XML state has no Regions section") << endmsg;
1471                 goto out;
1472         } else if (load_regions (*child)) {
1473                 goto out;
1474         }
1475
1476         if ((child = find_named_node (node, "Playlists")) == 0) {
1477                 error << _("Session: XML state has no playlists section") << endmsg;
1478                 goto out;
1479         } else if (playlists->load (*this, *child)) {
1480                 goto out;
1481         }
1482
1483         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1484                 // this is OK
1485         } else if (playlists->load_unused (*this, *child)) {
1486                 goto out;
1487         }
1488
1489         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1490                 if (load_compounds (*child)) {
1491                         goto out;
1492                 }
1493         }
1494
1495         if (version >= 3000) {
1496                 if ((child = find_named_node (node, "Bundles")) == 0) {
1497                         warning << _("Session: XML state has no bundles section") << endmsg;
1498                         //goto out;
1499                 } else {
1500                         /* We can't load Bundles yet as they need to be able
1501                            to convert from port names to Port objects, which can't happen until
1502                            later */
1503                         _bundle_xml_node = new XMLNode (*child);
1504                 }
1505         }
1506
1507         if (version < 3000) {
1508                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1509                         error << _("Session: XML state has no diskstreams section") << endmsg;
1510                         goto out;
1511                 } else if (load_diskstreams_2X (*child, version)) {
1512                         goto out;
1513                 }
1514         }
1515
1516         if ((child = find_named_node (node, VCAManager::xml_node_name)) != 0) {
1517                 _vca_manager->set_state (*child, version);
1518         }
1519
1520         if ((child = find_named_node (node, "Routes")) == 0) {
1521                 error << _("Session: XML state has no routes section") << endmsg;
1522                 goto out;
1523         } else if (load_routes (*child, version)) {
1524                 goto out;
1525         }
1526
1527         /* Now that we have Routes and masters loaded, connect them if appropriate */
1528
1529         Slavable::Assign (_vca_manager); /* EMIT SIGNAL */
1530
1531         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1532         _diskstreams_2X.clear ();
1533
1534         if (version >= 3000) {
1535
1536                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1537                         error << _("Session: XML state has no route groups section") << endmsg;
1538                         goto out;
1539                 } else if (load_route_groups (*child, version)) {
1540                         goto out;
1541                 }
1542
1543         } else if (version < 3000) {
1544
1545                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1546                         error << _("Session: XML state has no edit groups section") << endmsg;
1547                         goto out;
1548                 } else if (load_route_groups (*child, version)) {
1549                         goto out;
1550                 }
1551
1552                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1553                         error << _("Session: XML state has no mix groups section") << endmsg;
1554                         goto out;
1555                 } else if (load_route_groups (*child, version)) {
1556                         goto out;
1557                 }
1558         }
1559
1560         if ((child = find_named_node (node, "Click")) == 0) {
1561                 warning << _("Session: XML state has no click section") << endmsg;
1562         } else if (_click_io) {
1563                 setup_click_state (&node);
1564         }
1565
1566         if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1567                 ControlProtocolManager::instance().set_state (*child, version);
1568         }
1569
1570         if ((child = find_named_node (node, "Script"))) {
1571                 for (XMLNodeList::const_iterator n = child->children ().begin (); n != child->children ().end (); ++n) {
1572                         if (!(*n)->is_content ()) { continue; }
1573                         gsize size;
1574                         guchar* buf = g_base64_decode ((*n)->content ().c_str (), &size);
1575                         try {
1576                                 Glib::Threads::Mutex::Lock lm (lua_lock);
1577                                 (*_lua_load)(std::string ((const char*)buf, size));
1578                         } catch (luabridge::LuaException const& e) {
1579                                 cerr << "LuaException:" << e.what () << endl;
1580                         }
1581                         g_free (buf);
1582                 }
1583         }
1584
1585         update_route_record_state ();
1586
1587         /* here beginneth the second phase ... */
1588         set_snapshot_name (_current_snapshot_name);
1589
1590         StateReady (); /* EMIT SIGNAL */
1591
1592         delete state_tree;
1593         state_tree = 0;
1594         return 0;
1595
1596   out:
1597         delete state_tree;
1598         state_tree = 0;
1599         return ret;
1600 }
1601
1602 int
1603 Session::load_routes (const XMLNode& node, int version)
1604 {
1605         XMLNodeList nlist;
1606         XMLNodeConstIterator niter;
1607         RouteList new_routes;
1608
1609         nlist = node.children();
1610
1611         set_dirty();
1612
1613         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1614
1615                 boost::shared_ptr<Route> route;
1616                 if (version < 3000) {
1617                         route = XMLRouteFactory_2X (**niter, version);
1618                 } else {
1619                         route = XMLRouteFactory (**niter, version);
1620                 }
1621
1622                 if (route == 0) {
1623                         error << _("Session: cannot create Route from XML description.") << endmsg;
1624                         return -1;
1625                 }
1626
1627                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1628
1629                 new_routes.push_back (route);
1630         }
1631
1632         BootMessage (_("Tracks/busses loaded;  Adding to Session"));
1633
1634         add_routes (new_routes, false, false, false, PresentationInfo::max_order);
1635
1636         BootMessage (_("Finished adding tracks/busses"));
1637
1638         return 0;
1639 }
1640
1641 boost::shared_ptr<Route>
1642 Session::XMLRouteFactory (const XMLNode& node, int version)
1643 {
1644         boost::shared_ptr<Route> ret;
1645
1646         if (node.name() != "Route") {
1647                 return ret;
1648         }
1649
1650         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1651
1652         DataType type = DataType::AUDIO;
1653         XMLProperty const * prop = node.property("default-type");
1654
1655         if (prop) {
1656                 type = DataType (prop->value());
1657         }
1658
1659         assert (type != DataType::NIL);
1660
1661         if (ds_child) {
1662
1663                 boost::shared_ptr<Track> track;
1664
1665                 if (type == DataType::AUDIO) {
1666                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1667                 } else {
1668                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1669                 }
1670
1671                 if (track->init()) {
1672                         return ret;
1673                 }
1674
1675                 if (track->set_state (node, version)) {
1676                         return ret;
1677                 }
1678
1679                 BOOST_MARK_TRACK (track);
1680                 ret = track;
1681
1682         } else {
1683                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1684                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1685
1686                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1687                         BOOST_MARK_ROUTE (r);
1688                         ret = r;
1689                 }
1690         }
1691
1692         return ret;
1693 }
1694
1695 boost::shared_ptr<Route>
1696 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1697 {
1698         boost::shared_ptr<Route> ret;
1699
1700         if (node.name() != "Route") {
1701                 return ret;
1702         }
1703
1704         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1705         if (!ds_prop) {
1706                 ds_prop = node.property (X_("diskstream"));
1707         }
1708
1709         DataType type = DataType::AUDIO;
1710         XMLProperty const * prop = node.property("default-type");
1711
1712         if (prop) {
1713                 type = DataType (prop->value());
1714         }
1715
1716         assert (type != DataType::NIL);
1717
1718         if (ds_prop) {
1719
1720                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1721                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1722                         ++i;
1723                 }
1724
1725                 if (i == _diskstreams_2X.end()) {
1726                         error << _("Could not find diskstream for route") << endmsg;
1727                         return boost::shared_ptr<Route> ();
1728                 }
1729
1730                 boost::shared_ptr<Track> track;
1731
1732                 if (type == DataType::AUDIO) {
1733                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1734                 } else {
1735                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1736                 }
1737
1738                 if (track->init()) {
1739                         return ret;
1740                 }
1741
1742                 if (track->set_state (node, version)) {
1743                         return ret;
1744                 }
1745
1746                 track->set_diskstream (*i);
1747
1748                 BOOST_MARK_TRACK (track);
1749                 ret = track;
1750
1751         } else {
1752                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1753                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1754
1755                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1756                         BOOST_MARK_ROUTE (r);
1757                         ret = r;
1758                 }
1759         }
1760
1761         return ret;
1762 }
1763
1764 int
1765 Session::load_regions (const XMLNode& node)
1766 {
1767         XMLNodeList nlist;
1768         XMLNodeConstIterator niter;
1769         boost::shared_ptr<Region> region;
1770
1771         nlist = node.children();
1772
1773         set_dirty();
1774
1775         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1776                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1777                         error << _("Session: cannot create Region from XML description.");
1778                         XMLProperty const * name = (**niter).property("name");
1779
1780                         if (name) {
1781                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1782                         }
1783
1784                         error << endmsg;
1785                 }
1786         }
1787
1788         return 0;
1789 }
1790
1791 int
1792 Session::load_compounds (const XMLNode& node)
1793 {
1794         XMLNodeList calist = node.children();
1795         XMLNodeConstIterator caiter;
1796         XMLProperty const * caprop;
1797
1798         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1799                 XMLNode* ca = *caiter;
1800                 ID orig_id;
1801                 ID copy_id;
1802
1803                 if ((caprop = ca->property (X_("original"))) == 0) {
1804                         continue;
1805                 }
1806                 orig_id = caprop->value();
1807
1808                 if ((caprop = ca->property (X_("copy"))) == 0) {
1809                         continue;
1810                 }
1811                 copy_id = caprop->value();
1812
1813                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1814                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1815
1816                 if (!orig || !copy) {
1817                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1818                                                    orig_id, copy_id)
1819                                 << endmsg;
1820                         continue;
1821                 }
1822
1823                 RegionFactory::add_compound_association (orig, copy);
1824         }
1825
1826         return 0;
1827 }
1828
1829 void
1830 Session::load_nested_sources (const XMLNode& node)
1831 {
1832         XMLNodeList nlist;
1833         XMLNodeConstIterator niter;
1834
1835         nlist = node.children();
1836
1837         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1838                 if ((*niter)->name() == "Source") {
1839
1840                         /* it may already exist, so don't recreate it unnecessarily
1841                          */
1842
1843                         XMLProperty const * prop = (*niter)->property (X_("id"));
1844                         if (!prop) {
1845                                 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1846                                 continue;
1847                         }
1848
1849                         ID source_id (prop->value());
1850
1851                         if (!source_by_id (source_id)) {
1852
1853                                 try {
1854                                         SourceFactory::create (*this, **niter, true);
1855                                 }
1856                                 catch (failed_constructor& err) {
1857                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1858                                 }
1859                         }
1860                 }
1861         }
1862 }
1863
1864 boost::shared_ptr<Region>
1865 Session::XMLRegionFactory (const XMLNode& node, bool full)
1866 {
1867         XMLProperty const * type = node.property("type");
1868
1869         try {
1870
1871                 const XMLNodeList& nlist = node.children();
1872
1873                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1874                         XMLNode *child = (*niter);
1875                         if (child->name() == "NestedSource") {
1876                                 load_nested_sources (*child);
1877                         }
1878                 }
1879
1880                 if (!type || type->value() == "audio") {
1881                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1882                 } else if (type->value() == "midi") {
1883                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1884                 }
1885
1886         } catch (failed_constructor& err) {
1887                 return boost::shared_ptr<Region> ();
1888         }
1889
1890         return boost::shared_ptr<Region> ();
1891 }
1892
1893 boost::shared_ptr<AudioRegion>
1894 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1895 {
1896         XMLProperty const * prop;
1897         boost::shared_ptr<Source> source;
1898         boost::shared_ptr<AudioSource> as;
1899         SourceList sources;
1900         SourceList master_sources;
1901         uint32_t nchans = 1;
1902         char buf[128];
1903
1904         if (node.name() != X_("Region")) {
1905                 return boost::shared_ptr<AudioRegion>();
1906         }
1907
1908         if ((prop = node.property (X_("channels"))) != 0) {
1909                 nchans = atoi (prop->value().c_str());
1910         }
1911
1912         if ((prop = node.property ("name")) == 0) {
1913                 cerr << "no name for this region\n";
1914                 abort ();
1915         }
1916
1917         if ((prop = node.property (X_("source-0"))) == 0) {
1918                 if ((prop = node.property ("source")) == 0) {
1919                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1920                         return boost::shared_ptr<AudioRegion>();
1921                 }
1922         }
1923
1924         PBD::ID s_id (prop->value());
1925
1926         if ((source = source_by_id (s_id)) == 0) {
1927                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1928                 return boost::shared_ptr<AudioRegion>();
1929         }
1930
1931         as = boost::dynamic_pointer_cast<AudioSource>(source);
1932         if (!as) {
1933                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1934                 return boost::shared_ptr<AudioRegion>();
1935         }
1936
1937         sources.push_back (as);
1938
1939         /* pickup other channels */
1940
1941         for (uint32_t n=1; n < nchans; ++n) {
1942                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1943                 if ((prop = node.property (buf)) != 0) {
1944
1945                         PBD::ID id2 (prop->value());
1946
1947                         if ((source = source_by_id (id2)) == 0) {
1948                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1949                                 return boost::shared_ptr<AudioRegion>();
1950                         }
1951
1952                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1953                         if (!as) {
1954                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1955                                 return boost::shared_ptr<AudioRegion>();
1956                         }
1957                         sources.push_back (as);
1958                 }
1959         }
1960
1961         for (uint32_t n = 0; n < nchans; ++n) {
1962                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1963                 if ((prop = node.property (buf)) != 0) {
1964
1965                         PBD::ID id2 (prop->value());
1966
1967                         if ((source = source_by_id (id2)) == 0) {
1968                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1969                                 return boost::shared_ptr<AudioRegion>();
1970                         }
1971
1972                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1973                         if (!as) {
1974                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1975                                 return boost::shared_ptr<AudioRegion>();
1976                         }
1977                         master_sources.push_back (as);
1978                 }
1979         }
1980
1981         try {
1982                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1983
1984                 /* a final detail: this is the one and only place that we know how long missing files are */
1985
1986                 if (region->whole_file()) {
1987                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1988                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1989                                 if (sfp) {
1990                                         sfp->set_length (region->length());
1991                                 }
1992                         }
1993                 }
1994
1995                 if (!master_sources.empty()) {
1996                         if (master_sources.size() != nchans) {
1997                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1998                         } else {
1999                                 region->set_master_sources (master_sources);
2000                         }
2001                 }
2002
2003                 return region;
2004
2005         }
2006
2007         catch (failed_constructor& err) {
2008                 return boost::shared_ptr<AudioRegion>();
2009         }
2010 }
2011
2012 boost::shared_ptr<MidiRegion>
2013 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
2014 {
2015         XMLProperty const * prop;
2016         boost::shared_ptr<Source> source;
2017         boost::shared_ptr<MidiSource> ms;
2018         SourceList sources;
2019
2020         if (node.name() != X_("Region")) {
2021                 return boost::shared_ptr<MidiRegion>();
2022         }
2023
2024         if ((prop = node.property ("name")) == 0) {
2025                 cerr << "no name for this region\n";
2026                 abort ();
2027         }
2028
2029         if ((prop = node.property (X_("source-0"))) == 0) {
2030                 if ((prop = node.property ("source")) == 0) {
2031                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
2032                         return boost::shared_ptr<MidiRegion>();
2033                 }
2034         }
2035
2036         PBD::ID s_id (prop->value());
2037
2038         if ((source = source_by_id (s_id)) == 0) {
2039                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
2040                 return boost::shared_ptr<MidiRegion>();
2041         }
2042
2043         ms = boost::dynamic_pointer_cast<MidiSource>(source);
2044         if (!ms) {
2045                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
2046                 return boost::shared_ptr<MidiRegion>();
2047         }
2048
2049         sources.push_back (ms);
2050
2051         try {
2052                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
2053                 /* a final detail: this is the one and only place that we know how long missing files are */
2054
2055                 if (region->whole_file()) {
2056                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
2057                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
2058                                 if (sfp) {
2059                                         sfp->set_length (region->length());
2060                                 }
2061                         }
2062                 }
2063
2064                 return region;
2065         }
2066
2067         catch (failed_constructor& err) {
2068                 return boost::shared_ptr<MidiRegion>();
2069         }
2070 }
2071
2072 XMLNode&
2073 Session::get_sources_as_xml ()
2074
2075 {
2076         XMLNode* node = new XMLNode (X_("Sources"));
2077         Glib::Threads::Mutex::Lock lm (source_lock);
2078
2079         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2080                 node->add_child_nocopy (i->second->get_state());
2081         }
2082
2083         return *node;
2084 }
2085
2086 void
2087 Session::reset_write_sources (bool mark_write_complete, bool force)
2088 {
2089         boost::shared_ptr<RouteList> rl = routes.reader();
2090         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2091                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2092                 if (tr) {
2093                         _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
2094                         tr->reset_write_sources(mark_write_complete, force);
2095                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
2096                 }
2097         }
2098 }
2099
2100 int
2101 Session::load_sources (const XMLNode& node)
2102 {
2103         XMLNodeList nlist;
2104         XMLNodeConstIterator niter;
2105         boost::shared_ptr<Source> source; /* don't need this but it stops some
2106                                            * versions of gcc complaining about
2107                                            * discarded return values.
2108                                            */
2109
2110         nlist = node.children();
2111
2112         set_dirty();
2113
2114         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2115           retry:
2116                 try {
2117                         if ((source = XMLSourceFactory (**niter)) == 0) {
2118                                 error << _("Session: cannot create Source from XML description.") << endmsg;
2119                         }
2120
2121                 } catch (MissingSource& err) {
2122
2123                         int user_choice;
2124
2125                         if (err.type == DataType::MIDI && Glib::path_is_absolute (err.path)) {
2126                                 error << string_compose (_("A external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
2127                                                          PROGRAM_NAME) << endmsg;
2128                                 return -1;
2129                         }
2130
2131                         if (!no_questions_about_missing_files) {
2132                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
2133                         } else {
2134                                 user_choice = -2;
2135                         }
2136
2137                         switch (user_choice) {
2138                         case 0:
2139                                 /* user added a new search location, so try again */
2140                                 goto retry;
2141
2142
2143                         case 1:
2144                                 /* user asked to quit the entire session load
2145                                  */
2146                                 return -1;
2147
2148                         case 2:
2149                                 no_questions_about_missing_files = true;
2150                                 goto retry;
2151
2152                         case 3:
2153                                 no_questions_about_missing_files = true;
2154                                 /* fallthru */
2155
2156                         case -1:
2157                         default:
2158                                 switch (err.type) {
2159
2160                                 case DataType::AUDIO:
2161                                         source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2162                                         break;
2163
2164                                 case DataType::MIDI:
2165                                         /* The MIDI file is actually missing so
2166                                          * just create a new one in the same
2167                                          * location. Do not announce its
2168                                          */
2169                                         string fullpath;
2170
2171                                         if (!Glib::path_is_absolute (err.path)) {
2172                                                 fullpath = Glib::build_filename (source_search_path (DataType::MIDI).front(), err.path);
2173                                         } else {
2174                                                 /* this should be an unrecoverable error: we would be creating a MIDI file outside
2175                                                    the session tree.
2176                                                 */
2177                                                 return -1;
2178                                         }
2179                                         /* Note that we do not announce the source just yet - we need to reset its ID before we do that */
2180                                         source = SourceFactory::createWritable (DataType::MIDI, *this, fullpath, false, _current_frame_rate, false, false);
2181                                         /* reset ID to match the missing one */
2182                                         source->set_id (**niter);
2183                                         /* Now we can announce it */
2184                                         SourceFactory::SourceCreated (source);
2185                                         break;
2186                                 }
2187                                 break;
2188                         }
2189                 }
2190         }
2191
2192         return 0;
2193 }
2194
2195 boost::shared_ptr<Source>
2196 Session::XMLSourceFactory (const XMLNode& node)
2197 {
2198         if (node.name() != "Source") {
2199                 return boost::shared_ptr<Source>();
2200         }
2201
2202         try {
2203                 /* note: do peak building in another thread when loading session state */
2204                 return SourceFactory::create (*this, node, true);
2205         }
2206
2207         catch (failed_constructor& err) {
2208                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the programmers."), PROGRAM_NAME) << endmsg;
2209                 return boost::shared_ptr<Source>();
2210         }
2211 }
2212
2213 int
2214 Session::save_template (string template_name, bool replace_existing)
2215 {
2216         if ((_state_of_the_state & CannotSave) || template_name.empty ()) {
2217                 return -1;
2218         }
2219
2220         bool absolute_path = Glib::path_is_absolute (template_name);
2221
2222         /* directory to put the template in */
2223         std::string template_dir_path;
2224
2225         if (!absolute_path) {
2226                 std::string user_template_dir(user_template_directory());
2227
2228                 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2229                         error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2230                                         user_template_dir, g_strerror (errno)) << endmsg;
2231                         return -1;
2232                 }
2233
2234                 template_dir_path = Glib::build_filename (user_template_dir, template_name);
2235         } else {
2236                 template_dir_path = template_name;
2237         }
2238
2239         if (!ARDOUR::Profile->get_trx()) {
2240                 if (!replace_existing && Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2241                         warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2242                                                                           template_dir_path) << endmsg;
2243                         return -2;
2244                 }
2245
2246                 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2247                         error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2248                                                                         template_dir_path, g_strerror (errno)) << endmsg;
2249                         return -1;
2250                 }
2251         }
2252
2253         /* file to write */
2254         std::string template_file_path;
2255
2256         if (ARDOUR::Profile->get_trx()) {
2257                 template_file_path = template_name;
2258         } else {
2259                 if (absolute_path) {
2260                         template_file_path = Glib::build_filename (template_dir_path, Glib::path_get_basename (template_dir_path) + template_suffix);
2261                 } else {
2262                         template_file_path = Glib::build_filename (template_dir_path, template_name + template_suffix);
2263                 }
2264         }
2265
2266         SessionSaveUnderway (); /* EMIT SIGNAL */
2267
2268         XMLTree tree;
2269
2270         {
2271                 PBD::Unwinder<std::string> uw (_template_state_dir, template_dir_path);
2272                 tree.set_root (&get_template());
2273         }
2274
2275         if (!tree.write (template_file_path)) {
2276                 error << _("template not saved") << endmsg;
2277                 return -1;
2278         }
2279
2280         store_recent_templates (template_file_path);
2281
2282         return 0;
2283 }
2284
2285 void
2286 Session::refresh_disk_space ()
2287 {
2288 #if __APPLE__ || __FreeBSD__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2289
2290         Glib::Threads::Mutex::Lock lm (space_lock);
2291
2292         /* get freespace on every FS that is part of the session path */
2293
2294         _total_free_4k_blocks = 0;
2295         _total_free_4k_blocks_uncertain = false;
2296
2297         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2298
2299                 struct statfs statfsbuf;
2300                 statfs (i->path.c_str(), &statfsbuf);
2301
2302                 double const scale = statfsbuf.f_bsize / 4096.0;
2303
2304                 /* See if this filesystem is read-only */
2305                 struct statvfs statvfsbuf;
2306                 statvfs (i->path.c_str(), &statvfsbuf);
2307
2308                 /* f_bavail can be 0 if it is undefined for whatever
2309                    filesystem we are looking at; Samba shares mounted
2310                    via GVFS are an example of this.
2311                 */
2312                 if (statfsbuf.f_bavail == 0) {
2313                         /* block count unknown */
2314                         i->blocks = 0;
2315                         i->blocks_unknown = true;
2316                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2317                         /* read-only filesystem */
2318                         i->blocks = 0;
2319                         i->blocks_unknown = false;
2320                 } else {
2321                         /* read/write filesystem with known space */
2322                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2323                         i->blocks_unknown = false;
2324                 }
2325
2326                 _total_free_4k_blocks += i->blocks;
2327                 if (i->blocks_unknown) {
2328                         _total_free_4k_blocks_uncertain = true;
2329                 }
2330         }
2331 #elif defined PLATFORM_WINDOWS
2332         vector<string> scanned_volumes;
2333         vector<string>::iterator j;
2334         vector<space_and_path>::iterator i;
2335     DWORD nSectorsPerCluster, nBytesPerSector,
2336           nFreeClusters, nTotalClusters;
2337     char disk_drive[4];
2338         bool volume_found;
2339
2340         _total_free_4k_blocks = 0;
2341
2342         for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2343                 strncpy (disk_drive, (*i).path.c_str(), 3);
2344                 disk_drive[3] = 0;
2345                 strupr(disk_drive);
2346
2347                 volume_found = false;
2348                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2349                 {
2350                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2351                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2352                         i->blocks = (uint32_t)(nFreeBytes / 4096);
2353
2354                         for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2355                                 if (0 == j->compare(disk_drive)) {
2356                                         volume_found = true;
2357                                         break;
2358                                 }
2359                         }
2360
2361                         if (!volume_found) {
2362                                 scanned_volumes.push_back(disk_drive);
2363                                 _total_free_4k_blocks += i->blocks;
2364                         }
2365                 }
2366         }
2367
2368         if (0 == _total_free_4k_blocks) {
2369                 strncpy (disk_drive, path().c_str(), 3);
2370                 disk_drive[3] = 0;
2371
2372                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2373                 {
2374                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2375                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2376                         _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2377                 }
2378         }
2379 #endif
2380 }
2381
2382 string
2383 Session::get_best_session_directory_for_new_audio ()
2384 {
2385         vector<space_and_path>::iterator i;
2386         string result = _session_dir->root_path();
2387
2388         /* handle common case without system calls */
2389
2390         if (session_dirs.size() == 1) {
2391                 return result;
2392         }
2393
2394         /* OK, here's the algorithm we're following here:
2395
2396         We want to select which directory to use for
2397         the next file source to be created. Ideally,
2398         we'd like to use a round-robin process so as to
2399         get maximum performance benefits from splitting
2400         the files across multiple disks.
2401
2402         However, in situations without much diskspace, an
2403         RR approach may end up filling up a filesystem
2404         with new files while others still have space.
2405         Its therefore important to pay some attention to
2406         the freespace in the filesystem holding each
2407         directory as well. However, if we did that by
2408         itself, we'd keep creating new files in the file
2409         system with the most space until it was as full
2410         as all others, thus negating any performance
2411         benefits of this RAID-1 like approach.
2412
2413         So, we use a user-configurable space threshold. If
2414         there are at least 2 filesystems with more than this
2415         much space available, we use RR selection between them.
2416         If not, then we pick the filesystem with the most space.
2417
2418         This gets a good balance between the two
2419         approaches.
2420         */
2421
2422         refresh_disk_space ();
2423
2424         int free_enough = 0;
2425
2426         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2427                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2428                         free_enough++;
2429                 }
2430         }
2431
2432         if (free_enough >= 2) {
2433                 /* use RR selection process, ensuring that the one
2434                    picked works OK.
2435                 */
2436
2437                 i = last_rr_session_dir;
2438
2439                 do {
2440                         if (++i == session_dirs.end()) {
2441                                 i = session_dirs.begin();
2442                         }
2443
2444                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2445                                 SessionDirectory sdir(i->path);
2446                                 if (sdir.create ()) {
2447                                         result = (*i).path;
2448                                         last_rr_session_dir = i;
2449                                         return result;
2450                                 }
2451                         }
2452
2453                 } while (i != last_rr_session_dir);
2454
2455         } else {
2456
2457                 /* pick FS with the most freespace (and that
2458                    seems to actually work ...)
2459                 */
2460
2461                 vector<space_and_path> sorted;
2462                 space_and_path_ascending_cmp cmp;
2463
2464                 sorted = session_dirs;
2465                 sort (sorted.begin(), sorted.end(), cmp);
2466
2467                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2468                         SessionDirectory sdir(i->path);
2469                         if (sdir.create ()) {
2470                                 result = (*i).path;
2471                                 last_rr_session_dir = i;
2472                                 return result;
2473                         }
2474                 }
2475         }
2476
2477         return result;
2478 }
2479
2480 string
2481 Session::automation_dir () const
2482 {
2483         return Glib::build_filename (_path, automation_dir_name);
2484 }
2485
2486 string
2487 Session::analysis_dir () const
2488 {
2489         return Glib::build_filename (_path, analysis_dir_name);
2490 }
2491
2492 string
2493 Session::plugins_dir () const
2494 {
2495         return Glib::build_filename (_path, plugins_dir_name);
2496 }
2497
2498 string
2499 Session::externals_dir () const
2500 {
2501         return Glib::build_filename (_path, externals_dir_name);
2502 }
2503
2504 int
2505 Session::load_bundles (XMLNode const & node)
2506 {
2507         XMLNodeList nlist = node.children();
2508         XMLNodeConstIterator niter;
2509
2510         set_dirty();
2511
2512         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2513                 if ((*niter)->name() == "InputBundle") {
2514                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2515                 } else if ((*niter)->name() == "OutputBundle") {
2516                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2517                 } else {
2518                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2519                         return -1;
2520                 }
2521         }
2522
2523         return 0;
2524 }
2525
2526 int
2527 Session::load_route_groups (const XMLNode& node, int version)
2528 {
2529         XMLNodeList nlist = node.children();
2530         XMLNodeConstIterator niter;
2531
2532         set_dirty ();
2533
2534         if (version >= 3000) {
2535
2536                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2537                         if ((*niter)->name() == "RouteGroup") {
2538                                 RouteGroup* rg = new RouteGroup (*this, "");
2539                                 add_route_group (rg);
2540                                 rg->set_state (**niter, version);
2541                         }
2542                 }
2543
2544         } else if (version < 3000) {
2545
2546                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2547                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2548                                 RouteGroup* rg = new RouteGroup (*this, "");
2549                                 add_route_group (rg);
2550                                 rg->set_state (**niter, version);
2551                         }
2552                 }
2553         }
2554
2555         return 0;
2556 }
2557
2558 static bool
2559 state_file_filter (const string &str, void* /*arg*/)
2560 {
2561         return (str.length() > strlen(statefile_suffix) &&
2562                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2563 }
2564
2565 static string
2566 remove_end(string state)
2567 {
2568         string statename(state);
2569
2570         string::size_type start,end;
2571         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2572                 statename = statename.substr (start+1);
2573         }
2574
2575         if ((end = statename.rfind(statefile_suffix)) == string::npos) {
2576                 end = statename.length();
2577         }
2578
2579         return string(statename.substr (0, end));
2580 }
2581
2582 vector<string>
2583 Session::possible_states (string path)
2584 {
2585         vector<string> states;
2586         find_files_matching_filter (states, path, state_file_filter, 0, false, false);
2587
2588         transform(states.begin(), states.end(), states.begin(), remove_end);
2589
2590         sort (states.begin(), states.end());
2591
2592         return states;
2593 }
2594
2595 vector<string>
2596 Session::possible_states () const
2597 {
2598         return possible_states(_path);
2599 }
2600
2601 void
2602 Session::add_route_group (RouteGroup* g)
2603 {
2604         _route_groups.push_back (g);
2605         route_group_added (g); /* EMIT SIGNAL */
2606
2607         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2608         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2609         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2610
2611         set_dirty ();
2612 }
2613
2614 void
2615 Session::remove_route_group (RouteGroup& rg)
2616 {
2617         list<RouteGroup*>::iterator i;
2618
2619         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2620                 _route_groups.erase (i);
2621                 delete &rg;
2622
2623                 route_group_removed (); /* EMIT SIGNAL */
2624         }
2625 }
2626
2627 /** Set a new order for our route groups, without adding or removing any.
2628  *  @param groups Route group list in the new order.
2629  */
2630 void
2631 Session::reorder_route_groups (list<RouteGroup*> groups)
2632 {
2633         _route_groups = groups;
2634
2635         route_groups_reordered (); /* EMIT SIGNAL */
2636         set_dirty ();
2637 }
2638
2639
2640 RouteGroup *
2641 Session::route_group_by_name (string name)
2642 {
2643         list<RouteGroup *>::iterator i;
2644
2645         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2646                 if ((*i)->name() == name) {
2647                         return* i;
2648                 }
2649         }
2650         return 0;
2651 }
2652
2653 RouteGroup&
2654 Session::all_route_group() const
2655 {
2656         return *_all_route_group;
2657 }
2658
2659 void
2660 Session::add_commands (vector<Command*> const & cmds)
2661 {
2662         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2663                 add_command (*i);
2664         }
2665 }
2666
2667 void
2668 Session::add_command (Command* const cmd)
2669 {
2670         assert (_current_trans);
2671         DEBUG_UNDO_HISTORY (
2672             string_compose ("Current Undo Transaction %1, adding command: %2",
2673                             _current_trans->name (),
2674                             cmd->name ()));
2675         _current_trans->add_command (cmd);
2676 }
2677
2678 PBD::StatefulDiffCommand*
2679 Session::add_stateful_diff_command (boost::shared_ptr<PBD::StatefulDestructible> sfd)
2680 {
2681         PBD::StatefulDiffCommand* cmd = new PBD::StatefulDiffCommand (sfd);
2682         add_command (cmd);
2683         return cmd;
2684 }
2685
2686 void
2687 Session::begin_reversible_command (const string& name)
2688 {
2689         begin_reversible_command (g_quark_from_string (name.c_str ()));
2690 }
2691
2692 /** Begin a reversible command using a GQuark to identify it.
2693  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2694  *  but there must be as many begin...()s as there are commit...()s.
2695  */
2696 void
2697 Session::begin_reversible_command (GQuark q)
2698 {
2699         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2700            to hold all the commands that are committed.  This keeps the order of
2701            commands correct in the history.
2702         */
2703
2704         if (_current_trans == 0) {
2705                 DEBUG_UNDO_HISTORY (string_compose (
2706                     "Begin Reversible Command, new transaction: %1", g_quark_to_string (q)));
2707
2708                 /* start a new transaction */
2709                 assert (_current_trans_quarks.empty ());
2710                 _current_trans = new UndoTransaction();
2711                 _current_trans->set_name (g_quark_to_string (q));
2712         } else {
2713                 DEBUG_UNDO_HISTORY (
2714                     string_compose ("Begin Reversible Command, current transaction: %1",
2715                                     _current_trans->name ()));
2716         }
2717
2718         _current_trans_quarks.push_front (q);
2719 }
2720
2721 void
2722 Session::abort_reversible_command ()
2723 {
2724         if (_current_trans != 0) {
2725                 DEBUG_UNDO_HISTORY (
2726                     string_compose ("Abort Reversible Command: %1", _current_trans->name ()));
2727                 _current_trans->clear();
2728                 delete _current_trans;
2729                 _current_trans = 0;
2730                 _current_trans_quarks.clear();
2731         }
2732 }
2733
2734 void
2735 Session::commit_reversible_command (Command *cmd)
2736 {
2737         assert (_current_trans);
2738         assert (!_current_trans_quarks.empty ());
2739
2740         struct timeval now;
2741
2742         if (cmd) {
2743                 DEBUG_UNDO_HISTORY (
2744                     string_compose ("Current Undo Transaction %1, adding command: %2",
2745                                     _current_trans->name (),
2746                                     cmd->name ()));
2747                 _current_trans->add_command (cmd);
2748         }
2749
2750         DEBUG_UNDO_HISTORY (
2751             string_compose ("Commit Reversible Command, current transaction: %1",
2752                             _current_trans->name ()));
2753
2754         _current_trans_quarks.pop_front ();
2755
2756         if (!_current_trans_quarks.empty ()) {
2757                 DEBUG_UNDO_HISTORY (
2758                     string_compose ("Commit Reversible Command, transaction is not "
2759                                     "top-level, current transaction: %1",
2760                                     _current_trans->name ()));
2761                 /* the transaction we're committing is not the top-level one */
2762                 return;
2763         }
2764
2765         if (_current_trans->empty()) {
2766                 /* no commands were added to the transaction, so just get rid of it */
2767                 DEBUG_UNDO_HISTORY (
2768                     string_compose ("Commit Reversible Command, No commands were "
2769                                     "added to current transaction: %1",
2770                                     _current_trans->name ()));
2771                 delete _current_trans;
2772                 _current_trans = 0;
2773                 return;
2774         }
2775
2776         gettimeofday (&now, 0);
2777         _current_trans->set_timestamp (now);
2778
2779         _history.add (_current_trans);
2780         _current_trans = 0;
2781 }
2782
2783 static bool
2784 accept_all_audio_files (const string& path, void* /*arg*/)
2785 {
2786         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2787                 return false;
2788         }
2789
2790         if (!AudioFileSource::safe_audio_file_extension (path)) {
2791                 return false;
2792         }
2793
2794         return true;
2795 }
2796
2797 static bool
2798 accept_all_midi_files (const string& path, void* /*arg*/)
2799 {
2800         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2801                 return false;
2802         }
2803
2804         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2805                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2806                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2807 }
2808
2809 static bool
2810 accept_all_state_files (const string& path, void* /*arg*/)
2811 {
2812         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2813                 return false;
2814         }
2815
2816         std::string const statefile_ext (statefile_suffix);
2817         if (path.length() >= statefile_ext.length()) {
2818                 return (0 == path.compare (path.length() - statefile_ext.length(), statefile_ext.length(), statefile_ext));
2819         } else {
2820                 return false;
2821         }
2822 }
2823
2824 int
2825 Session::find_all_sources (string path, set<string>& result)
2826 {
2827         XMLTree tree;
2828         XMLNode* node;
2829
2830         if (!tree.read (path)) {
2831                 return -1;
2832         }
2833
2834         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2835                 return -2;
2836         }
2837
2838         XMLNodeList nlist;
2839         XMLNodeConstIterator niter;
2840
2841         nlist = node->children();
2842
2843         set_dirty();
2844
2845         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2846
2847                 XMLProperty const * prop;
2848
2849                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2850                         continue;
2851                 }
2852
2853                 DataType type (prop->value());
2854
2855                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2856                         continue;
2857                 }
2858
2859                 if (Glib::path_is_absolute (prop->value())) {
2860                         /* external file, ignore */
2861                         continue;
2862                 }
2863
2864                 string found_path;
2865                 bool is_new;
2866                 uint16_t chan;
2867
2868                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2869                         result.insert (found_path);
2870                 }
2871         }
2872
2873         return 0;
2874 }
2875
2876 int
2877 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2878 {
2879         vector<string> state_files;
2880         string ripped;
2881         string this_snapshot_path;
2882
2883         result.clear ();
2884
2885         ripped = _path;
2886
2887         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2888                 ripped = ripped.substr (0, ripped.length() - 1);
2889         }
2890
2891         find_files_matching_filter (state_files, ripped, accept_all_state_files, (void *) 0, true, true);
2892
2893         if (state_files.empty()) {
2894                 /* impossible! */
2895                 return 0;
2896         }
2897
2898         this_snapshot_path = Glib::build_filename (_path, legalize_for_path (_current_snapshot_name));
2899         this_snapshot_path += statefile_suffix;
2900
2901         for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
2902
2903                 cerr << "Looking at snapshot " << (*i) << " ( with this = [" << this_snapshot_path << "])\n";
2904
2905                 if (exclude_this_snapshot && *i == this_snapshot_path) {
2906                         cerr << "\texcluded\n";
2907                         continue;
2908
2909                 }
2910
2911                 if (find_all_sources (*i, result) < 0) {
2912                         return -1;
2913                 }
2914         }
2915
2916         return 0;
2917 }
2918
2919 struct RegionCounter {
2920     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2921     AudioSourceList::iterator iter;
2922     boost::shared_ptr<Region> region;
2923     uint32_t count;
2924
2925     RegionCounter() : count (0) {}
2926 };
2927
2928 int
2929 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2930 {
2931         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2932         return r.get_value_or (1);
2933 }
2934
2935 void
2936 Session::cleanup_regions ()
2937 {
2938         bool removed = false;
2939         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2940
2941         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
2942
2943                 uint32_t used = playlists->region_use_count (i->second);
2944
2945                 if (used == 0 && !i->second->automatic ()) {
2946                         boost::weak_ptr<Region> w = i->second;
2947                         ++i;
2948                         removed = true;
2949                         RegionFactory::map_remove (w);
2950                 } else {
2951                         ++i;
2952                 }
2953         }
2954
2955         if (removed) {
2956                 // re-check to remove parent references of compound regions
2957                 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
2958                         if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
2959                                 ++i;
2960                                 continue;
2961                         }
2962                         assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
2963                         if (0 == playlists->region_use_count (i->second)) {
2964                                 boost::weak_ptr<Region> w = i->second;
2965                                 ++i;
2966                                 RegionFactory::map_remove (w);
2967                         } else {
2968                                 ++i;
2969                         }
2970                 }
2971         }
2972
2973         /* dump the history list */
2974         _history.clear ();
2975
2976         save_state ("");
2977 }
2978
2979 bool
2980 Session::can_cleanup_peakfiles () const
2981 {
2982         if (deletion_in_progress()) {
2983                 return false;
2984         }
2985         if (!_writable || (_state_of_the_state & CannotSave)) {
2986                 warning << _("Cannot cleanup peak-files for read-only session.") << endmsg;
2987                 return false;
2988         }
2989         if (record_status() == Recording) {
2990                 error << _("Cannot cleanup peak-files while recording") << endmsg;
2991                 return false;
2992         }
2993         return true;
2994 }
2995
2996 int
2997 Session::cleanup_peakfiles ()
2998 {
2999         Glib::Threads::Mutex::Lock lm (peak_cleanup_lock, Glib::Threads::TRY_LOCK);
3000         if (!lm.locked()) {
3001                 return -1;
3002         }
3003
3004         assert (can_cleanup_peakfiles ());
3005         assert (!peaks_cleanup_in_progres());
3006
3007         _state_of_the_state = StateOfTheState (_state_of_the_state | PeakCleanup);
3008
3009         int timeout = 5000; // 5 seconds
3010         while (!SourceFactory::files_with_peaks.empty()) {
3011                 Glib::usleep (1000);
3012                 if (--timeout < 0) {
3013                         warning << _("Timeout waiting for peak-file creation to terminate before cleanup, please try again later.") << endmsg;
3014                         _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
3015                         return -1;
3016                 }
3017         }
3018
3019         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3020                 boost::shared_ptr<AudioSource> as;
3021                 if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
3022                         as->close_peakfile();
3023                 }
3024         }
3025
3026         PBD::clear_directory (session_directory().peak_path());
3027
3028         _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
3029
3030         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3031                 boost::shared_ptr<AudioSource> as;
3032                 if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
3033                         SourceFactory::setup_peakfile(as, true);
3034                 }
3035         }
3036         return 0;
3037 }
3038
3039 static void
3040 merge_all_sources (boost::shared_ptr<const Playlist> pl, std::set<boost::shared_ptr<Source> >* all_sources)
3041 {
3042         pl->deep_sources (*all_sources);
3043 }
3044
3045 int
3046 Session::cleanup_sources (CleanupReport& rep)
3047 {
3048         // FIXME: needs adaptation to midi
3049
3050         vector<boost::shared_ptr<Source> > dead_sources;
3051         string audio_path;
3052         string midi_path;
3053         vector<string> candidates;
3054         vector<string> unused;
3055         set<string> sources_used_by_all_snapshots;
3056         string spath;
3057         int ret = -1;
3058         string tmppath1;
3059         string tmppath2;
3060         Searchpath asp;
3061         Searchpath msp;
3062         set<boost::shared_ptr<Source> > sources_used_by_this_snapshot;
3063
3064         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
3065
3066         /* this is mostly for windows which doesn't allow file
3067          * renaming if the file is in use. But we don't special
3068          * case it because we need to know if this causes
3069          * problems, and the easiest way to notice that is to
3070          * keep it in place for all platforms.
3071          */
3072
3073         request_stop (false);
3074         _butler->summon ();
3075         _butler->wait_until_finished ();
3076
3077         /* consider deleting all unused playlists */
3078
3079         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
3080                 ret = 0;
3081                 goto out;
3082         }
3083
3084         /* sync the "all regions" property of each playlist with its current state
3085          */
3086
3087         playlists->sync_all_regions_with_regions ();
3088
3089         /* find all un-used sources */
3090
3091         rep.paths.clear ();
3092         rep.space = 0;
3093
3094         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
3095
3096                 SourceMap::iterator tmp;
3097
3098                 tmp = i;
3099                 ++tmp;
3100
3101                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
3102                    capture files.
3103                 */
3104
3105                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
3106                         dead_sources.push_back (i->second);
3107                         i->second->drop_references ();
3108                 }
3109
3110                 i = tmp;
3111         }
3112
3113         /* build a list of all the possible audio directories for the session */
3114
3115         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3116                 SessionDirectory sdir ((*i).path);
3117                 asp += sdir.sound_path();
3118         }
3119         audio_path += asp.to_string();
3120
3121
3122         /* build a list of all the possible midi directories for the session */
3123
3124         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3125                 SessionDirectory sdir ((*i).path);
3126                 msp += sdir.midi_path();
3127         }
3128         midi_path += msp.to_string();
3129
3130         find_files_matching_filter (candidates, audio_path, accept_all_audio_files, (void *) 0, true, true);
3131         find_files_matching_filter (candidates, midi_path, accept_all_midi_files, (void *) 0, true, true);
3132
3133         /* add sources from all other snapshots as "used", but don't use this
3134            snapshot because the state file on disk still references sources we
3135            may have already dropped.
3136         */
3137
3138         find_all_sources_across_snapshots (sources_used_by_all_snapshots, true);
3139
3140         /* Although the region factory has a list of all regions ever created
3141          * for this session, we're only interested in regions actually in
3142          * playlists right now. So merge all playlist regions lists together.
3143          *
3144          * This will include the playlists used within compound regions.
3145          */
3146
3147         playlists->foreach (boost::bind (merge_all_sources, _1, &sources_used_by_this_snapshot));
3148
3149         /*  add our current source list
3150          */
3151
3152         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
3153                 boost::shared_ptr<FileSource> fs;
3154                 SourceMap::iterator tmp = i;
3155                 ++tmp;
3156
3157                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) == 0) {
3158                         /* not a file */
3159                         i = tmp;
3160                         continue;
3161                 }
3162
3163                 /* this is mostly for windows which doesn't allow file
3164                  * renaming if the file is in use. But we do not special
3165                  * case it because we need to know if this causes
3166                  * problems, and the easiest way to notice that is to
3167                  * keep it in place for all platforms.
3168                  */
3169
3170                 fs->close ();
3171
3172                 if (!fs->is_stub()) {
3173
3174                         /* Note that we're checking a list of all
3175                          * sources across all snapshots with the list
3176                          * of sources used by this snapshot.
3177                          */
3178
3179                         if (sources_used_by_this_snapshot.find (i->second) != sources_used_by_this_snapshot.end()) {
3180                                 /* this source is in use by this snapshot */
3181                                 sources_used_by_all_snapshots.insert (fs->path());
3182                                 cerr << "Source from source list found in used_by_this_snapshot (" << fs->path() << ")\n";
3183                         } else {
3184                                 cerr << "Source from source list NOT found in used_by_this_snapshot (" << fs->path() << ")\n";
3185                                 /* this source is NOT in use by this snapshot
3186                                  */
3187
3188                                 /* remove all related regions from RegionFactory master list
3189                                  */
3190
3191                                 RegionFactory::remove_regions_using_source (i->second);
3192
3193                                 /* remove from our current source list
3194                                  * also. We may not remove it from
3195                                  * disk, because it may be used by
3196                                  * other snapshots, but it isn't used inside this
3197                                  * snapshot anymore, so we don't need a
3198                                  * reference to it.
3199                                  */
3200
3201                                 sources.erase (i);
3202                         }
3203                 }
3204
3205                 i = tmp;
3206         }
3207
3208         /* now check each candidate source to see if it exists in the list of
3209            sources_used_by_all_snapshots. If it doesn't, put it into "unused".
3210         */
3211
3212         cerr << "Candidates: " << candidates.size() << endl;
3213         cerr << "Used by others: " << sources_used_by_all_snapshots.size() << endl;
3214
3215         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
3216
3217                 bool used = false;
3218                 spath = *x;
3219
3220                 for (set<string>::iterator i = sources_used_by_all_snapshots.begin(); i != sources_used_by_all_snapshots.end(); ++i) {
3221
3222                         tmppath1 = canonical_path (spath);
3223                         tmppath2 = canonical_path ((*i));
3224
3225                         cerr << "\t => " << tmppath2 << endl;
3226
3227                         if (tmppath1 == tmppath2) {
3228                                 used = true;
3229                                 break;
3230                         }
3231                 }
3232
3233                 if (!used) {
3234                         unused.push_back (spath);
3235                 }
3236         }
3237
3238         cerr << "Actually unused: " << unused.size() << endl;
3239
3240         if (unused.empty()) {
3241                 /* Nothing to do */
3242                 ret = 0;
3243                 goto out;
3244         }
3245
3246         /* now try to move all unused files into the "dead" directory(ies) */
3247
3248         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3249                 GStatBuf statbuf;
3250
3251                 string newpath;
3252
3253                 /* don't move the file across filesystems, just
3254                    stick it in the `dead_dir_name' directory
3255                    on whichever filesystem it was already on.
3256                 */
3257
3258                 if ((*x).find ("/sounds/") != string::npos) {
3259
3260                         /* old school, go up 1 level */
3261
3262                         newpath = Glib::path_get_dirname (*x);      // "sounds"
3263                         newpath = Glib::path_get_dirname (newpath); // "session-name"
3264
3265                 } else {
3266
3267                         /* new school, go up 4 levels */
3268
3269                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
3270                         newpath = Glib::path_get_dirname (newpath); // "session-name"
3271                         newpath = Glib::path_get_dirname (newpath); // "interchange"
3272                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
3273                 }
3274
3275                 newpath = Glib::build_filename (newpath, dead_dir_name);
3276
3277                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
3278                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
3279                         return -1;
3280                 }
3281
3282                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
3283
3284                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3285
3286                         /* the new path already exists, try versioning */
3287
3288                         char buf[PATH_MAX+1];
3289                         int version = 1;
3290                         string newpath_v;
3291
3292                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3293                         newpath_v = buf;
3294
3295                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
3296                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3297                                 newpath_v = buf;
3298                         }
3299
3300                         if (version == 999) {
3301                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3302                                                   newpath)
3303                                       << endmsg;
3304                         } else {
3305                                 newpath = newpath_v;
3306                         }
3307
3308                 }
3309
3310                 if ((g_stat ((*x).c_str(), &statbuf) != 0) || (::g_rename ((*x).c_str(), newpath.c_str()) != 0)) {
3311                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"), (*x),
3312                                                  newpath, g_strerror (errno)) << endmsg;
3313                         continue;
3314                 }
3315
3316                 /* see if there an easy to find peakfile for this file, and remove it.
3317                  */
3318
3319                 string base = Glib::path_get_basename (*x);
3320                 base += "%A"; /* this is what we add for the channel suffix of all native files,
3321                                  or for the first channel of embedded files. it will miss
3322                                  some peakfiles for other channels
3323                                */
3324                 string peakpath = construct_peak_filepath (base);
3325
3326                 if (Glib::file_test (peakpath.c_str (), Glib::FILE_TEST_EXISTS)) {
3327                         if (::g_unlink (peakpath.c_str ()) != 0) {
3328                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"), peakpath, _path,
3329                                                          g_strerror (errno)) << endmsg;
3330                                 /* try to back out */
3331                                 ::g_rename (newpath.c_str (), _path.c_str ());
3332                                 goto out;
3333                         }
3334                 }
3335
3336                 rep.paths.push_back (*x);
3337                 rep.space += statbuf.st_size;
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 static void set_progress (Progress* p, size_t n, size_t t)
4936 {
4937         p->set_progress (float (n) / float(t));
4938 }
4939
4940 int
4941 Session::archive_session (const std::string& dest, const std::string& name, ArchiveEncode compress_audio, Progress* progress)
4942 {
4943         if (dest.empty () || name.empty ()) {
4944                 return -1;
4945         }
4946
4947         /* save current values */
4948         bool was_dirty = dirty ();
4949         string old_path = _path;
4950         string old_name = _name;
4951         string old_snapshot = _current_snapshot_name;
4952         string old_sd = _session_dir->root_path();
4953         string old_config_search_path[DataType::num_types];
4954         old_config_search_path[DataType::AUDIO] = config.get_audio_search_path ();
4955         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();
4956
4957         /* ensure that session-path is included in search-path */
4958         bool ok = false;
4959         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4960                 if ((*sd).path == old_path) {
4961                         ok = true;
4962                 }
4963         }
4964         if (!ok) {
4965                 return -1;
4966         }
4967
4968         /* create temporary dir to save session to */
4969 #ifdef PLATFORM_WINDOWS
4970         char tmp[256] = "C:\\TEMP\\";
4971         GetTempPath (sizeof (tmp), tmp);
4972 #else
4973         char const* tmp = getenv("TMPDIR");
4974         if (!tmp) {
4975                 tmp = "/tmp/";
4976         }
4977 #endif
4978         if ((strlen (tmp) + 21) > 1024) {
4979                 return -1;
4980         }
4981
4982         char tmptpl[1024];
4983         strcpy (tmptpl, tmp);
4984         strcat (tmptpl, "ardourarchive-XXXXXX");
4985         char*  tmpdir = g_mkdtemp (tmptpl);
4986
4987         if (!tmpdir) {
4988                 return -1;
4989         }
4990
4991         std::string to_dir = std::string (tmpdir);
4992
4993         /* switch session directory temporarily */
4994         (*_session_dir) = to_dir;
4995
4996         if (!_session_dir->create()) {
4997                 (*_session_dir) = old_sd;
4998                 remove_directory (to_dir);
4999                 return -1;
5000         }
5001
5002         /* prepare archive */
5003         string archive = Glib::build_filename (dest, name + ".tar.xz");
5004
5005 #ifndef NDEBUG
5006         cout << "ARCHIVE: " << archive << "\n";
5007 #endif
5008
5009         PBD::ScopedConnectionList progress_connection;
5010         PBD::FileArchive ar (archive);
5011         if (progress) {
5012                 ar.progress.connect_same_thread (progress_connection, boost::bind (&set_progress, progress, _1, _2));
5013         }
5014
5015         /* collect files to archive */
5016         std::map<string,string> filemap;
5017
5018         vector<string> do_not_copy_extensions;
5019         do_not_copy_extensions.push_back (statefile_suffix);
5020         do_not_copy_extensions.push_back (pending_suffix);
5021         do_not_copy_extensions.push_back (backup_suffix);
5022         do_not_copy_extensions.push_back (temp_suffix);
5023         do_not_copy_extensions.push_back (history_suffix);
5024
5025         vector<string> blacklist_dirs;
5026         blacklist_dirs.push_back (string (peak_dir_name) + G_DIR_SEPARATOR);
5027         blacklist_dirs.push_back (string (analysis_dir_name) + G_DIR_SEPARATOR);
5028         blacklist_dirs.push_back (string (dead_dir_name) + G_DIR_SEPARATOR);
5029         blacklist_dirs.push_back (string (export_dir_name) + G_DIR_SEPARATOR);
5030         blacklist_dirs.push_back (string (externals_dir_name) + G_DIR_SEPARATOR);
5031         blacklist_dirs.push_back (string (plugins_dir_name) + G_DIR_SEPARATOR);
5032
5033         std::map<boost::shared_ptr<AudioFileSource>, std::string> orig_sources;
5034
5035         if (compress_audio != NO_ENCODE) {
5036                 Glib::Threads::Mutex::Lock lm (source_lock);
5037                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
5038                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (i->second);
5039                         if (!afs) {
5040                                 continue;
5041                         }
5042                         if (afs->readable_length () == 0) {
5043                                 continue;
5044                         }
5045
5046                         orig_sources[afs] = afs->path();
5047
5048                         std::string new_path = make_new_media_path (afs->path (), to_dir, name);
5049                         new_path = Glib::build_filename (Glib::path_get_dirname (new_path), PBD::basename_nosuffix (new_path) + ".flac");
5050                         g_mkdir_with_parents (Glib::path_get_dirname (new_path).c_str (), 0755);
5051
5052                         // TODO: set progress to "encoding", use total readable_length () somehow.
5053                         // .. or a custom progress report like save-as.
5054                         try {
5055                                 SndFileSource* ns = new SndFileSource (*this, *(afs.get()), new_path, compress_audio == FLAC_16BIT, NULL /*progress*/);
5056                                 afs->replace_file (new_path);
5057                                 delete ns;
5058                         } catch (...) {
5059                                 cerr << "failed to encode " << afs->path() << " to " << new_path << "\n";
5060                         }
5061                 }
5062         }
5063
5064         /* index files relevant for this session */
5065         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
5066                 vector<string> files;
5067
5068                 size_t prefix_len = (*sd).path.size();
5069                 if (prefix_len > 0 && (*sd).path.at (prefix_len - 1) != G_DIR_SEPARATOR) {
5070                         ++prefix_len;
5071                 }
5072
5073                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
5074
5075                 static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
5076                 static const std::string videofile_dir_string = string (video_dir_name) + G_DIR_SEPARATOR;
5077                 static const std::string midifile_dir_string  = string (midi_dir_name)  + G_DIR_SEPARATOR;
5078
5079                 for (vector<string>::const_iterator i = files.begin (); i != files.end (); ++i) {
5080                         std::string from = *i;
5081
5082 #ifdef __APPLE__
5083                         string filename = Glib::path_get_basename (from);
5084                         std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
5085                         if (filename == ".DS_STORE") {
5086                                 continue;
5087                         }
5088 #endif
5089
5090                         if (from.find (audiofile_dir_string) != string::npos) {
5091                                 if (!compress_audio != NO_ENCODE) {
5092                                         filemap[from] = make_new_media_path (from, name, name);
5093                                 }
5094                         } else if (from.find (midifile_dir_string) != string::npos) {
5095                                 filemap[from] = make_new_media_path (from, name, name);
5096                         } else if (from.find (videofile_dir_string) != string::npos) {
5097                                 filemap[from] = make_new_media_path (from, name, name);
5098                         } else {
5099                                 bool do_copy = true;
5100                                 for (vector<string>::iterator v = blacklist_dirs.begin(); v != blacklist_dirs.end(); ++v) {
5101                                         if (from.find (*v) != string::npos) {
5102                                                 do_copy = false;
5103                                                 break;
5104                                         }
5105                                 }
5106                                 for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
5107                                         if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
5108                                                 do_copy = false;
5109                                                 break;
5110                                         }
5111                                 }
5112
5113                                 if (do_copy) {
5114                                         filemap[from] = name + G_DIR_SEPARATOR + from.substr (prefix_len);
5115                                 }
5116                         }
5117                 }
5118         }
5119
5120         /* include external media */
5121         {
5122                 Glib::Threads::Mutex::Lock lm (source_lock);
5123                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
5124                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
5125                         if (!fs) {
5126                                 continue;
5127                         }
5128                         if (fs->within_session()) {
5129                                 continue;
5130                         }
5131
5132                         if (fs->type () != DataType::AUDIO) {
5133                                 continue;
5134                         }
5135
5136                         std::string from = fs->path();
5137                         filemap[from] = make_new_media_path (from, name, name);
5138                         remove_dir_from_search_path (Glib::path_get_dirname (from), DataType::AUDIO);
5139                 }
5140         }
5141
5142         /* write session file */
5143         _path = to_dir;
5144         g_mkdir_with_parents (externals_dir ().c_str (), 0755);
5145
5146         PBD::Unwinder<bool> uw (LV2Plugin::force_state_save, true);
5147         save_state (name);
5148         save_default_options ();
5149
5150         size_t prefix_len = _path.size();
5151         if (prefix_len > 0 && _path.at (prefix_len - 1) != G_DIR_SEPARATOR) {
5152                 ++prefix_len;
5153         }
5154
5155         /* collect session-state files */
5156         vector<string> files;
5157         do_not_copy_extensions.clear ();
5158         do_not_copy_extensions.push_back (history_suffix);
5159
5160         blacklist_dirs.clear ();
5161         blacklist_dirs.push_back (string (externals_dir_name) + G_DIR_SEPARATOR);
5162
5163         find_files_matching_filter (files, to_dir, accept_all_files, 0, false, true, true);
5164         for (vector<string>::const_iterator i = files.begin (); i != files.end (); ++i) {
5165                 std::string from = *i;
5166                 bool do_copy = true;
5167                 for (vector<string>::iterator v = blacklist_dirs.begin(); v != blacklist_dirs.end(); ++v) {
5168                         if (from.find (*v) != string::npos) {
5169                                 do_copy = false;
5170                                 break;
5171                         }
5172                 }
5173                 for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
5174                         if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
5175                                 do_copy = false;
5176                                 break;
5177                         }
5178                 }
5179                 if (do_copy) {
5180                         filemap[from] = name + G_DIR_SEPARATOR + from.substr (prefix_len);
5181                 }
5182         }
5183
5184         /* restore original values */
5185         _path = old_path;
5186         _name = old_name;
5187         set_snapshot_name (old_snapshot);
5188         (*_session_dir) = old_sd;
5189         if (was_dirty) {
5190                 set_dirty ();
5191         }
5192         config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
5193         config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
5194
5195         for (std::map<boost::shared_ptr<AudioFileSource>, std::string>::iterator i = orig_sources.begin (); i != orig_sources.end (); ++i) {
5196                 i->first->replace_file (i->second);
5197         }
5198
5199 #ifndef NDEBUG
5200         /* done  -- now zip */
5201         for (std::map<string,string>::const_iterator i = filemap.begin(); i != filemap.end (); ++i) {
5202                 cout << "archive " << (*i).first << " as " << (*i).second << "\n";
5203         }
5204 #endif
5205
5206         int rv = ar.create (filemap);
5207         remove_directory (to_dir);
5208
5209         return rv;
5210 }
5211
5212 void
5213 Session::undo (uint32_t n)
5214 {
5215         if (actively_recording()) {
5216                 return;
5217         }
5218
5219         _history.undo (n);
5220 }
5221
5222 void
5223 Session::redo (uint32_t n)
5224 {
5225         if (actively_recording()) {
5226                 return;
5227         }
5228
5229         _history.redo (n);
5230 }