Example #1
0
        internal int outer_loop(
            LameGlobalFlags gfp,
            GrInfo cod_info,
            float[] l3_xmin,
            float[] xrpow,
            int ch,
            int targ_bits)
        {
            var gfc             = gfp.internal_flags;
            var cod_info_w      = new GrInfo();
            var save_xrpow      = new float[576];
            var distort         = new float[L3Side.SFBMAX];
            var best_noise_info = new CalcNoiseResult();
            int better;
            var prev_noise          = new CalcNoiseData();
            var best_part2_3_length = 9999999;
            var bEndOfSearch        = false;
            var bRefine             = false;
            var best_ggain_pass1    = 0;

            bin_search_StepSize(gfc, cod_info, targ_bits, ch, xrpow);
            if (0 == gfc.noise_shaping)
            {
                return(100);
            }

            qupvt.calc_noise(cod_info, l3_xmin, distort, best_noise_info, prev_noise);
            best_noise_info.bits = cod_info.part2_3_length;
            cod_info_w.assign(cod_info);
            var age = 0;

            Array.Copy(xrpow, 0, save_xrpow, 0, 576);
            while (!bEndOfSearch)
            {
                do
                {
                    var noise_info = new CalcNoiseResult();
                    int search_limit;
                    var maxggain = 255;
                    if ((gfc.substep_shaping & 2) != 0)
                    {
                        search_limit = 20;
                    }
                    else
                    {
                        search_limit = 3;
                    }

                    if (gfc.sfb21_extra)
                    {
                        if (distort[cod_info_w.sfbmax] > 1.0)
                        {
                            break;
                        }

                        if (cod_info_w.block_type == Encoder.SHORT_TYPE &&
                            (distort[cod_info_w.sfbmax + 1] > 1.0 || distort[cod_info_w.sfbmax + 2] > 1.0))
                        {
                            break;
                        }
                    }

                    if (!balance_noise(gfp, cod_info_w, distort, xrpow, bRefine))
                    {
                        break;
                    }

                    if (cod_info_w.scalefac_scale != 0)
                    {
                        maxggain = 254;
                    }

                    var huff_bits = targ_bits - cod_info_w.part2_length;
                    if (huff_bits <= 0)
                    {
                        break;
                    }

                    while ((cod_info_w.part2_3_length = tk.count_bits(gfc, xrpow, cod_info_w, prev_noise)) >
                           huff_bits && cod_info_w.global_gain <= maxggain)
                    {
                        cod_info_w.global_gain++;
                    }

                    if (cod_info_w.global_gain > maxggain)
                    {
                        break;
                    }

                    if (best_noise_info.over_count == 0)
                    {
                        while ((cod_info_w.part2_3_length = tk.count_bits(gfc, xrpow, cod_info_w, prev_noise)) >
                               best_part2_3_length && cod_info_w.global_gain <= maxggain)
                        {
                            cod_info_w.global_gain++;
                        }

                        if (cod_info_w.global_gain > maxggain)
                        {
                            break;
                        }
                    }

                    qupvt.calc_noise(cod_info_w, l3_xmin, distort, noise_info, prev_noise);
                    noise_info.bits = cod_info_w.part2_3_length;
                    if (cod_info.block_type != Encoder.SHORT_TYPE)
                    {
                        better = gfp.quant_comp;
                    }
                    else
                    {
                        better = gfp.quant_comp_short;
                    }

                    better = quant_compare(better, best_noise_info, noise_info, cod_info_w, distort) ? 1 : 0;
                    if (better != 0)
                    {
                        best_part2_3_length = cod_info.part2_3_length;
                        best_noise_info     = noise_info;
                        cod_info.assign(cod_info_w);
                        age = 0;
                        Array.Copy(xrpow, 0, save_xrpow, 0, 576);
                    }
                    else
                    {
                        if (gfc.full_outer_loop == 0)
                        {
                            if (++age > search_limit && best_noise_info.over_count == 0)
                            {
                                break;
                            }

                            if (gfc.noise_shaping_amp == 3 && bRefine && age > 30)
                            {
                                break;
                            }

                            if (gfc.noise_shaping_amp == 3 && bRefine &&
                                cod_info_w.global_gain - best_ggain_pass1 > 15)
                            {
                                break;
                            }
                        }
                    }
                }while (cod_info_w.global_gain + cod_info_w.scalefac_scale < 255);

                if (gfc.noise_shaping_amp == 3)
                {
                    if (!bRefine)
                    {
                        cod_info_w.assign(cod_info);
                        Array.Copy(save_xrpow, 0, xrpow, 0, 576);
                        age = 0;
                        best_ggain_pass1 = cod_info_w.global_gain;
                        bRefine          = true;
                    }
                    else
                    {
                        bEndOfSearch = true;
                    }
                }
                else
                {
                    bEndOfSearch = true;
                }
            }

            Debug.Assert(cod_info.global_gain + cod_info.scalefac_scale <= 255);
            if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh)
            {
                Array.Copy(save_xrpow, 0, xrpow, 0, 576);
            }
            else if ((gfc.substep_shaping & 1) != 0)
            {
                trancate_smallspectrums(gfc, cod_info, l3_xmin, xrpow);
            }

            return(best_noise_info.over_count);
        }
