/** 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)];
            }
        }
Beispiel #3
0
        /** 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));
        }
Beispiel #4
0
        /** 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("");
            }
        }
Beispiel #5
0
 /** 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));
        }