示例#1
0
        internal void get_framebits(LameGlobalFlags gfp, int[] frameBits)
        {
            var gfc = gfp.internal_flags;

            gfc.bitrate_index = gfc.VBR_min_bitrate;
            var bitsPerFrame = bs.getframebits(gfp);

            gfc.bitrate_index = 1;
            bitsPerFrame      = bs.getframebits(gfp);
            for (var i = 1; i <= gfc.VBR_max_bitrate; i++)
            {
                gfc.bitrate_index = i;
                var mb = new MeanBits(bitsPerFrame);
                frameBits[i] = rv.ResvFrameBegin(gfp, mb);
                bitsPerFrame = mb.bits;
            }
        }
        public void iteration_loop(LameGlobalFlags gfp, float[][] pe, float[] ms_ener_ratio, III_psy_ratio[][] ratio)
        {
            var gfc = gfp.internal_flags;
            var l3_xmin = new float[L3Side.SFBMAX];
            var xrpow = new float[576];
            var targ_bits = new int[2];
            int mean_bits = 0, max_bits;

            var l3_side = gfc.l3_side;

            var mb = new MeanBits(mean_bits);

            quantize.rv.ResvFrameBegin(gfp, mb);
            mean_bits = mb.bits;

            /* quantize! */
            for (var gr = 0; gr < gfc.mode_gr; gr++)
            {
                /*
                 * calculate needed bits
                 */
                max_bits = quantize.qupvt.on_pe(gfp, pe, targ_bits, mean_bits, gr, gr);

                if (gfc.mode_ext == Encoder.MPG_MD_MS_LR)
                {
                    quantize.ms_convert(gfc.l3_side, gr);
                    quantize.qupvt.reduce_side(targ_bits, ms_ener_ratio[gr], mean_bits, max_bits);
                }

                for (var ch = 0; ch < gfc.channels_out; ch++)
                {
                    float adjust, masking_lower_db;
                    var   cod_info = l3_side.tt[gr][ch];

                    if (cod_info.block_type != Encoder.SHORT_TYPE)
                    {
                        // NORM, START or STOP type
                        adjust           = 0;
                        masking_lower_db = gfc.PSY.mask_adjust - adjust;
                    }
                    else
                    {
                        adjust           = 0;
                        masking_lower_db = gfc.PSY.mask_adjust_short - adjust;
                    }

                    gfc.masking_lower = (float)Math.Pow(10.0, masking_lower_db * 0.1);

                    /*
                     * init_outer_loop sets up cod_info, scalefac and xrpow
                     */
                    quantize.init_outer_loop(gfc, cod_info);
                    if (quantize.init_xrpow(gfc, cod_info, xrpow))
                    {
                        /*
                         * xr contains energy we will have to encode calculate the
                         * masking abilities find some good quantization in
                         * outer_loop
                         */
                        quantize.qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, l3_xmin);
                        quantize.outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, targ_bits[ch]);
                    }

                    quantize.iteration_finish_one(gfc, gr, ch);
                    Debug.Assert(cod_info.part2_3_length <= LameInternalFlags.MAX_BITS_PER_CHANNEL);
                    Debug.Assert(cod_info.part2_3_length <= targ_bits[ch]);
                } // for ch
            }     // for gr

            quantize.rv.ResvFrameEnd(gfc, mean_bits);
        }
