lock processor list and reconfigure processors after moving meter or control outs...
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2002 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 #define __STDC_FORMAT_MACROS 1
26 #include <stdint.h>
27
28 #include <algorithm>
29 #include <fstream>
30 #include <string>
31 #include <cerrno>
32
33 #include <sigc++/bind.h>
34
35 #include <cstdio> /* snprintf(3) ... grrr */
36 #include <cmath>
37 #include <unistd.h>
38 #include <sys/stat.h>
39 #include <climits>
40 #include <fcntl.h>
41 #include <poll.h>
42 #include <signal.h>
43 #include <sys/mman.h>
44 #include <sys/time.h>
45 #include <dirent.h>
46
47 #ifdef HAVE_SYS_VFS_H
48 #include <sys/vfs.h>
49 #else
50 #include <sys/param.h>
51 #include <sys/mount.h>
52 #endif
53
54 #include <glibmm.h>
55 #include <glibmm/thread.h>
56
57 #include "midi++/mmc.h"
58 #include "midi++/port.h"
59
60 #include "pbd/error.h"
61 #include "pbd/pathscanner.h"
62 #include "pbd/pthread_utils.h"
63 #include "pbd/search_path.h"
64 #include "pbd/stacktrace.h"
65
66 #include "ardour/audio_diskstream.h"
67 #include "ardour/audio_track.h"
68 #include "ardour/audioengine.h"
69 #include "ardour/audiofilesource.h"
70 #include "ardour/audioplaylist.h"
71 #include "ardour/audioregion.h"
72 #include "ardour/auditioner.h"
73 #include "ardour/buffer.h"
74 #include "ardour/butler.h"
75 #include "ardour/configuration.h"
76 #include "ardour/control_protocol_manager.h"
77 #include "ardour/crossfade.h"
78 #include "ardour/cycle_timer.h"
79 #include "ardour/directory_names.h"
80 #include "ardour/filename_extensions.h"
81 #include "ardour/io_processor.h"
82 #include "ardour/location.h"
83 #include "ardour/midi_diskstream.h"
84 #include "ardour/midi_patch_manager.h"
85 #include "ardour/midi_playlist.h"
86 #include "ardour/midi_region.h"
87 #include "ardour/midi_source.h"
88 #include "ardour/midi_track.h"
89 #include "ardour/named_selection.h"
90 #include "ardour/playlist_factory.h"
91 #include "ardour/processor.h"
92 #include "ardour/region_factory.h"
93 #include "ardour/route_group.h"
94 #include "ardour/send.h"
95 #include "ardour/session.h"
96 #include "ardour/session_directory.h"
97 #include "ardour/session_metadata.h"
98 #include "ardour/session_state_utils.h"
99 #include "ardour/session_utils.h"
100 #include "ardour/silentfilesource.h"
101 #include "ardour/slave.h"
102 #include "ardour/smf_source.h"
103 #include "ardour/sndfile_helpers.h"
104 #include "ardour/sndfilesource.h"
105 #include "ardour/source_factory.h"
106 #include "ardour/template_utils.h"
107 #include "ardour/tempo.h"
108 #include "ardour/ticker.h"
109 #include "ardour/user_bundle.h"
110 #include "ardour/utils.h"
111 #include "ardour/utils.h"
112 #include "ardour/version.h"
113
114 #include "control_protocol/control_protocol.h"
115
116 #include "i18n.h"
117 #include <locale.h>
118
119 using namespace std;
120 using namespace ARDOUR;
121 using namespace PBD;
122
123 void
124 Session::first_stage_init (string fullpath, string snapshot_name)
125 {
126         if (fullpath.length() == 0) {
127                 destroy ();
128                 throw failed_constructor();
129         }
130
131         char buf[PATH_MAX+1];
132         if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
133                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
134                 destroy ();
135                 throw failed_constructor();
136         }
137
138         _path = string(buf);
139
140         if (_path[_path.length()-1] != '/') {
141                 _path += '/';
142         }
143
144         if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
145                 cerr << "Session non-writable based on " << _path << endl;
146                 _writable = false;
147         } else {
148                 cerr << "Session writable based on " << _path << endl;
149                 _writable = true;
150         }
151
152         /* these two are just provisional settings. set_state()
153            will likely override them.
154         */
155
156         _name = _current_snapshot_name = snapshot_name;
157
158         set_history_depth (Config->get_history_depth());
159
160         _current_frame_rate = _engine.frame_rate ();
161         _nominal_frame_rate = _current_frame_rate;
162         _base_frame_rate = _current_frame_rate;
163
164         _tempo_map = new TempoMap (_current_frame_rate);
165         _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
166
167
168         _non_soloed_outs_muted = false;
169         _listen_cnt = 0;
170         g_atomic_int_set (&processing_prohibited, 0);
171         _transport_speed = 0;
172         _last_transport_speed = 0;
173         _target_transport_speed = 0;
174         auto_play_legal = false;
175         transport_sub_state = 0;
176         _transport_frame = 0;
177         _requested_return_frame = -1;
178         end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
179         start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
180         g_atomic_int_set (&_record_status, Disabled);
181         loop_changing = false;
182         play_loop = false;
183         have_looped = false;
184         _last_roll_location = 0;
185         _last_record_location = 0;
186         pending_locate_frame = 0;
187         pending_locate_roll = false;
188         pending_locate_flush = false;
189         state_was_pending = false;
190         set_next_event ();
191         outbound_mtc_timecode_frame = 0;
192         next_quarter_frame_to_send = -1;
193         current_block_size = 0;
194         solo_update_disabled = false;
195         _have_captured = false;
196         _worst_output_latency = 0;
197         _worst_input_latency = 0;
198         _worst_track_latency = 0;
199         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
200         _was_seamless = Config->get_seamless_loop ();
201         _slave = 0;
202         session_send_mmc = false;
203         session_send_mtc = false;
204         g_atomic_int_set (&_playback_load, 100);
205         g_atomic_int_set (&_capture_load, 100);
206         g_atomic_int_set (&_playback_load_min, 100);
207         g_atomic_int_set (&_capture_load_min, 100);
208         _play_range = false;
209         _exporting = false;
210         _exporting_realtime = false;
211         _gain_automation_buffer = 0;
212         _pan_automation_buffer = 0;
213         _npan_buffers = 0;
214         pending_abort = false;
215         destructive_index = 0;
216         first_file_data_format_reset = true;
217         first_file_header_format_reset = true;
218         post_export_sync = false;
219         //midi_thread = (pthread_t) 0;
220
221         AudioDiskstream::allocate_working_buffers();
222
223         /* default short fade = 15ms */
224
225         Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
226         SndFileSource::setup_standard_crossfades (*this, frame_rate());
227
228         last_mmc_step.tv_sec = 0;
229         last_mmc_step.tv_usec = 0;
230         step_speed = 0.0;
231
232         /* click sounds are unset by default, which causes us to internal
233            waveforms for clicks.
234         */
235
236         click_length = 0;
237         click_emphasis_length = 0;
238         _clicking = false;
239
240         process_function = &Session::process_with_events;
241
242         if (config.get_use_video_sync()) {
243                 waiting_for_sync_offset = true;
244         } else {
245                 waiting_for_sync_offset = false;
246         }
247
248         last_timecode_when = 0;
249         _timecode_offset = 0;
250         _timecode_offset_negative = true;
251         last_timecode_valid = false;
252
253         sync_time_vars ();
254
255         last_rr_session_dir = session_dirs.begin();
256         refresh_disk_space ();
257
258         // set_default_fade (0.2, 5.0); /* steepness, millisecs */
259
260         /* slave stuff */
261
262         average_slave_delta = 1800; // !!! why 1800 ????
263         have_first_delta_accumulator = false;
264         delta_accumulator_cnt = 0;
265         slave_state = Stopped;
266
267         _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
268
269         /* These are all static "per-class" signals */
270
271         RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
272         SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
273         PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
274         Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
275         NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
276         AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
277
278         Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
279
280         IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
281
282         /* stop IO objects from doing stuff until we're ready for them */
283
284         Delivery::disable_panners ();
285         IO::disable_connecting ();
286 }
287
288 int
289 Session::second_stage_init (bool new_session)
290 {
291         AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
292
293         if (!new_session) {
294                 if (load_state (_current_snapshot_name)) {
295                         return -1;
296                 }
297                 remove_empty_sounds ();
298         }
299
300         if (_butler->start_thread()) {
301                 return -1;
302         }
303
304         if (start_midi_thread ()) {
305                 return -1;
306         }
307
308         // set_state() will call setup_raid_path(), but if it's a new session we need
309         // to call setup_raid_path() here.
310
311         if (state_tree) {
312                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
313                         return -1;
314                 }
315         } else {
316                 setup_raid_path(_path);
317         }
318
319         /* we can't save till after ::when_engine_running() is called,
320            because otherwise we save state with no connections made.
321            therefore, we reset _state_of_the_state because ::set_state()
322            will have cleared it.
323
324            we also have to include Loading so that any events that get
325            generated between here and the end of ::when_engine_running()
326            will be processed directly rather than queued.
327         */
328
329         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
330
331
332         _locations.changed.connect (mem_fun (this, &Session::locations_changed));
333         _locations.added.connect (mem_fun (this, &Session::locations_added));
334         setup_click_sounds (0);
335         setup_midi_control ();
336
337         /* Pay attention ... */
338
339         _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
340         _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
341
342         try {
343                 when_engine_running();
344         }
345
346         /* handle this one in a different way than all others, so that its clear what happened */
347
348         catch (AudioEngine::PortRegistrationFailure& err) {
349                 error << err.what() << endmsg;
350                 return -1;
351         }
352
353         catch (...) {
354                 return -1;
355         }
356
357         BootMessage (_("Reset Remote Controls"));
358
359         send_full_time_code (0);
360         _engine.transport_locate (0);
361         deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
362         deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
363
364         MidiClockTicker::instance().set_session(*this);
365         MIDI::Name::MidiPatchManager::instance().set_session(*this);
366
367         /* initial program change will be delivered later; see ::config_changed() */
368
369         BootMessage (_("Reset Control Protocols"));
370
371         ControlProtocolManager::instance().set_session (*this);
372
373         config.set_end_marker_is_free (new_session);
374
375         _state_of_the_state = Clean;
376
377         DirtyChanged (); /* EMIT SIGNAL */
378
379         if (state_was_pending) {
380                 save_state (_current_snapshot_name);
381                 remove_pending_capture_state ();
382                 state_was_pending = false;
383         }
384
385         BootMessage (_("Session loading complete"));
386
387         return 0;
388 }
389
390 string
391 Session::raid_path () const
392 {
393         SearchPath raid_search_path;
394
395         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396                 raid_search_path += sys::path((*i).path);
397         }
398
399         return raid_search_path.to_string ();
400 }
401
402 void
403 Session::setup_raid_path (string path)
404 {
405         if (path.empty()) {
406                 return;
407         }
408
409         space_and_path sp;
410         string fspath;
411
412         session_dirs.clear ();
413
414         SearchPath search_path(path);
415         SearchPath sound_search_path;
416         SearchPath midi_search_path;
417
418         for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
419                 sp.path = (*i).to_string ();
420                 sp.blocks = 0; // not needed
421                 session_dirs.push_back (sp);
422
423                 SessionDirectory sdir(sp.path);
424
425                 sound_search_path += sdir.sound_path ();
426                 midi_search_path += sdir.midi_path ();
427         }
428
429         // set the search path for each data type
430         FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
431         SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
432
433         // reset the round-robin soundfile path thingie
434         last_rr_session_dir = session_dirs.begin();
435 }
436
437 int
438 Session::ensure_subdirs ()
439 {
440         string dir;
441
442         dir = session_directory().peak_path().to_string();
443
444         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
445                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
446                 return -1;
447         }
448
449         dir = session_directory().sound_path().to_string();
450
451         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453                 return -1;
454         }
455
456         dir = session_directory().midi_path().to_string();
457
458         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460                 return -1;
461         }
462
463         dir = session_directory().dead_sound_path().to_string();
464
465         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467                 return -1;
468         }
469
470         dir = session_directory().export_path().to_string();
471
472         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474                 return -1;
475         }
476
477         dir = analysis_dir ();
478
479         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481                 return -1;
482         }
483
484         return 0;
485 }
486
487 int
488 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
489 {
490
491         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
492                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
493                 return -1;
494         }
495
496         if (ensure_subdirs ()) {
497                 return -1;
498         }
499
500         /* check new_session so we don't overwrite an existing one */
501
502         if (!mix_template.empty()) {
503                 std::string in_path = mix_template;
504
505                 ifstream in(in_path.c_str());
506
507                 if (in){
508                         string out_path = _path;
509                         out_path += _name;
510                         out_path += statefile_suffix;
511
512                         ofstream out(out_path.c_str());
513
514                         if (out){
515                                 out << in.rdbuf();
516
517                                 // okay, session is set up.  Treat like normal saved
518                                 // session from now on.
519
520                                 new_session = false;
521                                 return 0;
522
523                         } else {
524                                 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
525                                         << endmsg;
526                                 return -1;
527                         }
528
529                 } else {
530                         error << string_compose (_("Could not open mix template %1 for reading"), in_path)
531                                 << endmsg;
532                         return -1;
533                 }
534
535         }
536
537         /* Instantiate metadata */
538
539         _metadata = new SessionMetadata ();
540
541         /* set initial start + end point */
542
543         start_location->set_end (0);
544         _locations.add (start_location);
545
546         end_location->set_end (initial_length);
547         _locations.add (end_location);
548
549         _state_of_the_state = Clean;
550
551         save_state ("");
552
553         return 0;
554 }
555
556
557 int
558 Session::load_diskstreams (const XMLNode& node)
559 {
560         XMLNodeList          clist;
561         XMLNodeConstIterator citer;
562
563         clist = node.children();
564
565         for (citer = clist.begin(); citer != clist.end(); ++citer) {
566
567                 try {
568                         /* diskstreams added automatically by DiskstreamCreated handler */
569                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
570                                 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
571                                 add_diskstream (dstream);
572                         } else if ((*citer)->name() == "MidiDiskstream") {
573                                 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
574                                 add_diskstream (dstream);
575                         } else {
576                                 error << _("Session: unknown diskstream type in XML") << endmsg;
577                         }
578                 }
579
580                 catch (failed_constructor& err) {
581                         error << _("Session: could not load diskstream via XML state") << endmsg;
582                         return -1;
583                 }
584         }
585
586         return 0;
587 }
588
589 void
590 Session::maybe_write_autosave()
591 {
592         if (dirty() && record_status() != Recording) {
593                 save_state("", true);
594         }
595 }
596
597 void
598 Session::remove_pending_capture_state ()
599 {
600         sys::path pending_state_file_path(_session_dir->root_path());
601
602         pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
603
604         try
605         {
606                 sys::remove (pending_state_file_path);
607         }
608         catch(sys::filesystem_error& ex)
609         {
610                 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
611                                 pending_state_file_path.to_string(), ex.what()) << endmsg;
612         }
613 }
614
615 /** Rename a state file.
616  * @param snapshot_name Snapshot name.
617  */
618 void
619 Session::rename_state (string old_name, string new_name)
620 {
621         if (old_name == _current_snapshot_name || old_name == _name) {
622                 /* refuse to rename the current snapshot or the "main" one */
623                 return;
624         }
625
626         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
627         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
628
629         const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
630         const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
631
632         try
633         {
634                 sys::rename (old_xml_path, new_xml_path);
635         }
636         catch (const sys::filesystem_error& err)
637         {
638                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
639                                 old_name, new_name, err.what()) << endmsg;
640         }
641 }
642
643 /** Remove a state file.
644  * @param snapshot_name Snapshot name.
645  */
646 void
647 Session::remove_state (string snapshot_name)
648 {
649         if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
650                 // refuse to remove the current snapshot or the "main" one
651                 return;
652         }
653
654         sys::path xml_path(_session_dir->root_path());
655
656         xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
657
658         if (!create_backup_file (xml_path)) {
659                 // don't remove it if a backup can't be made
660                 // create_backup_file will log the error.
661                 return;
662         }
663
664         // and delete it
665         sys::remove (xml_path);
666 }
667
668 int
669 Session::save_state (string snapshot_name, bool pending)
670 {
671         XMLTree tree;
672         sys::path xml_path(_session_dir->root_path());
673
674         if (!_writable || (_state_of_the_state & CannotSave)) {
675                 return 1;
676         }
677
678         if (!_engine.connected ()) {
679                 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
680                       << endmsg;
681                 return 1;
682         }
683
684         /* tell sources we're saving first, in case they write out to a new file
685          * which should be saved with the state rather than the old one */
686         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
687                 i->second->session_saved();
688
689         tree.set_root (&get_state());
690
691         if (snapshot_name.empty()) {
692                 snapshot_name = _current_snapshot_name;
693         }
694
695         if (!pending) {
696
697                 /* proper save: use statefile_suffix (.ardour in English) */
698
699                 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
700
701                 /* make a backup copy of the old file */
702
703                 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
704                         // create_backup_file will log the error
705                         return -1;
706                 }
707
708         } else {
709
710                 /* pending save: use pending_suffix (.pending in English) */
711                 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
712         }
713
714         sys::path tmp_path(_session_dir->root_path());
715
716         tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
717
718         // cerr << "actually writing state to " << xml_path.to_string() << endl;
719
720         if (!tree.write (tmp_path.to_string())) {
721                 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
722                 sys::remove (tmp_path);
723                 return -1;
724
725         } else {
726
727                 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
728                         error << string_compose (_("could not rename temporary session file %1 to %2"),
729                                         tmp_path.to_string(), xml_path.to_string()) << endmsg;
730                         sys::remove (tmp_path);
731                         return -1;
732                 }
733         }
734
735         if (!pending) {
736
737                 save_history (snapshot_name);
738
739                 bool was_dirty = dirty();
740
741                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
742
743                 if (was_dirty) {
744                         DirtyChanged (); /* EMIT SIGNAL */
745                 }
746
747                 StateSaved (snapshot_name); /* EMIT SIGNAL */
748         }
749
750         return 0;
751 }
752
753 int
754 Session::restore_state (string snapshot_name)
755 {
756         if (load_state (snapshot_name) == 0) {
757                 set_state (*state_tree->root(), Stateful::loading_state_version);
758         }
759
760         return 0;
761 }
762
763 int
764 Session::load_state (string snapshot_name)
765 {
766         delete state_tree;
767         state_tree = 0;
768
769         state_was_pending = false;
770
771         /* check for leftover pending state from a crashed capture attempt */
772
773         sys::path xmlpath(_session_dir->root_path());
774         xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
775
776         if (sys::exists (xmlpath)) {
777
778                 /* there is pending state from a crashed capture attempt */
779
780                 if (AskAboutPendingState()) {
781                         state_was_pending = true;
782                 }
783         }
784
785         if (!state_was_pending) {
786                 xmlpath = _session_dir->root_path();
787                 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
788         }
789
790         if (!sys::exists (xmlpath)) {
791                 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
792                 return 1;
793         }
794
795         state_tree = new XMLTree;
796
797         set_dirty();
798
799         /* writable() really reflects the whole folder, but if for any
800            reason the session state file can't be written to, still
801            make us unwritable.
802         */
803
804         if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
805                 _writable = false;
806         }
807
808         if (!state_tree->read (xmlpath.to_string())) {
809                 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
810                 delete state_tree;
811                 state_tree = 0;
812                 return -1;
813         }
814
815         XMLNode& root (*state_tree->root());
816
817         if (root.name() != X_("Session")) {
818                 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
819                 delete state_tree;
820                 state_tree = 0;
821                 return -1;
822         }
823
824         const XMLProperty* prop;
825
826         if ((prop = root.property ("version")) == 0) {
827                 /* no version implies very old version of Ardour */
828                 Stateful::loading_state_version = 1000;
829         } else {
830                 int major;
831                 int minor;
832                 int micro;
833
834                 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, &micro);
835                 Stateful::loading_state_version = (major * 1000) + minor;
836         }
837                 
838         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
839
840                 sys::path backup_path(_session_dir->root_path());
841
842                 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
843
844                 // only create a backup once
845                 if (sys::exists (backup_path)) {
846                         return 0;
847                 }
848
849                 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
850                                         xmlpath.to_string(), backup_path.to_string())
851                      << endmsg;
852
853                 try
854                 {
855                         sys::copy_file (xmlpath, backup_path);
856                 }
857                 catch(sys::filesystem_error& ex)
858                 {
859                         error << string_compose (_("Unable to make backup of state file %1 (%2)"),
860                                         xmlpath.to_string(), ex.what())
861                                 << endmsg;
862                         return -1;
863                 }
864         }
865
866         return 0;
867 }
868
869 int
870 Session::load_options (const XMLNode& node)
871 {
872         LocaleGuard lg (X_("POSIX"));
873         config.set_variables (node);
874         return 0;
875 }
876
877 XMLNode&
878 Session::get_state()
879 {
880         return state(true);
881 }
882
883 XMLNode&
884 Session::get_template()
885 {
886         /* if we don't disable rec-enable, diskstreams
887            will believe they need to store their capture
888            sources in their state node.
889         */
890
891         disable_record (false);
892
893         return state(false);
894 }
895
896 XMLNode&
897 Session::state(bool full_state)
898 {
899         XMLNode* node = new XMLNode("Session");
900         XMLNode* child;
901
902         // store libardour version, just in case
903         char buf[16];
904         snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
905         node->add_property("version", string(buf));
906
907         /* store configuration settings */
908
909         if (full_state) {
910
911                 node->add_property ("name", _name);
912                 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
913                 node->add_property ("sample-rate", buf);
914
915                 if (session_dirs.size() > 1) {
916
917                         string p;
918
919                         vector<space_and_path>::iterator i = session_dirs.begin();
920                         vector<space_and_path>::iterator next;
921
922                         ++i; /* skip the first one */
923                         next = i;
924                         ++next;
925
926                         while (i != session_dirs.end()) {
927
928                                 p += (*i).path;
929
930                                 if (next != session_dirs.end()) {
931                                         p += ':';
932                                 } else {
933                                         break;
934                                 }
935
936                                 ++next;
937                                 ++i;
938                         }
939
940                         child = node->add_child ("Path");
941                         child->add_content (p);
942                 }
943         }
944
945         /* save the ID counter */
946
947         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
948         node->add_property ("id-counter", buf);
949
950         /* various options */
951
952         node->add_child_nocopy (config.get_variables ());
953
954         node->add_child_nocopy (_metadata->get_state());
955
956         child = node->add_child ("Sources");
957
958         if (full_state) {
959                 Glib::Mutex::Lock sl (source_lock);
960
961                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
962
963                         /* Don't save information about non-destructive file sources that are empty */
964                         /* FIXME: MIDI breaks if this is made FileSource like it should be... */
965
966                         boost::shared_ptr<AudioFileSource> fs;
967                         if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
968                                 if (!fs->destructive()) {
969                                         if (fs->length(fs->timeline_position()) == 0) {
970                                                 continue;
971                                         }
972                                 }
973                         }
974
975                         child->add_child_nocopy (siter->second->get_state());
976                 }
977         }
978
979         child = node->add_child ("Regions");
980
981         if (full_state) {
982                 Glib::Mutex::Lock rl (region_lock);
983
984                 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
985
986                         /* only store regions not attached to playlists */
987
988                         if (i->second->playlist() == 0) {
989                                 child->add_child_nocopy (i->second->state (true));
990                         }
991                 }
992         }
993
994         child = node->add_child ("DiskStreams");
995
996         {
997                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
998                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
999                         if (!(*i)->hidden()) {
1000                                 child->add_child_nocopy ((*i)->get_state());
1001                         }
1002                 }
1003         }
1004
1005         if (full_state) {
1006                 node->add_child_nocopy (_locations.get_state());
1007         } else {
1008                 // for a template, just create a new Locations, populate it
1009                 // with the default start and end, and get the state for that.
1010                 Locations loc;
1011                 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1012                 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1013                 start->set_end(0);
1014                 loc.add (start);
1015                 end->set_end(compute_initial_length());
1016                 loc.add (end);
1017                 node->add_child_nocopy (loc.get_state());
1018         }
1019
1020         child = node->add_child ("Bundles");
1021         {
1022                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1023                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1024                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1025                         if (b) {
1026                                 child->add_child_nocopy (b->get_state());
1027                         }
1028                 }
1029         }
1030
1031         child = node->add_child ("Routes");
1032         {
1033                 boost::shared_ptr<RouteList> r = routes.reader ();
1034
1035                 RoutePublicOrderSorter cmp;
1036                 RouteList public_order (*r);
1037                 public_order.sort (cmp);
1038
1039                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1040                         if (!(*i)->is_hidden()) {
1041                                 if (full_state) {
1042                                         child->add_child_nocopy ((*i)->get_state());
1043                                 } else {
1044                                         child->add_child_nocopy ((*i)->get_template());
1045                                 }
1046                         }
1047                 }
1048         }
1049
1050
1051         child = node->add_child ("RouteGroups");
1052         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1053                 child->add_child_nocopy ((*i)->get_state());
1054         }
1055
1056         child = node->add_child ("Playlists");
1057         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1058                 if (!(*i)->hidden()) {
1059                         if (!(*i)->empty()) {
1060                                 if (full_state) {
1061                                         child->add_child_nocopy ((*i)->get_state());
1062                                 } else {
1063                                         child->add_child_nocopy ((*i)->get_template());
1064                                 }
1065                         }
1066                 }
1067         }
1068
1069         child = node->add_child ("UnusedPlaylists");
1070         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1071                 if (!(*i)->hidden()) {
1072                         if (!(*i)->empty()) {
1073                                 if (full_state) {
1074                                         child->add_child_nocopy ((*i)->get_state());
1075                                 } else {
1076                                         child->add_child_nocopy ((*i)->get_template());
1077                                 }
1078                         }
1079                 }
1080         }
1081
1082
1083         if (_click_io) {
1084                 child = node->add_child ("Click");
1085                 child->add_child_nocopy (_click_io->state (full_state));
1086         }
1087
1088         if (full_state) {
1089                 child = node->add_child ("NamedSelections");
1090                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1091                         if (full_state) {
1092                                 child->add_child_nocopy ((*i)->get_state());
1093                         }
1094                 }
1095         }
1096
1097         node->add_child_nocopy (_tempo_map->get_state());
1098
1099         node->add_child_nocopy (get_control_protocol_state());
1100
1101         if (_extra_xml) {
1102                 node->add_child_copy (*_extra_xml);
1103         }
1104
1105         return *node;
1106 }
1107
1108 XMLNode&
1109 Session::get_control_protocol_state ()
1110 {
1111         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1112         return cpm.get_state();
1113 }
1114
1115 int
1116 Session::set_state (const XMLNode& node, int version)
1117 {
1118         XMLNodeList nlist;
1119         XMLNode* child;
1120         const XMLProperty* prop;
1121         int ret = -1;
1122
1123         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1124
1125         if (node.name() != X_("Session")){
1126                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1127                 return -1;
1128         }
1129
1130         if ((prop = node.property ("version")) != 0) {
1131                 version = atoi (prop->value ()) * 1000;
1132         }
1133
1134         if ((prop = node.property ("name")) != 0) {
1135                 _name = prop->value ();
1136         }
1137
1138         if ((prop = node.property (X_("sample-rate"))) != 0) {
1139
1140                 _nominal_frame_rate = atoi (prop->value());
1141
1142                 if (_nominal_frame_rate != _current_frame_rate) {
1143                         if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1144                                 return -1;
1145                         }
1146                 }
1147         }
1148
1149         setup_raid_path(_session_dir->root_path().to_string());
1150
1151         if ((prop = node.property (X_("id-counter"))) != 0) {
1152                 uint64_t x;
1153                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1154                 ID::init_counter (x);
1155         } else {
1156                 /* old sessions used a timebased counter, so fake
1157                    the startup ID counter based on a standard
1158                    timestamp.
1159                 */
1160                 time_t now;
1161                 time (&now);
1162                 ID::init_counter (now);
1163         }
1164
1165
1166         IO::disable_connecting ();
1167
1168         /* Object loading order:
1169
1170         Path
1171         Extra
1172         Options/Config
1173         MIDI Control // relies on data from Options/Config
1174         Metadata
1175         Locations
1176         Sources
1177         AudioRegions
1178         AudioDiskstreams
1179         Connections
1180         Routes
1181         RouteGroups
1182         MixGroups
1183         Click
1184         ControlProtocols
1185         */
1186
1187         if ((child = find_named_node (node, "Extra")) != 0) {
1188                 _extra_xml = new XMLNode (*child);
1189         }
1190
1191         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1192                 load_options (*child);
1193         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1194                 load_options (*child);
1195         } else {
1196                 error << _("Session: XML state has no options section") << endmsg;
1197         }
1198
1199         if (use_config_midi_ports ()) {
1200         }
1201
1202         if (version >= 3000) {
1203                 if ((child = find_named_node (node, "Metadata")) == 0) {
1204                         warning << _("Session: XML state has no metadata section") << endmsg;
1205                 } else if (_metadata->set_state (*child, version)) {
1206                         goto out;
1207                 }
1208         }
1209
1210         if ((child = find_named_node (node, "Locations")) == 0) {
1211                 error << _("Session: XML state has no locations section") << endmsg;
1212                 goto out;
1213         } else if (_locations.set_state (*child, version)) {
1214                 goto out;
1215         }
1216
1217         Location* location;
1218
1219         if ((location = _locations.auto_loop_location()) != 0) {
1220                 set_auto_loop_location (location);
1221         }
1222
1223         if ((location = _locations.auto_punch_location()) != 0) {
1224                 set_auto_punch_location (location);
1225         }
1226
1227         if ((location = _locations.end_location()) == 0) {
1228                 _locations.add (end_location);
1229         } else {
1230                 delete end_location;
1231                 end_location = location;
1232         }
1233
1234         if ((location = _locations.start_location()) == 0) {
1235                 _locations.add (start_location);
1236         } else {
1237                 delete start_location;
1238                 start_location = location;
1239         }
1240
1241         AudioFileSource::set_header_position_offset (start_location->start());
1242
1243         if ((child = find_named_node (node, "Sources")) == 0) {
1244                 error << _("Session: XML state has no sources section") << endmsg;
1245                 goto out;
1246         } else if (load_sources (*child)) {
1247                 goto out;
1248         }
1249
1250         if ((child = find_named_node (node, "Regions")) == 0) {
1251                 error << _("Session: XML state has no Regions section") << endmsg;
1252                 goto out;
1253         } else if (load_regions (*child)) {
1254                 goto out;
1255         }
1256
1257         if ((child = find_named_node (node, "Playlists")) == 0) {
1258                 error << _("Session: XML state has no playlists section") << endmsg;
1259                 goto out;
1260         } else if (load_playlists (*child)) {
1261                 goto out;
1262         }
1263
1264         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1265                 // this is OK
1266         } else if (load_unused_playlists (*child)) {
1267                 goto out;
1268         }
1269         
1270         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1271                 if (load_named_selections (*child)) {
1272                         goto out;
1273                 }
1274         }
1275
1276         if ((child = find_named_node (node, "DiskStreams")) == 0) {
1277                 error << _("Session: XML state has no diskstreams section") << endmsg;
1278                 goto out;
1279         } else if (load_diskstreams (*child)) {
1280                 goto out;
1281         }
1282
1283         if (version >= 3000) {
1284                 if ((child = find_named_node (node, "Bundles")) == 0) {
1285                         warning << _("Session: XML state has no bundles section") << endmsg;
1286                         //goto out;
1287                 } else {
1288                         /* We can't load Bundles yet as they need to be able
1289                            to convert from port names to Port objects, which can't happen until
1290                            later */
1291                         _bundle_xml_node = new XMLNode (*child);
1292                 }
1293         }
1294         
1295         if (version >= 3000) {
1296                 
1297                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1298                         error << _("Session: XML state has no route groups section") << endmsg;
1299                         goto out;
1300                 } else if (load_route_groups (*child, version)) {
1301                         goto out;
1302                 }
1303                 
1304         } else if (version < 3000) {
1305                 
1306                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1307                         error << _("Session: XML state has no edit groups section") << endmsg;
1308                         goto out;
1309                 } else if (load_route_groups (*child, version)) {
1310                         goto out;
1311                 }
1312
1313                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1314                         error << _("Session: XML state has no mix groups section") << endmsg;
1315                         goto out;
1316                 } else if (load_route_groups (*child, version)) {
1317                         goto out;
1318                 }
1319         }
1320
1321         if ((child = find_named_node (node, "TempoMap")) == 0) {
1322                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1323                 goto out;
1324         } else if (_tempo_map->set_state (*child, version)) {
1325                 goto out;
1326         }
1327
1328         if ((child = find_named_node (node, "Routes")) == 0) {
1329                 error << _("Session: XML state has no routes section") << endmsg;
1330                 goto out;
1331         } else if (load_routes (*child, version)) {
1332                 goto out;
1333         }
1334
1335         if ((child = find_named_node (node, "Click")) == 0) {
1336                 warning << _("Session: XML state has no click section") << endmsg;
1337         } else if (_click_io) {
1338                 _click_io->set_state (*child, version);
1339         }
1340
1341         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1342                 ControlProtocolManager::instance().set_protocol_states (*child);
1343         }
1344
1345         /* here beginneth the second phase ... */
1346
1347         StateReady (); /* EMIT SIGNAL */
1348
1349         return 0;
1350
1351   out:
1352         return ret;
1353 }
1354
1355 int
1356 Session::load_routes (const XMLNode& node, int version)
1357 {
1358         XMLNodeList nlist;
1359         XMLNodeConstIterator niter;
1360         RouteList new_routes;
1361
1362         nlist = node.children();
1363
1364         set_dirty();
1365
1366         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1367
1368                 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1369
1370                 if (route == 0) {
1371                         error << _("Session: cannot create Route from XML description.") << endmsg;
1372                         return -1;
1373                 }
1374
1375                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1376
1377                 new_routes.push_back (route);
1378         }
1379
1380         add_routes (new_routes, false);
1381
1382         return 0;
1383 }
1384
1385 boost::shared_ptr<Route>
1386 Session::XMLRouteFactory (const XMLNode& node, int version)
1387 {
1388         if (node.name() != "Route") {
1389                 return boost::shared_ptr<Route> ((Route*) 0);
1390         }
1391
1392         bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1393
1394         DataType type = DataType::AUDIO;
1395         const XMLProperty* prop = node.property("default-type");
1396
1397         if (prop) {
1398                 type = DataType(prop->value());
1399         }
1400
1401         assert(type != DataType::NIL);
1402
1403         if (has_diskstream) {
1404                 if (type == DataType::AUDIO) {
1405                         boost::shared_ptr<Route> ret (new AudioTrack (*this, node, version));
1406                         return ret;
1407                 } else {
1408                         boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version));
1409                         return ret;
1410                 }
1411         } else {
1412                 boost::shared_ptr<Route> ret (new Route (*this, node));
1413                 return ret;
1414         }
1415 }
1416
1417 int
1418 Session::load_regions (const XMLNode& node)
1419 {
1420         XMLNodeList nlist;
1421         XMLNodeConstIterator niter;
1422         boost::shared_ptr<Region> region;
1423
1424         nlist = node.children();
1425
1426         set_dirty();
1427
1428         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1429                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1430                         error << _("Session: cannot create Region from XML description.");
1431                         const XMLProperty *name = (**niter).property("name");
1432
1433                         if (name) {
1434                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1435                         }
1436
1437                         error << endmsg;
1438                 }
1439         }
1440
1441         return 0;
1442 }
1443
1444 boost::shared_ptr<Region>
1445 Session::XMLRegionFactory (const XMLNode& node, bool full)
1446 {
1447         const XMLProperty* type = node.property("type");
1448
1449         try {
1450
1451         if ( !type || type->value() == "audio" ) {
1452
1453                 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1454
1455         } else if (type->value() == "midi") {
1456
1457                 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1458
1459         }
1460
1461         } catch (failed_constructor& err) {
1462                 return boost::shared_ptr<Region> ();
1463         }
1464
1465         return boost::shared_ptr<Region> ();
1466 }
1467
1468 boost::shared_ptr<AudioRegion>
1469 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1470 {
1471         const XMLProperty* prop;
1472         boost::shared_ptr<Source> source;
1473         boost::shared_ptr<AudioSource> as;
1474         SourceList sources;
1475         SourceList master_sources;
1476         uint32_t nchans = 1;
1477         char buf[128];
1478
1479         if (node.name() != X_("Region")) {
1480                 return boost::shared_ptr<AudioRegion>();
1481         }
1482
1483         if ((prop = node.property (X_("channels"))) != 0) {
1484                 nchans = atoi (prop->value().c_str());
1485         }
1486
1487         if ((prop = node.property ("name")) == 0) {
1488                 cerr << "no name for this region\n";
1489                 abort ();
1490         }
1491
1492         if ((prop = node.property (X_("source-0"))) == 0) {
1493                 if ((prop = node.property ("source")) == 0) {
1494                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1495                         return boost::shared_ptr<AudioRegion>();
1496                 }
1497         }
1498
1499         PBD::ID s_id (prop->value());
1500
1501         if ((source = source_by_id (s_id)) == 0) {
1502                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1503                 return boost::shared_ptr<AudioRegion>();
1504         }
1505
1506         as = boost::dynamic_pointer_cast<AudioSource>(source);
1507         if (!as) {
1508                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1509                 return boost::shared_ptr<AudioRegion>();
1510         }
1511
1512         sources.push_back (as);
1513
1514         /* pickup other channels */
1515
1516         for (uint32_t n=1; n < nchans; ++n) {
1517                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1518                 if ((prop = node.property (buf)) != 0) {
1519
1520                         PBD::ID id2 (prop->value());
1521
1522                         if ((source = source_by_id (id2)) == 0) {
1523                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1524                                 return boost::shared_ptr<AudioRegion>();
1525                         }
1526
1527                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1528                         if (!as) {
1529                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1530                                 return boost::shared_ptr<AudioRegion>();
1531                         }
1532                         sources.push_back (as);
1533                 }
1534         }
1535
1536         for (uint32_t n = 0; n < nchans; ++n) {
1537                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1538                 if ((prop = node.property (buf)) != 0) {
1539
1540                         PBD::ID id2 (prop->value());
1541
1542                         if ((source = source_by_id (id2)) == 0) {
1543                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1544                                 return boost::shared_ptr<AudioRegion>();
1545                         }
1546
1547                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1548                         if (!as) {
1549                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1550                                 return boost::shared_ptr<AudioRegion>();
1551                         }
1552                         master_sources.push_back (as);
1553                 }
1554         }
1555
1556         try {
1557                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1558
1559                 /* a final detail: this is the one and only place that we know how long missing files are */
1560
1561                 if (region->whole_file()) {
1562                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1563                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1564                                 if (sfp) {
1565                                         sfp->set_length (region->length());
1566                                 }
1567                         }
1568                 }
1569
1570                 if (!master_sources.empty()) {
1571                         if (master_sources.size() != nchans) {
1572                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1573                         } else {
1574                                 region->set_master_sources (master_sources);
1575                         }
1576                 }
1577
1578                 return region;
1579
1580         }
1581
1582         catch (failed_constructor& err) {
1583                 return boost::shared_ptr<AudioRegion>();
1584         }
1585 }
1586
1587 boost::shared_ptr<MidiRegion>
1588 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1589 {
1590         const XMLProperty* prop;
1591         boost::shared_ptr<Source> source;
1592         boost::shared_ptr<MidiSource> ms;
1593         SourceList sources;
1594         uint32_t nchans = 1;
1595
1596         if (node.name() != X_("Region")) {
1597                 return boost::shared_ptr<MidiRegion>();
1598         }
1599
1600         if ((prop = node.property (X_("channels"))) != 0) {
1601                 nchans = atoi (prop->value().c_str());
1602         }
1603
1604         if ((prop = node.property ("name")) == 0) {
1605                 cerr << "no name for this region\n";
1606                 abort ();
1607         }
1608
1609         // Multiple midi channels?  that's just crazy talk
1610         assert(nchans == 1);
1611
1612         if ((prop = node.property (X_("source-0"))) == 0) {
1613                 if ((prop = node.property ("source")) == 0) {
1614                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1615                         return boost::shared_ptr<MidiRegion>();
1616                 }
1617         }
1618
1619         PBD::ID s_id (prop->value());
1620
1621         if ((source = source_by_id (s_id)) == 0) {
1622                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1623                 return boost::shared_ptr<MidiRegion>();
1624         }
1625
1626         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1627         if (!ms) {
1628                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1629                 return boost::shared_ptr<MidiRegion>();
1630         }
1631
1632         sources.push_back (ms);
1633
1634         try {
1635                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1636                 /* a final detail: this is the one and only place that we know how long missing files are */
1637
1638                 if (region->whole_file()) {
1639                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1640                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1641                                 if (sfp) {
1642                                         sfp->set_length (region->length());
1643                                 }
1644                         }
1645                 }
1646
1647                 return region;
1648         }
1649
1650         catch (failed_constructor& err) {
1651                 return boost::shared_ptr<MidiRegion>();
1652         }
1653 }
1654
1655 XMLNode&
1656 Session::get_sources_as_xml ()
1657
1658 {
1659         XMLNode* node = new XMLNode (X_("Sources"));
1660         Glib::Mutex::Lock lm (source_lock);
1661
1662         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1663                 node->add_child_nocopy (i->second->get_state());
1664         }
1665
1666         return *node;
1667 }
1668
1669 string
1670 Session::path_from_region_name (DataType type, string name, string identifier)
1671 {
1672         char buf[PATH_MAX+1];
1673         uint32_t n;
1674         SessionDirectory sdir(get_best_session_directory_for_new_source());
1675         sys::path source_dir = ((type == DataType::AUDIO)
1676                 ? sdir.sound_path() : sdir.midi_path());
1677
1678         string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1679
1680         for (n = 0; n < 999999; ++n) {
1681                 if (identifier.length()) {
1682                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1683                                   identifier.c_str(), n, ext.c_str());
1684                 } else {
1685                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1686                                         n, ext.c_str());
1687                 }
1688
1689                 sys::path source_path = source_dir / buf;
1690
1691                 if (!sys::exists (source_path)) {
1692                         return source_path.to_string();
1693                 }
1694         }
1695
1696         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1697                                  name, identifier)
1698               << endmsg;
1699
1700         return "";
1701 }
1702
1703
1704 int
1705 Session::load_sources (const XMLNode& node)
1706 {
1707         XMLNodeList nlist;
1708         XMLNodeConstIterator niter;
1709         boost::shared_ptr<Source> source;
1710
1711         nlist = node.children();
1712
1713         set_dirty();
1714
1715         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1716                 try {
1717                         if ((source = XMLSourceFactory (**niter)) == 0) {
1718                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1719                         }
1720                 } catch (MissingSource& err) {
1721                         warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1722                         source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1723                 }
1724         }
1725
1726         return 0;
1727 }
1728
1729 boost::shared_ptr<Source>
1730 Session::XMLSourceFactory (const XMLNode& node)
1731 {
1732         if (node.name() != "Source") {
1733                 return boost::shared_ptr<Source>();
1734         }
1735
1736         try {
1737                 /* note: do peak building in another thread when loading session state */
1738                 return SourceFactory::create (*this, node, true);
1739         }
1740
1741         catch (failed_constructor& err) {
1742                 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1743                 return boost::shared_ptr<Source>();
1744         }
1745 }
1746
1747 int
1748 Session::save_template (string template_name)
1749 {
1750         XMLTree tree;
1751
1752         if (_state_of_the_state & CannotSave) {
1753                 return -1;
1754         }
1755
1756         sys::path user_template_dir(user_template_directory());
1757
1758         try
1759         {
1760                 sys::create_directories (user_template_dir);
1761         }
1762         catch(sys::filesystem_error& ex)
1763         {
1764                 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1765                                 user_template_dir.to_string(), ex.what()) << endmsg;
1766                 return -1;
1767         }
1768
1769         tree.set_root (&get_template());
1770
1771         sys::path template_file_path(user_template_dir);
1772         template_file_path /= template_name + template_suffix;
1773
1774         if (sys::exists (template_file_path))
1775         {
1776                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1777                                 template_file_path.to_string()) << endmsg;
1778                 return -1;
1779         }
1780
1781         if (!tree.write (template_file_path.to_string())) {
1782                 error << _("mix template not saved") << endmsg;
1783                 return -1;
1784         }
1785
1786         return 0;
1787 }
1788
1789 int
1790 Session::rename_template (string old_name, string new_name)
1791 {
1792         sys::path old_path (user_template_directory());
1793         old_path /= old_name + template_suffix;
1794
1795         sys::path new_path(user_template_directory());
1796         new_path /= new_name + template_suffix;
1797
1798         if (sys::exists (new_path)) {
1799                 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1800                                           new_path.to_string()) << endmsg;
1801                 return -1;
1802         }
1803
1804         try {
1805                 sys::rename (old_path, new_path);
1806                 return 0;
1807         } catch (...) {
1808                 return -1;
1809         }
1810 }
1811
1812 int
1813 Session::delete_template (string name)
1814 {
1815         sys::path path = user_template_directory();
1816         path /= name + template_suffix;
1817
1818         try {
1819                 sys::remove (path);
1820                 return 0;
1821         } catch (...) {
1822                 return -1;
1823         }
1824 }
1825
1826 void
1827 Session::refresh_disk_space ()
1828 {
1829 #if HAVE_SYS_VFS_H
1830         struct statfs statfsbuf;
1831         vector<space_and_path>::iterator i;
1832         Glib::Mutex::Lock lm (space_lock);
1833         double scale;
1834
1835         /* get freespace on every FS that is part of the session path */
1836
1837         _total_free_4k_blocks = 0;
1838
1839         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1840                 statfs ((*i).path.c_str(), &statfsbuf);
1841
1842                 scale = statfsbuf.f_bsize/4096.0;
1843
1844                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1845                 _total_free_4k_blocks += (*i).blocks;
1846         }
1847 #endif
1848 }
1849
1850 string
1851 Session::get_best_session_directory_for_new_source ()
1852 {
1853         vector<space_and_path>::iterator i;
1854         string result = _session_dir->root_path().to_string();
1855
1856         /* handle common case without system calls */
1857
1858         if (session_dirs.size() == 1) {
1859                 return result;
1860         }
1861
1862         /* OK, here's the algorithm we're following here:
1863
1864         We want to select which directory to use for
1865         the next file source to be created. Ideally,
1866         we'd like to use a round-robin process so as to
1867         get maximum performance benefits from splitting
1868         the files across multiple disks.
1869
1870         However, in situations without much diskspace, an
1871         RR approach may end up filling up a filesystem
1872         with new files while others still have space.
1873         Its therefore important to pay some attention to
1874         the freespace in the filesystem holding each
1875         directory as well. However, if we did that by
1876         itself, we'd keep creating new files in the file
1877         system with the most space until it was as full
1878         as all others, thus negating any performance
1879         benefits of this RAID-1 like approach.
1880
1881         So, we use a user-configurable space threshold. If
1882         there are at least 2 filesystems with more than this
1883         much space available, we use RR selection between them.
1884         If not, then we pick the filesystem with the most space.
1885
1886         This gets a good balance between the two
1887         approaches.
1888         */
1889
1890         refresh_disk_space ();
1891
1892         int free_enough = 0;
1893
1894         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1895                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1896                         free_enough++;
1897                 }
1898         }
1899
1900         if (free_enough >= 2) {
1901                 /* use RR selection process, ensuring that the one
1902                    picked works OK.
1903                 */
1904
1905                 i = last_rr_session_dir;
1906
1907                 do {
1908                         if (++i == session_dirs.end()) {
1909                                 i = session_dirs.begin();
1910                         }
1911
1912                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1913                                 if (create_session_directory ((*i).path)) {
1914                                         result = (*i).path;
1915                                         last_rr_session_dir = i;
1916                                         return result;
1917                                 }
1918                         }
1919
1920                 } while (i != last_rr_session_dir);
1921
1922         } else {
1923
1924                 /* pick FS with the most freespace (and that
1925                    seems to actually work ...)
1926                 */
1927
1928                 vector<space_and_path> sorted;
1929                 space_and_path_ascending_cmp cmp;
1930
1931                 sorted = session_dirs;
1932                 sort (sorted.begin(), sorted.end(), cmp);
1933
1934                 for (i = sorted.begin(); i != sorted.end(); ++i) {
1935                         if (create_session_directory ((*i).path)) {
1936                                 result = (*i).path;
1937                                 last_rr_session_dir = i;
1938                                 return result;
1939                         }
1940                 }
1941         }
1942
1943         return result;
1944 }
1945
1946 int
1947 Session::load_playlists (const XMLNode& node)
1948 {
1949         XMLNodeList nlist;
1950         XMLNodeConstIterator niter;
1951         boost::shared_ptr<Playlist> playlist;
1952
1953         nlist = node.children();
1954
1955         set_dirty();
1956
1957         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1958
1959                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1960                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
1961                 }
1962         }
1963
1964         return 0;
1965 }
1966
1967 int
1968 Session::load_unused_playlists (const XMLNode& node)
1969 {
1970         XMLNodeList nlist;
1971         XMLNodeConstIterator niter;
1972         boost::shared_ptr<Playlist> playlist;
1973
1974         nlist = node.children();
1975
1976         set_dirty();
1977
1978         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1979
1980                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1981                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
1982                         continue;
1983                 }
1984
1985                 // now manually untrack it
1986
1987                 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1988         }
1989
1990         return 0;
1991 }
1992
1993 boost::shared_ptr<Playlist>
1994 Session::XMLPlaylistFactory (const XMLNode& node)
1995 {
1996         try {
1997                 return PlaylistFactory::create (*this, node);
1998         }
1999
2000         catch (failed_constructor& err) {
2001                 return boost::shared_ptr<Playlist>();
2002         }
2003 }
2004
2005 int
2006 Session::load_named_selections (const XMLNode& node)
2007 {
2008         XMLNodeList nlist;
2009         XMLNodeConstIterator niter;
2010         NamedSelection *ns;
2011
2012         nlist = node.children();
2013
2014         set_dirty();
2015
2016         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2017
2018                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2019                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2020                 }
2021         }
2022
2023         return 0;
2024 }
2025
2026 NamedSelection *
2027 Session::XMLNamedSelectionFactory (const XMLNode& node)
2028 {
2029         try {
2030                 return new NamedSelection (*this, node);
2031         }
2032
2033         catch (failed_constructor& err) {
2034                 return 0;
2035         }
2036 }
2037
2038 string
2039 Session::automation_dir () const
2040 {
2041         return Glib::build_filename (_path, "automation");
2042 }
2043
2044 string
2045 Session::analysis_dir () const
2046 {
2047         return Glib::build_filename (_path, "analysis");
2048 }
2049
2050 int
2051 Session::load_bundles (XMLNode const & node)
2052 {
2053         XMLNodeList nlist = node.children();
2054         XMLNodeConstIterator niter;
2055
2056         set_dirty();
2057
2058         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2059                 if ((*niter)->name() == "InputBundle") {
2060                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2061                 } else if ((*niter)->name() == "OutputBundle") {
2062                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2063                 } else {
2064                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2065                         return -1;
2066                 }
2067         }
2068
2069         return 0;
2070 }
2071
2072 int
2073 Session::load_route_groups (const XMLNode& node, int version)
2074 {
2075         XMLNodeList nlist = node.children();
2076         XMLNodeConstIterator niter;
2077
2078         set_dirty ();
2079
2080         if (version >= 3000) {
2081                 
2082                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2083                         if ((*niter)->name() == "RouteGroup") {
2084                                 RouteGroup* rg = new RouteGroup (*this, "");
2085                                 add_route_group (rg);
2086                                 rg->set_state (**niter, version);
2087                         }
2088                 }
2089
2090         } else if (version < 3000) {
2091
2092                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2093                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2094                                 RouteGroup* rg = new RouteGroup (*this, "");
2095                                 add_route_group (rg);
2096                                 rg->set_state (**niter, version);
2097                         }
2098                 }
2099         }
2100
2101         return 0;
2102 }
2103
2104 void
2105 Session::auto_save()
2106 {
2107         save_state (_current_snapshot_name);
2108 }
2109
2110 static bool
2111 state_file_filter (const string &str, void */*arg*/)
2112 {
2113         return (str.length() > strlen(statefile_suffix) &&
2114                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2115 }
2116
2117 struct string_cmp {
2118         bool operator()(const string* a, const string* b) {
2119                 return *a < *b;
2120         }
2121 };
2122
2123 static string*
2124 remove_end(string* state)
2125 {
2126         string statename(*state);
2127
2128         string::size_type start,end;
2129         if ((start = statename.find_last_of ('/')) != string::npos) {
2130                 statename = statename.substr (start+1);
2131         }
2132
2133         if ((end = statename.rfind(".ardour")) == string::npos) {
2134                 end = statename.length();
2135         }
2136
2137         return new string(statename.substr (0, end));
2138 }
2139
2140 vector<string *> *
2141 Session::possible_states (string path)
2142 {
2143         PathScanner scanner;
2144         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2145
2146         transform(states->begin(), states->end(), states->begin(), remove_end);
2147
2148         string_cmp cmp;
2149         sort (states->begin(), states->end(), cmp);
2150
2151         return states;
2152 }
2153
2154 vector<string *> *
2155 Session::possible_states () const
2156 {
2157         return possible_states(_path);
2158 }
2159
2160 void
2161 Session::add_route_group (RouteGroup* g)
2162 {
2163         _route_groups.push_back (g);
2164         route_group_added (g); /* EMIT SIGNAL */
2165         set_dirty ();
2166 }
2167
2168 void
2169 Session::remove_route_group (RouteGroup& rg)
2170 {
2171         list<RouteGroup*>::iterator i;
2172
2173         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2174                 (*i)->apply (&Route::drop_route_group, this);
2175                 _route_groups.erase (i);
2176                 route_group_removed (); /* EMIT SIGNAL */
2177         }
2178
2179         delete &rg;
2180 }
2181
2182
2183 RouteGroup *
2184 Session::route_group_by_name (string name)
2185 {
2186         list<RouteGroup *>::iterator i;
2187
2188         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2189                 if ((*i)->name() == name) {
2190                         return* i;
2191                 }
2192         }
2193         return 0;
2194 }
2195
2196 void
2197 Session::begin_reversible_command(const string& name)
2198 {
2199         UndoTransaction* trans = new UndoTransaction();
2200         trans->set_name(name);
2201
2202         if (!_current_trans.empty()) {
2203                 _current_trans.top()->add_command (trans);
2204         } else {
2205                 _current_trans.push(trans);
2206         }
2207 }
2208
2209 void
2210 Session::commit_reversible_command(Command *cmd)
2211 {
2212         assert(!_current_trans.empty());
2213         struct timeval now;
2214
2215         if (cmd) {
2216                 _current_trans.top()->add_command(cmd);
2217         }
2218
2219         if (_current_trans.top()->empty()) {
2220                 _current_trans.pop();
2221                 return;
2222         }
2223
2224         gettimeofday(&now, 0);
2225         _current_trans.top()->set_timestamp(now);
2226
2227         _history.add(_current_trans.top());
2228         _current_trans.pop();
2229 }
2230
2231 Session::GlobalRouteBooleanState
2232 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2233 {
2234         GlobalRouteBooleanState s;
2235         boost::shared_ptr<RouteList> r = routes.reader ();
2236
2237         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2238                 if (!(*i)->is_hidden()) {
2239                         RouteBooleanState v;
2240
2241                         v.first =* i;
2242                         Route* r = (*i).get();
2243                         v.second = (r->*method)();
2244
2245                         s.push_back (v);
2246                 }
2247         }
2248
2249         return s;
2250 }
2251
2252 Session::GlobalRouteMeterState
2253 Session::get_global_route_metering ()
2254 {
2255         GlobalRouteMeterState s;
2256         boost::shared_ptr<RouteList> r = routes.reader ();
2257
2258         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2259                 if (!(*i)->is_hidden()) {
2260                         RouteMeterState v;
2261
2262                         v.first =* i;
2263                         v.second = (*i)->meter_point();
2264
2265                         s.push_back (v);
2266                 }
2267         }
2268
2269         return s;
2270 }
2271
2272 void
2273 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2274 {
2275         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2276
2277                 boost::shared_ptr<Route> r = (i->first.lock());
2278
2279                 if (r) {
2280                         r->set_meter_point (i->second, arg);
2281                 }
2282         }
2283 }
2284
2285 void
2286 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2287 {
2288         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2289
2290                 boost::shared_ptr<Route> r = (i->first.lock());
2291
2292                 if (r) {
2293                         Route* rp = r.get();
2294                         (rp->*method) (i->second, arg);
2295                 }
2296         }
2297 }
2298
2299 void
2300 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2301 {
2302         set_global_route_boolean (s, &Route::set_mute, src);
2303 }
2304
2305 void
2306 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2307 {
2308         set_global_route_boolean (s, &Route::set_solo, src);
2309 }
2310
2311 void
2312 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2313 {
2314         set_global_route_boolean (s, &Route::set_record_enable, src);
2315 }
2316
2317 static bool
2318 accept_all_non_peak_files (const string& path, void */*arg*/)
2319 {
2320         return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2321 }
2322
2323 static bool
2324 accept_all_state_files (const string& path, void */*arg*/)
2325 {
2326         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2327 }
2328
2329 int
2330 Session::find_all_sources (string path, set<string>& result)
2331 {
2332         XMLTree tree;
2333         XMLNode* node;
2334
2335         if (!tree.read (path)) {
2336                 return -1;
2337         }
2338
2339         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2340                 return -2;
2341         }
2342
2343         XMLNodeList nlist;
2344         XMLNodeConstIterator niter;
2345
2346         nlist = node->children();
2347
2348         set_dirty();
2349
2350         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2351
2352                 XMLProperty* prop;
2353
2354                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2355                         continue;
2356                 }
2357
2358                 DataType type (prop->value());
2359
2360                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2361                         continue;
2362                 }
2363
2364                 if (prop->value()[0] == '/') {
2365                         /* external file, ignore */
2366                         continue;
2367                 }
2368
2369                 Glib::ustring found_path;
2370                 bool is_new;
2371                 uint16_t chan;
2372
2373                 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2374                         result.insert (found_path);
2375                 }
2376         }
2377
2378         return 0;
2379 }
2380
2381 int
2382 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2383 {
2384         PathScanner scanner;
2385         vector<string*>* state_files;
2386         string ripped;
2387         string this_snapshot_path;
2388
2389         result.clear ();
2390
2391         ripped = _path;
2392
2393         if (ripped[ripped.length()-1] == '/') {
2394                 ripped = ripped.substr (0, ripped.length() - 1);
2395         }
2396
2397         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2398
2399         if (state_files == 0) {
2400                 /* impossible! */
2401                 return 0;
2402         }
2403
2404         this_snapshot_path = _path;
2405         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2406         this_snapshot_path += statefile_suffix;
2407
2408         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2409
2410                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2411                         continue;
2412                 }
2413
2414                 if (find_all_sources (**i, result) < 0) {
2415                         return -1;
2416                 }
2417         }
2418
2419         return 0;
2420 }
2421
2422 struct RegionCounter {
2423     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2424     AudioSourceList::iterator iter;
2425     boost::shared_ptr<Region> region;
2426     uint32_t count;
2427
2428     RegionCounter() : count (0) {}
2429 };
2430
2431 int
2432 Session::cleanup_sources (CleanupReport& rep)
2433 {
2434         // FIXME: needs adaptation to midi
2435
2436         vector<boost::shared_ptr<Source> > dead_sources;
2437         vector<boost::shared_ptr<Playlist> > playlists_tbd;
2438         PathScanner scanner;
2439         string sound_path;
2440         vector<space_and_path>::iterator i;
2441         vector<space_and_path>::iterator nexti;
2442         vector<string*>* soundfiles;
2443         vector<string> unused;
2444         set<string> all_sources;
2445         bool used;
2446         string spath;
2447         int ret = -1;
2448
2449         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2450
2451
2452         /* step 1: consider deleting all unused playlists */
2453
2454         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2455                 int status;
2456
2457                 status = AskAboutPlaylistDeletion (*x);
2458
2459                 switch (status) {
2460                 case -1:
2461                         ret = 0;
2462                         goto out;
2463                         break;
2464
2465                 case 0:
2466                         playlists_tbd.push_back (*x);
2467                         break;
2468
2469                 default:
2470                         /* leave it alone */
2471                         break;
2472                 }
2473         }
2474
2475         /* now delete any that were marked for deletion */
2476
2477         for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2478                 (*x)->drop_references ();
2479         }
2480
2481         playlists_tbd.clear ();
2482
2483         /* step 2: find all un-used sources */
2484
2485         rep.paths.clear ();
2486         rep.space = 0;
2487
2488         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2489
2490                 SourceMap::iterator tmp;
2491
2492                 tmp = i;
2493                 ++tmp;
2494
2495                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2496                    capture files.
2497                 */
2498
2499                 if (!source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2500                         dead_sources.push_back (i->second);
2501                         i->second->GoingAway();
2502                 }
2503
2504                 i = tmp;
2505         }
2506
2507         /* build a list of all the possible sound directories for the session */
2508
2509         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2510
2511                 nexti = i;
2512                 ++nexti;
2513
2514                 SessionDirectory sdir ((*i).path);
2515                 sound_path += sdir.sound_path().to_string();
2516
2517                 if (nexti != session_dirs.end()) {
2518                         sound_path += ':';
2519                 }
2520
2521                 i = nexti;
2522         }
2523
2524         /* now do the same thing for the files that ended up in the sounds dir(s)
2525            but are not referenced as sources in any snapshot.
2526         */
2527
2528         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2529
2530         if (soundfiles == 0) {
2531                 return 0;
2532         }
2533
2534         /* find all sources, but don't use this snapshot because the
2535            state file on disk still references sources we may have already
2536            dropped.
2537         */
2538
2539         find_all_sources_across_snapshots (all_sources, true);
2540
2541         /*  add our current source list
2542          */
2543
2544         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2545                 boost::shared_ptr<FileSource> fs;
2546
2547                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2548                         all_sources.insert (fs->path());
2549                 }
2550         }
2551
2552         char tmppath1[PATH_MAX+1];
2553         char tmppath2[PATH_MAX+1];
2554
2555         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2556
2557                 used = false;
2558                 spath = **x;
2559
2560                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2561
2562                         realpath(spath.c_str(), tmppath1);
2563                         realpath((*i).c_str(),  tmppath2);
2564
2565                         if (strcmp(tmppath1, tmppath2) == 0) {
2566                                 used = true;
2567                                 break;
2568                         }
2569                 }
2570
2571                 if (!used) {
2572                         unused.push_back (spath);
2573                 }
2574         }
2575
2576         /* now try to move all unused files into the "dead_sounds" directory(ies) */
2577
2578         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2579                 struct stat statbuf;
2580
2581                 rep.paths.push_back (*x);
2582                 if (stat ((*x).c_str(), &statbuf) == 0) {
2583                         rep.space += statbuf.st_size;
2584                 }
2585
2586                 string newpath;
2587
2588                 /* don't move the file across filesystems, just
2589                    stick it in the `dead_sound_dir_name' directory
2590                    on whichever filesystem it was already on.
2591                 */
2592
2593                 if ((*x).find ("/sounds/") != string::npos) {
2594
2595                         /* old school, go up 1 level */
2596
2597                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2598                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2599
2600                 } else {
2601
2602                         /* new school, go up 4 levels */
2603
2604                         newpath = Glib::path_get_dirname (*x);      // "audiofiles"
2605                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2606                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2607                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2608                 }
2609
2610                 newpath += '/';
2611                 newpath += dead_sound_dir_name;
2612
2613                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2614                         error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2615                         return -1;
2616                 }
2617
2618                 newpath += '/';
2619                 newpath += Glib::path_get_basename ((*x));
2620
2621                 if (access (newpath.c_str(), F_OK) == 0) {
2622
2623                         /* the new path already exists, try versioning */
2624
2625                         char buf[PATH_MAX+1];
2626                         int version = 1;
2627                         string newpath_v;
2628
2629                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2630                         newpath_v = buf;
2631
2632                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2633                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2634                                 newpath_v = buf;
2635                         }
2636
2637                         if (version == 999) {
2638                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2639                                                   newpath)
2640                                       << endmsg;
2641                         } else {
2642                                 newpath = newpath_v;
2643                         }
2644
2645                 } else {
2646
2647                         /* it doesn't exist, or we can't read it or something */
2648
2649                 }
2650
2651                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2652                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2653                                           (*x), newpath, strerror (errno))
2654                               << endmsg;
2655                         goto out;
2656                 }
2657
2658                 /* see if there an easy to find peakfile for this file, and remove it.
2659                  */
2660
2661                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2662                 peakpath += peakfile_suffix;
2663
2664                 if (access (peakpath.c_str(), W_OK) == 0) {
2665                         if (::unlink (peakpath.c_str()) != 0) {
2666                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2667                                                   peakpath, _path, strerror (errno))
2668                                       << endmsg;
2669                                 /* try to back out */
2670                                 rename (newpath.c_str(), _path.c_str());
2671                                 goto out;
2672                         }
2673                 }
2674         }
2675
2676         ret = 0;
2677
2678         /* dump the history list */
2679
2680         _history.clear ();
2681
2682         /* save state so we don't end up a session file
2683            referring to non-existent sources.
2684         */
2685
2686         save_state ("");
2687
2688   out:
2689         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2690
2691         return ret;
2692 }
2693
2694 int
2695 Session::cleanup_trash_sources (CleanupReport& rep)
2696 {
2697         // FIXME: needs adaptation for MIDI
2698
2699         vector<space_and_path>::iterator i;
2700         string dead_sound_dir;
2701         struct dirent* dentry;
2702         struct stat statbuf;
2703         DIR* dead;
2704
2705         rep.paths.clear ();
2706         rep.space = 0;
2707
2708         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2709
2710                 dead_sound_dir = (*i).path;
2711                 dead_sound_dir += dead_sound_dir_name;
2712
2713                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2714                         continue;
2715                 }
2716
2717                 while ((dentry = readdir (dead)) != 0) {
2718
2719                         /* avoid '.' and '..' */
2720
2721                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2722                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2723                                 continue;
2724                         }
2725
2726                         string fullpath;
2727
2728                         fullpath = dead_sound_dir;
2729                         fullpath += '/';
2730                         fullpath += dentry->d_name;
2731
2732                         if (stat (fullpath.c_str(), &statbuf)) {
2733                                 continue;
2734                         }
2735
2736                         if (!S_ISREG (statbuf.st_mode)) {
2737                                 continue;
2738                         }
2739
2740                         if (unlink (fullpath.c_str())) {
2741                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2742                                                   fullpath, strerror (errno))
2743                                       << endmsg;
2744                         }
2745
2746                         rep.paths.push_back (dentry->d_name);
2747                         rep.space += statbuf.st_size;
2748                 }
2749
2750                 closedir (dead);
2751
2752         }
2753
2754         return 0;
2755 }
2756
2757 void
2758 Session::set_dirty ()
2759 {
2760         bool was_dirty = dirty();
2761
2762         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2763
2764
2765         if (!was_dirty) {
2766                 DirtyChanged(); /* EMIT SIGNAL */
2767         }
2768 }
2769
2770
2771 void
2772 Session::set_clean ()
2773 {
2774         bool was_dirty = dirty();
2775
2776         _state_of_the_state = Clean;
2777
2778
2779         if (was_dirty) {
2780                 DirtyChanged(); /* EMIT SIGNAL */
2781         }
2782 }
2783
2784 void
2785 Session::set_deletion_in_progress ()
2786 {
2787         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2788 }
2789
2790 void
2791 Session::clear_deletion_in_progress ()
2792 {
2793         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2794 }
2795
2796 void
2797 Session::add_controllable (boost::shared_ptr<Controllable> c)
2798 {
2799         /* this adds a controllable to the list managed by the Session.
2800            this is a subset of those managed by the Controllable class
2801            itself, and represents the only ones whose state will be saved
2802            as part of the session.
2803         */
2804
2805         Glib::Mutex::Lock lm (controllables_lock);
2806         controllables.insert (c);
2807 }
2808
2809 struct null_deleter { void operator()(void const *) const {} };
2810
2811 void
2812 Session::remove_controllable (Controllable* c)
2813 {
2814         if (_state_of_the_state | Deletion) {
2815                 return;
2816         }
2817
2818         Glib::Mutex::Lock lm (controllables_lock);
2819
2820         Controllables::iterator x = controllables.find(
2821                  boost::shared_ptr<Controllable>(c, null_deleter()));
2822
2823         if (x != controllables.end()) {
2824                 controllables.erase (x);
2825         }
2826 }
2827
2828 boost::shared_ptr<Controllable>
2829 Session::controllable_by_id (const PBD::ID& id)
2830 {
2831         Glib::Mutex::Lock lm (controllables_lock);
2832
2833         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2834                 if ((*i)->id() == id) {
2835                         return *i;
2836                 }
2837         }
2838
2839         return boost::shared_ptr<Controllable>();
2840 }
2841
2842 void
2843 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2844 {
2845         if (_writable) {
2846                 Stateful::add_instant_xml (node, _path);
2847         }
2848
2849         if (write_to_config) {
2850                 Config->add_instant_xml (node);
2851         }
2852 }
2853
2854 XMLNode*
2855 Session::instant_xml (const string& node_name)
2856 {
2857         return Stateful::instant_xml (node_name, _path);
2858 }
2859
2860 int
2861 Session::save_history (string snapshot_name)
2862 {
2863         XMLTree tree;
2864
2865         if (!_writable) {
2866                 return 0;
2867         }
2868
2869         if (snapshot_name.empty()) {
2870                 snapshot_name = _current_snapshot_name;
2871         }
2872
2873         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2874         const string backup_filename = history_filename + backup_suffix;
2875         const sys::path xml_path = _session_dir->root_path() / history_filename;
2876         const sys::path backup_path = _session_dir->root_path() / backup_filename;
2877
2878         if (sys::exists (xml_path)) {
2879                 try
2880                 {
2881                         sys::rename (xml_path, backup_path);
2882                 }
2883                 catch (const sys::filesystem_error& err)
2884                 {
2885                         error << _("could not backup old history file, current history not saved") << endmsg;
2886                         return -1;
2887                 }
2888         }
2889
2890         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2891                 return 0;
2892         }
2893
2894         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2895
2896         if (!tree.write (xml_path.to_string()))
2897         {
2898                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2899
2900                 try
2901                 {
2902                         sys::remove (xml_path);
2903                         sys::rename (backup_path, xml_path);
2904                 }
2905                 catch (const sys::filesystem_error& err)
2906                 {
2907                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
2908                                         backup_path.to_string(), err.what()) << endmsg;
2909                 }
2910
2911                 return -1;
2912         }
2913
2914         return 0;
2915 }
2916
2917 int
2918 Session::restore_history (string snapshot_name)
2919 {
2920         XMLTree tree;
2921
2922         if (snapshot_name.empty()) {
2923                 snapshot_name = _current_snapshot_name;
2924         }
2925
2926         const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2927         const sys::path xml_path = _session_dir->root_path() / xml_filename;
2928
2929         info << "Loading history from " << xml_path.to_string() << endmsg;
2930
2931         if (!sys::exists (xml_path)) {
2932                 info << string_compose (_("%1: no history file \"%2\" for this session."),
2933                                 _name, xml_path.to_string()) << endmsg;
2934                 return 1;
2935         }
2936
2937         if (!tree.read (xml_path.to_string())) {
2938                 error << string_compose (_("Could not understand session history file \"%1\""),
2939                                 xml_path.to_string()) << endmsg;
2940                 return -1;
2941         }
2942
2943         // replace history
2944         _history.clear();
2945
2946         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2947
2948                 XMLNode *t = *it;
2949                 UndoTransaction* ut = new UndoTransaction ();
2950                 struct timeval tv;
2951
2952                 ut->set_name(t->property("name")->value());
2953                 stringstream ss(t->property("tv-sec")->value());
2954                 ss >> tv.tv_sec;
2955                 ss.str(t->property("tv-usec")->value());
2956                 ss >> tv.tv_usec;
2957                 ut->set_timestamp(tv);
2958
2959                 for (XMLNodeConstIterator child_it  = t->children().begin();
2960                                 child_it != t->children().end(); child_it++)
2961                 {
2962                         XMLNode *n = *child_it;
2963                         Command *c;
2964
2965                         if (n->name() == "MementoCommand" ||
2966                                         n->name() == "MementoUndoCommand" ||
2967                                         n->name() == "MementoRedoCommand") {
2968
2969                                 if ((c = memento_command_factory(n))) {
2970                                         ut->add_command(c);
2971                                 }
2972
2973                         } else if (n->name() == X_("GlobalRouteStateCommand")) {
2974
2975                                 if ((c = global_state_command_factory (*n))) {
2976                                         ut->add_command (c);
2977                                 }
2978
2979                         } else if (n->name() == "DeltaCommand") {
2980                                 PBD::ID  id(n->property("midi-source")->value());
2981                                 boost::shared_ptr<MidiSource> midi_source =
2982                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2983                                 if (midi_source) {
2984                                         ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2985                                 } else {
2986                                         error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2987                                 }
2988
2989                         } else if (n->name() == "DiffCommand") {
2990                                 PBD::ID  id(n->property("midi-source")->value());
2991                                 boost::shared_ptr<MidiSource> midi_source =
2992                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2993                                 if (midi_source) {
2994                                         ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
2995                                 } else {
2996                                         error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2997                                 }
2998
2999                         } else {
3000                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3001                         }
3002                 }
3003
3004                 _history.add (ut);
3005         }
3006
3007         return 0;
3008 }
3009
3010 void
3011 Session::config_changed (std::string p, bool ours)
3012 {
3013         if (ours) {
3014                 set_dirty ();
3015         }
3016
3017         if (p == "seamless-loop") {
3018
3019         } else if (p == "rf-speed") {
3020
3021         } else if (p == "auto-loop") {
3022
3023         } else if (p == "auto-input") {
3024
3025                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3026                         /* auto-input only makes a difference if we're rolling */
3027
3028                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3029
3030                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3031                                 if ((*i)->record_enabled ()) {
3032                                         (*i)->monitor_input (!config.get_auto_input());
3033                                 }
3034                         }
3035                 }
3036
3037         } else if (p == "punch-in") {
3038
3039                 Location* location;
3040
3041                 if ((location = _locations.auto_punch_location()) != 0) {
3042
3043                         if (config.get_punch_in ()) {
3044                                 replace_event (Event::PunchIn, location->start());
3045                         } else {
3046                                 remove_event (location->start(), Event::PunchIn);
3047                         }
3048                 }
3049
3050         } else if (p == "punch-out") {
3051
3052                 Location* location;
3053
3054                 if ((location = _locations.auto_punch_location()) != 0) {
3055
3056                         if (config.get_punch_out()) {
3057                                 replace_event (Event::PunchOut, location->end());
3058                         } else {
3059                                 clear_events (Event::PunchOut);
3060                         }
3061                 }
3062
3063         } else if (p == "edit-mode") {
3064
3065                 Glib::Mutex::Lock lm (playlist_lock);
3066
3067                 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3068                         (*i)->set_edit_mode (Config->get_edit_mode ());
3069                 }
3070
3071         } else if (p == "use-video-sync") {
3072
3073                 waiting_for_sync_offset = config.get_use_video_sync();
3074
3075         } else if (p == "mmc-control") {
3076
3077                 //poke_midi_thread ();
3078
3079         } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3080
3081                 if (mmc) {
3082                         mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3083                 }
3084
3085         } else if (p == "mmc-send-id") {
3086
3087                 if (mmc) {
3088                         mmc->set_send_device_id (Config->get_mmc_send_device_id());
3089                 }
3090
3091         } else if (p == "midi-control") {
3092
3093                 //poke_midi_thread ();
3094
3095         } else if (p == "raid-path") {
3096
3097                 setup_raid_path (config.get_raid_path());
3098
3099         } else if (p == "timecode-format") {
3100
3101                 sync_time_vars ();
3102
3103         } else if (p == "video-pullup") {
3104
3105                 sync_time_vars ();
3106
3107         } else if (p == "seamless-loop") {
3108
3109                 if (play_loop && transport_rolling()) {
3110                         // to reset diskstreams etc
3111                         request_play_loop (true);
3112                 }
3113
3114         } else if (p == "rf-speed") {
3115
3116                 cumulative_rf_motion = 0;
3117                 reset_rf_scale (0);
3118
3119         } else if (p == "click-sound") {
3120
3121                 setup_click_sounds (1);
3122
3123         } else if (p == "click-emphasis-sound") {
3124
3125                 setup_click_sounds (-1);
3126
3127         } else if (p == "clicking") {
3128
3129                 if (Config->get_clicking()) {
3130                         if (_click_io && click_data) { // don't require emphasis data
3131                                 _clicking = true;
3132                         }
3133                 } else {
3134                         _clicking = false;
3135                 }
3136
3137         } else if (p == "send-mtc") {
3138
3139                 /* only set the internal flag if we have
3140                    a port.
3141                 */
3142
3143                 if (_mtc_port != 0) {
3144                         session_send_mtc = Config->get_send_mtc();
3145                         if (session_send_mtc) {
3146                                 /* mark us ready to send */
3147                                 next_quarter_frame_to_send = 0;
3148                         }
3149                 } else {
3150                         session_send_mtc = false;
3151                 }
3152
3153         } else if (p == "send-mmc") {
3154
3155                 /* only set the internal flag if we have
3156                    a port.
3157                 */
3158
3159                 if (_mmc_port != 0) {
3160                         session_send_mmc = Config->get_send_mmc();
3161                 } else {
3162                         mmc = 0;
3163                         session_send_mmc = false;
3164                 }
3165
3166         } else if (p == "midi-feedback") {
3167
3168                 /* only set the internal flag if we have
3169                    a port.
3170                 */
3171
3172                 if (_mtc_port != 0) {
3173                         session_midi_feedback = Config->get_midi_feedback();
3174                 }
3175
3176         } else if (p == "jack-time-master") {
3177
3178                 engine().reset_timebase ();
3179
3180         } else if (p == "native-file-header-format") {
3181
3182                 if (!first_file_header_format_reset) {
3183                         reset_native_file_format ();
3184                 }
3185
3186                 first_file_header_format_reset = false;
3187
3188         } else if (p == "native-file-data-format") {
3189
3190                 if (!first_file_data_format_reset) {
3191                         reset_native_file_format ();
3192                 }
3193
3194                 first_file_data_format_reset = false;
3195
3196         } else if (p == "external-sync") {
3197                 if (!config.get_external_sync()) {
3198                         drop_sync_source ();
3199                 } else {
3200                         use_sync_source (config.get_sync_source());
3201                 }
3202         } else if (p == "remote-model") {
3203                 set_remote_control_ids ();
3204         }  else if (p == "denormal-model") {
3205                 setup_fpu ();
3206         } else if (p == "history-depth") {
3207                 set_history_depth (Config->get_history_depth());
3208         } else if (p == "sync-all-route-ordering") {
3209                 sync_order_keys ("session");
3210         } else if (p == "initial-program-change") {
3211
3212                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3213                         MIDI::byte buf[2];
3214
3215                         buf[0] = MIDI::program; // channel zero by default
3216                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3217
3218                         _mmc_port->midimsg (buf, sizeof (buf), 0);
3219                 }
3220         } else if (p == "initial-program-change") {
3221
3222                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3223                         MIDI::byte* buf = new MIDI::byte[2];
3224
3225                         buf[0] = MIDI::program; // channel zero by default
3226                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3227                         // deliver_midi (_mmc_port, buf, 2);
3228                 }
3229         } else if (p == "solo-mute-override") {
3230                 // catch_up_on_solo_mute_override ();
3231         } else if (p == "listen-position") {
3232                 listen_position_changed ();
3233         } else if (p == "solo-control-is-listen-control") {
3234                 solo_control_mode_changed ();
3235         }
3236
3237
3238         set_dirty ();
3239 }
3240
3241 void
3242 Session::set_history_depth (uint32_t d)
3243 {
3244         _history.set_depth (d);
3245 }