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