示例#3
0
        internal void calc_target_bits(
            LameGlobalFlags gfp,
            float[][] pe,
            float[] ms_ener_ratio,
            int[][] targ_bits,
            int[] analog_silence_bits,
            int[] max_frame_bits)
        {
            var gfc = gfp.internal_flags;

            var   l3_side = gfc.l3_side;
            float res_factor;
            int   gr, ch, totbits, mean_bits = 0;

            gfc.bitrate_index = gfc.VBR_max_bitrate;
            var mb = new MeanBits(mean_bits);

            max_frame_bits[0]      = rv.ResvFrameBegin(gfp, mb);
            mean_bits              = mb.bits;
            gfc.bitrate_index      = 1;
            mean_bits              = bs.getframebits(gfp) - gfc.sideinfo_len * 8;
            analog_silence_bits[0] = mean_bits / (gfc.mode_gr * gfc.channels_out);
            mean_bits              = gfp.VBR_mean_bitrate_kbps * gfp.framesize * 1000;
            if ((gfc.substep_shaping & 1) != 0)
            {
                mean_bits = (int)(mean_bits * 1.09);
            }

            mean_bits /= gfp.out_samplerate;
            mean_bits -= gfc.sideinfo_len * 8;
            mean_bits /= gfc.mode_gr * gfc.channels_out;
            res_factor = .93f + .07f * (11.0f - gfp.compression_ratio) / (11.0f - 5.5f);
            if (res_factor < .90)
            {
                res_factor = .90f;
            }

            if (res_factor > 1.00)
            {
                res_factor = 1.00f;
            }

            for (gr = 0; gr < gfc.mode_gr; gr++)
            {
                var sum = 0;
                for (ch = 0; ch < gfc.channels_out; ch++)
                {
                    targ_bits[gr][ch] = (int)(res_factor * mean_bits);
                    if (pe[gr][ch] > 700)
                    {
                        var add_bits = (int)((pe[gr][ch] - 700) / 1.4);

                        var cod_info = l3_side.tt[gr][ch];
                        targ_bits[gr][ch] = (int)(res_factor * mean_bits);
                        if (cod_info.block_type == Encoder.SHORT_TYPE)
                        {
                            if (add_bits < mean_bits / 2)
                            {
                                add_bits = mean_bits / 2;
                            }
                        }

                        if (add_bits > mean_bits * 3 / 2)
                        {
                            add_bits = mean_bits * 3 / 2;
                        }
                        else if (add_bits < 0)
                        {
                            add_bits = 0;
                        }

                        targ_bits[gr][ch] += add_bits;
                    }

                    if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL)
                    {
                        targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL;
                    }

                    sum += targ_bits[gr][ch];
                }

                if (sum > LameInternalFlags.MAX_BITS_PER_GRANULE)
                {
                    for (ch = 0; ch < gfc.channels_out; ++ch)
                    {
                        targ_bits[gr][ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE;
                        targ_bits[gr][ch] /= sum;
                    }
                }
            }

            if (gfc.mode_ext == Encoder.MPG_MD_MS_LR)
            {
                for (gr = 0; gr < gfc.mode_gr; gr++)
                {
                    qupvt.reduce_side(
                        targ_bits[gr],
                        ms_ener_ratio[gr],
                        mean_bits * gfc.channels_out,
                        LameInternalFlags.MAX_BITS_PER_GRANULE);
                }
            }

            totbits = 0;
            for (gr = 0; gr < gfc.mode_gr; gr++)
            {
                for (ch = 0; ch < gfc.channels_out; ch++)
                {
                    if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL)
                    {
                        targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL;
                    }

                    totbits += targ_bits[gr][ch];
                }
            }

            if (totbits > max_frame_bits[0])
            {
                for (gr = 0; gr < gfc.mode_gr; gr++)
                {
                    for (ch = 0; ch < gfc.channels_out; ch++)
                    {
                        targ_bits[gr][ch] *= max_frame_bits[0];
                        targ_bits[gr][ch] /= totbits;
                    }
                }
            }
        }
