consolidate roll methods into Route::roll()

We want Track to shrink, and logic consolidation is always good. Route already knew about
disk_reader and disk_writer, now it knows about _monitoring_control too
This commit is contained in:
Paul Davis 2017-09-18 21:27:55 -04:00
parent 10b76ae631
commit 40aebce699
8 changed files with 195 additions and 293 deletions

View File

@ -37,9 +37,6 @@ class LIBARDOUR_API AudioTrack : public Track
AudioTrack (Session&, std::string name, TrackMode m = Normal);
~AudioTrack ();
int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample,
int declick, bool& need_butler);
void freeze_me (InterThreadInfo&);
void unfreeze ();

View File

@ -42,8 +42,6 @@ public:
int init ();
int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler);
void realtime_locate ();
void non_realtime_locate (samplepos_t);
@ -120,6 +118,8 @@ public:
MidiChannelFilter& playback_filter() { return _playback_filter; }
MidiChannelFilter& capture_filter() { return _capture_filter; }
virtual void filter_input (BufferSet& bufs);
boost::shared_ptr<MidiPlaylist> midi_playlist ();
PBD::Signal1<void, boost::weak_ptr<MidiSource> > DataRecorded;

View File

@ -77,6 +77,7 @@ class PluginInsert;
class RouteGroup;
class Send;
class InternalReturn;
class MonitorControl;
class MonitorProcessor;
class Pannable;
class CapturingProcessor;
@ -128,11 +129,15 @@ public:
bool set_name (const std::string& str);
static void set_name_in_state (XMLNode &, const std::string &, bool rename_playlist = true);
boost::shared_ptr<MonitorControl> monitoring_control() const { return _monitoring_control; }
MonitorState monitoring_state () const;
virtual MeterState metering_state () const;
/* these are the core of the API of a Route. see the protected sections as well */
virtual void filter_input (BufferSet &) {}
virtual int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample,
int declick, bool& need_butler);
@ -474,13 +479,6 @@ public:
return _solo_safe_control;
}
boost::shared_ptr<MonitorControl> monitoring_control() const {
/* tracks override this to provide actual monitoring control;
busses have no possible choices except input monitoring.
*/
return boost::shared_ptr<MonitorControl> ();
}
/* Route doesn't own these items, but sub-objects that it does own have them
and to make UI code a bit simpler, we provide direct access to them
here.
@ -603,7 +601,7 @@ public:
void fill_buffers_with_input (BufferSet& bufs, boost::shared_ptr<IO> io, pframes_t nframes);
void passthru (BufferSet&, samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, int declick);
void passthru (BufferSet&, samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, int declick, bool gain_automation_ok);
virtual void write_out_of_band_data (BufferSet& /* bufs */, samplepos_t /* start_sample */, samplepos_t /* end_sample */,
samplecnt_t /* nframes */) {}
@ -640,6 +638,7 @@ public:
boost::shared_ptr<Pannable> _pannable;
boost::shared_ptr<DiskReader> _disk_reader;
boost::shared_ptr<DiskWriter> _disk_writer;
boost::shared_ptr<MonitorControl> _monitoring_control;
DiskIOPoint _disk_io_point;

View File

@ -38,7 +38,6 @@ class DiskReader;
class DiskWriter;
class IO;
class Location;
class MonitorControl;
class RecordEnableControl;
class RecordSafeControl;
@ -62,9 +61,6 @@ class LIBARDOUR_API Track : public Route, public Recordable
TrackMode mode () const { return _mode; }
boost::shared_ptr<MonitorControl> monitoring_control() const { return _monitoring_control; }
MonitorState monitoring_state () const;
MeterState metering_state () const;
bool set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure);
@ -72,9 +68,6 @@ class LIBARDOUR_API Track : public Route, public Recordable
virtual int no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample,
bool state_changing);
virtual int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample,
int declick, bool& need_butler) = 0;
bool needs_butler() const { return _needs_butler; }
bool can_record();
@ -197,7 +190,6 @@ class LIBARDOUR_API Track : public Route, public Recordable
MeterPoint _saved_meter_point;
TrackMode _mode;
bool _needs_butler;
boost::shared_ptr<MonitorControl> _monitoring_control;
//private: (FIXME)
struct FreezeRecordProcessorInfo {

View File

@ -222,52 +222,6 @@ AudioTrack::set_state_part_two ()
}
}
/** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
* or set to false.
*/
int
AudioTrack::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler)
{
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) {
return 0;
}
if (n_outputs().n_total() == 0 && _processors.empty()) {
return 0;
}
if (!_active) {
silence (nframes);
if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
_meter->reset();
}
return 0;
}
_silent = false;
_amp->apply_gain_automation(false);
BufferSet& bufs = _session.get_route_buffers (n_process_buffers ());
fill_buffers_with_input (bufs, _input, nframes);
if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
_meter->run (bufs, start_sample, end_sample, 1.0 /*speed()*/, nframes, true);
}
process_output_buffers (bufs, start_sample, end_sample, nframes, declick, (!_disk_writer->record_enabled() && _session.transport_rolling()));
if (_disk_reader->need_butler() || _disk_writer->need_butler()) {
need_butler = true;
}
flush_processor_buffers_locked (nframes);
return 0;
}
int
AudioTrack::export_stuff (BufferSet& buffers, samplepos_t start, samplecnt_t nframes,
boost::shared_ptr<Processor> endpoint, bool include_endpoint, bool for_export, bool for_freeze)

