コード例 #1
0
ファイル: RawMetaEvent.cs プロジェクト: zhangx3000/GFF
        public override MidiEvent Clone()
        {
            MetaEventType arg_23_0 = base.MetaEventType;
            long          arg_23_1 = base.AbsoluteTime;

            byte[] expr_12 = this.Data;
            return(new RawMetaEvent(arg_23_0, arg_23_1, (byte[])((expr_12 != null) ? expr_12.Clone() : null)));
        }
コード例 #2
0
        private void CheckTextMap(string inText, string outText, MetaEventType eventType, MidiMappingRules mappingRules, EventRuleArgs args)
        {
            TextEvent textEvent = new TextEvent(inText, eventType, 0);
            bool      matched   = mappingRules.Process(textEvent, args);

            Assert.IsTrue(matched);
            Assert.AreEqual(textEvent.Text, outText);
            Assert.AreEqual(textEvent.MetaEventType, eventType);
        }
コード例 #3
0
        private TextMap CreateTextMap(MetaEventType eventType, string inValue, string outValue)
        {
            TextMap textMap = new TextMap();

            textMap.InValue   = inValue;
            textMap.EventType = eventType;
            textMap.OutValue  = outValue;
            return(textMap);
        }
コード例 #4
0
ファイル: Event.cs プロジェクト: Seabass992/MusicStuff
        public MetaEvent(BinaryReader reader)
        {
            EventType     = Event.Type.Meta;
            EventTypeByte = reader.ReadByte();
            Type          = (MetaEventType)EventTypeByte;
            var length = new VLQ(reader);

            Length      = length.Value;
            LengthBytes = length.Bytes.ToArray();
            DataBytes   = reader.ReadBytes(Convert.ToInt32(Length));
        }
コード例 #5
0
        /// <summary>
        /// Reads a meta-event from a stream
        /// </summary>
        /// <param name="br">A binary reader based on the stream of MIDI data</param>
        /// <returns>A new MetaEvent object</returns>
        public static MetaEvent ReadMetaEvent(BinaryReader br)
        {
            MetaEventType metaEvent = (MetaEventType)br.ReadByte();
            int           length    = ReadVarInt(br);

            MetaEvent me = new MetaEvent();

            switch (metaEvent)
            {
            case MetaEventType.TextEvent:           // Text event
            case MetaEventType.Copyright:           // Copyright
            case MetaEventType.SequenceTrackName:   // Sequence / Track Name
            case MetaEventType.TrackInstrumentName: // Track instrument name
            case MetaEventType.Lyric:               // lyric
            case MetaEventType.Marker:              // marker
            case MetaEventType.CuePoint:            // cue point
            case MetaEventType.ProgramName:
            case MetaEventType.DeviceName:
                me = new TextEvent(br, length);
                break;

            case MetaEventType.EndTrack: // This event must come at the end of each track
                if (length != 0)
                {
                    throw new FormatException("End track length");
                }
                break;

            case MetaEventType.SetTempo: // Set tempo
                me = new TempoEvent(br, length);
                break;

            case MetaEventType.TimeSignature: // Time signature
                me = new TimeSignatureEvent(br, length);
                break;

            default:
//System.Windows.Forms.MessageBox.Show(String.Format("Unsupported MetaEvent {0} length {1} pos {2}",metaEvent,length,br.BaseStream.Position));
                me.data = br.ReadBytes(length);
                if (me.data.Length != length)
                {
                    throw new FormatException("Failed to read metaevent's data fully");
                }
                break;
            }
            me.metaEvent      = metaEvent;
            me.metaDataLength = length;

            return(me);
        }
コード例 #6
0
ファイル: RawMetaEvent.cs プロジェクト: zhangx3000/GFF
 public RawMetaEvent(MetaEventType metaEventType, long absoluteTime, byte[] data) : base(metaEventType, (data != null) ? data.Length : 0, absoluteTime)
 {
     this.Data = data;
 }
コード例 #7
0
ファイル: MetaEvent.cs プロジェクト: h4ltYu/EOS
        public static MetaEvent ReadMetaEvent(BinaryReader br)
        {
            MetaEventType metaEventType  = (MetaEventType)br.ReadByte();
            int           num            = MidiEvent.ReadVarInt(br);
            MetaEvent     metaEvent      = new MetaEvent();
            MetaEventType metaEventType2 = metaEventType;

            if (metaEventType2 <= MetaEventType.SetTempo)
            {
                switch (metaEventType2)
                {
                case MetaEventType.TrackSequenceNumber:
                    metaEvent = new TrackSequenceNumberEvent(br, num);
                    goto IL_E9;

                case MetaEventType.TextEvent:
                case MetaEventType.Copyright:
                case MetaEventType.SequenceTrackName:
                case MetaEventType.TrackInstrumentName:
                case MetaEventType.Lyric:
                case MetaEventType.Marker:
                case MetaEventType.CuePoint:
                case MetaEventType.ProgramName:
                case MetaEventType.DeviceName:
                    metaEvent = new TextEvent(br, num);
                    goto IL_E9;

                default:
                    if (metaEventType2 != MetaEventType.EndTrack)
                    {
                        if (metaEventType2 == MetaEventType.SetTempo)
                        {
                            metaEvent = new TempoEvent(br, num);
                            goto IL_E9;
                        }
                    }
                    else
                    {
                        if (num != 0)
                        {
                            throw new FormatException("End track length");
                        }
                        goto IL_E9;
                    }
                    break;
                }
            }
            else
            {
                if (metaEventType2 == MetaEventType.SmpteOffset)
                {
                    metaEvent = new SmpteOffsetEvent(br, num);
                    goto IL_E9;
                }
                switch (metaEventType2)
                {
                case MetaEventType.TimeSignature:
                    metaEvent = new TimeSignatureEvent(br, num);
                    goto IL_E9;

                case MetaEventType.KeySignature:
                    metaEvent = new KeySignatureEvent(br, num);
                    goto IL_E9;

                default:
                    if (metaEventType2 == MetaEventType.SequencerSpecific)
                    {
                        metaEvent = new SequencerSpecificEvent(br, num);
                        goto IL_E9;
                    }
                    break;
                }
            }
            metaEvent.data = br.ReadBytes(num);
            if (metaEvent.data.Length != num)
            {
                throw new FormatException("Failed to read metaevent's data fully");
            }
IL_E9:
            metaEvent.metaEvent      = metaEventType;
            metaEvent.metaDataLength = num;
            return(metaEvent);
        }