示例#4
0
        internal int VBR_new_prepare(
            LameGlobalFlags gfp,
            float[][] pe,
            III_psy_ratio[][] ratio,
            float[][][] l3_xmin,
            int[] frameBits,
            int[][] max_bits)
        {
            var gfc = gfp.internal_flags;
            var analog_silence = 1;
            int avg = 0, bits = 0;
            int maximum_framebits;

            if (!gfp.free_format)
            {
                gfc.bitrate_index = gfc.VBR_max_bitrate;
                var mb = new MeanBits(avg);
                rv.ResvFrameBegin(gfp, mb);
                avg = mb.bits;
                get_framebits(gfp, frameBits);
                maximum_framebits = frameBits[gfc.VBR_max_bitrate];
            }
            else
            {
                gfc.bitrate_index = 0;
                var mb = new MeanBits(avg);
                maximum_framebits = rv.ResvFrameBegin(gfp, mb);
                avg          = mb.bits;
                frameBits[0] = maximum_framebits;
            }

            for (var gr = 0; gr < gfc.mode_gr; gr++)
            {
                qupvt.on_pe(gfp, pe, max_bits[gr], avg, gr, 0);
                if (gfc.mode_ext == Encoder.MPG_MD_MS_LR)
                {
                    ms_convert(gfc.l3_side, gr);
                }

                for (var ch = 0; ch < gfc.channels_out; ++ch)
                {
                    var cod_info = gfc.l3_side.tt[gr][ch];
                    gfc.masking_lower = (float)Math.Pow(10.0, gfc.PSY.mask_adjust * 0.1);
                    init_outer_loop(gfc, cod_info);
                    if (0 != qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, l3_xmin[gr][ch]))
                    {
                        analog_silence = 0;
                    }

                    bits += max_bits[gr][ch];
                }
            }

            for (var gr = 0; gr < gfc.mode_gr; gr++)
            {
                for (var ch = 0; ch < gfc.channels_out; ch++)
                {
                    if (bits > maximum_framebits)
                    {
                        max_bits[gr][ch] *= maximum_framebits;
                        max_bits[gr][ch] /= bits;
                    }
                }
            }

            return(analog_silence);
        }
        public void iteration_loop(LameGlobalFlags gfp, float[][] pe, float[] ms_ener_ratio, III_psy_ratio[][] ratio)
        {
            var gfc     = gfp.internal_flags;
            var l3_xmin = new float[L3Side.SFBMAX];
            var xrpow   = new float[576];

            var targ_bits           = Arrays.ReturnRectangularArray <int>(2, 2);
            var max_frame_bits      = new int[1];
            var analog_silence_bits = new int[1];

            var l3_side = gfc.l3_side;

            var mean_bits = 0;

            quantize.calc_target_bits(gfp, pe, ms_ener_ratio, targ_bits, analog_silence_bits, max_frame_bits);

            /*
             * encode granules
             */
            for (var gr = 0; gr < gfc.mode_gr; gr++)
            {
                if (gfc.mode_ext == Encoder.MPG_MD_MS_LR)
                {
                    quantize.ms_convert(gfc.l3_side, gr);
                }

                for (var ch = 0; ch < gfc.channels_out; ch++)
                {
                    float adjust, masking_lower_db;
                    var   cod_info = l3_side.tt[gr][ch];

                    if (cod_info.block_type != Encoder.SHORT_TYPE)
                    {
                        // NORM, START or STOP type
                        adjust           = 0;
                        masking_lower_db = gfc.PSY.mask_adjust - adjust;
                    }
                    else
                    {
                        adjust           = 0;
                        masking_lower_db = gfc.PSY.mask_adjust_short - adjust;
                    }

                    gfc.masking_lower = (float)Math.Pow(10.0, masking_lower_db * 0.1);

                    /*
                     * cod_info, scalefac and xrpow get initialized in
                     * init_outer_loop
                     */
                    quantize.init_outer_loop(gfc, cod_info);
                    if (quantize.init_xrpow(gfc, cod_info, xrpow))
                    {
                        /*
                         * xr contains energy we will have to encode calculate the
                         * masking abilities find some good quantization in
                         * outer_loop
                         */
                        var ath_over = quantize.qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, l3_xmin);
                        if (0 == ath_over) // analog silence
                        {
                            targ_bits[gr][ch] = analog_silence_bits[0];
                        }

                        quantize.outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, targ_bits[gr][ch]);
                    }

                    quantize.iteration_finish_one(gfc, gr, ch);
                } // ch
            }     // gr

            /*
             * find a bitrate which can refill the resevoir to positive size.
             */
            for (gfc.bitrate_index = gfc.VBR_min_bitrate; gfc.bitrate_index <= gfc.VBR_max_bitrate; gfc.bitrate_index++)
            {
                var mb = new MeanBits(mean_bits);
                var rc = quantize.rv.ResvFrameBegin(gfp, mb);
                mean_bits = mb.bits;
                if (rc >= 0)
                {
                    break;
                }
            }

            Debug.Assert(gfc.bitrate_index <= gfc.VBR_max_bitrate);

            quantize.rv.ResvFrameEnd(gfc, mean_bits);
        }
