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