SF2: Make timing more accurate, also some fixes

I'm not saying sample-accurate, because it turns out, Fluidsynth has an internal buffer size and thus timing granularity of 64 frames. So 64 frames is the max. accuracy attainable for SF2. But it's better than nothing. Big thanks to David Henningsson of the Fluidsynth dev team, who very helpfully answered questions. A great guy.
In addition, there are some fixes to earlier commits here, which I ran into while working on the SF2 timing.
This commit is contained in:
Vesa
2014-07-06 16:11:35 +03:00
parent 8407427c4b
commit ff0c9beadd
4 changed files with 172 additions and 100 deletions

View File

@@ -29,6 +29,7 @@
#include "DetuningHelper.h"
#include "InstrumentSoundShaping.h"
#include "InstrumentTrack.h"
#include "Instrument.h"
#include "MidiEvent.h"
#include "MidiPort.h"
#include "song.h"
@@ -197,7 +198,9 @@ void NotePlayHandle::play( sampleFrame * _working_buffer )
instrumentTrack()->isSustainPedalPressed() == false &&
m_totalFramesPlayed + framesThisPeriod > m_frames )
{
noteOff( m_frames - m_totalFramesPlayed );
noteOff( m_totalFramesPlayed == 0
? ( m_frames + offset() ) // if we have noteon and noteoff during the same period, take offset in account for release frame
: ( m_frames - m_totalFramesPlayed ) ); // otherwise, the offset is already negated and can be ignored
}
// under some circumstances we're called even if there's nothing to play
@@ -206,7 +209,9 @@ void NotePlayHandle::play( sampleFrame * _working_buffer )
if( framesLeft() > 0 )
{
// clear offset frames if we're at the first period
if( m_totalFramesPlayed == 0 )
// skip for single-streamed instruments, because in their case NPH::play() could be called from an IPH without a buffer argument
// ... also, they don't actually render the sound in NPH's, which is an even better reason to skip...
if( m_totalFramesPlayed == 0 && ! ( m_instrumentTrack->instrument()->flags() & Instrument::IsSingleStreamed ) )
{
memset( _working_buffer, 0, sizeof( sampleFrame ) * offset() );
}