All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.vacco.libmp3lame.JVBR_old_iteration_loop Maven / Gradle / Ivy

package io.vacco.libmp3lame;

final class JVBR_old_iteration_loop extends Jquantize /* implements Jiteration_loop */ {
  /*********************************************************************
   *
   *      VBR_prepare()
   *
   *  2000-09-04 Robert Hegemann
   *
   *  * converts LR to MS coding when necessary
   *  * calculates allowed/adjusted quantization noise amounts
   *  * detects analog silent frames
   *
   *  some remarks:
   *  - lower masking depending on Quality setting
   *  - quality control together with adjusted ATH MDCT scaling
   *    on lower quality setting allocate more noise from
   *    ATH masking, and on higher quality setting allocate
   *    less noise from ATH masking.
   *  - experiments show that going more than 2dB over GPSYCHO's
   *    limits ends up in very annoying artefacts
   *
   *********************************************************************/

  /* RH: this one needs to be overhauled sometime */
  private static final boolean VBR_old_prepare(
      final Jlame_internal_flags gfc,
      final float pe[][] /*[2][2]*/,
      final float ms_ener_ratio[ /*2*/],
      final JIII_psy_ratio ratio[][] /*[2][2]*/,
      final float l3_xmin[][][] /*[2][2][SFBMAX]*/,
      final int frameBits[] /*[16]*/,
      final int min_bits[][] /*[2][2]*/,
      final int max_bits[][] /*[2][2]*/,
      final int bands[][] /*[2][2]*/) {
    final JSessionConfig cfg = gfc.cfg;
    final JEncResult eov = gfc.ov_enc;
    final Jgr_info[][] tt = gfc.l3_side.tt;

    float adjust = 0.0f;
    boolean analog_silence = true;
    int bits = 0;

    eov.bitrate_index = cfg.vbr_max_bitrate_index;
    final int avg = ((int) Jreservoir.ResvFrameBegin(gfc /*, &avg*/)) / cfg.mode_gr;

    get_framebits(gfc, frameBits);

    final JQntStateVar sv_qnt = gfc.sv_qnt; // java
    final int mode_gr = cfg.mode_gr; // java
    final int channels_out = cfg.channels_out; // java
    for (int gr = 0; gr < mode_gr; gr++) {
      final int mxb = Jquantize_pvt.on_pe(gfc, pe, max_bits[gr], avg, gr, false);
      if (gfc.ov_enc.mode_ext == Jencoder.MPG_MD_MS_LR) {
        gfc.l3_side.ms_convert(gr);
        Jquantize_pvt.reduce_side(max_bits[gr], ms_ener_ratio[gr], avg, mxb);
      }
      final Jgr_info[] tt_gr = tt[gr]; // java
      final float[] pe_gr = pe[gr]; // java
      final JIII_psy_ratio[] ratio_gr = ratio[gr]; // java
      final float[][] l3_xmin_gr = l3_xmin[gr]; // java
      final int[] bands_gr = bands[gr]; // java
      for (int ch = 0; ch < channels_out; ++ch) {
        final Jgr_info cod_info = tt_gr[ch];

        float masking_lower_db;
        if (cod_info.block_type != Jencoder.SHORT_TYPE) {
          /* NORM, START or STOP type */
          adjust = 1.28f / (1f + (float) Math.exp((double) (3.5f - pe_gr[ch] / 300.f))) - 0.05f;
          masking_lower_db = sv_qnt.mask_adjust - adjust;
        } else {
          adjust = 2.56f / (1f + (float) Math.exp((double) (3.5f - pe_gr[ch] / 300.f))) - 0.14f;
          masking_lower_db = sv_qnt.mask_adjust_short - adjust;
        }
        sv_qnt.masking_lower = (float) Math.pow(10.0, (double) (masking_lower_db * 0.1f));

        init_outer_loop(gfc, cod_info);
        bands_gr[ch] = Jquantize_pvt.calc_xmin(gfc, ratio_gr[ch], cod_info, l3_xmin_gr[ch]);
        if (bands_gr[ch] != 0) {
          analog_silence = false;
        }

        min_bits[gr][ch] = 126;

        bits += max_bits[gr][ch];
      }
    }
    final int max_frame_bits = frameBits[cfg.vbr_max_bitrate_index]; // java
    for (int gr = 0; gr < mode_gr; gr++) {
      final int[] max_bits_gr = max_bits[gr]; // java
      final int[] min_bits_gr = min_bits[gr]; // java
      for (int ch = 0; ch < channels_out; ch++) {
        if (bits > max_frame_bits && bits > 0) {
          int v = max_bits_gr[ch]; // java
          v *= max_frame_bits;
          v /= bits;
          max_bits_gr[ch] = v;
        }
        if (min_bits_gr[ch] > max_bits_gr[ch]) {
          min_bits_gr[ch] = max_bits_gr[ch];
        }
      } /* for ch */
    } /* for gr */

    return analog_silence;
  }