示例#6
0
        public void iteration_loop(LameGlobalFlags gfp, float[][] pe, float[] ms_ener_ratio, III_psy_ratio[][] ratio)
        {
            var gfc = gfp.internal_flags;

            var l3_xmin = Arrays.ReturnRectangularArray <float>(2, 2, L3Side.SFBMAX);

            var xrpow = new float[576];

            var bands     = Arrays.ReturnRectangularArray <int>(2, 2);
            var frameBits = new int[15];

            var min_bits  = Arrays.ReturnRectangularArray <int>(2, 2);
            var max_bits  = Arrays.ReturnRectangularArray <int>(2, 2);
            var mean_bits = 0;

            var l3_side = gfc.l3_side;

            var analog_silence = quantize.VBR_old_prepare(
                gfp,
                pe,
                ms_ener_ratio,
                ratio,
                l3_xmin,
                frameBits,
                min_bits,
                max_bits,
                bands);

            /*---------------------------------*/
            for (;;)
            {
                /*
                 * quantize granules with lowest possible number of bits
                 */
                var used_bits = 0;

                for (var gr = 0; gr < gfc.mode_gr; gr++)
                {
                    for (var ch = 0; ch < gfc.channels_out; ch++)
                    {
                        var cod_info = l3_side.tt[gr][ch];

                        /*
                         * init_outer_loop sets up cod_info, scalefac and xrpow
                         */
                        var ret = quantize.init_xrpow(gfc, cod_info, xrpow);
                        if (!ret || max_bits[gr][ch] == 0)
                        {
                            continue; // with next channel
                        }
                        quantize.VBR_encode_granule(
                            gfp,
                            cod_info,
                            l3_xmin[gr][ch],
                            xrpow,
                            ch,
                            min_bits[gr][ch],
                            max_bits[gr][ch]);

                        /*
                         * do the 'substep shaping'
                         */
                        if ((gfc.substep_shaping & 1) != 0)
                        {
                            quantize.trancate_smallspectrums(gfc, l3_side.tt[gr][ch], l3_xmin[gr][ch], xrpow);
                        }

                        var usedB = cod_info.part2_3_length + cod_info.part2_length;
                        used_bits += usedB;
                    } // for ch
                }

                /*
                 * find lowest bitrate able to hold used bits
                 */
                if (analog_silence != 0 && 0 == gfp.VBR_hard_min)
                {
                    gfc.bitrate_index = 1;
                }
                else
                {
                    gfc.bitrate_index = gfc.VBR_min_bitrate;
                }

                for (; gfc.bitrate_index < gfc.VBR_max_bitrate; gfc.bitrate_index++)
                {
                    if (used_bits <= frameBits[gfc.bitrate_index])
                    {
                        break;
                    }
                }

                var mb   = new MeanBits(mean_bits);
                var bits = quantize.rv.ResvFrameBegin(gfp, mb);
                mean_bits = mb.bits;

                if (used_bits <= bits)
                {
                    break;
                }

                quantize.bitpressure_strategy(gfc, l3_xmin, min_bits, max_bits);
            }
            /* breaks adjusted */
            /*--------------------------------------*/

            for (var gr = 0; gr < gfc.mode_gr; gr++)
            {
                for (var ch = 0; ch < gfc.channels_out; ch++)
                {
                    quantize.iteration_finish_one(gfc, gr, ch);
                }
            }

            quantize.rv.ResvFrameEnd(gfc, mean_bits);
        }
