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