Exemplo n.º 1
0
        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);
            }
        }