summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-09-28 20:40:53 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-09-28 20:40:53 +0000
commit43b17b5df1927a6c08a382c420c49d7ac1014852 (patch)
tree090359c64ff468e1a7a8ffe19093b04ce33b4c29 /libs/ardour
parente11b3f90c2d02735a071d526d67cfd0de90cbac3 (diff)
changes from torben for processor/plugin count determination and other fixes; rework cycle_start() mess, first pass
git-svn-id: svn://localhost/ardour2/branches/3.0@3821 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/buffer.h2
-rw-r--r--libs/ardour/ardour/io.h2
-rw-r--r--libs/ardour/audioengine.cc5
-rw-r--r--libs/ardour/audioregion.cc2
-rw-r--r--libs/ardour/io.cc9
-rw-r--r--libs/ardour/route.cc323
-rw-r--r--libs/ardour/session_process.cc4
7 files changed, 328 insertions, 19 deletions
diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h
index 72df6c7fd6..e03489568c 100644
--- a/libs/ardour/ardour/buffer.h
+++ b/libs/ardour/ardour/buffer.h
@@ -74,7 +74,7 @@ public:
/** Clear the entire buffer */
virtual void clear() { silence(_capacity, 0); }
-
+
virtual void read_from(const Buffer& src, nframes_t offset, nframes_t len) = 0;
protected:
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 08c8a1b211..521efbafb4 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -287,6 +287,8 @@ class IO : public SessionObject, public AutomatableControls, public Latent
DataType _default_type;
bool _public_ports;
+ virtual void prepare_inputs (nframes_t nframes, nframes_t offset);
+
virtual void set_deferred_state() {}
void reset_panner ();
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 956b956020..8629a5c0df 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -342,11 +342,6 @@ AudioEngine::process_callback (nframes_t nframes)
boost::shared_ptr<Ports> p = ports.reader();
- // Prepare ports (ie read data if necessary)
- for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
- (*i)->cycle_start (nframes, 0);
- }
-
if (_freewheeling) {
/* emit the Freewheel signal and stop freewheeling in the event of trouble */
if (Freewheel (nframes)) {
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 477c479de8..f74fb83735 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -473,7 +473,7 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
}
}
} else if (_scale_amplitude != 1.0f) {
- ARDOUR::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
+ apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
}
merge:
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 7db2493c76..c51920cd0d 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -2744,3 +2744,12 @@ IO::UserBundleInfo::UserBundleInfo (IO* io, boost::shared_ptr<UserBundle> b)
);
}
+void
+IO::prepare_inputs (nframes_t nframes, nframes_t offset)
+{
+ /* io_lock, not taken: function must be called from Session::process() calltree */
+
+ for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
+ (*i).cycle_start (nframes, offset);
+ }
+}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 7cf6c4ef36..a90a730ea6 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -722,6 +722,312 @@ Route::process_output_buffers (BufferSet& bufs,
}
}
+#ifdef NEW_POB
+/** 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 (BufferSet& bufs,
+ nframes_t start_frame, nframes_t end_frame,
+ nframes_t nframes, nframes_t offset, bool with_processors, int declick,
+ bool meter)
+{
+ // This is definitely very audio-only for now
+ assert(_default_type == DataType::AUDIO);
+
+ ProcessorList::iterator i;
+ bool post_fader_work = false;
+ bool mute_declick_applied = false;
+ gain_t dmg, dsg, dg;
+ IO *co;
+ bool mute_audible;
+ bool solo_audible;
+ bool no_monitor;
+ gain_t* gab = _session.gain_automation_buffer();
+
+ switch (Config->get_monitoring_model()) {
+ case HardwareMonitoring:
+ case ExternalMonitoring:
+ no_monitor = true;
+ break;
+ default:
+ no_monitor = false;
+ }
+
+ declick = _pending_declick;
+
+ {
+ Glib::Mutex::Lock cm (_control_outs_lock, Glib::TRY_LOCK);
+
+ if (cm.locked()) {
+ co = _control_outs;
+ } else {
+ co = 0;
+ }
+ }
+
+ {
+ Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
+
+ if (dm.locked()) {
+ dmg = desired_mute_gain;
+ dsg = desired_solo_gain;
+ dg = _desired_gain;
+ } else {
+ dmg = mute_gain;
+ dsg = solo_gain;
+ dg = _gain;
+ }
+ }
+
+ /* ----------------------------------------------------------------------------------------------------
+ GLOBAL DECLICK (for transport changes etc.)
+ input metering & monitoring (control outs)
+ denormal control
+ pre-fader redirects
+ pre-fader metering & monitoring (control outs)
+ gain stage
+ post-fader redirects
+ global mute
+ main output
+ post-fader metering & monitoring (control outs)
+ */
+
+ {
+ Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
+ for (i = processors.begin(); i != processors.end(); ++i) {
+ (*i)->run_in_place (bufs, start_frame, end_frame, nframes, offset);
+ }
+ }
+
+ /* ----------------------------------------------------------------------------------------------------
+ INPUT METERING & MONITORING
+ -------------------------------------------------------------------------------------------------- */
+
+ if (meter && (_meter_point == MeterInput)) {
+ _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset);
+ }
+
+ if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) {
+ Amp::run_in_place (bufs, nframes, mute_gain, dmg, false);
+ mute_gain = dmg;
+ mute_declick_applied = true;
+ }
+
+ /* ----------------------------------------------------------------------------------------------------
+ PRE-FADER REDIRECTS
+ -------------------------------------------------------------------------------------------------- */
+
+ // This really should already be true...
+ bufs.set_count(pre_fader_streams());
+
+
+ if ((_meter_point == MeterPreFader) && co) {
+
+ solo_audible = dsg > 0;
+ mute_audible = dmg > 0 || !_mute_affects_pre_fader;
+
+ if ( // muted by solo of another track
+
+ !solo_audible ||
+
+ // muted by mute of this track
+
+ !mute_audible ||
+
+ // rec-enabled but not s/w monitoring
+
+ (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
+
+ ) {
+
+ co->silence (nframes, offset);
+
+ } else {
+
+ co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
+ }
+ }
+
+ /* ----------------------------------------------------------------------------------------------------
+ GAIN STAGE
+ -------------------------------------------------------------------------------------------------- */
+
+ /* if not recording or recording and requiring any monitor signal, then apply gain */
+
+ if ( // not recording
+
+ !(record_enabled() && _session.actively_recording()) ||
+
+ // OR recording
+
+ // AND software monitoring required
+
+ Config->get_monitoring_model() == SoftwareMonitoring) {
+
+ if (apply_gain_automation) {
+
+ if (_phase_invert) {
+ for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
+ Sample* const sp = i->data();
+
+ for (nframes_t nx = 0; nx < nframes; ++nx) {
+ sp[nx] *= -gab[nx];
+ }
+ }
+ } else {
+ for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
+ Sample* const sp = i->data();
+
+ for (nframes_t nx = 0; nx < nframes; ++nx) {
+ sp[nx] *= gab[nx];
+ }
+ }
+ }
+
+ if (apply_gain_automation && _session.transport_rolling() && nframes > 0) {
+ _effective_gain = gab[nframes-1];
+ }
+
+ } else {
+
+ /* manual (scalar) gain */
+
+ if (_gain != dg) {
+
+ Amp::run_in_place (bufs, nframes, _gain, dg, _phase_invert);
+ _gain = dg;
+
+ } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) {
+
+ /* no need to interpolate current gain value,
+ but its non-unity, so apply it. if the gain
+ is zero, do nothing because we'll ship silence
+ below.
+ */
+
+ gain_t this_gain;
+
+ if (_phase_invert) {
+ this_gain = -_gain;
+ } else {
+ this_gain = _gain;
+ }
+
+ for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
+ Sample* const sp = i->data();
+ apply_gain_to_buffer(sp,nframes,this_gain);
+ }
+
+ } else if (_gain == 0) {
+ for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
+ i->clear();
+ }
+ }
+ }
+
+ } else {
+
+ /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */
+
+ }
+
+
+ /* ----------------------------------------------------------------------------------------------------
+ CONTROL OUTPUT STAGE
+ -------------------------------------------------------------------------------------------------- */
+
+ if ((_meter_point == MeterPostFader) && co) {
+
+ solo_audible = solo_gain > 0;
+ mute_audible = dmg > 0 || !_mute_affects_control_outs;
+
+ if ( // silent anyway
+
+ (_gain == 0 && !apply_gain_automation) ||
+
+ // muted by solo of another track
+
+ !solo_audible ||
+
+ // muted by mute of this track
+
+ !mute_audible ||
+
+ // recording but not s/w monitoring
+
+ (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording()))
+
+ ) {
+
+ co->silence (nframes, offset);
+
+ } else {
+
+ co->deliver_output (bufs, start_frame, end_frame, nframes, offset);
+ }
+ }
+
+ /* ----------------------------------------------------------------------------------------------------
+ MAIN OUTPUT STAGE
+ -------------------------------------------------------------------------------------------------- */
+
+ solo_audible = dsg > 0;
+ mute_audible = dmg > 0 || !_mute_affects_main_outs;
+
+ if (n_outputs().get(_default_type) == 0) {
+
+ /* relax */
+
+ } else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) {
+
+ IO::silence (nframes, offset);
+
+ } else {
+
+ if ( // silent anyway
+
+ (_gain == 0 && !apply_gain_automation) ||
+
+ // muted by solo of another track, but not using control outs for solo
+
+ (!solo_audible && (Config->get_solo_model() != SoloBus)) ||
+
+ // muted by mute of this track
+
+ !mute_audible
+
+ ) {
+
+ /* don't use Route::silence() here, because that causes
+ all outputs (sends, port processors, etc. to be silent).
+ */
+
+ if (_meter_point == MeterPostFader) {
+ peak_meter().reset();
+ }
+
+ IO::silence (nframes, offset);
+
+ } else {
+
+ deliver_output(bufs, start_frame, end_frame, nframes, offset);
+
+ }
+
+ }
+}
+
+#endif /* NEW_POB */
+
ChanCount
Route::n_process_buffers ()
{
@@ -829,6 +1135,8 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
_processors.push_back (processor);
+ // Set up processor list channels. This will set processor->[input|output]_streams(),
+ // configure redirect ports properly, etc.
if (_reset_processor_counts (err)) {
_processors.pop_back ();
_reset_processor_counts (0); // it worked before we tried to add it ...
@@ -844,16 +1152,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
}
- _processors.push_back (processor);
-
- // Set up processor list channels. This will set processor->[input|output]_streams(),
- // configure redirect ports properly, etc.
- if (_reset_processor_counts (err)) {
- _processors.pop_back ();
- _reset_processor_counts (0); // it worked before we tried to add it ...
- return -1;
- }
-
// Ensure peak vector sizes before the plugin is activated
ChanCount potential_max_streams;
@@ -1404,14 +1702,14 @@ Route::check_some_processor_counts (list<ProcessorCount>& iclist, ChanCount requ
err->index = index;
err->count = required_inputs;
}
- return false;
+ return true;
}
(*i).in = required_inputs;
required_inputs = (*i).out;
}
- return true;
+ return false;
}
int
@@ -2774,3 +3072,4 @@ Route::set_pending_declick (int declick)
}
}
+
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index abe802548a..e4025ca6de 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -103,6 +103,8 @@ Session::no_roll (nframes_t nframes, nframes_t offset)
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ (*i)->prepare_inputs (nframes, offset);
+
if ((*i)->is_hidden()) {
continue;
}
@@ -142,6 +144,8 @@ Session::process_routes (nframes_t nframes, nframes_t offset)
int ret;
+ (*i)->prepare_inputs (nframes, offset);
+
if ((*i)->is_hidden()) {
continue;
}