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