/** Given a midi note number, return the accidental (if any) * that should be used when displaying the note in this key signature. * * The current measure is also required. Once we return an * accidental for a measure, the accidental remains for the * rest of the measure. So we must update the current keymap * with any new accidentals that we return. When we move to another * measure, we reset the keymap back to the key signature. */ public Accid GetAccidental(int notenumber, int measure) { if (measure != prevmeasure) { ResetKeyMap(); prevmeasure = measure; } Accid result = keymap[notenumber]; if (result == Accid.Sharp) { keymap[notenumber] = Accid.None; keymap[notenumber - 1] = Accid.Natural; } else if (result == Accid.Flat) { keymap[notenumber] = Accid.None; keymap[notenumber + 1] = Accid.Natural; } else if (result == Accid.Natural) { keymap[notenumber] = Accid.None; int nextkey = NoteScale.FromNumber(notenumber + 1); int prevkey = NoteScale.FromNumber(notenumber - 1); /* If we insert a natural, then either: * - the next key must go back to sharp, * - the previous key must go back to flat. */ if (notenumber > 0) { if (keymap[notenumber - 1] == Accid.None && keymap[notenumber + 1] == Accid.None && NoteScale.IsBlackKey(nextkey) && NoteScale.IsBlackKey(prevkey)) { if (num_flats == 0) { keymap[notenumber + 1] = Accid.Sharp; } else { keymap[notenumber - 1] = Accid.Flat; } } else if (keymap[notenumber - 1] == Accid.None && NoteScale.IsBlackKey(prevkey)) { keymap[notenumber - 1] = Accid.Flat; } else if (keymap[notenumber + 1] == Accid.None && NoteScale.IsBlackKey(nextkey)) { keymap[notenumber + 1] = Accid.Sharp; } else { /* Shouldn't get here */ } } } return(result); }
/** The keymap tells what accidental symbol is needed for each * note in the scale. Reset the keymap to the values of the * key signature. */ private void ResetKeyMap() { Accid[] key; if (num_flats > 0) { key = flatkeys[num_flats]; } else { key = sharpkeys[num_sharps]; } for (int notenumber = 0; notenumber < keymap.Length; notenumber++) { keymap[notenumber] = key[NoteScale.FromNumber(notenumber)]; } }
/** Get the letter (A, A#, Bb) representing this note */ private string Letter(int notenumber, WhiteNote whitenote) { int notescale = NoteScale.FromNumber(notenumber); switch (notescale) { case NoteScale.A: return("A"); case NoteScale.B: return("B"); case NoteScale.C: return("C"); case NoteScale.D: return("D"); case NoteScale.E: return("E"); case NoteScale.F: return("F"); case NoteScale.G: return("G"); case NoteScale.Asharp: if (whitenote.Letter == WhiteNote.A) { return("A#"); } else { return("Bb"); } case NoteScale.Csharp: if (whitenote.Letter == WhiteNote.C) { return("C#"); } else { return("Db"); } case NoteScale.Dsharp: if (whitenote.Letter == WhiteNote.D) { return("D#"); } else { return("Eb"); } case NoteScale.Fsharp: if (whitenote.Letter == WhiteNote.F) { return("F#"); } else { return("Gb"); } case NoteScale.Gsharp: if (whitenote.Letter == WhiteNote.G) { return("G#"); } else { return("Ab"); } default: return(""); } }
/** Get the name for this note */ private string NoteName(int notenumber, WhiteNote whitenote) { if (sheetmusic.ShowNoteLetters == MidiOptions.NoteNameLetter) { return(Letter(notenumber, whitenote)); } else if (sheetmusic.ShowNoteLetters == MidiOptions.NoteNameFixedDoReMi) { string[] fixedDoReMi = { "La", "Li", "Ti", "Do", "Di", "Re", "Ri", "Mi", "Fa", "Fi", "So", "Si" }; int notescale = NoteScale.FromNumber(notenumber); return(fixedDoReMi[notescale]); } else if (sheetmusic.ShowNoteLetters == MidiOptions.NoteNameMovableDoReMi) { string[] fixedDoReMi = { "La", "Li", "Ti", "Do", "Di", "Re", "Ri", "Mi", "Fa", "Fi", "So", "Si" }; int mainscale = sheetmusic.MainKey.Notescale(); int diff = NoteScale.C - mainscale; notenumber += diff; if (notenumber < 0) { notenumber += 12; } int notescale = NoteScale.FromNumber(notenumber); return(fixedDoReMi[notescale]); } else if (sheetmusic.ShowNoteLetters == MidiOptions.NoteNameFixedNumber) { string[] num = { "10", "11", "12", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; int notescale = NoteScale.FromNumber(notenumber); return(num[notescale]); } else if (sheetmusic.ShowNoteLetters == MidiOptions.NoteNameMovableNumber) { string[] num = { "10", "11", "12", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; int mainscale = sheetmusic.MainKey.Notescale(); int diff = NoteScale.C - mainscale; notenumber += diff; if (notenumber < 0) { notenumber += 12; } int notescale = NoteScale.FromNumber(notenumber); return(num[notescale]); } else { return(""); } }
/** Given a midi note number, return the white note (the * non-sharp/non-flat note) that should be used when displaying * this note in this key signature. This should be called * before calling GetAccidental(). */ public WhiteNote GetWhiteNote(int notenumber) { int notescale = NoteScale.FromNumber(notenumber); int octave = (notenumber + 3) / 12 - 1; int letter = 0; int[] whole_sharps = { WhiteNote.A, WhiteNote.A, WhiteNote.B, WhiteNote.C, WhiteNote.C, WhiteNote.D, WhiteNote.D, WhiteNote.E, WhiteNote.F, WhiteNote.F, WhiteNote.G, WhiteNote.G }; int[] whole_flats = { WhiteNote.A, WhiteNote.B,WhiteNote.B, WhiteNote.C, WhiteNote.D,WhiteNote.D, WhiteNote.E,WhiteNote.E, WhiteNote.F, WhiteNote.G,WhiteNote.G, WhiteNote.A }; Accid accid = keymap[notenumber]; if (accid == Accid.Flat) { letter = whole_flats[notescale]; } else if (accid == Accid.Sharp) { letter = whole_sharps[notescale]; } else if (accid == Accid.Natural) { letter = whole_sharps[notescale]; } else if (accid == Accid.None) { letter = whole_sharps[notescale]; /* If the note number is a sharp/flat, and there's no accidental, * determine the white note by seeing whether the previous or next note * is a natural. */ if (NoteScale.IsBlackKey(notescale)) { if (keymap[notenumber - 1] == Accid.Natural && keymap[notenumber + 1] == Accid.Natural) { if (num_flats > 0) { letter = whole_flats[notescale]; } else { letter = whole_sharps[notescale]; } } else if (keymap[notenumber - 1] == Accid.Natural) { letter = whole_sharps[notescale]; } else if (keymap[notenumber + 1] == Accid.Natural) { letter = whole_flats[notescale]; } } } /* The above algorithm doesn't quite work for G-flat major. * Handle it here. */ if (num_flats == Gflat && notescale == NoteScale.B) { letter = WhiteNote.C; } if (num_flats == Gflat && notescale == NoteScale.Bflat) { letter = WhiteNote.B; } if (num_flats > 0 && notescale == NoteScale.Aflat) { octave++; } return(new WhiteNote(letter, octave)); }