View File

@ -317,61 +317,6 @@ MidiTrack::update_controls(const BufferSet& bufs)
}
}
/** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
* or set to false.
*/
int
MidiTrack::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler)
{
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) {
return 0;
}
if (n_outputs().n_total() == 0 && _processors.empty()) {
return 0;
}
if (!_active) {
silence (nframes);
if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
_meter->reset();
}
return 0;
}
_silent = false;
_amp->apply_gain_automation (false);
BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
fill_buffers_with_input (bufs, _input, nframes);
/* filter captured data before meter sees it */
_capture_filter.filter (bufs);
if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
_meter->run (bufs, start_sample, end_sample, 1.0 /*speed()*/, nframes, true);
}
/* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
write_out_of_band_data (bufs, start_sample, end_sample, nframes);
/* final argument: don't waste time with automation if we're not recording or rolling */
process_output_buffers (bufs, start_sample, end_sample, nframes, declick, (!_disk_writer->record_enabled() && !_session.transport_stopped()));
if (_disk_reader->need_butler() || _disk_writer->need_butler()) {
need_butler = true;
}
flush_processor_buffers_locked (nframes);
return 0;
}
int
MidiTrack::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing)
{
@ -863,3 +808,9 @@ MidiTrack::monitoring_state () const
}
return ms;
}
void
MidiTrack::filter_input (BufferSet& bufs)
{
_capture_filter.filter (bufs);
}

View File

