prevent infinite mixing loops

Prevent infinite mixing loops by disabling the send button for
a channel line when clicking it would cause an infinite loop.
This commit is contained in:
Andrew Kelley
2009-09-29 19:16:19 -07:00
parent ce7891b7bd
commit 504a03f2cf
3 changed files with 39 additions and 8 deletions

View File

@@ -97,6 +97,10 @@ public:
// delete the connection made by createChannelSend
void deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel);
// determine if adding a send from sendFrom to
// sendTo would result in an infinite mixer loop.
bool isInfiniteLoop(fx_ch_t fromChannel, fx_ch_t toChannel);
// return the FloatModel of fromChannel sending its output to the input of
// toChannel. NULL if there is no send.
FloatModel * channelSendModel(fx_ch_t fromChannel, fx_ch_t toChannel);

View File

@@ -158,6 +158,26 @@ void FxMixer::deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel)
}
bool FxMixer::isInfiniteLoop(fx_ch_t sendFrom, fx_ch_t sendTo) {
// can't send master to anything
if( sendFrom == 0 ) return true;
// can't send channel to itself
if( sendFrom == sendTo ) return true;
// follow sendTo's outputs recursively looking for something that sends
// to sendFrom
for(int i=0; i<m_fxChannels[sendTo]->m_sends.size(); ++i)
{
if( isInfiniteLoop( sendFrom, m_fxChannels[sendTo]->m_sends[i] ) )
{
return true;
}
}
return false;
}
// how much does fromChannel send its output to the input of toChannel?
FloatModel * FxMixer::channelSendModel(fx_ch_t fromChannel, fx_ch_t toChannel)

View File

@@ -148,6 +148,8 @@ void FxMixerView::addNewChannel()
newChannelIndex));
chLayout->addWidget(m_fxChannelViews[newChannelIndex]->m_fxLine);
m_fxRacksLayout->addWidget( m_fxChannelViews[newChannelIndex]->m_rackView );
updateFxLine(newChannelIndex);
}
@@ -207,29 +209,34 @@ void FxMixerView::setCurrentFxLine( FxLine * _line )
}
void FxMixerView::updateFxLine(int i)
void FxMixerView::updateFxLine(int index)
{
FxMixer * mix = engine::fxMixer();
// does current channel send to this channel?
FloatModel * sendModel = mix->channelSendModel(m_currentFxLine->channelIndex(), i);
int selIndex = m_currentFxLine->channelIndex();
FxLine * thisLine = m_fxChannelViews[index]->m_fxLine;
FloatModel * sendModel = mix->channelSendModel(selIndex, index);
if( sendModel == NULL )
{
// does not send, hide send knob
m_fxChannelViews[i]->m_fxLine->m_sendKnob->setVisible(false);
thisLine->m_sendKnob->setVisible(false);
}
else
{
// it does send, show knob and connect
m_fxChannelViews[i]->m_fxLine->m_sendKnob->setVisible(true);
m_fxChannelViews[i]->m_fxLine->m_sendKnob->setModel(sendModel);
thisLine->m_sendKnob->setVisible(true);
thisLine->m_sendKnob->setModel(sendModel);
}
m_fxChannelViews[i]->m_fxLine->update();
m_fxChannelViews[i]->m_fxLine->m_sendBtn->updateLightStatus();
// disable the send button if it would cause an infinite loop
thisLine->m_sendBtn->setVisible(! mix->isInfiniteLoop(selIndex, index));
thisLine->m_sendBtn->updateLightStatus();
thisLine->update();
}
void FxMixerView::setCurrentFxLine( int _line )
{
setCurrentFxLine( m_fxChannelViews[_line]->m_fxLine );