private void WriteVbrHeader(bool isPlaceholder) { var buffer = new byte[GetFrameLength(this.mpegVersion, 64000, this.sampleRate, 0)]; if (!isPlaceholder) { uint header = this.firstFrameHeader; int dataOffset = GetFrameDataOffset(this.mpegVersion, this.channelMode); header &= 0xFFFE0DFF; // Clear CRC, bitrate, and padding fields header |= (uint)(mpegVersion == 3 ? 5 : 8) << 12; // 64 kbit/sec BitHelper.CopyBytes(buffer, 0, BigEndianBitConverter.GetBytes(header)); BitHelper.CopyBytes(buffer, dataOffset, BigEndianBitConverter.GetBytes(0x58696E67)); // "Xing" BitHelper.CopyBytes(buffer, dataOffset + 4, BigEndianBitConverter.GetBytes((uint)0x7)); // Flags BitHelper.CopyBytes(buffer, dataOffset + 8, BigEndianBitConverter.GetBytes((uint)frameOffsets.Count)); // Frame count BitHelper.CopyBytes(buffer, dataOffset + 12, BigEndianBitConverter.GetBytes(totalFrameLength)); // File length for (int i = 0; i < 100; i++) { int frameIndex = (int)((i / 100.0) * this.frameOffsets.Count); buffer[dataOffset + 16 + i] = (byte)(this.frameOffsets[frameIndex] / (double)this.totalFrameLength * 256.0); } } this.fileStream.Write(buffer, 0, buffer.Length); }
public void WriteChunk(byte[] chunk, uint timeStamp) { if (chunk.Length < 1) { return; } if (chunk[0] == 0) { // Header if (chunk.Length < 3) { return; } ulong bits = (ulong)BigEndianBitConverter.ToUInt16(chunk, 1) << 48; aacProfile = BitHelper.Read(ref bits, 5) - 1; sampleRateIndex = BitHelper.Read(ref bits, 4); channelConfig = BitHelper.Read(ref bits, 4); if (aacProfile < 0 || aacProfile > 3) { throw new AudioExtractionException("Unsupported AAC profile."); } if (sampleRateIndex > 12) { throw new AudioExtractionException("Invalid AAC sample rate index."); } if (channelConfig > 6) { throw new AudioExtractionException("Invalid AAC channel configuration."); } } else { // Audio data int dataSize = chunk.Length - 1; ulong bits = 0; // Reference: WriteADTSHeader from FAAC's bitstream.c BitHelper.Write(ref bits, 12, 0xFFF); BitHelper.Write(ref bits, 1, 0); BitHelper.Write(ref bits, 2, 0); BitHelper.Write(ref bits, 1, 1); BitHelper.Write(ref bits, 2, aacProfile); BitHelper.Write(ref bits, 4, sampleRateIndex); BitHelper.Write(ref bits, 1, 0); BitHelper.Write(ref bits, 3, channelConfig); BitHelper.Write(ref bits, 1, 0); BitHelper.Write(ref bits, 1, 0); BitHelper.Write(ref bits, 1, 0); BitHelper.Write(ref bits, 1, 0); BitHelper.Write(ref bits, 13, 7 + dataSize); BitHelper.Write(ref bits, 11, 0x7FF); BitHelper.Write(ref bits, 2, 0); fileStream.Write(BigEndianBitConverter.GetBytes(bits), 1, 7); fileStream.Write(chunk, 1, dataSize); } }