コード例 #8
0
ファイル: MIDI.cs プロジェクト: xchellx/Demolisher
        // Token: 0x06000155 RID: 341 RVA: 0x00004F50 File Offset: 0x00003150
        public static MIDI FromStream(Stream stream)
        {
            ABinaryReader abinaryReader = new ABinaryReader(stream, Endianness.Big);
            MIDI          midi          = new MIDI();

            if (abinaryReader.ReadRawString(4) != "MThd")
            {
                throw new InvalidDataException("Missing header chunk in MIDI file.");
            }
            if (abinaryReader.Read32() != 6U)
            {
                throw new InvalidDataException("Invalid header size in MIDI file.");
            }
            MIDIFormat enumValue = (MIDIFormat)abinaryReader.Read16();

            if (!enumValue.IsDefined <MIDIFormat>())
            {
                throw new InvalidDataException("Invalid format in MIDI file.");
            }
            abinaryReader.Read16();
            int num = (int)abinaryReader.Read16();

            if ((num & 32768) != 0)
            {
                midi.division = new SMPTEDivision((SMPTEFrameRate)(-(int)(num >> 8)), num & 255);                 // TODO: Cannot infer type, so: (ModularType) -> (int)
            }
            else
            {
                midi.division = new TicksPerBeatDivision(num);
            }
            int num2 = 0;

            while (!abinaryReader.IsAtEndOfStream)
            {
                if (abinaryReader.ReadRawString(4) != "MTrk")
                {
                    throw new InvalidDataException("Missing track chunk in MIDI file.");
                }
                ulong num3 = 0UL;
                uint  num4 = abinaryReader.Read32();
                abinaryReader.SetAnchor();
                Track track = new Track();
                byte  b     = 0;
                while (abinaryReader.Position < (long)((ulong)num4))
                {
                    ulong num5 = abinaryReader.ReadUIntVar();
                    byte  b2   = abinaryReader.Read8();
                    if (b2 < 128)
                    {
                        if (b == 0)
                        {
                            throw new InvalidDataException("Encountered running status event with no previous status available.");
                        }
                        b2 = b;
                        abinaryReader.Position -= 1L;
                    }
                    if (b2 >= 240 && b2 <= 247)
                    {
                        b = 0;
                    }
                    else if (b2 >= 128 && b2 <= 239)
                    {
                        b = b2;
                    }
                    num3 += num5;
                    if (b2 == 255)
                    {
                        MetaEventType metaEventType = (MetaEventType)abinaryReader.Read8();
                        int           num6          = (int)abinaryReader.ReadUIntVar();
                        if (!metaEventType.IsDefined <MetaEventType>())
                        {
                            throw new InvalidDataException(string.Format("Encountered unsupported meta event type {0}.", metaEventType));
                        }
                        MetaEventType metaEventType2 = metaEventType;
                        if (metaEventType2 <= MetaEventType.EndOfTrack)
                        {
                            switch (metaEventType2)
                            {
                            case MetaEventType.SequenceNumber:
                                if (num6 != 2)
                                {
                                    throw new InvalidDataException("Invalid size in sequence-number event.");
                                }
                                track.Add(new SequenceNumberEvent(num5, (int)abinaryReader.Read16()), num3);
                                continue;

                            case MetaEventType.Text:
                                track.Add(new TextEvent(num5, abinaryReader.ReadRawString(num6)), num3);
                                continue;

                            case MetaEventType.CopyrightNotice:
                                track.Add(new CopyrightNoticeEvent(num5, abinaryReader.ReadRawString(num6)), num3);
                                continue;

                            case MetaEventType.Name:
                                track.Add(new TrackNameEvent(num5, abinaryReader.ReadRawString(num6)), num3);
                                continue;

                            case MetaEventType.InstrumentName:
                                track.Add(new InstrumentNameEvent(num5, abinaryReader.ReadRawString(num6)), num3);
                                continue;

                            case MetaEventType.Lyrics:
                                track.Add(new LyricsEvent(num5, abinaryReader.ReadRawString(num6)), num3);
                                continue;

                            case MetaEventType.Marker:
                                track.Add(new MarkerEvent(num5, abinaryReader.ReadRawString(num6)), num3);
                                continue;

                            case MetaEventType.CuePoint:
                                track.Add(new CuePointEvent(num5, abinaryReader.ReadRawString(num6)), num3);
                                continue;

                            default:
                                if (metaEventType2 != MetaEventType.ChannelPrefix)
                                {
                                    if (metaEventType2 == MetaEventType.EndOfTrack)
                                    {
                                        if (num6 != 0)
                                        {
                                            throw new InvalidDataException("Invalid size in end-of-track event.");
                                        }
                                        track.Add(new EndOfTrackEvent(num5), num3);
                                        continue;
                                    }
                                }
                                else
                                {
                                    if (num6 != 1)
                                    {
                                        throw new InvalidDataException("Invalid size in channel-prefix event.");
                                    }
                                    track.Add(new ChannelPrefixEvent(num5, abinaryReader.Read8()), num3);
                                    continue;
                                }
                                break;
                            }
                        }
                        else if (metaEventType2 != MetaEventType.TempoChange)
                        {
                            switch (metaEventType2)
                            {
                            case MetaEventType.TimeSignature:
                                if (num6 != 4)
                                {
                                    throw new InvalidDataException("Invalid size in time-signature event.");
                                }
                                track.Add(new TimeSignatureEvent(num5, (int)abinaryReader.Read8(), (int)abinaryReader.Read8(), (int)abinaryReader.Read8(), (int)abinaryReader.Read8()), num3);
                                continue;

                            case MetaEventType.KeySignature:
                                if (num6 != 2)
                                {
                                    throw new InvalidDataException("Invalid size in key-signature event.");
                                }
                                track.Add(new KeySignatureEvent(num5, (int)abinaryReader.ReadS8(), (Scale)abinaryReader.Read8()), num3);
                                continue;

                            default:
                                if (metaEventType2 == MetaEventType.SequencerSpecific)
                                {
                                    byte[] array = abinaryReader.Read8s(num6);
                                    if (num6 == 0 || num6 < ((array[0] == 0) ? 3 : 1))
                                    {
                                        throw new InvalidDataException("Invalid size in sequencer-specific event.");
                                    }
                                    bool flag           = array[0] == 0;
                                    int  manufacturerID = flag ? ((int)array[1] << 8 | (int)array[2]) : ((int)array[0]);
                                    track.Add(new SequencerSpecificEvent(num5, manufacturerID, flag, array.Duplicate(flag ? 3 : 1, array.Length - (flag ? 3 : 1))), num3);
                                    continue;
                                }
                                break;
                            }
                        }
                        else
                        {
                            if (num6 != 3)
                            {
                                throw new InvalidDataException("Invalid size in tempo-change event.");
                            }
                            track.Add(new TempoChangeEvent(num5, abinaryReader.Read24()), num3);
                            continue;
                        }
                        throw new NotImplementedException(string.Format("Encountered unimplemented meta event type {0}.", metaEventType));
                    }
                    else if (b2 == 240 || b2 == 247)
                    {
                        byte[] array2 = abinaryReader.Read8s((int)abinaryReader.ReadUIntVar());
                        if (array2.Length == 0 || array2.Length < ((array2[0] == 0) ? 3 : 1))
                        {
                            throw new InvalidDataException("Encountered a SysEx event with an invalid size.");
                        }
                        SystemExclusiveEventType type = SystemExclusiveEventType.Normal;
                        bool flag2           = b2 == 247;
                        bool flag3           = array2.Last <byte>() == 247;
                        bool flag4           = array2[0] == 0;
                        int  manufacturerID2 = flag4 ? ((int)array2[1] << 8 | (int)array2[2]) : ((int)array2[0]);
                        if (flag2)
                        {
                            type = (flag3 ? SystemExclusiveEventType.Terminating : SystemExclusiveEventType.Continuation);
                        }
                        if (flag3)
                        {
                            array2 = array2.Duplicate(array2.Length - 1);
                        }
                        track.Add(new SystemExclusiveEvent(num5, type, manufacturerID2, flag4, array2), num3);
                    }
                    else
                    {
                        ChannelEventType channelEventType = (ChannelEventType)(b2 & 240);
                        byte             channelNumber    = (byte)(b2 & 15);
                        if (!channelEventType.IsDefined <ChannelEventType>())
                        {
                            throw new InvalidDataException(string.Format("Encountered undefined channel-event type {0}.", channelEventType));
                        }
                        ChannelEventType channelEventType2 = channelEventType;
                        if (channelEventType2 <= ChannelEventType.NoteAftertouch)
                        {
                            if (channelEventType2 == ChannelEventType.NoteOff)
                            {
                                track.Add(new NoteOffEvent(num5, (int)channelNumber, abinaryReader.Read8(), (int)abinaryReader.Read8()), num3);
                                continue;
                            }
                            if (channelEventType2 == ChannelEventType.NoteOn)
                            {
                                track.Add(new NoteOnEvent(num5, (int)channelNumber, (int)abinaryReader.Read8(), (int)abinaryReader.Read8()), num3);
                                continue;
                            }
                            if (channelEventType2 == ChannelEventType.NoteAftertouch)
                            {
                                track.Add(new NoteAftertouchEvent(num5, (int)channelNumber, (int)abinaryReader.Read8(), (int)abinaryReader.Read8()), num3);
                                continue;
                            }
                        }
                        else if (channelEventType2 <= ChannelEventType.ProgramChange)
                        {
                            if (channelEventType2 == ChannelEventType.Controller)
                            {
                                track.Add(new ControllerEvent(num5, (int)channelNumber, (int)abinaryReader.Read8(), (int)abinaryReader.Read8()), num3);
                                continue;
                            }
                            if (channelEventType2 == ChannelEventType.ProgramChange)
                            {
                                track.Add(new ProgramChangeEvent(num5, (int)channelNumber, (int)abinaryReader.Read8()), num3);
                                continue;
                            }
                        }
                        else
                        {
                            if (channelEventType2 == ChannelEventType.ChannelAftertouch)
                            {
                                track.Add(new ChannelAftertouchEvent(num5, (int)channelNumber, (int)abinaryReader.Read8()), num3);
                                continue;
                            }
                            if (channelEventType2 == ChannelEventType.PitchBend)
                            {
                                track.Add(new PitchBendEvent(num5, (int)channelNumber, (int)(abinaryReader.Read8() & 127) | (int)(abinaryReader.Read8() & 127) << 7), num3);
                                continue;
                            }
                        }
                        throw new NotImplementedException(string.Format("Encountered unimplemented channel event type {0}.", channelEventType));
                    }
                }
                midi.tracks.Add(track);
                abinaryReader.ResetAnchor();
                num2++;
            }
            return(midi);
        }
