Mixer, Pattern: fixed pattern freeze with MIDI-based instruments

When freezing patterns the freezer hung forever as it checked for any
running play handles in order to render echoes etc. after the last note.
However if there are MIDI-based instruments such as LB302, ZASF,
Sf2Player etc. there will always be play handles (InstrumentPlayHandles)
in the mixer's play handle array. Therefore explicitely check for
remaining NotePlayHandles when freezing pattern. Furthermore added a
counter variable for safety reasons so rendering note tails will never
exceed 2000 buffer periods.

Thanks to Mikobuntu for reporting this issue!

Closes #3109262.
This commit is contained in:
Tobias Doerffel
2012-01-29 13:04:08 +01:00
parent 60758172b0
commit e5bc77f4c3
3 changed files with 29 additions and 8 deletions

View File

@@ -240,10 +240,7 @@ public:
void removePlayHandles( track * _track );
inline bool hasPlayHandles() const
{
return !m_playHandles.empty();
}
bool hasNotePlayHandles();
// methods providing information for other classes

View File

@@ -1,7 +1,7 @@
/*
* mixer.cpp - audio-device-independent mixer for LMMS
*
* Copyright (c) 2004-2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -965,6 +965,27 @@ void mixer::removePlayHandles( track * _track )
bool mixer::hasNotePlayHandles()
{
lock();
for( PlayHandleList::Iterator it = m_playHandles.begin();
it != m_playHandles.end(); ++it )
{
if( (*it)->type() == playHandle::NotePlayHandle )
{
unlock();
return true;
}
}
unlock();
return false;
}
AudioDevice * mixer::tryAudioDevices()
{
bool success_ful = false;

View File

@@ -1,7 +1,7 @@
/*
* pattern.cpp - implementation of class pattern which holds notes
*
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2007 Danny McRae <khjklujn/at/yahoo.com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -766,9 +766,12 @@ void patternFreezeThread::run()
m_statusDlg->setProgress( ppp * 100 / m_pattern->length() );
}
m_statusDlg->setProgress( 100 );
// render tails
while( engine::getMixer()->hasPlayHandles() &&
m_pattern->m_freezeAborted == false )
int count = 0;
while( engine::getMixer()->hasNotePlayHandles() &&
m_pattern->m_freezeAborted == false &&
++count < 2000 )
{
freeze_recorder->processNextBuffer();
}