From e5bc77f4c31e58061d431c797d2545262d790848 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Sun, 29 Jan 2012 13:04:08 +0100 Subject: [PATCH] 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. --- include/mixer.h | 5 +---- src/core/mixer.cpp | 23 ++++++++++++++++++++++- src/tracks/pattern.cpp | 9 ++++++--- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index 40a8c33f0..e84122049 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -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 diff --git a/src/core/mixer.cpp b/src/core/mixer.cpp index a36102f3f..bdb955d7a 100644 --- a/src/core/mixer.cpp +++ b/src/core/mixer.cpp @@ -1,7 +1,7 @@ /* * mixer.cpp - audio-device-independent mixer for LMMS * - * Copyright (c) 2004-2011 Tobias Doerffel + * Copyright (c) 2004-2012 Tobias Doerffel * * 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; diff --git a/src/tracks/pattern.cpp b/src/tracks/pattern.cpp index 8110555fb..67f07fbd3 100644 --- a/src/tracks/pattern.cpp +++ b/src/tracks/pattern.cpp @@ -1,7 +1,7 @@ /* * pattern.cpp - implementation of class pattern which holds notes * - * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2004-2012 Tobias Doerffel * Copyright (c) 2005-2007 Danny McRae * * 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(); }