コード例 #9
0
ファイル: MIDIEvent.cs プロジェクト: xchellx/Demolisher
        // Token: 0x06000008 RID: 8 RVA: 0x00002124 File Offset: 0x00000324
        private static MIDIEvent FromStream(ABinaryReader binaryReader, ulong deltaTime, byte statusByte)
        {
            if (statusByte == 255)
            {
                MetaEventType metaEventType = (MetaEventType)binaryReader.Read8();
                int           num           = (int)binaryReader.ReadUIntVar();
                if (!metaEventType.IsDefined <MetaEventType>())
                {
                    throw new InvalidDataException(string.Format("Encountered unsupported meta event type {0}.", metaEventType));
                }
                MetaEventType metaEventType2 = metaEventType;
                if (metaEventType2 <= MetaEventType.EndOfTrack)
                {
                    switch (metaEventType2)
                    {
                    case MetaEventType.SequenceNumber:
                        if (num != 2)
                        {
                            throw new InvalidDataException("Invalid size in sequence-number event.");
                        }
                        return(new SequenceNumberEvent(deltaTime, (int)binaryReader.Read16()));

                    case MetaEventType.Text:
                        return(new TextEvent(deltaTime, binaryReader.ReadRawString(num)));

                    case MetaEventType.CopyrightNotice:
                        return(new CopyrightNoticeEvent(deltaTime, binaryReader.ReadRawString(num)));

                    case MetaEventType.Name:
                        return(new TrackNameEvent(deltaTime, binaryReader.ReadRawString(num)));

                    case MetaEventType.InstrumentName:
                        return(new InstrumentNameEvent(deltaTime, binaryReader.ReadRawString(num)));

                    case MetaEventType.Lyrics:
                        return(new LyricsEvent(deltaTime, binaryReader.ReadRawString(num)));

                    case MetaEventType.Marker:
                        return(new MarkerEvent(deltaTime, binaryReader.ReadRawString(num)));

                    case MetaEventType.CuePoint:
                        return(new CuePointEvent(deltaTime, binaryReader.ReadRawString(num)));

                    default:
                        if (metaEventType2 != MetaEventType.ChannelPrefix)
                        {
                            if (metaEventType2 == MetaEventType.EndOfTrack)
                            {
                                if (num != 0)
                                {
                                    throw new InvalidDataException("Invalid size in end-of-track event.");
                                }
                                return(new EndOfTrackEvent(deltaTime));
                            }
                        }
                        else
                        {
                            if (num != 1)
                            {
                                throw new InvalidDataException("Invalid size in channel-prefix event.");
                            }
                            return(new ChannelPrefixEvent(deltaTime, binaryReader.Read8()));
                        }
                        break;
                    }
                }
                else if (metaEventType2 != MetaEventType.TempoChange)
                {
                    switch (metaEventType2)
                    {
                    case MetaEventType.TimeSignature:
                        if (num != 4)
                        {
                            throw new InvalidDataException("Invalid size in time-signature event.");
                        }
                        return(new TimeSignatureEvent(deltaTime, (int)binaryReader.Read8(), (int)binaryReader.Read8(), (int)binaryReader.Read8(), (int)binaryReader.Read8()));

                    case MetaEventType.KeySignature:
                        if (num != 2)
                        {
                            throw new InvalidDataException("Invalid size in key-signature event.");
                        }
                        return(new KeySignatureEvent(deltaTime, (int)binaryReader.ReadS8(), (Scale)binaryReader.Read8()));

                    default:
                        if (metaEventType2 == MetaEventType.SequencerSpecific)
                        {
                            byte[] array = binaryReader.Read8s(num);
                            if (num == 0 || num < ((array[0] == 0) ? 3 : 1))
                            {
                                throw new InvalidDataException("Invalid size in sequencer-specific event.");
                            }
                            bool flag           = array[0] == 0;
                            int  manufacturerID = flag ? ((int)array[1] << 8 | (int)array[2]) : ((int)array[0]);
                            return(new SequencerSpecificEvent(deltaTime, manufacturerID, flag, array.Duplicate(flag ? 3 : 1, array.Length - (flag ? 3 : 1))));
                        }
                        break;
                    }
                }
                else
                {
                    if (num != 3)
                    {
                        throw new InvalidDataException("Invalid size in tempo-change event.");
                    }
                    return(new TempoChangeEvent(deltaTime, binaryReader.Read24()));
                }
                throw new NotImplementedException(string.Format("Encountered unimplemented meta event type {0}.", metaEventType));
            }
            else if (statusByte == 240 || statusByte == 247)
            {
                byte[] array2 = binaryReader.Read8s((int)binaryReader.ReadUIntVar());
                if (array2.Length == 0 || array2.Length < ((array2[0] == 0) ? 3 : 1))
                {
                    throw new InvalidDataException("Encountered a SysEx event with an invalid size.");
                }
                SystemExclusiveEventType type = SystemExclusiveEventType.Normal;
                bool flag2           = statusByte == 247;
                bool flag3           = array2.Last <byte>() == 247;
                bool flag4           = array2[0] == 0;
                int  manufacturerID2 = flag4 ? ((int)array2[1] << 8 | (int)array2[2]) : ((int)array2[0]);
                if (flag2)
                {
                    type = (flag3 ? SystemExclusiveEventType.Terminating : SystemExclusiveEventType.Continuation);
                }
                if (flag3)
                {
                    array2 = array2.Duplicate(array2.Length - 1);
                }
                return(new SystemExclusiveEvent(deltaTime, type, manufacturerID2, flag4, array2));
            }
            else
            {
                ChannelEventType channelEventType = (ChannelEventType)(statusByte & 240);
                byte             channelNumber    = (byte)(statusByte & 15);
                if (!channelEventType.IsDefined <ChannelEventType>())
                {
                    throw new InvalidDataException(string.Format("Encountered undefined channel-event type {0}.", channelEventType));
                }
                ChannelEventType channelEventType2 = channelEventType;
                if (channelEventType2 <= ChannelEventType.NoteAftertouch)
                {
                    if (channelEventType2 == ChannelEventType.NoteOff)
                    {
                        return(new NoteOffEvent(deltaTime, (int)channelNumber, binaryReader.Read8(), (int)binaryReader.Read8()));
                    }
                    if (channelEventType2 == ChannelEventType.NoteOn)
                    {
                        return(new NoteOnEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8(), (int)binaryReader.Read8()));
                    }
                    if (channelEventType2 == ChannelEventType.NoteAftertouch)
                    {
                        return(new NoteAftertouchEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8(), (int)binaryReader.Read8()));
                    }
                }
                else if (channelEventType2 <= ChannelEventType.ProgramChange)
                {
                    if (channelEventType2 == ChannelEventType.Controller)
                    {
                        return(new ControllerEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8(), (int)binaryReader.Read8()));
                    }
                    if (channelEventType2 == ChannelEventType.ProgramChange)
                    {
                        return(new ProgramChangeEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8()));
                    }
                }
                else
                {
                    if (channelEventType2 == ChannelEventType.ChannelAftertouch)
                    {
                        return(new ChannelAftertouchEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8()));
                    }
                    if (channelEventType2 == ChannelEventType.PitchBend)
                    {
                        return(new PitchBendEvent(deltaTime, (int)channelNumber, (int)(binaryReader.Read8() & 127) | (int)(binaryReader.Read8() & 127) << 7));
                    }
                }
                throw new NotImplementedException(string.Format("Encountered unimplemented channel event type {0}.", channelEventType));
            }
        }
