manage Route::_have_internal_generator more accurately and never flush processors if there is on; correctly manage declicking so that only *TRACKS* without internal generators will declick at transport state transitions (fixes horrible click at transport stop in some configurations
git-svn-id: svn://localhost/ardour2/branches/3.0@9100 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -243,7 +243,7 @@ Amp::declick (BufferSet& bufs, framecnt_t nframes, int dir)
|
||||
if (declick != nframes) {
|
||||
|
||||
if (target == 0.0) {
|
||||
memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
|
||||
memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
|
||||
} else if (target != 1.0) {
|
||||
apply_gain_to_buffer (&buffer[declick], nframes - declick, target);
|
||||
}
|
||||
|
||||
@@ -482,6 +482,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
||||
ChanCount n_process_buffers ();
|
||||
|
||||
virtual bool should_monitor () const;
|
||||
virtual void maybe_declick (BufferSet&, framecnt_t, int);
|
||||
|
||||
virtual int _set_state (const XMLNode&, int, bool call_base);
|
||||
|
||||
|
||||
@@ -202,6 +202,8 @@ class Track : public Route, public PublicDiskstream
|
||||
XMLNode* pending_state;
|
||||
bool _destructive;
|
||||
|
||||
void maybe_declick (BufferSet&, framecnt_t, int);
|
||||
|
||||
virtual bool send_silence () const;
|
||||
|
||||
boost::shared_ptr<RecEnableControllable> _rec_enable_control;
|
||||
|
||||
@@ -54,7 +54,10 @@ void
|
||||
AudioPort::cycle_end (pframes_t nframes)
|
||||
{
|
||||
if (sends_output() && !_buffer->written()) {
|
||||
_buffer->silence (nframes);
|
||||
/* we can't use nframes here because the current buffer capacity may
|
||||
be shorter than the full buffer size if we split the cycle.
|
||||
*/
|
||||
_buffer->silence (_buffer->capacity());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -379,6 +379,14 @@ Route::set_gain (gain_t val, void *src)
|
||||
_amp->set_gain (val, src);
|
||||
}
|
||||
|
||||
void
|
||||
Route::maybe_declick (BufferSet&, framecnt_t, int)
|
||||
{
|
||||
/* this is the "bus" implementation and they never declick.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/** Process this route for one (sub) cycle (process thread)
|
||||
*
|
||||
* @param bufs Scratch buffers to use for the signal path
|
||||
@@ -399,10 +407,6 @@ Route::process_output_buffers (BufferSet& bufs,
|
||||
|
||||
bufs.is_silent (false);
|
||||
|
||||
if (!declick) {
|
||||
declick = _pending_declick;
|
||||
}
|
||||
|
||||
/* figure out if we're going to use gain automation */
|
||||
if (gain_automation_ok) {
|
||||
_amp->setup_gain_automation (start_frame, end_frame, nframes);
|
||||
@@ -418,10 +422,7 @@ Route::process_output_buffers (BufferSet& bufs,
|
||||
GLOBAL DECLICK (for transport changes etc.)
|
||||
----------------------------------------------------------------------------------------- */
|
||||
|
||||
if (declick != 0) {
|
||||
Amp::declick (bufs, nframes, declick);
|
||||
}
|
||||
|
||||
maybe_declick (bufs, nframes, declick);
|
||||
_pending_declick = 0;
|
||||
|
||||
/* -------------------------------------------------------------------------------------------
|
||||
@@ -1057,6 +1058,17 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
|
||||
|
||||
(*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
|
||||
}
|
||||
|
||||
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
||||
boost::shared_ptr<PluginInsert> pi;
|
||||
|
||||
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
|
||||
if (pi->is_generator()) {
|
||||
_have_internal_generator = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_output->set_user_latency (0);
|
||||
}
|
||||
@@ -2401,10 +2413,22 @@ Route::set_processor_state (const XMLNode& node)
|
||||
{
|
||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||
_processors = new_order;
|
||||
|
||||
if (must_configure) {
|
||||
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||
configure_processors_unlocked (0);
|
||||
}
|
||||
|
||||
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
||||
boost::shared_ptr<PluginInsert> pi;
|
||||
|
||||
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
|
||||
if (pi->is_generator()) {
|
||||
_have_internal_generator = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processors_changed (RouteProcessorChange ());
|
||||
@@ -2690,7 +2714,7 @@ Route::nonrealtime_handle_transport_stopped (bool /*abort_ignored*/, bool did_lo
|
||||
|
||||
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
||||
|
||||
if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
|
||||
if (!_have_internal_generator && (Config->get_plugins_stop_with_transport() && can_flush_processors)) {
|
||||
(*i)->flush ();
|
||||
}
|
||||
|
||||
|
||||
@@ -690,3 +690,23 @@ Track::send_silence () const
|
||||
|
||||
return send_silence;
|
||||
}
|
||||
|
||||
void
|
||||
Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
|
||||
{
|
||||
/* never declick if there is an internal generator - we just want it to
|
||||
keep generating sound without interruption.
|
||||
*/
|
||||
|
||||
if (_have_internal_generator) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!declick) {
|
||||
declick = _pending_declick;
|
||||
}
|
||||
|
||||
if (declick != 0) {
|
||||
Amp::declick (bufs, nframes, declick);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user