lmms
lmms copied to clipboard
Improve PlayHandle removal in Mixer
Problem
In Mixer::renderNextBuffer()
, when a clear signal is received (by calling Mixer::clear()
, which sets m_clearSignal
to true
), Mixer::clearInternal()
gets called and it simply adds every PlayHandle
except InstrumentPlayHandle
s from m_playHandles
to m_playHandlesToRemove
. However, right after Mixer::clearInternal()
is called in Mixer::renderNextBuffer()
, a loop iterates through m_playHandlesToRemove
and removes the same PlayHandles
from m_playHandles
. In other words, it unnecessarily stores a list of PlayHandles
to be removed only to actually remove then right afterwards. Mixer::clear()
seems to be called only within Song::stop()
.
Other than Mixer::clear()
, the only method that adds a play handle to m_playHandlesToRemove is Mixer::removePlayHandle()
, which is only called by the FileBrowser
class to stop a preset preview PlayHandle
. Also, only one preset preview PlayHandle
seems to be active at a time.
Solution
-
Add the members
PresetPreviewPlayHandle m_presetPreviewPlayHandle
andbool m_presetPreviewStopped
toMixer
. -
Create the method
Mixer::addPresetPreviewPlayHandle()
:
bool Mixer::addPresetPreviewPlayHandle( PresetPreviewPlayHandle *handle )
{
m_presetPreviewStopped = false;
m_presetPreviewPlayHandle = handle;
return addPlayHandle( handle );
}
- Create the method
Mixer::stopPresetPreview()
:
void Mixer::stopPreview()
{
m_presetPreviewStopped = true;
}
- Modify
Mixer::renderNextBuffer()
so that:
if( m_clearSignal )
{
m_clearSignal = false;
clearInternal();
}
ConstPlayHandleList::Iterator it_rem = m_playHandlesToRemove.begin();
while( it_rem != m_playHandlesToRemove.end() )
{
// [...]
}
becomes something like:
if( m_presetPreviewStopped && m_presetPreviewPlayHandle != NULL ) {
//Actually stop m_presetPreviewPlayHandle [...]
m_presetPreviewPlayHandle = NULL;
}
if( m_clearSignal )
{
ConstPlayHandleList::Iterator it = m_playHandles.begin();
while( it != m_playHandles.end() )
{
// [...]
}
m_clearSignal = false;
}
- Update
FileBrowser.cpp
with the new methods.
Mixer::clearInternal
was added in #2879 by @jasp00 to fix a deadlock. I think we can remove it once we find a solution without deadlocks.
For preset previewing, I'm not sure why that can be an issue. I also think Mixer
is not a place for handling preset previews.
Mixer has been rewritten recently. Does this issue still occur?