public void TestBitStream() { byte[] data = { 0xAA, 0xAD, 0xFE, 0xE9, 0xFF, 0xFF, 0xFF }; BitStream stream = new BitStream(data); // 2 5 5 45 // (10)(101)(010 1)(0101101) // 0xAA 0xAD // 63 745 // (111111)(10 11101001) // 0xFE 0xAA // 16777215 // (11111111 11111111 11111111) // 0xFF 0xFF 0xFF Assert.AreEqual(2, stream.ReadInt32(2)); Assert.AreEqual(5, stream.ReadInt32(3)); Assert.AreEqual(5, stream.ReadInt32(4)); Assert.AreEqual(45, stream.ReadInt32(7)); Assert.AreEqual(63, stream.ReadInt32(6)); Assert.AreEqual(745, stream.ReadInt32(10)); Assert.AreEqual(16777215, stream.ReadInt32(24)); }
/// <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("file"); long end = position + length; header = AudioHeader.Unknown; file.Seek(position); ByteVector 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)File.BufferSize)); for (int i = 0; i < buffer.Count - 3 && (length < 0 || position + i < end); i++) if (buffer[i] == 0xFF && buffer[i+1] >= 0xF0) // 0xFFF try { BitStream 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 int 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 int 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 int numberofframes = bits.ReadInt32(2) + 1; long numberofsamples = numberofframes * 1024; long bitrate = framelength * 8 * samplerate / numberofsamples; header = new AudioHeader(channels[channelconfigindex], (int)bitrate, (int)samplerate, (int)numberofsamples, numberofframes); return true; } catch (CorruptFileException) { } position += File.BufferSize; } while (buffer.Count > 3 && (length < 0 || position < end)); return false; }
public static bool Find(out AudioHeader header, TagLib.File file, long position, int length) { if (file == null) { throw new ArgumentNullException("file"); } long num = position + length; header = Unknown; file.Seek(position); ByteVector vector = file.ReadBlock(3); if (vector.Count >= 3) { do { file.Seek(position + 3L); vector = vector.Mid(vector.Count - 3); vector.Add(file.ReadBlock((int) TagLib.File.BufferSize)); for (int i = 0; (i < (vector.Count - 3)) && ((length < 0) || ((position + i) < num)); i++) { if ((vector[i] == 0xff) && (vector[i + 1] >= 240)) { bool flag; try { BitStream stream = new BitStream(vector.Mid(i, 7).Data); stream.ReadInt32(12); stream.ReadInt32(1); stream.ReadInt32(2); stream.ReadInt32(1); stream.ReadInt32(2); int index = stream.ReadInt32(4); if (index >= sample_rates.Length) { return false; } long num4 = sample_rates[index]; stream.ReadInt32(1); int num5 = stream.ReadInt32(3); if (num5 >= channels.Length) { return false; } stream.ReadInt32(4); long num6 = stream.ReadInt32(13); if (num6 < 7L) { return false; } stream.ReadInt32(11); int numberofframes = stream.ReadInt32(2) + 1; long num8 = numberofframes * 0x400; long num9 = ((num6 * 8L) * num4) / num8; header = new AudioHeader(channels[num5], (int) num9, (int) num4, (int) num8, numberofframes); flag = true; } catch (CorruptFileException) { } return flag; } } position += TagLib.File.BufferSize; } while ((vector.Count > 3) && ((length < 0) || (position < num))); } return false; }