Ejemplo n.º 1
0
        public static short ReadInt16LE(this IReadable input)
        {
            var ch1 = input.ReadByte();
            var ch2 = input.ReadByte();

            return(Platform.ToInt16((ch2 << 8) | ch1));
        }
Ejemplo n.º 2
0
        public static ushort ReadUInt16BE(this IReadable input)
        {
            var ch1 = input.ReadByte();
            var ch2 = input.ReadByte();

            return(Platform.Platform.ToUInt16((ch1 << 8) | (ch2 << 0)));
        }
Ejemplo n.º 3
0
        private static MidiEvent ReadVoiceMessage(IReadable input, int delta, byte status, byte data1)
        {
            switch ((MidiEventTypeEnum)(status & 0xF0))
            {
            case MidiEventTypeEnum.NoteOff:
                return(new MidiEvent(delta, status, data1, (byte)input.ReadByte()));

            case MidiEventTypeEnum.NoteOn:
                var velocity = input.ReadByte();
                if (velocity == 0)
                {
                    status = (byte)((status & 0x0F) | 0x80);
                }
                return(new MidiEvent(delta, status, data1, (byte)velocity));

            case MidiEventTypeEnum.NoteAftertouch:
                return(new MidiEvent(delta, status, data1, (byte)input.ReadByte()));

            case MidiEventTypeEnum.Controller:
                return(new MidiEvent(delta, status, data1, (byte)input.ReadByte()));

            case MidiEventTypeEnum.ProgramChange:
                return(new MidiEvent(delta, status, data1, 0));

            case MidiEventTypeEnum.ChannelAftertouch:
                return(new MidiEvent(delta, status, data1, 0));

            case MidiEventTypeEnum.PitchBend:
                return(new MidiEvent(delta, status, data1, (byte)input.ReadByte()));

            default:
                throw new Exception("The status provided was not that of a voice message.");
            }
        }
Ejemplo n.º 4
0
        public static short ReadInt16BE(this IReadable input)
        {
            var ch1 = input.ReadByte();
            var ch2 = input.ReadByte();

            return(TypeUtils.ToInt16((ch1 << 8) | (ch2 << 0)));
        }
Ejemplo n.º 5
0
        public SoundFontSampleData(IReadable input)
        {
            var id = input.Read8BitChars(4);
            var size = input.ReadInt32LE();
            if (id.ToLower() != "list")
                throw new Exception("Invalid soundfont. Could not find sdta LIST chunk.");
            var readTo = input.Position + size;
            id = input.Read8BitChars(4);
            if (id.ToLower() != "sdta")
                throw new Exception("Invalid soundfont. The LIST chunk is not of type sdta.");

            BitsPerSample = 0;
            byte[] rawSampleData = null;
            while (input.Position < readTo)
            {
                var subID = input.Read8BitChars(4);
                size = input.ReadInt32LE();
                switch (subID.ToLower())
                {
                    case "smpl":
                        BitsPerSample = 16;
                        rawSampleData = input.ReadByteArray(size);
                        break;
                    case "sm24":
                        if (rawSampleData == null || size != Math.Ceiling(SampleData.Length / 2.0))
                        {//ignore this chunk if wrong size or if it comes first
                            input.Skip(size);
                        }
                        else
                        {
                            BitsPerSample = 24;
                            for (var x = 0; x < SampleData.Length; x++)
                            {
                                var b = new byte[3];
                                b[0] = (byte)input.ReadByte();
                                b[1] = rawSampleData[2 * x];
                                b[2] = rawSampleData[2 * x + 1];
                            }
                        }
                        if (size % 2 == 1)
                        {
                            if (input.ReadByte() != 0)
                            {
                                input.Position--;
                            }
                        }
                        break;
                    default:
                        throw new Exception("Invalid soundfont. Unknown chunk id: " + subID + ".");
                }
            }

            if (BitsPerSample == 16)
            {
                SampleData = rawSampleData;
            }
            else if (BitsPerSample != 24)
                throw new Exception("Only 16 and 24 bit samples are supported.");

        }