コード例 #10
0
ファイル: MidiStream.cs プロジェクト: Bpendragon/MidiToWav
        public List <TrackChunk> ConstructStreams(string file)
        {
            byte[] data;
            uint   dataPointer = 0;
            var    tracks      = new List <TrackChunk>();

            try
            {
                data = File.ReadAllBytes(file);
            }
            catch
            {
                throw;
            }

            if (data[dataPointer++] != 0x4D ||
                data[dataPointer++] != 0x54 ||
                data[dataPointer++] != 0x68 ||
                data[dataPointer++] != 0x64
                )
            {
                throw new FileLoadException("Not a MIDI File");
            }


            Header.Length = (uint)(data[dataPointer++] << 24 | data[dataPointer++] << 16 | data[dataPointer++] << 8 | data[dataPointer++]);

            Header.Format = (MidiFormat)(data[dataPointer++] << 8 | data[dataPointer++]);
            uint numTracks = (uint)(data[dataPointer++] << 8 | data[dataPointer++]);

            Header.NumTracks = numTracks;
            Header.Division  = new DivisionInfo((ushort)(data[dataPointer++] << 8 | data[dataPointer++]));


            for (int i = 0; i < numTracks; i++)
            {
                if (data[dataPointer++] != 0x4D ||
                    data[dataPointer++] != 0x54 ||
                    data[dataPointer++] != 0x72 ||
                    data[dataPointer++] != 0x6B
                    )
                {
                    throw new FileLoadException("Missing Track Header");
                }

                var track  = new TrackChunk();
                var length = (uint)(data[dataPointer++] << 24 | data[dataPointer++] << 16 | data[dataPointer++] << 8 | data[dataPointer++]);
                track.Length = length;

                var target = dataPointer + length;

                MetaEventType LastMessage = MetaEventType.None;

                while (LastMessage != MetaEventType.EndOfTrack)
                {
                    //First item on each time through the loop get the Delta Time
                    uint delta_counter = 0;
                    while (data[dataPointer] >= 0x80)
                    {
                        delta_counter = (delta_counter << 7 | (byte)(data[dataPointer] & 0x7F));
                        dataPointer++;
                    }

                    //this gets the last byte added on.
                    delta_counter = (delta_counter << 7 | (byte)(data[dataPointer] & 0x7F));
                    dataPointer++;
                    var tmpEvent = new MidiTrackEvent(delta_counter);


                    if ((data[dataPointer] >> 4) < 0x8)
                    {
                        throw new FileLoadException(data[dataPointer] + " is not a valid message identifier");
                    }
                    else if ((data[dataPointer] >> 4) != 0xF)
                    {
                        tmpEvent.EventType = (MidiTrackEventType)(data[dataPointer] >> 4);
                    }
                    else
                    {
                        tmpEvent.EventType = (MidiTrackEventType)data[dataPointer];
                    }



                    if (tmpEvent.EventType == MidiTrackEventType.Meta)
                    {
                        dataPointer++; // do this here because we still need the datapointer to know the channel for the voice messages
                        tmpEvent.MetaType = (MetaEventType)(data[dataPointer++]);

                        uint msgLength = 0;
                        while (data[dataPointer] >= 0x80)
                        {
                            msgLength = (msgLength << 7 | (byte)(data[dataPointer] & 0x7F));
                            dataPointer++;
                        }

                        //this gets the last byte added on.
                        msgLength = (msgLength << 7 | (byte)(data[dataPointer] & 0x7F));
                        dataPointer++;

                        for (int j = 0; j < msgLength; j++)
                        {
                            tmpEvent.Data.Add(data[dataPointer++]);
                        }

                        if (tmpEvent.MetaType == MetaEventType.TrackName)
                        {
                            track.Name = Encoding.ASCII.GetString(tmpEvent.Data.ToArray());
                        }
                    }
                    else
                    {
                        switch (tmpEvent.EventType)
                        {
                        case MidiTrackEventType.NoteOff:
                        case MidiTrackEventType.NoteOn:
                        case MidiTrackEventType.PolyphonicAftertouch:
                            tmpEvent.ChannelNumber = data[dataPointer++] & 0x0F;
                            tmpEvent.KeyNumber     = data[dataPointer++];
                            tmpEvent.Value         = data[dataPointer++];
                            break;

                        case MidiTrackEventType.ControlChange:
                            tmpEvent.ChannelNumber = data[dataPointer++] & 0x0F;
                            tmpEvent.Controller    = (MidiController)(data[dataPointer++]);
                            tmpEvent.Value         = data[dataPointer++];
                            break;

                        case MidiTrackEventType.PitchWheelChange:
                        case MidiTrackEventType.SongPositionPointer:
                            dataPointer++;
                            tmpEvent.FourteenBit = (ushort)(data[dataPointer++] | data[dataPointer++] << 7);
                            break;

                        case MidiTrackEventType.SongSelect:
                        case MidiTrackEventType.ChannelAftertouch:
                        case MidiTrackEventType.ProgramChange:
                            dataPointer++;
                            tmpEvent.Value = data[dataPointer++];
                            break;

                        case MidiTrackEventType.SystemExclusive:
                            dataPointer++;
                            while (data[dataPointer] != 0xF7)
                            {
                                tmpEvent.Data.Add(data[dataPointer++]);
                            }
                            dataPointer++;

                            break;

                        default:
                            break;
                        }
                    }
                    track.Events.Add(tmpEvent);
                    LastMessage = tmpEvent.MetaType;
                }

                tracks.Add(track);
            }
            return(tracks);
        }
コード例 #11
0
ファイル: TextEvent.cs プロジェクト: hanistory/hasuite
 /// <summary>
 /// Creates a new TextEvent
 /// </summary>
 /// <param name="text">The text in this type</param>
 /// <param name="metaEventType">MetaEvent type (must be one that is
 /// associated with text data)</param>
 /// <param name="absoluteTime">Absolute time of this event</param>
 public TextEvent(string text, MetaEventType metaEventType, long absoluteTime)
     : base(metaEventType, text.Length, absoluteTime)
 {
     this.text = text;
 }
コード例 #12
0
 /// <summary>
 /// Custom constructor for use by derived types, who will manage the data themselves
 /// </summary>
 /// <param name="metaEventType">Meta event type</param>
 /// <param name="metaDataLength">Meta data length</param>
 /// <param name="absoluteTime">Absolute time</param>
 public MetaEvent(MetaEventType metaEventType, int metaDataLength, long absoluteTime)
     : base(absoluteTime, 1, MidiCommandCode.MetaEvent)
 {
     this.metaEvent      = metaEventType;
     this.metaDataLength = metaDataLength;
 }
