Exemple #1
0
        private static string DescribeKeySignature(byte[] bytes)
        {
            int n = MidiMetaEvent.GetDataLength(MidiMetaEvent.KeySignatureType);

            if (bytes.Length < n)
            {
                return(null);
            }
            MidiKeySignature k = MidiMetaEvent.DataToKeySignature(bytes);

            return((k == MidiKeySignature.NA) ? null :
                   k.ToString().Replace("Flat", "b").Replace("Sharp", "#").Replace("Major", " major").Replace("Minor", " minor"));
        }
Exemple #2
0
        /// <summary>Gets the key signature in effect at a given (total) time.</summary>
        /// <param name="time">The total time (in ticks) at which to get the effective key signature.</param>
        /// <returns>The key signature at the specified time.</returns>
        public MidiKeySignature GetKeySignature(int time)
        {
            MidiKeySignature keySignature = MidiKeySignature.NA;

            foreach (KeyValuePair <int, MidiKeySignature> pair in this.KeySignatureMap)
            {
                if (pair.Key > time)
                {
                    break;
                }
                keySignature = pair.Value;
            }
            return(keySignature);
        }
Exemple #3
0
        /// <summary>Adds an entry to the key signature map, or updates the entry if it already exists.</summary>
        /// <param name="metaEvent">A MidiMetaEvent object representing a key signature.</param>
        public void SetKeySignature(MidiMetaEvent metaEvent)
        {
            if (metaEvent.TotalTime < 0)
            {
                return;
            }
            MidiKeySignature keySignature = MidiMetaEvent.DataToKeySignature(metaEvent.Data);

            if (keySignature == MidiKeySignature.NA)
            {
                return;
            }
            this.KeySignatureMap[metaEvent.TotalTime] = keySignature;
        }
Exemple #4
0
        /// <summary>
        /// Changes the total (cumulative) time of each MTrk event in a track chunk, starting
        /// at the specified index in this file's list, by the specified number of ticks.
        /// </summary>
        /// <param name="index">The index of the event in this file's list at which to start the change.</param>
        /// <param name="delta">The number of ticks by which to change the total time of each event.</param>
        public void AdjustTotalTimes(int index, int delta)
        {
            if (delta == 0)
            {
                return;
            }

            /* Starting at the specified index, change the total time of each event in the list (until end-
             * of-list or a non-event is encountered, presumably indicating the end of the track/chunk),
             * and collect a list of key signature map "keys" (i.e., total times) affected by the change.
             */
            List <int> keys = new List <int>();

            for (int i = index; i < this.ItemCount; ++i)
            {
                MidiEvent mtrkEvent = this.Items[i] as MidiEvent;
                if (mtrkEvent == null)
                {
                    break;
                }
                mtrkEvent.TotalTime += delta;

                /* If this is a meta-event representing a key signature, add its former
                 * total time to the list of keys (total times) affected by this change.
                 */
                MidiMetaEvent metaEvent = MidiFile.ItemToKeySignatureEvent(mtrkEvent);
                if (metaEvent != null)
                {
                    keys.Add(metaEvent.TotalTime - delta);
                }
            }

            /* Since our key signature map is keyed by total time, it must be adjusted correspondingly.
             * Replace each affected entry with a new one having the updated "key" (total time).
             */
            if (delta > 0)
            {
                keys.Reverse();
            }
            foreach (int key in keys)
            {
                MidiKeySignature keySignature = this.KeySignatureMap[key];
                this.KeySignatureMap.Remove(key);
                this.KeySignatureMap[key + delta] = keySignature;
            }
        }
 private static string DescribeInstrument(int data, int channel, MidiKeySignature keySignature)
 {
     return(MidiChannelEvent.InstrumentMap[data]);
 }
 private static string DescribeController(int data, int channel, MidiKeySignature keySignature)
 {
     return(MidiChannelEvent.ControllerMap[data]);
 }
        /// <summary>Converts a numeric value to a string representation of its assigned note(s).</summary>
        /// <param name="n">Numeric value assigned to note (middle C has a reference value of 60).</param>
        /// <returns>String representation of note(s) to which numeric value is assigned.</returns>
        private static string DescribeNote(int n, int channel, MidiKeySignature keySignature)
        {
            /* If appropriate, notate as percussion. */
            if (channel == 9 && MidiChannelEvent.PercussionMap.ContainsKey(n))
            {
                return(MidiChannelEvent.PercussionMap[n]);
            }

            /* Otherwise, notate as pitch. */
            string s = null;
            int    i = (n / 12) - 1;

            /* If there is no key signature, assume C major. */
            MidiKeySignature k = (keySignature == MidiKeySignature.NA) ? MidiKeySignature.CMajor : keySignature;

            /* Convert the numeric value based on key signature (see MidiKeySignature notation chart). */
            switch (n % 12)
            {
            case 0:
                if (k > MidiKeySignature.EMajor && k < MidiKeySignature.CFlatMajor)
                {
                    s = "B#"; --i;
                }
                else
                {
                    s = "C";
                } break;

            case 1: s = (k > MidiKeySignature.FMajor || k < MidiKeySignature.CFlatMajor) ? "C#" : "Db"; break;

            case 2: s = "D"; break;

            case 3: s = (k > MidiKeySignature.GMajor && k < MidiKeySignature.CFlatMajor) ? "D#" : "Eb"; break;

            case 4: s = (k == MidiKeySignature.CFlatMajor || k == MidiKeySignature.AFlatMinor) ? "Fb" : "E"; break;

            case 5: s = (k > MidiKeySignature.AMajor && k < MidiKeySignature.CFlatMajor) ? "E#" : "F"; break;

            case 6: s = (k > MidiKeySignature.BFlatMinor || k < MidiKeySignature.CFlatMajor) ? "F#" : "Gb"; break;

            case 7: s = "G"; break;

            case 8: s = (k > MidiKeySignature.CMajor && k < MidiKeySignature.CFlatMajor) ? "G#" : "Ab"; break;

            case 9: s = "A"; break;

            case 10: s = (k > MidiKeySignature.DMajor && k < MidiKeySignature.CFlatMajor) ? "A#" : "Bb"; break;

            case 11:
                if (k >= MidiKeySignature.CFlatMajor && k < MidiKeySignature.DFlatMajor)
                {
                    s = "Cb"; ++i;
                }
                else
                {
                    s = "B";
                } break;

            default: return(string.Empty);
            }
            return(s + " " + ((i < 0) ? "-" : (i > 9) ? "+" : i.ToString()));
        }
        /// <summary>Returns a comment for the first data byte of a channel message/event.</summary>
        /// <param name="messageType">Identifies the type of channel message (high nibble of status byte).</param>
        /// <param name="data">The first data byte of the event.</param>
        /// <param name="channel">One of the sixteen logical MIDI channels on which the event is transmitted.</param>
        /// <param name="keySignature">A MidiKeySignature value that applies to the event.</param>
        /// <returns>A comment for the data byte.</returns>
        public static string GetData1Comment(MidiMessageType messageType, int data, int channel, MidiKeySignature keySignature)
        {
            string s = (MidiChannelEvent.TypeMap[messageType].DescribeData1 == null) ? null :
                       MidiChannelEvent.TypeMap[messageType].DescribeData1(data, channel, keySignature);

            return(MidiChannelEvent.BuildDataComment(MidiChannelEvent.TypeMap[messageType].Data1Name, data, s));
        }