Ejemplo n.º 6
0
        public static uint ReadUInt32(this IReadable input)
        {
            var ch1 = input.ReadByte();
            var ch2 = input.ReadByte();
            var ch3 = input.ReadByte();
            var ch4 = input.ReadByte();

            return(TypeUtils.ToUInt32((ch1 << 24) | (ch2 << 16) | (ch3 << 8) | (ch4 << 0)));
        }
Ejemplo n.º 7
0
        public static int ReadInt32LE(this IReadable input)
        {
            var ch1 = input.ReadByte();
            var ch2 = input.ReadByte();
            var ch3 = input.ReadByte();
            var ch4 = input.ReadByte();

            return((ch4 << 24) | (ch3 << 16) | (ch2 << 8) | (ch1 << 0));
        }
Ejemplo n.º 8
0
        public static uint ReadUInt32LE(this IReadable input)
        {
            var ch1 = input.ReadByte();
            var ch2 = input.ReadByte();
            var ch3 = input.ReadByte();
            var ch4 = input.ReadByte();

            return(Platform.ToUInt32((ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1));
        }
Ejemplo n.º 9
0
        public static float GpReadFloat(this IReadable data)
        {
            var bytes = new byte[4];

            bytes[3] = (byte)data.ReadByte();
            bytes[2] = (byte)data.ReadByte();
            bytes[2] = (byte)data.ReadByte();
            bytes[1] = (byte)data.ReadByte();
            return(Platform.Platform.ToFloat(bytes));
        }
Ejemplo n.º 10
0
        public static string Read8BitString(this IReadable input)
        {
            var s = new StringBuilder();
            var c = input.ReadByte();

            while (c != 0)
            {
                s.AppendChar(c);
                c = input.ReadByte();
            }
            return(s.ToString());
        }
Ejemplo n.º 11
0
 public SampleHeader(IReadable input)
 {
     Name                = input.Read8BitStringLength(20);
     Start               = input.ReadInt32LE();
     End                 = input.ReadInt32LE();
     StartLoop           = input.ReadInt32LE();
     EndLoop             = input.ReadInt32LE();
     SampleRate          = input.ReadInt32LE();
     RootKey             = (byte)input.ReadByte();
     Tune                = Platform.Platform.ToInt16(input.ReadByte());
     SampleLink          = input.ReadUInt16LE();
     SoundFontSampleLink = (SFSampleLink)input.ReadUInt16LE();
 }
Ejemplo n.º 12
0
 public SampleHeader(IReadable input)
 {
     Name = input.Read8BitStringLength(20);
     Start = input.ReadInt32LE();
     End = input.ReadInt32LE();
     StartLoop = input.ReadInt32LE();
     EndLoop = input.ReadInt32LE();
     SampleRate = input.ReadInt32LE();
     RootKey = (byte) input.ReadByte();
     Tune = TypeUtils.ToInt16(input.ReadByte());
     SampleLink = input.ReadUInt16LE();
     SoundFontSampleLink = (SFSampleLink) input.ReadUInt16LE();
 }
Ejemplo n.º 13
0
        public static string Read8BitStringLength(this IReadable input, int length)
        {
            var s = new StringBuilder();
            var z = -1;

            for (var i = 0; i < length; i++)
            {
                var c = input.ReadByte();
                if (c == 0 && z == -1)
                {
                    z = i;
                }

                s.AppendChar(c);
            }

            var t = s.ToString();

            if (z >= 0)
            {
                return(t.Substring(0, z));
            }

            return(t);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Reads an integer as size, skips a byte and reads the string itself
        /// </summary>
        /// <returns></returns>
        public static string GpReadStringIntByte(this IReadable data)
        {
            var length = data.ReadInt32LE() - 1;

            data.ReadByte();
            return(data.GpReadString(length));
        }
Ejemplo n.º 15
0
        private bool FindHead(IReadable input, int attempts)
        {
            var match = 0;

            while (attempts > 0)
            {
                switch (input.ReadByte())
                {
                case (int)'M':
                    match = 1;
                    break;

                case (int)'T':
                    match = match == 1 ? 2 : 0;
                    break;

                case (int)'h':
                    match = match == 2 ? 3 : 0;
                    break;

                case (int)'d':
                    if (match == 3)
                    {
                        return(true);
                    }
                    match = 0;
                    break;
                }
                attempts--;
            }
            return(false);
        }
Ejemplo n.º 16
0
        public static Color GpReadColor(this IReadable data, bool readAlpha = false)
        {
            byte r = (byte)data.ReadByte();
            byte g = (byte)data.ReadByte();
            byte b = (byte)data.ReadByte();
            byte a = 255;

            if (readAlpha)
            {
                a = (byte)data.ReadByte();
            }
            else
            {
                data.Skip(1);
            }
            return(new Color(r, g, b, a));
        }
Ejemplo n.º 17
0
        public static string Read8BitChars(this IReadable input, int length)
        {
            var s = new StringBuilder();

            for (int i = 0; i < length; i++)
            {
                s.AppendChar(input.ReadByte());
            }
            return(s.ToString());
        }
Ejemplo n.º 18
0
        public static sbyte ReadSignedByte(this IReadable readable)
        {
            var n = readable.ReadByte();

            if (n >= 128)
            {
                return((sbyte)(n - 256));
            }
            return((sbyte)n);
        }
Ejemplo n.º 19
0
        private static MidiEvent ReadSystemCommonMessage(IReadable input, int delta, byte status)
        {
            switch ((SystemCommonTypeEnum)status)
            {
            case SystemCommonTypeEnum.SystemExclusive2:
            case SystemCommonTypeEnum.SystemExclusive:
            {
                var maker = input.ReadInt16BE();
                if (maker == 0x0)
                {
                    maker = input.ReadInt16BE();
                }
                else if (maker == 0xF7)
                {
                    return(null);
                }
                var data = new FastList <byte>();
                var b    = input.ReadByte();
                while (b != 0xF7)
                {
                    data.Add((byte)b);
                    b = input.ReadByte();
                }
                return(new SystemExclusiveEvent(delta, status, maker, data.ToArray()));
            }

            case SystemCommonTypeEnum.MtcQuarterFrame:
                return(new SystemCommonEvent(delta, status, (byte)input.ReadByte(), 0));

            case SystemCommonTypeEnum.SongPosition:
                return(new SystemCommonEvent(delta, status, (byte)input.ReadByte(), (byte)input.ReadByte()));

            case SystemCommonTypeEnum.SongSelect:
                return(new SystemCommonEvent(delta, status, (byte)input.ReadByte(), 0));

            case SystemCommonTypeEnum.TuneRequest:
                return(new SystemCommonEvent(delta, status, 0, 0));

            default:
                throw new Exception("The system common message was invalid or unsupported : " + status);
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Reads a byte as size and the string itself.
        /// Additionally it is ensured the specified amount of bytes is read.
        /// </summary>
        /// <param name="data">the data to read from.</param>
        /// <param name="length">the amount of bytes to read</param>
        /// <returns></returns>
        public static string GpReadStringByteLength(this IReadable data, int length)
        {
            var stringLength = data.ReadByte();
            var s            = data.GpReadString(stringLength);

            if (stringLength < length)
            {
                data.Skip(length - stringLength);
            }
            return(s);
        }
Ejemplo n.º 21
0
        private static int ReadVariableLength(IReadable input)
        {
            var value = 0;
            int next;

            do
            {
                next  = input.ReadByte();
                value = value << 7;
                value = value | (next & 0x7F);
            } while ((next & 0x80) == 0x80);
            return(value);
        }
Ejemplo n.º 22
0
        public static HydraShdr Load(IReadable reader)
        {
            var shdr = new HydraShdr();

            shdr.SampleName      = reader.Read8BitStringLength(20);
            shdr.Start           = reader.ReadUInt32LE();
            shdr.End             = reader.ReadUInt32LE();
            shdr.StartLoop       = reader.ReadUInt32LE();
            shdr.EndLoop         = reader.ReadUInt32LE();
            shdr.SampleRate      = reader.ReadUInt32LE();
            shdr.OriginalPitch   = (byte)reader.ReadByte();
            shdr.PitchCorrection = reader.ReadSignedByte();
            shdr.SampleLink      = reader.ReadUInt16LE();
            shdr.SampleType      = reader.ReadUInt16LE();
            return(shdr);
        }
Ejemplo n.º 23
0
        public int ReadBit()
        {
            // need a new byte?
            if (_position >= ByteSize)
            {
                _currentByte = _source.ReadByte();
                if (_currentByte == -1)
                {
                    throw new EndOfReaderException();
                }
                _position = 0;
            }

            // shift the desired byte to the least significant bit and
            // get the value using masking
            var value = (_currentByte >> (ByteSize - _position - 1)) & 0x01;

            _position++;
            return(value);
        }
Ejemplo n.º 24
0
 private static MidiEvent ReadSystemCommonMessage(IReadable input, int delta, byte status)
 {
     switch ((SystemCommonTypeEnum)status)
     {
         case SystemCommonTypeEnum.SystemExclusive2:
         case SystemCommonTypeEnum.SystemExclusive:
             {
                 var maker = input.ReadInt16BE();
                 if (maker == 0x0)
                 {
                     maker = input.ReadInt16BE();
                 }
                 else if (maker == 0xF7)
                     return null;
                 var data = new FastList<byte>();
                 var b = input.ReadByte();
                 while (b != 0xF7)
                 {
                     data.Add((byte)b);
                     b = input.ReadByte();
                 }
                 return new SystemExclusiveEvent(delta, status, maker, data.ToArray());
             }
         case SystemCommonTypeEnum.MtcQuarterFrame:
             return new SystemCommonEvent(delta, status, (byte)input.ReadByte(), 0);
         case SystemCommonTypeEnum.SongPosition:
             return new SystemCommonEvent(delta, status, (byte)input.ReadByte(), (byte)input.ReadByte());
         case SystemCommonTypeEnum.SongSelect:
             return new SystemCommonEvent(delta, status, (byte)input.ReadByte(), 0);
         case SystemCommonTypeEnum.TuneRequest:
             return new SystemCommonEvent(delta, status, 0, 0);
         default:
             throw new Exception("The system common message was invalid or unsupported : " + status);
     }
 }
Ejemplo n.º 25
0
        private static MidiEvent ReadMetaMessage(IReadable input, int delta, byte status)
        {
            var metaStatus = input.ReadByte();

            switch ((MetaEventTypeEnum)metaStatus)
            {
            case MetaEventTypeEnum.SequenceNumber:
            {
                var count = input.ReadByte();
                if (count == 0)
                {
                    return(new MetaNumberEvent(delta, status, (byte)metaStatus, -1));
                }
                else if (count == 2)
                {
                    return(new MetaNumberEvent(delta, status, (byte)metaStatus, input.ReadInt16BE()));
                }
                else
                {
                    throw new Exception("Invalid sequence number event.");
                }
            }

            case MetaEventTypeEnum.TextEvent:
                return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)));

            case MetaEventTypeEnum.CopyrightNotice:
                return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)));

            case MetaEventTypeEnum.SequenceOrTrackName:
                return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)));

            case MetaEventTypeEnum.InstrumentName:
                return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)));

            case MetaEventTypeEnum.LyricText:
                return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)));

            case MetaEventTypeEnum.MarkerText:
                return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)));

            case MetaEventTypeEnum.CuePoint:
                return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)));

            case MetaEventTypeEnum.PatchName:
                return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)));

            case MetaEventTypeEnum.PortName:
                return(new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input)));

            case MetaEventTypeEnum.MidiChannel:
                if (input.ReadByte() != 1)
                {
                    throw new Exception("Invalid midi channel event. Expected size of 1.");
                }
                return(new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte()));

            case MetaEventTypeEnum.MidiPort:
                if (input.ReadByte() != 1)
                {
                    throw new Exception("Invalid midi port event. Expected size of 1.");
                }
                return(new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte()));

            case MetaEventTypeEnum.EndOfTrack:
                return(new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte()));

            case MetaEventTypeEnum.Tempo:
                if (input.ReadByte() != 3)
                {
                    throw new Exception("Invalid tempo event. Expected size of 3.");
                }
                return(new MetaNumberEvent(delta, status, (byte)metaStatus, (input.ReadByte() << 16) | (input.ReadByte() << 8) | input.ReadByte()));

            case MetaEventTypeEnum.SmpteOffset:
                if (input.ReadByte() != 5)
                {
                    throw new Exception("Invalid smpte event. Expected size of 5.");
                }
                return(new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte()));

            case MetaEventTypeEnum.TimeSignature:
                if (input.ReadByte() != 4)
                {
                    throw new Exception("Invalid time signature event. Expected size of 4.");
                }
                return(new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte()));

            case MetaEventTypeEnum.KeySignature:
                if (input.ReadByte() != 2)
                {
                    throw new Exception("Invalid key signature event. Expected size of 2.");
                }
                return(new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte()));

            case MetaEventTypeEnum.SequencerSpecific:
                var length = ReadVariableLength(input);
                var data   = input.ReadByteArray(length);
                return(new MetaDataEvent(delta, status, (byte)metaStatus, data));
            }
            throw new Exception("Not a valid meta message Status: " + status + " Meta: " + metaStatus);
        }
