Drop notes with length zero (#3031)

This commit is contained in:
Javier Serrano Polo
2016-09-12 20:10:18 +00:00
committed by GitHub
parent ede0e07f5e
commit 1f90337523
6 changed files with 65 additions and 189 deletions

View File

@@ -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;

View File

@@ -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();

View File

@@ -198,3 +198,9 @@ void MidiTime::setTicksPerTact( tick_t tpt )
{
s_ticksPerTact = tpt;
}
MidiTime MidiTime::stepPosition( int step )
{
return step * ticksPerTact() / stepsPerTact();
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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 )
{