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