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