Ejemplo n.º 26
0
        private MidiTrack ReadTrack(IReadable input)
        {
            var instList    = new FastList <Byte>();
            var drumList    = new FastList <Byte>();
            var channelList = new FastList <Byte>();
            var eventList   = new FastList <MidiEvent>();
            var noteOnCount = 0;
            var totalTime   = 0;

            while (input.Read8BitChars(4) != "MTrk")
            {
                var length = input.ReadInt32BE();
                while (length > 0)
                {
                    length--;
                    input.ReadByte();
                }
            }

            var endPosition = input.ReadInt32BE() + input.Position;
            var prevStatus  = 0;

            while (input.Position < endPosition)
            {
                var delta = ReadVariableLength(input);
                totalTime += delta;
                var status = input.ReadByte();
                if (status >= 0x80 && status <= 0xEF)
                {//voice message
                    prevStatus = status;
                    eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte()));
                    noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                }
                else if (status >= 0xF0 && status <= 0xF7)
                {//system common message
                    prevStatus = 0;
                    eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status));
                }
                else if (status >= 0xF8 && status <= 0xFF)
                {//realtime message
                    eventList.Add(ReadRealTimeMessage(input, delta, (byte)status));
                }
                else
                {     //data bytes
                    if (prevStatus == 0)
                    { //if no running status continue to next status byte
                        while ((status & 0x80) != 0x80)
                        {
                            status = input.ReadByte();
                        }
                        if (status >= 0x80 && status <= 0xEF)
                        {//voice message
                            prevStatus = status;
                            eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte()));
                            noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                        }
                        else if (status >= 0xF0 && status <= 0xF7)
                        {//system common message
                            eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status));
                        }
                        else if (status >= 0xF8 && status <= 0xFF)
                        {//realtime message
                            eventList.Add(ReadRealTimeMessage(input, delta, (byte)status));
                        }
                    }
                    else
                    {//otherwise apply running status
                        eventList.Add(ReadVoiceMessage(input, delta, (byte)prevStatus, (byte)status));
                        noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                    }
                }
            }

            if (input.Position != endPosition)
            {
                throw new Exception("The track length was invalid for the current MTrk chunk.");
            }
            if (channelList.IndexOf(MidiHelper.DrumChannel) != -1)
            {
                if (drumList.IndexOf(0) == -1)
                {
                    drumList.Add(0);
                }
            }
            else
            {
                if (instList.IndexOf(0) == -1)
                {
                    instList.Add(0);
                }
            }
            var track = new MidiTrack(instList.ToArray(),
                                      drumList.ToArray(),
                                      channelList.ToArray(),
                                      eventList.ToArray());

            track.NoteOnCount = noteOnCount;
            track.EndTime     = totalTime;
            return(track);
        }
