Drop notes with length zero (#3031)
This commit is contained in:
committed by
GitHub
parent
ede0e07f5e
commit
1f90337523
@@ -97,6 +97,7 @@ public:
|
||||
static tick_t ticksPerTact( const TimeSig &sig );
|
||||
static int stepsPerTact();
|
||||
static void setTicksPerTact( tick_t tpt );
|
||||
static MidiTime stepPosition( int step );
|
||||
|
||||
private:
|
||||
tick_t m_ticks;
|
||||
|
||||
@@ -70,11 +70,11 @@ public:
|
||||
// note management
|
||||
Note * addNote( const Note & _new_note, const bool _quant_pos = true );
|
||||
|
||||
void removeNote( const Note * _note_to_del );
|
||||
void removeNote( Note * _note_to_del );
|
||||
|
||||
Note * noteAtStep( int _step );
|
||||
|
||||
Note * rearrangeNote( const Note * _note_to_proc,
|
||||
Note * rearrangeNote( Note * _note_to_proc,
|
||||
const bool _quant_pos = true );
|
||||
void rearrangeAllNotes();
|
||||
void clearNotes();
|
||||
@@ -84,7 +84,8 @@ public:
|
||||
return m_notes;
|
||||
}
|
||||
|
||||
void setStep( int _step, bool _enabled );
|
||||
Note * addStepNote( int step );
|
||||
void setStep( int step, bool enabled );
|
||||
|
||||
// pattern-type stuff
|
||||
inline PatternTypes type() const
|
||||
@@ -122,7 +123,6 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
void ensureBeatNotes();
|
||||
void updateBBTrack();
|
||||
|
||||
|
||||
|
||||
@@ -198,3 +198,9 @@ void MidiTime::setTicksPerTact( tick_t tpt )
|
||||
{
|
||||
s_ticksPerTact = tpt;
|
||||
}
|
||||
|
||||
|
||||
MidiTime MidiTime::stepPosition( int step )
|
||||
{
|
||||
return step * ticksPerTact() / stepsPerTact();
|
||||
}
|
||||
|
||||
@@ -1627,17 +1627,8 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
|
||||
m_mouseDownRight = true;
|
||||
if( it != notes.begin()-1 )
|
||||
{
|
||||
Note *note = *it;
|
||||
m_pattern->addJournalCheckPoint();
|
||||
if( note->length() > 0 )
|
||||
{
|
||||
m_pattern->removeNote( note );
|
||||
}
|
||||
else
|
||||
{
|
||||
note->setLength( 0 );
|
||||
m_pattern->dataChanged();
|
||||
}
|
||||
m_pattern->removeNote( *it );
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
}
|
||||
@@ -2288,19 +2279,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
|
||||
)
|
||||
{
|
||||
// delete this note
|
||||
if( it != notes.end() )
|
||||
{
|
||||
if( note->length() > 0 )
|
||||
{
|
||||
m_pattern->removeNote( note );
|
||||
}
|
||||
else
|
||||
{
|
||||
note->setLength( 0 );
|
||||
m_pattern->dataChanged();
|
||||
}
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
m_pattern->removeNote( note );
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3700,7 +3680,7 @@ void PianoRoll::cutSelectedNotes()
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
|
||||
for( const Note *note : selected_notes )
|
||||
for( Note *note : selected_notes )
|
||||
{
|
||||
// note (the memory of it) is also deleted by
|
||||
// pattern::removeNote(...) so we don't have to do that
|
||||
|
||||
@@ -656,25 +656,21 @@ bool InstrumentTrack::play( const MidiTime & _start, const fpp_t _frames,
|
||||
while( nit != notes.end() &&
|
||||
( cur_note = *nit )->pos() == cur_start )
|
||||
{
|
||||
if( cur_note->length() != 0 )
|
||||
const f_cnt_t note_frames =
|
||||
cur_note->length().frames( frames_per_tick );
|
||||
|
||||
NotePlayHandle* notePlayHandle = NotePlayHandleManager::acquire( this, _offset, note_frames, *cur_note );
|
||||
notePlayHandle->setBBTrack( bb_track );
|
||||
// are we playing global song?
|
||||
if( _tco_num < 0 )
|
||||
{
|
||||
const f_cnt_t note_frames =
|
||||
cur_note->length().frames(
|
||||
frames_per_tick );
|
||||
|
||||
NotePlayHandle* notePlayHandle = NotePlayHandleManager::acquire( this, _offset, note_frames, *cur_note );
|
||||
notePlayHandle->setBBTrack( bb_track );
|
||||
// are we playing global song?
|
||||
if( _tco_num < 0 )
|
||||
{
|
||||
// then set song-global offset of pattern in order to
|
||||
// properly perform the note detuning
|
||||
notePlayHandle->setSongGlobalParentOffset( p->startPosition() );
|
||||
}
|
||||
|
||||
Engine::mixer()->addPlayHandle( notePlayHandle );
|
||||
played_a_note = true;
|
||||
// then set song-global offset of pattern in order to
|
||||
// properly perform the note detuning
|
||||
notePlayHandle->setSongGlobalParentOffset( p->startPosition() );
|
||||
}
|
||||
|
||||
Engine::mixer()->addPlayHandle( notePlayHandle );
|
||||
played_a_note = true;
|
||||
++nit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,8 +151,6 @@ void Pattern::init()
|
||||
this, SLOT( changeTimeSignature() ) );
|
||||
saveJournallingState( false );
|
||||
|
||||
ensureBeatNotes();
|
||||
|
||||
changeLength( length() );
|
||||
restoreJournallingState();
|
||||
}
|
||||
@@ -256,7 +254,7 @@ Note * Pattern::addNote( const Note & _new_note, const bool _quant_pos )
|
||||
|
||||
|
||||
|
||||
void Pattern::removeNote( const Note * _note_to_del )
|
||||
void Pattern::removeNote( Note * _note_to_del )
|
||||
{
|
||||
instrumentTrack()->lock();
|
||||
NoteVector::Iterator it = m_notes.begin();
|
||||
@@ -288,7 +286,8 @@ Note * Pattern::noteAtStep( int _step )
|
||||
for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end();
|
||||
++it )
|
||||
{
|
||||
if( ( *it )->pos() == ( _step * MidiTime::ticksPerTact() ) / MidiTime::stepsPerTact() )
|
||||
if( ( *it )->pos() == MidiTime::stepPosition( _step )
|
||||
&& ( *it )->length() < 0 )
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
@@ -297,8 +296,7 @@ Note * Pattern::noteAtStep( int _step )
|
||||
}
|
||||
|
||||
|
||||
Note * Pattern::rearrangeNote( const Note * _note_to_proc,
|
||||
const bool _quant_pos )
|
||||
Note * Pattern::rearrangeNote( Note * _note_to_proc, const bool _quant_pos )
|
||||
{
|
||||
// just rearrange the position of the note by removing it and adding
|
||||
// a copy of it -> addNote inserts it at the correct position
|
||||
@@ -336,17 +334,29 @@ void Pattern::clearNotes()
|
||||
|
||||
|
||||
|
||||
void Pattern::setStep( int _step, bool _enabled )
|
||||
Note * Pattern::addStepNote( int step )
|
||||
{
|
||||
for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end();
|
||||
++it )
|
||||
return addNote( Note( MidiTime( -DefaultTicksPerTact ),
|
||||
MidiTime::stepPosition( step ) ), false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Pattern::setStep( int step, bool enabled )
|
||||
{
|
||||
if( enabled )
|
||||
{
|
||||
if( ( *it )->pos() == ( _step * MidiTime::ticksPerTact() ) / MidiTime::stepsPerTact() &&
|
||||
( *it )->length() <= 0 )
|
||||
if ( !noteAtStep( step ) )
|
||||
{
|
||||
( *it )->setLength( _enabled ?
|
||||
-DefaultTicksPerTact : 0 );
|
||||
addStepNote( step );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while( Note * note = noteAtStep( step ) )
|
||||
{
|
||||
removeNote( note );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,10 +417,7 @@ void Pattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
for( NoteVector::Iterator it = m_notes.begin();
|
||||
it != m_notes.end(); ++it )
|
||||
{
|
||||
if( ( *it )->length() )
|
||||
{
|
||||
( *it )->saveState( _doc, _this );
|
||||
}
|
||||
( *it )->saveState( _doc, _this );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +460,6 @@ void Pattern::loadSettings( const QDomElement & _this )
|
||||
m_steps = MidiTime::stepsPerTact();
|
||||
}
|
||||
|
||||
ensureBeatNotes();
|
||||
checkType();
|
||||
|
||||
emit dataChanged();
|
||||
@@ -494,7 +500,6 @@ void Pattern::clear()
|
||||
{
|
||||
addJournalCheckPoint();
|
||||
clearNotes();
|
||||
ensureBeatNotes();
|
||||
}
|
||||
|
||||
|
||||
@@ -503,7 +508,6 @@ void Pattern::clear()
|
||||
void Pattern::addSteps()
|
||||
{
|
||||
m_steps += MidiTime::stepsPerTact();
|
||||
ensureBeatNotes();
|
||||
emit dataChanged();
|
||||
updateBBTrack();
|
||||
}
|
||||
@@ -512,7 +516,6 @@ void Pattern::cloneSteps()
|
||||
{
|
||||
int oldLength = m_steps;
|
||||
m_steps *= 2; // cloning doubles the track
|
||||
ensureBeatNotes();
|
||||
for(int i = 0; i < oldLength; ++i )
|
||||
{
|
||||
Note *toCopy = noteAtStep( i );
|
||||
@@ -526,7 +529,6 @@ void Pattern::cloneSteps()
|
||||
newNote->setVolume( toCopy->getVolume() );
|
||||
}
|
||||
}
|
||||
ensureBeatNotes();
|
||||
emit dataChanged();
|
||||
updateBBTrack();
|
||||
}
|
||||
@@ -541,18 +543,7 @@ void Pattern::removeSteps()
|
||||
{
|
||||
for( int i = m_steps - n; i < m_steps; ++i )
|
||||
{
|
||||
for( NoteVector::Iterator it = m_notes.begin();
|
||||
it != m_notes.end(); ++it )
|
||||
{
|
||||
if( ( *it )->pos() ==
|
||||
( i * MidiTime::ticksPerTact() ) /
|
||||
MidiTime::stepsPerTact() &&
|
||||
( *it )->length() <= 0 )
|
||||
{
|
||||
removeNote( *it );
|
||||
break;
|
||||
}
|
||||
}
|
||||
setStep( i, false );
|
||||
}
|
||||
m_steps -= n;
|
||||
emit dataChanged();
|
||||
@@ -571,66 +562,6 @@ TrackContentObjectView * Pattern::createView( TrackView * _tv )
|
||||
|
||||
|
||||
|
||||
|
||||
void Pattern::ensureBeatNotes()
|
||||
{
|
||||
// make sure, that all step-note exist
|
||||
for( int i = 0; i < m_steps; ++i )
|
||||
{
|
||||
bool found = false;
|
||||
NoteVector::Iterator it;
|
||||
|
||||
for( it = m_notes.begin(); it != m_notes.end(); ++it )
|
||||
{
|
||||
Note *note = *it;
|
||||
// if a note in this position is the one we want
|
||||
if( note->pos() ==
|
||||
( i * MidiTime::ticksPerTact() ) / MidiTime::stepsPerTact()
|
||||
&& note->length() <= 0 )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( found == false )
|
||||
{
|
||||
addNote( Note( MidiTime( 0 ), MidiTime( ( i *
|
||||
MidiTime::ticksPerTact() ) /
|
||||
MidiTime::stepsPerTact() ) ), false );
|
||||
}
|
||||
}
|
||||
|
||||
// remove notes we no longer need:
|
||||
// that is, disabled notes that no longer fall to the steps of the new time sig
|
||||
|
||||
for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end(); )
|
||||
{
|
||||
bool needed = false;
|
||||
Note *note = *it;
|
||||
|
||||
for( int i = 0; i < m_steps; ++i )
|
||||
{
|
||||
if( note->pos() == ( i * MidiTime::ticksPerTact() ) / MidiTime::stepsPerTact()
|
||||
|| note->length() != 0 )
|
||||
{
|
||||
needed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( needed == false )
|
||||
{
|
||||
delete note;
|
||||
it = m_notes.erase( it );
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Pattern::updateBBTrack()
|
||||
{
|
||||
if( getTrack()->trackContainer() == Engine::getBBTrackContainer() )
|
||||
@@ -676,23 +607,8 @@ void Pattern::changeTimeSignature()
|
||||
}
|
||||
}
|
||||
last_pos = last_pos.nextFullTact() * MidiTime::ticksPerTact();
|
||||
for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end(); )
|
||||
{
|
||||
if( ( *it )->length() == 0 && ( *it )->pos() >= last_pos )
|
||||
{
|
||||
delete *it;
|
||||
it = m_notes.erase( it );
|
||||
--m_steps;
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
m_steps = qMax<tick_t>(
|
||||
qMax<tick_t>( m_steps, MidiTime::stepsPerTact() ),
|
||||
m_steps = qMax<tick_t>( MidiTime::stepsPerTact(),
|
||||
last_pos.getTact() * MidiTime::stepsPerTact() );
|
||||
ensureBeatNotes();
|
||||
updateBBTrack();
|
||||
}
|
||||
|
||||
@@ -865,28 +781,14 @@ void PatternView::mousePressEvent( QMouseEvent * _me )
|
||||
|
||||
Note * n = m_pat->noteAtStep( step );
|
||||
|
||||
// if note at step not found, ensureBeatNotes and try again
|
||||
if( n == NULL )
|
||||
{
|
||||
m_pat -> ensureBeatNotes();
|
||||
n = m_pat->noteAtStep( step );
|
||||
if( n == NULL ) // still can't find a note? bail!
|
||||
{
|
||||
qDebug( "Something went wrong in pattern.cpp: couldn't add note at step %d!", step );
|
||||
return;
|
||||
}
|
||||
m_pat->addStepNote( step );
|
||||
}
|
||||
else // note at step found
|
||||
{
|
||||
m_pat->addJournalCheckPoint();
|
||||
if( n->length() < 0 )
|
||||
{
|
||||
n->setLength( 0 ); // set note as enabled beat note
|
||||
}
|
||||
else
|
||||
{
|
||||
n->setLength( -DefaultTicksPerTact ); // set note as disabled beat note
|
||||
}
|
||||
m_pat->setStep( step, false );
|
||||
}
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
@@ -941,21 +843,17 @@ void PatternView::wheelEvent( QWheelEvent * _we )
|
||||
return;
|
||||
}
|
||||
|
||||
int vol = 0;
|
||||
int len = 0;
|
||||
|
||||
Note * n = m_pat->noteAtStep( step );
|
||||
if( !n && _we->delta() > 0 )
|
||||
{
|
||||
n = m_pat->addStepNote( step );
|
||||
n->setVolume( 0 );
|
||||
}
|
||||
if( n != NULL )
|
||||
{
|
||||
vol = n->getVolume();
|
||||
len = n->length();
|
||||
int vol = n->getVolume();
|
||||
|
||||
if( len == 0 && _we->delta() > 0 )
|
||||
{
|
||||
n->setLength( -DefaultTicksPerTact );
|
||||
n->setVolume( 5 );
|
||||
}
|
||||
else if( _we->delta() > 0 )
|
||||
if( _we->delta() > 0 )
|
||||
{
|
||||
n->setVolume( qMin( 100, vol + 5 ) );
|
||||
}
|
||||
@@ -1150,14 +1048,9 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
const int x = TCO_BORDER_WIDTH + static_cast<int>( it * w / steps );
|
||||
const int y = height() - s_stepBtnOff->height() - 1;
|
||||
|
||||
// get volume and length of note, if noteAtStep returned null
|
||||
// (meaning, note at step doesn't exist for some reason)
|
||||
// then set both at zero, ie. treat as an off step
|
||||
const int vol = ( n != NULL ? n->getVolume() : 0 );
|
||||
const int len = ( n != NULL ? int( n->length() ) : 0 );
|
||||
|
||||
if( len < 0 )
|
||||
if( n )
|
||||
{
|
||||
const int vol = n->getVolume();
|
||||
p.drawPixmap( x, y, stepoff );
|
||||
for( int i = 0; i < vol / 5 + 1; ++i )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user