コード例 #13
0
 /// <summary>
 ///  Creates a meta event with raw data
 /// </summary>
 public RawMetaEvent(MetaEventType metaEventType, long absoluteTime, byte[] data) : base(metaEventType,
                                                                                         data?.Length ?? 0, absoluteTime)
 {
     Data = data;
 }
コード例 #14
0
ファイル: MidiFile.cs プロジェクト: ed-cooper/ReadMIDI
        /// <summary>
        /// Opens a new <see cref="MidiFile"/> from the specified path.
        /// </summary>
        /// <param name="path">The path to load the midi file from.</param>
        public MidiFile(string path)
        {
            Utils.PrintDebug("Loading file: " + path + "\r\n-----------------");
            BinaryReader br = new BinaryReader(File.Open(path, FileMode.Open));

            using (br)
            {
                // Check valid MIDI file
                if (Encoding.ASCII.GetString(br.ReadBytes(4)) == "MThd")
                {
                    if (Utils.CorrectEndian(br.ReadUInt32()) == 6)
                    {
                        // Valid MIDI file

                        // Get MIDI internal file format
                        fileFormat = (FileFormat)Utils.CorrectEndian(br.ReadUInt16());
                        Utils.PrintDebug("HEAD: FileFormat " + fileFormat.ToString());

                        // Get track count
                        trackCount = Utils.CorrectEndian(br.ReadUInt16());
                        Utils.PrintDebug("HEAD: Tracks " + trackCount);

                        // Get MIDI time conversion
                        deltaTicksPerQuarterNote = Utils.CorrectEndian(br.ReadUInt16());
                        Utils.PrintDebug("HEAD: DeltaTicksPerQuarterNote " + deltaTicksPerQuarterNote);

                        // Current track
                        uint track = 0;
                        // Tracks list
                        List <TrackChunk> tracks = new List <TrackChunk>();

                        // Repeat for every track chunk
                        while (br.BaseStream.Position != br.BaseStream.Length)
                        {
                            Utils.PrintDebug("-----------------\r\nTRACK: " + br.BaseStream.Position);
                            if (Encoding.ASCII.GetString(br.ReadBytes(4)) == "MTrk")
                            {
                                // Valid track chunk

                                // Create new track data
                                List <MetaEvent> metaEvents = new List <MetaEvent>();
                                List <MidiEvent> midiEvents = new List <MidiEvent>();

                                // Absolute time
                                uint absTime = 0;

                                // End position in bytes of chunk
                                long targetPosition = br.BaseStream.Position + 4 + Utils.CorrectEndian(br.ReadUInt32());
                                // Used for continous status between MIDI events
                                byte statusOld = 0x00;

                                // Repeat for every event
                                while (br.BaseStream.Position < targetPosition)
                                {
                                    // Get delta time (time since last MIDI event)
                                    uint deltaTime = Utils.ReadVariableLengthUint(br);
                                    // Get first byte of event (used to identify event type)
                                    byte eventHeader = br.ReadByte();

                                    // Update absolute time
                                    absTime += deltaTime;

                                    switch (eventHeader)
                                    {
                                    case 0xFF:     // Meta Event
                                        // Get meta event type
                                        MetaEventType metaCode = (MetaEventType)br.ReadByte();
                                        // Get length in bytes of event data
                                        int lenData1 = (int)Utils.ReadVariableLengthUint(br);

                                        switch (metaCode)
                                        {
                                        case MetaEventType.SequenceNumber:
                                            if (lenData1 == 2)
                                            {
                                                ushort sequenceNumber = Utils.CorrectEndian(br.ReadUInt16());
                                                metaEvents.Add(new SequenceNumberEvent(track, deltaTime, absTime, sequenceNumber));
                                                Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), sequenceNumber, br.BaseStream.Position));
                                            }
                                            else
                                            {
                                                Utils.PrintDebug("Could not read MIDI file - invalid SequenceNumber meta event");
                                                throw new FormatException("Could not read MIDI file - invalid SequenceNumber meta event");
                                            }
                                            break;

                                        case MetaEventType.TextEvent:
                                            string text = Encoding.ASCII.GetString(br.ReadBytes(lenData1));
                                            metaEvents.Add(new TextEvent(track, deltaTime, absTime, text));
                                            Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), text, br.BaseStream.Position));
                                            break;

                                        case MetaEventType.CopyrightNotice:
                                            string copyright = Encoding.ASCII.GetString(br.ReadBytes(lenData1));
                                            metaEvents.Add(new TextEvent(track, deltaTime, absTime, copyright, MetaEventType.CopyrightNotice));
                                            Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), copyright, br.BaseStream.Position));
                                            break;

                                        case MetaEventType.SequenceName:
                                            string sequenceName = Encoding.ASCII.GetString(br.ReadBytes(lenData1));
                                            metaEvents.Add(new TextEvent(track, deltaTime, absTime, sequenceName, MetaEventType.SequenceName));
                                            Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), sequenceName, br.BaseStream.Position));
                                            break;

                                        case MetaEventType.InstrumentName:
                                            string instrumentName = Encoding.ASCII.GetString(br.ReadBytes(lenData1));
                                            metaEvents.Add(new TextEvent(track, deltaTime, absTime, instrumentName, MetaEventType.InstrumentName));
                                            Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), instrumentName, br.BaseStream.Position));
                                            break;

                                        case MetaEventType.LyricText:
                                            string lyric = Encoding.ASCII.GetString(br.ReadBytes(lenData1));
                                            metaEvents.Add(new TextEvent(track, deltaTime, absTime, lyric, MetaEventType.LyricText));
                                            Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), lyric, br.BaseStream.Position));
                                            break;

                                        case MetaEventType.MarkerText:
                                            string marker = Encoding.ASCII.GetString(br.ReadBytes(lenData1));
                                            metaEvents.Add(new TextEvent(track, deltaTime, absTime, marker, MetaEventType.MarkerText));
                                            Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), marker, br.BaseStream.Position));
                                            break;

                                        case MetaEventType.CuePoint:
                                            string cuePoint = Encoding.ASCII.GetString(br.ReadBytes(lenData1));
                                            metaEvents.Add(new TextEvent(track, deltaTime, absTime, cuePoint, MetaEventType.CuePoint));
                                            Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), cuePoint, br.BaseStream.Position));
                                            break;

                                        case MetaEventType.MidiChannelPrefix:
                                            if (lenData1 == 1)
                                            {
                                                byte channel = br.ReadByte();
                                                metaEvents.Add(new MidiChannelPrefixEvent(track, deltaTime, absTime, channel));
                                                Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), channel, br.BaseStream.Position));
                                            }
                                            else
                                            {
                                                Utils.PrintDebug("Could not read MIDI file - invalid MIDIChannelPrefix meta event (Position: " + br.BaseStream.Position + ")");
                                                throw new FormatException("Could not read MIDI file - invalid MIDIChannelPrefix meta event (Position: " + br.BaseStream.Position + ")");
                                            }
                                            break;

                                        case MetaEventType.EndOfTrack:
                                            if (lenData1 == 0)
                                            {
                                                metaEvents.Add(new EndOfTrackEvent(track, deltaTime, absTime));
                                                Utils.PrintDebug(string.Format("META: {0} {1}", metaCode.ToString(), br.BaseStream.Position));
                                            }
                                            else
                                            {
                                                Utils.PrintDebug("Could not read MIDI file - invalid EndOfTrack meta event (Position: " + br.BaseStream.Position + ")");
                                                throw new FormatException("Could not read MIDI file - invalid EndOfTrack meta event (Position: " + br.BaseStream.Position + ")");
                                            }
                                            break;

                                        case MetaEventType.SetTempo:
                                            if (lenData1 == 3)
                                            {
                                                uint tempo = (uint)((br.ReadByte() << 16) + (br.ReadByte() << 8) + br.ReadByte());
                                                metaEvents.Add(new SetTempoEvent(track, deltaTime, absTime, tempo));
                                                Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), tempo, br.BaseStream.Position));
                                            }
                                            else
                                            {
                                                Utils.PrintDebug("Could not read MIDI file - invalid SetTempo meta event (Position: " + br.BaseStream.Position + ")");
                                                throw new FormatException("Could not read MIDI file - invalid SetTempo meta event (Position: " + br.BaseStream.Position + ")");
                                            }
                                            break;

                                        case MetaEventType.SMPTEOffset:
                                            if (lenData1 == 5)
                                            {
                                                byte  hour          = br.ReadByte();
                                                byte  frameRateCode = (byte)(hour & 0xC0);
                                                float frameRate     = 24F;
                                                switch (frameRateCode)
                                                {
                                                case 0:             // 24
                                                    frameRate = 24F;
                                                    break;

                                                case 1:             // 25
                                                    frameRate = 25F;
                                                    break;

                                                case 2:             // 'Drop' 30
                                                    frameRate = 29.97F;
                                                    break;

                                                case 3:             // 30
                                                    frameRate = 30F;
                                                    break;
                                                }
                                                hour = (byte)(hour & 0x3F);
                                                byte minute   = br.ReadByte();
                                                byte second   = br.ReadByte();
                                                byte frame    = br.ReadByte();
                                                byte subFrame = br.ReadByte();
                                                metaEvents.Add(new SMPTEOffsetEvent(track, deltaTime, absTime, frameRate, hour, minute, second, frame, subFrame));
                                                Utils.PrintDebug(string.Format("META: SMPTEOffset {0} {1} {2} {3} {4} {5} {6}", frameRate, hour, minute, second, frame, subFrame, br.BaseStream.Position));
                                            }
                                            else
                                            {
                                                Utils.PrintDebug("Could not read MIDI file - invalid SMPTEOffset meta event (Position: " + br.BaseStream.Position + ")");
                                                throw new FormatException("Could not read MIDI file - invalid SMPTEOffset meta event (Position: " + br.BaseStream.Position + ")");
                                            }
                                            break;

                                        case MetaEventType.TimeSignature:
                                            if (lenData1 == 4)
                                            {
                                                byte numerator             = br.ReadByte();
                                                byte denominator           = (byte)Math.Pow(br.ReadByte(), 2);
                                                byte ticksPerQuarterNote   = br.ReadByte();
                                                byte ticksPerQuarter32Note = br.ReadByte();
                                                metaEvents.Add(new TimeSignatureEvent(track, deltaTime, absTime, numerator, denominator, ticksPerQuarterNote, ticksPerQuarter32Note));
                                                Utils.PrintDebug(string.Format("META: {0} {1} {2} {3} {4} {5}", metaCode.ToString(), numerator, denominator, ticksPerQuarterNote, ticksPerQuarter32Note, br.BaseStream.Position));
                                            }
                                            else
                                            {
                                                Utils.PrintDebug("Could not read MIDI file - invalid TimeSignature meta event (Position: " + br.BaseStream.Position + ")");
                                                throw new FormatException("Could not read MIDI file - invalid TimeSignature meta event (Position: " + br.BaseStream.Position + ")");
                                            }
                                            break;

                                        case MetaEventType.KeySignature:
                                            if (lenData1 == 2)
                                            {
                                                sbyte key    = br.ReadSByte();
                                                byte  flats  = (byte)key;
                                                byte  sharps = 0;
                                                if (key < 0)
                                                {
                                                    flats  = 0;
                                                    sharps = (byte)(key * -1);
                                                }
                                                bool minor = Convert.ToBoolean(br.ReadByte());
                                                metaEvents.Add(new KeySignatureEvent(track, deltaTime, absTime, key, minor));
                                                Utils.PrintDebug(string.Format("META: {0} {1} {2} {3} {4} {5}", metaCode.ToString(), key, sharps, flats, minor, br.BaseStream.Position));
                                            }
                                            else
                                            {
                                                Utils.PrintDebug("Could not read MIDI file - invalid KeySignature meta event (Position: " + br.BaseStream.Position + ")");
                                                throw new FormatException("Could not read MIDI file - invalid KeySignature meta event (Position: " + br.BaseStream.Position + ")");
                                            }
                                            break;

                                        default:
                                            byte[] data = br.ReadBytes(lenData1);
                                            Utils.PrintDebug(string.Format("META: {0} {1}", metaCode.ToString(), br.BaseStream.Position));
                                            break;
                                        }
                                        break;

                                    default:     // MIDI Event
                                        // Get first half of first byte
                                        byte first = (byte)((eventHeader & 0xF0) >> 4);
                                        // Get second half of first byte
                                        byte last = (byte)(eventHeader & 0x0F);

                                        if (first == 0xF)                   // System Message
                                        {
                                            if (last == 0x0 || last == 0x7) // Sysex Event
                                            {
                                                byte[] data = br.ReadBytes((int)Utils.ReadVariableLengthUint(br));
                                                metaEvents.Add(new SysExEvent(track, deltaTime, absTime, data));
                                                Utils.PrintDebug(string.Format("SYSEX: {0}", br.BaseStream.Position));
                                            }
                                            else
                                            {
                                                Utils.PrintDebug("System messages are not supported (Position: " + br.BaseStream.Position + ")");
                                                throw new NotImplementedException("System messages are not supported (Position: " + br.BaseStream.Position + ")");
                                            }
                                        }
                                        else     // Standard Midi Event
                                        {
                                            // Get event data, assume status has been carried for now

                                            // Get type of MIDI event
                                            MidiEventType eventType = (MidiEventType)((statusOld & 0xF0) >> 4);
                                            // Get channel of MIDI event
                                            byte channel = (byte)(eventHeader & 0x0F);
                                            // Indicates that old data is being used
                                            bool usingOld = true;

                                            if (Enum.IsDefined(typeof(MidiEventType), first))     // New status code
                                            {
                                                // Use new status values
                                                eventType = (MidiEventType)first;
                                                channel   = last;
                                                usingOld  = false;
                                                statusOld = eventHeader;     // Update temporary status record
                                            }

                                            // Get event specific data
                                            switch (eventType)
                                            {
                                            case MidiEventType.NoteOff:
                                                byte key1 = eventHeader;
                                                if (!usingOld)
                                                {
                                                    key1 = br.ReadByte();
                                                }
                                                byte vel1 = br.ReadByte();
                                                midiEvents.Add(new NoteOffEvent(channel, track, deltaTime, absTime, key1, vel1));
                                                Utils.PrintDebug(string.Format("MIDI: {0} {1} {2} {3}", eventType.ToString(), key1, vel1, br.BaseStream.Position));
                                                break;

                                            case MidiEventType.NoteOn:
                                                byte key2 = eventHeader;
                                                if (!usingOld)
                                                {
                                                    key2 = br.ReadByte();
                                                }
                                                byte vel2 = br.ReadByte();
                                                midiEvents.Add(new NoteOnEvent(channel, track, deltaTime, absTime, key2, vel2));
                                                Utils.PrintDebug(string.Format("MIDI: {0} {1} {2} {3}", eventType.ToString(), key2, vel2, br.BaseStream.Position));
                                                break;

                                            case MidiEventType.PolyphonicKeyPressure:
                                                byte key3 = eventHeader;
                                                if (!usingOld)
                                                {
                                                    key3 = br.ReadByte();
                                                }
                                                byte vel3 = br.ReadByte();
                                                midiEvents.Add(new PolyphonicKeyPressureEvent(channel, track, deltaTime, absTime, key3, vel3));
                                                Utils.PrintDebug(string.Format("MIDI: {0} {1} {2} {3}", eventType.ToString(), key3, vel3, br.BaseStream.Position));
                                                break;

                                            case MidiEventType.ControlChange:
                                                byte controller = eventHeader;
                                                if (!usingOld)
                                                {
                                                    controller = br.ReadByte();
                                                }
                                                byte value = br.ReadByte();
                                                midiEvents.Add(new ControlChangeEvent(channel, track, deltaTime, absTime, controller, value));
                                                Utils.PrintDebug(string.Format("MIDI: {0} {1} {2} {3}", eventType.ToString(), controller, value, br.BaseStream.Position));
                                                break;

                                            case MidiEventType.InstrumentChange:
                                                byte patch = eventHeader;
                                                if (!usingOld)
                                                {
                                                    patch = br.ReadByte();
                                                }
                                                midiEvents.Add(new InstrumentChangeEvent(channel, track, deltaTime, absTime, patch));
                                                Utils.PrintDebug(string.Format("MIDI: {0} {1} {2}", eventType.ToString(), patch, br.BaseStream.Position));
                                                break;

                                            case MidiEventType.ChannelPressure:
                                                byte pressure = eventHeader;
                                                if (!usingOld)
                                                {
                                                    pressure = br.ReadByte();
                                                }
                                                midiEvents.Add(new ChannelPressureEvent(channel, track, deltaTime, absTime, pressure));
                                                Utils.PrintDebug(string.Format("MIDI: {0} {1} {2}", eventType.ToString(), pressure, br.BaseStream.Position));
                                                break;

                                            case MidiEventType.PitchWeelChange:
                                                byte p1 = eventHeader;
                                                if (!usingOld)
                                                {
                                                    p1 = br.ReadByte();
                                                }
                                                byte   p2    = br.ReadByte();
                                                ushort pitch = (ushort)((p2 << 8) + p1);
                                                midiEvents.Add(new PitchWheelChangeEvent(channel, track, deltaTime, absTime, pitch));
                                                Utils.PrintDebug(string.Format("MIDI: {0} {1} {2}", eventType.ToString(), pitch, br.BaseStream.Position));
                                                break;
                                            }
                                        }
                                        break;
                                    }
                                    track++;
                                }

                                tracks.Add(new TrackChunk(metaEvents.ToArray(), midiEvents.ToArray()));
                            }
                            else
                            {
                                // Unrecognised track chunk
                                Utils.PrintDebug("Could not read MIDI file - invalid chunk");
                                throw new FormatException("Could not read MIDI file - invalid chunk");
                            }
                        }

                        // Update public tracks
                        this.tracks = tracks.ToArray();

                        Utils.PrintDebug("-----------------\r\nLoad Complete\r\n-----------------");
                    }
                    else
                    {
                        // Header chunk was not 6 bytes long
                        Utils.PrintDebug("Could not read MIDI file - unexpected header chunk length");
                        throw new FormatException("Could not read MIDI file - unexpected header chunk length");
                    }
                }
                else
                {
                    // Header cunk missing / corrupted
                    Utils.PrintDebug("Could not read MIDI file - header chunk missing");
                    throw new FormatException("Could not read MIDI file - header chunk missing");
                }
            }
        }