Ejemplo n.º 27
0
 /// <summary>
 ///  Skips an integer (4byte) and reads a string using
 ///  a bytesize
 /// </summary>
 /// <returns></returns>
 public static string GpReadStringIntUnused(this IReadable data)
 {
     data.Skip(4);
     return(data.GpReadString(data.ReadByte()));
 }
Ejemplo n.º 28
0
 private bool FindHead(IReadable input, int attempts)
 {
     var match = 0;
     while (attempts > 0)
     {
         switch (input.ReadByte())
         {
             case (int)'M':
                 match = 1;
                 break;
             case (int)'T':
                 match = match == 1 ? 2 : 0;
                 break;
             case (int)'h':
                 match = match == 2 ? 3 : 0;
                 break;
             case (int)'d':
                 if (match == 3) return true;
                 match = 0;
                 break;
         }
         attempts--;
     }
     return false;
 }
Ejemplo n.º 29
0
 public static bool GpReadBool(this IReadable data)
 {
     return(data.ReadByte() != 0);
 }
Ejemplo n.º 30
0
        public static int ReadSInt8(this IReadable input)
        {
            var v = input.ReadByte();

            return((((v & 255) >> 7) * (-256)) + (v & 255));
        }
Ejemplo n.º 31
0
 private static MidiEvent ReadVoiceMessage(IReadable input, int delta, byte status, byte data1)
 {
     switch ((MidiEventTypeEnum)(status & 0xF0))
     {
         case MidiEventTypeEnum.NoteOff:
             return new MidiEvent(delta, status, data1, (byte)input.ReadByte());
         case MidiEventTypeEnum.NoteOn:
             var velocity = input.ReadByte();
             if (velocity == 0)
                 status = (byte)((status & 0x0F) | 0x80);
             return new MidiEvent(delta, status, data1, (byte)velocity);
         case MidiEventTypeEnum.NoteAftertouch:
             return new MidiEvent(delta, status, data1, (byte)input.ReadByte());
         case MidiEventTypeEnum.Controller:
             return new MidiEvent(delta, status, data1, (byte)input.ReadByte());
         case MidiEventTypeEnum.ProgramChange:
             return new MidiEvent(delta, status, data1, 0);
         case MidiEventTypeEnum.ChannelAftertouch:
             return new MidiEvent(delta, status, data1, 0);
         case MidiEventTypeEnum.PitchBend:
             return new MidiEvent(delta, status, data1, (byte)input.ReadByte());
         default:
             throw new Exception("The status provided was not that of a voice message.");
     }
 }
