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