示例#1
0
 private static void TriggerEvent(MidiEvent evnt, int track)
 {
     if (evnt is TempoMetaMidiEvent)
     {
         TempoMetaMidiEvent tempoEvent = (TempoMetaMidiEvent)evnt;
         SetTrackTempo(track, tempoEvent.Value);
     }
     else if (evnt is EndOfTrackMetaMidiEvent)
     {
         //Loop??
         _trackEventIndex[track] = 0;
     }
     else if (evnt is ControllerVoiceMidiEvent)
     {
         ControllerVoiceMidiEvent ccEvent = (ControllerVoiceMidiEvent)evnt;
         OnCC(track, ccEvent.Channel, ccEvent.Number, ccEvent.Value);
     }
     else if (evnt is OnNoteVoiceMidiEvent)
     {
         OnNoteVoiceMidiEvent voiceEvent = (OnNoteVoiceMidiEvent)evnt;
         OnNoteOn(track, voiceEvent.Channel, voiceEvent.Note, voiceEvent.Velocity);
     }
     else if (evnt is OffNoteVoiceMidiEvent)
     {
         OffNoteVoiceMidiEvent voiceEvent = (OffNoteVoiceMidiEvent)evnt;
         OnNoteOff(track, voiceEvent.Channel, voiceEvent.Note);
     }
 }
