Esempio n. 1
0
        /// <summary>
        ///     Construct the MP3 header using the settings of the global flags.
        ///     <img src="1000px-Mp3filestructure.svg.png">
        /// </summary>
        /// <param name="gfp">
        ///     global flags
        /// </param>
        /// <param name="buffer">
        ///     header
        /// </param>
        private void setLameTagFrameHeader(LameGlobalFlags gfp, byte[] buffer)
        {
            var gfc = gfp.internal_flags;

            // MP3 Sync Word
            buffer[0] = shiftInBitsValue(buffer[0], 8, 0xff);

            buffer[1] = shiftInBitsValue(buffer[1], 3, 7);
            buffer[1] = shiftInBitsValue(buffer[1], 1, gfp.out_samplerate < 16000 ? 0 : 1);

            // Mp3Version
            buffer[1] = shiftInBitsValue(buffer[1], 1, gfp.version);

            // 01 == Layer 3
            buffer[1] = shiftInBitsValue(buffer[1], 2, 4 - 3);

            // Error protection
            buffer[1] = shiftInBitsValue(buffer[1], 1, !gfp.error_protection ? 1 : 0);

            // Bit rate
            buffer[2] = shiftInBitsValue(buffer[2], 4, gfc.bitrate_index);

            // Frequency
            buffer[2] = shiftInBitsValue(buffer[2], 2, gfc.samplerate_index);

            // Pad. Bit
            buffer[2] = shiftInBitsValue(buffer[2], 1, 0);

            // Priv. Bit
            buffer[2] = shiftInBitsValue(buffer[2], 1, gfp.extension);

            // Mode
            buffer[3] = shiftInBitsValue(buffer[3], 2, (int)gfp.mode);

            // Mode extension (Used with Joint Stereo)
            buffer[3] = shiftInBitsValue(buffer[3], 2, gfc.mode_ext);

            // Copy
            buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.copyright);

            // Original
            buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.original);

            // Emphasis
            buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.emphasis);

            /* the default VBR header. 48 kbps layer III, no padding, no crc */
            /* but sampling freq, mode and copyright/copy protection taken */
            /* from first valid frame */
            buffer[0] = 0xff;
            var abyte = unchecked ((byte)(buffer[1] & 0xf1));

            int bitrate;

            if (1 == gfp.version)
            {
                bitrate = XING_BITRATE1;
            }
            else
            {
                if (gfp.out_samplerate < 16000)
                {
                    bitrate = XING_BITRATE25;
                }
                else
                {
                    bitrate = XING_BITRATE2;
                }
            }

            if (gfp.VBR == VbrMode.vbr_off)
            {
                bitrate = gfp.brate;
            }

            byte bbyte;

            if (gfp.free_format)
            {
                bbyte = 0x00;
            }
            else
            {
                bbyte = (byte)(16 * lame.BitrateIndex(bitrate, gfp.version, gfp.out_samplerate));
            }

            /*
             * Use as much of the info from the real frames in the Xing header:
             * samplerate, channels, crc, etc...
             */
            if (gfp.version == 1)
            {
                /* MPEG1 */
                buffer[1] = (byte)(abyte | 0x0a);     // was 0x0b;
                abyte     = (byte)(buffer[2] & 0x0d); // AF keep also private bit
                buffer[2] = (byte)(bbyte | abyte);    // 64kbs MPEG1 frame
            }
            else
            {
                /* MPEG2 */
                buffer[1] = (byte)(abyte | 0x02);     // was 0x03;
                abyte     = (byte)(buffer[2] & 0x0d); // AF keep also private bit
                buffer[2] = (byte)(bbyte | abyte);    // 64kbs MPEG2 frame
            }
        }