#include #include #include namespace Music { bool Parser::parse(Emitter &emitter,Music::Chord &chord) { mEmitter=&emitter; mIndex=0; Byte peekSymbol; mNotes.remove(); chord.size(0); mIsInError=false; while(true) { insertSymbols(ScanSymbols::Note1); if(!nextSymbol())break; // this needs to be removed if(symbolIn(ScanSymbols::Note1)) { parseNote(); if(!nextSymbol())break; } removeSymbols(ScanSymbols::Note1); if(symbolIn(ScanSymbols::Verb1)) { if(!parseVerb())break; if(!nextSymbol())break; } if(symbolIn(ScanSymbols::HalfDiminished1)) { parseHalfDiminished(); if(!nextSymbol())break; } if(symbolIn(ScanSymbols::Diminished1)) { parseDiminished(); if(!nextSymbol())break; } if(symbolIn(ScanSymbols::MinorMajor71)) { parseMinorMajor(); if(!nextSymbol())break; } if(symbolIn(ScanSymbols::Minor1)) // parseMinor looks for minor-degree { parseMinor(); if(!nextSymbol())break; } if(symbolIn(ScanSymbols::Major71)) { parseMajorSeventh(); } if(symbolIn(ScanSymbols::Degree1)) { parseDegree(); if(!nextSymbol())break; } if(symbolIn(ScanSymbols::Alter1)) { parseAlteration(); if(!nextSymbol())break; } } if(mIsInError)return false; if(!mNotes.size()) { chord.create(mRootNote,Music::Chord::MajorTriad); } else { Notes ¬es=(Notes&)chord; notes.size(mNotes.size()+1); notes[0]=mRootNote; for(int index=0;indexpeekSymbol(); if(ScanSymbols::Degree1!=peekSymbol) { Note minorThird; Note perfectFifth; minorThird=mRootNote.getThird(); minorThird--; mNotes.insert(&minorThird); perfectFifth=mRootNote.getFifth(); mNotes.insert(&perfectFifth); } else if(ScanSymbols::Degree1==peekSymbol) { expect(ScanSymbols::Degree1); if(3==mByteValue.value()) { Note minorThird=mRootNote.getThird(); Note perfectFifth=mRootNote.getFifth(); minorThird--; if(!haveNote(minorThird))mNotes.insert(&minorThird); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); } else if(4==mByteValue.value()) { Note minorFourth=mRootNote.getFourth(); Note perfectFifth=mRootNote.getFifth(); minorFourth--; if(!haveNote(minorFourth))mNotes.insert(&minorFourth); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); } else if(5==mByteValue.value()) { Note minorFifth=mRootNote.getFifth(); Note minorThird=mRootNote.getThird(); minorFifth--; minorThird--; if(!haveNote(minorFifth))mNotes.insert(&minorFifth); if(!haveNote(minorThird))mNotes.insert(&minorThird); } else if(6==mByteValue.value()) { Note perfectFifth=mRootNote.getFifth(); Note minorThird=mRootNote.getThird(); Note majorSixth=mRootNote.getSixth(); minorThird--; if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); if(!haveNote(minorThird))mNotes.insert(&minorThird); if(!haveNote(majorSixth))mNotes.insert(&majorSixth); } else if(7==mByteValue.value()) { Note minorThird=mRootNote.getThird(); Note perfectFifth=mRootNote.getFifth(); Note minorSeventh=mRootNote.getSeventh(); minorSeventh--; minorThird--; if(!haveNote(minorThird))mNotes.insert(&minorThird); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); if(!haveNote(minorSeventh))mNotes.insert(&minorSeventh); } else if(9==mByteValue.value()) { Note minorThird=mRootNote.getThird(); Note minorNinth=mRootNote.getNinth(); Note perfectFifth=mRootNote.getFifth(); minorNinth--; minorThird--; if(!haveNote(minorThird))mNotes.insert(&minorThird); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); if(!haveNote(minorNinth))mNotes.insert(&minorNinth); } else if(11==mByteValue.value()) { Note minorThird=mRootNote.getThird(); Note perfectFifth=mRootNote.getFifth(); Note minorEleventh=mRootNote.getEleventh(); minorThird--; minorEleventh--; if(!haveNote(minorThird))mNotes.insert(&minorThird); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); if(!haveNote(minorEleventh))mNotes.insert(&minorEleventh); } else if(13==mByteValue.value()) { Note minorThird=mRootNote.getThird(); Note perfectFifth=mRootNote.getFifth(); Note minorThirteenth=mRootNote.getThirteenth(); minorThirteenth--; minorThird--; if(!haveNote(minorThird))mNotes.insert(&minorThird); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); if(!haveNote(minorThirteenth))mNotes.insert(&minorThirteenth); } } return true; } bool Parser::parseMinorMajor(void) // minor major is basically a minor chord with a #7 { Note minorThird; Note perfectFifth; Note majorSeventh; minorThird=mRootNote.getThird(); minorThird--; mNotes.insert(&minorThird); perfectFifth=mRootNote.getFifth(); mNotes.insert(&perfectFifth); majorSeventh=mRootNote.getSeventh(); mNotes.insert(&majorSeventh); return true; } bool Parser::parseDegree(void) { if(3==mByteValue.value()) { Note third=mRootNote.getThird(); if(!haveNote(third))mNotes.insert(&third); } else if(4==mByteValue.value()) { Note fourth=mRootNote.getFourth(); if(!haveNote(fourth))mNotes.insert(&fourth); } else if(5==mByteValue.value()) { Note fifth=mRootNote.getFifth(); if(!haveNote(fifth))mNotes.insert(&fifth); } else if(6==mByteValue.value()) { Note sixth=mRootNote.getSixth(); Note third=mRootNote.getThird(); Note perfectFifth=mRootNote.getFifth(); if(!haveNote(sixth))mNotes.insert(&sixth); if(!haveNote(third))mNotes.insert(&third); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); } else if(7==mByteValue.value()) { Note third=mRootNote.getThird(); Note perfectFifth=mRootNote.getFifth(); Note minorSeventh=mRootNote.getSeventh(); minorSeventh--; if(!haveNote(third))mNotes.insert(&third); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); if(!haveNote(minorSeventh))mNotes.insert(&minorSeventh); } else if(9==mByteValue.value()) { Note third=mRootNote.getThird(); Note perfectFifth=mRootNote.getFifth(); Note ninth=mRootNote.getNinth(); if(!haveNote(third))mNotes.insert(&third); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); if(!haveNote(ninth))mNotes.insert(&ninth); } else if(11==mByteValue.value()) { Note third=mRootNote.getThird(); Note perfectFifth=mRootNote.getFifth(); Note eleventh=mRootNote.getEleventh(); if(!haveNote(third))mNotes.insert(&third); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); if(!haveNote(eleventh))mNotes.insert(&eleventh); } else if(13==mByteValue.value()) { Note third=mRootNote.getThird(); Note perfectFifth=mRootNote.getFifth(); Note thirteenth=mRootNote.getThirteenth(); if(!haveNote(third))mNotes.insert(&third); if(!haveNote(perfectFifth))mNotes.insert(&perfectFifth); if(!haveNote(thirteenth))mNotes.insert(&thirteenth); } return false; } bool Parser::parseAlteration(void) { Byte inflection=mByteValue; expect(ScanSymbols::Degree1); Note note(mRootNote.getNinth()); if(3==mByteValue.value()) { note=mRootNote.getThird(); } else if(4==mByteValue.value()) { note=mRootNote.getFourth(); } else if(5==mByteValue.value()) { note=mRootNote.getFifth(); } else if(6==mByteValue.value()) { note=mRootNote.getSixth(); } else if(7==mByteValue.value()) { note=mRootNote.getSeventh(); } else if(9==mByteValue.value()) { note=mRootNote.getNinth(); } else if(11==mByteValue.value()) { note=mRootNote.getEleventh(); } else if(13==mByteValue.value()) { note=mRootNote.getThirteenth(); } mNotes.remove(note); // if the note already exists then remove it because we're altering it. if(ScanSymbols::Sharp1==inflection)note++; else note--; mNotes.insert(¬e); return true; } bool Parser::parseNote(void) { switch(mByteValue.value()) { case 'A' : mRootNote=Note(Note::A); mRootNote.setOctave(mRootNote.getOctave()-1); break; case 'B' : mRootNote=Note(Note::B); mRootNote.setOctave(mRootNote.getOctave()-1); break; case 'C' : mRootNote=Note(Note::C); mRootNote.setOctave(mRootNote.getOctave()-1); break; case 'D' : mRootNote=Note(Note::D); mRootNote.setOctave(mRootNote.getOctave()-1); break; case 'E' : mRootNote=Note(Note::E); mRootNote.setOctave(mRootNote.getOctave()-1); break; case 'F' : mRootNote=Note(Note::F); mRootNote.setOctave(mRootNote.getOctave()-1); break; case 'G' : mRootNote=Note(Note::G); mRootNote.setOctave(mRootNote.getOctave()-1); break; } if(ScanSymbols::Alter1==peekSymbol()) { expect(ScanSymbols::Alter1); if(mByteValue.value()==ScanSymbols::Sharp1)mRootNote++; else mRootNote--; } return true; } ScanSymbols::ScanSymbol Parser::peekSymbol(void) { if(mIndex>=mEmitter->size())return ScanSymbols::Stop1; return (ScanSymbols::ScanSymbol)(*mEmitter)[mIndex].value(); } bool Parser::nextSymbol() { int length; int index; bool returnCode; if(mIndex+1>=mEmitter->size())return false; returnCode=true; mKey=(ScanSymbols::ScanSymbol)(*mEmitter)[mIndex++].value(); switch(mKey) { case ScanSymbols::Note1 : mByteValue=(*mEmitter)[mIndex++].value(); break; case ScanSymbols::Degree1 : mByteValue=(*mEmitter)[mIndex++].value(); break; case ScanSymbols::Alter1 : mByteValue=(*mEmitter)[mIndex++].value(); break; case ScanSymbols::Verb1 : length=(*mEmitter)[mIndex++].value(); mStrValue.reserve(length+1); for(index=0;index &symbols) { for(int index=0;index &symbols) { for(int index=0;index &symbols) { for(int index=0;index&)mNotes)[0]==third)return false; return true; } };