Prevent freeze/bounce of sidechain processors

This also consolidates code to test if a processor can be frozen
from various places.
This commit is contained in:
Robin Gareus 2020-03-14 12:36:00 +01:00
parent 97f3d9496b
commit 8f37865070
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 47 additions and 31 deletions

View File

@ -608,6 +608,8 @@ protected:
samplecnt_t bounce_get_latency (boost::shared_ptr<Processor> endpoint, bool include_endpoint, bool for_export, bool for_freeze) const;
ChanCount bounce_get_output_streams (ChanCount &cc, boost::shared_ptr<Processor> endpoint, bool include_endpoint, bool for_export, bool for_freeze) const;
bool can_freeze_processor (boost::shared_ptr<Processor>, bool allow_routing = false) const;
bool _active;
samplecnt_t _signal_latency;

View File

@ -406,21 +406,23 @@ AudioTrack::freeze_me (InterThreadInfo& itt)
for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
if ((*r)->does_routing() && (*r)->active()) {
if (boost::dynamic_pointer_cast<PeakMeter>(*r)) {
continue;
}
if (!can_freeze_processor (*r)) {
break;
}
if (!boost::dynamic_pointer_cast<PeakMeter>(*r)) {
FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo ((*r)->get_state(), (*r));
FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo ((*r)->get_state(), (*r));
frii->id = (*r)->id();
frii->id = (*r)->id();
_freeze_record.processor_info.push_back (frii);
_freeze_record.processor_info.push_back (frii);
/* now deactivate the processor, */
if (!boost::dynamic_pointer_cast<Amp>(*r)) {
(*r)->deactivate ();
}
/* now deactivate the processor, */
if (!boost::dynamic_pointer_cast<Amp>(*r)) {
(*r)->deactivate ();
}
_session.set_dirty ();

View File

@ -564,10 +564,7 @@ Route::bounce_process (BufferSet& buffers, samplepos_t start, samplecnt_t nframe
}
/* if we're *not* exporting, stop processing if we come across a routing processor. */
if (!for_export && boost::dynamic_pointer_cast<PortInsert>(*i)) {
break;
}
if (!for_export && for_freeze && (*i)->does_routing() && (*i)->active()) {
if (!for_export && !can_freeze_processor (*i, !for_freeze)) {
break;
}
@ -618,10 +615,7 @@ Route::bounce_get_latency (boost::shared_ptr<Processor> endpoint,
}
continue;
}
if (!for_export && boost::dynamic_pointer_cast<PortInsert>(*i)) {
break;
}
if (!for_export && for_freeze && (*i)->does_routing() && (*i)->active()) {
if (!for_export && !can_freeze_processor (*i, !for_freeze)) {
break;
}
if (!(*i)->does_routing() && !boost::dynamic_pointer_cast<PeakMeter>(*i)) {
@ -646,10 +640,7 @@ Route::bounce_get_output_streams (ChanCount &cc, boost::shared_ptr<Processor> en
if (!include_endpoint && (*i) == endpoint) {
break;
}
if (!for_export && boost::dynamic_pointer_cast<PortInsert>(*i)) {
break;
}
if (!for_export && for_freeze && (*i)->does_routing() && (*i)->active()) {
if (!for_export && !can_freeze_processor (*i, !for_freeze)) {
break;
}
if (!(*i)->does_routing() && !boost::dynamic_pointer_cast<PeakMeter>(*i)) {
@ -5177,19 +5168,40 @@ Route::metering_state () const
}
bool
Route::has_external_redirects () const
Route::can_freeze_processor (boost::shared_ptr<Processor> p, bool allow_routing) const
{
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
/* ignore inactive processors and obviously ignore the main
* outs since everything has them and we don't care.
*/
if ((*i)->active() && (*i) != _main_outs && (*i)->does_routing()) {
return true;;
}
/* ignore inactive processors and obviously ignore the main
* outs since everything has them and we don't care.
*/
if (!p->active()) {
return true;
}
if (p != _main_outs && p->does_routing()) {
return allow_routing;
}
if (boost::dynamic_pointer_cast<PortInsert>(p)) {
return false;
}
boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert>(p);
if (pi && pi->has_sidechain () && pi->sidechain_input () && pi->sidechain_input ()->connected()) {
return false;
}
return true;
}
bool
Route::has_external_redirects () const
{
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
if (!can_freeze_processor (*i)) {
return true;
}
}
return false;
}