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