示例#7
0
        internal int on_pe(LameGlobalFlags gfp, float[][] pe, int[] targ_bits, int mean_bits, int gr, int cbr)
        {
            var gfc = gfp.internal_flags;
            int tbits = 0, bits;
            var add_bits = new int[2];
            int ch;
            var mb         = new MeanBits(tbits);
            var extra_bits = rv.ResvMaxBits(gfp, mean_bits, mb, cbr);

            tbits = mb.bits;
            var max_bits = tbits + extra_bits;

            if (max_bits > LameInternalFlags.MAX_BITS_PER_GRANULE)
            {
                max_bits = LameInternalFlags.MAX_BITS_PER_GRANULE;
            }

            for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch)
            {
                targ_bits[ch] = Math.Min(LameInternalFlags.MAX_BITS_PER_CHANNEL, tbits / gfc.channels_out);
                add_bits[ch]  = (int)(targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch]);
                if (add_bits[ch] > mean_bits * 3 / 4)
                {
                    add_bits[ch] = mean_bits * 3 / 4;
                }

                if (add_bits[ch] < 0)
                {
                    add_bits[ch] = 0;
                }

                if (add_bits[ch] + targ_bits[ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL)
                {
                    add_bits[ch] = Math.Max(0, LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[ch]);
                }

                bits += add_bits[ch];
            }

            if (bits > extra_bits)
            {
                for (ch = 0; ch < gfc.channels_out; ++ch)
                {
                    add_bits[ch] = extra_bits * add_bits[ch] / bits;
                }
            }

            for (ch = 0; ch < gfc.channels_out; ++ch)
            {
                targ_bits[ch] += add_bits[ch];
                extra_bits    -= add_bits[ch];
            }

            for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch)
            {
                bits += targ_bits[ch];
            }

            if (bits > LameInternalFlags.MAX_BITS_PER_GRANULE)
            {
                var sum = 0;
                for (ch = 0; ch < gfc.channels_out; ++ch)
                {
                    targ_bits[ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE;
                    targ_bits[ch] /= bits;
                    sum           += targ_bits[ch];
                }

                Debug.Assert(sum <= LameInternalFlags.MAX_BITS_PER_GRANULE);
            }

            return(max_bits);
        }
示例#8
0
        public void iteration_loop(LameGlobalFlags gfp, float[][] pe, float[] ms_ener_ratio, III_psy_ratio[][] ratio)
        {
            var gfc = gfp.internal_flags;

            var l3_xmin = Arrays.ReturnRectangularArray <float>(2, 2, L3Side.SFBMAX);

            var xrpow     = Arrays.ReturnRectangularArray <float>(2, 2, 576);
            var frameBits = new int[15];

            var max_bits = Arrays.ReturnRectangularArray <int>(2, 2);

            var l3_side = gfc.l3_side;

            var analog_silence = quantize.VBR_new_prepare(gfp, pe, ratio, l3_xmin, frameBits, max_bits);

            for (var gr = 0; gr < gfc.mode_gr; gr++)
            {
                for (var ch = 0; ch < gfc.channels_out; ch++)
                {
                    var cod_info = l3_side.tt[gr][ch];

                    /*
                     * init_outer_loop sets up cod_info, scalefac and xrpow
                     */
                    if (!quantize.init_xrpow(gfc, cod_info, xrpow[gr][ch]))
                    {
                        max_bits[gr][ch] = 0;
                    }
                } // for ch
            }

            /*
             * quantize granules with lowest possible number of bits
             */

            var used_bits = quantize.vbr.VBR_encode_frame(gfc, xrpow, l3_xmin, max_bits);

            if (!gfp.free_format)
            {
                /*
                 * find lowest bitrate able to hold used bits
                 */
                if (analog_silence != 0 && 0 == gfp.VBR_hard_min)
                {
                    gfc.bitrate_index = 1;
                }
                else
                {
                    gfc.bitrate_index = gfc.VBR_min_bitrate;
                }

                for (; gfc.bitrate_index < gfc.VBR_max_bitrate; gfc.bitrate_index++)
                {
                    if (used_bits <= frameBits[gfc.bitrate_index])
                    {
                        break;
                    }
                }

                if (gfc.bitrate_index > gfc.VBR_max_bitrate)
                {
                    gfc.bitrate_index = gfc.VBR_max_bitrate;
                }
            }
            else
            {
                gfc.bitrate_index = 0;
            }

            if (used_bits <= frameBits[gfc.bitrate_index])
            {
                /* update Reservoire status */
                int mean_bits = 0, fullframebits;
                var mb = new MeanBits(mean_bits);
                fullframebits = quantize.rv.ResvFrameBegin(gfp, mb);
                mean_bits     = mb.bits;
                Debug.Assert(used_bits <= fullframebits);
                for (var gr = 0; gr < gfc.mode_gr; gr++)
                {
                    for (var ch = 0; ch < gfc.channels_out; ch++)
                    {
                        var cod_info = l3_side.tt[gr][ch];
                        quantize.rv.ResvAdjust(gfc, cod_info);
                    }
                }

                quantize.rv.ResvFrameEnd(gfc, mean_bits);
            }
            else
            {
                /*
                 * SHOULD NOT HAPPEN INTERNAL ERROR
                 */
                throw new Exception("INTERNAL ERROR IN VBR NEW CODE, please send bug report");
            }
        }