176 lines
3.2 KiB
C++
176 lines
3.2 KiB
C++
#include <music/scanner.hpp>
|
|
#include <music/scansymbols.hpp>
|
|
|
|
namespace Music
|
|
{
|
|
|
|
void Scanner::init(const String &chordSymbol)
|
|
{
|
|
remove();
|
|
mIndex=0;
|
|
mLength=chordSymbol.length();
|
|
if(!mLength)return;
|
|
mSymbol=chordSymbol;
|
|
}
|
|
|
|
char Scanner::peekChar(void)
|
|
{
|
|
if(mIndex>=mLength)return -1;
|
|
return mSymbol.charAt(mIndex);
|
|
}
|
|
|
|
char Scanner::nextChar()
|
|
{
|
|
if(mIndex+1>mLength)return -1;
|
|
return mSymbol.charAt(mIndex++);
|
|
}
|
|
|
|
void Scanner::pushBack(void)
|
|
{
|
|
if(!mIndex)return;
|
|
mIndex--;
|
|
}
|
|
|
|
bool Scanner::scan(const String &chordSymbol)
|
|
{
|
|
char symbol;
|
|
init(chordSymbol);
|
|
while(-1!=(symbol=nextChar()))
|
|
{
|
|
if(isInflection(symbol))
|
|
scanInflection(symbol);
|
|
else if('/'==symbol)
|
|
scanSlash();
|
|
else if(isdigit(symbol))
|
|
scanDegree(symbol);
|
|
else if('^'==symbol||'-'==symbol)
|
|
scanMnemonic(symbol);
|
|
else if(isalpha(symbol))
|
|
scanAlpha(symbol);
|
|
else
|
|
return false;
|
|
}
|
|
emit(ScanSymbols::Stop1);
|
|
if(size()<=1)return false;
|
|
return true;
|
|
}
|
|
|
|
void Scanner::scanAlpha(char symbol)
|
|
{
|
|
char nextChar;
|
|
|
|
if(isNote(symbol))
|
|
{
|
|
emit(ScanSymbols::Note1,Byte(symbol));
|
|
}
|
|
else if(isalpha(symbol)&&!isInflection(symbol)&&!isHalfDiminished(symbol)&&!isDiminished(symbol))
|
|
{
|
|
string verb;
|
|
verb+=tolower(symbol);
|
|
while(-1!=(nextChar=this->nextChar()))
|
|
{
|
|
if(!isalpha(nextChar)||isInflection(nextChar))
|
|
{
|
|
pushBack();
|
|
break;
|
|
}
|
|
verb+=tolower(nextChar);
|
|
}
|
|
emit(ScanSymbols::Verb1,verb);
|
|
}
|
|
else if(isalpha(symbol)&&isInflection(symbol))
|
|
{
|
|
string verb;
|
|
emit(ScanSymbols::Note1,Byte(symbol));
|
|
symbol=this->nextChar();
|
|
scanInflection(symbol);
|
|
while(-1!=(nextChar=this->nextChar()))
|
|
{
|
|
if(!isalpha(nextChar)||isInflection(nextChar))
|
|
{
|
|
pushBack();
|
|
break;
|
|
}
|
|
verb+=tolower(nextChar);
|
|
}
|
|
emit(ScanSymbols::Verb1,verb);
|
|
}
|
|
else if(isalpha(symbol)&&isHalfDiminished(symbol))
|
|
{
|
|
emit(ScanSymbols::HalfDiminished1);
|
|
}
|
|
else if(isalpha(symbol)&&isDiminished(symbol))
|
|
{
|
|
emit(ScanSymbols::Diminished1);
|
|
}
|
|
else emit(ScanSymbols::Note1,Byte(symbol));
|
|
}
|
|
|
|
bool Scanner::isNote(char symbol)
|
|
{
|
|
if('A'==symbol||'B'==symbol||'C'==symbol||'D'==symbol||'E'==symbol||'F'==symbol||'G'==symbol)return true;
|
|
return false;
|
|
}
|
|
|
|
bool Scanner::isInflection(char symbol)
|
|
{
|
|
if('b'==symbol||'#'==symbol)return true;
|
|
return false;
|
|
}
|
|
|
|
bool Scanner::isHalfDiminished(char symbol)
|
|
{
|
|
if('h'==symbol)return true;
|
|
return false;
|
|
}
|
|
|
|
bool Scanner::isDiminished(char symbol)
|
|
{
|
|
if('o'==symbol)return true;
|
|
return false;
|
|
}
|
|
|
|
void Scanner::scanDegree(char symbol)
|
|
{
|
|
String str;
|
|
|
|
str+=symbol;
|
|
while(-1!=(symbol=peekChar())&&isdigit(symbol))
|
|
{
|
|
symbol=nextChar();
|
|
str+=symbol;
|
|
}
|
|
emit(ScanSymbols::Degree1,Byte(str.toInt()));
|
|
}
|
|
|
|
void Scanner::scanMnemonic(char symbol)
|
|
{
|
|
char nextSymbol;
|
|
|
|
nextSymbol=peekChar();
|
|
if(symbol=='-' && nextSymbol=='^')
|
|
{
|
|
emit(ScanSymbols::MinorMajor71);
|
|
nextChar();
|
|
}
|
|
else if(symbol=='^')emit(ScanSymbols::Major71);
|
|
else if(symbol=='-')emit(ScanSymbols::Minor1);
|
|
}
|
|
|
|
void Scanner::scanInflection(char symbol)
|
|
{
|
|
if('b'==symbol)emit(ScanSymbols::Alter1,Byte(ScanSymbols::Flat1));
|
|
else if('#'==symbol)emit(ScanSymbols::Alter1,Byte(ScanSymbols::Sharp1));
|
|
}
|
|
|
|
void Scanner::scanSlash()
|
|
{
|
|
emit(ScanSymbols::Slash1);
|
|
}
|
|
|
|
String Scanner::toString(void)const
|
|
{
|
|
return Emitter::toString();
|
|
}
|
|
};
|