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