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

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

The newest version!
package io.vacco.libmp3lame;

final class JABR_iteration_loop extends Jquantize /* implements Jiteration_loop */ {
  /********************************************************************
   *
   *  calc_target_bits()
   *
   *  calculates target bits for ABR encoding
   *
   *  mt 2000/05/31
   *
   * @return analog_silence_bits | (max_frame_bits << 32)
   ********************************************************************/
  private static final long calc_target_bits(
      final Jlame_internal_flags gfc,
      final float pe[][] /*[2][2]*/,
      final float ms_ener_ratio[] /*[2]*/,
      final int targ_bits[][] /*[2][2]*/ /*, int[] analog_silence_bits, int[] max_frame_bits*/) {
    final JSessionConfig cfg = gfc.cfg;
    final JEncResult eov = gfc.ov_enc;
    final Jgr_info[][] tt = gfc.l3_side.tt;
    final int mode_gr = cfg.mode_gr; // java
    final int framesize = 576 * mode_gr;

    eov.bitrate_index = cfg.vbr_max_bitrate_index;
    final long tmp = Jreservoir.ResvFrameBegin(gfc /*, &mean_bits */);
    final int max_frame_bits = (int) tmp;
    int mean_bits = (int) (tmp >> 32);

    eov.bitrate_index = 1;
    mean_bits = Jbitstream.getframebits(gfc) - (cfg.sideinfo_len << 3);
    final int channels_out = cfg.channels_out; // java
    final int analog_silence_bits = mean_bits / (mode_gr * channels_out);

    mean_bits = cfg.vbr_avg_bitrate_kbps * framesize * 1000;
    if ((gfc.sv_qnt.substep_shaping & 1) != 0) {
      mean_bits *= 1.09f;
    }
    mean_bits /= cfg.samplerate;
    mean_bits -= cfg.sideinfo_len << 3;
    mean_bits /= (mode_gr * channels_out);

    /*
      res_factor is the percentage of the target bitrate that should
      be used on average.  the remaining bits are added to the
      bitreservoir and used for difficult to encode frames.

      Since we are tracking the average bitrate, we should adjust
      res_factor "on the fly", increasing it if the average bitrate
      is greater than the requested bitrate, and decreasing it
      otherwise.  Reasonable ranges are from .9 to 1.0

      Until we get the above suggestion working, we use the following
      tuning:
      compression ratio    res_factor
      5.5  (256kbps)         1.0      no need for bitreservoir
      11   (128kbps)         .93      7% held for reservoir

      with linear interpolation for other values.

    */
    float res_factor = .93f + .07f * (11.0f - cfg.compression_ratio) / (11.0f - 5.5f);
    if (res_factor < .90f) {
      res_factor = .90f;
    }
    if (res_factor > 1.00f) {
      res_factor = 1.00f;
    }
    final int bits = (int) (res_factor * mean_bits); // java

    for (int gr = 0; gr < mode_gr; gr++) {
      final int[] targ_bits_gr = targ_bits[gr]; // java
      final Jgr_info[] tt_gr = tt[gr]; // java
      final float[] pe_gr = pe[gr]; // java
      int sum = 0;
      int ch = 0;
      do {
        targ_bits_gr[ch] = bits;

        if (pe_gr[ch] > 700) {
          int add_bits = (int) ((pe_gr[ch] - 700) / 1.4f);

          final Jgr_info cod_info = tt_gr[ch];
          targ_bits_gr[ch] = bits;

          /* short blocks use a little extra, no matter what the pe */
          if (cod_info.block_type == Jencoder.SHORT_TYPE) {
            final int v = mean_bits >> 1; // java
            if (add_bits < v) {
              add_bits = v;
            }
          }
          /* at most increase bits by 1.5*average */
          final int v = (mean_bits * 3) >> 1; // java
          if (add_bits > v) {
            add_bits = v;
          } else if (add_bits < 0) {
            add_bits = 0;
          }

          targ_bits_gr[ch] += add_bits;
        }
        if (targ_bits_gr[ch] > Jutil.MAX_BITS_PER_CHANNEL) {
          targ_bits_gr[ch] = Jutil.MAX_BITS_PER_CHANNEL;
        }
        sum += targ_bits_gr[ch];
      } while (++ch < channels_out); /* for ch */
      if (sum > Jutil.MAX_BITS_PER_GRANULE) {
        ch = 0;
        do {
          targ_bits_gr[ch] *= Jutil.MAX_BITS_PER_GRANULE;
          targ_bits_gr[ch] /= sum;
        } while (++ch < channels_out);
      }
    } /* for gr */

    if (gfc.ov_enc.mode_ext == Jencoder.MPG_MD_MS_LR) {
      mean_bits *= channels_out;
      for (int gr = 0; gr < mode_gr; gr++) {
        Jquantize_pvt.reduce_side(
            targ_bits[gr], ms_ener_ratio[gr], mean_bits, Jutil.MAX_BITS_PER_GRANULE);
      }
    }

    /*  sum target bits */
    int totbits = 0;
    for (int gr = 0; gr < mode_gr; gr++) {
      final int[] targ_bits_gr = targ_bits[gr]; // java
      int ch = 0;
      do {
        int v = targ_bits_gr[ch];
        if (v > Jutil.MAX_BITS_PER_CHANNEL) {
          v = Jutil.MAX_BITS_PER_CHANNEL;
          targ_bits_gr[ch] = v;
        }
        totbits += v;
      } while (++ch < channels_out);
    }

    /*  repartion target bits if needed */
    if (totbits > max_frame_bits && totbits > 0) {
      for (int gr = 0; gr < mode_gr; gr++) {
        final int[] targ_bits_gr = targ_bits[gr]; // java
        int ch = 0;
        do {
          int v = targ_bits_gr[ch];
          v *= max_frame_bits;
          v /= totbits;
          targ_bits_gr[ch] = v;
        } while (++ch < channels_out);
      }
    }
    return (long) analog_silence_bits | ((long) max_frame_bits << 32);
  }
  /********************************************************************
   *
   *  ABR_iteration_loop()
   *
   *  encode a frame with a disired average bitrate
   *
   *  mt 2000/05/31
   *
   ********************************************************************/
  // private static final void ABR_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[Jencoder.SFBMAX];
    final float xrpow[] = new float[576];
    final int targ_bits[][] = new int[2][2];
    final Jgr_info[][] tt = gfc.l3_side.tt;

