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