stable backport:
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/branches/lmms/stable-0.4@2048 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#include "bb_track_container.h"
|
||||
#include "clipboard.h"
|
||||
#include "combobox.h"
|
||||
#include "debug.h"
|
||||
@@ -579,11 +580,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() ) );
|
||||
|
||||
@@ -2973,6 +2975,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 )
|
||||
{
|
||||
if( validPattern() == false )
|
||||
@@ -3041,7 +3056,7 @@ void pianoRoll::recordAccompany( void )
|
||||
}
|
||||
|
||||
m_recording = true;
|
||||
|
||||
|
||||
if( m_pattern->getTrack()->getTrackContainer() == engine::getSong() )
|
||||
{
|
||||
engine::getSong()->play();
|
||||
@@ -3068,17 +3083,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<note>::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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
* song_editor.cpp - basic window for song-editing
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "tooltip.h"
|
||||
#include "visualization_widget.h"
|
||||
#include "audio_device.h"
|
||||
#include "piano_roll.h"
|
||||
|
||||
|
||||
|
||||
@@ -414,6 +415,7 @@ void songEditor::scrolled( int _new_pos )
|
||||
void songEditor::play( void )
|
||||
{
|
||||
m_s->play();
|
||||
engine::getPianoRoll()->stopRecording();
|
||||
if( m_s->playMode() == song::Mode_PlaySong )
|
||||
{
|
||||
m_playButton->setIcon( embed::getIconPixmap( "pause" ) );
|
||||
@@ -446,6 +448,7 @@ void songEditor::recordAccompany( void )
|
||||
void songEditor::stop( void )
|
||||
{
|
||||
m_s->stop();
|
||||
engine::getPianoRoll()->stopRecording();
|
||||
m_playButton->setIcon( embed::getIconPixmap( "play" ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* instrument_track.cpp - implementation of instrument-track-class
|
||||
* (window + data-structures)
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* 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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user