Exemplo n.º 1
0
        /** 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);
        }
Exemplo n.º 2
0
        /** 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));
        }