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