private void WriteVBRHeader(bool isPlaceholder) { var buff = new byte[GetFrameLength(_mpegVersion, 64000, _sampleRate, 0)]; if (!isPlaceholder) { var header = _firstFrameHeader; var dataOffset = GetFrameDataOffset(_mpegVersion, _channelMode); header &= 0xFFFF0DFF; // Clear bitrate and padding fields header |= 0x00010000; // Set protection bit (indicates that CRC is NOT present) header |= (uint)(_mpegVersion == 3 ? 5 : 8) << 12; // 64 kbit/sec General.CopyBytes(buff, 0, BitConverterBE.GetBytes(header)); General.CopyBytes(buff, dataOffset, BitConverterBE.GetBytes((uint)0x58696E67)); // "Xing" General.CopyBytes(buff, dataOffset + 4, BitConverterBE.GetBytes((uint)0x7)); // Flags General.CopyBytes(buff, dataOffset + 8, BitConverterBE.GetBytes((uint)_frameOffsets.Count)); // Frame count General.CopyBytes(buff, dataOffset + 12, BitConverterBE.GetBytes((uint)_totalFrameLength)); // File length for (var i = 0; i < 100; i++) { var frameIndex = (int)(i / 100.0 * _frameOffsets.Count); buff[dataOffset + 16 + i] = (byte)(_frameOffsets[frameIndex] / (double)_totalFrameLength * 256.0); } } _fs.Write(buff, 0, buff.Length); }
public void WriteChunk(byte[] chunk, uint timeStamp) { if (chunk.Length < 1) { return; } if (chunk[0] == 0) { // Header if (chunk.Length < 3) { return; } var bits = (ulong)BitConverterBE.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 == 4) // HE-AAC { _aacProfile = 1; // Uses LC profile + SBR } if (_aacProfile < 0 || _aacProfile > 3) { throw new Exception("Unsupported AAC profile."); } if (_sampleRateIndex > 12) { throw new Exception("Invalid AAC sample rate index."); } if (_channelConfig > 6) { throw new Exception("Invalid AAC channel configuration."); } } else { // Audio data var 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); _fs.Write(BitConverterBE.GetBytes(bits), 1, 7); _fs.Write(chunk, 1, dataSize); } }