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