Improve performance when moving channels in the Mixer (#8235)

Improves performance when moving mixer channels to the left or right using simple Qt layout operations and swapping of values. This commit also addresses a deadlock in Mixer::mixToChannel by ensuring we lock and unlock the same channel regardless of any move operations occurring simultaneously on another thread.
This commit is contained in:
Sotonye Atemie
2026-02-09 11:57:28 -05:00
committed by GitHub
parent 84f691cafc
commit 441fd905be
5 changed files with 22 additions and 36 deletions

View File

@@ -64,6 +64,7 @@ public:
void keyPressEvent(QKeyEvent* ke) override;
void reset();
int channelIndex() const { return m_channelIndex; }
void setChannelIndex(int index);

View File

@@ -83,7 +83,6 @@ public:
// move the channel to the left or right
void moveChannelLeft(int index);
void moveChannelLeft(int index, int focusIndex);
void moveChannelRight(int index);
void renameChannel(int index);

View File

@@ -644,12 +644,13 @@ FloatModel * Mixer::channelSendModel( mix_ch_t fromChannel, mix_ch_t toChannel )
void Mixer::mixToChannel( const SampleFrame* _buf, mix_ch_t _ch )
{
if( m_mixerChannels[_ch]->m_muteModel.value() == false )
const auto channel = m_mixerChannels[_ch];
if (!channel->m_muteModel.value())
{
m_mixerChannels[_ch]->m_lock.lock();
MixHelpers::add( m_mixerChannels[_ch]->m_buffer, _buf, Engine::audioEngine()->framesPerPeriod() );
m_mixerChannels[_ch]->m_hasInput = true;
m_mixerChannels[_ch]->m_lock.unlock();
channel->m_lock.lock();
MixHelpers::add(channel->m_buffer, _buf, Engine::audioEngine()->framesPerPeriod());
channel->m_hasInput = true;
channel->m_lock.unlock();
}
}

View File

@@ -249,13 +249,7 @@ void MixerChannelView::keyPressEvent(QKeyEvent* ke)
void MixerChannelView::setChannelIndex(int index)
{
MixerChannel* mixerChannel = Engine::mixer()->mixerChannel(index);
m_fader->setModel(&mixerChannel->m_volumeModel);
m_muteButton->setModel(&mixerChannel->m_muteModel);
m_soloButton->setModel(&mixerChannel->m_soloModel);
m_effectRackView->setModel(&mixerChannel->m_fxChain);
m_channelNumberLcd->setValue(index);
m_renameLineEdit->setText(elideName(mixerChannel->m_name));
m_channelIndex = index;
}

View File

@@ -433,38 +433,29 @@ void MixerView::deleteUnusedChannels()
}
}
void MixerView::moveChannelLeft(int index, int focusIndex)
{
// can't move master or first channel left or last channel right
if (index <= 1 || index >= m_mixerChannelViews.size()) return;
Mixer *m = getMixer();
// Move instruments channels
m->moveChannelLeft(index);
// Update widgets models
m_mixerChannelViews[index]->setChannelIndex(index);
m_mixerChannelViews[index - 1]->setChannelIndex(index - 1);
// Focus on new position
setCurrentMixerChannel(focusIndex);
}
void MixerView::moveChannelLeft(int index)
{
moveChannelLeft(index, index - 1);
// can't move master or first channel left or last channel right
if (index <= 1 || index >= m_mixerChannelViews.size()) { return; }
m_mixer->moveChannelLeft(index);
const auto layoutIndex = chLayout->indexOf(m_mixerChannelViews[index]);
assert(layoutIndex >= 1);
chLayout->removeWidget(m_mixerChannelViews[index]);
chLayout->insertWidget(layoutIndex - 1, m_mixerChannelViews[index]);
m_mixerChannelViews[index]->setChannelIndex(index - 1);
m_mixerChannelViews[index - 1]->setChannelIndex(index);
std::swap(m_mixerChannelViews[index - 1], m_mixerChannelViews[index]);
}
void MixerView::moveChannelRight(int index)
{
moveChannelLeft(index + 1, index + 1);
moveChannelLeft(index + 1);
}