    int mean_bits = 0;

    long tmp =
        calc_target_bits(
            gfc, pe, ms_ener_ratio, targ_bits /*, &analog_silence_bits, &max_frame_bits */);
    final int analog_silence_bits = (int) tmp;
    /*  encode granules */
    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[] targ_bits_gr = targ_bits[gr]; // java
      final JIII_psy_ratio[] pratio_gr = ratio[gr]; // java
      final Jgr_info[] tt_gr = tt[gr]; // java

      if (gfc.ov_enc.mode_ext == Jencoder.MPG_MD_MS_LR) {
        gfc.l3_side.ms_convert(gr);
      }
      int ch = 0;
      do {
        float adjust, masking_lower_db;
        final Jgr_info cod_info = tt_gr[ch];

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

        /*  cod_info, scalefac and xrpow get initialized in init_outer_loop */
        init_outer_loop(gfc, cod_info);
        if (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
           */
          final int ath_over = Jquantize_pvt.calc_xmin(gfc, pratio_gr[ch], cod_info, l3_xmin);
          if (0 == ath_over) {
            targ_bits_gr[ch] = analog_silence_bits;
          }

          outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, targ_bits_gr[ch]);
        }
        iteration_finish_one(gfc, gr, ch);
      } while (++ch < channels_out); /* ch */
    } /* gr */

    /*  find a bitrate which can refill the resevoir to positive size. */
    for (eov.bitrate_index = cfg.vbr_min_bitrate_index;
        eov.bitrate_index <= cfg.vbr_max_bitrate_index;
        eov.bitrate_index++) {
      tmp = Jreservoir.ResvFrameBegin(gfc /*, &mean_bits */);
      mean_bits = (int) (tmp >> 32);
      if (((int) tmp) >= 0) {
        break;
      }
    }

    Jreservoir.ResvFrameEnd(gfc, mean_bits);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy