public PairList GetChords() { Dict chord = new Dict(); //string[] NoteName = NoteNameSharp; for (int i = 0; i < notes.Count; i++) { int note = notes[i]; double decay = hold[i] ? 0.5 : 1; int scale; // Major scale = NoteScale.FromNumber(note); // as 1th Acc(chord, NoteName[scale], decay / 3); scale = NoteScale.FromNumber(note - 4); // as 3th Acc(chord, NoteName[scale], decay / 3); scale = NoteScale.FromNumber(note - 7); // as 5th Acc(chord, NoteName[scale], decay / 3); // Minor scale = NoteScale.FromNumber(note); // as 1th Acc(chord, NoteName[scale] + "m", decay / 3); scale = NoteScale.FromNumber(note - 3); // as 3th Acc(chord, NoteName[scale] + "m", decay / 3); scale = NoteScale.FromNumber(note - 7); // as 5th Acc(chord, NoteName[scale] + "m", decay / 3); // 7th scale = NoteScale.FromNumber(note); // as 1th Acc(chord, NoteName[scale] + "7", decay / 4); scale = NoteScale.FromNumber(note - 4); // as 3th Acc(chord, NoteName[scale] + "7", decay / 4); scale = NoteScale.FromNumber(note - 7); // as 5th Acc(chord, NoteName[scale] + "7", decay / 4); scale = NoteScale.FromNumber(note - 10); // as 7th Acc(chord, NoteName[scale] + "7", decay / 4); } if (l != null) { PairList chord_l = l.GetChords(); foreach (var pair in chord_l) { Acc(chord, pair.Key, pair.Value); } } if (r != null) { PairList chord_r = r.GetChords(); foreach (var pair in chord_r) { Acc(chord, pair.Key, pair.Value / 2); } } List <KeyValuePair <string, double> > ret = new List <KeyValuePair <string, double> >(); foreach (var c in chord) { ret.Add(c); } ret.Sort((a, b) => (b.Value.CompareTo(a.Value))); return(ret); }
/** 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 (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 < 128; notenumber++) { keymap[notenumber] = key[NoteScale.FromNumber(notenumber)]; } }
/** Return the midi note number corresponding to this white note. * The midi note numbers cover all keys, including sharps/flats, * so each octave is 12 notes. Middle C (C4) is 60. Some example * numbers for various notes: * * A 2 = 33 * A#2 = 34 * G 2 = 43 * G#2 = 44 * A 3 = 45 * A 4 = 57 * A#4 = 58 * B 4 = 59 * C 4 = 60 */ public int Number() { int offset = 0; switch (letter) { case A: offset = NoteScale.A; break; case B: offset = NoteScale.B; break; case C: offset = NoteScale.C; break; case D: offset = NoteScale.D; break; case E: offset = NoteScale.E; break; case F: offset = NoteScale.F; break; case G: offset = NoteScale.G; break; default: offset = 0; break; } return(NoteScale.ToNumber(offset, octave)); }
/** 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)); }
/** Get the color for a given note number */ public Color NoteColor(int number) { return(NoteColors[NoteScale.FromNumber(number)]); }