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