3b0e891b2b34c8390b1b5eafe400cd528eb6f33e
[ardour.git] / libs / ardour / track.cc
1 /*
2     Copyright (C) 2006 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 #include "pbd/error.h"
19
20 #include "ardour/amp.h"
21 #include "ardour/audioengine.h"
22 #include "ardour/audiofilesource.h"
23 #include "ardour/audioregion.h"
24 #include "ardour/debug.h"
25 #include "ardour/delivery.h"
26 #include "ardour/disk_reader.h"
27 #include "ardour/disk_writer.h"
28 #include "ardour/event_type_map.h"
29 #include "ardour/io_processor.h"
30 #include "ardour/meter.h"
31 #include "ardour/midi_region.h"
32 #include "ardour/monitor_control.h"
33 #include "ardour/playlist.h"
34 #include "ardour/playlist_factory.h"
35 #include "ardour/port.h"
36 #include "ardour/processor.h"
37 #include "ardour/profile.h"
38 #include "ardour/region_factory.h"
39 #include "ardour/record_enable_control.h"
40 #include "ardour/record_safe_control.h"
41 #include "ardour/route_group_specialized.h"
42 #include "ardour/session.h"
43 #include "ardour/session_playlists.h"
44 #include "ardour/smf_source.h"
45 #include "ardour/track.h"
46 #include "ardour/types_convert.h"
47 #include "ardour/utils.h"
48
49 #include "pbd/i18n.h"
50
51 using namespace std;
52 using namespace ARDOUR;
53 using namespace PBD;
54
55 Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode mode, DataType default_type)
56         : Route (sess, name, flag, default_type)
57         , _saved_meter_point (_meter_point)
58         , _disk_io_point (DiskIOPreFader)
59         , _mode (mode)
60         , _alignment_choice (Automatic)
61 {
62         _freeze_record.state = NoFreeze;
63         _declickable = true;
64 }
65
66 Track::~Track ()
67 {
68         DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
69
70         if (_disk_reader) {
71                 _disk_reader->set_route (boost::shared_ptr<Route>());
72                 _disk_reader.reset ();
73         }
74
75         if (_disk_writer) {
76                 _disk_writer->set_route (boost::shared_ptr<Route>());
77                 _disk_writer.reset ();
78         }
79 }
80
81 int
82 Track::init ()
83 {
84         if (Route::init ()) {
85                 return -1;
86         }
87
88         use_new_playlist (data_type());
89
90         /* disk writer and reader processors will be added when Route calls
91          * add_processors_oh_children_of_mine ().
92          */
93
94         boost::shared_ptr<Route> rp (boost::dynamic_pointer_cast<Route> (shared_from_this()));
95         boost::shared_ptr<Track> rt = boost::dynamic_pointer_cast<Track> (rp);
96
97         _record_enable_control.reset (new RecordEnableControl (_session, EventTypeMap::instance().to_symbol (RecEnableAutomation), *this));
98         add_control (_record_enable_control);
99
100         _record_safe_control.reset (new RecordSafeControl (_session, EventTypeMap::instance().to_symbol (RecSafeAutomation), *this));
101         add_control (_record_safe_control);
102
103         _monitoring_control.reset (new MonitorControl (_session, EventTypeMap::instance().to_symbol (MonitoringAutomation), *this));
104         add_control (_monitoring_control);
105
106         _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
107
108         _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2));
109         _record_safe_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_safe_changed, this, _1, _2));
110         _record_enable_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_enable_changed, this, _1, _2));
111
112         _input->changed.connect_same_thread (*this, boost::bind (&Track::input_changed, this));
113
114         return 0;
115 }
116
117 void
118 Track::add_processors_oh_children_of_mine ()
119 {
120         cerr << name() << " ::apocom(), create DW + DR\n";
121
122         DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable;
123
124         if (_mode == Destructive && !Profile->get_trx()) {
125                 dflags = DiskIOProcessor::Flag (dflags | DiskIOProcessor::Destructive);
126         } else if (_mode == NonLayered){
127                 dflags = DiskIOProcessor::Flag(dflags | DiskIOProcessor::NonLayered);
128         }
129
130         _disk_reader.reset (new DiskReader (_session, name(), dflags));
131         _disk_reader->set_block_size (_session.get_block_size ());
132         _disk_reader->set_route (boost::dynamic_pointer_cast<Route> (shared_from_this()));
133
134         _disk_writer.reset (new DiskWriter (_session, name(), dflags));
135         _disk_writer->set_block_size (_session.get_block_size ());
136         _disk_writer->set_route (boost::dynamic_pointer_cast<Route> (shared_from_this()));
137 }
138
139 void
140 Track::input_changed ()
141 {
142         if (_disk_writer && _alignment_choice == Automatic) {
143                 set_align_choice_from_io ();
144         }
145 }
146
147 XMLNode&
148 Track::get_state ()
149 {
150         return state (true);
151 }
152
153 XMLNode&
154 Track::state (bool full)
155 {
156         XMLNode& root (Route::state (full));
157
158         if (_playlists[DataType::AUDIO]) {
159                 root.set_property (X_("audio-playlist"), _playlists[DataType::AUDIO]->id().to_s());
160         }
161
162         if (_playlists[DataType::MIDI]) {
163                 root.set_property (X_("midi-playlist"), _playlists[DataType::MIDI]->id().to_s());
164         }
165
166         root.add_child_nocopy (_monitoring_control->get_state ());
167         root.add_child_nocopy (_record_safe_control->get_state ());
168         root.add_child_nocopy (_record_enable_control->get_state ());
169
170         root.set_property (X_("saved-meter-point"), _saved_meter_point);
171         root.set_property (X_("disk-io-point"), _disk_io_point);
172         root.set_property (X_("alignment-choice"), _alignment_choice);
173
174         return root;
175 }
176
177 int
178 Track::set_state (const XMLNode& node, int version)
179 {
180         if (Route::set_state (node, version)) {
181                 return -1;
182         }
183
184         XMLNode* child;
185
186         if (version >= 3000 && version < 4000) {
187                 if ((child = find_named_node (node, X_("Diskstream"))) != 0) {
188                         /* XXX if we remember anything from stored DiskStream
189                            state (older Ardour versions) that is needed by a
190                            DiskReader or DiskWriter, we should cook up a new
191                            XMLNode here, populate it with that information
192                            (child nodes, properties, etc.) and then call
193                            ::set_state() on the writer/reader.
194
195                            But at present (June 2017), there's no such state.
196                         */
197                 }
198         }
199
200         std::string playlist_id;
201
202         if (node.get_property (X_("audio-playlist"), playlist_id)) {
203                 find_and_use_playlist (DataType::AUDIO, PBD::ID (playlist_id));
204         }
205
206         if (node.get_property (X_("midi-playlist"), playlist_id)) {
207                 find_and_use_playlist (DataType::MIDI, PBD::ID (playlist_id));
208         }
209
210         XMLNodeList nlist = node.children();
211         for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
212                 child = *niter;
213
214                 if (child->name() == Controllable::xml_node_name) {
215                         std::string name;
216                         if (!child->get_property ("name", name)) {
217                                 continue;
218                         }
219
220                         if (name == _record_enable_control->name()) {
221                                 _record_enable_control->set_state (*child, version);
222                         } else if (name == _record_safe_control->name()) {
223                                 _record_safe_control->set_state (*child, version);
224                         } else if (name == _monitoring_control->name()) {
225                                 _monitoring_control->set_state (*child, version);
226                         }
227                 }
228         }
229
230         if (!node.get_property (X_("saved-meter-point"), _saved_meter_point)) {
231                 _saved_meter_point = _meter_point;
232         }
233
234         if (!node.get_property (X_("saved-meter-point"), _disk_io_point)) {
235                 _disk_io_point = DiskIOPreFader;
236         }
237
238         AlignChoice ac;
239
240         if (node.get_property (X_("alignment-choice"), ac)) {
241                 set_align_choice (ac, true);
242         }
243
244         return 0;
245 }
246
247 XMLNode&
248 Track::get_template ()
249 {
250         return state (false);
251 }
252
253 Track::FreezeRecord::~FreezeRecord ()
254 {
255         for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
256                 delete *i;
257         }
258 }
259
260 Track::FreezeState
261 Track::freeze_state() const
262 {
263         return _freeze_record.state;
264 }
265
266 bool
267 Track::can_record()
268 {
269         bool will_record = true;
270         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
271                 if (!i->connected())
272                         will_record = false;
273         }
274
275         return will_record;
276 }
277
278 int
279 Track::prep_record_enabled (bool yn)
280 {
281         if (yn && _record_safe_control->get_value()) {
282                 return -1;
283         }
284
285         if (!can_be_record_enabled()) {
286                 return -1;
287         }
288
289         /* keep track of the meter point as it was before we rec-enabled */
290         if (!_disk_writer->record_enabled()) {
291                 _saved_meter_point = _meter_point;
292         }
293
294         bool will_follow;
295
296         if (yn) {
297                 will_follow = _disk_writer->prep_record_enable ();
298         } else {
299                 will_follow = _disk_writer->prep_record_disable ();
300         }
301
302         if (will_follow) {
303                 if (yn) {
304                         if (_meter_point != MeterCustom) {
305                                 set_meter_point (MeterInput);
306                         }
307                 } else {
308                         set_meter_point (_saved_meter_point);
309                 }
310         }
311
312         return 0;
313 }
314
315 void
316 Track::record_enable_changed (bool, Controllable::GroupControlDisposition)
317 {
318         _disk_writer->set_record_enabled (_record_enable_control->get_value());
319 }
320
321 void
322 Track::record_safe_changed (bool, Controllable::GroupControlDisposition)
323 {
324         _disk_writer->set_record_safe (_record_safe_control->get_value());
325 }
326
327 bool
328 Track::can_be_record_safe ()
329 {
330         return !_record_enable_control->get_value() && _disk_writer && _session.writable() && (_freeze_record.state != Frozen);
331 }
332
333 bool
334 Track::can_be_record_enabled ()
335 {
336         return !_record_safe_control->get_value() && _disk_writer && !_disk_writer->record_safe() && _session.writable() && (_freeze_record.state != Frozen);
337 }
338
339 void
340 Track::parameter_changed (string const & p)
341 {
342         if (p == "track-name-number") {
343                 resync_track_name ();
344         }
345         else if (p == "track-name-take") {
346                 resync_track_name ();
347         }
348         else if (p == "take-name") {
349                 if (_session.config.get_track_name_take()) {
350                         resync_track_name ();
351                 }
352         }
353 }
354
355 void
356 Track::resync_track_name ()
357 {
358         set_name(name());
359 }
360
361 bool
362 Track::set_name (const string& str)
363 {
364         bool ret;
365
366         if (str.empty ()) {
367                 return false;
368         }
369
370         if (_record_enable_control->get_value()) {
371                 /* when re-arm'ed the file (named after the track) is already ready to rolll */
372                 return false;
373         }
374
375         string diskstream_name = "";
376         if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) {
377                 // Note: any text is fine, legalize_for_path() fixes this later
378                 diskstream_name += _session.config.get_take_name ();
379                 diskstream_name += "_";
380         }
381         const int64_t tracknumber = track_number();
382         if (tracknumber > 0 && _session.config.get_track_name_number()) {
383                 char num[64], fmt[10];
384                 snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals());
385                 snprintf(num, sizeof(num), fmt, tracknumber);
386                 diskstream_name += num;
387                 diskstream_name += "_";
388         }
389         diskstream_name += str;
390
391         if (diskstream_name == _diskstream_name) {
392                 return true;
393         }
394         _diskstream_name = diskstream_name;
395
396         _disk_writer->set_write_source_name (diskstream_name);
397
398         boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
399
400         if (_playlists[data_type()]->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) {
401                 /* Only rename the diskstream (and therefore the playlist) if
402                    a) the playlist has never had a region added to it and
403                    b) there is only one playlist for this track.
404
405                    If (a) is not followed, people can get confused if, say,
406                    they have notes about a playlist with a given name and then
407                    it changes (see mantis #4759).
408
409                    If (b) is not followed, we rename the current playlist and not
410                    the other ones, which is a bit confusing (see mantis #4977).
411                 */
412                 _disk_reader->set_name (str);
413                 _disk_writer->set_name (str);
414         }
415
416         for (uint32_t n = 0; n < DataType::num_types; ++n) {
417                 if (_playlists[n]) {
418                         _playlists[n]->set_name (str);
419                 }
420         }
421
422         /* save state so that the statefile fully reflects any filename changes */
423
424         if ((ret = Route::set_name (str)) == 0) {
425                 _session.save_state ("");
426         }
427
428         return ret;
429 }
430
431 void
432 Track::set_latency_compensation (framecnt_t longest_session_latency)
433 {
434         Route::set_latency_compensation (longest_session_latency);
435         _disk_reader->set_roll_delay (_roll_delay);
436 }
437
438 int
439 Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing)
440 {
441         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
442
443         if (!lm.locked()) {
444                 return 0;
445         }
446
447         bool can_record = _session.actively_recording ();
448
449         /* no outputs? nothing to do ... what happens if we have sends etc. ? */
450
451         if (n_outputs().n_total() == 0 && !ARDOUR::Profile->get_mixbus()) {
452                 //Note: Mixbus has its own output mechanism, so we should operate even if no explicit outputs are assigned
453                 return 0;
454         }
455
456         /* not active ... do the minimum possible by just outputting silence */
457
458         if (!_active) {
459                 silence (nframes);
460                 if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
461                         _meter->reset();
462                 }
463                 return 0;
464         }
465
466         if (session_state_changing) {
467                 if (_session.transport_speed() != 0.0f) {
468                         /* we're rolling but some state is changing (e.g. our
469                            disk reader contents) so we cannot use them. Be
470                            silent till this is over. Don't declick.
471
472                            XXX note the absurdity of ::no_roll() being called when we ARE rolling!
473                         */
474                         passthru_silence (start_frame, end_frame, nframes, 0);
475                         return 0;
476                 }
477                 /* we're really not rolling, so we're either delivery silence or actually
478                    monitoring, both of which are safe to do while session_state_changing is true.
479                 */
480         }
481
482         _disk_writer->check_record_status (start_frame, can_record);
483
484         bool be_silent;
485
486         MonitorState const s = monitoring_state ();
487         /* we are not rolling, so be silent even if we are monitoring disk, as there
488            will be no disk data coming in.
489         */
490         switch (s) {
491         case MonitoringSilence:
492                 be_silent = true;
493                 break;
494         case MonitoringDisk:
495                 be_silent = true;
496                 break;
497         case MonitoringInput:
498                 be_silent = false;
499                 break;
500         default:
501                 be_silent = false;
502                 break;
503         }
504
505         //if we have an internal generator, let it play regardless of monitoring state
506         if (_have_internal_generator) {
507                 be_silent = false;
508         }
509
510         _amp->apply_gain_automation (false);
511
512         /* if have_internal_generator, or .. */
513
514         if (be_silent) {
515
516                 if (_meter_point == MeterInput) {
517                         /* still need input monitoring and metering */
518
519                         bool const track_rec = _disk_writer->record_enabled ();
520                         bool const auto_input = _session.config.get_auto_input ();
521                         bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
522                         bool const tape_machine_mode = Config->get_tape_machine_mode ();
523                         bool no_meter = false;
524
525                         /* this needs a proper K-map
526                          * and should be separated into a function similar to monitoring_state()
527                          * that also handles roll() states in audio_track.cc, midi_track.cc and route.cc
528                          *
529                          * see http://www.oofus.co.uk/ardour/Ardour3MonitorModesV3.pdf
530                          */
531                         if (!auto_input && !track_rec) {
532                                 no_meter=true;
533                         }
534                         else if (tape_machine_mode && !track_rec && auto_input) {
535                                 no_meter=true;
536                         }
537                         else if (!software_monitor && tape_machine_mode && !track_rec) {
538                                 no_meter=true;
539                         }
540                         else if (!software_monitor && !tape_machine_mode && !track_rec && !auto_input) {
541                                 no_meter=true;
542                         }
543
544                         if (no_meter) {
545                                 BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
546                                 _meter->run (bufs, start_frame, end_frame, 1.0, nframes, true);
547                                 _input->process_input (boost::shared_ptr<Processor>(), start_frame, end_frame, _session.transport_speed(), nframes);
548                         } else {
549                                 _input->process_input (_meter, start_frame, end_frame, _session.transport_speed(), nframes);
550                         }
551                 }
552
553                 passthru_silence (start_frame, end_frame, nframes, 0);
554
555         } else {
556
557                 BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
558
559                 fill_buffers_with_input (bufs, _input, nframes);
560
561                 if (_meter_point == MeterInput) {
562                         _meter->run (bufs, start_frame, end_frame, _session.transport_speed(), nframes, true);
563                 }
564
565                 passthru (bufs, start_frame, end_frame, nframes, false);
566         }
567
568         flush_processor_buffers_locked (nframes);
569
570         return 0;
571 }
572
573 int
574 Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, bool& need_butler)
575 {
576         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
577         if (!lm.locked()) {
578                 // XXX DISK reader needs to seek ahead the correct distance ?? OR DOES IT ?
579                 //framecnt_t playback_distance = _disk_reader->calculate_playback_distance(nframes);
580                 //if (can_internal_playback_seek(playback_distance)) {
581                 // internal_playback_seek(playback_distance);
582                 //}
583                 return 0;
584         }
585
586         if (n_outputs().n_total() == 0 && _processors.empty()) {
587                 return 0;
588         }
589
590         if (!_active) {
591                 silence (nframes);
592                 return 0;
593         }
594
595         _silent = true;
596         _amp->apply_gain_automation(false);
597
598         silence (nframes);
599         flush_processor_buffers_locked (nframes);
600
601         //BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true));
602         // XXXX DISKWRITER/READER ADVANCE, SET need_butler
603         return 0;
604 }
605
606 boost::shared_ptr<Playlist>
607 Track::playlist ()
608 {
609         return _playlists[data_type()];
610 }
611
612 void
613 Track::request_input_monitoring (bool m)
614 {
615         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
616                 AudioEngine::instance()->request_input_monitoring ((*i)->name(), m);
617         }
618 }
619
620 void
621 Track::ensure_input_monitoring (bool m)
622 {
623         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
624                 AudioEngine::instance()->ensure_input_monitoring ((*i)->name(), m);
625         }
626 }
627
628 bool
629 Track::destructive () const
630 {
631         return _disk_writer->destructive ();
632 }
633
634 list<boost::shared_ptr<Source> > &
635 Track::last_capture_sources ()
636 {
637         return _disk_writer->last_capture_sources ();
638 }
639
640 void
641 Track::update_latency_information ()
642 {
643         Glib::Threads::RWLock::ReaderLock lr (_processor_lock);
644         framecnt_t chain_latency = _input->latency ();
645
646         for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) {
647                 (*p)->set_input_latency (chain_latency);
648                 chain_latency += (*p)->signal_latency ();
649         }
650 }
651
652 std::string
653 Track::steal_write_source_name()
654 {
655         return _disk_writer->steal_write_source_name ();
656 }
657
658 void
659 Track::reset_write_sources (bool r, bool force)
660 {
661         _disk_writer->reset_write_sources (r, force);
662 }
663
664 float
665 Track::playback_buffer_load () const
666 {
667         return _disk_reader->buffer_load ();
668 }
669
670 float
671 Track::capture_buffer_load () const
672 {
673         return _disk_writer->buffer_load ();
674 }
675
676 int
677 Track::do_refill ()
678 {
679         return _disk_reader->do_refill ();
680 }
681
682 int
683 Track::do_flush (RunContext c, bool force)
684 {
685         return _disk_writer->do_flush (c, force);
686 }
687
688 void
689 Track::set_pending_overwrite (bool o)
690 {
691         _disk_reader->set_pending_overwrite (o);
692 }
693
694 int
695 Track::seek (framepos_t p, bool complete_refill)
696 {
697         if (_disk_reader->seek (p, complete_refill)) {
698                 return -1;
699         }
700         return _disk_writer->seek (p, complete_refill);
701 }
702
703 int
704 Track::can_internal_playback_seek (framecnt_t p)
705 {
706         return _disk_reader->can_internal_playback_seek (p);
707 }
708
709 int
710 Track::internal_playback_seek (framecnt_t p)
711 {
712         return _disk_reader->internal_playback_seek (p);
713 }
714
715 void
716 Track::non_realtime_locate (framepos_t p)
717 {
718         Route::non_realtime_locate (p);
719
720         if (!is_private_route()) {
721                 /* don't waste i/o cycles and butler calls
722                    for private tracks (e.g.auditioner)
723                 */
724                 _disk_reader->non_realtime_locate (p);
725                 _disk_writer->non_realtime_locate (p);
726         }
727 }
728
729 void
730 Track::non_realtime_speed_change ()
731 {
732         _disk_reader->non_realtime_speed_change ();
733 }
734
735 int
736 Track::overwrite_existing_buffers ()
737 {
738         return _disk_reader->overwrite_existing_buffers ();
739 }
740
741 framecnt_t
742 Track::get_captured_frames (uint32_t n) const
743 {
744         return _disk_writer->get_captured_frames (n);
745 }
746
747 int
748 Track::set_loop (Location* l)
749 {
750         if (_disk_reader->set_loop (l)) {
751                 return -1;
752         }
753         return _disk_writer->set_loop (l);
754 }
755
756 void
757 Track::transport_looped (framepos_t p)
758 {
759         return _disk_writer->transport_looped (p);
760 }
761
762 bool
763 Track::realtime_speed_change ()
764 {
765         if (_disk_reader->realtime_speed_change ()) {
766                 return -1;
767         }
768         return _disk_writer->realtime_speed_change ();
769 }
770
771 void
772 Track::realtime_handle_transport_stopped ()
773 {
774         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
775
776         if (!lm.locked ()) {
777                 return;
778         }
779
780         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
781                 (*i)->realtime_handle_transport_stopped ();
782         }
783 }
784
785 void
786 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
787 {
788         _disk_writer->transport_stopped_wallclock (n, t, g);
789 }
790
791 bool
792 Track::pending_overwrite () const
793 {
794         return _disk_reader->pending_overwrite ();
795 }
796
797 void
798 Track::prepare_to_stop (framepos_t t, framepos_t a)
799 {
800         _disk_writer->prepare_to_stop (t, a);
801 }
802
803 void
804 Track::set_slaved (bool s)
805 {
806         _disk_reader->set_slaved (s);
807         _disk_writer->set_slaved (s);
808 }
809
810 ChanCount
811 Track::n_channels ()
812 {
813         return _disk_reader->output_streams();
814 }
815
816 framepos_t
817 Track::get_capture_start_frame (uint32_t n) const
818 {
819         return _disk_writer->get_capture_start_frame (n);
820 }
821
822 AlignStyle
823 Track::alignment_style () const
824 {
825         return _disk_writer->alignment_style ();
826 }
827
828 AlignChoice
829 Track::alignment_choice () const
830 {
831         return _disk_writer->alignment_choice ();
832 }
833
834 framepos_t
835 Track::current_capture_start () const
836 {
837         return _disk_writer->current_capture_start ();
838 }
839
840 framepos_t
841 Track::current_capture_end () const
842 {
843         return _disk_writer->current_capture_end ();
844 }
845
846 void
847 Track::playlist_modified ()
848 {
849         _disk_reader->playlist_modified ();
850 }
851
852 int
853 Track::find_and_use_playlist (DataType dt, PBD::ID const & id)
854 {
855         boost::shared_ptr<Playlist> playlist;
856
857         if ((playlist = _session.playlists->by_id (id)) == 0) {
858                 return -1;
859         }
860
861         if (!playlist) {
862                 error << string_compose(_("DiskIOProcessor: \"%1\" isn't an playlist"), id.to_s()) << endmsg;
863                 return -1;
864         }
865
866         return use_playlist (dt, playlist);
867 }
868
869 int
870 Track::use_playlist (DataType dt, boost::shared_ptr<Playlist> p)
871 {
872         int ret;
873
874         if ((ret = _disk_reader->use_playlist (dt, p)) == 0) {
875                 if ((ret = _disk_writer->use_playlist (dt, p)) == 0) {
876                         p->set_orig_track_id (id());
877                 }
878         }
879
880         if (ret == 0) {
881                 _playlists[dt] = p;
882         }
883
884         return ret;
885 }
886
887 int
888 Track::use_copy_playlist ()
889 {
890         assert (_playlists[data_type()]);
891
892         if (_playlists[data_type()] == 0) {
893                 error << string_compose(_("DiskIOProcessor %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
894                 return -1;
895         }
896
897         string newname;
898         boost::shared_ptr<Playlist> playlist;
899
900         newname = Playlist::bump_name (_playlists[data_type()]->name(), _session);
901
902         if ((playlist = PlaylistFactory::create (_playlists[data_type()], newname)) == 0) {
903                 return -1;
904         }
905
906         playlist->reset_shares();
907
908         return use_playlist (data_type(), playlist);
909 }
910
911 int
912 Track::use_new_playlist (DataType dt)
913 {
914         string newname;
915         boost::shared_ptr<Playlist> playlist = _playlists[dt];
916
917         if (playlist) {
918                 newname = Playlist::bump_name (playlist->name(), _session);
919         } else {
920                 newname = Playlist::bump_name (_name, _session);
921         }
922
923         playlist = PlaylistFactory::create (dt, _session, newname, is_private_route());
924
925         if (!playlist) {
926                 return -1;
927         }
928
929         return use_playlist (dt, playlist);
930 }
931
932 void
933 Track::set_align_choice (AlignChoice ac, bool force)
934 {
935         switch (ac) {
936         case Automatic:
937                 _alignment_choice = Automatic;
938                 set_align_choice_from_io ();
939                 return;
940         default:
941                 break;
942         }
943
944         _disk_writer->set_align_choice (ac, force);
945         _alignment_choice = ac;
946 }
947
948 void
949 Track::set_align_style (AlignStyle s, bool force)
950 {
951         _disk_writer->set_align_style (s, force);
952 }
953
954 void
955 Track::set_align_choice_from_io ()
956 {
957         bool have_physical = false;
958
959         if (_input) {
960                 uint32_t n = 0;
961                 vector<string> connections;
962                 boost::shared_ptr<Port> p;
963
964                 while (true) {
965
966                         p = _input->nth (n++);
967
968                         if (!p) {
969                                 break;
970                         }
971
972                         if (p->get_connections (connections) != 0) {
973                                 if (AudioEngine::instance()->port_is_physical (connections[0])) {
974                                         have_physical = true;
975                                         break;
976                                 }
977                         }
978
979                         connections.clear ();
980                 }
981         }
982
983 #ifdef MIXBUS
984         // compensate for latency when bouncing from master or mixbus.
985         // we need to use "ExistingMaterial" to pick up the master bus' latency
986         // see also Route::direct_feeds_according_to_reality
987         IOVector ios;
988         ios.push_back (_input);
989         if (_session.master_out() && ios.fed_by (_session.master_out()->output())) {
990                 have_physical = true;
991         }
992         for (uint32_t n = 0; n < NUM_MIXBUSES && !have_physical; ++n) {
993                 if (_session.get_mixbus (n) && ios.fed_by (_session.get_mixbus(n)->output())) {
994                         have_physical = true;
995                 }
996         }
997 #endif
998
999         if (have_physical) {
1000                 _disk_writer->set_align_style (ExistingMaterial);
1001         } else {
1002                 _disk_writer->set_align_style (CaptureTime);
1003         }
1004 }
1005
1006 void
1007 Track::set_block_size (pframes_t n)
1008 {
1009         Route::set_block_size (n);
1010         _disk_reader->set_block_size (n);
1011         _disk_writer->set_block_size (n);
1012 }
1013
1014 void
1015 Track::adjust_playback_buffering ()
1016 {
1017         if (_disk_reader) {
1018                 _disk_reader->adjust_buffering ();
1019         }
1020 }
1021
1022 void
1023 Track::adjust_capture_buffering ()
1024 {
1025         if (_disk_writer) {
1026                 _disk_writer->adjust_buffering ();
1027         }
1028 }
1029
1030 #ifdef USE_TRACKS_CODE_FEATURES
1031
1032 /* This is the Tracks version of Track::monitoring_state().
1033  *
1034  * Ardour developers: try to flag or fix issues if parts of the libardour API
1035  * change in ways that invalidate this
1036  */
1037
1038 MonitorState
1039 Track::monitoring_state () const
1040 {
1041         /* Explicit requests */
1042
1043         if (_monitoring != MonitorInput) {
1044                 return MonitoringInput;
1045         }
1046
1047         if (_monitoring & MonitorDisk) {
1048                 return MonitoringDisk;
1049         }
1050
1051         /* This is an implementation of the truth table in doc/monitor_modes.pdf;
1052            I don't think it's ever going to be too pretty too look at.
1053         */
1054
1055         // GZ: NOT USED IN TRACKS
1056         //bool const auto_input = _session.config.get_auto_input ();
1057         //bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
1058         //bool const tape_machine_mode = Config->get_tape_machine_mode ();
1059
1060         bool const roll = _session.transport_rolling ();
1061         bool const track_rec = _diskstream->record_enabled ();
1062         bool session_rec = _session.actively_recording ();
1063
1064         if (track_rec) {
1065
1066                 if (!session_rec && roll) {
1067                         return MonitoringDisk;
1068                 } else {
1069                         return MonitoringInput;
1070                 }
1071
1072         } else {
1073
1074                 if (roll) {
1075                         return MonitoringDisk;
1076                 }
1077         }
1078
1079         return MonitoringSilence;
1080 }
1081
1082 #else
1083
1084 /* This is the Ardour/Mixbus version of Track::monitoring_state().
1085  *
1086  * Tracks developers: do NOT modify this method under any circumstances.
1087  */
1088
1089 MonitorState
1090 Track::monitoring_state () const
1091 {
1092         /* Explicit requests */
1093         MonitorChoice m (_monitoring_control->monitoring_choice());
1094
1095         if (m != MonitorAuto) {
1096
1097                 MonitorState ms ((MonitorState) 0);
1098
1099                 if (m & MonitorInput) {
1100                         ms = MonitoringInput;
1101                 }
1102
1103                 if (m & MonitorDisk) {
1104                         ms = MonitorState (ms | MonitoringDisk);
1105                 }
1106
1107                 return ms;
1108         }
1109
1110         switch (_session.config.get_session_monitoring ()) {
1111                 case MonitorDisk:
1112                         return MonitoringDisk;
1113                         break;
1114                 case MonitorInput:
1115                         return MonitoringInput;
1116                         break;
1117                 default:
1118                         break;
1119         }
1120
1121         /* This is an implementation of the truth table in doc/monitor_modes.pdf;
1122            I don't think it's ever going to be too pretty too look at.
1123         */
1124
1125         bool const roll = _session.transport_rolling ();
1126         bool const track_rec = _disk_writer->record_enabled ();
1127         bool const auto_input = _session.config.get_auto_input ();
1128         bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
1129         bool const tape_machine_mode = Config->get_tape_machine_mode ();
1130         bool session_rec;
1131
1132         /* I suspect that just use actively_recording() is good enough all the
1133          * time, but just to keep the semantics the same as they were before
1134          * sept 26th 2012, we differentiate between the cases where punch is
1135          * enabled and those where it is not.
1136          *
1137          * rg: I suspect this is not the case: monitoring may differ
1138          */
1139
1140         if (_session.config.get_punch_in() || _session.config.get_punch_out() || _session.preroll_record_punch_enabled ()) {
1141                 session_rec = _session.actively_recording ();
1142         } else {
1143                 session_rec = _session.get_record_enabled();
1144         }
1145
1146         if (track_rec) {
1147
1148                 if (!session_rec && roll && auto_input) {
1149                         return MonitoringDisk;
1150                 } else {
1151                         return software_monitor ? MonitoringInput : MonitoringSilence;
1152                 }
1153
1154         } else {
1155
1156                 if (tape_machine_mode) {
1157
1158                         return MonitoringDisk;
1159
1160                 } else {
1161
1162                         if (!roll && auto_input) {
1163                                 return software_monitor ? MonitoringInput : MonitoringSilence;
1164                         } else {
1165                                 return MonitoringDisk;
1166                         }
1167
1168                 }
1169         }
1170
1171         abort(); /* NOTREACHED */
1172         return MonitoringSilence;
1173 }
1174
1175 #endif
1176
1177 void
1178 Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
1179 {
1180         /* never declick if there is an internal generator - we just want it to
1181            keep generating sound without interruption.
1182
1183            ditto if we are monitoring inputs.
1184         */
1185
1186         if (_have_internal_generator || (_monitoring_control->monitoring_choice() == MonitorInput)) {
1187                 return;
1188         }
1189
1190         if (!declick) {
1191                 declick = _pending_declick;
1192         }
1193
1194         if (declick != 0) {
1195                 Amp::declick (bufs, nframes, declick);
1196         }
1197 }
1198
1199 framecnt_t
1200 Track::check_initial_delay (framecnt_t nframes, framepos_t& transport_frame)
1201 {
1202         if (_roll_delay > nframes) {
1203
1204                 _roll_delay -= nframes;
1205                 silence_unlocked (nframes);
1206                 /* transport frame is not legal for caller to use */
1207                 return 0;
1208
1209         } else if (_roll_delay > 0) {
1210
1211                 nframes -= _roll_delay;
1212                 silence_unlocked (_roll_delay);
1213                 transport_frame += _roll_delay;
1214
1215                 /* shuffle all the port buffers for things that lead "out" of this Route
1216                    to reflect that we just wrote _roll_delay frames of silence.
1217                 */
1218
1219                 Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
1220                 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1221                         boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
1222                         if (iop) {
1223                                 iop->increment_port_buffer_offset (_roll_delay);
1224                         }
1225                 }
1226                 _output->increment_port_buffer_offset (_roll_delay);
1227
1228                 _roll_delay = 0;
1229
1230         }
1231
1232         return nframes;
1233 }
1234
1235 void
1236 Track::monitoring_changed (bool, Controllable::GroupControlDisposition)
1237 {
1238         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1239                 (*i)->monitoring_changed ();
1240         }
1241 }
1242
1243 MeterState
1244 Track::metering_state () const
1245 {
1246         bool rv;
1247         if (_session.transport_rolling ()) {
1248                 // audio_track.cc || midi_track.cc roll() runs meter IFF:
1249                 rv = _meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled());
1250         } else {
1251                 // track no_roll() always metering if
1252                 rv = _meter_point == MeterInput;
1253         }
1254         return rv ? MeteringInput : MeteringRoute;
1255 }
1256
1257 bool
1258 Track::set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure)
1259 {
1260         if (Route::set_processor_state (node, prop, new_order, must_configure)) {
1261                 return true;
1262         }
1263
1264         if (prop->value() == "diskreader") {
1265                 if (_disk_reader) {
1266                         _disk_reader->set_state (node, Stateful::current_state_version);
1267                         new_order.push_back (_disk_reader);
1268                         return true;
1269                 }
1270         } else if (prop->value() == "diskwriter") {
1271                 if (_disk_writer) {
1272                         _disk_writer->set_state (node, Stateful::current_state_version);
1273                         new_order.push_back (_disk_writer);
1274                         return true;
1275                 }
1276         }
1277
1278         error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
1279         return false;
1280 }
1281
1282 void
1283 Track::use_captured_sources (SourceList& srcs, CaptureInfos const & capture_info)
1284 {
1285         if (srcs.empty()) {
1286                 return;
1287         }
1288
1289         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
1290         boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
1291
1292         if (afs) {
1293                 use_captured_audio_sources (srcs, capture_info);
1294         }
1295
1296         if (mfs) {
1297                 use_captured_midi_sources (srcs, capture_info);
1298         }
1299 }
1300
1301 void
1302 Track::use_captured_midi_sources (SourceList& srcs, CaptureInfos const & capture_info)
1303 {
1304         if (srcs.empty() || data_type() != DataType::MIDI) {
1305                 return;
1306         }
1307
1308         boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
1309         boost::shared_ptr<Playlist> pl = _playlists[DataType::MIDI];
1310         boost::shared_ptr<MidiRegion> midi_region;
1311         CaptureInfos::const_iterator ci;
1312
1313         if (!mfs || !pl) {
1314                 return;
1315         }
1316
1317         framecnt_t total_capture = 0;
1318
1319         for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1320                 total_capture += (*ci)->frames;
1321         }
1322
1323         /* we will want to be able to keep (over)writing the source
1324            but we don't want it to be removable. this also differs
1325            from the audio situation, where the source at this point
1326            must be considered immutable. luckily, we can rely on
1327            MidiSource::mark_streaming_write_completed() to have
1328            already done the necessary work for that.
1329         */
1330
1331         string whole_file_region_name;
1332         whole_file_region_name = region_name_from_path (mfs->name(), true);
1333
1334         /* Register a new region with the Session that
1335            describes the entire source. Do this first
1336            so that any sub-regions will obviously be
1337            children of this one (later!)
1338         */
1339
1340         try {
1341                 PropertyList plist;
1342
1343                 plist.add (Properties::name, whole_file_region_name);
1344                 plist.add (Properties::whole_file, true);
1345                 plist.add (Properties::automatic, true);
1346                 plist.add (Properties::start, 0);
1347                 plist.add (Properties::length, total_capture);
1348                 plist.add (Properties::layer, 0);
1349
1350                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1351
1352                 midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1353                 midi_region->special_set_position (capture_info.front()->start);
1354         }
1355
1356         catch (failed_constructor& err) {
1357                 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1358                 /* XXX what now? */
1359         }
1360
1361         pl->clear_changes ();
1362         pl->freeze ();
1363
1364         /* Session frame time of the initial capture in this pass, which is where the source starts */
1365         framepos_t initial_capture = 0;
1366         if (!capture_info.empty()) {
1367                 initial_capture = capture_info.front()->start;
1368         }
1369
1370         BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
1371         const framepos_t preroll_off = _session.preroll_record_trim_len ();
1372
1373         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1374
1375                 string region_name;
1376
1377                 RegionFactory::region_name (region_name, mfs->name(), false);
1378
1379                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1380                                                                       _name, (*ci)->start, (*ci)->frames, region_name));
1381
1382
1383                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1384
1385                 try {
1386                         PropertyList plist;
1387
1388                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
1389                         plist.add (Properties::start, (*ci)->start - initial_capture);
1390                         plist.add (Properties::length, (*ci)->frames);
1391                         plist.add (Properties::length_beats, converter.from((*ci)->frames).to_double());
1392                         plist.add (Properties::name, region_name);
1393
1394                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1395                         midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1396                         if (preroll_off > 0) {
1397                                 midi_region->trim_front ((*ci)->start - initial_capture + preroll_off);
1398                         }
1399                 }
1400
1401                 catch (failed_constructor& err) {
1402                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1403                         continue; /* XXX is this OK? */
1404                 }
1405
1406                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1407
1408                 pl->add_region (midi_region, (*ci)->start + preroll_off);
1409         }
1410
1411         pl->thaw ();
1412         _session.add_command (new StatefulDiffCommand (pl));
1413 }
1414
1415 void
1416 Track::use_captured_audio_sources (SourceList& srcs, CaptureInfos const & capture_info)
1417 {
1418         if (srcs.empty() || data_type() != DataType::AUDIO) {
1419                 return;
1420         }
1421
1422         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
1423         boost::shared_ptr<Playlist> pl = _playlists[DataType::AUDIO];
1424         boost::shared_ptr<AudioRegion> region;
1425
1426         if (!afs || !pl) {
1427                 return;
1428         }
1429
1430         /* destructive tracks have a single, never changing region */
1431
1432         if (destructive()) {
1433
1434                 /* send a signal that any UI can pick up to do the right thing. there is
1435                    a small problem here in that a UI may need the peak data to be ready
1436                    for the data that was recorded and this isn't interlocked with that
1437                    process. this problem is deferred to the UI.
1438                  */
1439
1440                 pl->LayeringChanged(); // XXX this may not get the UI to do the right thing
1441                 return;
1442         }
1443
1444         string whole_file_region_name;
1445         whole_file_region_name = region_name_from_path (afs->name(), true);
1446
1447         /* Register a new region with the Session that
1448            describes the entire source. Do this first
1449            so that any sub-regions will obviously be
1450            children of this one (later!)
1451         */
1452
1453         try {
1454                 PropertyList plist;
1455
1456                 plist.add (Properties::start, afs->last_capture_start_frame());
1457                 plist.add (Properties::length, afs->length(0));
1458                 plist.add (Properties::name, whole_file_region_name);
1459                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1460                 rx->set_automatic (true);
1461                 rx->set_whole_file (true);
1462
1463                 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1464                 region->special_set_position (afs->natural_position());
1465         }
1466
1467
1468         catch (failed_constructor& err) {
1469                 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1470                 /* XXX what now? */
1471         }
1472
1473         pl->clear_changes ();
1474         pl->set_capture_insertion_in_progress (true);
1475         pl->freeze ();
1476
1477         const framepos_t preroll_off = _session.preroll_record_trim_len ();
1478         framecnt_t buffer_position = afs->last_capture_start_frame ();
1479         CaptureInfos::const_iterator ci;
1480
1481         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1482
1483                 string region_name;
1484
1485                 RegionFactory::region_name (region_name, whole_file_region_name, false);
1486
1487                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture bufpos %5 start @ %2 length %3 add new region %4\n",
1488                                                                       _name, (*ci)->start, (*ci)->frames, region_name, buffer_position));
1489
1490                 try {
1491
1492                         PropertyList plist;
1493
1494                         plist.add (Properties::start, buffer_position);
1495                         plist.add (Properties::length, (*ci)->frames);
1496                         plist.add (Properties::name, region_name);
1497
1498                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1499                         region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1500                         if (preroll_off > 0) {
1501                                 region->trim_front (buffer_position + preroll_off);
1502                         }
1503                 }
1504
1505                 catch (failed_constructor& err) {
1506                         error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1507                         continue; /* XXX is this OK? */
1508                 }
1509
1510                 pl->add_region (region, (*ci)->start + preroll_off, 1, _disk_writer->non_layered());
1511                 pl->set_layer (region, DBL_MAX);
1512
1513                 buffer_position += (*ci)->frames;
1514         }
1515
1516         pl->thaw ();
1517         pl->set_capture_insertion_in_progress (false);
1518         _session.add_command (new StatefulDiffCommand (pl));
1519 }
1520
1521 #ifdef __clang__
1522 __attribute__((annotate("realtime")))
1523 #endif
1524 void
1525 Track::setup_invisible_processors_oh_children_of_mine (ProcessorList& processors)
1526 {
1527         ProcessorList::iterator insert_pos;
1528
1529         switch (_disk_io_point) {
1530         case DiskIOPreFader:
1531                 insert_pos = find (processors.begin(), processors.end(), _trim);
1532                 if (insert_pos != processors.end()) {
1533                         insert_pos = processors.insert (insert_pos, _disk_writer);
1534                         processors.insert (insert_pos, _disk_reader);
1535                 }
1536                 break;
1537         case DiskIOPostFader:
1538                 insert_pos = find (processors.begin(), processors.end(), _main_outs);
1539                 if (insert_pos != processors.end()) {
1540                         insert_pos = processors.insert (insert_pos, _disk_writer);
1541                         processors.insert (insert_pos, _disk_reader);
1542                 }
1543         case DiskIOCustom:
1544                 break;
1545         }
1546 }
1547
1548 void
1549 Track::set_disk_io_position (DiskIOPoint diop)
1550 {
1551         bool display = false;
1552
1553         switch (diop) {
1554         case DiskIOCustom:
1555                 display = true;
1556                 break;
1557         default:
1558                 display = false;
1559         }
1560
1561         _disk_writer->set_display_to_user (display);
1562         _disk_reader->set_display_to_user (display);
1563
1564         const bool changed = (diop != _disk_io_point);
1565
1566         _disk_io_point = diop;
1567
1568         if (changed) {
1569                 Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
1570                 configure_processors (0);
1571         }
1572
1573         processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
1574 }