diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 6d2e42c3d6a..5ef604defb8 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -237,6 +237,7 @@ protected slots: MidiPort m_midiPort; NotePlayHandle* m_notes[NumKeys]; + NotePlayHandleList m_sustainedNotes; int m_runningMidiNotes[NumKeys]; QMutex m_midiNotesMutex; diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 0dff48fc02b..84d888fee6b 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -252,17 +252,8 @@ void NotePlayHandle::play( sampleFrame * _working_buffer ) if( m_released && (!instrumentTrack()->isSustainPedalPressed() || m_releaseStarted) ) { - if (m_releaseStarted == false) - { + m_releaseStarted = true; - if( m_origin == OriginMidiInput ) - { - setLength( MidiTime( static_cast( totalFramesPlayed() / Engine::framesPerTick() ) ) ); - m_instrumentTrack->midiNoteOff( *this ); - } - - m_releaseStarted = true; - } f_cnt_t todo = framesThisPeriod; // if this note is base-note for arpeggio, always set @@ -389,6 +380,16 @@ void NotePlayHandle::noteOff( const f_cnt_t _s ) MidiTime::fromFrames( _s, Engine::framesPerTick() ), _s ); } + + // inform attached components about MIDI finished (used for recording in Piano Roll) + if (!instrumentTrack()->isSustainPedalPressed()) + { + if( m_origin == OriginMidiInput ) + { + setLength( MidiTime( static_cast( totalFramesPlayed() / Engine::framesPerTick() ) ) ); + m_instrumentTrack->midiNoteOff( *this ); + } + } } diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 71cc43fb56e..21a589c4152 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -273,6 +273,12 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti // be deleted later automatically) Engine::mixer()->requestChangeInModel(); m_notes[event.key()]->noteOff( offset ); + if (isSustainPedalPressed() && + m_notes[event.key()]->origin() == + m_notes[event.key()]->OriginMidiInput) + { + m_sustainedNotes << m_notes[event.key()]; + } m_notes[event.key()] = NULL; Engine::mixer()->doneChangeInModel(); } @@ -302,8 +308,24 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti { m_sustainPedalPressed = true; } - else + else if (isSustainPedalPressed()) { + for (NotePlayHandle* nph : m_sustainedNotes) + { + if (nph && nph->isReleased()) + { + if( nph->origin() == + nph->OriginMidiInput) + { + nph->setLength( + MidiTime( static_cast( + nph->totalFramesPlayed() / + Engine::framesPerTick() ) ) ); + midiNoteOff( *nph ); + } + } + } + m_sustainedNotes.clear(); m_sustainPedalPressed = false; } }