From 889d1e8bb3c65626646f7c788ab95f8f553bc75e Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Mon, 3 Mar 2008 22:54:20 +0000 Subject: [PATCH] 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 --- ChangeLog | 40 ++++++++++++++++++++++++++++++++++++++++ configure.in | 4 ++-- src/core/mixer.cpp | 38 ++++++++++++++++++++++++++++++++++---- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 828b647d7..16a06dac2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2008-03-03 Tobias Doerffel + + * 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 * include/ladspa_control.h: diff --git a/configure.in b/configure.in index 65fc7665b..669327c17 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/src/core/mixer.cpp b/src/core/mixer.cpp index 40dab8160..1b99192c8 100644 --- a/src/core/mixer.cpp +++ b/src/core/mixer.cpp @@ -25,6 +25,7 @@ */ +#include #include #include @@ -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 h; + for( mixerWorkerThread::jobQueueItems::iterator it = + jq.items.begin(); it != jq.items.end(); ++it ) + { +#define COND_NPH static_cast( it->job )->type() == playHandle::NotePlayHandle +#define COND_MONOPHONIC static_cast( it->job )-> \ + getInstrumentTrack()-> \ + getInstrument()->isMonophonic() +if( COND_NPH ) +{ + if( COND_MONOPHONIC ) + { + notePlayHandle * n = static_cast( 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,m_audioPorts, mixerWorkerThread::AudioPortEffects,1); DISTRIBUTE_JOB_QUEUE(jq); - WAIT_FOR_JOBS(); + WAIT_FOR_JOBS(TRUE); } else {