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