コード例 #15
0
        public void ConvertFromBinary(System.IO.BinaryReader reader)
        {
            this.ChunkSize = UtilBinary.ReadUintValue(reader);

            ChannelEventType lastChannelEventType    = 0;// = ChannelEventType.Unknown;
            byte             lastChannelEventChannel = 0;

            while (true)
            {
                //Debug.WriteLine(reader.BaseStream.Position);

                uint deltaTicks     = UtilBinary.ReadVariableLengthValue(reader);
                byte trackEventType = UtilBinary.ReadByteValue(reader);

                if (trackEventType == (byte)0xFF)
                {
                    //Debug.WriteLine("*****************Meta Event********************");

                    MetaEventType metaEventType = (MetaEventType)UtilBinary.ReadByteValue(reader);

                    //Debug.WriteLine(metaEventType);

                    int lengthOfMetaData = 0;

                    //meta event
                    switch (metaEventType)
                    {
                    case MetaEventType.SequenceNumber:
                        UtilBinary.ReadByteValue(reader);
                        this.SequenceNumber = new SequenceNumberEvent(UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader));
                        break;

                    case MetaEventType.TextEvent:
                        lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader);
                        this.Comments    = new TextEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData)));
                        //Debug.WriteLine(this.Comments.Text);
                        break;

                    case MetaEventType.CopyrightNotice:
                        lengthOfMetaData     = (int)UtilBinary.ReadVariableLengthValue(reader);
                        this.CopyrightNotice = new CopyrightNoticeEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData)));
                        //Debug.WriteLine(this.CopyrightNotice.Text);
                        break;

                    case MetaEventType.TrackName:
                        lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader);
                        this.TrackName   = new TrackNameEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData)));
                        //Debug.WriteLine(this.TrackName.Text);
                        break;

                    case MetaEventType.InstrumentName:
                        lengthOfMetaData    = (int)UtilBinary.ReadVariableLengthValue(reader);
                        this.InstrumentName = new InstrumentNameEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData)));
                        //Debug.WriteLine(this.InstrumentName.Text);
                        break;

                    case MetaEventType.Lyrics:
                        lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader);
                        this.Lyrics      = new LyricsEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData)));
                        //Debug.WriteLine(this.Lyrics.Text);
                        break;

                    case MetaEventType.Marker:
                        lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader);
                        this.Marker      = new MarkerEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData)));
                        //Debug.WriteLine(this.Marker.Text);
                        break;

                    case MetaEventType.CuePoint:
                        lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader);
                        this.CuePoint    = new CuePointEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData)));
                        //Debug.WriteLine(this.CuePoint.Text);
                        break;

                    case MetaEventType.DeviceName:
                        lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader);
                        this.DeviceName  = new DeviceNameEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData)));
                        //Debug.WriteLine(this.DeviceName.Text);
                        break;

                    case MetaEventType.MidiChannel:
                        UtilBinary.ReadByteValue(reader);
                        this.Channel = new MidiChannelEvent(UtilBinary.ReadByteValue(reader));
                        //Debug.WriteLine(this.Channel.Channel);
                        break;

                    case MetaEventType.MidiPort:
                        UtilBinary.ReadByteValue(reader);
                        this.Port = new MidiPortEvent(UtilBinary.ReadByteValue(reader));
                        break;

                    case MetaEventType.EndOfTrack:
                        UtilBinary.ReadByteValue(reader);
                        //this.EndOfTrack = new EndOfTrackEvent();
                        //this.EndOfTrack.DeltaTicks = deltaTicks;
                        //Debug.WriteLine(this.EndOfTrack.ToString());
                        return;

                        break;

                    case MetaEventType.Tempo:
                        UtilBinary.ReadByteValue(reader);
                        uint microSecondsPerQuarterNote = UtilBinary.Read3ByteInteger(reader);
                        this.Tempo = new TempoEvent(microSecondsPerQuarterNote, this.TimeSignature.Denominator);
                        break;

                    case MetaEventType.SMPTEOffSet:
                        UtilBinary.ReadByteValue(reader);
                        this.SMPTEOffSet = new SMPTEOffSetEvent(UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader));
                        break;

                    case MetaEventType.TimeSignature:
                        UtilBinary.ReadByteValue(reader);
                        this.TimeSignature                   = new TimeSignatureEvent();
                        this.TimeSignature.Numerator         = UtilBinary.ReadByteValue(reader);
                        this.TimeSignature.Denominator       = (byte)Math.Pow(2, UtilBinary.ReadByteValue(reader));
                        this.TimeSignature.MetronomePulse    = UtilBinary.ReadByteValue(reader);
                        this.TimeSignature.ThirtySecondNotes = UtilBinary.ReadByteValue(reader);
                        //Debug.WriteLine(this.TimeSignature.ToString());
                        //this.Tempo = new TempoEvent(this.Tempo.MicroSecondsPerQuarterNote, this.TimeSignature.Denominator);
                        break;

                    case MetaEventType.KeySignature:
                        UtilBinary.ReadByteValue(reader);
                        this.KeySignature = new KeySignatureEvent(UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader));
                        break;

                    case MetaEventType.SequencerSpecific:
                        throw new NotImplementedException();
                        break;

                    default:
                        break;
                    }
                }
                else
                {
                    //Debug.WriteLine("---------------------");
                    //Debug.WriteLine(deltaTime);

                    //Debug.WriteLine(UtilBinary.ReadByteValue(reader));
                    //Debug.WriteLine(UtilBinary.ReadByteValue(reader));
                    //Debug.WriteLine(UtilBinary.ReadByteValue(reader));

                    ChannelMidiEvent chan = new ChannelMidiEvent();

                    chan.DeltaTicks = deltaTicks;
                    chan.File       = this.File;

                    byte[] typeAndChannelBytes = UtilBinary.SplitByte(trackEventType);
                    byte   typeOrData          = typeAndChannelBytes[0];

                    if (Enum.IsDefined(typeof(ChannelEventType), typeOrData))
                    {
                        chan.Type            = (ChannelEventType)typeOrData;
                        lastChannelEventType = chan.Type;

                        chan.Channel            = typeAndChannelBytes[1];
                        lastChannelEventChannel = chan.Channel;

                        chan.Parameter1 = UtilBinary.ReadByteValue(reader);
                        chan.Parameter2 = UtilBinary.ReadByteValue(reader);
                    }
                    else
                    {
                        chan.Type       = lastChannelEventType;
                        chan.Channel    = lastChannelEventChannel;
                        chan.Parameter1 = trackEventType;
                        chan.Parameter2 = UtilBinary.ReadByteValue(reader);
                    }

                    if (chan.Type == ChannelEventType.NoteOn && chan.Parameter2 == 0)
                    {
                        chan.Type = ChannelEventType.NoteOff;
                    }

                    //Debug.WriteLine(chan.Type.ToString());
                    //Debug.WriteLine(chan.Channel.ToString());

                    //this.File.Tracks[(int)chan.Channel].ChannelEvents.Add(chan);
                    this.ChannelEvents.Add(chan);

                    //Debug.Write(chan.ToString());
                }
            }
        }
