Ensure that NotePlayHandles get processed before the InstrumentPlayHandle on instruments that use both NotePlayHandles and InstrumentPlayHandle, such as LB302 and SF2-Player

Issue: Currently, we use threads to process all PlayHandles, so there's no guarantee of the order they are processed in. This causes timing inaccuracy and jitter: notes of instruments that use both NPH's and IPH's can get randomly delayed by one entire period.
The issue is solved thusly:
- When processing an IPH, we check if the instrument is midi-based. If yes, we just process it normally (no NPH's to worry about).
- If it's not, then it also uses NPH's, so we'll have the IPH wait until all NPH's belonging to same instrument have been processed. There's some similar code in the new FX mixer, I pretty much just copied how we do it there.
This commit is contained in:
Vesa
2014-06-06 14:24:51 +03:00
parent dba1e75a53
commit bad08a2632
3 changed files with 25 additions and 5 deletions

View File

@@ -119,13 +119,13 @@ public:
virtual bool isFromTrack( const track * _track ) const;
protected:
inline InstrumentTrack * instrumentTrack() const
{
return m_instrumentTrack;
}
protected:
// instruments may use this to apply a soft fade out at the end of
// notes - method does this only if really less or equal
// desiredReleaseFrames() frames are left

View File

@@ -22,11 +22,12 @@
*
*/
#ifndef _INSTRUMENT_PLAY_HANDLE_H
#define _INSTRUMENT_PLAY_HANDLE_H
#ifndef INSTRUMENT_PLAY_HANDLE_H
#define INSTRUMENT_PLAY_HANDLE_H
#include "PlayHandle.h"
#include "Instrument.h"
#include "NotePlayHandle.h"
class InstrumentPlayHandle : public PlayHandle
@@ -45,6 +46,25 @@ public:
virtual void play( sampleFrame * _working_buffer )
{
// if the instrument is midi-based, we can safely render right away
if( m_instrument->flags() & Instrument::IsMidiBased )
{
m_instrument->play( _working_buffer );
return;
}
// if not, we need to ensure that all our nph's have been processed first
ConstNotePlayHandleList nphv = NotePlayHandle::nphsOfInstrumentTrack( m_instrument->instrumentTrack(), true );
foreach( const NotePlayHandle * cnph, nphv )
{
NotePlayHandle * nph = const_cast<NotePlayHandle *>( cnph );
while( nph->state() != ThreadableJob::Done )
{
nph->process();
}
}
m_instrument->play( _working_buffer );
}

View File

@@ -79,7 +79,7 @@ public:
virtual Flags flags() const
{
return IsSingleStreamed | IsMidiBased;
return IsSingleStreamed;
}
virtual PluginView * instantiateView( QWidget * _parent );