fix echo adds taps under hold notes
This commit is contained in:
@@ -598,17 +598,23 @@ void NoteData::EliminateAllButOneTap(int row)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int NoteData::GetNumTracksHeldAtRow( int row )
|
void NoteData::GetTracksHeldAtRow( int row, vector<int>& viTracksOut )
|
||||||
{
|
{
|
||||||
// Optimization opportunity:
|
|
||||||
// Search more efficiently knowing that m_HoldNotes is sorted.
|
|
||||||
int iNumTracksHeld = 0;
|
int iNumTracksHeld = 0;
|
||||||
float fBeat = NoteRowToBeat(row);
|
float fBeat = NoteRowToBeat(row);
|
||||||
for( unsigned i=0; i<m_HoldNotes.size(); i++ )
|
for( unsigned i=0; i<m_HoldNotes.size(); i++ )
|
||||||
{
|
{
|
||||||
const HoldNote& hn = m_HoldNotes[i];
|
const HoldNote& hn = m_HoldNotes[i];
|
||||||
|
|
||||||
if( fBeat >= hn.fStartBeat && fBeat <= hn.fEndBeat )
|
if( fBeat >= hn.fStartBeat && fBeat <= hn.fEndBeat )
|
||||||
iNumTracksHeld++;
|
viTracksOut.push_back( hn.iTrack );
|
||||||
}
|
}
|
||||||
return iNumTracksHeld;
|
}
|
||||||
|
|
||||||
|
int NoteData::GetNumTracksHeldAtRow( int row )
|
||||||
|
{
|
||||||
|
static vector<int> viTracks;
|
||||||
|
viTracks.clear();
|
||||||
|
GetTracksHeldAtRow( row, viTracks );
|
||||||
|
return viTracks.size();
|
||||||
}
|
}
|
||||||
@@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
#include "NoteTypes.h"
|
#include "NoteTypes.h"
|
||||||
|
|
||||||
// '1' = tap note
|
|
||||||
// '2' = hold note begin
|
|
||||||
// '3' = hold note end ('1' can also end a HoldNote) ('3' without a matching '2' is ignored
|
|
||||||
// ... for future expansion
|
|
||||||
|
|
||||||
class NoteData
|
class NoteData
|
||||||
{
|
{
|
||||||
@@ -84,6 +80,17 @@ public:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
inline int GetNumTracksWithTap( int index ) const
|
inline int GetNumTracksWithTap( int index ) const
|
||||||
|
{
|
||||||
|
int iNum = 0;
|
||||||
|
for( int t=0; t<m_iNumTracks; t++ )
|
||||||
|
{
|
||||||
|
TapNote tn = GetTapNote(t, index);
|
||||||
|
if( tn == TAP_TAP )
|
||||||
|
iNum++;
|
||||||
|
}
|
||||||
|
return iNum;
|
||||||
|
}
|
||||||
|
inline int GetNumTracksWithTapOrHoldHead( int index ) const
|
||||||
{
|
{
|
||||||
int iNum = 0;
|
int iNum = 0;
|
||||||
for( int t=0; t<m_iNumTracks; t++ )
|
for( int t=0; t<m_iNumTracks; t++ )
|
||||||
@@ -95,6 +102,16 @@ public:
|
|||||||
return iNum;
|
return iNum;
|
||||||
}
|
}
|
||||||
inline int GetFirstTrackWithTap( int index ) const
|
inline int GetFirstTrackWithTap( int index ) const
|
||||||
|
{
|
||||||
|
for( int t=0; t<m_iNumTracks; t++ )
|
||||||
|
{
|
||||||
|
TapNote tn = GetTapNote(t, index);
|
||||||
|
if( tn == TAP_TAP )
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
inline int GetFirstTrackWithTapOrHoldHead( int index ) const
|
||||||
{
|
{
|
||||||
for( int t=0; t<m_iNumTracks; t++ )
|
for( int t=0; t<m_iNumTracks; t++ )
|
||||||
{
|
{
|
||||||
@@ -108,6 +125,11 @@ public:
|
|||||||
{
|
{
|
||||||
return GetFirstTrackWithTap( index ) != -1;
|
return GetFirstTrackWithTap( index ) != -1;
|
||||||
}
|
}
|
||||||
|
inline bool IsThereATapOrHoldHeadAtRow( int index ) const
|
||||||
|
{
|
||||||
|
return GetFirstTrackWithTapOrHoldHead( index ) != -1;
|
||||||
|
}
|
||||||
|
void GetTracksHeldAtRow( int row, vector<int>& viTracksOut );
|
||||||
int GetNumTracksHeldAtRow( int row );
|
int GetNumTracksHeldAtRow( int row );
|
||||||
|
|
||||||
// used in edit/record
|
// used in edit/record
|
||||||
|
|||||||
@@ -726,24 +726,33 @@ void NoteDataUtil::Echo( NoteData &in, float fStartBeat, float fEndBeat )
|
|||||||
{
|
{
|
||||||
iEchoTrack = iFirstTapInRow;
|
iEchoTrack = iFirstTapInRow;
|
||||||
}
|
}
|
||||||
|
if( iEchoTrack==-1 )
|
||||||
|
continue; // don't lay
|
||||||
|
|
||||||
// don't insert a new note if there's already a tap within this interval
|
// don't insert a new note if there's already a tap within this interval
|
||||||
bool bTapInMiddle = false;
|
bool bTapInMiddle = false;
|
||||||
for( int r2=iRowWindowBegin+1; r2<=iRowWindowEnd-1; r2++ )
|
for( int r2=iRowWindowBegin+1; r2<=iRowWindowEnd-1; r2++ )
|
||||||
if( in.IsThereATapAtRow(r2) )
|
if( in.IsThereATapOrHoldHeadAtRow(r2) )
|
||||||
{
|
{
|
||||||
bTapInMiddle = true;
|
bTapInMiddle = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( bTapInMiddle )
|
if( bTapInMiddle )
|
||||||
continue;
|
continue; // don't lay
|
||||||
|
|
||||||
if( iEchoTrack==-1 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int iNumTracksHeld = in.GetNumTracksHeldAtRow(iRowEcho);
|
{
|
||||||
if( iNumTracksHeld >= 2 )
|
vector<int> viTracks;
|
||||||
continue;
|
in.GetTracksHeldAtRow( iRowEcho, viTracks );
|
||||||
|
|
||||||
|
// don't lay if holding 2 already
|
||||||
|
if( viTracks.size() >= 2 )
|
||||||
|
continue; // don't lay
|
||||||
|
|
||||||
|
// don't lay echos on top of a HoldNote
|
||||||
|
if( find(viTracks.begin(),viTracks.end(),iEchoTrack) != viTracks.end() )
|
||||||
|
continue; // don't lay
|
||||||
|
}
|
||||||
|
|
||||||
in.SetTapNote( iEchoTrack, iRowEcho, TAP_ADDITION );
|
in.SetTapNote( iEchoTrack, iRowEcho, TAP_ADDITION );
|
||||||
}
|
}
|
||||||
@@ -776,7 +785,7 @@ void NoteDataUtil::ConvertTapsToHolds( NoteData &in, int iSimultaneousHolds, flo
|
|||||||
{
|
{
|
||||||
// If there are two taps in a row on the same track,
|
// If there are two taps in a row on the same track,
|
||||||
// don't convert the earlier one to a hold.
|
// don't convert the earlier one to a hold.
|
||||||
if( in.GetFirstTrackWithTap(r2) == t )
|
if( in.GetFirstTrackWithTapOrHoldHead(r2) == t )
|
||||||
goto dont_add_hold;
|
goto dont_add_hold;
|
||||||
iTapsLeft--;
|
iTapsLeft--;
|
||||||
if( iTapsLeft == 0 )
|
if( iTapsLeft == 0 )
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ typedef unsigned char TapNote;
|
|||||||
|
|
||||||
static const TapNote TAP_EMPTY = '0';
|
static const TapNote TAP_EMPTY = '0';
|
||||||
static const TapNote TAP_TAP = '1'; /* impatient? */
|
static const TapNote TAP_TAP = '1'; /* impatient? */
|
||||||
static const TapNote TAP_HOLD_HEAD = '2';
|
static const TapNote TAP_HOLD_HEAD = '2'; // graded liuke a TA_TAP
|
||||||
|
|
||||||
/* In 2sand3s mode, holds are deleted and TAP_HOLD_END is added: */
|
/* In 2sand3s mode, holds are deleted and TAP_HOLD_END is added: */
|
||||||
static const TapNote TAP_HOLD_TAIL = '3';
|
static const TapNote TAP_HOLD_TAIL = '3';
|
||||||
|
|||||||
Reference in New Issue
Block a user