Ejemplo n.º 32
0
 private static int ReadVariableLength(IReadable input)
 {
     var value = 0;
     int next;
     do
     {
         next = input.ReadByte();
         value = value << 7;
         value = value | (next & 0x7F);
     } while ((next & 0x80) == 0x80);
     return value;
 }
Ejemplo n.º 33
0
 public override HaxeInt ReadByte()
 {
     return(_readable.ReadByte());
 }
Ejemplo n.º 34
0
        public SoundFontSampleData(IReadable input)
        {
            var id   = input.Read8BitChars(4);
            var size = input.ReadInt32LE();

            if (id.ToLower() != "list")
            {
                throw new Exception("Invalid soundfont. Could not find sdta LIST chunk.");
            }
            var readTo = input.Position + size;

            id = input.Read8BitChars(4);
            if (id.ToLower() != "sdta")
            {
                throw new Exception("Invalid soundfont. The LIST chunk is not of type sdta.");
            }

            BitsPerSample = 0;
            byte[] rawSampleData = null;
            while (input.Position < readTo)
            {
                var subID = input.Read8BitChars(4);
                size = input.ReadInt32LE();
                switch (subID.ToLower())
                {
                case "smpl":
                    BitsPerSample = 16;
                    rawSampleData = input.ReadByteArray(size);
                    break;

                case "sm24":
                    if (rawSampleData == null || size != Math.Ceiling(SampleData.Length / 2.0))
                    {    //ignore this chunk if wrong size or if it comes first
                        input.Skip(size);
                    }
                    else
                    {
                        BitsPerSample = 24;
                        for (var x = 0; x < SampleData.Length; x++)
                        {
                            var b = new byte[3];
                            b[0] = (byte)input.ReadByte();
                            b[1] = rawSampleData[2 * x];
                            b[2] = rawSampleData[2 * x + 1];
                        }
                    }
                    if (size % 2 == 1)
                    {
                        if (input.ReadByte() != 0)
                        {
                            input.Position--;
                        }
                    }
                    break;

                default:
                    throw new Exception("Invalid soundfont. Unknown chunk id: " + subID + ".");
                }
            }

            if (BitsPerSample == 16)
            {
                SampleData = rawSampleData;
            }
            else if (BitsPerSample != 24)
            {
                throw new Exception("Only 16 and 24 bit samples are supported.");
            }
        }