示例#2
0
        public void AddTempoEvent(long time, TempoMetaMidiEvent tempoEvent)
        {
            if (TempoEvents.ContainsKey(time))
            {
                System.Diagnostics.Debug.WriteLine(string.Format("TempoEvent at time {0} already exists.", time));
                return;
            }

            TempoEvents.Add(time, tempoEvent);
        }
        /// <summary>Parse a meta MIDI event from the data stream.</summary>
        /// <param name="deltaTime">The previously parsed delta-time for this event.</param>
        /// <param name="eventType">The previously parsed type of message we're expecting to find.</param>
        /// <param name="data">The data stream from which to read the event information.</param>
        /// <param name="pos">The position of the start of the event information.</param>
        /// <returns>The parsed meta MIDI event.</returns>
        private static MidiEvent ParseMetaEvent(long deltaTime, byte eventType, byte[] data, ref long pos)
        {
            try {
                MidiEvent tempEvent = null;

                // Create the correct meta event based on its meta event id/type
                switch (eventType)
                {
                // Sequence number
                case SequenceNumberMetaMidiEvent.MetaId:
                    pos++;     // skip past the 0x02
                    int number = ((data[pos] << 8) | data[pos + 1]);
                    tempEvent = new SequenceNumberMetaMidiEvent(deltaTime, number);
                    pos      += 2; // skip read values
                    break;

                // Text events (copyright, lyrics, etc)
                case TextMetaMidiEvent.MetaId:
                    tempEvent = new TextMetaMidiEvent(deltaTime, ReadASCIIText(data, ref pos));
                    break;

                case CopyrightTextMetaMidiEvent.MetaId:
                    tempEvent = new CopyrightTextMetaMidiEvent(deltaTime, ReadASCIIText(data, ref pos));
                    break;

                case SequenceTrackNameTextMetaMidiEvent.MetaId:
                    tempEvent = new SequenceTrackNameTextMetaMidiEvent(deltaTime, ReadASCIIText(data, ref pos));
                    break;

                case InstrumentTextMetaMidiEvent.MetaId:
                    tempEvent = new InstrumentTextMetaMidiEvent(deltaTime, ReadASCIIText(data, ref pos));
                    break;

                case LyricTextMetaMidiEvent.MetaId:
                    tempEvent = new LyricTextMetaMidiEvent(deltaTime, ReadASCIIText(data, ref pos));
                    break;

                case MarkerTextMetaMidiEvent.MetaId:
                    tempEvent = new MarkerTextMetaMidiEvent(deltaTime, ReadASCIIText(data, ref pos));
                    break;

                case CuePointTextMetaMidiEvent.MetaId:
                    tempEvent = new CuePointTextMetaMidiEvent(deltaTime, ReadASCIIText(data, ref pos));
                    break;

                case ProgramNameTextMetaMidiEvent.MetaId:
                    tempEvent = new ProgramNameTextMetaMidiEvent(deltaTime, ReadASCIIText(data, ref pos));
                    break;

                case DeviceNameTextMidiEvent.MetaId:
                    tempEvent = new DeviceNameTextMidiEvent(deltaTime, ReadASCIIText(data, ref pos));
                    break;

                // Channel prefix
                case ChannelPrefixMetaMidiEvent.MetaId:
                    pos++;     // skip 0x1
                    tempEvent = new ChannelPrefixMetaMidiEvent(deltaTime, data[pos]);
                    pos++;     // skip read value
                    break;

                // Port number
                case MidiPortMetaMidiEvent.MetaId:
                    pos++;     // skip 0x1
                    tempEvent = new MidiPortMetaMidiEvent(deltaTime, data[pos]);
                    pos++;     // skip read value
                    break;

                // End of track
                case EndOfTrackMetaMidiEvent.MetaId:
                    pos++;     // skip 0x0
                    tempEvent = new EndOfTrackMetaMidiEvent(deltaTime);
                    break;

                // Tempo
                case TempoMetaMidiEvent.MetaId:
                    pos++;     // skip 0x3
                    int tempo = ((data[pos] << 16) | data[pos + 1] << 8 | data[pos + 2]);
                    tempEvent = new TempoMetaMidiEvent(deltaTime, tempo);
                    pos      += 3;
                    break;

                // SMPTE offset
                case SMPTEOffsetMetaMidiEvent.MetaId:
                    pos++;     // skip 0x5
                    tempEvent = new SMPTEOffsetMetaMidiEvent(deltaTime,
                                                             data[pos], data[pos + 1], data[pos + 2], data[pos + 3], data[pos + 4]);
                    pos += 5;
                    break;

                // Time signature
                case TimeSignatureMetaMidiEvent.MetaId:
                    pos++;     // skip past 0x4
                    tempEvent = new TimeSignatureMetaMidiEvent(deltaTime,
                                                               data[pos], data[pos + 1], data[pos + 2], data[pos + 3]);
                    pos += 4;
                    break;

                // Key signature
                case KeySignatureMetaMidiEvent.MetaId:
                    pos++;     // skip past 0x2
                    tempEvent = new KeySignatureMetaMidiEvent(deltaTime, (Key)data[pos], (Tonality)data[pos + 1]);
                    pos      += 2;
                    break;

                // Proprietary
                case ProprietaryMetaMidiEvent.MetaId:
                    // Read in the variable length and that much data, then store it
                    long   length   = ReadVariableLength(data, ref pos);
                    byte[] propData = new byte[length];
                    Array.Copy(data, (int)pos, propData, 0, (int)length);
                    tempEvent = new ProprietaryMetaMidiEvent(deltaTime, propData);
                    pos      += length;
                    break;

                // An unknown meta event!
                default:
                    // Read in the variable length and that much data, then store it
                    length = ReadVariableLength(data, ref pos);
                    byte[] unknownData = new byte[length];
                    Array.Copy(data, (int)pos, unknownData, 0, (int)length);
                    tempEvent = new UnknownMetaMidiEvent(deltaTime, eventType, unknownData);
                    pos      += length;
                    break;
                }
                return(tempEvent);
            }
            // Something bad happened; wrap it in a parser exception
            catch (Exception exc) { throw new MidiParserException("Unable to parse meta MIDI event.", exc, pos); }
        }
示例#4
0
        private double GetMicrosecondsPerTick(TempoMetaMidiEvent tempoEvent)
        {
            int microsecondsPerBeat = tempoEvent.Value;                // microseconds / beat

            return((double)microsecondsPerBeat / TicksPerBeatOrFrame); // returns microseconds / tick
        }