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