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); }
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; } } } }
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); }
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); }
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); }
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"); } }