diff --git a/ChangeLog b/ChangeLog index 941196f21..79d722d5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-07-16 Tobias Doerffel + + * src/core/mixer.cpp: + fixed logical error in mixer::renderNextBuffer() which led to lot of + clicks and pops when using parallelization-level > 1 + + * include/note_play_handle.h: + * src/tracks/instrument_track-cpp: + fixed broken detection of last period of a note which resulted in + clicks and pops as the soft fade-out at the end sometimes was done twice + 2007-05-12 Javier Serrano Polo * include/clipboard.h: diff --git a/include/note_play_handle.h b/include/note_play_handle.h index 6543d5f13..d33770d94 100644 --- a/include/note_play_handle.h +++ b/include/note_play_handle.h @@ -33,6 +33,7 @@ #include "note.h" #include "instrument.h" #include "instrument_track.h" +#include "engine.h" class notePlayHandle; @@ -70,6 +71,55 @@ public: m_releaseFramesDone >= m_releaseFramesToDo ) ); } + bool willFinishThisPeriod( void ) const + { + f_cnt_t rftd = m_releaseFramesToDo; + f_cnt_t fbr = m_framesBeforeRelease; + f_cnt_t rfd = m_releaseFramesDone; + if( m_released == TRUE ) + { + f_cnt_t todo = engine::getMixer()->framesPerAudioBuffer(); + if( arpBaseNote() == TRUE ) + { + rftd = rfd + 2 * + engine::getMixer()->framesPerAudioBuffer(); + } + if( fbr ) + { + if( fbr <= + engine::getMixer()->framesPerAudioBuffer() ) + { + todo -= fbr; + fbr = 0; + } + else + { + todo = 0; + fbr -= + engine::getMixer()->framesPerAudioBuffer(); + } + } + if( todo && rfd < rftd ) + { + if( rftd - rfd >= todo ) + { + rfd += todo; + } + else + { + rfd = rftd; + } + } + } + + if( arpBaseNote() == TRUE && m_subNotes.size() == 0 ) + { + rfd = rftd; + } + + return( ( m_released && fbr == 0 && rfd >= rftd ) ); + } + virtual bool isFromTrack( const track * _track ) const; @@ -87,6 +137,7 @@ public: f_cnt_t actualReleaseFramesToDo( void ) const; + // returns how many samples this note is aligned ahead, i.e. // at which position it is inserted in the according buffer inline f_cnt_t framesAhead( void ) const diff --git a/src/core/mixer.cpp b/src/core/mixer.cpp index 2e2ef7e1b..a2b15ebfa 100644 --- a/src/core/mixer.cpp +++ b/src/core/mixer.cpp @@ -327,8 +327,12 @@ const surroundSampleFrame * mixer::renderNextBuffer( void ) else if( !n->supportsParallelizing() ) { n->play(); + ++idx; + } + else + { + ++idx; } - ++idx; } for( playHandleVector::iterator it = par_hndls.begin(); it != par_hndls.end(); ++it ) @@ -340,7 +344,7 @@ const surroundSampleFrame * mixer::renderNextBuffer( void ) { while( idx < m_playHandles.size() ) { - register playHandle * n = m_playHandles[idx]; + playHandle * n = m_playHandles[idx]; // delete play-handle if it played completely if( n->done() ) { diff --git a/src/core/note_play_handle.cpp b/src/core/note_play_handle.cpp index 728b84055..dca3c2346 100644 --- a/src/core/note_play_handle.cpp +++ b/src/core/note_play_handle.cpp @@ -202,7 +202,7 @@ void notePlayHandle::play( bool _try_parallelizing ) } else { - // no, then just decrese framesBeforeRelease + // no, then just decrease framesBeforeRelease // and wait for next loop... (we're not in // release-phase yet) todo = 0; diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp index fd883c5dc..3691d1f0c 100644 --- a/src/tracks/instrument_track.cpp +++ b/src/tracks/instrument_track.cpp @@ -576,14 +576,9 @@ void instrumentTrack::processAudioBuffer( sampleFrame * _buf, } } } + // last time we're called for current note? - if( ( _n->actualReleaseFramesToDo() == 0 && - _n->totalFramesPlayed() + - engine::getMixer()->framesPerAudioBuffer() >= - _n->frames() ) || - ( _n->released() && _n->releaseFramesDone() + - engine::getMixer()->framesPerAudioBuffer() >= - _n->actualReleaseFramesToDo() ) ) + if( _n->willFinishThisPeriod() ) { // then do a soft fade-out at the end to avoid clicks for( fpab_t i = ( _frames >= ENV_FRAMES ) ?