Exemplo n.º 1
0
 /// <summary>
 ///     Reads format specific information at the start of the
 ///     file.
 /// </summary>
 /// <param name="start">
 ///     A <see cref="long" /> value containing the seek position
 ///     at which the tags end and the media data begins.
 /// </param>
 /// <param name="propertiesStyle">
 ///     A <see cref="ReadStyle" /> value specifying at what level
 ///     of accuracy to read the media properties, or
 ///     <see
 ///         cref="ReadStyle.None" />
 ///     to ignore the properties.
 /// </param>
 /// <remarks>
 ///     This method only searches for an audio header in the
 ///     first 16384 bytes of code to avoid searching forever in
 ///     corrupt files.
 /// </remarks>
 protected override void ReadStart(long start,
                                   ReadStyle propertiesStyle)
 {
     // Only check the first 16 bytes so we're not stuck
     // reading a bad file forever.
     if ((propertiesStyle & ReadStyle.Average) != 0 &&
         !AudioHeader.Find(out first_header, this,
                           start, 0x4000))
     {
         throw new CorruptFileException(
                   "ADTS audio header not found.");
     }
 }
Exemplo n.º 2
0
 /// <summary>
 ///     Searches for an audio header in a <see cref="TagLib.File" /> starting at a specified position and searching to the
 ///     end of the file.
 /// </summary>
 /// <param name="header">
 ///     A <see cref="AudioHeader" /> object in which the found
 ///     header will be stored.
 /// </param>
 /// <param name="file">
 ///     A <see cref="TagLib.File" /> object to search.
 /// </param>
 /// <param name="position">
 ///     A <see cref="long" /> value specifying the seek position
 ///     in <paramref name="file" /> at which to start searching.
 /// </param>
 /// <returns>
 ///     A <see cref="bool" /> value indicating whether or not a
 ///     header was found.
 /// </returns>
 /// <remarks>
 ///     Searching to the end of the file can be very, very slow
 ///     especially for corrupt or non-MPEG files. It is
 ///     recommended to use
 ///     <see
 ///         cref="M:AudioHeader.Find(AudioHeader,TagLib.File,long,int)" />
 ///     instead.
 /// </remarks>
 public static bool Find(out AudioHeader header,
                         TagLib.File file, long position)
 {
     return(Find(out header, file, position, -1));
 }
Exemplo n.º 3
0
        /// <summary>
        ///     Searches for an audio header in a <see cref="TagLib.File" /> starting at a specified position and searching through
        ///     a specified number of bytes.
        /// </summary>
        /// <param name="header">
        ///     A <see cref="AudioHeader" /> object in which the found
        ///     header will be stored.
        /// </param>
        /// <param name="file">
        ///     A <see cref="TagLib.File" /> object to search.
        /// </param>
        /// <param name="position">
        ///     A <see cref="long" /> value specifying the seek position
        ///     in <paramref name="file" /> at which to start searching.
        /// </param>
        /// <param name="length">
        ///     A <see cref="int" /> value specifying the maximum number
        ///     of bytes to search before aborting.
        /// </param>
        /// <returns>
        ///     A <see cref="bool" /> value indicating whether or not a
        ///     header was found.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="file" /> is <see langword="null" />.
        /// </exception>
        public static bool Find(out AudioHeader header,
                                TagLib.File file, long position, int length)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            var end = position + length;

            header = Unknown;

            file.Seek(position);

            var buffer = file.ReadBlock(3);

            if (buffer.Count < 3)
            {
                return(false);
            }

            do
            {
                file.Seek(position + 3);
                buffer = buffer.Mid(buffer.Count - 3);
                buffer.Add(file.ReadBlock(
                               (int)TagLib.File.BufferSize));

                for (var i = 0;
                     i < buffer.Count - 3 &&
                     (length < 0 || position + i < end);
                     i++)
                {
                    if (buffer[i] == 0xFF &&
                        buffer[i + 1] >= 0xF0)                        // 0xFFF
                    {
                        try
                        {
                            var bits = new BitStream(buffer.Mid(i, 7)
                                                     .Data);

                            // 12 bits sync header
                            bits.ReadInt32(12);

                            // 1 bit mpeg 2/4
                            bits.ReadInt32(1);

                            // 2 bits layer
                            bits.ReadInt32(2);

                            // 1 bit protection absent
                            bits.ReadInt32(1);

                            // 2 bits profile object type
                            bits.ReadInt32(2);

                            // 4 bits sampling frequency index
                            var samplerateindex = bits.ReadInt32(4);
                            if (samplerateindex >= sample_rates.Length)
                            {
                                return(false);
                            }

                            long samplerate = sample_rates[samplerateindex];

                            // 1 bit private bit
                            bits.ReadInt32(1);

                            // 3 bits channel configuration
                            var channelconfigindex = bits.ReadInt32(3);
                            if (channelconfigindex >= channels.Length)
                            {
                                return(false);
                            }

                            // 4 copyright bits
                            bits.ReadInt32(4);

                            // 13 bits frame length
                            long framelength = bits.ReadInt32(13);                             // double check framelength
                            if (framelength < 7)
                            {
                                return(false);
                            }

                            // 11 bits buffer fullness
                            bits.ReadInt32(11);

                            // 2 bits number of raw data blocks in frame
                            var numberofframes = bits.ReadInt32(2) + 1;

                            long numberofsamples = numberofframes * 1024;
                            var  bitrate         = framelength * 8 * samplerate / numberofsamples;

                            header = new AudioHeader(channels[channelconfigindex],
                                                     (int)bitrate,
                                                     (int)samplerate,
                                                     (int)numberofsamples,
                                                     numberofframes);

                            return(true);
                        }
                        catch (CorruptFileException)
                        {
                        }
                    }
                }

                position += TagLib.File.BufferSize;
            } while (buffer.Count > 3 && (length < 0 || position < end));

            return(false);
        }