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:
@@ -230,6 +230,7 @@ private:
|
||||
NotePlayHandle* m_notes[NumKeys];
|
||||
int m_runningMidiNotes[NumKeys];
|
||||
bool m_sustainPedalPressed;
|
||||
QMutex m_notesMutex;
|
||||
|
||||
bool m_silentBuffersProcessed;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() )
|
||||
|
||||
Reference in New Issue
Block a user