  private static final void bitpressure_strategy(
      final Jlame_internal_flags gfc,
      final float l3_xmin[][][] /*[2][2][SFBMAX]*/,
      final int min_bits[][] /*[2][2]*/,
      final int max_bits[][] /*[2][2]*/) {
    final JSessionConfig cfg = gfc.cfg;
    final Jgr_info[][] tt = gfc.l3_side.tt;
    final int mode_gr = cfg.mode_gr; // java
    final int channels_out = cfg.channels_out; // java

    for (int gr = 0; gr < mode_gr; gr++) {
      final Jgr_info[] tt_gr = tt[gr]; // java
      final float[][] l3_xmin_gr = l3_xmin[gr]; // java
      final int[] max_bits_gr = max_bits[gr]; // java
      final int[] min_bits_gr = min_bits[gr]; // java
      for (int ch = 0; ch < channels_out; ch++) {
        final Jgr_info gi = tt_gr[ch];
        final float[] xmin = l3_xmin_gr[ch]; // java
        int pxmin = 0;
        for (int sfb = 0, psy_lmax = gi.psy_lmax; sfb < psy_lmax; sfb++) {
          xmin[pxmin++] *= 1.f + .029f * sfb * sfb / Jencoder.SBMAX_l / Jencoder.SBMAX_l;
        }

        if (gi.block_type == Jencoder.SHORT_TYPE) {
          for (int sfb = gi.sfb_smin; sfb < Jencoder.SBMAX_s; sfb++) {
            final float v = 1.f + .029f * sfb * sfb / Jencoder.SBMAX_s / Jencoder.SBMAX_s; // java
            xmin[pxmin++] *= v;
            xmin[pxmin++] *= v;
            xmin[pxmin++] *= v;
          }
        }
        final int v1 = min_bits_gr[ch];
        final int v2 = (int) (0.9f * max_bits_gr[ch]);
        max_bits_gr[ch] = (v1 >= v2 ? v1 : v2);
      }
    }
  }

  /*********************************************************************
   *
   *      VBR_encode_granule()
   *
   *  2000-09-04 Robert Hegemann
   *
   *********************************************************************/
  private static final void VBR_encode_granule(
      final Jlame_internal_flags gfc,
      final Jgr_info cod_info,
      final float[] l3_xmin, /* allowed distortion of the scalefactor */
      final float xrpow[ /*576*/], /* coloured magnitudes of spectral values */
      final int ch,
      int min_bits,
      int max_bits) {
    final Jgr_info bst_cod_info = new Jgr_info();
    final float bst_xrpow[] = new float[576];
    final int Max_bits = max_bits;
    int real_bits = max_bits + 1;
    int this_bits = (max_bits + min_bits) >> 1;
    int found = 0;
    final boolean sfb21_extra = gfc.sv_qnt.sfb21_extra;

    final int[] buf = bst_cod_info.l3_enc;
    int i = buf.length;
    do {
      buf[--i] = 0;
    } while (i > 0);

    /*  search within round about 40 bits of optimal */
    int dbits;
    do {

      if (this_bits > Max_bits - 42) {
        gfc.sv_qnt.sfb21_extra = false;
      } else {
        gfc.sv_qnt.sfb21_extra = sfb21_extra;
      }

      final int over = outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, this_bits);

      /*  is quantization as good as we are looking for ?
       *  in this case: is no scalefactor band distorted?
       */
      if (over <= 0) {
        found = 1;
        /*  now we know it can be done with "real_bits"
         *  and maybe we can skip some iterations
         */
        real_bits = cod_info.part2_3_length;

        /*  store best quantization so far */
        bst_cod_info.copyFrom(cod_info);
        System.arraycopy(xrpow, 0, bst_xrpow, 0, 576);

        /*  try with fewer bits */
        max_bits = real_bits - 32;
        dbits = max_bits - min_bits;
        this_bits = (max_bits + min_bits) >> 1;
      } else {
        /*  try with more bits */
        min_bits = this_bits + 32;
        dbits = max_bits - min_bits;
        this_bits = (max_bits + min_bits) >> 1;

        if (found != 0) {
          found = 2;
          /*  start again with best quantization so far */
          cod_info.copyFrom(bst_cod_info);
          System.arraycopy(bst_xrpow, 0, xrpow, 0, 576);
        }
      }
    } while (dbits > 12);