コード例 #16
0
 public static string GetMetaString(MetaEventType value)
 {
     return(Enum.GetName(typeof(MetaEventType), value));
 }
コード例 #17
0
 /// <summary>
 /// Initialises the <see cref="MetaEvent"/> instance.
 /// </summary>
 /// <param name="track">The track of the event.</param>
 /// <param name="deltaTime">The delta time of the event.</param>
 /// <param name="absoluteTime">The absolute time of the event.</param>
 /// <param name="type">The type of the event.</param>
 protected void Init(uint track, uint deltaTime, uint absoluteTime, MetaEventType type)
 {
     Init(track, deltaTime, absoluteTime);
     this.type = type;
 }
コード例 #18
0
 /// <summary>
 ///  Creates a meta event with raw data
 /// </summary>
 //public RawMetaEvent(MetaEventType metaEventType, long absoluteTime, byte[] data) : base(metaEventType, data?.Length ?? 0, absoluteTime)
 public RawMetaEvent(MetaEventType metaEventType, long absoluteTime, byte[] data) : base(metaEventType, (data == null ? 0: data.Length), absoluteTime)
 {
     Data = data;
 }
コード例 #19
0
 /// <summary>
 /// Custom constructor for use by derived types, who will manage the data themselves
 /// </summary>
 /// <param name="metaEventType">Meta event type</param>
 /// <param name="metaDataLength">Meta data length</param>
 /// <param name="absoluteTime">Absolute time</param>
 public MetaEvent(MetaEventType metaEventType, int metaDataLength, long absoluteTime)
     : base(absoluteTime,1,MidiCommandCode.MetaEvent)
 {
     this.metaEvent = metaEventType;
     this.metaDataLength = metaDataLength;
 }
