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