From 8aec19379e086a8da09f25169a87bdacd915af45 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Thu, 19 Feb 2009 13:37:41 +0000 Subject: [PATCH] fixed various bugs regarding recording: * once recording has been started, stop it as soon as playMode of song changes or similiar things happen (closes #2486341) * fixed broken record-accompany in most use-cases other than using record-while-playing-song by also tracking NoteOn events and remember current play position to use the correct note postitions on NoteOff events (play position might have wrapped around in the meantime due to looppoints or end of BB track) (closes #2486299, #2486203) git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@2046 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 16 ++++++++ include/instrument_track.h | 5 ++- include/piano_roll.h | 17 ++++++-- src/gui/piano_roll.cpp | 73 +++++++++++++++++++++++++++------ src/gui/song_editor.cpp | 5 ++- src/tracks/instrument_track.cpp | 10 +++-- 6 files changed, 103 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index db756e042..ffbedbd57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2009-02-19 Tobias Doerffel + + * include/instrument_track.h: + * include/piano_roll.h: + * src/gui/piano_roll.cpp: + * src/gui/song_editor.cpp: + * src/tracks/instrument_track.cpp: + fixed various bugs regarding recording: + - once recording has been started, stop it as soon as playMode of song + changes or similiar things happen (closes #2486341) + - fixed broken record-accompany in most use-cases other than using + record-while-playing-song by also tracking NoteOn events and remember + current play position to use the correct note postitions on NoteOff + events (play position might have wrapped around in the meantime due + to looppoints or end of BB track) (closes #2486299, #2486203) + 2009-02-14 Andrew Kelley * src/gui/dialogs/about_dialog.ui: diff --git a/include/instrument_track.h b/include/instrument_track.h index e061a90e8..7b7fab9bf 100644 --- a/include/instrument_track.h +++ b/include/instrument_track.h @@ -2,7 +2,7 @@ * instrument_track.h - declaration of class instrumentTrack, a track + window * which holds an instrument-plugin * - * Copyright (c) 2004-2008 Tobias Doerffel + * Copyright (c) 2004-2009 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -185,7 +185,8 @@ public: signals: void instrumentChanged( void ); void newNote( void ); - void noteDone( const note & _n ); + void noteOn( const note & _n ); + void noteOff( const note & _n ); void nameChanged( void ); diff --git a/include/piano_roll.h b/include/piano_roll.h index d29d245a5..a58f0c606 100644 --- a/include/piano_roll.h +++ b/include/piano_roll.h @@ -2,7 +2,7 @@ * piano_roll.h - declaration of class pianoRoll which is a window where you * can set and edit notes in an easy way * - * Copyright (c) 2004-2008 Tobias Doerffel + * Copyright (c) 2004-2009 Tobias Doerffel * Copyright (c) 2008 Andrew Kelley * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -32,6 +32,7 @@ #include "serializing_object.h" #include "note.h" #include "lmms_basics.h" +#include "song.h" #include "fluiq/collapsible_widget.h" @@ -55,6 +56,11 @@ class pianoRoll : public FLUIQ::CollapsibleWidget, public serializingObject public: void setCurrentPattern( pattern * _new_pattern ); + inline void stopRecording( void ) + { + m_recording = false; + } + inline bool isRecording( void ) const { return m_recording; @@ -70,6 +76,8 @@ public: return m_pattern != NULL; } + song::PlayModes desiredPlayModeForAccompany( void ) const; + int quantization( void ) const; @@ -80,6 +88,8 @@ public: { return "pianoroll"; } + + public slots: void play( void ); void record( void ); @@ -109,8 +119,8 @@ protected: protected slots: - - void recordNote( const note & _n ); + void startRecordNote( const note & _n ); + void finishRecordNote( const note & _n ); void horScrolled( int _new_pos ); void verScrolled( int _new_pos ); @@ -241,6 +251,7 @@ private: midiTime m_currentPosition; bool m_recording; + QList m_recordingNotes; note * m_currentNote; Actions m_action; diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp index b84e412e0..5828eb279 100644 --- a/src/gui/piano_roll.cpp +++ b/src/gui/piano_roll.cpp @@ -48,6 +48,7 @@ #include +#include "bb_track_container.h" #include "clipboard.h" #include "combobox.h" #include "debug.h" @@ -574,11 +575,12 @@ void pianoRoll::setCurrentPattern( pattern * _new_pattern ) // of start-notes and so on...) resizeEvent( NULL ); - // and now connect to noteDone()-signal of channel so that - // we receive note-off-events from it's midi-port for recording it connect( m_pattern->getInstrumentTrack(), - SIGNAL( noteDone( const note & ) ), - this, SLOT( recordNote( const note & ) ) ); + SIGNAL( noteOn( const note & ) ), + this, SLOT( startRecordNote( const note & ) ) ); + connect( m_pattern->getInstrumentTrack(), + SIGNAL( noteOff( const note & ) ), + this, SLOT( finishRecordNote( const note & ) ) ); setWindowTitle( tr( "Piano-Roll - %1" ).arg( m_pattern->name() ) ); @@ -2964,6 +2966,19 @@ int pianoRoll::getKey( int _y ) const +song::PlayModes pianoRoll::desiredPlayModeForAccompany( void ) const +{ + if( m_pattern->getTrack()->getTrackContainer() == + engine::getBBTrackContainer() ) + { + return song::Mode_PlayBB; + } + return song::Mode_PlaySong; +} + + + + void pianoRoll::play( void ) { engine::getMainWindow()->setPlaybackMode( PPM_PianoRoll ); @@ -3038,7 +3053,7 @@ void pianoRoll::recordAccompany( void ) } m_recording = true; - + if( m_pattern->getTrack()->getTrackContainer() == engine::getSong() ) { engine::getSong()->play(); @@ -3065,17 +3080,49 @@ void pianoRoll::stop( void ) -void pianoRoll::recordNote( const note & _n ) +void pianoRoll::startRecordNote( const note & _n ) { - if( m_recording == true && validPattern() == true ) + if( m_recording == true && validPattern() == true && + engine::getSong()->isPlaying() && + ( engine::getSong()->playMode() == + desiredPlayModeForAccompany() || + engine::getSong()->playMode() == + song::Mode_PlayPattern ) ) { - note n( _n.length(), engine::getSong()->getPlayPos( - engine::getSong()->playMode() ) - _n.length(), + note n( 1, engine::getSong()->getPlayPos( + engine::getSong()->playMode() ), _n.key(), _n.getVolume(), _n.getPanning() ); - n.quantizeLength( quantization() ); - m_pattern->addNote( n ); - update(); - engine::getSong()->setModified(); + m_recordingNotes << n; + } +} + + + + +void pianoRoll::finishRecordNote( const note & _n ) +{ + if( m_recording == true && validPattern() == true && + engine::getSong()->isPlaying() && + ( engine::getSong()->playMode() == + desiredPlayModeForAccompany() || + engine::getSong()->playMode() == + song::Mode_PlayPattern ) ) + { + for( QList::Iterator it = m_recordingNotes.begin(); + it != m_recordingNotes.end(); ++it ) + { + if( it->key() == _n.key() ) + { + note n( _n.length(), it->pos(), + it->key(), it->getVolume(), + it->getPanning() ); + n.quantizeLength( quantization() ); + m_pattern->addNote( n ); + update(); + m_recordingNotes.erase( it ); + break; + } + } } } diff --git a/src/gui/song_editor.cpp b/src/gui/song_editor.cpp index e77c6113d..158c48cb3 100644 --- a/src/gui/song_editor.cpp +++ b/src/gui/song_editor.cpp @@ -3,7 +3,7 @@ /* * song_editor.cpp - basic window for song-editing * - * Copyright (c) 2004-2008 Tobias Doerffel + * Copyright (c) 2004-2009 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -47,6 +47,7 @@ #include "tool_button.h" #include "tooltip.h" #include "audio_device.h" +#include "piano_roll.h" @@ -280,6 +281,7 @@ void songEditor::play( void ) engine::getMainWindow()->setPlaybackMode( PPM_Song ); m_s->play(); + engine::getPianoRoll()->stopRecording(); if( m_s->playMode() == song::Mode_PlaySong ) { m_playButton->setIcon( embed::getIconPixmap( "pause" ) ); @@ -316,6 +318,7 @@ void songEditor::recordAccompany( void ) void songEditor::stop( void ) { m_s->stop(); + engine::getPianoRoll()->stopRecording(); m_playButton->setIcon( embed::getIconPixmap( "play" ) ); } diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp index 32f191770..ef8c2a227 100644 --- a/src/tracks/instrument_track.cpp +++ b/src/tracks/instrument_track.cpp @@ -2,7 +2,7 @@ * instrument_track.cpp - implementation of instrument-track-class * (window + data-structures) * - * Copyright (c) 2004-2008 Tobias Doerffel + * Copyright (c) 2004-2009 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -248,6 +248,8 @@ void instrumentTrack::processInEvent( const midiEvent & _me, { m_notes[_me.key()] = nph; } + + emit noteOn( n ); } break; } @@ -259,7 +261,7 @@ void instrumentTrack::processInEvent( const midiEvent & _me, { // create dummy-note which has the same length // as the played note for sending it later - // to all slots connected to signal noteDone() + // to all slots connected to signal noteOff() // this is for example needed by piano-roll for // recording notes into a pattern note done_note( @@ -274,7 +276,7 @@ void instrumentTrack::processInEvent( const midiEvent & _me, n->noteOff(); m_notes[_me.key()] = NULL; - emit noteDone( done_note ); + emit noteOff( done_note ); } break; } @@ -463,7 +465,7 @@ void instrumentTrack::deleteNotePluginData( notePlayHandle * _n ) _n->getVolume(), _n->getPanning() ); _n->noteOff(); m_notes[_n->key()] = NULL; - emit noteDone( done_note ); + emit noteOff( done_note ); } }