Ejemplo n.º 35
0
 private static MidiEvent ReadMetaMessage(IReadable input, int delta, byte status)
 {
     var metaStatus = input.ReadByte();
     switch ((MetaEventTypeEnum)metaStatus)
     {
         case MetaEventTypeEnum.SequenceNumber:
             {
                 var count = input.ReadByte();
                 if (count == 0)
                     return new MetaNumberEvent(delta, status, (byte)metaStatus, -1);
                 else if (count == 2)
                 {
                     return new MetaNumberEvent(delta, status, (byte)metaStatus, input.ReadInt16BE());
                 }
                 else
                     throw new Exception("Invalid sequence number event.");
             }
         case MetaEventTypeEnum.TextEvent:
             return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input));
         case MetaEventTypeEnum.CopyrightNotice:
             return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input));
         case MetaEventTypeEnum.SequenceOrTrackName:
             return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input));
         case MetaEventTypeEnum.InstrumentName:
             return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input));
         case MetaEventTypeEnum.LyricText:
             return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input));
         case MetaEventTypeEnum.MarkerText:
             return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input));
         case MetaEventTypeEnum.CuePoint:
             return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input));
         case MetaEventTypeEnum.PatchName:
             return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input));
         case MetaEventTypeEnum.PortName:
             return new MetaTextEvent(delta, status, (byte)metaStatus, ReadString(input));
         case MetaEventTypeEnum.MidiChannel:
             if (input.ReadByte() != 1)
                 throw new Exception("Invalid midi channel event. Expected size of 1.");
             return new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte());
         case MetaEventTypeEnum.MidiPort:
             if (input.ReadByte() != 1)
                 throw new Exception("Invalid midi port event. Expected size of 1.");
             return new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte());
         case MetaEventTypeEnum.EndOfTrack:
             return new MetaEvent(delta, status, (byte)metaStatus, (byte)input.ReadByte());
         case MetaEventTypeEnum.Tempo:
             if (input.ReadByte() != 3)
                 throw new Exception("Invalid tempo event. Expected size of 3.");
             return new MetaNumberEvent(delta, status, (byte)metaStatus, (input.ReadByte() << 16) | (input.ReadByte() << 8) | input.ReadByte());
         case MetaEventTypeEnum.SmpteOffset:
             if (input.ReadByte() != 5)
                 throw new Exception("Invalid smpte event. Expected size of 5.");
             return new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte());
         case MetaEventTypeEnum.TimeSignature:
             if (input.ReadByte() != 4)
                 throw new Exception("Invalid time signature event. Expected size of 4.");
             return new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte() + ":" + input.ReadByte());
         case MetaEventTypeEnum.KeySignature:
             if (input.ReadByte() != 2)
                 throw new Exception("Invalid key signature event. Expected size of 2.");
             return new MetaTextEvent(delta, status, (byte)metaStatus, input.ReadByte() + ":" + input.ReadByte());
         case MetaEventTypeEnum.SequencerSpecific:
             var length = ReadVariableLength(input);
             var data = input.ReadByteArray(length);
             return new MetaDataEvent(delta, status, (byte)metaStatus, data);
     }
     throw new Exception("Not a valid meta message Status: " + status + " Meta: " + metaStatus);
 }