コード例 #20
0
ファイル: TextEvent.cs プロジェクト: ed-cooper/ReadMIDI
 /// <summary>
 /// Creates a new instance of the <see cref="TextEvent"/> class using the specified text and type.
 /// </summary>
 /// <param name="track">The track of the event.</param>
 /// <param name="deltaTime">The delta time of the event.</param>
 /// <param name="absoluteTime">The absolute time of the event.</param>
 /// <param name="text">The text.</param>
 /// <param name="type">The type of the event.</param>
 internal TextEvent(uint track, uint deltaTime, uint absoluteTime, string text, MetaEventType type)
 {
     Init(track, deltaTime, absoluteTime, type);
     this.text = text;
 }
コード例 #21
0
 /// <summary>
 /// Creates a new TextEvent
 /// </summary>
 /// <param name="text">The text in this type</param>
 /// <param name="metaEventType">MetaEvent type (must be one that is
 /// associated with text data)</param>
 /// <param name="absoluteTime">Absolute time of this event</param>
 public TextEvent(string text, MetaEventType metaEventType, long absoluteTime)
     : base(metaEventType, text.Length, absoluteTime)
 {
     this.text = text;
 }
コード例 #22
0
        /// <summary>
        /// Reads a meta-event from a stream
        /// </summary>
        /// <param name="br">A binary reader based on the stream of MIDI data</param>
        /// <returns>A new MetaEvent object</returns>
        public static MetaEvent ReadMetaEvent(BinaryReader br)
        {
            MetaEventType metaEvent = (MetaEventType)br.ReadByte();
            int           length    = ReadVarInt(br);

            MetaEvent me = new MetaEvent();

            switch (metaEvent)
            {
            case MetaEventType.TrackSequenceNumber:                     // Sets the track's sequence number.
                me = new TrackSequenceNumberEvent(br, length);
                break;

            case MetaEventType.TextEvent:                 // Text event
            case MetaEventType.Copyright:                 // Copyright
            case MetaEventType.SequenceTrackName:         // Sequence / Track Name
            case MetaEventType.TrackInstrumentName:       // Track instrument name
            case MetaEventType.Lyric:                     // lyric
            case MetaEventType.Marker:                    // marker
            case MetaEventType.CuePoint:                  // cue point
            case MetaEventType.ProgramName:
            case MetaEventType.DeviceName:
                me = new TextEvent(br, length);
                break;

            case MetaEventType.EndTrack:                     // This event must come at the end of each track
                if (length != 0)
                {
                    throw new FormatException("End track length");
                }
                break;

            case MetaEventType.SetTempo:                     // Set tempo
                me = new TempoEvent(br, length);
                break;

            case MetaEventType.TimeSignature:                     // Time signature
                me = new TimeSignatureEvent(br, length);
                break;

            case MetaEventType.KeySignature:                     // Key signature
                me = new KeySignatureEvent(br, length);
                break;

            case MetaEventType.SequencerSpecific:                     // Sequencer specific information
                me = new SequencerSpecificEvent(br, length);
                break;

            case MetaEventType.SmpteOffset:
                me = new SmpteOffsetEvent(br, length);
                break;

            default:
                me.data = br.ReadBytes(length);
                if (me.data.Length != length)
                {
                    throw new FormatException("Failed to read metaevent's data fully");
                }
                break;
            }
            me.metaEvent      = metaEvent;
            me.metaDataLength = length;

            return(me);
        }