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