Ejemplo n.º 36
0
 public static sbyte ReadSignedByte(this IReadable readable)
 {
     return(unchecked ((sbyte)(byte)readable.ReadByte()));
 }
Ejemplo n.º 37
0
        private MidiTrack ReadTrack(IReadable input)
        {
            var instList = new FastList<Byte>();
            var drumList = new FastList<Byte>();
            var channelList = new FastList<Byte>();
            var eventList = new FastList<MidiEvent>();
            var noteOnCount = 0;
            var totalTime = 0;
            while (input.Read8BitChars(4) != "MTrk")
            {
                var length = input.ReadInt32BE();
                while (length > 0)
                {
                    length--;
                    input.ReadByte();
                }
            }

            var endPosition = input.ReadInt32BE() + input.Position;
            var prevStatus = 0;
            while (input.Position < endPosition)
            {
                var delta = ReadVariableLength(input);
                totalTime += delta;
                var status = input.ReadByte();
                if (status >= 0x80 && status <= 0xEF)
                {//voice message
                    prevStatus = status;
                    eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte()));
                    noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                }
                else if (status >= 0xF0 && status <= 0xF7)
                {//system common message
                    prevStatus = 0;
                    eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status));
                }
                else if (status >= 0xF8 && status <= 0xFF)
                {//realtime message
                    eventList.Add(ReadRealTimeMessage(input, delta, (byte)status));
                }
                else
                {//data bytes
                    if (prevStatus == 0)
                    {//if no running status continue to next status byte
                        while ((status & 0x80) != 0x80)
                        {
                            status = input.ReadByte();
                        }
                        if (status >= 0x80 && status <= 0xEF)
                        {//voice message
                            prevStatus = status;
                            eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte()));
                            noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                        }
                        else if (status >= 0xF0 && status <= 0xF7)
                        {//system common message
                            eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status));
                        }
                        else if (status >= 0xF8 && status <= 0xFF)
                        {//realtime message
                            eventList.Add(ReadRealTimeMessage(input, delta, (byte)status));
                        }
                    }
                    else
                    {//otherwise apply running status
                        eventList.Add(ReadVoiceMessage(input, delta, (byte)prevStatus, (byte)status));
                        noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                    }
                }
            }

            if (input.Position != endPosition)
                throw new Exception("The track length was invalid for the current MTrk chunk.");
            if (channelList.IndexOf(MidiHelper.DrumChannel) != -1)
            {
                if (drumList.IndexOf(0) == -1)
                    drumList.Add(0);
            }
            else
            {
                if (instList.IndexOf(0) == -1)
                    instList.Add(0);
            }
            var track = new MidiTrack(instList.ToArray(),
                drumList.ToArray(),
                channelList.ToArray(),
                eventList.ToArray());
            track.NoteOnCount = noteOnCount;
            track.EndTime = totalTime;
            return track;
        }