Fix stuck notes on notestacking

Fixes #865. Added a check so we don't add subnotes to a note that is already released (can happen with very short midinotes, eg. sliding the mouse accross the gui piano).
I also added a mutex to incoming midievent handling in instrumenttrack. Not sure if strictly necessary, but seems like this would prevent problems in the long run.
Also fixed a glitch in noteplayhandle where silent master notes got stuck playing indefinitely ( isMasternote() returns true even if the nph just hadChildren, so it never gets ended if it did - instead we check if we still have subnotes).
This commit is contained in:
Vesa
2014-06-19 00:30:48 +03:00
parent 4ef5b5fef3
commit 0f03219c93
4 changed files with 6 additions and 5 deletions

View File

@@ -230,6 +230,7 @@ private:
NotePlayHandle* m_notes[NumKeys];
int m_runningMidiNotes[NumKeys];
bool m_sustainPedalPressed;
QMutex m_notesMutex;
bool m_silentBuffersProcessed;

View File

@@ -235,7 +235,7 @@ void InstrumentFunctionNoteStacking::processNote( NotePlayHandle * _n )
// time an audio-buffer is rendered...
if( ( _n->origin() == NotePlayHandle::OriginArpeggio || ( _n->hasParent() == false && _n->instrumentTrack()->isArpeggioEnabled() == false ) ) &&
_n->totalFramesPlayed() == 0 &&
m_chordsEnabledModel.value() == true )
m_chordsEnabledModel.value() == true && ! _n->isReleased() )
{
// then insert sub-notes for chord
const int selected_chord = m_chordsModel.value();

View File

@@ -101,7 +101,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
m_instrumentTrack->midiNoteOn( *this );
}
if( hasParent() || !instrumentTrack->isArpeggioEnabled() )
if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() )
{
const int baseVelocity = m_instrumentTrack->midiPort()->baseVelocity();
@@ -229,7 +229,7 @@ void NotePlayHandle::play( sampleFrame * _working_buffer )
// because we do not allow NotePlayHandle::isFinished() to be true
// until all sub-notes are completely played and no new ones
// are inserted by arpAndChordsTabWidget::processNote()
if( isMasterNote() )
if( ! m_subNotes.isEmpty() )
{
m_releaseFramesToDo = m_releaseFramesDone + 2 * engine::mixer()->framesPerPeriod();
}
@@ -349,7 +349,7 @@ void NotePlayHandle::noteOff( const f_cnt_t _s )
m_framesBeforeRelease = _s;
m_releaseFramesToDo = qMax<f_cnt_t>( 0, actualReleaseFramesToDo() );
if( hasParent() || !instrumentTrack()->isArpeggioEnabled() )
if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() )
{
// send MidiNoteOff event
f_cnt_t realOffset = offset() + _s; // get actual frameoffset of release, in global time

View File

@@ -240,7 +240,7 @@ MidiEvent InstrumentTrack::applyMasterKey( const MidiEvent& event )
void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset )
{
engine::mixer()->lock();
QMutexLocker locker( &m_notesMutex );
bool eventHandled = false;
switch( event.type() )