@ -57,6 +57,7 @@
#include "ardour/delayline.h"
#include "ardour/midi_buffer.h"
#include "ardour/midi_port.h"
#include "ardour/monitor_control.h"
#include "ardour/monitor_processor.h"
#include "ardour/pannable.h"
#include "ardour/panner.h"
@ -598,11 +599,11 @@ Route::monitor_run (samplepos_t start_sample, samplepos_t end_sample, pframes_t
assert (is_monitor());
BufferSet& bufs (_session.get_route_buffers (n_process_buffers()));
fill_buffers_with_input (bufs, _input, nframes);
passthru (bufs, start_sample, end_sample, nframes, declick);
passthru (bufs, start_sample, end_sample, nframes, declick, true);
}
void
Route::passthru (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, int declick)
Route::passthru (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, int declick, bool gain_automation_ok)
{
_silent = false;
@ -616,8 +617,13 @@ Route::passthru (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
bufs.silence (nframes, 0);
}
/* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
write_out_of_band_data (bufs, start_sample, end_sample, nframes);
process_output_buffers (bufs, start_sample, end_sample, nframes, declick, true);
/* run processor chain */
process_output_buffers (bufs, start_sample, end_sample, nframes, declick, gain_automation_ok);
}
void
@ -3581,7 +3587,7 @@ Route::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sam
_amp->apply_gain_automation (false);
_trim->apply_gain_automation (false);
passthru (bufs, start_sample, end_sample, nframes, 0);
passthru (bufs, start_sample, end_sample, nframes, 0, true);
flush_processor_buffers_locked (nframes);
@ -3589,35 +3595,42 @@ Route::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sam
}
int
Route::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& /* need_butler */)
Route::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler)
{
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) {
return 0;
}
if (!_active) {
silence_unlocked (nframes);
return 0;
}
samplepos_t unused = 0;
if ((nframes = check_initial_delay (nframes, unused)) == 0) {
if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || (!_disk_writer || _disk_writer->record_enabled()))) {
_meter->reset();
}
return 0;
}
_silent = false;
_amp->apply_gain_automation(false);
BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
BufferSet& bufs = _session.get_route_buffers (n_process_buffers ());
fill_buffers_with_input (bufs, _input, nframes);
if (_meter_point == MeterInput) {
_meter->run (bufs, start_sample, end_sample, 1.0, nframes, true);
/* filter captured data before meter sees it */
filter_input (bufs);
if (_meter_point == MeterInput &&
((_monitoring_control->monitoring_choice() & MonitorInput) || (_disk_writer && _disk_writer->record_enabled()))) {
_meter->run (bufs, start_sample, end_sample, 1.0 /*speed()*/, nframes, true);
}
passthru (bufs, start_sample, end_sample, nframes, declick);
passthru (bufs, start_sample, end_sample, nframes, declick, ((_disk_writer && !_disk_writer->record_enabled()) && _session.transport_rolling()));
if ((_disk_reader && _disk_reader->need_butler()) || (_disk_writer && _disk_writer->need_butler())) {
need_butler = true;
}
flush_processor_buffers_locked (nframes);
@ -4811,15 +4824,6 @@ Route::processor_by_id (PBD::ID id) const
return boost::shared_ptr<Processor> ();
}
/** @return the monitoring state, or in other words what data we are pushing
* into the route (data from the inputs, data from disk or silence)
*/
MonitorState
Route::monitoring_state () const
{
return MonitoringInput;
}
/** @return what we should be metering; either the data coming from the input
* IO or the data that is flowing through the route.
*/
@ -5670,3 +5674,154 @@ Route::set_disk_io_point (DiskIOPoint diop)
processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
}
#ifdef USE_TRACKS_CODE_FEATURES
/* This is the Tracks version of Track::monitoring_state().
*
* Ardour developers: try to flag or fix issues if parts of the libardour API
* change in ways that invalidate this
*/
MonitorState
Route::monitoring_state () const
{
/* Explicit requests */
if (_monitoring != MonitorInput) {
return MonitoringInput;
}
if (_monitoring & MonitorDisk) {
return MonitoringDisk;
}
/* This is an implementation of the truth table in doc/monitor_modes.pdf;
I don't think it's ever going to be too pretty too look at.
*/
// GZ: NOT USED IN TRACKS
//bool const auto_input = _session.config.get_auto_input ();
//bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
//bool const tape_machine_mode = Config->get_tape_machine_mode ();
bool const roll = _session.transport_rolling ();
bool const track_rec = _diskstream->record_enabled ();
bool session_rec = _session.actively_recording ();
if (track_rec) {
if (!session_rec && roll) {
return MonitoringDisk;
} else {
return MonitoringInput;
}
} else {
if (roll) {
return MonitoringDisk;
}
}
return MonitoringSilence;
}
#else
/* This is the Ardour/Mixbus version of Track::monitoring_state().
*
* Tracks developers: do NOT modify this method under any circumstances.
*/
MonitorState
Route::monitoring_state () const
{
if (!_disk_reader) {
return MonitoringInput;
}
/* Explicit requests */
MonitorChoice m (_monitoring_control->monitoring_choice());
if (m != MonitorAuto) {
MonitorState ms ((MonitorState) 0);
if (m & MonitorInput) {
ms = MonitoringInput;
}
if (m & MonitorDisk) {
ms = MonitorState (ms | MonitoringDisk);
}
return ms;
}
switch (_session.config.get_session_monitoring ()) {
case MonitorDisk:
return MonitoringDisk;
break;
case MonitorInput:
return MonitoringInput;
break;
default:
break;
}
/* This is an implementation of the truth table in doc/monitor_modes.pdf;
I don't think it's ever going to be too pretty too look at.
*/
bool const roll = _session.transport_rolling ();
bool const track_rec = _disk_writer->record_enabled ();
bool const auto_input = _session.config.get_auto_input ();
bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
bool const tape_machine_mode = Config->get_tape_machine_mode ();
bool session_rec;
/* I suspect that just use actively_recording() is good enough all the
* time, but just to keep the semantics the same as they were before
* sept 26th 2012, we differentiate between the cases where punch is
* enabled and those where it is not.
*
* rg: I suspect this is not the case: monitoring may differ
*/
if (_session.config.get_punch_in() || _session.config.get_punch_out() || _session.preroll_record_punch_enabled ()) {
session_rec = _session.actively_recording ();
} else {
session_rec = _session.get_record_enabled();
}
if (track_rec) {
if (!session_rec && roll && auto_input) {
return MonitoringDisk;
} else {
return software_monitor ? MonitoringInput : MonitoringSilence;
}
} else {
if (tape_machine_mode) {
return MonitoringDisk;
} else {
if (!roll && auto_input) {
return software_monitor ? MonitoringInput : MonitoringSilence;
} else {
return MonitoringDisk;
}
}
}
abort(); /* NOTREACHED */
return MonitoringSilence;
}
#endif

