always process all note-play-handles of monophonic instruments by the same thread serially - fixes problems with monophonic instruments which rely on notes being processed in correct order

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@759 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2008-03-03 22:54:20 +00:00
parent cb48cea3c2
commit 889d1e8bb3
3 changed files with 76 additions and 6 deletions

View File

@@ -1,3 +1,43 @@
2008-03-03 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* src/core/mixer.cpp:
always process all note-play-handles of monophonic instruments by the
same thread serially - fixes problems with monophonic instruments
which rely on notes being processed in correct order
* src/core/instrument_sound_shaping.cpp:
fixed out-of-range initial value of filter-frequency-model
* src/core/main_window.cpp:
set directory before selecting file in QFileDialog
* src/widgets/knob.cpp:
removed relative painting - fixes badly draw knobs in several cases
* src/core/song_editor.cpp:
* src/core/track.cpp:
* src/widgets/knob.cpp:
* src/widgets/volume_knob.cpp:
made textFloat's work properly and displayed at correct position
* src/widgets/text_float.cpp:
* include/text_float.h:
always use main-window as parent and make sure to be moved relative to
it, i.e. do not show outside of moved main-window
* include/mmp.h:
* src/lib/mmp.cpp:
* src/core/song.cpp:
removed overwrite-check as in Qt4 QFileDialog does this on its own
* include/midi_event_processor.h:
* include/instrument_track.h:
* src/tracks/instrument_track.cpp:
do not lock mixer and call notePlayHandle::noteOff() in
instrumentTrack::processInEvent() when processing monophonic
instruments in playNote() - fixes lockups in LB302 in multithreaded
mode
2008-03-02 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* include/ladspa_control.h:

View File

@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT(lmms, 0.4.0-svn20080228, lmms-devel/at/lists/dot/sf/dot/net)
AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20080228)
AC_INIT(lmms, 0.4.0-svn20080303, lmms-devel/at/lists/dot/sf/dot/net)
AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20080303)
AM_CONFIG_HEADER(config.h)

View File

@@ -25,6 +25,7 @@
*/
#include <QtCore/QHash>
#include <QtCore/QWaitCondition>
#include <math.h>
@@ -34,6 +35,8 @@
#include "song.h"
#include "templates.h"
#include "envelope_and_lfo_parameters.h"
#include "note_play_handle.h"
#include "instrument_track.h"
#include "debug.h"
#include "engine.h"
#include "config_mgr.h"
@@ -390,7 +393,7 @@ void mixer::setClipScaling( bool _state )
m_workers[i]->addJob( &_jq ); \
}
#define WAIT_FOR_JOBS() \
#define WAIT_FOR_JOBS(_cond) \
while( m_workerSem.available() < m_numWorkers ) \
{ \
m_workerSem.acquire( 1 ); \
@@ -413,7 +416,7 @@ for( mixerWorkerThread::jobQueueItems::iterator it = jq.items.end(); \
{ \
--it; \
jq.lock.lockForRead(); \
if( !it->done && it->workerID != i && \
if( _cond && !it->done && it->workerID != i && \
(++n) % m_numWorkers == 0 ) \
{ \
jq.lock.unlock(); \
@@ -515,13 +518,40 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
mixerWorkerThread::PlayHandle,
!( *it )->done() &&
!( *it )->supportsParallelizing() );
// we have to process all note-play-handles of a monophonic instrument by the
// same thread serially as monophonic instruments rely on processing note-play-
// handles in correct order
QHash<instrumentTrack *, int> h;
for( mixerWorkerThread::jobQueueItems::iterator it =
jq.items.begin(); it != jq.items.end(); ++it )
{
#define COND_NPH static_cast<playHandle *>( it->job )->type() == playHandle::NotePlayHandle
#define COND_MONOPHONIC static_cast<notePlayHandle *>( it->job )-> \
getInstrumentTrack()-> \
getInstrument()->isMonophonic()
if( COND_NPH )
{
if( COND_MONOPHONIC )
{
notePlayHandle * n = static_cast<notePlayHandle *>( it->job );
if( h.contains( n->getInstrumentTrack() ) )
{
it->workerID = h[n->getInstrumentTrack()];
}
else
{
h[n->getInstrumentTrack()] = it->workerID;
}
}
}
}
DISTRIBUTE_JOB_QUEUE(jq);
for( playHandleVector::iterator it = par_hndls.begin();
it != par_hndls.end(); ++it )
{
( *it )->waitForWorkerThread();
}
WAIT_FOR_JOBS();
WAIT_FOR_JOBS( h.size() > 0 && ( COND_NPH ? !COND_MONOPHONIC : TRUE ) );
}
else
{
@@ -558,7 +588,7 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
FILL_JOB_QUEUE(jq,QVector<audioPort*>,m_audioPorts,
mixerWorkerThread::AudioPortEffects,1);
DISTRIBUTE_JOB_QUEUE(jq);
WAIT_FOR_JOBS();
WAIT_FOR_JOBS(TRUE);
}
else
{