Example #2
0
        internal int calc_noise(
            GrInfo cod_info,
            float[] l3_xmin,
            float[] distort,
            CalcNoiseResult res,
            CalcNoiseData prev_noise)
        {
            var   distortPos = 0;
            var   l3_xminPos = 0;
            int   sfb, l, over = 0;
            float over_noise_db = 0;
            float tot_noise_db  = 0;
            var   max_noise     = -20.0f;
            var   j             = 0;

            var scalefac    = cod_info.scalefac;
            var scalefacPos = 0;

            res.over_SSD = 0;
            for (sfb = 0; sfb < cod_info.psymax; sfb++)
            {
                var s = cod_info.global_gain -
                        ((scalefac[scalefacPos++] + (cod_info.preflag != 0 ? pretab[sfb] : 0)) <<
                         (cod_info.scalefac_scale + 1)) - cod_info.subblock_gain[cod_info.window[sfb]] * 8;
                var noise = 0.0f;
                if (prev_noise != null && prev_noise.step[sfb] == s)
                {
                    noise = prev_noise.noise[sfb];
                    j    += cod_info.width[sfb];
                    distort[distortPos++] = noise / l3_xmin[l3_xminPos++];
                    noise = prev_noise.noise_log[sfb];
                }
                else
                {
                    var step = POW20(s);
                    l = cod_info.width[sfb] >> 1;
                    if (j + cod_info.width[sfb] > cod_info.max_nonzero_coeff)
                    {
                        int usefullsize;
                        usefullsize = cod_info.max_nonzero_coeff - j + 1;
                        if (usefullsize > 0)
                        {
                            l = usefullsize >> 1;
                        }
                        else
                        {
                            l = 0;
                        }
                    }

                    var sl = new StartLine(j);
                    noise = calc_noise_core(cod_info, sl, l, step);
                    j     = sl.s;
                    if (prev_noise != null)
                    {
                        prev_noise.step[sfb]  = s;
                        prev_noise.noise[sfb] = noise;
                    }

                    noise = distort[distortPos++] = noise / l3_xmin[l3_xminPos++];
                    noise = Util.FAST_LOG10((float)Math.Max(noise, 1E-20));
                    if (prev_noise != null)
                    {
                        prev_noise.noise_log[sfb] = noise;
                    }
                }

                if (prev_noise != null)
                {
                    prev_noise.global_gain = cod_info.global_gain;
                }

                tot_noise_db += noise;
                if (noise > 0.0)
                {
                    int tmp;
                    tmp           = Math.Max((int)(noise * 10 + .5), 1);
                    res.over_SSD += tmp * tmp;
                    over++;
                    over_noise_db += noise;
                }

                max_noise = Math.Max(max_noise, noise);
            }

            res.over_count = over;
            res.tot_noise  = tot_noise_db;
            res.over_noise = over_noise_db;
            res.max_noise  = max_noise;
            return(over);
        }