Exemplo n.º 1
0
        private static async Task <Tuple <List <Frame>, BitrateType, TimeSpan, UInt32> > CollectSamplesAsync(IBinaryStream stream, UInt32 streamLength, UInt32?amount)
        {
            var samples          = new List <Frame>();
            var bitrateType      = BitrateType.Constant;
            var duration         = new TimeSpan();
            var bitrateSum       = 0U;
            var originalPosition = stream.Position;

            while (stream.Position + 20 < streamLength)
            {
                if (amount.HasValue && (samples.Count == amount.Value))
                {
                    break;
                }

                var possibleFrameHeader = await stream.PeekUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false);

                if ((possibleFrameHeader & 0xFFFE0000) == 0xFFFA0000)
                {
                    var bitrate   = Frame.GetBitrate(possibleFrameHeader);
                    var frequency = Frame.GetFrequency(possibleFrameHeader);
                    var padding   = Frame.GetPadding(possibleFrameHeader);
                    var version   = Frame.GetVersion(possibleFrameHeader);
                    var layer     = Frame.GetLayer(possibleFrameHeader);
                    if ((bitrate != 0) && (frequency != 0))
                    {
                        var frame = new Frame(stream.Position, version, layer, bitrate, frequency, padding);
                        if (samples.Count == 0)
                        {
                            var firstFrameContent = await stream.ReadAsync(frame.Length).ConfigureAwait(false);

                            bitrateType = firstFrameContent.IndexOf("Xing").HasValue ? BitrateType.Variable : BitrateType.Constant;
                        }
                        else
                        {
                            stream.Position += frame.Length;
                            duration        += frame.Duration;
                            bitrateSum      += frame.Bitrate;
                        }
                        samples.Add(frame);
                        continue;
                    }
                }

                // this situation means that we've read some samples and haven't found valid sample right after the last valid sample
                // and it means that the file in wrong format, corrupted or we've found all samples.
                if (samples.Count > 0)
                {
                    break;
                }

                stream.Position += 1;
                if (stream.Position - originalPosition > 1024)
                {
                    break;
                }
            }
            return(new Tuple <List <Frame>, BitrateType, TimeSpan, UInt32>(samples, bitrateType, duration, (samples.Count > 0) ? (UInt32)(bitrateSum / samples.Count) : 0));
        }
Exemplo n.º 2
0
        public static async Task <UInt32> ReadUInt32Async(this IBinaryStream stream, ByteOrder byteOrder)
        {
            var buffer = await stream.ReadAsync(4).ConfigureAwait(false);

            var value = 0U;

            for (var i = 0; i < 4; i++)
            {
                value |= (UInt32)buffer[i] << 8 * ((byteOrder == ByteOrder.BigEndian) ? (3 - i) : i);
            }
            return(value);
        }
Exemplo n.º 3
0
        public static async Task <XingFrame> CreateAsync(IBinaryStream stream, Frame frame)
        {
            var position = stream.Position;

            stream.Position = frame.Offset;
            var data = await stream.ReadAsync(40).ConfigureAwait(false);

            var index = data.IndexOf("Xing");

            stream.Position = frame.Offset + index.Value + 4;

            var framesCount = (UInt32?)null;
            var bytesCount  = (UInt32?)null;
            var toc         = (Byte[])null;
            var quality     = (UInt32?)null;
            var flags       = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false);

            if ((flags & 0x01) > 0)
            {
                framesCount = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false);
            }
            if ((flags & 0x02) > 0)
            {
                bytesCount = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false);
            }
            if ((flags & 0x04) > 0)
            {
                toc = await stream.ReadAsync(100).ConfigureAwait(false);
            }
            if ((flags & 0x08) > 0)
            {
                quality = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false);
            }

            stream.Position = position;
            return(new XingFrame()
            {
                FramesCount = framesCount, BytesCount = bytesCount, Quality = quality
            });
        }
Exemplo n.º 4
0
        public static async Task <Int32> ReadInt32Async(this IBinaryStream stream, Byte amount, ByteOrder byteOrder)
        {
            if (amount > 4)
            {
                throw new ArgumentOutOfRangeException();
            }

            var buffer = await stream.ReadAsync(amount).ConfigureAwait(false);

            var value = 0;

            for (var i = 0; i < amount; i++)
            {
                value |= buffer[i] << 8 * ((byteOrder == ByteOrder.BigEndian) ? (amount - i - 1) : i);
            }
            return(value);
        }
