示例#1
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.");

        }
示例#2
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.");
            }
        }
示例#3
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);
        }
示例#4
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);
 }