summaryrefslogtreecommitdiff
path: root/libs/ardour/route.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/route.cc')
-rw-r--r--libs/ardour/route.cc174
1 files changed, 79 insertions, 95 deletions
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 0e132f6412..d3ddaa4caf 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -42,7 +42,9 @@
#include <ardour/panner.h>
#include <ardour/dB.h>
#include <ardour/mix.h>
-
+#include <ardour/declicker.h>
+#include <ardour/meter.h>
+#include <ardour/buffer_set.h>
#include "i18n.h"
using namespace std;
@@ -74,7 +76,7 @@ Route::Route (Session& sess, const XMLNode& node)
void
Route::init ()
{
- redirect_max_outs = 0;
+ redirect_max_outs.reset();
_muted = false;
_soloed = false;
_solo_safe = false;
@@ -215,8 +217,19 @@ Route::set_gain (gain_t val, void *src)
IO::set_gain (val, src);
}
+/** Process this route for one (sub) cycle (process thread)
+ *
+ * @param bufs Scratch buffers to use for the signal path
+ * @param start_frame Initial transport frame
+ * @param end_frame Final transport frame
+ * @param nframes Number of frames to output (to ports)
+ * @param offset Output offset (of port buffers, for split cycles)
+ *
+ * Note that (end_frame - start_frame) may not be equal to nframes when the
+ * transport speed isn't 1.0 (eg varispeed).
+ */
void
-Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
+Route::process_output_buffers (BufferSet& bufs,
jack_nframes_t start_frame, jack_nframes_t end_frame,
jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick,
bool meter)
@@ -224,7 +237,6 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
// This is definitely very audio-only for now
assert(_default_type == DataType::AUDIO);
- uint32_t n;
RedirectList::iterator i;
bool post_fader_work = false;
bool mute_declick_applied = false;
@@ -267,17 +279,17 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
-------------------------------------------------------------------------------------------------- */
if (declick > 0) {
- apply_declick (bufs, nbufs, nframes, 0.0, 1.0, _phase_invert);
+ Declicker::run (bufs, nframes, 0.0, 1.0, _phase_invert);
_pending_declick = 0;
} else if (declick < 0) {
- apply_declick (bufs, nbufs, nframes, 1.0, 0.0, _phase_invert);
+ Declicker::run (bufs, nframes, 1.0, 0.0, _phase_invert);
_pending_declick = 0;
} else {
/* no global declick */
if (solo_gain != dsg) {
- apply_declick (bufs, nbufs, nframes, solo_gain, dsg, _phase_invert);
+ Declicker::run (bufs, nframes, solo_gain, dsg, _phase_invert);
solo_gain = dsg;
}
}
@@ -288,13 +300,11 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
-------------------------------------------------------------------------------------------------- */
if (meter && (_meter_point == MeterInput)) {
- for (n = 0; n < nbufs; ++n) {
- _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
- }
+ _meter->run(bufs, nframes);
}
if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
- apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
+ Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert);
mute_gain = dmg;
mute_declick_applied = true;
}
@@ -324,7 +334,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
} else {
- co->deliver_output (bufs, nbufs, nframes, offset);
+ co->deliver_output (bufs, nframes, offset);
}
}
@@ -340,7 +350,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
for (i = _redirects.begin(); i != _redirects.end(); ++i) {
switch ((*i)->placement()) {
case PreFader:
- (*i)->run (bufs, nbufs, nframes, offset);
+ (*i)->run (bufs, nframes, offset);
break;
case PostFader:
post_fader_work = true;
@@ -364,7 +374,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) {
- apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
+ Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert);
mute_gain = dmg;
mute_declick_applied = true;
}
@@ -374,9 +384,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
-------------------------------------------------------------------------------------------------- */
if (meter && (_meter_point == MeterPreFader)) {
- for (n = 0; n < nbufs; ++n) {
- _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
- }
+ _meter->run(bufs, nframes);
}
@@ -403,7 +411,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
} else {
- co->deliver_output (bufs, nbufs, nframes, offset);
+ co->deliver_output (bufs, nframes, offset);
}
}
@@ -431,16 +439,16 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
if (apply_gain_automation) {
if (_phase_invert) {
- for (n = 0; n < nbufs; ++n) {
- Sample *sp = bufs[n];
+ for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
+ Sample* const sp = i->data(nframes);
for (jack_nframes_t nx = 0; nx < nframes; ++nx) {
sp[nx] *= -gab[nx];
}
}
} else {
- for (n = 0; n < nbufs; ++n) {
- Sample *sp = bufs[n];
+ for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
+ Sample* const sp = i->data(nframes);
for (jack_nframes_t nx = 0; nx < nframes; ++nx) {
sp[nx] *= gab[nx];
@@ -458,7 +466,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
if (_gain != dg) {
- apply_declick (bufs, nbufs, nframes, _gain, dg, _phase_invert);
+ Declicker::run (bufs, nframes, _gain, dg, _phase_invert);
_gain = dg;
} else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
@@ -477,14 +485,14 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
this_gain = _gain;
}
- for (n = 0; n < nbufs; ++n) {
- Sample *sp = bufs[n];
+ for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
+ Sample* const sp = i->data(nframes);
apply_gain_to_buffer(sp,nframes,this_gain);
}
} else if (_gain == 0) {
- for (n = 0; n < nbufs; ++n) {
- memset (bufs[n], 0, sizeof (Sample) * nframes);
+ for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
+ i->clear();
}
}
}
@@ -511,7 +519,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
case PreFader:
break;
case PostFader:
- (*i)->run (bufs, nbufs, nframes, offset);
+ (*i)->run (bufs, nframes, offset);
break;
}
}
@@ -530,7 +538,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
}
if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) {
- apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
+ Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert);
mute_gain = dmg;
mute_declick_applied = true;
}
@@ -566,7 +574,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
} else {
- co->deliver_output_no_pan (bufs, nbufs, nframes, offset);
+ co->deliver_output_no_pan (bufs, nframes, offset);
}
}
@@ -575,7 +583,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
----------------------------------------------------------------------*/
if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) {
- apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert);
+ Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert);
mute_gain = dmg;
mute_declick_applied = true;
}
@@ -616,7 +624,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
*/
if (_meter_point == MeterPostFader) {
- reset_peak_meters ();
+ peak_meter().reset();
}
IO::silence (nframes, offset);
@@ -624,15 +632,15 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
} else {
if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) {
- pan (bufs, nbufs, nframes, offset, speed_quietning);
+ pan (bufs, nframes, offset, speed_quietning);
} else {
// cerr << _name << " panner state = " << _panner->automation_state() << endl;
if (!_panner->empty() &&
(_panner->automation_state() & Play ||
((_panner->automation_state() & Touch) && !_panner->touching()))) {
- pan_automated (bufs, nbufs, start_frame, end_frame, nframes, offset);
+ pan_automated (bufs, start_frame, end_frame, nframes, offset);
} else {
- pan (bufs, nbufs, nframes, offset, 1.0);
+ pan (bufs, nframes, offset, 1.0);
}
}
}
@@ -647,47 +655,38 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
// cerr << "meter post" << endl;
if ((_gain == 0 && !apply_gain_automation) || dmg == 0) {
- uint32_t no = n_outputs().get(DataType::AUDIO);
- for (n = 0; n < no; ++n) {
- _peak_power[n] = 0;
- }
+ _meter->reset();
} else {
- uint32_t no = n_outputs().get(DataType::AUDIO);
- for (n = 0; n < no; ++n) {
- _peak_power[n] = Session::compute_peak (audio_output(n)->get_audio_buffer ().data(nframes, offset), nframes, _peak_power[n]);
- }
+ _meter->run(output_buffers(), nframes, offset);
}
}
}
-uint32_t
+ChanCount
Route::n_process_buffers ()
{
- return max (n_inputs().get(_default_type), static_cast<size_t>(redirect_max_outs));
+ return max (n_inputs(), redirect_max_outs);
}
void
Route::passthru (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter_first)
{
- vector<Sample*>& bufs = _session.get_passthru_buffers();
- uint32_t limit = n_process_buffers ();
+ BufferSet& bufs = _session.get_scratch_buffers(n_process_buffers());
_silent = false;
- collect_input (bufs, limit, nframes, offset);
+ collect_input (bufs, nframes, offset);
#define meter_stream meter_first
if (meter_first) {
- for (uint32_t n = 0; n < limit; ++n) {
- _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
- }
+ _meter->run(bufs, nframes);
meter_stream = false;
} else {
meter_stream = true;
}
- process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
+ process_output_buffers (bufs, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
#undef meter_stream
}
@@ -763,7 +762,7 @@ Route::set_mute (bool yn, void *src)
int
Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
{
- uint32_t old_rmo = redirect_max_outs;
+ ChanCount old_rmo = redirect_max_outs;
if (!_session.engine().connected()) {
return 1;
@@ -775,13 +774,13 @@ Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t*
boost::shared_ptr<PluginInsert> pi;
boost::shared_ptr<PortInsert> porti;
- uint32_t potential_max_streams = 0;
+ ChanCount potential_max_streams;
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
pi->set_count (1);
- if (pi->input_streams() == 0) {
- /* instrument plugin */
+ if (pi->input_streams() == ChanCount::ZERO) {
+ /* generator plugin */
_have_internal_generator = true;
}
@@ -805,12 +804,7 @@ Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t*
}
// Ensure peak vector sizes before the plugin is activated
- while (_peak_power.size() < potential_max_streams) {
- _peak_power.push_back(0);
- }
- while (_visible_peak_power.size() < potential_max_streams) {
- _visible_peak_power.push_back(0);
- }
+ _meter->setup(potential_max_streams);
_redirects.push_back (redirect);
@@ -824,7 +818,7 @@ Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t*
redirect->active_changed.connect (mem_fun (*this, &Route::redirect_active_proxy));
}
- if (redirect_max_outs != old_rmo || old_rmo == 0) {
+ if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
reset_panner ();
}
@@ -836,7 +830,7 @@ Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t*
int
Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_streams)
{
- uint32_t old_rmo = redirect_max_outs;
+ ChanCount old_rmo = redirect_max_outs;
if (!_session.engine().connected()) {
return 1;
@@ -848,7 +842,7 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea
RedirectList::iterator existing_end = _redirects.end();
--existing_end;
- uint32_t potential_max_streams = 0;
+ ChanCount potential_max_streams;
for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
@@ -857,18 +851,13 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
pi->set_count (1);
- uint32_t m = max(pi->input_streams(), pi->output_streams());
+ ChanCount m = max(pi->input_streams(), pi->output_streams());
if (m > potential_max_streams)
potential_max_streams = m;
}
// Ensure peak vector sizes before the plugin is activated
- while (_peak_power.size() < potential_max_streams) {
- _peak_power.push_back(0);
- }
- while (_visible_peak_power.size() < potential_max_streams) {
- _visible_peak_power.push_back(0);
- }
+ _meter->setup(potential_max_streams);
_redirects.push_back (*i);
@@ -884,7 +873,7 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea
}
}
- if (redirect_max_outs != old_rmo || old_rmo == 0) {
+ if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
reset_panner ();
}
@@ -895,7 +884,7 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea
void
Route::clear_redirects (void *src)
{
- uint32_t old_rmo = redirect_max_outs;
+ ChanCount old_rmo = redirect_max_outs;
if (!_session.engine().connected()) {
return;
@@ -910,7 +899,7 @@ Route::clear_redirects (void *src)
reset_panner ();
}
- redirect_max_outs = 0;
+ redirect_max_outs.reset();
_have_internal_generator = false;
redirects_changed (src); /* EMIT SIGNAL */
}
@@ -918,13 +907,13 @@ Route::clear_redirects (void *src)
int
Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
{
- uint32_t old_rmo = redirect_max_outs;
+ ChanCount old_rmo = redirect_max_outs;
if (!_session.engine().connected()) {
return 1;
}
- redirect_max_outs = 0;
+ redirect_max_outs.reset();
{
Glib::RWLock::WriterLock lm (redirect_lock);
@@ -1020,7 +1009,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
map<Placement,list<InsertCount> > insert_map;
jack_nframes_t initial_streams;
- redirect_max_outs = 0;
+ redirect_max_outs.reset();
i_cnt = 0;
s_cnt = 0;
@@ -1102,7 +1091,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
recompute:
- redirect_max_outs = 0;
+ redirect_max_outs.reset();
RedirectList::iterator prev = _redirects.end();
for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
@@ -1110,7 +1099,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
if (r == _redirects.begin()) {
- s->expect_inputs (n_inputs().get(_default_type));
+ s->expect_inputs (n_inputs());
} else {
s->expect_inputs ((*prev)->output_streams());
}
@@ -1167,7 +1156,7 @@ Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inp
int
Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_streams)
{
- uint32_t old_rmo = redirect_max_outs;
+ ChanCount old_rmo = redirect_max_outs;
if (err_streams) {
*err_streams = 0;
@@ -1240,7 +1229,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st
}
}
- if (redirect_max_outs != old_rmo || old_rmo == 0) {
+ if (redirect_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
reset_panner ();
}
@@ -1290,7 +1279,7 @@ Route::sort_redirects (uint32_t* err_streams)
{
RedirectSorter comparator;
Glib::RWLock::WriterLock lm (redirect_lock);
- uint32_t old_rmo = redirect_max_outs;
+ ChanCount old_rmo = redirect_max_outs;
/* the sweet power of C++ ... */
@@ -1706,8 +1695,6 @@ Route::silence (jack_nframes_t nframes, jack_nframes_t offset)
{
if (!_silent) {
- // reset_peak_meters ();
-
IO::silence (nframes, offset);
if (_control_outs) {
@@ -2004,14 +1991,14 @@ Route::pans_required () const
return 0;
}
- return max (n_inputs ().get(DataType::AUDIO), static_cast<size_t>(redirect_max_outs));
+ return max (n_inputs ().get(DataType::AUDIO), static_cast<size_t>(redirect_max_outs.get(DataType::AUDIO)));
}
int
Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset,
bool session_state_changing, bool can_record, bool rec_monitors_input)
{
- if (n_outputs().get(_default_type) == 0) {
+ if (n_outputs().get_total() == 0) {
return 0;
}
@@ -2022,7 +2009,7 @@ Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes
apply_gain_automation = false;
- if (n_inputs().get(_default_type)) {
+ if (n_inputs().get_total()) {
passthru (start_frame, end_frame, nframes, offset, 0, false);
} else {
silence (nframes, offset);
@@ -2089,8 +2076,6 @@ Route::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t
if (am.locked() && _session.transport_rolling()) {
- jack_nframes_t start_frame = end_frame - nframes;
-
if (gain_automation_playback()) {
apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
}
@@ -2114,7 +2099,7 @@ void
Route::toggle_monitor_input ()
{
for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
- (*i)->request_monitor_input(!(*i)->monitoring_input());
+ i->request_monitor_input( ! i->monitoring_input());
}
}
@@ -2126,11 +2111,10 @@ Route::has_external_redirects () const
for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
- uint32_t no = pi->n_outputs().get(_default_type);
-
- for (uint32_t n = 0; n < no; ++n) {
+ for (PortSet::const_iterator port = pi->outputs().begin();
+ port != pi->outputs().end(); ++port) {
- string port_name = pi->output(n)->name();
+ string port_name = port->name();
string client_name = port_name.substr (0, port_name.find(':'));
/* only say "yes" if the redirect is actually in use */