00001
00008 #include "core/keysignature.h"
00009 #include "core/staff.h"
00010 #include "core/mark.h"
00011
00033 CAKeySignature::CAKeySignature(CAKeySignatureType type, signed char accs, CAMajorMinorGender gender, CAStaff *staff, int timeStart)
00034 : CAMusElement(staff, timeStart) {
00035 _musElementType = CAMusElement::KeySignature;
00036
00037 setKeySignatureType(type, accs, gender);
00038 }
00039
00085 void CAKeySignature::setKeySignatureType(CAKeySignatureType type, signed char accs, CAMajorMinorGender gender) {
00086 _keySignatureType = type;
00087
00088 if (type == MajorMinor) {
00089 _majorMinorGender = gender;
00090
00091 for (int i=0; i<7; i++)
00092 _accidentals[i] = 0;
00093
00094
00095
00096 int idx = 3;
00097 for (int i=0; i<accs; i++) {
00098 _accidentals[idx] = 1;
00099 idx = (idx+4)%7;
00100 }
00101
00102 idx = 6;
00103 for (int i=0; i>accs; i--) {
00104 _accidentals[idx] = -1;
00105 idx = (idx+3)%7;
00106 }
00107 }
00108 }
00109
00110 CAKeySignature::~CAKeySignature() {
00111 }
00112
00113 CAKeySignature* CAKeySignature::clone() {
00114 CAKeySignature *k = new CAKeySignature(_keySignatureType, numberOfAccidentals(), _majorMinorGender, (CAStaff*)_context, _timeStart);
00115
00116 for (int i=0; i<markList().size(); i++) {
00117 CAMark *m = static_cast<CAMark*>(markList()[i]->clone());
00118 m->setAssociatedElement(k);
00119 k->addMark( m );
00120 }
00121
00122 return k;
00123 }
00124
00131 signed char CAKeySignature::numberOfAccidentals() {
00132 signed char sum=0;
00133 for (int i=0; i<7; i++)
00134 sum += _accidentals[i];
00135
00136 return sum;
00137 }
00138
00139 int CAKeySignature::compare(CAMusElement *elt) {
00140 if (elt->musElementType()!=CAMusElement::KeySignature)
00141 return -1;
00142
00143 int diffs=0;
00144 if (_keySignatureType!=((CAKeySignature*)elt)->keySignatureType()) diffs++;
00145 else {
00146 if (_majorMinorGender!=((CAKeySignature*)elt)->majorMinorGender()) diffs++;
00147 if (numberOfAccidentals()!=((CAKeySignature*)elt)->numberOfAccidentals()) diffs++;
00148 }
00149
00150 return diffs;
00151 }
00152
00158 const QString CAKeySignature::keySignatureToString( signed char numberOfAccs, CAMajorMinorGender gender ) {
00159
00160 int pitch = ((4*numberOfAccs) % 7) + ((numberOfAccs < 0) ? 7 : 0);
00161
00162 if (gender==CAKeySignature::Minor)
00163 pitch = (pitch + 5) % 7;
00164
00165 signed char accs = 0;
00166
00167 if (numberOfAccs>5 && gender==CAKeySignature::Major)
00168 accs = (numberOfAccs-5)/7+1;
00169 else
00170 if (numberOfAccs>2 && gender==CAKeySignature::Minor)
00171 accs = (numberOfAccs-2)/7 + 1;
00172 else
00173 if (numberOfAccs<-1 && gender==CAKeySignature::Major)
00174 accs = (numberOfAccs+1)/7-1;
00175 else
00176 if (numberOfAccs<-4 && gender==CAKeySignature::Minor)
00177 accs = (numberOfAccs+4)/7 - 1;
00178
00179 QString name;
00180
00181 name = (char)((pitch+2)%7 + 'a');
00182
00183 for (int i=0; i < accs; i++)
00184 name += "is";
00185
00186 for (int i=0; i > accs; i--) {
00187 if ( (name == "e") || (name == "a") )
00188 name += "s";
00189 else if (name[0]=='a')
00190 name += "as";
00191 else
00192 name += "es";
00193 }
00194
00195 if (gender==CAKeySignature::Major)
00196 name[0] = name[0].toUpper();
00197
00198 return name;
00199 }
00200
00204 signed char CAKeySignature::keySigAccsFromString( QString keySig ) {
00205 CAMajorMinorGender gender = keySigGenderFromString(keySig);
00206 keySig[0] = keySig[0].toLower();
00207 signed char accs = static_cast<signed char>( ((keySig[0].toAscii() - 'a') * 2 + 4) % 7 - 4 );
00208
00209 QString key(keySig);
00210 accs -= 7*keySig.count("as");
00211 accs -= 7*keySig.count("es");
00212 accs += 7*keySig.count("is");
00213
00214 if (gender==CAKeySignature::Major)
00215 accs += 3;
00216
00217 return accs;
00218 }
00219
00223 CAKeySignature::CAMajorMinorGender CAKeySignature::keySigGenderFromString( const QString keySig ) {
00224 if (keySig[0].isUpper())
00225 return CAKeySignature::Major;
00226 else
00227 return CAKeySignature::Minor;
00228 }
00229
00230 const QString CAKeySignature::keySignatureTypeToString(CAKeySignatureType type) {
00231 switch (type) {
00232 case MajorMinor: return "major-minor";
00233 case Modus: return "modus";
00234 case Custom: return "custom";
00235 default: return "";
00236 }
00237 }
00238
00239 CAKeySignature::CAKeySignatureType CAKeySignature::keySignatureTypeFromString(const QString type) {
00240 if (type=="major-minor") {
00241 return MajorMinor;
00242 } else
00243 if (type=="modus") {
00244 return Modus;
00245 } else
00246 if (type=="custom") {
00247 return Custom;
00248 } else
00249 return Custom;
00250 }
00251
00252 const QString CAKeySignature::majorMinorGenderToString(CAMajorMinorGender gender) {
00253 switch (gender) {
00254 case Major: return "major";
00255 case Minor: return "minor";
00256 default: return "";
00257 }
00258 }
00259
00260 CAKeySignature::CAMajorMinorGender CAKeySignature::majorMinorGenderFromString(const QString gender) {
00261 if (gender=="major") return Major; else
00262 if (gender=="minor") return Minor;
00263 else return Major;
00264 }
00265
00266 const QString CAKeySignature::modusToString(CAModus modus) {
00267 switch (modus) {
00268 case Ionian: return "ionian";
00269 case Dorian: return "dorian";
00270 case Phrygian: return "phrygian";
00271 case Lydian: return "lydian";
00272 case Mixolydian: return "mixolydian";
00273 case Aeolian: return "aeolian";
00274 case Locrian: return "locrian";
00275 case Hypodorian: return "hypodorian";
00276 case Hypolydian: return "hypolydian";
00277 case Hypomixolydian: return "hypomixolydian";
00278 case Hypophrygian: return "hypophrygian";
00279 default: return "";
00280 }
00281 }
00282
00283 CAKeySignature::CAModus CAKeySignature::modusFromString(const QString modus) {
00284 if (modus=="ionian") return Ionian; else
00285 if (modus=="dorian") return Dorian; else
00286 if (modus=="phrygian") return Phrygian; else
00287 if (modus=="lydian") return Lydian; else
00288 if (modus=="mixolydian") return Mixolydian; else
00289 if (modus=="aeolian") return Aeolian; else
00290 if (modus=="locrian") return Locrian; else
00291 if (modus=="hypodorian") return Hypodorian; else
00292 if (modus=="hypolydian") return Hypolydian; else
00293 if (modus=="hypomixolydian") return Hypomixolydian; else
00294 if (modus=="hypophrygian") return Hypophrygian;
00295 else return Ionian;
00296 }
00297