View File

@ -548,7 +548,7 @@ Track::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sam
_meter->run (bufs, start_sample, end_sample, _session.transport_speed(), nframes, true);
}
passthru (bufs, start_sample, end_sample, nframes, false);
passthru (bufs, start_sample, end_sample, nframes, false, true);
}
flush_processor_buffers_locked (nframes);
@ -980,152 +980,6 @@ Track::adjust_capture_buffering ()
}
}
#ifdef USE_TRACKS_CODE_FEATURES
/* This is the Tracks version of Track::monitoring_state().
*
* Ardour developers: try to flag or fix issues if parts of the libardour API
* change in ways that invalidate this
*/
MonitorState
Track::monitoring_state () const
{
/* Explicit requests */
if (_monitoring != MonitorInput) {
return MonitoringInput;
}
if (_monitoring & MonitorDisk) {
return MonitoringDisk;
}
/* This is an implementation of the truth table in doc/monitor_modes.pdf;
I don't think it's ever going to be too pretty too look at.
*/
// GZ: NOT USED IN TRACKS
//bool const auto_input = _session.config.get_auto_input ();
//bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
//bool const tape_machine_mode = Config->get_tape_machine_mode ();
bool const roll = _session.transport_rolling ();
bool const track_rec = _diskstream->record_enabled ();
bool session_rec = _session.actively_recording ();
if (track_rec) {
if (!session_rec && roll) {
return MonitoringDisk;
} else {
return MonitoringInput;
}
} else {
if (roll) {
return MonitoringDisk;
}
}
return MonitoringSilence;
}
#else
/* This is the Ardour/Mixbus version of Track::monitoring_state().
*
* Tracks developers: do NOT modify this method under any circumstances.
*/
MonitorState
Track::monitoring_state () const
{
/* Explicit requests */
MonitorChoice m (_monitoring_control->monitoring_choice());
if (m != MonitorAuto) {
MonitorState ms ((MonitorState) 0);
if (m & MonitorInput) {
ms = MonitoringInput;
}
if (m & MonitorDisk) {
ms = MonitorState (ms | MonitoringDisk);
}
return ms;
}
switch (_session.config.get_session_monitoring ()) {
case MonitorDisk:
return MonitoringDisk;
break;
case MonitorInput:
return MonitoringInput;
break;
default:
break;
}
/* This is an implementation of the truth table in doc/monitor_modes.pdf;
I don't think it's ever going to be too pretty too look at.
*/
bool const roll = _session.transport_rolling ();
bool const track_rec = _disk_writer->record_enabled ();
bool const auto_input = _session.config.get_auto_input ();
bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
bool const tape_machine_mode = Config->get_tape_machine_mode ();
bool session_rec;
/* I suspect that just use actively_recording() is good enough all the
* time, but just to keep the semantics the same as they were before
* sept 26th 2012, we differentiate between the cases where punch is
* enabled and those where it is not.
*
* rg: I suspect this is not the case: monitoring may differ
*/
if (_session.config.get_punch_in() || _session.config.get_punch_out() || _session.preroll_record_punch_enabled ()) {
session_rec = _session.actively_recording ();
} else {
session_rec = _session.get_record_enabled();
}
if (track_rec) {
if (!session_rec && roll && auto_input) {
return MonitoringDisk;
} else {
return software_monitor ? MonitoringInput : MonitoringSilence;
}
} else {
if (tape_machine_mode) {
return MonitoringDisk;
} else {
if (!roll && auto_input) {
return software_monitor ? MonitoringInput : MonitoringSilence;
} else {
return MonitoringDisk;
}
}
}
abort(); /* NOTREACHED */
return MonitoringSilence;
}
#endif
void
Track::maybe_declick (BufferSet& bufs, samplecnt_t nframes, int declick)