Exemplo n.º 5
0
        public static async Task <Byte> ReadByteAsync(this IBinaryStream stream)
        {
            var buffer = await stream.ReadAsync(1).ConfigureAwait(false);

            return(buffer[0]);
        }
Exemplo n.º 6
0
        public static async Task <String> ReadStringAsync(this IBinaryStream stream, UInt32 length)
        {
            var buffer = await stream.ReadAsync(length).ConfigureAwait(false);

            return(Encoding.UTF8.GetString(buffer, 0, (Int32)length));
        }
Exemplo n.º 7
0
        public static async Task <UInt16> ReadUInt16Async(this IBinaryStream stream, ByteOrder byteOrder)
        {
            var buffer = await stream.ReadAsync(2).ConfigureAwait(false);

            return((UInt16)((byteOrder == ByteOrder.BigEndian) ? ((buffer[0] << 8) | buffer[1]) : (buffer[0] | (buffer[1] << 8))));
        }
Exemplo n.º 8
0
 public static Task <Byte[]> GetDataAsync(IBinaryStream stream, DataLocation dataLocation)
 {
     stream.Position = dataLocation.Position;
     return(stream.ReadAsync(dataLocation.Length));
 }
Exemplo n.º 9
0
Arquivo: Id3v2.cs Projeto: Venzz/Venz
        public static async Task <Id3v2> ParseAsync(IBinaryStream stream)
        {
            stream.Position += 3;
            var id3v2        = new Id3v2();
            var majorVersion = await stream.ReadByteAsync().ConfigureAwait(false);

            var revision = await stream.ReadByteAsync().ConfigureAwait(false);

            var flags = await stream.ReadByteAsync().ConfigureAwait(false);

            var size           = Id3v2.DecodeSize(await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false));
            var endingPosition = stream.Position + size;

            while (stream.Position < endingPosition)
            {
                var frameId = await stream.ReadStringAsync(4).ConfigureAwait(false);

                if (!Id3v2.IsValidAlphaNumeric(frameId))
                {
                    stream.Position = endingPosition;
                    break;
                }

                var frameSize = 0U;
                switch (majorVersion)
                {
                case 4:
                    frameSize = Id3v2.DecodeSize(await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false));
                    break;

                case 3:
                    frameSize = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false);

                    break;

                default:
                    throw new NotSupportedException();
                }

                var frameFlags = await stream.ReadUInt16Async(ByteOrder.LittleEndian).ConfigureAwait(false);

                switch (frameId)
                {
                case "TIT2":
                    id3v2.Title = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false));
                    break;

                case "TALB":
                    id3v2.Album = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false));
                    break;

                case "TOAL":
                    break;

                case "TPE1":
                    id3v2.Artist = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false));
                    break;

                case "TPE2":
                    id3v2.AlbumArtist = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false));
                    break;

                case "TRCK":
                    var track = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false));
                    if (track != null)
                    {
                        id3v2.Track = ParseTrack(track);
                    }
                    break;

                case "TYER":
                    var year = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false));
                    if (year != null)
                    {
                        id3v2.Year = ParseYear(year);
                    }
                    break;

                case "APIC":
                    var readBytes = 0U;
                    var encoding  = (FrameEncoding)await stream.ReadByteAsync().ConfigureAwait(false);

                    readBytes++;
                    while (await stream.ReadByteAsync().ConfigureAwait(false) != 0)     // MIME type <text string> $00
                    {
                        readBytes++;
                    }
                    readBytes++;
                    var pictureType = await stream.ReadByteAsync().ConfigureAwait(false);

                    readBytes++;
                    while (await stream.ReadByteAsync().ConfigureAwait(false) != 0)     // <text string according to encoding> $00 (00)
                    {
                        readBytes++;
                    }
                    id3v2.Cover      = new DataLocation(stream.Position, frameSize - readBytes - 1);
                    stream.Position += frameSize - readBytes - 1;
                    break;

                case "TCON":
                case "COMM":
                default:
                    stream.Position += frameSize;
                    break;
                }
            }

            return(id3v2);
        }