Initial
This commit is contained in:
232
guitar/ChordMapper.cpp
Normal file
232
guitar/ChordMapper.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
#include <guitar/ChordMapper.hpp>
|
||||
|
||||
bool ChordMapper::map(const Music::Chord &chord,Block<FrettedNote> &frettedNotes)
|
||||
{
|
||||
FrettedNote frettedNote;
|
||||
bool returnCode=true;
|
||||
bool isBarChord=false;
|
||||
|
||||
frettedNotes.remove();
|
||||
if(getAt(chord.getRoot(),frettedNote,frettedNotes)) // try to set the root on the top string
|
||||
{
|
||||
frettedNotes.insert(&frettedNote);
|
||||
isBarChord=true;
|
||||
}
|
||||
for(int index=chord.size()-1;index>=0;index--)
|
||||
{
|
||||
Note ¬e=((Music::Chord&)chord)[index];
|
||||
if(getAt(note,frettedNote,frettedNotes))frettedNotes.insert(&frettedNote);
|
||||
else
|
||||
{
|
||||
String message("[Fretboard::getAt] Unable to map note '"+note.toString()+String("'"));
|
||||
returnCode=false;
|
||||
}
|
||||
}
|
||||
if(!returnCode)
|
||||
{
|
||||
isBarChord=false;
|
||||
returnCode=true;
|
||||
frettedNotes.remove();
|
||||
int noteCount=0;
|
||||
int chordIndex=2;
|
||||
int direction=-1;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
while(noteCount<chord.size())
|
||||
{
|
||||
if(chordIndex<0)chordIndex=chord.size()-1;
|
||||
else if(chordIndex>=chord.size())chordIndex=0;
|
||||
Note ¬e=((Music::Chord&)chord)[chordIndex];
|
||||
if(getAt(Fretboard::Strings-1,-1,note,frettedNote,frettedNotes))frettedNotes.insert(&frettedNote);
|
||||
else returnCode=false;
|
||||
chordIndex+=direction;
|
||||
noteCount++;
|
||||
}
|
||||
*/
|
||||
}
|
||||
if(isBarChord && frettedNotes.size()) // check to see if we can fill in some notes at the bar chord fret
|
||||
{
|
||||
getFillerNotes(frettedNotes[0].getFret(),chord,frettedNotes);
|
||||
}
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* searches for a note mapping starting at given string at fret 0 (note string 0 is the top (6th)string
|
||||
* takes care of string collisions.
|
||||
* @param note - The note to find a mapping for.
|
||||
* @param fretted note - If result is true contains note mapping.
|
||||
* @param containedNotes - Notes that are already in the mapping, used
|
||||
to limit selected notes and to minimize distance between notes.
|
||||
*/
|
||||
|
||||
bool ChordMapper::getAt(int startingString,int direction,const Note ¬e,FrettedNote &frettedNote,Block<FrettedNote> &containedNotes)
|
||||
{
|
||||
for(int stringCount=0,srIndex=startingString;stringCount<Fretboard::Strings;stringCount++,srIndex+=direction)
|
||||
{
|
||||
if(srIndex>=Fretboard::Strings)srIndex=0;
|
||||
else if(srIndex<0)srIndex=Fretboard::Strings-1;
|
||||
for(int frIndex=0;frIndex<mFretboard.getFrets()+1;frIndex++)
|
||||
{
|
||||
Note &srchNote=mFretboard[srIndex][frIndex];
|
||||
if(srchNote.getNote()==note.getNote())
|
||||
{
|
||||
frettedNote.setNote(note);
|
||||
frettedNote.setString(srIndex);
|
||||
frettedNote.setFret(frIndex);
|
||||
if(contains(frettedNote,containedNotes))continue;
|
||||
if(distance(frettedNote,containedNotes)>MaxFretDistance)continue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Get the FrettedNote for the given Note.
|
||||
@param note - The note we are looking to map.
|
||||
@param frettedNote - The fretted note we are looking for (get's filled in on success)
|
||||
@param containedNotes - List of frettednotes we already have (so don't choose any of these).
|
||||
|
||||
*/
|
||||
bool ChordMapper::getAt(const Note ¬e,FrettedNote &frettedNote,Block<FrettedNote> &containedNotes)
|
||||
{
|
||||
for(int srIndex=0;srIndex<mFretboard.size();srIndex++)
|
||||
{
|
||||
if(srIndex>=Fretboard::Strings)srIndex=0;
|
||||
for(int frIndex=0;frIndex<mFretboard.getFrets()+1;frIndex++)
|
||||
{
|
||||
Note &srchNote=mFretboard[srIndex][frIndex];
|
||||
if(srchNote.getNote()==note.getNote())
|
||||
{
|
||||
frettedNote.setNote(note);
|
||||
frettedNote.setString(srIndex);
|
||||
frettedNote.setFret(frIndex);
|
||||
if(contains(frettedNote,containedNotes))continue;
|
||||
if(distance(frettedNote,containedNotes)>MaxFretDistance)continue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the greatest distance between fretted note and grouping of notes
|
||||
Distance is simply fret distance, does not account for string distance
|
||||
@param frettedNote - The fretted note to get distance.
|
||||
@param frettedNotes - The collection of notes with which to compare distances
|
||||
*/
|
||||
int ChordMapper::distance(const FrettedNote &frettedNote,Block<FrettedNote> &frettedNotes)
|
||||
{
|
||||
int maxDistance=0;
|
||||
int currDistance;
|
||||
|
||||
for(int index=0;index<frettedNotes.size();index++)
|
||||
{
|
||||
FrettedNote &currNote=frettedNotes[index];
|
||||
currDistance=frettedNote.getFret()-currNote.getFret();
|
||||
if(currDistance<0)currDistance=-currDistance;
|
||||
if(currDistance>maxDistance)maxDistance=currDistance;
|
||||
}
|
||||
OutputDebugString(String(String("Distance is :")+String().fromInt(maxDistance)+String("\n")).str());
|
||||
return maxDistance;
|
||||
}
|
||||
|
||||
/*
|
||||
Return the distance between two fretted notes.
|
||||
*/
|
||||
int ChordMapper::distance(const FrettedNote &firstNote,const FrettedNote &secondNote)
|
||||
{
|
||||
int fretDistance=firstNote.getFret()-secondNote.getFret();
|
||||
return fretDistance<0?-fretDistance:fretDistance;
|
||||
}
|
||||
|
||||
/*
|
||||
Find filler notes for given chord on given fret on empty string.
|
||||
*/
|
||||
bool ChordMapper::getFillerNotes(int fret,const Music::Chord &chord,Block<FrettedNote> &frettedNotes)
|
||||
{
|
||||
bool notesInChord;
|
||||
for(int stringIndex=0;stringIndex<mFretboard.size();stringIndex++)
|
||||
{
|
||||
Note ¬e=mFretboard[stringIndex][fret];
|
||||
FrettedNote frettedNote;
|
||||
frettedNote.setNote(note);
|
||||
frettedNote.setString(stringIndex);
|
||||
frettedNote.setFret(fret);
|
||||
if(!contains(frettedNote,frettedNotes)&&isIn(frettedNote,chord))frettedNotes.insert(&frettedNote);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Check to see if the fretted note exists in the collection of fretted notes.
|
||||
* @param frettedNote - The fretted note to check for
|
||||
* @param frettedNotes - The collection of fretted notes
|
||||
*/
|
||||
bool ChordMapper::contains(const FrettedNote &frettedNote,Block<FrettedNote> &frettedNotes)
|
||||
{
|
||||
for(int index=0;index<frettedNotes.size();index++)
|
||||
{
|
||||
FrettedNote &currNote=frettedNotes[index];
|
||||
if(currNote.getString()==frettedNote.getString())return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Check to see if the given note is part of the chord
|
||||
@param frettedNote - The note
|
||||
@param chord - The chord
|
||||
@return - True if the given note is part of the chord, false otherwise
|
||||
*/
|
||||
bool ChordMapper::isIn(const FrettedNote &frettedNote,const Music::Chord &chord)
|
||||
{
|
||||
for(int index=0;index<chord.size();index++)
|
||||
if(frettedNote.getNote()==((Music::Chord&)chord)[index])return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ChordMapper::getNearestNote(const FrettedNote &frettedNote,const Note &srchNote,FrettedNote &foundNote)
|
||||
{
|
||||
bool found=false;
|
||||
int stringOffset=1;
|
||||
int fretOffset=1;
|
||||
|
||||
while(!found)
|
||||
{
|
||||
if(getNearestNoteInRange(frettedNote,srchNote,foundNote,stringOffset,fretOffset))found=true;
|
||||
stringOffset++;
|
||||
fretOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
bool ChordMapper::getNearestNoteInRange(const FrettedNote &frettedNote,const Note &srchNote,FrettedNote &foundNote,int stringOffset,int fretOffset)
|
||||
{
|
||||
for(int currentString=frettedNote.getString()-1;currentString<frettedNote.getString()+1;currentString++)
|
||||
{
|
||||
for(int currentFret=frettedNote.getFret()-1;currentFret<frettedNote.getFret()+1;currentFret++)
|
||||
{
|
||||
if(currentString>=Fretboard::Strings || currentString<0)continue;
|
||||
if(currentFret>=Fretboard::Frets || currentFret<0)continue;
|
||||
Note ¬e=mFretboard[currentString][currentFret];
|
||||
if(note==srchNote)
|
||||
{
|
||||
FrettedNote frettedNote;
|
||||
frettedNote.setNote(note);
|
||||
frettedNote.setString(currentString);
|
||||
frettedNote.setFret(currentFret);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user