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