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