    gfc.sv_qnt.sfb21_extra = sfb21_extra;

    /*  found=0 => nothing found, use last one
     *  found=1 => we just found the best and left the loop
     *  found=2 => we restored a good one and have now l3_enc to restore too
     */
    if (found == 2) {
      System.arraycopy(bst_cod_info.l3_enc, 0, cod_info.l3_enc, 0, 576);
    }
  }

  /************************************************************************
   *
   *      VBR_iteration_loop()
   *
   *  tries to find out how many bits are needed for each granule and channel
   *  to get an acceptable quantization. An appropriate bitrate will then be
   *  choosed for quantization.  rh 8/99
   *
   *  Robert Hegemann 2000-09-06 rewrite
   *
   ************************************************************************/

  // private static final void VBR_old_iteration_loop(final Jlame_internal_flags gfc, final float
  // pe[][]/*[2][2]*/,
  //		final float ms_ener_ratio[]/*[2]*/, final JIII_psy_ratio ratio[][]/*[2][2]*/)
  // @Override
  static final void iteration(
      final Jlame_internal_flags gfc,
      final float pe[][] /*[2][2]*/,
      final float ms_ener_ratio[] /*[2]*/,
      final JIII_psy_ratio ratio[][] /*[2][2]*/) {
    final JSessionConfig cfg = gfc.cfg;
    final JEncResult eov = gfc.ov_enc;
    final float l3_xmin[][][] = new float[2][2][Jencoder.SFBMAX];

    final float xrpow[] = new float[576];
    final int bands[][] = new int[2][2];
    final int frameBits[] = new int[15];
    final int min_bits[][] = new int[2][2];
    final int max_bits[][] = new int[2][2];
    final Jgr_info[][] tt = gfc.l3_side.tt;
    final int mode_gr = cfg.mode_gr; // java
    final int channels_out = cfg.channels_out; // java

    final boolean analog_silence =
        VBR_old_prepare(
            gfc, pe, ms_ener_ratio, ratio, l3_xmin, frameBits, min_bits, max_bits, bands);

    /*---------------------------------*/
    int mean_bits;
    for (; ; ) {

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

      int used_bits = 0;

      for (int gr = 0; gr < mode_gr; gr++) {
        final Jgr_info[] tt_gr = tt[gr]; // java
        final float[][] l3_xmin_gr = l3_xmin[gr]; // java
        final int[] max_bits_gr = max_bits[gr]; // java
        final int[] min_bits_gr = min_bits[gr]; // java
        for (int ch = 0; ch < channels_out; ch++) {
          final Jgr_info cod_info = tt_gr[ch]; // java

          /*  init_outer_loop sets up cod_info, scalefac and xrpow */
          if (!init_xrpow(gfc, cod_info, xrpow) || max_bits_gr[ch] == 0) {
            /*  xr contains no energy
             *  l3_enc, our encoding data, will be quantized to zero
             */
            continue; /* with next channel */
          }

          VBR_encode_granule(
              gfc, cod_info, l3_xmin_gr[ch], xrpow, ch, min_bits_gr[ch], max_bits_gr[ch]);

          /*  do the 'substep shaping' */
          if ((gfc.sv_qnt.substep_shaping & 1) != 0) {
            trancate_smallspectrums(gfc, tt_gr[ch], l3_xmin_gr[ch], xrpow);
          }

          final int ret = cod_info.part2_3_length + cod_info.part2_length;
          used_bits += ret;
        } /* for ch */
      } /* for gr */

      /*  find lowest bitrate able to hold used bits */
      if (analog_silence && !cfg.enforce_min_bitrate) {
        eov.bitrate_index = 1;
      } else {
        eov.bitrate_index = cfg.vbr_min_bitrate_index;
      }

      for (; eov.bitrate_index < cfg.vbr_max_bitrate_index; eov.bitrate_index++) {
        if (used_bits <= frameBits[eov.bitrate_index]) {
          break;
        }
      }
      final long tmp = Jreservoir.ResvFrameBegin(gfc /*, &mean_bits */);
      final int bits = (int) tmp;
      mean_bits = (int) (tmp >> 32);

      if (used_bits <= bits) {
        break;
      }

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

    for (int gr = 0; gr < mode_gr; gr++) {
      for (int ch = 0; ch < channels_out; ch++) {
        iteration_finish_one(gfc, gr, ch);
      } /* for ch */
    } /* for gr */
    Jreservoir.ResvFrameEnd(gfc, mean_bits);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy