io.vacco.libmp3lame.JVBR_new_iteration_loop Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jlame Show documentation
Show all versions of jlame Show documentation
Java versions of the Lame mp3 codec libraries
The newest version!
package io.vacco.libmp3lame;
final class JVBR_new_iteration_loop extends Jquantize /* implements Jiteration_loop */ {
/** @return java: (analog_silence << 31) | (max_resv) */
private static final int VBR_new_prepare(
final Jlame_internal_flags gfc,
final float pe[][] /*[2][2]*/,
final JIII_psy_ratio ratio[][] /*[2][2]*/,
final float l3_xmin[][][] /*[2][2][SFBMAX]*/,
final int frameBits[] /*[16]*/,
final int max_bits[][] /*[2][2]*/ // ,
) // final int[] max_resv)
{
final JSessionConfig cfg = gfc.cfg;
final JEncResult eov = gfc.ov_enc;
int analog_silence = 0x80000000;
int bits = 0;
int avg, max_resv, maximum_framebits;
if (!cfg.free_format) {
eov.bitrate_index = cfg.vbr_max_bitrate_index;
avg = (int) (Jreservoir.ResvFrameBegin(gfc /*, &avg*/) >> 32);
max_resv = gfc.sv_enc.ResvMax;
get_framebits(gfc, frameBits);
maximum_framebits = frameBits[cfg.vbr_max_bitrate_index];
} else {
eov.bitrate_index = 0;
final long tmp = Jreservoir.ResvFrameBegin(gfc /*, &avg*/);
maximum_framebits = (int) tmp;
avg = (int) (tmp >> 32);
frameBits[0] = maximum_framebits;
max_resv = gfc.sv_enc.ResvMax;
}
final Jgr_info[][] tt = gfc.l3_side.tt; // java
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[] max_bits_gr = max_bits[gr]; // java
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);
}
final Jgr_info[] tt_gr = tt[gr]; // java
final JIII_psy_ratio[] ratio_gr = ratio[gr]; // java
final float[][] l3_xmin_gr = l3_xmin[gr]; // java
for (int ch = 0; ch < channels_out; ++ch) {
sv_qnt.masking_lower = (float) Math.pow(10.0, (double) (sv_qnt.mask_adjust * 0.1f));
final Jgr_info cod_info = tt_gr[ch];
init_outer_loop(gfc, cod_info);
if (0 != Jquantize_pvt.calc_xmin(gfc, ratio_gr[ch], cod_info, l3_xmin_gr[ch])) {
analog_silence = 0;
}
bits += max_bits_gr[ch];
}
}
for (int gr = 0; gr < mode_gr; gr++) {
final int[] max_bits_gr = max_bits[gr]; // java
for (int ch = 0; ch < channels_out; ch++) {
if (bits > maximum_framebits && bits > 0) {
int v = max_bits_gr[ch]; // java
v *= maximum_framebits;
v /= bits;
max_bits_gr[ch] = v;
}
} /* for ch */
} /* for gr */
if (analog_silence != 0) {
max_resv = 0;
}
return (analog_silence) | (max_resv);
}
// void VBR_new_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],
// const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2])
// @Override
static final void iteration(
final Jlame_internal_flags gfc,
final float pe[][],
final float ms_ratio[],
final JIII_psy_ratio ratio[][]) {
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[2][2][576]; // java: already zeroed
final int frameBits[] = new int[15];
final int max_bits[][] = new int[2][2];
final Jgr_info[][] tt = gfc.l3_side.tt;
// ms_ener_ratio; /* not used */
final int analog_silence =
VBR_new_prepare(gfc, pe, ratio, l3_xmin, frameBits, max_bits /*, &pad*/);
final int pad = analog_silence & 0x7fffffff; // java: analog_silence highest bit
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 int[] max_bits_gr = max_bits[gr]; // java
for (int ch = 0; ch < channels_out; ch++) {
final Jgr_info cod_info = tt_gr[ch];
/* init_outer_loop sets up cod_info, scalefac and xrpow */
if (!init_xrpow(gfc, cod_info, xrpow[gr][ch])) {
max_bits_gr[ch] = 0; /* silent granule needs no bits */
}
} /* for ch */
} /* for gr */
/* quantize granules with lowest possible number of bits */
final int used_bits = Jvbrquantize.VBR_encode_frame(gfc, xrpow, l3_xmin, max_bits);
if (!cfg.free_format) {
int i, j;
/* find lowest bitrate able to hold used bits */
if (analog_silence < 0 && !cfg.enforce_min_bitrate) { // java analog_silence highest bit
/* we detected analog silence and the user did not specify
* any hard framesize limit, so start with smallest possible frame
*/
i = 1;
} else {
i = cfg.vbr_min_bitrate_index;
}
final int vbr_max_bitrate_index = cfg.vbr_max_bitrate_index; // java
for (; i < vbr_max_bitrate_index; i++) {
if (used_bits <= frameBits[i]) {
break;
}
}
if (i > vbr_max_bitrate_index) {
i = vbr_max_bitrate_index;
}
if (pad > 0) {
for (j = vbr_max_bitrate_index; j > i; --j) {
final int unused = frameBits[j] - used_bits;
if (unused <= pad) {
break;
}
}
eov.bitrate_index = j;
} else {
eov.bitrate_index = i;
}
} else {
/* #if 0
static int mmm = 0;
int fff = getFramesize_kbps( gfc, used_bits );
int hhh = getFramesize_kbps( gfc, MAX_BITS_PER_GRANULE * cfg.mode_gr );
if( mmm < fff )
mmm = fff;
printf( "demand=%3d kbps max=%3d kbps limit=%3d kbps\n", fff, mmm, hhh );
#endif */
eov.bitrate_index = 0;
}
if (used_bits <= frameBits[eov.bitrate_index]) {
/* update Reservoire status */
final long tmp = Jreservoir.ResvFrameBegin(gfc /*, &mean_bits*/);
final int mean_bits = (int) (tmp >> 32);
for (int gr = 0; gr < mode_gr; gr++) {
final Jgr_info[] tt_gr = tt[gr]; // java
for (int ch = 0; ch < channels_out; ch++) {
final Jgr_info cod_info = tt_gr[ch];
Jreservoir.ResvAdjust(gfc, cod_info);
}
}
Jreservoir.ResvFrameEnd(gfc, mean_bits);
return;
} // else {
/* SHOULD NOT HAPPEN INTERNAL ERROR */
System.err.print("INTERNAL ERROR IN VBR NEW CODE, please send bug report\n");
System.exit(-1);
return;
// }
}
}