diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 4057d7990..d4ca720c3 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -204,8 +204,8 @@ public: signals: void instrumentChanged(); void newNote(); - void noteOn( const note & _n ); - void noteOff( const note & _n ); + void midiNoteOn( const note& ); + void midiNoteOff( const note& ); void nameChanged(); diff --git a/src/core/note_play_handle.cpp b/src/core/note_play_handle.cpp index 96d93c3de..6a434aea6 100644 --- a/src/core/note_play_handle.cpp +++ b/src/core/note_play_handle.cpp @@ -105,6 +105,11 @@ notePlayHandle::notePlayHandle( InstrumentTrack * _it, setFrames( _frames ); + // inform attached components about new MIDI note (used for recording in Piano Roll) + if( m_origin == OriginMidiInput ) + { + m_instrumentTrack->midiNoteOn( *this ); + } if( !isTopNote() || !instrumentTrack()->isArpeggioEnabled() ) { @@ -122,6 +127,13 @@ notePlayHandle::~notePlayHandle() { noteOff( 0 ); + // inform attached components about MIDI finished (used for recording in Piano Roll) + if( m_origin == OriginMidiInput ) + { + setLength( MidiTime( static_cast( totalFramesPlayed() / engine::framesPerTick() ) ) ); + m_instrumentTrack->midiNoteOff( *this ); + } + if( isTopNote() ) { delete m_baseDetuning; diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp index 6eace8b46..ddd450faa 100644 --- a/src/gui/piano_roll.cpp +++ b/src/gui/piano_roll.cpp @@ -765,15 +765,9 @@ void pianoRoll::setCurrentPattern( pattern * _new_pattern ) // of start-notes and so on...) resizeEvent( NULL ); - connect( m_pattern->instrumentTrack(), - SIGNAL( noteOn( const note & ) ), - this, SLOT( startRecordNote( const note & ) ) ); - connect( m_pattern->instrumentTrack(), - SIGNAL( noteOff( const note & ) ), - this, SLOT( finishRecordNote( const note & ) ) ); - connect( m_pattern->instrumentTrack()->pianoModel(), - SIGNAL( dataChanged() ), - this, SLOT( update() ) ); + connect( m_pattern->instrumentTrack(), SIGNAL( midiNoteOn( const note& ) ), this, SLOT( startRecordNote( const note& ) ) ); + connect( m_pattern->instrumentTrack(), SIGNAL( midiNoteOff( const note& ) ), this, SLOT( finishRecordNote( const note& ) ) ); + connect( m_pattern->instrumentTrack()->pianoModel(), SIGNAL( dataChanged() ), this, SLOT( update() ) ); setWindowTitle( tr( "Piano-Roll - %1" ).arg( m_pattern->name() ) ); diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index c05a379f1..e7a58834a 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -237,20 +237,16 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti { if( m_notes[event.key()] == NULL ) { - // create temporary note - note n; - n.setKey( event.key() ); - n.setVolume( event.volume() ); - // create (timed) note-play-handle - notePlayHandle* nph = new notePlayHandle( this, time.frames( engine::framesPerTick() ), typeInfo::max() / 2, - n, NULL, false, event.channel() ); + notePlayHandle* nph = new notePlayHandle( this, time.frames( engine::framesPerTick() ), + typeInfo::max() / 2, + note( MidiTime(), MidiTime(), event.key(), event.volume() ), + NULL, false, event.channel(), + notePlayHandle::OriginMidiInput ); if( engine::mixer()->addPlayHandle( nph ) ) { m_notes[event.key()] = nph; } - - emit noteOn( n ); } eventHandled = true; @@ -258,28 +254,15 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti } case MidiNoteOff: - { - notePlayHandle* nph = m_notes[event.key()]; - if( nph != NULL ) + if( m_notes[event.key()] != NULL ) { - // create dummy-note which has the same length - // as the played note for sending it later - // to all slots connected to signal noteOff() - // this is for example needed by piano-roll for - // recording notes into a pattern - note n( MidiTime( static_cast( nph->totalFramesPlayed() / engine::framesPerTick() ) ), - 0, nph->key(), nph->getVolume(), nph->getPanning() ); - - emit noteOff( n ); - - // now do actual note off and remove internal reference to NotePlayHandle (which itself will + // do actual note off and remove internal reference to NotePlayHandle (which itself will // be deleted later automatically) - nph->noteOff(); + m_notes[event.key()]->noteOff(); m_notes[event.key()] = NULL; } eventHandled = true; break; - } case MidiKeyPressure: if( m_notes[event.key()] != NULL ) @@ -467,24 +450,11 @@ QString InstrumentTrack::instrumentName() const -void InstrumentTrack::deleteNotePluginData( notePlayHandle * _n ) +void InstrumentTrack::deleteNotePluginData( notePlayHandle* n ) { if( m_instrument != NULL ) { - m_instrument->deleteNotePluginData( _n ); - } - - // Notes deleted when keys still pressed - if( m_notes[_n->key()] == _n ) - { - note done_note( MidiTime( static_cast( - _n->totalFramesPlayed() / - engine::framesPerTick() ) ), - 0, _n->key(), - _n->getVolume(), _n->getPanning() ); - _n->noteOff(); - m_notes[_n->key()] = NULL; - emit noteOff( done_note ); + m_instrument->deleteNotePluginData( n ); } }