diff --git a/lame.all.js b/lame.all.js index bdd5a7e..0102a78 100644 --- a/lame.all.js +++ b/lame.all.js @@ -264,4357 +264,4357 @@ function Version() { } +/* + * MP3 huffman table selecting and bit counting + * + * Copyright (c) 1999-2005 Takehiro TOMINAGA + * Copyright (c) 2002-2005 Gabriel Bouvigne + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ -function Presets() { - function VBRPresets(qual, comp, compS, - y, shThreshold, shThresholdS, - adj, adjShort, lower, - curve, sens, inter, - joint, mod, fix) { - this.vbr_q = qual; - this.quant_comp = comp; - this.quant_comp_s = compS; - this.expY = y; - this.st_lrm = shThreshold; - this.st_s = shThresholdS; - this.masking_adj = adj; - this.masking_adj_short = adjShort; - this.ath_lower = lower; - this.ath_curve = curve; - this.ath_sensitivity = sens; - this.interch = inter; - this.safejoint = joint; - this.sfb21mod = mod; - this.msfix = fix; - } +/* $Id: Takehiro.java,v 1.26 2011/05/24 20:48:06 kenchis Exp $ */ - function ABRPresets(kbps, comp, compS, - joint, fix, shThreshold, - shThresholdS, bass, sc, - mask, lower, curve, - interCh, sfScale) { - this.quant_comp = comp; - this.quant_comp_s = compS; - this.safejoint = joint; - this.nsmsfix = fix; - this.st_lrm = shThreshold; - this.st_s = shThresholdS; - this.nsbass = bass; - this.scale = sc; - this.masking_adj = mask; - this.ath_lower = lower; - this.ath_curve = curve; - this.interch = interCh; - this.sfscale = sfScale; - } +//package mp3; - var lame; +//import java.util.Arrays; - this.setModules = function (_lame) { - lame = _lame; - }; - /** - *
-     * Switch mappings for VBR mode VBR_RH
-     *             vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix
-     * 
- */ - var vbr_old_switch_map = [ - new VBRPresets(0, 9, 9, 0, 5.20, 125.0, -4.2, -6.3, 4.8, 1, 0, 0, 2, 21, 0.97), - new VBRPresets(1, 9, 9, 0, 5.30, 125.0, -3.6, -5.6, 4.5, 1.5, 0, 0, 2, 21, 1.35), - new VBRPresets(2, 9, 9, 0, 5.60, 125.0, -2.2, -3.5, 2.8, 2, 0, 0, 2, 21, 1.49), - new VBRPresets(3, 9, 9, 1, 5.80, 130.0, -1.8, -2.8, 2.6, 3, -4, 0, 2, 20, 1.64), - new VBRPresets(4, 9, 9, 1, 6.00, 135.0, -0.7, -1.1, 1.1, 3.5, -8, 0, 2, 0, 1.79), - new VBRPresets(5, 9, 9, 1, 6.40, 140.0, 0.5, 0.4, -7.5, 4, -12, 0.0002, 0, 0, 1.95), - new VBRPresets(6, 9, 9, 1, 6.60, 145.0, 0.67, 0.65, -14.7, 6.5, -19, 0.0004, 0, 0, 2.30), - new VBRPresets(7, 9, 9, 1, 6.60, 145.0, 0.8, 0.75, -19.7, 8, -22, 0.0006, 0, 0, 2.70), - new VBRPresets(8, 9, 9, 1, 6.60, 145.0, 1.2, 1.15, -27.5, 10, -23, 0.0007, 0, 0, 0), - new VBRPresets(9, 9, 9, 1, 6.60, 145.0, 1.6, 1.6, -36, 11, -25, 0.0008, 0, 0, 0), - new VBRPresets(10, 9, 9, 1, 6.60, 145.0, 2.0, 2.0, -36, 12, -25, 0.0008, 0, 0, 0) + +function Takehiro() { + + var qupvt = null; + this.qupvt = null; + + this.setModules = function (_qupvt) { + this.qupvt = _qupvt; + qupvt = _qupvt; + } + + function Bits(b) { + this.bits = 0 | b; + } + + var subdv_table = [[0, 0], /* 0 bands */ + [0, 0], /* 1 bands */ + [0, 0], /* 2 bands */ + [0, 0], /* 3 bands */ + [0, 0], /* 4 bands */ + [0, 1], /* 5 bands */ + [1, 1], /* 6 bands */ + [1, 1], /* 7 bands */ + [1, 2], /* 8 bands */ + [2, 2], /* 9 bands */ + [2, 3], /* 10 bands */ + [2, 3], /* 11 bands */ + [3, 4], /* 12 bands */ + [3, 4], /* 13 bands */ + [3, 4], /* 14 bands */ + [4, 5], /* 15 bands */ + [4, 5], /* 16 bands */ + [4, 6], /* 17 bands */ + [5, 6], /* 18 bands */ + [5, 6], /* 19 bands */ + [5, 7], /* 20 bands */ + [6, 7], /* 21 bands */ + [6, 7], /* 22 bands */ ]; /** - *
-     *                 vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix
-     * 
+ * nonlinear quantization of xr More accurate formula than the ISO formula. + * Takes into account the fact that we are quantizing xr . ix, but we want + * ix^4/3 to be as close as possible to x^4/3. (taking the nearest int would + * mean ix is as close as possible to xr, which is different.) + * + * From Segher Boessenkool 11/1999 + * + * 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro Tominaga. + * If you need the ASM code, check CVS circa Aug 2000. + * + * 01/2004: Optimizations by Gabriel Bouvigne */ - var vbr_psy_switch_map = [ - new VBRPresets(0, 9, 9, 0, 4.20, 25.0, -7.0, -4.0, 7.5, 1, 0, 0, 2, 26, 0.97), - new VBRPresets(1, 9, 9, 0, 4.20, 25.0, -5.6, -3.6, 4.5, 1.5, 0, 0, 2, 21, 1.35), - new VBRPresets(2, 9, 9, 0, 4.20, 25.0, -4.4, -1.8, 2, 2, 0, 0, 2, 18, 1.49), - new VBRPresets(3, 9, 9, 1, 4.20, 25.0, -3.4, -1.25, 1.1, 3, -4, 0, 2, 15, 1.64), - new VBRPresets(4, 9, 9, 1, 4.20, 25.0, -2.2, 0.1, 0, 3.5, -8, 0, 2, 0, 1.79), - new VBRPresets(5, 9, 9, 1, 4.20, 25.0, -1.0, 1.65, -7.7, 4, -12, 0.0002, 0, 0, 1.95), - new VBRPresets(6, 9, 9, 1, 4.20, 25.0, -0.0, 2.47, -7.7, 6.5, -19, 0.0004, 0, 0, 2), - new VBRPresets(7, 9, 9, 1, 4.20, 25.0, 0.5, 2.0, -14.5, 8, -22, 0.0006, 0, 0, 2), - new VBRPresets(8, 9, 9, 1, 4.20, 25.0, 1.0, 2.4, -22.0, 10, -23, 0.0007, 0, 0, 2), - new VBRPresets(9, 9, 9, 1, 4.20, 25.0, 1.5, 2.95, -30.0, 11, -25, 0.0008, 0, 0, 2), - new VBRPresets(10, 9, 9, 1, 4.20, 25.0, 2.0, 2.95, -36.0, 12, -30, 0.0008, 0, 0, 2) - ]; + function quantize_lines_xrpow_01(l, istep, xr, xrPos, ix, ixPos) { + var compareval0 = (1.0 - 0.4054) / istep; - function apply_vbr_preset(gfp, a, enforce) { - var vbr_preset = gfp.VBR == VbrMode.vbr_rh ? vbr_old_switch_map - : vbr_psy_switch_map; + l = l >> 1; + while ((l--) != 0) { + ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; + ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; + } + } - var x = gfp.VBR_q_frac; - var p = vbr_preset[a]; - var q = vbr_preset[a + 1]; - var set = p; + /** + * XRPOW_FTOI is a macro to convert floats to ints.
+ * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
+ * ROUNDFAC= -0.0946
+ * + * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]
+ * ROUNDFAC=0.4054
+ * + * Note: using floor() or 0| is extremely slow. On machines where the + * TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile to write + * some ASM for XRPOW_FTOI(). + */ + function quantize_lines_xrpow(l, istep, xr, xrPos, ix, ixPos) { - // NOOP(vbr_q); - // NOOP(quant_comp); - // NOOP(quant_comp_s); - // NOOP(expY); - p.st_lrm = p.st_lrm + x * (q.st_lrm - p.st_lrm); - // LERP(st_lrm); - p.st_s = p.st_s + x * (q.st_s - p.st_s); - // LERP(st_s); - p.masking_adj = p.masking_adj + x * (q.masking_adj - p.masking_adj); - // LERP(masking_adj); - p.masking_adj_short = p.masking_adj_short + x - * (q.masking_adj_short - p.masking_adj_short); - // LERP(masking_adj_short); - p.ath_lower = p.ath_lower + x * (q.ath_lower - p.ath_lower); - // LERP(ath_lower); - p.ath_curve = p.ath_curve + x * (q.ath_curve - p.ath_curve); - // LERP(ath_curve); - p.ath_sensitivity = p.ath_sensitivity + x - * (q.ath_sensitivity - p.ath_sensitivity); - // LERP(ath_sensitivity); - p.interch = p.interch + x * (q.interch - p.interch); - // LERP(interch); - // NOOP(safejoint); - // NOOP(sfb21mod); - p.msfix = p.msfix + x * (q.msfix - p.msfix); - // LERP(msfix); + l = l >> 1; + var remaining = l % 2; + l = l >> 1; + while (l-- != 0) { + var x0, x1, x2, x3; + var rx0, rx1, rx2, rx3; - lame_set_VBR_q(gfp, set.vbr_q); + x0 = xr[xrPos++] * istep; + x1 = xr[xrPos++] * istep; + rx0 = 0 | x0; + x2 = xr[xrPos++] * istep; + rx1 = 0 | x1; + x3 = xr[xrPos++] * istep; + rx2 = 0 | x2; + x0 += qupvt.adj43[rx0]; + rx3 = 0 | x3; + x1 += qupvt.adj43[rx1]; + ix[ixPos++] = 0 | x0; + x2 += qupvt.adj43[rx2]; + ix[ixPos++] = 0 | x1; + x3 += qupvt.adj43[rx3]; + ix[ixPos++] = 0 | x2; + ix[ixPos++] = 0 | x3; + } + if (remaining != 0) { + var x0, x1; + var rx0, rx1; - if (enforce != 0) - gfp.quant_comp = set.quant_comp; - else if (!(Math.abs(gfp.quant_comp - -1) > 0)) - gfp.quant_comp = set.quant_comp; - // SET_OPTION(quant_comp, set.quant_comp, -1); - if (enforce != 0) - gfp.quant_comp_short = set.quant_comp_s; - else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) - gfp.quant_comp_short = set.quant_comp_s; - // SET_OPTION(quant_comp_short, set.quant_comp_s, -1); - if (set.expY != 0) { - gfp.experimentalY = set.expY != 0; - } - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre = set.st_lrm; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre = set.st_lrm; - // SET_OPTION(short_threshold_lrm, set.st_lrm, -1); - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre_s = set.st_s; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre_s = set.st_s; - // SET_OPTION(short_threshold_s, set.st_s, -1); - if (enforce != 0) - gfp.maskingadjust = set.masking_adj; - else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) - gfp.maskingadjust = set.masking_adj; - // SET_OPTION(maskingadjust, set.masking_adj, 0); - if (enforce != 0) - gfp.maskingadjust_short = set.masking_adj_short; - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = set.masking_adj_short; - // SET_OPTION(maskingadjust_short, set.masking_adj_short, 0); - if (enforce != 0) - gfp.ATHlower = -set.ath_lower / 10.0; - else if (!(Math.abs((-gfp.ATHlower * 10.0) - 0) > 0)) - gfp.ATHlower = -set.ath_lower / 10.0; - // SET_OPTION(ATHlower, set.ath_lower, 0); - if (enforce != 0) - gfp.ATHcurve = set.ath_curve; - else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) - gfp.ATHcurve = set.ath_curve; - // SET_OPTION(ATHcurve, set.ath_curve, -1); - if (enforce != 0) - gfp.athaa_sensitivity = set.ath_sensitivity; - else if (!(Math.abs(gfp.athaa_sensitivity - -1) > 0)) - gfp.athaa_sensitivity = set.ath_sensitivity; - // SET_OPTION(athaa_sensitivity, set.ath_sensitivity, 0); - if (set.interch > 0) { - if (enforce != 0) - gfp.interChRatio = set.interch; - else if (!(Math.abs(gfp.interChRatio - -1) > 0)) - gfp.interChRatio = set.interch; - // SET_OPTION(interChRatio, set.interch, -1); - } - - /* parameters for which there is no proper set/get interface */ - if (set.safejoint > 0) { - gfp.exp_nspsytune = gfp.exp_nspsytune | set.safejoint; - } - if (set.sfb21mod > 0) { - gfp.exp_nspsytune = gfp.exp_nspsytune | (set.sfb21mod << 20); - } - if (enforce != 0) - gfp.msfix = set.msfix; - else if (!(Math.abs(gfp.msfix - -1) > 0)) - gfp.msfix = set.msfix; - // SET_OPTION(msfix, set.msfix, -1); - - if (enforce == 0) { - gfp.VBR_q = a; - gfp.VBR_q_frac = x; + x0 = xr[xrPos++] * istep; + x1 = xr[xrPos++] * istep; + rx0 = 0 | x0; + rx1 = 0 | x1; + x0 += qupvt.adj43[rx0]; + x1 += qupvt.adj43[rx1]; + ix[ixPos++] = 0 | x0; + ix[ixPos++] = 0 | x1; } } /** - *
-     *  Switch mappings for ABR mode
-     *
-     *              kbps  quant q_s safejoint nsmsfix st_lrm  st_s  ns-bass scale   msk ath_lwr ath_curve  interch , sfscale
-     * 
+ * Quantization function This function will select which lines to quantize + * and call the proper quantization function */ - var abr_switch_map = [ - new ABRPresets(8, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -30.0, 11, 0.0012, 1), /* 8, impossible to use in stereo */ - new ABRPresets(16, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -25.0, 11, 0.0010, 1), /* 16 */ - new ABRPresets(24, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -20.0, 11, 0.0010, 1), /* 24 */ - new ABRPresets(32, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -15.0, 11, 0.0010, 1), /* 32 */ - new ABRPresets(40, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 40 */ - new ABRPresets(48, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 48 */ - new ABRPresets(56, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -6.0, 11, 0.0008, 1), /* 56 */ - new ABRPresets(64, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -2.0, 11, 0.0008, 1), /* 64 */ - new ABRPresets(80, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, .0, 8, 0.0007, 1), /* 80 */ - new ABRPresets(96, 9, 9, 0, 2.50, 6.60, 145, 0, 0.95, 0, 1.0, 5.5, 0.0006, 1), /* 96 */ - new ABRPresets(112, 9, 9, 0, 2.25, 6.60, 145, 0, 0.95, 0, 2.0, 4.5, 0.0005, 1), /* 112 */ - new ABRPresets(128, 9, 9, 0, 1.95, 6.40, 140, 0, 0.95, 0, 3.0, 4, 0.0002, 1), /* 128 */ - new ABRPresets(160, 9, 9, 1, 1.79, 6.00, 135, 0, 0.95, -2, 5.0, 3.5, 0, 1), /* 160 */ - new ABRPresets(192, 9, 9, 1, 1.49, 5.60, 125, 0, 0.97, -4, 7.0, 3, 0, 0), /* 192 */ - new ABRPresets(224, 9, 9, 1, 1.25, 5.20, 125, 0, 0.98, -6, 9.0, 2, 0, 0), /* 224 */ - new ABRPresets(256, 9, 9, 1, 0.97, 5.20, 125, 0, 1.00, -8, 10.0, 1, 0, 0), /* 256 */ - new ABRPresets(320, 9, 9, 1, 0.90, 5.20, 125, 0, 1.00, -10, 12.0, 0, 0, 0) /* 320 */ - ]; + function quantize_xrpow(xp, pi, istep, codInfo, prevNoise) { + /* quantize on xr^(3/4) instead of xr */ + var sfb; + var sfbmax; + var j = 0; + var prev_data_use; + var accumulate = 0; + var accumulate01 = 0; + var xpPos = 0; + var iData = pi; + var iDataPos = 0; + var acc_iData = iData; + var acc_iDataPos = 0; + var acc_xp = xp; + var acc_xpPos = 0; - function apply_abr_preset(gfp, preset, enforce) { - /* Variables for the ABR stuff */ - var actual_bitrate = preset; + /* + * Reusing previously computed data does not seems to work if global + * gain is changed. Finding why it behaves this way would allow to use a + * cache of previously computed values (let's 10 cached values per sfb) + * that would probably provide a noticeable speedup + */ + prev_data_use = (prevNoise != null && (codInfo.global_gain == prevNoise.global_gain)); - var r = lame.nearestBitrateFullIndex(preset); + if (codInfo.block_type == Encoder.SHORT_TYPE) + sfbmax = 38; + else + sfbmax = 21; - gfp.VBR = VbrMode.vbr_abr; - gfp.VBR_mean_bitrate_kbps = actual_bitrate; - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, 320); - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, 8); - gfp.brate = gfp.VBR_mean_bitrate_kbps; - if (gfp.VBR_mean_bitrate_kbps > 320) { - gfp.disable_reservoir = true; - } + for (sfb = 0; sfb <= sfbmax; sfb++) { + var step = -1; - /* parameters for which there is no proper set/get interface */ - if (abr_switch_map[r].safejoint > 0) - gfp.exp_nspsytune = gfp.exp_nspsytune | 2; - /* safejoint */ + if (prev_data_use || codInfo.block_type == Encoder.NORM_TYPE) { + step = codInfo.global_gain + - ((codInfo.scalefac[sfb] + (codInfo.preflag != 0 ? qupvt.pretab[sfb] + : 0)) << (codInfo.scalefac_scale + 1)) + - codInfo.subblock_gain[codInfo.window[sfb]] * 8; + } + if (prev_data_use && (prevNoise.step[sfb] == step)) { + /* + * do not recompute this part, but compute accumulated lines + */ + if (accumulate != 0) { + quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, + acc_iData, acc_iDataPos); + accumulate = 0; + } + if (accumulate01 != 0) { + quantize_lines_xrpow_01(accumulate01, istep, acc_xp, + acc_xpPos, acc_iData, acc_iDataPos); + accumulate01 = 0; + } + } else { /* should compute this part */ + var l = codInfo.width[sfb]; - if (abr_switch_map[r].sfscale > 0) { - gfp.internal_flags.noise_shaping = 2; - } - /* ns-bass tweaks */ - if (Math.abs(abr_switch_map[r].nsbass) > 0) { - var k = (int)(abr_switch_map[r].nsbass * 4); - if (k < 0) - k += 64; - gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 2); - } + if ((j + codInfo.width[sfb]) > codInfo.max_nonzero_coeff) { + /* do not compute upper zero part */ + var usefullsize; + usefullsize = codInfo.max_nonzero_coeff - j + 1; + Arrays.fill(pi, codInfo.max_nonzero_coeff, 576, 0); + l = usefullsize; - if (enforce != 0) - gfp.quant_comp = abr_switch_map[r].quant_comp; - else if (!(Math.abs(gfp.quant_comp - -1) > 0)) - gfp.quant_comp = abr_switch_map[r].quant_comp; - // SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1); - if (enforce != 0) - gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; - else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) - gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; - // SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1); + if (l < 0) { + l = 0; + } - if (enforce != 0) - gfp.msfix = abr_switch_map[r].nsmsfix; - else if (!(Math.abs(gfp.msfix - -1) > 0)) - gfp.msfix = abr_switch_map[r].nsmsfix; - // SET_OPTION(msfix, abr_switch_map[r].nsmsfix, -1); + /* no need to compute higher sfb values */ + sfb = sfbmax + 1; + } - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; - // SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1); - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; - // SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1); + /* accumulate lines to quantize */ + if (0 == accumulate && 0 == accumulate01) { + acc_iData = iData; + acc_iDataPos = iDataPos; + acc_xp = xp; + acc_xpPos = xpPos; + } + if (prevNoise != null && prevNoise.sfb_count1 > 0 + && sfb >= prevNoise.sfb_count1 + && prevNoise.step[sfb] > 0 + && step >= prevNoise.step[sfb]) { - /* - * ABR seems to have big problems with clipping, especially at low - * bitrates - */ - /* - * so we compensate for that here by using a scale value depending on - * bitrate - */ - if (enforce != 0) - gfp.scale = abr_switch_map[r].scale; - else if (!(Math.abs(gfp.scale - -1) > 0)) - gfp.scale = abr_switch_map[r].scale; - // SET_OPTION(scale, abr_switch_map[r].scale, -1); + if (accumulate != 0) { + quantize_lines_xrpow(accumulate, istep, acc_xp, + acc_xpPos, acc_iData, acc_iDataPos); + accumulate = 0; + acc_iData = iData; + acc_iDataPos = iDataPos; + acc_xp = xp; + acc_xpPos = xpPos; + } + accumulate01 += l; + } else { + if (accumulate01 != 0) { + quantize_lines_xrpow_01(accumulate01, istep, acc_xp, + acc_xpPos, acc_iData, acc_iDataPos); + accumulate01 = 0; + acc_iData = iData; + acc_iDataPos = iDataPos; + acc_xp = xp; + acc_xpPos = xpPos; + } + accumulate += l; + } - if (enforce != 0) - gfp.maskingadjust = abr_switch_map[r].masking_adj; - else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) - gfp.maskingadjust = abr_switch_map[r].masking_adj; - // SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0); - if (abr_switch_map[r].masking_adj > 0) { - if (enforce != 0) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9); - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9); - // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * - // .9, 0); - } else { - if (enforce != 0) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1); - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1); - // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * - // 1.1, 0); - } - - if (enforce != 0) - gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.; - else if (!(Math.abs((-gfp.ATHlower * 10.) - 0) > 0)) - gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.; - // SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0); - if (enforce != 0) - gfp.ATHcurve = abr_switch_map[r].ath_curve; - else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) - gfp.ATHcurve = abr_switch_map[r].ath_curve; - // SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1); - - if (enforce != 0) - gfp.interChRatio = abr_switch_map[r].interch; - else if (!(Math.abs(gfp.interChRatio - -1) > 0)) - gfp.interChRatio = abr_switch_map[r].interch; - // SET_OPTION(interChRatio, abr_switch_map[r].interch, -1); - - return preset; - } - - this.apply_preset = function(gfp, preset, enforce) { - /* translate legacy presets */ - switch (preset) { - case Lame.R3MIX: - { - preset = Lame.V3; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.MEDIUM: - { - preset = Lame.V4; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.MEDIUM_FAST: - { - preset = Lame.V4; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.STANDARD: - { - preset = Lame.V2; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.STANDARD_FAST: - { - preset = Lame.V2; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.EXTREME: - { - preset = Lame.V0; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.EXTREME_FAST: - { - preset = Lame.V0; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.INSANE: - { - preset = 320; - gfp.preset = preset; - apply_abr_preset(gfp, preset, enforce); - gfp.VBR = VbrMode.vbr_off; - return preset; - } - } + if (l <= 0) { + /* + * rh: 20040215 may happen due to "prev_data_use" + * optimization + */ + if (accumulate01 != 0) { + quantize_lines_xrpow_01(accumulate01, istep, acc_xp, + acc_xpPos, acc_iData, acc_iDataPos); + accumulate01 = 0; + } + if (accumulate != 0) { + quantize_lines_xrpow(accumulate, istep, acc_xp, + acc_xpPos, acc_iData, acc_iDataPos); + accumulate = 0; + } - gfp.preset = preset; - { - switch (preset) { - case Lame.V9: - apply_vbr_preset(gfp, 9, enforce); - return preset; - case Lame.V8: - apply_vbr_preset(gfp, 8, enforce); - return preset; - case Lame.V7: - apply_vbr_preset(gfp, 7, enforce); - return preset; - case Lame.V6: - apply_vbr_preset(gfp, 6, enforce); - return preset; - case Lame.V5: - apply_vbr_preset(gfp, 5, enforce); - return preset; - case Lame.V4: - apply_vbr_preset(gfp, 4, enforce); - return preset; - case Lame.V3: - apply_vbr_preset(gfp, 3, enforce); - return preset; - case Lame.V2: - apply_vbr_preset(gfp, 2, enforce); - return preset; - case Lame.V1: - apply_vbr_preset(gfp, 1, enforce); - return preset; - case Lame.V0: - apply_vbr_preset(gfp, 0, enforce); - return preset; - default: break; - } - } - if (8 <= preset && preset <= 320) { - return apply_abr_preset(gfp, preset, enforce); - } - - /* no corresponding preset found */ - gfp.preset = 0; - return preset; - } - - // Rest from getset.c: - - /** - * VBR quality level.
- * 0 = highest
- * 9 = lowest - */ - function lame_set_VBR_q(gfp, VBR_q) { - var ret = 0; - - if (0 > VBR_q) { - /* Unknown VBR quality level! */ - ret = -1; - VBR_q = 0; - } - if (9 < VBR_q) { - ret = -1; - VBR_q = 9; - } - - gfp.VBR_q = VBR_q; - gfp.VBR_q_frac = 0; - return ret; - } - -} - -/* - * ReplayGainAnalysis - analyzes input samples and give the recommended dB change - * Copyright (C) 2001 David Robinson and Glen Sawyer - * Improvements and optimizations added by Frank Klemm, and by Marcel Muller - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * concept and filter values by David Robinson (David@Robinson.org) - * -- blame him if you think the idea is flawed - * original coding by Glen Sawyer (mp3gain@hotmail.com) - * -- blame him if you think this runs too slowly, or the coding is otherwise flawed - * - * lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ ) - * -- credit him for all the _good_ programming ;) - * - * - * For an explanation of the concepts and the basic algorithms involved, go to: - * http://www.replaygain.org/ - */ - -/* - * Here's the deal. Call - * - * InitGainAnalysis ( long samplefreq ); - * - * to initialize everything. Call - * - * AnalyzeSamples ( var Float_t* left_samples, - * var Float_t* right_samples, - * size_t num_samples, - * int num_channels ); - * - * as many times as you want, with as many or as few samples as you want. - * If mono, pass the sample buffer in through left_samples, leave - * right_samples NULL, and make sure num_channels = 1. - * - * GetTitleGain() - * - * will return the recommended dB level change for all samples analyzed - * SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis(). - * - * GetAlbumGain() - * - * will return the recommended dB level change for all samples analyzed - * since InitGainAnalysis() was called and finalized with GetTitleGain(). - * - * Pseudo-code to process an album: - * - * Float_t l_samples [4096]; - * Float_t r_samples [4096]; - * size_t num_samples; - * unsigned int num_songs; - * unsigned int i; - * - * InitGainAnalysis ( 44100 ); - * for ( i = 1; i <= num_songs; i++ ) { - * while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 ) - * AnalyzeSamples ( left_samples, right_samples, num_samples, 2 ); - * fprintf ("Recommended dB change for song %2d: %+6.2 dB\n", i, GetTitleGain() ); - * } - * fprintf ("Recommended dB change for whole album: %+6.2 dB\n", GetAlbumGain() ); - */ - -/* - * So here's the main source of potential code confusion: - * - * The filters applied to the incoming samples are IIR filters, - * meaning they rely on up to number of previous samples - * AND up to number of previous filtered samples. - * - * I set up the AnalyzeSamples routine to minimize memory usage and interface - * complexity. The speed isn't compromised too much (I don't think), but the - * internal complexity is higher than it should be for such a relatively - * simple routine. - * - * Optimization/clarity suggestions are welcome. - */ - -/** - * Table entries per dB - */ -GainAnalysis.STEPS_per_dB = 100.; -/** - * Table entries for 0...MAX_dB (normal max. values are 70...80 dB) - */ -GainAnalysis.MAX_dB = 120.; -GainAnalysis.GAIN_NOT_ENOUGH_SAMPLES = -24601; -GainAnalysis.GAIN_ANALYSIS_ERROR = 0; -GainAnalysis.GAIN_ANALYSIS_OK = 1; -GainAnalysis.INIT_GAIN_ANALYSIS_ERROR = 0; -GainAnalysis.INIT_GAIN_ANALYSIS_OK = 1; - -GainAnalysis.YULE_ORDER = 10; -GainAnalysis.MAX_ORDER = GainAnalysis.YULE_ORDER; - -GainAnalysis.MAX_SAMP_FREQ = 48000; -GainAnalysis.RMS_WINDOW_TIME_NUMERATOR = 1; -GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR = 20; -GainAnalysis.MAX_SAMPLES_PER_WINDOW = ((GainAnalysis.MAX_SAMP_FREQ * GainAnalysis.RMS_WINDOW_TIME_NUMERATOR) / GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR + 1); - -function GainAnalysis() { - /** - * calibration value for 89dB - */ - var PINK_REF = 64.82; - - var YULE_ORDER = GainAnalysis.YULE_ORDER; - /** - * percentile which is louder than the proposed level - */ - var RMS_PERCENTILE = 0.95; - /** - * maximum allowed sample frequency [Hz] - */ - var MAX_SAMP_FREQ = GainAnalysis.MAX_SAMP_FREQ; - var RMS_WINDOW_TIME_NUMERATOR = GainAnalysis.RMS_WINDOW_TIME_NUMERATOR; - /** - * numerator / denominator = time slice size [s] - */ - var RMS_WINDOW_TIME_DENOMINATOR = GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR; - /** - * max. Samples per Time slice - */ - var MAX_SAMPLES_PER_WINDOW = GainAnalysis.MAX_SAMPLES_PER_WINDOW; - - - var ABYule = [ - [0.03857599435200, -3.84664617118067, -0.02160367184185, - 7.81501653005538, -0.00123395316851, -11.34170355132042, - -0.00009291677959, 13.05504219327545, -0.01655260341619, - -12.28759895145294, 0.02161526843274, 9.48293806319790, - -0.02074045215285, -5.87257861775999, 0.00594298065125, - 2.75465861874613, 0.00306428023191, -0.86984376593551, - 0.00012025322027, 0.13919314567432, 0.00288463683916], - [0.05418656406430, -3.47845948550071, -0.02911007808948, - 6.36317777566148, -0.00848709379851, -8.54751527471874, - -0.00851165645469, 9.47693607801280, -0.00834990904936, - -8.81498681370155, 0.02245293253339, 6.85401540936998, - -0.02596338512915, -4.39470996079559, 0.01624864962975, - 2.19611684890774, -0.00240879051584, -0.75104302451432, - 0.00674613682247, 0.13149317958808, -0.00187763777362], - [0.15457299681924, -2.37898834973084, -0.09331049056315, - 2.84868151156327, -0.06247880153653, -2.64577170229825, - 0.02163541888798, 2.23697657451713, -0.05588393329856, - -1.67148153367602, 0.04781476674921, 1.00595954808547, - 0.00222312597743, -0.45953458054983, 0.03174092540049, - 0.16378164858596, -0.01390589421898, -0.05032077717131, - 0.00651420667831, 0.02347897407020, -0.00881362733839], - [0.30296907319327, -1.61273165137247, -0.22613988682123, - 1.07977492259970, -0.08587323730772, -0.25656257754070, - 0.03282930172664, -0.16276719120440, -0.00915702933434, - -0.22638893773906, -0.02364141202522, 0.39120800788284, - -0.00584456039913, -0.22138138954925, 0.06276101321749, - 0.04500235387352, -0.00000828086748, 0.02005851806501, - 0.00205861885564, 0.00302439095741, -0.02950134983287], - [0.33642304856132, -1.49858979367799, -0.25572241425570, - 0.87350271418188, -0.11828570177555, 0.12205022308084, - 0.11921148675203, -0.80774944671438, -0.07834489609479, - 0.47854794562326, -0.00469977914380, -0.12453458140019, - -0.00589500224440, -0.04067510197014, 0.05724228140351, - 0.08333755284107, 0.00832043980773, -0.04237348025746, - -0.01635381384540, 0.02977207319925, -0.01760176568150], - [0.44915256608450, -0.62820619233671, -0.14351757464547, - 0.29661783706366, -0.22784394429749, -0.37256372942400, - -0.01419140100551, 0.00213767857124, 0.04078262797139, - -0.42029820170918, -0.12398163381748, 0.22199650564824, - 0.04097565135648, 0.00613424350682, 0.10478503600251, - 0.06747620744683, -0.01863887810927, 0.05784820375801, - -0.03193428438915, 0.03222754072173, 0.00541907748707], - [0.56619470757641, -1.04800335126349, -0.75464456939302, - 0.29156311971249, 0.16242137742230, -0.26806001042947, - 0.16744243493672, 0.00819999645858, -0.18901604199609, - 0.45054734505008, 0.30931782841830, -0.33032403314006, - -0.27562961986224, 0.06739368333110, 0.00647310677246, - -0.04784254229033, 0.08647503780351, 0.01639907836189, - -0.03788984554840, 0.01807364323573, -0.00588215443421], - [0.58100494960553, -0.51035327095184, -0.53174909058578, - -0.31863563325245, -0.14289799034253, -0.20256413484477, - 0.17520704835522, 0.14728154134330, 0.02377945217615, - 0.38952639978999, 0.15558449135573, -0.23313271880868, - -0.25344790059353, -0.05246019024463, 0.01628462406333, - -0.02505961724053, 0.06920467763959, 0.02442357316099, - -0.03721611395801, 0.01818801111503, -0.00749618797172], - [0.53648789255105, -0.25049871956020, -0.42163034350696, - -0.43193942311114, -0.00275953611929, -0.03424681017675, - 0.04267842219415, -0.04678328784242, -0.10214864179676, - 0.26408300200955, 0.14590772289388, 0.15113130533216, - -0.02459864859345, -0.17556493366449, -0.11202315195388, - -0.18823009262115, -0.04060034127000, 0.05477720428674, - 0.04788665548180, 0.04704409688120, -0.02217936801134]]; - - var ABButter = [ - [0.98621192462708, -1.97223372919527, -1.97242384925416, - 0.97261396931306, 0.98621192462708], - [0.98500175787242, -1.96977855582618, -1.97000351574484, - 0.97022847566350, 0.98500175787242], - [0.97938932735214, -1.95835380975398, -1.95877865470428, - 0.95920349965459, 0.97938932735214], - [0.97531843204928, -1.95002759149878, -1.95063686409857, - 0.95124613669835, 0.97531843204928], - [0.97316523498161, -1.94561023566527, -1.94633046996323, - 0.94705070426118, 0.97316523498161], - [0.96454515552826, -1.92783286977036, -1.92909031105652, - 0.93034775234268, 0.96454515552826], - [0.96009142950541, -1.91858953033784, -1.92018285901082, - 0.92177618768381, 0.96009142950541], - [0.95856916599601, -1.91542108074780, -1.91713833199203, - 0.91885558323625, 0.95856916599601], - [0.94597685600279, -1.88903307939452, -1.89195371200558, - 0.89487434461664, 0.94597685600279]]; + /* ends for-loop */ + } + } + if (sfb <= sfbmax) { + iDataPos += codInfo.width[sfb]; + xpPos += codInfo.width[sfb]; + j += codInfo.width[sfb]; + } + } + if (accumulate != 0) { /* last data part */ + quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, + acc_iData, acc_iDataPos); + accumulate = 0; + } + if (accumulate01 != 0) { /* last data part */ + quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_xpPos, + acc_iData, acc_iDataPos); + accumulate01 = 0; + } + } /** - * When calling this procedure, make sure that ip[-order] and op[-order] - * point to real data + * ix_max */ - //private void filterYule(final float[] input, int inputPos, float[] output, - //int outputPos, int nSamples, final float[] kernel) { - function filterYule(input, inputPos, output, outputPos, nSamples, kernel) { - - while ((nSamples--) != 0) { - /* 1e-10 is a hack to avoid slowdown because of denormals */ - output[outputPos] = 1e-10 + input[inputPos + 0] * kernel[0] - - output[outputPos - 1] * kernel[1] + input[inputPos - 1] - * kernel[2] - output[outputPos - 2] * kernel[3] - + input[inputPos - 2] * kernel[4] - output[outputPos - 3] - * kernel[5] + input[inputPos - 3] * kernel[6] - - output[outputPos - 4] * kernel[7] + input[inputPos - 4] - * kernel[8] - output[outputPos - 5] * kernel[9] - + input[inputPos - 5] * kernel[10] - output[outputPos - 6] - * kernel[11] + input[inputPos - 6] * kernel[12] - - output[outputPos - 7] * kernel[13] + input[inputPos - 7] - * kernel[14] - output[outputPos - 8] * kernel[15] - + input[inputPos - 8] * kernel[16] - output[outputPos - 9] - * kernel[17] + input[inputPos - 9] * kernel[18] - - output[outputPos - 10] * kernel[19] - + input[inputPos - 10] * kernel[20]; - ++outputPos; - ++inputPos; - } - } + function ix_max(ix, ixPos, endPos) { + var max1 = 0, max2 = 0; -//private void filterButter(final float[] input, int inputPos, -// float[] output, int outputPos, int nSamples, final float[] kernel) { - function filterButter(input, inputPos, output, outputPos, nSamples, kernel) { + do { + var x1 = ix[ixPos++]; + var x2 = ix[ixPos++]; + if (max1 < x1) + max1 = x1; - while ((nSamples--) != 0) { - output[outputPos] = input[inputPos + 0] * kernel[0] - - output[outputPos - 1] * kernel[1] + input[inputPos - 1] - * kernel[2] - output[outputPos - 2] * kernel[3] - + input[inputPos - 2] * kernel[4]; - ++outputPos; - ++inputPos; - } + if (max2 < x2) + max2 = x2; + } while (ixPos < endPos); + if (max1 < max2) + max1 = max2; + return max1; } - /** - * @return INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if - * not - */ - function ResetSampleFrequency(rgData, samplefreq) { - /* zero out initial values */ - for (var i = 0; i < MAX_ORDER; i++) - rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.; + function count_bit_ESC(ix, ixPos, end, t1, t2, s) { + /* ESC-table is used */ + var linbits = Tables.ht[t1].xlen * 65536 + Tables.ht[t2].xlen; + var sum = 0, sum2; - switch (0 | (samplefreq)) { - case 48000: - rgData.reqindex = 0; - break; - case 44100: - rgData.reqindex = 1; - break; - case 32000: - rgData.reqindex = 2; - break; - case 24000: - rgData.reqindex = 3; - break; - case 22050: - rgData.reqindex = 4; - break; - case 16000: - rgData.reqindex = 5; - break; - case 12000: - rgData.reqindex = 6; - break; - case 11025: - rgData.reqindex = 7; - break; - case 8000: - rgData.reqindex = 8; - break; - default: - return INIT_GAIN_ANALYSIS_ERROR; - } + do { + var x = ix[ixPos++]; + var y = ix[ixPos++]; - rgData.sampleWindow = 0 | ((samplefreq * RMS_WINDOW_TIME_NUMERATOR - + RMS_WINDOW_TIME_DENOMINATOR - 1) / RMS_WINDOW_TIME_DENOMINATOR); + if (x != 0) { + if (x > 14) { + x = 15; + sum += linbits; + } + x *= 16; + } - rgData.lsum = 0.; - rgData.rsum = 0.; - rgData.totsamp = 0; + if (y != 0) { + if (y > 14) { + y = 15; + sum += linbits; + } + x += y; + } - Arrays.ill(rgData.A, 0); + sum += Tables.largetbl[x]; + } while (ixPos < end); - return INIT_GAIN_ANALYSIS_OK; - } + sum2 = sum & 0xffff; + sum >>= 16; - this.InitGainAnalysis = function (rgData, samplefreq) { - if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) { - return INIT_GAIN_ANALYSIS_ERROR; + if (sum > sum2) { + sum = sum2; + t1 = t2; } - rgData.linpre = MAX_ORDER; - rgData.rinpre = MAX_ORDER; - rgData.lstep = MAX_ORDER; - rgData.rstep = MAX_ORDER; - rgData.lout = MAX_ORDER; - rgData.rout = MAX_ORDER; + s.bits += sum; + return t1; + } - Arrays.fill(rgData.B, 0); + function count_bit_noESC(ix, ixPos, end, s) { + /* No ESC-words */ + var sum1 = 0; + var hlen1 = Tables.ht[1].hlen; - return INIT_GAIN_ANALYSIS_OK; - }; + do { + var x = ix[ixPos + 0] * 2 + ix[ixPos + 1]; + ixPos += 2; + sum1 += hlen1[x]; + } while (ixPos < end); - /** - * square - */ - function fsqr(d) { - return d * d; + s.bits += sum1; + return 1; } - this.AnalyzeSamples = function (rgData, left_samples, left_samplesPos, right_samples, right_samplesPos, num_samples, - num_channels) { - var curleft; - var curleftBase; - var curright; - var currightBase; - var batchsamples; - var cursamples; - var cursamplepos; + function count_bit_noESC_from2(ix, ixPos, end, t1, s) { + /* No ESC-words */ + var sum = 0, sum2; + var xlen = Tables.ht[t1].xlen; + var hlen; + if (t1 == 2) + hlen = Tables.table23; + else + hlen = Tables.table56; - if (num_samples == 0) - return GAIN_ANALYSIS_OK; + do { + var x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; + ixPos += 2; + sum += hlen[x]; + } while (ixPos < end); - cursamplepos = 0; - batchsamples = num_samples; + sum2 = sum & 0xffff; + sum >>= 16; - switch (num_channels) { - case 1: - right_samples = left_samples; - right_samplesPos = left_samplesPos; - break; - case 2: - break; - default: - return GAIN_ANALYSIS_ERROR; + if (sum > sum2) { + sum = sum2; + t1++; } - if (num_samples < MAX_ORDER) { - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER, num_samples); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER, num_samples); - } else { - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER, MAX_ORDER); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER, MAX_ORDER); - } + s.bits += sum; + return t1; + } - while (batchsamples > 0) { - cursamples = batchsamples > rgData.sampleWindow - rgData.totsamp ? rgData.sampleWindow - - rgData.totsamp - : batchsamples; - if (cursamplepos < MAX_ORDER) { - curleft = rgData.linpre + cursamplepos; - curleftBase = rgData.linprebuf; - curright = rgData.rinpre + cursamplepos; - currightBase = rgData.rinprebuf; - if (cursamples > MAX_ORDER - cursamplepos) - cursamples = MAX_ORDER - cursamplepos; - } else { - curleft = left_samplesPos + cursamplepos; - curleftBase = left_samples; - curright = right_samplesPos + cursamplepos; - currightBase = right_samples; - } + function count_bit_noESC_from3(ix, ixPos, end, t1, s) { + /* No ESC-words */ + var sum1 = 0; + var sum2 = 0; + var sum3 = 0; + var xlen = Tables.ht[t1].xlen; + var hlen1 = Tables.ht[t1].hlen; + var hlen2 = Tables.ht[t1 + 1].hlen; + var hlen3 = Tables.ht[t1 + 2].hlen; - filterYule(curleftBase, curleft, rgData.lstepbuf, rgData.lstep - + rgData.totsamp, cursamples, ABYule[rgData.reqindex]); - filterYule(currightBase, curright, rgData.rstepbuf, rgData.rstep - + rgData.totsamp, cursamples, ABYule[rgData.reqindex]); + do { + var x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; + ixPos += 2; + sum1 += hlen1[x]; + sum2 += hlen2[x]; + sum3 += hlen3[x]; + } while (ixPos < end); + var t = t1; + if (sum1 > sum2) { + sum1 = sum2; + t++; + } + if (sum1 > sum3) { + sum1 = sum3; + t = t1 + 2; + } + s.bits += sum1; - filterButter(rgData.lstepbuf, rgData.lstep + rgData.totsamp, - rgData.loutbuf, rgData.lout + rgData.totsamp, cursamples, - ABButter[rgData.reqindex]); - filterButter(rgData.rstepbuf, rgData.rstep + rgData.totsamp, - rgData.routbuf, rgData.rout + rgData.totsamp, cursamples, - ABButter[rgData.reqindex]); + return t; + } - curleft = rgData.lout + rgData.totsamp; - /* Get the squared values */ - curleftBase = rgData.loutbuf; - curright = rgData.rout + rgData.totsamp; - currightBase = rgData.routbuf; + /*************************************************************************/ + /* choose table */ + /*************************************************************************/ - var i = cursamples % 8; - while ((i--) != 0) { - rgData.lsum += fsqr(curleftBase[curleft++]); - rgData.rsum += fsqr(currightBase[curright++]); - } - i = cursamples / 8; - while ((i--) != 0) { - rgData.lsum += fsqr(curleftBase[curleft + 0]) - + fsqr(curleftBase[curleft + 1]) - + fsqr(curleftBase[curleft + 2]) - + fsqr(curleftBase[curleft + 3]) - + fsqr(curleftBase[curleft + 4]) - + fsqr(curleftBase[curleft + 5]) - + fsqr(curleftBase[curleft + 6]) - + fsqr(curleftBase[curleft + 7]); - curleft += 8; - rgData.rsum += fsqr(currightBase[curright + 0]) - + fsqr(currightBase[curright + 1]) - + fsqr(currightBase[curright + 2]) - + fsqr(currightBase[curright + 3]) - + fsqr(currightBase[curright + 4]) - + fsqr(currightBase[curright + 5]) - + fsqr(currightBase[curright + 6]) - + fsqr(currightBase[curright + 7]); - curright += 8; - } + var huf_tbl_noESC = [1, 2, 5, 7, 7, 10, 10, 13, 13, + 13, 13, 13, 13, 13, 13]; - batchsamples -= cursamples; - cursamplepos += cursamples; - rgData.totsamp += cursamples; - if (rgData.totsamp == rgData.sampleWindow) { - /* Get the Root Mean Square (RMS) for this set of samples */ - var val = GainAnalysis.STEPS_per_dB - * 10. - * Math.log10((rgData.lsum + rgData.rsum) - / rgData.totsamp * 0.5 + 1.e-37); - var ival = (val <= 0) ? 0 : 0 | val; - if (ival >= rgData.A.length) - ival = rgData.A.length - 1; - rgData.A[ival]++; - rgData.lsum = rgData.rsum = 0.; + /** + * Choose the Huffman table that will encode ix[begin..end] with the fewest + * bits. + * + * Note: This code contains knowledge about the sizes and characteristics of + * the Huffman tables as defined in the IS (Table B.7), and will not work + * with any arbitrary tables. + */ + function choose_table(ix, ixPos, endPos, s) { + var max = ix_max(ix, ixPos, endPos); - System.arraycopy(rgData.loutbuf, rgData.totsamp, - rgData.loutbuf, 0, MAX_ORDER); - System.arraycopy(rgData.routbuf, rgData.totsamp, - rgData.routbuf, 0, MAX_ORDER); - System.arraycopy(rgData.lstepbuf, rgData.totsamp, - rgData.lstepbuf, 0, MAX_ORDER); - System.arraycopy(rgData.rstepbuf, rgData.totsamp, - rgData.rstepbuf, 0, MAX_ORDER); - rgData.totsamp = 0; - } - if (rgData.totsamp > rgData.sampleWindow) { - /* - * somehow I really screwed up: Error in programming! Contact - * author about totsamp > sampleWindow - */ - return GAIN_ANALYSIS_ERROR; - } - } - if (num_samples < MAX_ORDER) { - System.arraycopy(rgData.linprebuf, num_samples, rgData.linprebuf, - 0, MAX_ORDER - num_samples); - System.arraycopy(rgData.rinprebuf, num_samples, rgData.rinprebuf, - 0, MAX_ORDER - num_samples); - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER - num_samples, num_samples); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER - num_samples, num_samples); - } else { - System.arraycopy(left_samples, left_samplesPos + num_samples - - MAX_ORDER, rgData.linprebuf, 0, MAX_ORDER); - System.arraycopy(right_samples, right_samplesPos + num_samples - - MAX_ORDER, rgData.rinprebuf, 0, MAX_ORDER); - } + switch (max) { + case 0: + return max; - return GAIN_ANALYSIS_OK; - }; + case 1: + return count_bit_noESC(ix, ixPos, endPos, s); - function analyzeResult(Array, len) { - var i; + case 2: + case 3: + return count_bit_noESC_from2(ix, ixPos, endPos, + huf_tbl_noESC[max - 1], s); - var elems = 0; - for (i = 0; i < len; i++) - elems += Array[i]; - if (elems == 0) - return GAIN_NOT_ENOUGH_SAMPLES; + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + return count_bit_noESC_from3(ix, ixPos, endPos, + huf_tbl_noESC[max - 1], s); - var upper = 0 | Math.ceil(elems * (1. - RMS_PERCENTILE)); - for (i = len; i-- > 0;) { - if ((upper -= Array[i]) <= 0) - break; + default: + /* try tables with linbits */ + if (max > QuantizePVT.IXMAX_VAL) { + s.bits = QuantizePVT.LARGE_BITS; + return -1; + } + max -= 15; + var choice2; + for (choice2 = 24; choice2 < 32; choice2++) { + if (Tables.ht[choice2].linmax >= max) { + break; + } + } + var choice; + for (choice = choice2 - 8; choice < 24; choice++) { + if (Tables.ht[choice].linmax >= max) { + break; + } + } + return count_bit_ESC(ix, ixPos, endPos, choice, choice2, s); } - - //return (float) ((float) PINK_REF - (float) i / (float) STEPS_per_dB); - return (PINK_REF - i / GainAnalysis.STEPS_per_dB); } - this.GetTitleGain = function (rgData) { - var retval = analyzeResult(rgData.A, rgData.A.length); + /** + * count_bit + */ + this.noquant_count_bits = function (gfc, gi, prev_noise) { + var ix = gi.l3_enc; + var i = Math.min(576, ((gi.max_nonzero_coeff + 2) >> 1) << 1); - for (var i = 0; i < rgData.A.length; i++) { - rgData.B[i] += rgData.A[i]; - rgData.A[i] = 0; - } + if (prev_noise != null) + prev_noise.sfb_count1 = 0; - for (var i = 0; i < MAX_ORDER; i++) - rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.; + /* Determine count1 region */ + for (; i > 1; i -= 2) + if ((ix[i - 1] | ix[i - 2]) != 0) + break; + gi.count1 = i; - rgData.totsamp = 0; - rgData.lsum = rgData.rsum = 0.; - return retval; - } + /* Determines the number of bits to encode the quadruples. */ + var a1 = 0; + var a2 = 0; + for (; i > 3; i -= 4) { + var p; + /* hack to check if all values <= 1 */ + //throw "TODO: HACK if ((((long) ix[i - 1] | (long) ix[i - 2] | (long) ix[i - 3] | (long) ix[i - 4]) & 0xffffffffL) > 1L " + //if (true) { + if (((ix[i - 1] | ix[i - 2] | ix[i - 3] | ix[i - 4]) & 0x7fffffff) > 1) { + break; + } + p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + ix[i - 1]; + a1 += Tables.t32l[p]; + a2 += Tables.t33l[p]; + } + var bits = a1; + gi.count1table_select = 0; + if (a1 > a2) { + bits = a2; + gi.count1table_select = 1; + } -} + gi.count1bits = bits; + gi.big_values = i; + if (i == 0) + return bits; -/* - * bit reservoir source file - * - * Copyright (c) 1999-2000 Mark Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ + if (gi.block_type == Encoder.SHORT_TYPE) { + a1 = 3 * gfc.scalefac_band.s[3]; + if (a1 > gi.big_values) + a1 = gi.big_values; + a2 = gi.big_values; -/* $Id: Reservoir.java,v 1.9 2011/05/24 20:48:06 kenchis Exp $ */ + } else if (gi.block_type == Encoder.NORM_TYPE) { + /* bv_scf has 576 entries (0..575) */ + a1 = gi.region0_count = gfc.bv_scf[i - 2]; + a2 = gi.region1_count = gfc.bv_scf[i - 1]; -//package mp3; + a2 = gfc.scalefac_band.l[a1 + a2 + 2]; + a1 = gfc.scalefac_band.l[a1 + 1]; + if (a2 < i) { + var bi = new Bits(bits); + gi.table_select[2] = choose_table(ix, a2, i, bi); + bits = bi.bits; + } + } else { + gi.region0_count = 7; + /* gi.region1_count = SBPSY_l - 7 - 1; */ + gi.region1_count = Encoder.SBMAX_l - 1 - 7 - 1; + a1 = gfc.scalefac_band.l[7 + 1]; + a2 = i; + if (a1 > a2) { + a1 = a2; + } + } -/** - * ResvFrameBegin:
- * Called (repeatedly) at the beginning of a frame. Updates the maximum size of - * the reservoir, and checks to make sure main_data_begin was set properly by - * the formatter
- * Background information: - * - * This is the original text from the ISO standard. Because of sooo many bugs - * and irritations correcting comments are added in brackets []. A '^W' means - * you should remove the last word. - * - *
- *  1. The following rule can be used to calculate the maximum
- *     number of bits used for one granule [^W frame]:
- * At the highest possible bitrate of Layer III (320 kbps - * per stereo signal [^W^W^W], 48 kHz) the frames must be of - * [^W^W^W are designed to have] constant length, i.e. - * one buffer [^W^W the frame] length is:
- * - * 320 kbps * 1152/48 kHz = 7680 bit = 960 byte - * - * This value is used as the maximum buffer per channel [^W^W] at - * lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps - * stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit - * [per granule and channel] at 48 kHz sampling frequency. - * This means that there is a maximum deviation (short time buffer - * [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps. - * The actual deviation is equal to the number of bytes [with the - * meaning of octets] denoted by the main_data_end offset pointer. - * The actual maximum deviation is (2^9-1)*8 bit = 4088 bits - * [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits]. - * ... The xchange of buffer bits between the left and right channel - * is allowed without restrictions [exception: dual channel]. - * Because of the [constructed] constraint on the buffer size - * main_data_end is always set to 0 in the case of bit_rate_index==14, - * i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case - * all data are allocated between adjacent header [^W sync] words - * [, i.e. there is no buffering at all]. - *
- */ + /* have to allow for the case when bigvalues < region0 < region1 */ + /* (and region0, region1 are ignored) */ + a1 = Math.min(a1, i); + a2 = Math.min(a2, i); -function Reservoir() { - var bs; + /* Count the number of bits necessary to code the bigvalues region. */ + if (0 < a1) { + var bi = new Bits(bits); + gi.table_select[0] = choose_table(ix, 0, a1, bi); + bits = bi.bits; + } + if (a1 < a2) { + var bi = new Bits(bits); + gi.table_select[1] = choose_table(ix, a1, a2, bi); + bits = bi.bits; + } + if (gfc.use_best_huffman == 2) { + gi.part2_3_length = bits; + best_huffman_divide(gfc, gi); + bits = gi.part2_3_length; + } - this.setModules = function(_bs) { - bs = _bs; - } + if (prev_noise != null) { + if (gi.block_type == Encoder.NORM_TYPE) { + var sfb = 0; + while (gfc.scalefac_band.l[sfb] < gi.big_values) { + sfb++; + } + prev_noise.sfb_count1 = sfb; + } + } - this.ResvFrameBegin = function(gfp, mean_bits) { - var gfc = gfp.internal_flags; - var maxmp3buf; - var l3_side = gfc.l3_side; + return bits; + } - var frameLength = bs.getframebits(gfp); - mean_bits.bits = (frameLength - gfc.sideinfo_len * 8) / gfc.mode_gr; + this.count_bits = function (gfc, xr, gi, prev_noise) { + var ix = gi.l3_enc; - /** - *
-		 *  Meaning of the variables:
-		 *      resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1))
-		 *          Number of bits can be stored in previous frame(s) due to
-		 *          counter size constaints
-		 *      maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5))
-		 *          Number of bits allowed to encode one frame (you can take 8*511 bit
-		 *          from the bit reservoir and at most 8*1440 bit from the current
-		 *          frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible
-		 *          value for MPEG-1 and -2)
-		 * 
-		 *          maximum allowed granule/channel size times 4 = 8*2047 bits.,
-		 *          so this is the absolute maximum supported by the format.
-		 * 
-		 * 
-		 *      fullFrameBits:  maximum number of bits available for encoding
-		 *                      the current frame.
-		 * 
-		 *      mean_bits:      target number of bits per granule.
-		 * 
-		 *      frameLength:
-		 * 
-		 *      gfc.ResvMax:   maximum allowed reservoir
-		 * 
-		 *      gfc.ResvSize:  current reservoir size
-		 * 
-		 *      l3_side.resvDrain_pre:
-		 *         ancillary data to be added to previous frame:
-		 *         (only usefull in VBR modes if it is possible to have
-		 *         maxmp3buf < fullFrameBits)).  Currently disabled,
-		 *         see #define NEW_DRAIN
-		 *         2010-02-13: RH now enabled, it seems to be needed for CBR too,
-		 *                     as there exists one example, where the FhG decoder
-		 *                     can't decode a -b320 CBR file anymore.
-		 * 
-		 *      l3_side.resvDrain_post:
-		 *         ancillary data to be added to this frame:
-		 * 
-		 * 
- */ + /* since quantize_xrpow uses table lookup, we need to check this first: */ + var w = (QuantizePVT.IXMAX_VAL) / qupvt.IPOW20(gi.global_gain); - /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */ - var resvLimit = (8 * 256) * gfc.mode_gr - 8; + if (gi.xrpow_max > w) + return QuantizePVT.LARGE_BITS; - /* - * maximum allowed frame size. dont use more than this number of bits, - * even if the frame has the space for them: - */ - if (gfp.brate > 320) { - /* in freeformat the buffer is constant */ - maxmp3buf = 8 * ((int) ((gfp.brate * 1000) - / (gfp.out_samplerate / 1152) / 8 + .5)); - } else { - /* - * all mp3 decoders should have enough buffer to handle this value: - * size of a 320kbps 32kHz frame - */ - maxmp3buf = 8 * 1440; + quantize_xrpow(xr, ix, qupvt.IPOW20(gi.global_gain), gi, prev_noise); - /* - * Bouvigne suggests this more lax interpretation of the ISO doc - * instead of using 8*960. - */ + if ((gfc.substep_shaping & 2) != 0) { + var j = 0; + /* 0.634521682242439 = 0.5946*2**(.5*0.1875) */ + var gain = gi.global_gain + gi.scalefac_scale; + var roundfac = 0.634521682242439 / qupvt.IPOW20(gain); + for (var sfb = 0; sfb < gi.sfbmax; sfb++) { + var width = gi.width[sfb]; + if (0 == gfc.pseudohalf[sfb]) { + j += width; + } else { + var k; + for (k = j, j += width; k < j; ++k) { + ix[k] = (xr[k] >= roundfac) ? ix[k] : 0; + } + } + } + } + return this.noquant_count_bits(gfc, gi, prev_noise); + } - if (gfp.strict_ISO) { - maxmp3buf = 8 * ((int) (320000 / (gfp.out_samplerate / 1152) / 8 + .5)); - } - } + /** + * re-calculate the best scalefac_compress using scfsi the saved bits are + * kept in the bit reservoir. + */ + function recalc_divide_init(gfc, cod_info, ix, r01_bits, r01_div, r0_tbl, r1_tbl) { + var bigv = cod_info.big_values; - gfc.ResvMax = maxmp3buf - frameLength; - if (gfc.ResvMax > resvLimit) - gfc.ResvMax = resvLimit; - if (gfc.ResvMax < 0 || gfp.disable_reservoir) - gfc.ResvMax = 0; + for (var r0 = 0; r0 <= 7 + 15; r0++) { + r01_bits[r0] = QuantizePVT.LARGE_BITS; + } - var fullFrameBits = mean_bits.bits * gfc.mode_gr - + Math.min(gfc.ResvSize, gfc.ResvMax); + for (var r0 = 0; r0 < 16; r0++) { + var a1 = gfc.scalefac_band.l[r0 + 1]; + if (a1 >= bigv) + break; + var r0bits = 0; + var bi = new Bits(r0bits); + var r0t = choose_table(ix, 0, a1, bi); + r0bits = bi.bits; - if (fullFrameBits > maxmp3buf) - fullFrameBits = maxmp3buf; + for (var r1 = 0; r1 < 8; r1++) { + var a2 = gfc.scalefac_band.l[r0 + r1 + 2]; + if (a2 >= bigv) + break; + var bits = r0bits; + bi = new Bits(bits); + var r1t = choose_table(ix, a1, a2, bi); + bits = bi.bits; + if (r01_bits[r0 + r1] > bits) { + r01_bits[r0 + r1] = bits; + r01_div[r0 + r1] = r0; + r0_tbl[r0 + r1] = r0t; + r1_tbl[r0 + r1] = r1t; + } + } + } + } + function recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl) { + var bigv = cod_info2.big_values; - l3_side.resvDrain_pre = 0; + for (var r2 = 2; r2 < Encoder.SBMAX_l + 1; r2++) { + var a2 = gfc.scalefac_band.l[r2]; + if (a2 >= bigv) + break; + var bits = r01_bits[r2 - 2] + cod_info2.count1bits; + if (gi.part2_3_length <= bits) + break; + + var bi = new Bits(bits); + var r2t = choose_table(ix, a2, bigv, bi); + bits = bi.bits; + if (gi.part2_3_length <= bits) + continue; - // frame analyzer code - if (gfc.pinfo != null) { - /* - * expected bits per channel per granule [is this also right for - * mono/stereo, MPEG-1/2 ?] - */ - gfc.pinfo.mean_bits = mean_bits.bits / 2; - gfc.pinfo.resvsize = gfc.ResvSize; - } + gi.assign(cod_info2); + gi.part2_3_length = bits; + gi.region0_count = r01_div[r2 - 2]; + gi.region1_count = r2 - 2 - r01_div[r2 - 2]; + gi.table_select[0] = r0_tbl[r2 - 2]; + gi.table_select[1] = r1_tbl[r2 - 2]; + gi.table_select[2] = r2t; + } + } - return fullFrameBits; - } + this.best_huffman_divide = function (gfc, gi) { + var cod_info2 = new GrInfo(); + var ix = gi.l3_enc; + var r01_bits = new_int(7 + 15 + 1); + var r01_div = new_int(7 + 15 + 1); + var r0_tbl = new_int(7 + 15 + 1); + var r1_tbl = new_int(7 + 15 + 1); - /** - * returns targ_bits: target number of bits to use for 1 granule
- * extra_bits: amount extra available from reservoir
- * Mark Taylor 4/99 - */ - this.ResvMaxBits = function(gfp, mean_bits, targ_bits, cbr) { - var gfc = gfp.internal_flags; - var add_bits; - var ResvSize = gfc.ResvSize, ResvMax = gfc.ResvMax; + /* SHORT BLOCK stuff fails for MPEG2 */ + if (gi.block_type == Encoder.SHORT_TYPE && gfc.mode_gr == 1) + return; - /* compensate the saved bits used in the 1st granule */ - if (cbr != 0) - ResvSize += mean_bits; + cod_info2.assign(gi); + if (gi.block_type == Encoder.NORM_TYPE) { + recalc_divide_init(gfc, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl); + recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, + r0_tbl, r1_tbl); + } + var i = cod_info2.big_values; + if (i == 0 || (ix[i - 2] | ix[i - 1]) > 1) + return; - if ((gfc.substep_shaping & 1) != 0) - ResvMax *= 0.9; + i = gi.count1 + 2; + if (i > 576) + return; - targ_bits.bits = mean_bits; + /* Determines the number of bits to encode the quadruples. */ + cod_info2.assign(gi); + cod_info2.count1 = i; + var a1 = 0; + var a2 = 0; - /* extra bits if the reservoir is almost full */ - if (ResvSize * 10 > ResvMax * 9) { - add_bits = ResvSize - (ResvMax * 9) / 10; - targ_bits.bits += add_bits; - gfc.substep_shaping |= 0x80; - } else { - add_bits = 0; - gfc.substep_shaping &= 0x7f; - /* - * build up reservoir. this builds the reservoir a little slower - * than FhG. It could simple be mean_bits/15, but this was rigged to - * always produce 100 (the old value) at 128kbs - */ - if (!gfp.disable_reservoir && 0 == (gfc.substep_shaping & 1)) - targ_bits.bits -= .1 * mean_bits; - } - /* amount from the reservoir we are allowed to use. ISO says 6/10 */ - var extra_bits = (ResvSize < (gfc.ResvMax * 6) / 10 ? ResvSize - : (gfc.ResvMax * 6) / 10); - extra_bits -= add_bits; + for (; i > cod_info2.big_values; i -= 4) { + var p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + + ix[i - 1]; + a1 += Tables.t32l[p]; + a2 += Tables.t33l[p]; + } + cod_info2.big_values = i; - if (extra_bits < 0) - extra_bits = 0; - return extra_bits; - } + cod_info2.count1table_select = 0; + if (a1 > a2) { + a1 = a2; + cod_info2.count1table_select = 1; + } - /** - * Called after a granule's bit allocation. Readjusts the size of the - * reservoir to reflect the granule's usage. - */ - this.ResvAdjust = function(gfc, gi) { - gfc.ResvSize -= gi.part2_3_length + gi.part2_length; - } + cod_info2.count1bits = a1; - /** - * Called after all granules in a frame have been allocated. Makes sure that - * the reservoir size is within limits, possibly by adding stuffing bits. - */ - this.ResvFrameEnd = function(gfc, mean_bits) { - var over_bits; - var l3_side = gfc.l3_side; + if (cod_info2.block_type == Encoder.NORM_TYPE) + recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, + r0_tbl, r1_tbl); + else { + /* Count the number of bits necessary to code the bigvalues region. */ + cod_info2.part2_3_length = a1; + a1 = gfc.scalefac_band.l[7 + 1]; + if (a1 > i) { + a1 = i; + } + if (a1 > 0) { + var bi = new Bits(cod_info2.part2_3_length); + cod_info2.table_select[0] = choose_table(ix, 0, a1, bi); + cod_info2.part2_3_length = bi.bits; + } + if (i > a1) { + var bi = new Bits(cod_info2.part2_3_length); + cod_info2.table_select[1] = choose_table(ix, a1, i, bi); + cod_info2.part2_3_length = bi.bits; + } + if (gi.part2_3_length > cod_info2.part2_3_length) + gi.assign(cod_info2); + } + } - gfc.ResvSize += mean_bits * gfc.mode_gr; - var stuffingBits = 0; - l3_side.resvDrain_post = 0; - l3_side.resvDrain_pre = 0; + var slen1_n = [1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16]; + var slen2_n = [1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8]; + var slen1_tab = [0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4]; + var slen2_tab = [0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3]; + Takehiro.slen1_tab = slen1_tab; + Takehiro.slen2_tab = slen2_tab; - /* we must be byte aligned */ - if ((over_bits = gfc.ResvSize % 8) != 0) - stuffingBits += over_bits; + function scfsi_calc(ch, l3_side) { + var sfb; + var gi = l3_side.tt[1][ch]; + var g0 = l3_side.tt[0][ch]; - over_bits = (gfc.ResvSize - stuffingBits) - gfc.ResvMax; - if (over_bits > 0) { - stuffingBits += over_bits; - } + for (var i = 0; i < Tables.scfsi_band.length - 1; i++) { + for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { + if (g0.scalefac[sfb] != gi.scalefac[sfb] + && gi.scalefac[sfb] >= 0) + break; + } + if (sfb == Tables.scfsi_band[i + 1]) { + for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { + gi.scalefac[sfb] = -1; + } + l3_side.scfsi[ch][i] = 1; + } + } + var s1 = 0; + var c1 = 0; + for (sfb = 0; sfb < 11; sfb++) { + if (gi.scalefac[sfb] == -1) + continue; + c1++; + if (s1 < gi.scalefac[sfb]) + s1 = gi.scalefac[sfb]; + } + var s2 = 0; + var c2 = 0; + for (; sfb < Encoder.SBPSY_l; sfb++) { + if (gi.scalefac[sfb] == -1) + continue; + c2++; + if (s2 < gi.scalefac[sfb]) + s2 = gi.scalefac[sfb]; + } - /* - * NOTE: enabling the NEW_DRAIN code fixes some problems with FhG - * decoder shipped with MS Windows operating systems. Using this, it is - * even possible to use Gabriel's lax buffer consideration again, which - * assumes, any decoder should have a buffer large enough for a 320 kbps - * frame at 32 kHz sample rate. - * - * old drain code: lame -b320 BlackBird.wav --. does not play with - * GraphEdit.exe using FhG decoder V1.5 Build 50 - * - * new drain code: lame -b320 BlackBird.wav --. plays fine with - * GraphEdit.exe using FhG decoder V1.5 Build 50 - * - * Robert Hegemann, 2010-02-13. - */ - /* - * drain as many bits as possible into previous frame ancillary data In - * particular, in VBR mode ResvMax may have changed, and we have to make - * sure main_data_begin does not create a reservoir bigger than ResvMax - * mt 4/00 - */ - { - var mdb_bytes = Math.min(l3_side.main_data_begin * 8, stuffingBits) / 8; - l3_side.resvDrain_pre += 8 * mdb_bytes; - stuffingBits -= 8 * mdb_bytes; - gfc.ResvSize -= 8 * mdb_bytes; - l3_side.main_data_begin -= mdb_bytes; - } - /* drain the rest into this frames ancillary data */ - l3_side.resvDrain_post += stuffingBits; - gfc.ResvSize -= stuffingBits; - } -} + for (var i = 0; i < 16; i++) { + if (s1 < slen1_n[i] && s2 < slen2_n[i]) { + var c = slen1_tab[i] * c1 + slen2_tab[i] * c2; + if (gi.part2_length > c) { + gi.part2_length = c; + gi.scalefac_compress = i; + } + } + } + } -/* - * MP3 huffman table selecting and bit counting - * - * Copyright (c) 1999-2005 Takehiro TOMINAGA - * Copyright (c) 2002-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ + /** + * Find the optimal way to store the scalefactors. Only call this routine + * after final scalefactors have been chosen and the channel/granule will + * not be re-encoded. + */ + this.best_scalefac_store = function (gfc, gr, ch, l3_side) { + /* use scalefac_scale if we can */ + var gi = l3_side.tt[gr][ch]; + var sfb, i, j, l; + var recalc = 0; -/* $Id: Takehiro.java,v 1.26 2011/05/24 20:48:06 kenchis Exp $ */ + /* + * remove scalefacs from bands with ix=0. This idea comes from the AAC + * ISO docs. added mt 3/00 + */ + /* check if l3_enc=0 */ + j = 0; + for (sfb = 0; sfb < gi.sfbmax; sfb++) { + var width = gi.width[sfb]; + j += width; + for (l = -width; l < 0; l++) { + if (gi.l3_enc[l + j] != 0) + break; + } + if (l == 0) + gi.scalefac[sfb] = recalc = -2; + /* anything goes. */ + /* + * only best_scalefac_store and calc_scfsi know--and only they + * should know--about the magic number -2. + */ + } -//package mp3; + if (0 == gi.scalefac_scale && 0 == gi.preflag) { + var s = 0; + for (sfb = 0; sfb < gi.sfbmax; sfb++) + if (gi.scalefac[sfb] > 0) + s |= gi.scalefac[sfb]; -//import java.util.Arrays; + if (0 == (s & 1) && s != 0) { + for (sfb = 0; sfb < gi.sfbmax; sfb++) + if (gi.scalefac[sfb] > 0) + gi.scalefac[sfb] >>= 1; + gi.scalefac_scale = recalc = 1; + } + } + if (0 == gi.preflag && gi.block_type != Encoder.SHORT_TYPE + && gfc.mode_gr == 2) { + for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) + if (gi.scalefac[sfb] < qupvt.pretab[sfb] + && gi.scalefac[sfb] != -2) + break; + if (sfb == Encoder.SBPSY_l) { + for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) + if (gi.scalefac[sfb] > 0) + gi.scalefac[sfb] -= qupvt.pretab[sfb]; -function Takehiro() { + gi.preflag = recalc = 1; + } + } - var qupvt = null; - this.qupvt = null; + for (i = 0; i < 4; i++) + l3_side.scfsi[ch][i] = 0; - this.setModules = function (_qupvt) { - this.qupvt = _qupvt; - qupvt = _qupvt; + if (gfc.mode_gr == 2 && gr == 1 + && l3_side.tt[0][ch].block_type != Encoder.SHORT_TYPE + && l3_side.tt[1][ch].block_type != Encoder.SHORT_TYPE) { + scfsi_calc(ch, l3_side); + recalc = 0; + } + for (sfb = 0; sfb < gi.sfbmax; sfb++) { + if (gi.scalefac[sfb] == -2) { + gi.scalefac[sfb] = 0; + /* if anything goes, then 0 is a good choice */ + } + } + if (recalc != 0) { + if (gfc.mode_gr == 2) { + this.scale_bitcount(gi); + } else { + this.scale_bitcount_lsf(gfc, gi); + } + } } - function Bits(b) { - this.bits = 0 | b; + function all_scalefactors_not_negative(scalefac, n) { + for (var i = 0; i < n; ++i) { + if (scalefac[i] < 0) + return false; + } + return true; } - var subdv_table = [[0, 0], /* 0 bands */ - [0, 0], /* 1 bands */ - [0, 0], /* 2 bands */ - [0, 0], /* 3 bands */ - [0, 0], /* 4 bands */ - [0, 1], /* 5 bands */ - [1, 1], /* 6 bands */ - [1, 1], /* 7 bands */ - [1, 2], /* 8 bands */ - [2, 2], /* 9 bands */ - [2, 3], /* 10 bands */ - [2, 3], /* 11 bands */ - [3, 4], /* 12 bands */ - [3, 4], /* 13 bands */ - [3, 4], /* 14 bands */ - [4, 5], /* 15 bands */ - [4, 5], /* 16 bands */ - [4, 6], /* 17 bands */ - [5, 6], /* 18 bands */ - [5, 6], /* 19 bands */ - [5, 7], /* 20 bands */ - [6, 7], /* 21 bands */ - [6, 7], /* 22 bands */ - ]; - /** - * nonlinear quantization of xr More accurate formula than the ISO formula. - * Takes into account the fact that we are quantizing xr . ix, but we want - * ix^4/3 to be as close as possible to x^4/3. (taking the nearest int would - * mean ix is as close as possible to xr, which is different.) - * - * From Segher Boessenkool 11/1999 - * - * 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro Tominaga. - * If you need the ASM code, check CVS circa Aug 2000. + * number of bits used to encode scalefacs. * - * 01/2004: Optimizations by Gabriel Bouvigne + * 18*slen1_tab[i] + 18*slen2_tab[i] */ - function quantize_lines_xrpow_01(l, istep, xr, xrPos, ix, ixPos) { - var compareval0 = (1.0 - 0.4054) / istep; - - l = l >> 1; - while ((l--) != 0) { - ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; - ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; - } - } + var scale_short = [0, 18, 36, 54, 54, 36, 54, 72, + 54, 72, 90, 72, 90, 108, 108, 126]; /** - * XRPOW_FTOI is a macro to convert floats to ints.
- * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
- * ROUNDFAC= -0.0946
+ * number of bits used to encode scalefacs. * - * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]
- * ROUNDFAC=0.4054
+ * 17*slen1_tab[i] + 18*slen2_tab[i] + */ + var scale_mixed = [0, 18, 36, 54, 51, 35, 53, 71, + 52, 70, 88, 69, 87, 105, 104, 122]; + + /** + * number of bits used to encode scalefacs. * - * Note: using floor() or 0| is extremely slow. On machines where the - * TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile to write - * some ASM for XRPOW_FTOI(). + * 11*slen1_tab[i] + 10*slen2_tab[i] */ - function quantize_lines_xrpow(l, istep, xr, xrPos, ix, ixPos) { + var scale_long = [0, 10, 20, 30, 33, 21, 31, 41, 32, 42, + 52, 43, 53, 63, 64, 74]; - l = l >> 1; - var remaining = l % 2; - l = l >> 1; - while (l-- != 0) { - var x0, x1, x2, x3; - var rx0, rx1, rx2, rx3; + /** + * Also calculates the number of bits necessary to code the scalefactors. + */ + this.scale_bitcount = function (cod_info) { + var k, sfb, max_slen1 = 0, max_slen2 = 0; - x0 = xr[xrPos++] * istep; - x1 = xr[xrPos++] * istep; - rx0 = 0 | x0; - x2 = xr[xrPos++] * istep; - rx1 = 0 | x1; - x3 = xr[xrPos++] * istep; - rx2 = 0 | x2; - x0 += qupvt.adj43[rx0]; - rx3 = 0 | x3; - x1 += qupvt.adj43[rx1]; - ix[ixPos++] = 0 | x0; - x2 += qupvt.adj43[rx2]; - ix[ixPos++] = 0 | x1; - x3 += qupvt.adj43[rx3]; - ix[ixPos++] = 0 | x2; - ix[ixPos++] = 0 | x3; + /* maximum values */ + var tab; + var scalefac = cod_info.scalefac; + + + if (cod_info.block_type == Encoder.SHORT_TYPE) { + tab = scale_short; + if (cod_info.mixed_block_flag != 0) + tab = scale_mixed; + } else { /* block_type == 1,2,or 3 */ + tab = scale_long; + if (0 == cod_info.preflag) { + for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) + if (scalefac[sfb] < qupvt.pretab[sfb]) + break; + + if (sfb == Encoder.SBPSY_l) { + cod_info.preflag = 1; + for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) + scalefac[sfb] -= qupvt.pretab[sfb]; + } + } } - if (remaining != 0) { - var x0, x1; - var rx0, rx1; - x0 = xr[xrPos++] * istep; - x1 = xr[xrPos++] * istep; - rx0 = 0 | x0; - rx1 = 0 | x1; - x0 += qupvt.adj43[rx0]; - x1 += qupvt.adj43[rx1]; - ix[ixPos++] = 0 | x0; - ix[ixPos++] = 0 | x1; + for (sfb = 0; sfb < cod_info.sfbdivide; sfb++) + if (max_slen1 < scalefac[sfb]) + max_slen1 = scalefac[sfb]; + + for (; sfb < cod_info.sfbmax; sfb++) + if (max_slen2 < scalefac[sfb]) + max_slen2 = scalefac[sfb]; + + /* + * from Takehiro TOMINAGA 10/99 loop over *all* + * posible values of scalefac_compress to find the one which uses the + * smallest number of bits. ISO would stop at first valid index + */ + cod_info.part2_length = QuantizePVT.LARGE_BITS; + for (k = 0; k < 16; k++) { + if (max_slen1 < slen1_n[k] && max_slen2 < slen2_n[k] + && cod_info.part2_length > tab[k]) { + cod_info.part2_length = tab[k]; + cod_info.scalefac_compress = k; + } } + return cod_info.part2_length == QuantizePVT.LARGE_BITS; } /** - * Quantization function This function will select which lines to quantize - * and call the proper quantization function + * table of largest scalefactor values for MPEG2 + */ + var max_range_sfac_tab = [[15, 15, 7, 7], + [15, 15, 7, 0], [7, 3, 0, 0], [15, 31, 31, 0], + [7, 7, 7, 0], [3, 3, 0, 0]]; + + /** + * Also counts the number of bits to encode the scalefacs but for MPEG 2 + * Lower sampling frequencies (24, 22.05 and 16 kHz.) + * + * This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS, + * "Audio Decoding Layer III" */ - function quantize_xrpow(xp, pi, istep, codInfo, prevNoise) { - /* quantize on xr^(3/4) instead of xr */ - var sfb; - var sfbmax; - var j = 0; - var prev_data_use; - var accumulate = 0; - var accumulate01 = 0; - var xpPos = 0; - var iData = pi; - var iDataPos = 0; - var acc_iData = iData; - var acc_iDataPos = 0; - var acc_xp = xp; - var acc_xpPos = 0; + this.scale_bitcount_lsf = function (gfc, cod_info) { + var table_number, row_in_table, partition, nr_sfb, window; + var over; + var i, sfb; + var max_sfac = new_int(4); +//var partition_table; + var scalefac = cod_info.scalefac; /* - * Reusing previously computed data does not seems to work if global - * gain is changed. Finding why it behaves this way would allow to use a - * cache of previously computed values (let's 10 cached values per sfb) - * that would probably provide a noticeable speedup + * Set partition table. Note that should try to use table one, but do + * not yet... */ - prev_data_use = (prevNoise != null && (codInfo.global_gain == prevNoise.global_gain)); - - if (codInfo.block_type == Encoder.SHORT_TYPE) - sfbmax = 38; + if (cod_info.preflag != 0) + table_number = 2; else - sfbmax = 21; + table_number = 0; - for (sfb = 0; sfb <= sfbmax; sfb++) { - var step = -1; + for (i = 0; i < 4; i++) + max_sfac[i] = 0; - if (prev_data_use || codInfo.block_type == Encoder.NORM_TYPE) { - step = codInfo.global_gain - - ((codInfo.scalefac[sfb] + (codInfo.preflag != 0 ? qupvt.pretab[sfb] - : 0)) << (codInfo.scalefac_scale + 1)) - - codInfo.subblock_gain[codInfo.window[sfb]] * 8; + if (cod_info.block_type == Encoder.SHORT_TYPE) { + row_in_table = 1; + var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; + for (sfb = 0, partition = 0; partition < 4; partition++) { + nr_sfb = partition_table[partition] / 3; + for (i = 0; i < nr_sfb; i++, sfb++) + for (window = 0; window < 3; window++) + if (scalefac[sfb * 3 + window] > max_sfac[partition]) + max_sfac[partition] = scalefac[sfb * 3 + window]; } - if (prev_data_use && (prevNoise.step[sfb] == step)) { - /* - * do not recompute this part, but compute accumulated lines - */ - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate = 0; - } - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - } - } else { /* should compute this part */ - var l = codInfo.width[sfb]; + } else { + row_in_table = 0; + var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; + for (sfb = 0, partition = 0; partition < 4; partition++) { + nr_sfb = partition_table[partition]; + for (i = 0; i < nr_sfb; i++, sfb++) + if (scalefac[sfb] > max_sfac[partition]) + max_sfac[partition] = scalefac[sfb]; + } + } - if ((j + codInfo.width[sfb]) > codInfo.max_nonzero_coeff) { - /* do not compute upper zero part */ - var usefullsize; - usefullsize = codInfo.max_nonzero_coeff - j + 1; - Arrays.fill(pi, codInfo.max_nonzero_coeff, 576, 0); - l = usefullsize; + for (over = false, partition = 0; partition < 4; partition++) { + if (max_sfac[partition] > max_range_sfac_tab[table_number][partition]) + over = true; + } + if (!over) { + var slen1, slen2, slen3, slen4; - if (l < 0) { - l = 0; - } + cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; + for (partition = 0; partition < 4; partition++) + cod_info.slen[partition] = log2tab[max_sfac[partition]]; - /* no need to compute higher sfb values */ - sfb = sfbmax + 1; - } + /* set scalefac_compress */ + slen1 = cod_info.slen[0]; + slen2 = cod_info.slen[1]; + slen3 = cod_info.slen[2]; + slen4 = cod_info.slen[3]; - /* accumulate lines to quantize */ - if (0 == accumulate && 0 == accumulate01) { - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - if (prevNoise != null && prevNoise.sfb_count1 > 0 - && sfb >= prevNoise.sfb_count1 - && prevNoise.step[sfb] > 0 - && step >= prevNoise.step[sfb]) { + switch (table_number) { + case 0: + cod_info.scalefac_compress = (((slen1 * 5) + slen2) << 4) + + (slen3 << 2) + slen4; + break; - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate = 0; - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - accumulate01 += l; - } else { - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - accumulate += l; - } + case 1: + cod_info.scalefac_compress = 400 + (((slen1 * 5) + slen2) << 2) + + slen3; + break; - if (l <= 0) { - /* - * rh: 20040215 may happen due to "prev_data_use" - * optimization - */ - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - } - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate = 0; - } + case 2: + cod_info.scalefac_compress = 500 + (slen1 * 3) + slen2; + break; + default: + System.err.printf("intensity stereo not implemented yet\n"); break; - /* ends for-loop */ - } - } - if (sfb <= sfbmax) { - iDataPos += codInfo.width[sfb]; - xpPos += codInfo.width[sfb]; - j += codInfo.width[sfb]; } } - if (accumulate != 0) { /* last data part */ - quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate = 0; - } - if (accumulate01 != 0) { /* last data part */ - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate01 = 0; + if (!over) { + cod_info.part2_length = 0; + for (partition = 0; partition < 4; partition++) + cod_info.part2_length += cod_info.slen[partition] + * cod_info.sfb_partition_table[partition]; } - + return over; } - /** - * ix_max + /* + * Since no bands have been over-amplified, we can set scalefac_compress and + * slen[] for the formatter */ - function ix_max(ix, ixPos, endPos) { - var max1 = 0, max2 = 0; - - do { - var x1 = ix[ixPos++]; - var x2 = ix[ixPos++]; - if (max1 < x1) - max1 = x1; - - if (max2 < x2) - max2 = x2; - } while (ixPos < endPos); - if (max1 < max2) - max1 = max2; - return max1; - } + var log2tab = [0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, + 4, 4, 4, 4]; - function count_bit_ESC(ix, ixPos, end, t1, t2, s) { - /* ESC-table is used */ - var linbits = Tables.ht[t1].xlen * 65536 + Tables.ht[t2].xlen; - var sum = 0, sum2; + this.huffman_init = function (gfc) { + for (var i = 2; i <= 576; i += 2) { + var scfb_anz = 0, bv_index; + while (gfc.scalefac_band.l[++scfb_anz] < i) + ; - do { - var x = ix[ixPos++]; - var y = ix[ixPos++]; + bv_index = subdv_table[scfb_anz][0]; // .region0_count + while (gfc.scalefac_band.l[bv_index + 1] > i) + bv_index--; - if (x != 0) { - if (x > 14) { - x = 15; - sum += linbits; - } - x *= 16; + if (bv_index < 0) { + /* + * this is an indication that everything is going to be encoded + * as region0: bigvalues < region0 < region1 so lets set + * region0, region1 to some value larger than bigvalues + */ + bv_index = subdv_table[scfb_anz][0]; // .region0_count } - if (y != 0) { - if (y > 14) { - y = 15; - sum += linbits; - } - x += y; - } + gfc.bv_scf[i - 2] = bv_index; - sum += Tables.largetbl[x]; - } while (ixPos < end); + bv_index = subdv_table[scfb_anz][1]; // .region1_count + while (gfc.scalefac_band.l[bv_index + gfc.bv_scf[i - 2] + 2] > i) + bv_index--; - sum2 = sum & 0xffff; - sum >>= 16; + if (bv_index < 0) { + bv_index = subdv_table[scfb_anz][1]; // .region1_count + } - if (sum > sum2) { - sum = sum2; - t1 = t2; + gfc.bv_scf[i - 1] = bv_index; } - - s.bits += sum; - return t1; } +} - function count_bit_noESC(ix, ixPos, end, s) { - /* No ESC-words */ - var sum1 = 0; - var hlen1 = Tables.ht[1].hlen; - - do { - var x = ix[ixPos + 0] * 2 + ix[ixPos + 1]; - ixPos += 2; - sum1 += hlen1[x]; - } while (ixPos < end); +/* + * ReplayGainAnalysis - analyzes input samples and give the recommended dB change + * Copyright (C) 2001 David Robinson and Glen Sawyer + * Improvements and optimizations added by Frank Klemm, and by Marcel Muller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * concept and filter values by David Robinson (David@Robinson.org) + * -- blame him if you think the idea is flawed + * original coding by Glen Sawyer (mp3gain@hotmail.com) + * -- blame him if you think this runs too slowly, or the coding is otherwise flawed + * + * lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ ) + * -- credit him for all the _good_ programming ;) + * + * + * For an explanation of the concepts and the basic algorithms involved, go to: + * http://www.replaygain.org/ + */ - s.bits += sum1; - return 1; - } +/* + * Here's the deal. Call + * + * InitGainAnalysis ( long samplefreq ); + * + * to initialize everything. Call + * + * AnalyzeSamples ( var Float_t* left_samples, + * var Float_t* right_samples, + * size_t num_samples, + * int num_channels ); + * + * as many times as you want, with as many or as few samples as you want. + * If mono, pass the sample buffer in through left_samples, leave + * right_samples NULL, and make sure num_channels = 1. + * + * GetTitleGain() + * + * will return the recommended dB level change for all samples analyzed + * SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis(). + * + * GetAlbumGain() + * + * will return the recommended dB level change for all samples analyzed + * since InitGainAnalysis() was called and finalized with GetTitleGain(). + * + * Pseudo-code to process an album: + * + * Float_t l_samples [4096]; + * Float_t r_samples [4096]; + * size_t num_samples; + * unsigned int num_songs; + * unsigned int i; + * + * InitGainAnalysis ( 44100 ); + * for ( i = 1; i <= num_songs; i++ ) { + * while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 ) + * AnalyzeSamples ( left_samples, right_samples, num_samples, 2 ); + * fprintf ("Recommended dB change for song %2d: %+6.2 dB\n", i, GetTitleGain() ); + * } + * fprintf ("Recommended dB change for whole album: %+6.2 dB\n", GetAlbumGain() ); + */ - function count_bit_noESC_from2(ix, ixPos, end, t1, s) { - /* No ESC-words */ - var sum = 0, sum2; - var xlen = Tables.ht[t1].xlen; - var hlen; - if (t1 == 2) - hlen = Tables.table23; - else - hlen = Tables.table56; +/* + * So here's the main source of potential code confusion: + * + * The filters applied to the incoming samples are IIR filters, + * meaning they rely on up to number of previous samples + * AND up to number of previous filtered samples. + * + * I set up the AnalyzeSamples routine to minimize memory usage and interface + * complexity. The speed isn't compromised too much (I don't think), but the + * internal complexity is higher than it should be for such a relatively + * simple routine. + * + * Optimization/clarity suggestions are welcome. + */ - do { - var x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; - ixPos += 2; - sum += hlen[x]; - } while (ixPos < end); +/** + * Table entries per dB + */ +GainAnalysis.STEPS_per_dB = 100.; +/** + * Table entries for 0...MAX_dB (normal max. values are 70...80 dB) + */ +GainAnalysis.MAX_dB = 120.; +GainAnalysis.GAIN_NOT_ENOUGH_SAMPLES = -24601; +GainAnalysis.GAIN_ANALYSIS_ERROR = 0; +GainAnalysis.GAIN_ANALYSIS_OK = 1; +GainAnalysis.INIT_GAIN_ANALYSIS_ERROR = 0; +GainAnalysis.INIT_GAIN_ANALYSIS_OK = 1; - sum2 = sum & 0xffff; - sum >>= 16; +GainAnalysis.YULE_ORDER = 10; +GainAnalysis.MAX_ORDER = GainAnalysis.YULE_ORDER; - if (sum > sum2) { - sum = sum2; - t1++; - } +GainAnalysis.MAX_SAMP_FREQ = 48000; +GainAnalysis.RMS_WINDOW_TIME_NUMERATOR = 1; +GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR = 20; +GainAnalysis.MAX_SAMPLES_PER_WINDOW = ((GainAnalysis.MAX_SAMP_FREQ * GainAnalysis.RMS_WINDOW_TIME_NUMERATOR) / GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR + 1); - s.bits += sum; - return t1; - } +function GainAnalysis() { + /** + * calibration value for 89dB + */ + var PINK_REF = 64.82; - function count_bit_noESC_from3(ix, ixPos, end, t1, s) { - /* No ESC-words */ - var sum1 = 0; - var sum2 = 0; - var sum3 = 0; - var xlen = Tables.ht[t1].xlen; - var hlen1 = Tables.ht[t1].hlen; - var hlen2 = Tables.ht[t1 + 1].hlen; - var hlen3 = Tables.ht[t1 + 2].hlen; + var YULE_ORDER = GainAnalysis.YULE_ORDER; + /** + * percentile which is louder than the proposed level + */ + var RMS_PERCENTILE = 0.95; + /** + * maximum allowed sample frequency [Hz] + */ + var MAX_SAMP_FREQ = GainAnalysis.MAX_SAMP_FREQ; + var RMS_WINDOW_TIME_NUMERATOR = GainAnalysis.RMS_WINDOW_TIME_NUMERATOR; + /** + * numerator / denominator = time slice size [s] + */ + var RMS_WINDOW_TIME_DENOMINATOR = GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR; + /** + * max. Samples per Time slice + */ + var MAX_SAMPLES_PER_WINDOW = GainAnalysis.MAX_SAMPLES_PER_WINDOW; - do { - var x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; - ixPos += 2; - sum1 += hlen1[x]; - sum2 += hlen2[x]; - sum3 += hlen3[x]; - } while (ixPos < end); - var t = t1; - if (sum1 > sum2) { - sum1 = sum2; - t++; - } - if (sum1 > sum3) { - sum1 = sum3; - t = t1 + 2; - } - s.bits += sum1; - return t; - } + var ABYule = [ + [0.03857599435200, -3.84664617118067, -0.02160367184185, + 7.81501653005538, -0.00123395316851, -11.34170355132042, + -0.00009291677959, 13.05504219327545, -0.01655260341619, + -12.28759895145294, 0.02161526843274, 9.48293806319790, + -0.02074045215285, -5.87257861775999, 0.00594298065125, + 2.75465861874613, 0.00306428023191, -0.86984376593551, + 0.00012025322027, 0.13919314567432, 0.00288463683916], + [0.05418656406430, -3.47845948550071, -0.02911007808948, + 6.36317777566148, -0.00848709379851, -8.54751527471874, + -0.00851165645469, 9.47693607801280, -0.00834990904936, + -8.81498681370155, 0.02245293253339, 6.85401540936998, + -0.02596338512915, -4.39470996079559, 0.01624864962975, + 2.19611684890774, -0.00240879051584, -0.75104302451432, + 0.00674613682247, 0.13149317958808, -0.00187763777362], + [0.15457299681924, -2.37898834973084, -0.09331049056315, + 2.84868151156327, -0.06247880153653, -2.64577170229825, + 0.02163541888798, 2.23697657451713, -0.05588393329856, + -1.67148153367602, 0.04781476674921, 1.00595954808547, + 0.00222312597743, -0.45953458054983, 0.03174092540049, + 0.16378164858596, -0.01390589421898, -0.05032077717131, + 0.00651420667831, 0.02347897407020, -0.00881362733839], + [0.30296907319327, -1.61273165137247, -0.22613988682123, + 1.07977492259970, -0.08587323730772, -0.25656257754070, + 0.03282930172664, -0.16276719120440, -0.00915702933434, + -0.22638893773906, -0.02364141202522, 0.39120800788284, + -0.00584456039913, -0.22138138954925, 0.06276101321749, + 0.04500235387352, -0.00000828086748, 0.02005851806501, + 0.00205861885564, 0.00302439095741, -0.02950134983287], + [0.33642304856132, -1.49858979367799, -0.25572241425570, + 0.87350271418188, -0.11828570177555, 0.12205022308084, + 0.11921148675203, -0.80774944671438, -0.07834489609479, + 0.47854794562326, -0.00469977914380, -0.12453458140019, + -0.00589500224440, -0.04067510197014, 0.05724228140351, + 0.08333755284107, 0.00832043980773, -0.04237348025746, + -0.01635381384540, 0.02977207319925, -0.01760176568150], + [0.44915256608450, -0.62820619233671, -0.14351757464547, + 0.29661783706366, -0.22784394429749, -0.37256372942400, + -0.01419140100551, 0.00213767857124, 0.04078262797139, + -0.42029820170918, -0.12398163381748, 0.22199650564824, + 0.04097565135648, 0.00613424350682, 0.10478503600251, + 0.06747620744683, -0.01863887810927, 0.05784820375801, + -0.03193428438915, 0.03222754072173, 0.00541907748707], + [0.56619470757641, -1.04800335126349, -0.75464456939302, + 0.29156311971249, 0.16242137742230, -0.26806001042947, + 0.16744243493672, 0.00819999645858, -0.18901604199609, + 0.45054734505008, 0.30931782841830, -0.33032403314006, + -0.27562961986224, 0.06739368333110, 0.00647310677246, + -0.04784254229033, 0.08647503780351, 0.01639907836189, + -0.03788984554840, 0.01807364323573, -0.00588215443421], + [0.58100494960553, -0.51035327095184, -0.53174909058578, + -0.31863563325245, -0.14289799034253, -0.20256413484477, + 0.17520704835522, 0.14728154134330, 0.02377945217615, + 0.38952639978999, 0.15558449135573, -0.23313271880868, + -0.25344790059353, -0.05246019024463, 0.01628462406333, + -0.02505961724053, 0.06920467763959, 0.02442357316099, + -0.03721611395801, 0.01818801111503, -0.00749618797172], + [0.53648789255105, -0.25049871956020, -0.42163034350696, + -0.43193942311114, -0.00275953611929, -0.03424681017675, + 0.04267842219415, -0.04678328784242, -0.10214864179676, + 0.26408300200955, 0.14590772289388, 0.15113130533216, + -0.02459864859345, -0.17556493366449, -0.11202315195388, + -0.18823009262115, -0.04060034127000, 0.05477720428674, + 0.04788665548180, 0.04704409688120, -0.02217936801134]]; - /*************************************************************************/ - /* choose table */ - /*************************************************************************/ + var ABButter = [ + [0.98621192462708, -1.97223372919527, -1.97242384925416, + 0.97261396931306, 0.98621192462708], + [0.98500175787242, -1.96977855582618, -1.97000351574484, + 0.97022847566350, 0.98500175787242], + [0.97938932735214, -1.95835380975398, -1.95877865470428, + 0.95920349965459, 0.97938932735214], + [0.97531843204928, -1.95002759149878, -1.95063686409857, + 0.95124613669835, 0.97531843204928], + [0.97316523498161, -1.94561023566527, -1.94633046996323, + 0.94705070426118, 0.97316523498161], + [0.96454515552826, -1.92783286977036, -1.92909031105652, + 0.93034775234268, 0.96454515552826], + [0.96009142950541, -1.91858953033784, -1.92018285901082, + 0.92177618768381, 0.96009142950541], + [0.95856916599601, -1.91542108074780, -1.91713833199203, + 0.91885558323625, 0.95856916599601], + [0.94597685600279, -1.88903307939452, -1.89195371200558, + 0.89487434461664, 0.94597685600279]]; - var huf_tbl_noESC = [1, 2, 5, 7, 7, 10, 10, 13, 13, - 13, 13, 13, 13, 13, 13]; /** - * Choose the Huffman table that will encode ix[begin..end] with the fewest - * bits. - * - * Note: This code contains knowledge about the sizes and characteristics of - * the Huffman tables as defined in the IS (Table B.7), and will not work - * with any arbitrary tables. + * When calling this procedure, make sure that ip[-order] and op[-order] + * point to real data */ - function choose_table(ix, ixPos, endPos, s) { - var max = ix_max(ix, ixPos, endPos); - - switch (max) { - case 0: - return max; - - case 1: - return count_bit_noESC(ix, ixPos, endPos, s); + //private void filterYule(final float[] input, int inputPos, float[] output, + //int outputPos, int nSamples, final float[] kernel) { + function filterYule(input, inputPos, output, outputPos, nSamples, kernel) { - case 2: - case 3: - return count_bit_noESC_from2(ix, ixPos, endPos, - huf_tbl_noESC[max - 1], s); + while ((nSamples--) != 0) { + /* 1e-10 is a hack to avoid slowdown because of denormals */ + output[outputPos] = 1e-10 + input[inputPos + 0] * kernel[0] + - output[outputPos - 1] * kernel[1] + input[inputPos - 1] + * kernel[2] - output[outputPos - 2] * kernel[3] + + input[inputPos - 2] * kernel[4] - output[outputPos - 3] + * kernel[5] + input[inputPos - 3] * kernel[6] + - output[outputPos - 4] * kernel[7] + input[inputPos - 4] + * kernel[8] - output[outputPos - 5] * kernel[9] + + input[inputPos - 5] * kernel[10] - output[outputPos - 6] + * kernel[11] + input[inputPos - 6] * kernel[12] + - output[outputPos - 7] * kernel[13] + input[inputPos - 7] + * kernel[14] - output[outputPos - 8] * kernel[15] + + input[inputPos - 8] * kernel[16] - output[outputPos - 9] + * kernel[17] + input[inputPos - 9] * kernel[18] + - output[outputPos - 10] * kernel[19] + + input[inputPos - 10] * kernel[20]; + ++outputPos; + ++inputPos; + } + } - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - return count_bit_noESC_from3(ix, ixPos, endPos, - huf_tbl_noESC[max - 1], s); +//private void filterButter(final float[] input, int inputPos, +// float[] output, int outputPos, int nSamples, final float[] kernel) { + function filterButter(input, inputPos, output, outputPos, nSamples, kernel) { - default: - /* try tables with linbits */ - if (max > QuantizePVT.IXMAX_VAL) { - s.bits = QuantizePVT.LARGE_BITS; - return -1; - } - max -= 15; - var choice2; - for (choice2 = 24; choice2 < 32; choice2++) { - if (Tables.ht[choice2].linmax >= max) { - break; - } - } - var choice; - for (choice = choice2 - 8; choice < 24; choice++) { - if (Tables.ht[choice].linmax >= max) { - break; - } - } - return count_bit_ESC(ix, ixPos, endPos, choice, choice2, s); + while ((nSamples--) != 0) { + output[outputPos] = input[inputPos + 0] * kernel[0] + - output[outputPos - 1] * kernel[1] + input[inputPos - 1] + * kernel[2] - output[outputPos - 2] * kernel[3] + + input[inputPos - 2] * kernel[4]; + ++outputPos; + ++inputPos; } } /** - * count_bit + * @return INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if + * not */ - this.noquant_count_bits = function (gfc, gi, prev_noise) { - var ix = gi.l3_enc; - var i = Math.min(576, ((gi.max_nonzero_coeff + 2) >> 1) << 1); - - if (prev_noise != null) - prev_noise.sfb_count1 = 0; + function ResetSampleFrequency(rgData, samplefreq) { + /* zero out initial values */ + for (var i = 0; i < MAX_ORDER; i++) + rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.; - /* Determine count1 region */ - for (; i > 1; i -= 2) - if ((ix[i - 1] | ix[i - 2]) != 0) + switch (0 | (samplefreq)) { + case 48000: + rgData.reqindex = 0; break; - gi.count1 = i; - - /* Determines the number of bits to encode the quadruples. */ - var a1 = 0; - var a2 = 0; - for (; i > 3; i -= 4) { - var p; - /* hack to check if all values <= 1 */ - //throw "TODO: HACK if ((((long) ix[i - 1] | (long) ix[i - 2] | (long) ix[i - 3] | (long) ix[i - 4]) & 0xffffffffL) > 1L " - //if (true) { - if (((ix[i - 1] | ix[i - 2] | ix[i - 3] | ix[i - 4]) & 0x7fffffff) > 1) { + case 44100: + rgData.reqindex = 1; break; - } - p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + ix[i - 1]; - a1 += Tables.t32l[p]; - a2 += Tables.t33l[p]; - } - var bits = a1; - gi.count1table_select = 0; - if (a1 > a2) { - bits = a2; - gi.count1table_select = 1; - } - - gi.count1bits = bits; - gi.big_values = i; - if (i == 0) - return bits; - - if (gi.block_type == Encoder.SHORT_TYPE) { - a1 = 3 * gfc.scalefac_band.s[3]; - if (a1 > gi.big_values) - a1 = gi.big_values; - a2 = gi.big_values; - - } else if (gi.block_type == Encoder.NORM_TYPE) { - /* bv_scf has 576 entries (0..575) */ - a1 = gi.region0_count = gfc.bv_scf[i - 2]; - a2 = gi.region1_count = gfc.bv_scf[i - 1]; - - a2 = gfc.scalefac_band.l[a1 + a2 + 2]; - a1 = gfc.scalefac_band.l[a1 + 1]; - if (a2 < i) { - var bi = new Bits(bits); - gi.table_select[2] = choose_table(ix, a2, i, bi); - bits = bi.bits; - } - } else { - gi.region0_count = 7; - /* gi.region1_count = SBPSY_l - 7 - 1; */ - gi.region1_count = Encoder.SBMAX_l - 1 - 7 - 1; - a1 = gfc.scalefac_band.l[7 + 1]; - a2 = i; - if (a1 > a2) { - a1 = a2; - } - } - - /* have to allow for the case when bigvalues < region0 < region1 */ - /* (and region0, region1 are ignored) */ - a1 = Math.min(a1, i); - a2 = Math.min(a2, i); - - - /* Count the number of bits necessary to code the bigvalues region. */ - if (0 < a1) { - var bi = new Bits(bits); - gi.table_select[0] = choose_table(ix, 0, a1, bi); - bits = bi.bits; - } - if (a1 < a2) { - var bi = new Bits(bits); - gi.table_select[1] = choose_table(ix, a1, a2, bi); - bits = bi.bits; - } - if (gfc.use_best_huffman == 2) { - gi.part2_3_length = bits; - best_huffman_divide(gfc, gi); - bits = gi.part2_3_length; - } - - if (prev_noise != null) { - if (gi.block_type == Encoder.NORM_TYPE) { - var sfb = 0; - while (gfc.scalefac_band.l[sfb] < gi.big_values) { - sfb++; - } - prev_noise.sfb_count1 = sfb; - } + case 32000: + rgData.reqindex = 2; + break; + case 24000: + rgData.reqindex = 3; + break; + case 22050: + rgData.reqindex = 4; + break; + case 16000: + rgData.reqindex = 5; + break; + case 12000: + rgData.reqindex = 6; + break; + case 11025: + rgData.reqindex = 7; + break; + case 8000: + rgData.reqindex = 8; + break; + default: + return INIT_GAIN_ANALYSIS_ERROR; } - return bits; - } - - this.count_bits = function (gfc, xr, gi, prev_noise) { - var ix = gi.l3_enc; + rgData.sampleWindow = 0 | ((samplefreq * RMS_WINDOW_TIME_NUMERATOR + + RMS_WINDOW_TIME_DENOMINATOR - 1) / RMS_WINDOW_TIME_DENOMINATOR); - /* since quantize_xrpow uses table lookup, we need to check this first: */ - var w = (QuantizePVT.IXMAX_VAL) / qupvt.IPOW20(gi.global_gain); + rgData.lsum = 0.; + rgData.rsum = 0.; + rgData.totsamp = 0; - if (gi.xrpow_max > w) - return QuantizePVT.LARGE_BITS; + Arrays.ill(rgData.A, 0); - quantize_xrpow(xr, ix, qupvt.IPOW20(gi.global_gain), gi, prev_noise); + return INIT_GAIN_ANALYSIS_OK; + } - if ((gfc.substep_shaping & 2) != 0) { - var j = 0; - /* 0.634521682242439 = 0.5946*2**(.5*0.1875) */ - var gain = gi.global_gain + gi.scalefac_scale; - var roundfac = 0.634521682242439 / qupvt.IPOW20(gain); - for (var sfb = 0; sfb < gi.sfbmax; sfb++) { - var width = gi.width[sfb]; - if (0 == gfc.pseudohalf[sfb]) { - j += width; - } else { - var k; - for (k = j, j += width; k < j; ++k) { - ix[k] = (xr[k] >= roundfac) ? ix[k] : 0; - } - } - } + this.InitGainAnalysis = function (rgData, samplefreq) { + if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) { + return INIT_GAIN_ANALYSIS_ERROR; } - return this.noquant_count_bits(gfc, gi, prev_noise); - } - /** - * re-calculate the best scalefac_compress using scfsi the saved bits are - * kept in the bit reservoir. - */ - function recalc_divide_init(gfc, cod_info, ix, r01_bits, r01_div, r0_tbl, r1_tbl) { - var bigv = cod_info.big_values; + rgData.linpre = MAX_ORDER; + rgData.rinpre = MAX_ORDER; + rgData.lstep = MAX_ORDER; + rgData.rstep = MAX_ORDER; + rgData.lout = MAX_ORDER; + rgData.rout = MAX_ORDER; - for (var r0 = 0; r0 <= 7 + 15; r0++) { - r01_bits[r0] = QuantizePVT.LARGE_BITS; - } + Arrays.fill(rgData.B, 0); - for (var r0 = 0; r0 < 16; r0++) { - var a1 = gfc.scalefac_band.l[r0 + 1]; - if (a1 >= bigv) - break; - var r0bits = 0; - var bi = new Bits(r0bits); - var r0t = choose_table(ix, 0, a1, bi); - r0bits = bi.bits; + return INIT_GAIN_ANALYSIS_OK; + }; - for (var r1 = 0; r1 < 8; r1++) { - var a2 = gfc.scalefac_band.l[r0 + r1 + 2]; - if (a2 >= bigv) - break; - var bits = r0bits; - bi = new Bits(bits); - var r1t = choose_table(ix, a1, a2, bi); - bits = bi.bits; - if (r01_bits[r0 + r1] > bits) { - r01_bits[r0 + r1] = bits; - r01_div[r0 + r1] = r0; - r0_tbl[r0 + r1] = r0t; - r1_tbl[r0 + r1] = r1t; - } - } - } + /** + * square + */ + function fsqr(d) { + return d * d; } - function recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl) { - var bigv = cod_info2.big_values; + this.AnalyzeSamples = function (rgData, left_samples, left_samplesPos, right_samples, right_samplesPos, num_samples, + num_channels) { + var curleft; + var curleftBase; + var curright; + var currightBase; + var batchsamples; + var cursamples; + var cursamplepos; - for (var r2 = 2; r2 < Encoder.SBMAX_l + 1; r2++) { - var a2 = gfc.scalefac_band.l[r2]; - if (a2 >= bigv) - break; - var bits = r01_bits[r2 - 2] + cod_info2.count1bits; - if (gi.part2_3_length <= bits) - break; + if (num_samples == 0) + return GAIN_ANALYSIS_OK; - var bi = new Bits(bits); - var r2t = choose_table(ix, a2, bigv, bi); - bits = bi.bits; - if (gi.part2_3_length <= bits) - continue; + cursamplepos = 0; + batchsamples = num_samples; - gi.assign(cod_info2); - gi.part2_3_length = bits; - gi.region0_count = r01_div[r2 - 2]; - gi.region1_count = r2 - 2 - r01_div[r2 - 2]; - gi.table_select[0] = r0_tbl[r2 - 2]; - gi.table_select[1] = r1_tbl[r2 - 2]; - gi.table_select[2] = r2t; + switch (num_channels) { + case 1: + right_samples = left_samples; + right_samplesPos = left_samplesPos; + break; + case 2: + break; + default: + return GAIN_ANALYSIS_ERROR; } - } - - this.best_huffman_divide = function (gfc, gi) { - var cod_info2 = new GrInfo(); - var ix = gi.l3_enc; - var r01_bits = new_int(7 + 15 + 1); - var r01_div = new_int(7 + 15 + 1); - var r0_tbl = new_int(7 + 15 + 1); - var r1_tbl = new_int(7 + 15 + 1); - - /* SHORT BLOCK stuff fails for MPEG2 */ - if (gi.block_type == Encoder.SHORT_TYPE && gfc.mode_gr == 1) - return; - cod_info2.assign(gi); - if (gi.block_type == Encoder.NORM_TYPE) { - recalc_divide_init(gfc, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl); - recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, - r0_tbl, r1_tbl); + if (num_samples < MAX_ORDER) { + System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, + MAX_ORDER, num_samples); + System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, + MAX_ORDER, num_samples); + } else { + System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, + MAX_ORDER, MAX_ORDER); + System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, + MAX_ORDER, MAX_ORDER); } - var i = cod_info2.big_values; - if (i == 0 || (ix[i - 2] | ix[i - 1]) > 1) - return; - - i = gi.count1 + 2; - if (i > 576) - return; - - /* Determines the number of bits to encode the quadruples. */ - cod_info2.assign(gi); - cod_info2.count1 = i; - var a1 = 0; - var a2 = 0; + while (batchsamples > 0) { + cursamples = batchsamples > rgData.sampleWindow - rgData.totsamp ? rgData.sampleWindow + - rgData.totsamp + : batchsamples; + if (cursamplepos < MAX_ORDER) { + curleft = rgData.linpre + cursamplepos; + curleftBase = rgData.linprebuf; + curright = rgData.rinpre + cursamplepos; + currightBase = rgData.rinprebuf; + if (cursamples > MAX_ORDER - cursamplepos) + cursamples = MAX_ORDER - cursamplepos; + } else { + curleft = left_samplesPos + cursamplepos; + curleftBase = left_samples; + curright = right_samplesPos + cursamplepos; + currightBase = right_samples; + } - for (; i > cod_info2.big_values; i -= 4) { - var p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 - + ix[i - 1]; - a1 += Tables.t32l[p]; - a2 += Tables.t33l[p]; - } - cod_info2.big_values = i; + filterYule(curleftBase, curleft, rgData.lstepbuf, rgData.lstep + + rgData.totsamp, cursamples, ABYule[rgData.reqindex]); + filterYule(currightBase, curright, rgData.rstepbuf, rgData.rstep + + rgData.totsamp, cursamples, ABYule[rgData.reqindex]); - cod_info2.count1table_select = 0; - if (a1 > a2) { - a1 = a2; - cod_info2.count1table_select = 1; - } + filterButter(rgData.lstepbuf, rgData.lstep + rgData.totsamp, + rgData.loutbuf, rgData.lout + rgData.totsamp, cursamples, + ABButter[rgData.reqindex]); + filterButter(rgData.rstepbuf, rgData.rstep + rgData.totsamp, + rgData.routbuf, rgData.rout + rgData.totsamp, cursamples, + ABButter[rgData.reqindex]); - cod_info2.count1bits = a1; + curleft = rgData.lout + rgData.totsamp; + /* Get the squared values */ + curleftBase = rgData.loutbuf; + curright = rgData.rout + rgData.totsamp; + currightBase = rgData.routbuf; - if (cod_info2.block_type == Encoder.NORM_TYPE) - recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, - r0_tbl, r1_tbl); - else { - /* Count the number of bits necessary to code the bigvalues region. */ - cod_info2.part2_3_length = a1; - a1 = gfc.scalefac_band.l[7 + 1]; - if (a1 > i) { - a1 = i; - } - if (a1 > 0) { - var bi = new Bits(cod_info2.part2_3_length); - cod_info2.table_select[0] = choose_table(ix, 0, a1, bi); - cod_info2.part2_3_length = bi.bits; + var i = cursamples % 8; + while ((i--) != 0) { + rgData.lsum += fsqr(curleftBase[curleft++]); + rgData.rsum += fsqr(currightBase[curright++]); } - if (i > a1) { - var bi = new Bits(cod_info2.part2_3_length); - cod_info2.table_select[1] = choose_table(ix, a1, i, bi); - cod_info2.part2_3_length = bi.bits; + i = cursamples / 8; + while ((i--) != 0) { + rgData.lsum += fsqr(curleftBase[curleft + 0]) + + fsqr(curleftBase[curleft + 1]) + + fsqr(curleftBase[curleft + 2]) + + fsqr(curleftBase[curleft + 3]) + + fsqr(curleftBase[curleft + 4]) + + fsqr(curleftBase[curleft + 5]) + + fsqr(curleftBase[curleft + 6]) + + fsqr(curleftBase[curleft + 7]); + curleft += 8; + rgData.rsum += fsqr(currightBase[curright + 0]) + + fsqr(currightBase[curright + 1]) + + fsqr(currightBase[curright + 2]) + + fsqr(currightBase[curright + 3]) + + fsqr(currightBase[curright + 4]) + + fsqr(currightBase[curright + 5]) + + fsqr(currightBase[curright + 6]) + + fsqr(currightBase[curright + 7]); + curright += 8; } - if (gi.part2_3_length > cod_info2.part2_3_length) - gi.assign(cod_info2); - } - } - var slen1_n = [1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16]; - var slen2_n = [1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8]; - var slen1_tab = [0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4]; - var slen2_tab = [0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3]; - Takehiro.slen1_tab = slen1_tab; - Takehiro.slen2_tab = slen2_tab; - - function scfsi_calc(ch, l3_side) { - var sfb; - var gi = l3_side.tt[1][ch]; - var g0 = l3_side.tt[0][ch]; + batchsamples -= cursamples; + cursamplepos += cursamples; + rgData.totsamp += cursamples; + if (rgData.totsamp == rgData.sampleWindow) { + /* Get the Root Mean Square (RMS) for this set of samples */ + var val = GainAnalysis.STEPS_per_dB + * 10. + * Math.log10((rgData.lsum + rgData.rsum) + / rgData.totsamp * 0.5 + 1.e-37); + var ival = (val <= 0) ? 0 : 0 | val; + if (ival >= rgData.A.length) + ival = rgData.A.length - 1; + rgData.A[ival]++; + rgData.lsum = rgData.rsum = 0.; - for (var i = 0; i < Tables.scfsi_band.length - 1; i++) { - for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { - if (g0.scalefac[sfb] != gi.scalefac[sfb] - && gi.scalefac[sfb] >= 0) - break; + System.arraycopy(rgData.loutbuf, rgData.totsamp, + rgData.loutbuf, 0, MAX_ORDER); + System.arraycopy(rgData.routbuf, rgData.totsamp, + rgData.routbuf, 0, MAX_ORDER); + System.arraycopy(rgData.lstepbuf, rgData.totsamp, + rgData.lstepbuf, 0, MAX_ORDER); + System.arraycopy(rgData.rstepbuf, rgData.totsamp, + rgData.rstepbuf, 0, MAX_ORDER); + rgData.totsamp = 0; } - if (sfb == Tables.scfsi_band[i + 1]) { - for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { - gi.scalefac[sfb] = -1; - } - l3_side.scfsi[ch][i] = 1; + if (rgData.totsamp > rgData.sampleWindow) { + /* + * somehow I really screwed up: Error in programming! Contact + * author about totsamp > sampleWindow + */ + return GAIN_ANALYSIS_ERROR; } } - var s1 = 0; - var c1 = 0; - for (sfb = 0; sfb < 11; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - c1++; - if (s1 < gi.scalefac[sfb]) - s1 = gi.scalefac[sfb]; - } - var s2 = 0; - var c2 = 0; - for (; sfb < Encoder.SBPSY_l; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - c2++; - if (s2 < gi.scalefac[sfb]) - s2 = gi.scalefac[sfb]; + if (num_samples < MAX_ORDER) { + System.arraycopy(rgData.linprebuf, num_samples, rgData.linprebuf, + 0, MAX_ORDER - num_samples); + System.arraycopy(rgData.rinprebuf, num_samples, rgData.rinprebuf, + 0, MAX_ORDER - num_samples); + System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, + MAX_ORDER - num_samples, num_samples); + System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, + MAX_ORDER - num_samples, num_samples); + } else { + System.arraycopy(left_samples, left_samplesPos + num_samples + - MAX_ORDER, rgData.linprebuf, 0, MAX_ORDER); + System.arraycopy(right_samples, right_samplesPos + num_samples + - MAX_ORDER, rgData.rinprebuf, 0, MAX_ORDER); } - for (var i = 0; i < 16; i++) { - if (s1 < slen1_n[i] && s2 < slen2_n[i]) { - var c = slen1_tab[i] * c1 + slen2_tab[i] * c2; - if (gi.part2_length > c) { - gi.part2_length = c; - gi.scalefac_compress = i; - } - } - } - } + return GAIN_ANALYSIS_OK; + }; - /** - * Find the optimal way to store the scalefactors. Only call this routine - * after final scalefactors have been chosen and the channel/granule will - * not be re-encoded. - */ - this.best_scalefac_store = function (gfc, gr, ch, l3_side) { - /* use scalefac_scale if we can */ - var gi = l3_side.tt[gr][ch]; - var sfb, i, j, l; - var recalc = 0; + function analyzeResult(Array, len) { + var i; - /* - * remove scalefacs from bands with ix=0. This idea comes from the AAC - * ISO docs. added mt 3/00 - */ - /* check if l3_enc=0 */ - j = 0; - for (sfb = 0; sfb < gi.sfbmax; sfb++) { - var width = gi.width[sfb]; - j += width; - for (l = -width; l < 0; l++) { - if (gi.l3_enc[l + j] != 0) - break; - } - if (l == 0) - gi.scalefac[sfb] = recalc = -2; - /* anything goes. */ - /* - * only best_scalefac_store and calc_scfsi know--and only they - * should know--about the magic number -2. - */ + var elems = 0; + for (i = 0; i < len; i++) + elems += Array[i]; + if (elems == 0) + return GAIN_NOT_ENOUGH_SAMPLES; + + var upper = 0 | Math.ceil(elems * (1. - RMS_PERCENTILE)); + for (i = len; i-- > 0;) { + if ((upper -= Array[i]) <= 0) + break; } - if (0 == gi.scalefac_scale && 0 == gi.preflag) { - var s = 0; - for (sfb = 0; sfb < gi.sfbmax; sfb++) - if (gi.scalefac[sfb] > 0) - s |= gi.scalefac[sfb]; + //return (float) ((float) PINK_REF - (float) i / (float) STEPS_per_dB); + return (PINK_REF - i / GainAnalysis.STEPS_per_dB); + } - if (0 == (s & 1) && s != 0) { - for (sfb = 0; sfb < gi.sfbmax; sfb++) - if (gi.scalefac[sfb] > 0) - gi.scalefac[sfb] >>= 1; + this.GetTitleGain = function (rgData) { + var retval = analyzeResult(rgData.A, rgData.A.length); - gi.scalefac_scale = recalc = 1; - } + for (var i = 0; i < rgData.A.length; i++) { + rgData.B[i] += rgData.A[i]; + rgData.A[i] = 0; } - if (0 == gi.preflag && gi.block_type != Encoder.SHORT_TYPE - && gfc.mode_gr == 2) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (gi.scalefac[sfb] < qupvt.pretab[sfb] - && gi.scalefac[sfb] != -2) - break; - if (sfb == Encoder.SBPSY_l) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (gi.scalefac[sfb] > 0) - gi.scalefac[sfb] -= qupvt.pretab[sfb]; + for (var i = 0; i < MAX_ORDER; i++) + rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.; - gi.preflag = recalc = 1; - } - } + rgData.totsamp = 0; + rgData.lsum = rgData.rsum = 0.; + return retval; + } - for (i = 0; i < 4; i++) - l3_side.scfsi[ch][i] = 0; +} - if (gfc.mode_gr == 2 && gr == 1 - && l3_side.tt[0][ch].block_type != Encoder.SHORT_TYPE - && l3_side.tt[1][ch].block_type != Encoder.SHORT_TYPE) { - scfsi_calc(ch, l3_side); - recalc = 0; - } - for (sfb = 0; sfb < gi.sfbmax; sfb++) { - if (gi.scalefac[sfb] == -2) { - gi.scalefac[sfb] = 0; - /* if anything goes, then 0 is a good choice */ - } - } - if (recalc != 0) { - if (gfc.mode_gr == 2) { - this.scale_bitcount(gi); - } else { - this.scale_bitcount_lsf(gfc, gi); - } - } + +function Presets() { + function VBRPresets(qual, comp, compS, + y, shThreshold, shThresholdS, + adj, adjShort, lower, + curve, sens, inter, + joint, mod, fix) { + this.vbr_q = qual; + this.quant_comp = comp; + this.quant_comp_s = compS; + this.expY = y; + this.st_lrm = shThreshold; + this.st_s = shThresholdS; + this.masking_adj = adj; + this.masking_adj_short = adjShort; + this.ath_lower = lower; + this.ath_curve = curve; + this.ath_sensitivity = sens; + this.interch = inter; + this.safejoint = joint; + this.sfb21mod = mod; + this.msfix = fix; } - function all_scalefactors_not_negative(scalefac, n) { - for (var i = 0; i < n; ++i) { - if (scalefac[i] < 0) - return false; - } - return true; + function ABRPresets(kbps, comp, compS, + joint, fix, shThreshold, + shThresholdS, bass, sc, + mask, lower, curve, + interCh, sfScale) { + this.quant_comp = comp; + this.quant_comp_s = compS; + this.safejoint = joint; + this.nsmsfix = fix; + this.st_lrm = shThreshold; + this.st_s = shThresholdS; + this.nsbass = bass; + this.scale = sc; + this.masking_adj = mask; + this.ath_lower = lower; + this.ath_curve = curve; + this.interch = interCh; + this.sfscale = sfScale; } - /** - * number of bits used to encode scalefacs. - * - * 18*slen1_tab[i] + 18*slen2_tab[i] - */ - var scale_short = [0, 18, 36, 54, 54, 36, 54, 72, - 54, 72, 90, 72, 90, 108, 108, 126]; + var lame; - /** - * number of bits used to encode scalefacs. - * - * 17*slen1_tab[i] + 18*slen2_tab[i] - */ - var scale_mixed = [0, 18, 36, 54, 51, 35, 53, 71, - 52, 70, 88, 69, 87, 105, 104, 122]; + this.setModules = function (_lame) { + lame = _lame; + }; /** - * number of bits used to encode scalefacs. - * - * 11*slen1_tab[i] + 10*slen2_tab[i] + *
+     * Switch mappings for VBR mode VBR_RH
+     *             vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix
+     * 
*/ - var scale_long = [0, 10, 20, 30, 33, 21, 31, 41, 32, 42, - 52, 43, 53, 63, 64, 74]; + var vbr_old_switch_map = [ + new VBRPresets(0, 9, 9, 0, 5.20, 125.0, -4.2, -6.3, 4.8, 1, 0, 0, 2, 21, 0.97), + new VBRPresets(1, 9, 9, 0, 5.30, 125.0, -3.6, -5.6, 4.5, 1.5, 0, 0, 2, 21, 1.35), + new VBRPresets(2, 9, 9, 0, 5.60, 125.0, -2.2, -3.5, 2.8, 2, 0, 0, 2, 21, 1.49), + new VBRPresets(3, 9, 9, 1, 5.80, 130.0, -1.8, -2.8, 2.6, 3, -4, 0, 2, 20, 1.64), + new VBRPresets(4, 9, 9, 1, 6.00, 135.0, -0.7, -1.1, 1.1, 3.5, -8, 0, 2, 0, 1.79), + new VBRPresets(5, 9, 9, 1, 6.40, 140.0, 0.5, 0.4, -7.5, 4, -12, 0.0002, 0, 0, 1.95), + new VBRPresets(6, 9, 9, 1, 6.60, 145.0, 0.67, 0.65, -14.7, 6.5, -19, 0.0004, 0, 0, 2.30), + new VBRPresets(7, 9, 9, 1, 6.60, 145.0, 0.8, 0.75, -19.7, 8, -22, 0.0006, 0, 0, 2.70), + new VBRPresets(8, 9, 9, 1, 6.60, 145.0, 1.2, 1.15, -27.5, 10, -23, 0.0007, 0, 0, 0), + new VBRPresets(9, 9, 9, 1, 6.60, 145.0, 1.6, 1.6, -36, 11, -25, 0.0008, 0, 0, 0), + new VBRPresets(10, 9, 9, 1, 6.60, 145.0, 2.0, 2.0, -36, 12, -25, 0.0008, 0, 0, 0) + ]; /** - * Also calculates the number of bits necessary to code the scalefactors. + *
+     *                 vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix
+     * 
*/ - this.scale_bitcount = function (cod_info) { - var k, sfb, max_slen1 = 0, max_slen2 = 0; + var vbr_psy_switch_map = [ + new VBRPresets(0, 9, 9, 0, 4.20, 25.0, -7.0, -4.0, 7.5, 1, 0, 0, 2, 26, 0.97), + new VBRPresets(1, 9, 9, 0, 4.20, 25.0, -5.6, -3.6, 4.5, 1.5, 0, 0, 2, 21, 1.35), + new VBRPresets(2, 9, 9, 0, 4.20, 25.0, -4.4, -1.8, 2, 2, 0, 0, 2, 18, 1.49), + new VBRPresets(3, 9, 9, 1, 4.20, 25.0, -3.4, -1.25, 1.1, 3, -4, 0, 2, 15, 1.64), + new VBRPresets(4, 9, 9, 1, 4.20, 25.0, -2.2, 0.1, 0, 3.5, -8, 0, 2, 0, 1.79), + new VBRPresets(5, 9, 9, 1, 4.20, 25.0, -1.0, 1.65, -7.7, 4, -12, 0.0002, 0, 0, 1.95), + new VBRPresets(6, 9, 9, 1, 4.20, 25.0, -0.0, 2.47, -7.7, 6.5, -19, 0.0004, 0, 0, 2), + new VBRPresets(7, 9, 9, 1, 4.20, 25.0, 0.5, 2.0, -14.5, 8, -22, 0.0006, 0, 0, 2), + new VBRPresets(8, 9, 9, 1, 4.20, 25.0, 1.0, 2.4, -22.0, 10, -23, 0.0007, 0, 0, 2), + new VBRPresets(9, 9, 9, 1, 4.20, 25.0, 1.5, 2.95, -30.0, 11, -25, 0.0008, 0, 0, 2), + new VBRPresets(10, 9, 9, 1, 4.20, 25.0, 2.0, 2.95, -36.0, 12, -30, 0.0008, 0, 0, 2) + ]; - /* maximum values */ - var tab; - var scalefac = cod_info.scalefac; + function apply_vbr_preset(gfp, a, enforce) { + var vbr_preset = gfp.VBR == VbrMode.vbr_rh ? vbr_old_switch_map + : vbr_psy_switch_map; + var x = gfp.VBR_q_frac; + var p = vbr_preset[a]; + var q = vbr_preset[a + 1]; + var set = p; - if (cod_info.block_type == Encoder.SHORT_TYPE) { - tab = scale_short; - if (cod_info.mixed_block_flag != 0) - tab = scale_mixed; - } else { /* block_type == 1,2,or 3 */ - tab = scale_long; - if (0 == cod_info.preflag) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (scalefac[sfb] < qupvt.pretab[sfb]) - break; + // NOOP(vbr_q); + // NOOP(quant_comp); + // NOOP(quant_comp_s); + // NOOP(expY); + p.st_lrm = p.st_lrm + x * (q.st_lrm - p.st_lrm); + // LERP(st_lrm); + p.st_s = p.st_s + x * (q.st_s - p.st_s); + // LERP(st_s); + p.masking_adj = p.masking_adj + x * (q.masking_adj - p.masking_adj); + // LERP(masking_adj); + p.masking_adj_short = p.masking_adj_short + x + * (q.masking_adj_short - p.masking_adj_short); + // LERP(masking_adj_short); + p.ath_lower = p.ath_lower + x * (q.ath_lower - p.ath_lower); + // LERP(ath_lower); + p.ath_curve = p.ath_curve + x * (q.ath_curve - p.ath_curve); + // LERP(ath_curve); + p.ath_sensitivity = p.ath_sensitivity + x + * (q.ath_sensitivity - p.ath_sensitivity); + // LERP(ath_sensitivity); + p.interch = p.interch + x * (q.interch - p.interch); + // LERP(interch); + // NOOP(safejoint); + // NOOP(sfb21mod); + p.msfix = p.msfix + x * (q.msfix - p.msfix); + // LERP(msfix); - if (sfb == Encoder.SBPSY_l) { - cod_info.preflag = 1; - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - scalefac[sfb] -= qupvt.pretab[sfb]; - } - } - } + lame_set_VBR_q(gfp, set.vbr_q); - for (sfb = 0; sfb < cod_info.sfbdivide; sfb++) - if (max_slen1 < scalefac[sfb]) - max_slen1 = scalefac[sfb]; + if (enforce != 0) + gfp.quant_comp = set.quant_comp; + else if (!(Math.abs(gfp.quant_comp - -1) > 0)) + gfp.quant_comp = set.quant_comp; + // SET_OPTION(quant_comp, set.quant_comp, -1); + if (enforce != 0) + gfp.quant_comp_short = set.quant_comp_s; + else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) + gfp.quant_comp_short = set.quant_comp_s; + // SET_OPTION(quant_comp_short, set.quant_comp_s, -1); + if (set.expY != 0) { + gfp.experimentalY = set.expY != 0; + } + if (enforce != 0) + gfp.internal_flags.nsPsy.attackthre = set.st_lrm; + else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) + gfp.internal_flags.nsPsy.attackthre = set.st_lrm; + // SET_OPTION(short_threshold_lrm, set.st_lrm, -1); + if (enforce != 0) + gfp.internal_flags.nsPsy.attackthre_s = set.st_s; + else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) + gfp.internal_flags.nsPsy.attackthre_s = set.st_s; + // SET_OPTION(short_threshold_s, set.st_s, -1); + if (enforce != 0) + gfp.maskingadjust = set.masking_adj; + else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) + gfp.maskingadjust = set.masking_adj; + // SET_OPTION(maskingadjust, set.masking_adj, 0); + if (enforce != 0) + gfp.maskingadjust_short = set.masking_adj_short; + else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) + gfp.maskingadjust_short = set.masking_adj_short; + // SET_OPTION(maskingadjust_short, set.masking_adj_short, 0); + if (enforce != 0) + gfp.ATHlower = -set.ath_lower / 10.0; + else if (!(Math.abs((-gfp.ATHlower * 10.0) - 0) > 0)) + gfp.ATHlower = -set.ath_lower / 10.0; + // SET_OPTION(ATHlower, set.ath_lower, 0); + if (enforce != 0) + gfp.ATHcurve = set.ath_curve; + else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) + gfp.ATHcurve = set.ath_curve; + // SET_OPTION(ATHcurve, set.ath_curve, -1); + if (enforce != 0) + gfp.athaa_sensitivity = set.ath_sensitivity; + else if (!(Math.abs(gfp.athaa_sensitivity - -1) > 0)) + gfp.athaa_sensitivity = set.ath_sensitivity; + // SET_OPTION(athaa_sensitivity, set.ath_sensitivity, 0); + if (set.interch > 0) { + if (enforce != 0) + gfp.interChRatio = set.interch; + else if (!(Math.abs(gfp.interChRatio - -1) > 0)) + gfp.interChRatio = set.interch; + // SET_OPTION(interChRatio, set.interch, -1); + } - for (; sfb < cod_info.sfbmax; sfb++) - if (max_slen2 < scalefac[sfb]) - max_slen2 = scalefac[sfb]; + /* parameters for which there is no proper set/get interface */ + if (set.safejoint > 0) { + gfp.exp_nspsytune = gfp.exp_nspsytune | set.safejoint; + } + if (set.sfb21mod > 0) { + gfp.exp_nspsytune = gfp.exp_nspsytune | (set.sfb21mod << 20); + } + if (enforce != 0) + gfp.msfix = set.msfix; + else if (!(Math.abs(gfp.msfix - -1) > 0)) + gfp.msfix = set.msfix; + // SET_OPTION(msfix, set.msfix, -1); - /* - * from Takehiro TOMINAGA 10/99 loop over *all* - * posible values of scalefac_compress to find the one which uses the - * smallest number of bits. ISO would stop at first valid index - */ - cod_info.part2_length = QuantizePVT.LARGE_BITS; - for (k = 0; k < 16; k++) { - if (max_slen1 < slen1_n[k] && max_slen2 < slen2_n[k] - && cod_info.part2_length > tab[k]) { - cod_info.part2_length = tab[k]; - cod_info.scalefac_compress = k; - } + if (enforce == 0) { + gfp.VBR_q = a; + gfp.VBR_q_frac = x; } - return cod_info.part2_length == QuantizePVT.LARGE_BITS; } /** - * table of largest scalefactor values for MPEG2 - */ - var max_range_sfac_tab = [[15, 15, 7, 7], - [15, 15, 7, 0], [7, 3, 0, 0], [15, 31, 31, 0], - [7, 7, 7, 0], [3, 3, 0, 0]]; - - /** - * Also counts the number of bits to encode the scalefacs but for MPEG 2 - * Lower sampling frequencies (24, 22.05 and 16 kHz.) + *
+     *  Switch mappings for ABR mode
      *
-     * This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS,
-     * "Audio Decoding Layer III"
+     *              kbps  quant q_s safejoint nsmsfix st_lrm  st_s  ns-bass scale   msk ath_lwr ath_curve  interch , sfscale
+     * 
*/ - this.scale_bitcount_lsf = function (gfc, cod_info) { - var table_number, row_in_table, partition, nr_sfb, window; - var over; - var i, sfb; - var max_sfac = new_int(4); -//var partition_table; - var scalefac = cod_info.scalefac; + var abr_switch_map = [ + new ABRPresets(8, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -30.0, 11, 0.0012, 1), /* 8, impossible to use in stereo */ + new ABRPresets(16, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -25.0, 11, 0.0010, 1), /* 16 */ + new ABRPresets(24, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -20.0, 11, 0.0010, 1), /* 24 */ + new ABRPresets(32, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -15.0, 11, 0.0010, 1), /* 32 */ + new ABRPresets(40, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 40 */ + new ABRPresets(48, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 48 */ + new ABRPresets(56, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -6.0, 11, 0.0008, 1), /* 56 */ + new ABRPresets(64, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -2.0, 11, 0.0008, 1), /* 64 */ + new ABRPresets(80, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, .0, 8, 0.0007, 1), /* 80 */ + new ABRPresets(96, 9, 9, 0, 2.50, 6.60, 145, 0, 0.95, 0, 1.0, 5.5, 0.0006, 1), /* 96 */ + new ABRPresets(112, 9, 9, 0, 2.25, 6.60, 145, 0, 0.95, 0, 2.0, 4.5, 0.0005, 1), /* 112 */ + new ABRPresets(128, 9, 9, 0, 1.95, 6.40, 140, 0, 0.95, 0, 3.0, 4, 0.0002, 1), /* 128 */ + new ABRPresets(160, 9, 9, 1, 1.79, 6.00, 135, 0, 0.95, -2, 5.0, 3.5, 0, 1), /* 160 */ + new ABRPresets(192, 9, 9, 1, 1.49, 5.60, 125, 0, 0.97, -4, 7.0, 3, 0, 0), /* 192 */ + new ABRPresets(224, 9, 9, 1, 1.25, 5.20, 125, 0, 0.98, -6, 9.0, 2, 0, 0), /* 224 */ + new ABRPresets(256, 9, 9, 1, 0.97, 5.20, 125, 0, 1.00, -8, 10.0, 1, 0, 0), /* 256 */ + new ABRPresets(320, 9, 9, 1, 0.90, 5.20, 125, 0, 1.00, -10, 12.0, 0, 0, 0) /* 320 */ + ]; - /* - * Set partition table. Note that should try to use table one, but do - * not yet... - */ - if (cod_info.preflag != 0) - table_number = 2; - else - table_number = 0; + function apply_abr_preset(gfp, preset, enforce) { + /* Variables for the ABR stuff */ + var actual_bitrate = preset; + + var r = lame.nearestBitrateFullIndex(preset); + + gfp.VBR = VbrMode.vbr_abr; + gfp.VBR_mean_bitrate_kbps = actual_bitrate; + gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, 320); + gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, 8); + gfp.brate = gfp.VBR_mean_bitrate_kbps; + if (gfp.VBR_mean_bitrate_kbps > 320) { + gfp.disable_reservoir = true; + } - for (i = 0; i < 4; i++) - max_sfac[i] = 0; + /* parameters for which there is no proper set/get interface */ + if (abr_switch_map[r].safejoint > 0) + gfp.exp_nspsytune = gfp.exp_nspsytune | 2; + /* safejoint */ - if (cod_info.block_type == Encoder.SHORT_TYPE) { - row_in_table = 1; - var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (sfb = 0, partition = 0; partition < 4; partition++) { - nr_sfb = partition_table[partition] / 3; - for (i = 0; i < nr_sfb; i++, sfb++) - for (window = 0; window < 3; window++) - if (scalefac[sfb * 3 + window] > max_sfac[partition]) - max_sfac[partition] = scalefac[sfb * 3 + window]; - } - } else { - row_in_table = 0; - var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (sfb = 0, partition = 0; partition < 4; partition++) { - nr_sfb = partition_table[partition]; - for (i = 0; i < nr_sfb; i++, sfb++) - if (scalefac[sfb] > max_sfac[partition]) - max_sfac[partition] = scalefac[sfb]; - } + if (abr_switch_map[r].sfscale > 0) { + gfp.internal_flags.noise_shaping = 2; } - - for (over = false, partition = 0; partition < 4; partition++) { - if (max_sfac[partition] > max_range_sfac_tab[table_number][partition]) - over = true; + /* ns-bass tweaks */ + if (Math.abs(abr_switch_map[r].nsbass) > 0) { + var k = (int)(abr_switch_map[r].nsbass * 4); + if (k < 0) + k += 64; + gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 2); } - if (!over) { - var slen1, slen2, slen3, slen4; - - cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (partition = 0; partition < 4; partition++) - cod_info.slen[partition] = log2tab[max_sfac[partition]]; - /* set scalefac_compress */ - slen1 = cod_info.slen[0]; - slen2 = cod_info.slen[1]; - slen3 = cod_info.slen[2]; - slen4 = cod_info.slen[3]; + if (enforce != 0) + gfp.quant_comp = abr_switch_map[r].quant_comp; + else if (!(Math.abs(gfp.quant_comp - -1) > 0)) + gfp.quant_comp = abr_switch_map[r].quant_comp; + // SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1); + if (enforce != 0) + gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; + else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) + gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; + // SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1); - switch (table_number) { - case 0: - cod_info.scalefac_compress = (((slen1 * 5) + slen2) << 4) - + (slen3 << 2) + slen4; - break; + if (enforce != 0) + gfp.msfix = abr_switch_map[r].nsmsfix; + else if (!(Math.abs(gfp.msfix - -1) > 0)) + gfp.msfix = abr_switch_map[r].nsmsfix; + // SET_OPTION(msfix, abr_switch_map[r].nsmsfix, -1); - case 1: - cod_info.scalefac_compress = 400 + (((slen1 * 5) + slen2) << 2) - + slen3; - break; + if (enforce != 0) + gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; + else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) + gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; + // SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1); + if (enforce != 0) + gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; + else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) + gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; + // SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1); - case 2: - cod_info.scalefac_compress = 500 + (slen1 * 3) + slen2; - break; + /* + * ABR seems to have big problems with clipping, especially at low + * bitrates + */ + /* + * so we compensate for that here by using a scale value depending on + * bitrate + */ + if (enforce != 0) + gfp.scale = abr_switch_map[r].scale; + else if (!(Math.abs(gfp.scale - -1) > 0)) + gfp.scale = abr_switch_map[r].scale; + // SET_OPTION(scale, abr_switch_map[r].scale, -1); - default: - System.err.printf("intensity stereo not implemented yet\n"); - break; - } - } - if (!over) { - cod_info.part2_length = 0; - for (partition = 0; partition < 4; partition++) - cod_info.part2_length += cod_info.slen[partition] - * cod_info.sfb_partition_table[partition]; + if (enforce != 0) + gfp.maskingadjust = abr_switch_map[r].masking_adj; + else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) + gfp.maskingadjust = abr_switch_map[r].masking_adj; + // SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0); + if (abr_switch_map[r].masking_adj > 0) { + if (enforce != 0) + gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9); + else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) + gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9); + // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * + // .9, 0); + } else { + if (enforce != 0) + gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1); + else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) + gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1); + // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * + // 1.1, 0); } - return over; - } - /* - * Since no bands have been over-amplified, we can set scalefac_compress and - * slen[] for the formatter - */ - var log2tab = [0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, - 4, 4, 4, 4]; + if (enforce != 0) + gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.; + else if (!(Math.abs((-gfp.ATHlower * 10.) - 0) > 0)) + gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.; + // SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0); + if (enforce != 0) + gfp.ATHcurve = abr_switch_map[r].ath_curve; + else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) + gfp.ATHcurve = abr_switch_map[r].ath_curve; + // SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1); - this.huffman_init = function (gfc) { - for (var i = 2; i <= 576; i += 2) { - var scfb_anz = 0, bv_index; - while (gfc.scalefac_band.l[++scfb_anz] < i) - ; + if (enforce != 0) + gfp.interChRatio = abr_switch_map[r].interch; + else if (!(Math.abs(gfp.interChRatio - -1) > 0)) + gfp.interChRatio = abr_switch_map[r].interch; + // SET_OPTION(interChRatio, abr_switch_map[r].interch, -1); - bv_index = subdv_table[scfb_anz][0]; // .region0_count - while (gfc.scalefac_band.l[bv_index + 1] > i) - bv_index--; + return preset; + } - if (bv_index < 0) { - /* - * this is an indication that everything is going to be encoded - * as region0: bigvalues < region0 < region1 so lets set - * region0, region1 to some value larger than bigvalues - */ - bv_index = subdv_table[scfb_anz][0]; // .region0_count + this.apply_preset = function(gfp, preset, enforce) { + /* translate legacy presets */ + switch (preset) { + case Lame.R3MIX: + { + preset = Lame.V3; + gfp.VBR = VbrMode.vbr_mtrh; + break; } + case Lame.MEDIUM: + { + preset = Lame.V4; + gfp.VBR = VbrMode.vbr_rh; + break; + } + case Lame.MEDIUM_FAST: + { + preset = Lame.V4; + gfp.VBR = VbrMode.vbr_mtrh; + break; + } + case Lame.STANDARD: + { + preset = Lame.V2; + gfp.VBR = VbrMode.vbr_rh; + break; + } + case Lame.STANDARD_FAST: + { + preset = Lame.V2; + gfp.VBR = VbrMode.vbr_mtrh; + break; + } + case Lame.EXTREME: + { + preset = Lame.V0; + gfp.VBR = VbrMode.vbr_rh; + break; + } + case Lame.EXTREME_FAST: + { + preset = Lame.V0; + gfp.VBR = VbrMode.vbr_mtrh; + break; + } + case Lame.INSANE: + { + preset = 320; + gfp.preset = preset; + apply_abr_preset(gfp, preset, enforce); + gfp.VBR = VbrMode.vbr_off; + return preset; + } + } - gfc.bv_scf[i - 2] = bv_index; - - bv_index = subdv_table[scfb_anz][1]; // .region1_count - while (gfc.scalefac_band.l[bv_index + gfc.bv_scf[i - 2] + 2] > i) - bv_index--; - - if (bv_index < 0) { - bv_index = subdv_table[scfb_anz][1]; // .region1_count + gfp.preset = preset; + { + switch (preset) { + case Lame.V9: + apply_vbr_preset(gfp, 9, enforce); + return preset; + case Lame.V8: + apply_vbr_preset(gfp, 8, enforce); + return preset; + case Lame.V7: + apply_vbr_preset(gfp, 7, enforce); + return preset; + case Lame.V6: + apply_vbr_preset(gfp, 6, enforce); + return preset; + case Lame.V5: + apply_vbr_preset(gfp, 5, enforce); + return preset; + case Lame.V4: + apply_vbr_preset(gfp, 4, enforce); + return preset; + case Lame.V3: + apply_vbr_preset(gfp, 3, enforce); + return preset; + case Lame.V2: + apply_vbr_preset(gfp, 2, enforce); + return preset; + case Lame.V1: + apply_vbr_preset(gfp, 1, enforce); + return preset; + case Lame.V0: + apply_vbr_preset(gfp, 0, enforce); + return preset; + default: + break; } - - gfc.bv_scf[i - 1] = bv_index; } - } -} + if (8 <= preset && preset <= 320) { + return apply_abr_preset(gfp, preset, enforce); + } + /* no corresponding preset found */ + gfp.preset = 0; + return preset; + } + // Rest from getset.c: -BitStream.EQ = function (a, b) { - return (Math.abs(a) > Math.abs(b)) ? (Math.abs((a) - (b)) <= (Math - .abs(a) * 1e-6)) - : (Math.abs((a) - (b)) <= (Math.abs(b) * 1e-6)); -}; + /** + * VBR quality level.
+ * 0 = highest
+ * 9 = lowest + */ + function lame_set_VBR_q(gfp, VBR_q) { + var ret = 0; -BitStream.NEQ = function (a, b) { - return !BitStream.EQ(a, b); -}; + if (0 > VBR_q) { + /* Unknown VBR quality level! */ + ret = -1; + VBR_q = 0; + } + if (9 < VBR_q) { + ret = -1; + VBR_q = 9; + } -function BitStream() { - var self = this; - var CRC16_POLYNOMIAL = 0x8005; + gfp.VBR_q = VBR_q; + gfp.VBR_q_frac = 0; + return ret; + } - /* - * we work with ints, so when doing bit manipulation, we limit ourselves to - * MAX_LENGTH-2 just to be on the safe side - */ - var MAX_LENGTH = 32; +} - //GainAnalysis ga; - //MPGLib mpg; - //Version ver; - //VBRTag vbr; - var ga = null; - var mpg = null; - var ver = null; - var vbr = null; +/* + * bit reservoir source file + * + * Copyright (c) 1999-2000 Mark Taylor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ - //public final void setModules(GainAnalysis ga, MPGLib mpg, Version ver, - // VBRTag vbr) { +/* $Id: Reservoir.java,v 1.9 2011/05/24 20:48:06 kenchis Exp $ */ - this.setModules = function (_ga, _mpg, _ver, _vbr) { - ga = _ga; - mpg = _mpg; - ver = _ver; - vbr = _vbr; - }; +//package mp3; - /** - * Bit stream buffer. - */ - //private byte[] buf; - var buf = null; - /** - * Bit counter of bit stream. - */ - var totbit = 0; - /** - * Pointer to top byte in buffer. - */ - var bufByteIdx = 0; - /** - * Pointer to top bit of top byte in buffer. - */ - var bufBitIdx = 0; +/** + * ResvFrameBegin:
+ * Called (repeatedly) at the beginning of a frame. Updates the maximum size of + * the reservoir, and checks to make sure main_data_begin was set properly by + * the formatter
+ * Background information: + * + * This is the original text from the ISO standard. Because of sooo many bugs + * and irritations correcting comments are added in brackets []. A '^W' means + * you should remove the last word. + * + *
+ *  1. The following rule can be used to calculate the maximum
+ *     number of bits used for one granule [^W frame]:
+ * At the highest possible bitrate of Layer III (320 kbps + * per stereo signal [^W^W^W], 48 kHz) the frames must be of + * [^W^W^W are designed to have] constant length, i.e. + * one buffer [^W^W the frame] length is:
+ * + * 320 kbps * 1152/48 kHz = 7680 bit = 960 byte + * + * This value is used as the maximum buffer per channel [^W^W] at + * lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps + * stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit + * [per granule and channel] at 48 kHz sampling frequency. + * This means that there is a maximum deviation (short time buffer + * [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps. + * The actual deviation is equal to the number of bytes [with the + * meaning of octets] denoted by the main_data_end offset pointer. + * The actual maximum deviation is (2^9-1)*8 bit = 4088 bits + * [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits]. + * ... The xchange of buffer bits between the left and right channel + * is allowed without restrictions [exception: dual channel]. + * Because of the [constructed] constraint on the buffer size + * main_data_end is always set to 0 in the case of bit_rate_index==14, + * i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case + * all data are allocated between adjacent header [^W sync] words + * [, i.e. there is no buffering at all]. + *
+ */ - /** - * compute bitsperframe and mean_bits for a layer III frame - */ - this.getframebits = function (gfp) { - var gfc = gfp.internal_flags; - var bit_rate; - /* get bitrate in kbps [?] */ - if (gfc.bitrate_index != 0) - bit_rate = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; - else - bit_rate = gfp.brate; +function Reservoir() { + var bs; - /* main encoding routine toggles padding on and off */ - /* one Layer3 Slot consists of 8 bits */ - var bytes = 0 | (gfp.version + 1) * 72000 * bit_rate / gfp.out_samplerate + gfc.padding; - return 8 * bytes; - }; + this.setModules = function(_bs) { + bs = _bs; + } - function putheader_bits(gfc) { - System.arraycopy(gfc.header[gfc.w_ptr].buf, 0, buf, bufByteIdx, gfc.sideinfo_len); - bufByteIdx += gfc.sideinfo_len; - totbit += gfc.sideinfo_len * 8; - gfc.w_ptr = (gfc.w_ptr + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); - } + this.ResvFrameBegin = function(gfp, mean_bits) { + var gfc = gfp.internal_flags; + var maxmp3buf; + var l3_side = gfc.l3_side; - /** - * write j bits into the bit stream - */ - function putbits2(gfc, val, j) { + var frameLength = bs.getframebits(gfp); + mean_bits.bits = (frameLength - gfc.sideinfo_len * 8) / gfc.mode_gr; - while (j > 0) { - var k; - if (bufBitIdx == 0) { - bufBitIdx = 8; - bufByteIdx++; - if (gfc.header[gfc.w_ptr].write_timing == totbit) { - putheader_bits(gfc); - } - buf[bufByteIdx] = 0; - } + /** + *
+		 *  Meaning of the variables:
+		 *      resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1))
+		 *          Number of bits can be stored in previous frame(s) due to
+		 *          counter size constaints
+		 *      maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5))
+		 *          Number of bits allowed to encode one frame (you can take 8*511 bit
+		 *          from the bit reservoir and at most 8*1440 bit from the current
+		 *          frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible
+		 *          value for MPEG-1 and -2)
+		 * 
+		 *          maximum allowed granule/channel size times 4 = 8*2047 bits.,
+		 *          so this is the absolute maximum supported by the format.
+		 * 
+		 * 
+		 *      fullFrameBits:  maximum number of bits available for encoding
+		 *                      the current frame.
+		 * 
+		 *      mean_bits:      target number of bits per granule.
+		 * 
+		 *      frameLength:
+		 * 
+		 *      gfc.ResvMax:   maximum allowed reservoir
+		 * 
+		 *      gfc.ResvSize:  current reservoir size
+		 * 
+		 *      l3_side.resvDrain_pre:
+		 *         ancillary data to be added to previous frame:
+		 *         (only usefull in VBR modes if it is possible to have
+		 *         maxmp3buf < fullFrameBits)).  Currently disabled,
+		 *         see #define NEW_DRAIN
+		 *         2010-02-13: RH now enabled, it seems to be needed for CBR too,
+		 *                     as there exists one example, where the FhG decoder
+		 *                     can't decode a -b320 CBR file anymore.
+		 * 
+		 *      l3_side.resvDrain_post:
+		 *         ancillary data to be added to this frame:
+		 * 
+		 * 
+ */ - k = Math.min(j, bufBitIdx); - j -= k; + /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */ + var resvLimit = (8 * 256) * gfc.mode_gr - 8; - bufBitIdx -= k; + /* + * maximum allowed frame size. dont use more than this number of bits, + * even if the frame has the space for them: + */ + if (gfp.brate > 320) { + /* in freeformat the buffer is constant */ + maxmp3buf = 8 * ((int) ((gfp.brate * 1000) + / (gfp.out_samplerate / 1152) / 8 + .5)); + } else { + /* + * all mp3 decoders should have enough buffer to handle this value: + * size of a 320kbps 32kHz frame + */ + maxmp3buf = 8 * 1440; - /* 32 too large on 32 bit machines */ + /* + * Bouvigne suggests this more lax interpretation of the ISO doc + * instead of using 8*960. + */ - buf[bufByteIdx] |= ((val >> j) << bufBitIdx); - totbit += k; - } - } + if (gfp.strict_ISO) { + maxmp3buf = 8 * ((int) (320000 / (gfp.out_samplerate / 1152) / 8 + .5)); + } + } - /** - * write j bits into the bit stream, ignoring frame headers - */ - function putbits_noheaders(gfc, val, j) { + gfc.ResvMax = maxmp3buf - frameLength; + if (gfc.ResvMax > resvLimit) + gfc.ResvMax = resvLimit; + if (gfc.ResvMax < 0 || gfp.disable_reservoir) + gfc.ResvMax = 0; - while (j > 0) { - var k; - if (bufBitIdx == 0) { - bufBitIdx = 8; - bufByteIdx++; - buf[bufByteIdx] = 0; - } + var fullFrameBits = mean_bits.bits * gfc.mode_gr + + Math.min(gfc.ResvSize, gfc.ResvMax); - k = Math.min(j, bufBitIdx); - j -= k; + if (fullFrameBits > maxmp3buf) + fullFrameBits = maxmp3buf; - bufBitIdx -= k; - /* 32 too large on 32 bit machines */ + l3_side.resvDrain_pre = 0; - buf[bufByteIdx] |= ((val >> j) << bufBitIdx); - totbit += k; - } - } + // frame analyzer code + if (gfc.pinfo != null) { + /* + * expected bits per channel per granule [is this also right for + * mono/stereo, MPEG-1/2 ?] + */ + gfc.pinfo.mean_bits = mean_bits.bits / 2; + gfc.pinfo.resvsize = gfc.ResvSize; + } - /** - * Some combinations of bitrate, Fs, and stereo make it impossible to stuff - * out a frame using just main_data, due to the limited number of bits to - * indicate main_data_length. In these situations, we put stuffing bits into - * the ancillary data... - */ - function drain_into_ancillary(gfp, remainingBits) { - var gfc = gfp.internal_flags; - var i; + return fullFrameBits; + } - if (remainingBits >= 8) { - putbits2(gfc, 0x4c, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x41, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x4d, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x45, 8); - remainingBits -= 8; - } + /** + * returns targ_bits: target number of bits to use for 1 granule
+ * extra_bits: amount extra available from reservoir
+ * Mark Taylor 4/99 + */ + this.ResvMaxBits = function(gfp, mean_bits, targ_bits, cbr) { + var gfc = gfp.internal_flags; + var add_bits; + var ResvSize = gfc.ResvSize, ResvMax = gfc.ResvMax; - if (remainingBits >= 32) { - var version = ver.getLameShortVersion(); - if (remainingBits >= 32) - for (i = 0; i < version.length && remainingBits >= 8; ++i) { - remainingBits -= 8; - putbits2(gfc, version.charAt(i), 8); - } - } + /* compensate the saved bits used in the 1st granule */ + if (cbr != 0) + ResvSize += mean_bits; - for (; remainingBits >= 1; remainingBits -= 1) { - putbits2(gfc, gfc.ancillary_flag, 1); - gfc.ancillary_flag ^= (!gfp.disable_reservoir ? 1 : 0); - } + if ((gfc.substep_shaping & 1) != 0) + ResvMax *= 0.9; + targ_bits.bits = mean_bits; - } + /* extra bits if the reservoir is almost full */ + if (ResvSize * 10 > ResvMax * 9) { + add_bits = ResvSize - (ResvMax * 9) / 10; + targ_bits.bits += add_bits; + gfc.substep_shaping |= 0x80; + } else { + add_bits = 0; + gfc.substep_shaping &= 0x7f; + /* + * build up reservoir. this builds the reservoir a little slower + * than FhG. It could simple be mean_bits/15, but this was rigged to + * always produce 100 (the old value) at 128kbs + */ + if (!gfp.disable_reservoir && 0 == (gfc.substep_shaping & 1)) + targ_bits.bits -= .1 * mean_bits; + } - /** - * write N bits into the header - */ - function writeheader(gfc, val, j) { - var ptr = gfc.header[gfc.h_ptr].ptr; + /* amount from the reservoir we are allowed to use. ISO says 6/10 */ + var extra_bits = (ResvSize < (gfc.ResvMax * 6) / 10 ? ResvSize + : (gfc.ResvMax * 6) / 10); + extra_bits -= add_bits; - while (j > 0) { - var k = Math.min(j, 8 - (ptr & 7)); - j -= k; - /* >> 32 too large for 32 bit machines */ + if (extra_bits < 0) + extra_bits = 0; + return extra_bits; + } - gfc.header[gfc.h_ptr].buf[ptr >> 3] |= ((val >> j)) << (8 - (ptr & 7) - k); - ptr += k; - } - gfc.header[gfc.h_ptr].ptr = ptr; - } + /** + * Called after a granule's bit allocation. Readjusts the size of the + * reservoir to reflect the granule's usage. + */ + this.ResvAdjust = function(gfc, gi) { + gfc.ResvSize -= gi.part2_3_length + gi.part2_length; + } - function CRC_update(value, crc) { - value <<= 8; - for (var i = 0; i < 8; i++) { - value <<= 1; - crc <<= 1; + /** + * Called after all granules in a frame have been allocated. Makes sure that + * the reservoir size is within limits, possibly by adding stuffing bits. + */ + this.ResvFrameEnd = function(gfc, mean_bits) { + var over_bits; + var l3_side = gfc.l3_side; - if ((((crc ^ value) & 0x10000) != 0)) - crc ^= CRC16_POLYNOMIAL; - } - return crc; - } + gfc.ResvSize += mean_bits * gfc.mode_gr; + var stuffingBits = 0; + l3_side.resvDrain_post = 0; + l3_side.resvDrain_pre = 0; - this.CRC_writeheader = function (gfc, header) { - var crc = 0xffff; - /* (jo) init crc16 for error_protection */ + /* we must be byte aligned */ + if ((over_bits = gfc.ResvSize % 8) != 0) + stuffingBits += over_bits; - crc = CRC_update(header[2] & 0xff, crc); - crc = CRC_update(header[3] & 0xff, crc); - for (var i = 6; i < gfc.sideinfo_len; i++) { - crc = CRC_update(header[i] & 0xff, crc); - } + over_bits = (gfc.ResvSize - stuffingBits) - gfc.ResvMax; + if (over_bits > 0) { + stuffingBits += over_bits; + } - header[4] = (byte)(crc >> 8); - header[5] = (byte)(crc & 255); - }; + /* + * NOTE: enabling the NEW_DRAIN code fixes some problems with FhG + * decoder shipped with MS Windows operating systems. Using this, it is + * even possible to use Gabriel's lax buffer consideration again, which + * assumes, any decoder should have a buffer large enough for a 320 kbps + * frame at 32 kHz sample rate. + * + * old drain code: lame -b320 BlackBird.wav --. does not play with + * GraphEdit.exe using FhG decoder V1.5 Build 50 + * + * new drain code: lame -b320 BlackBird.wav --. plays fine with + * GraphEdit.exe using FhG decoder V1.5 Build 50 + * + * Robert Hegemann, 2010-02-13. + */ + /* + * drain as many bits as possible into previous frame ancillary data In + * particular, in VBR mode ResvMax may have changed, and we have to make + * sure main_data_begin does not create a reservoir bigger than ResvMax + * mt 4/00 + */ + { + var mdb_bytes = Math.min(l3_side.main_data_begin * 8, stuffingBits) / 8; + l3_side.resvDrain_pre += 8 * mdb_bytes; + stuffingBits -= 8 * mdb_bytes; + gfc.ResvSize -= 8 * mdb_bytes; + l3_side.main_data_begin -= mdb_bytes; + } + /* drain the rest into this frames ancillary data */ + l3_side.resvDrain_post += stuffingBits; + gfc.ResvSize -= stuffingBits; + } +} - function encodeSideInfo2(gfp, bitsPerFrame) { - var gfc = gfp.internal_flags; - var l3_side; - var gr, ch; - l3_side = gfc.l3_side; - gfc.header[gfc.h_ptr].ptr = 0; - Arrays.fill(gfc.header[gfc.h_ptr].buf, 0, gfc.sideinfo_len, 0); - if (gfp.out_samplerate < 16000) - writeheader(gfc, 0xffe, 12); - else - writeheader(gfc, 0xfff, 12); - writeheader(gfc, (gfp.version), 1); - writeheader(gfc, 4 - 3, 2); - writeheader(gfc, (!gfp.error_protection ? 1 : 0), 1); - writeheader(gfc, (gfc.bitrate_index), 4); - writeheader(gfc, (gfc.samplerate_index), 2); - writeheader(gfc, (gfc.padding), 1); - writeheader(gfc, (gfp.extension), 1); - writeheader(gfc, (gfp.mode.ordinal()), 2); - writeheader(gfc, (gfc.mode_ext), 2); - writeheader(gfc, (gfp.copyright), 1); - writeheader(gfc, (gfp.original), 1); - writeheader(gfc, (gfp.emphasis), 2); - if (gfp.error_protection) { - writeheader(gfc, 0, 16); - /* dummy */ - } +/** + * A Vbr header may be present in the ancillary data field of the first frame of + * an mp3 bitstream
+ * The Vbr header (optionally) contains + *
    + *
  • frames total number of audio frames in the bitstream + *
  • bytes total number of bytes in the bitstream + *
  • toc table of contents + *
+ * + * toc (table of contents) gives seek points for random access.
+ * The ith entry determines the seek point for i-percent duration.
+ * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes
+ * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes + */ +VBRTag.NUMTOCENTRIES = 100; +VBRTag.MAXFRAMESIZE = 2880; - if (gfp.version == 1) { - /* MPEG1 */ - writeheader(gfc, (l3_side.main_data_begin), 9); +function VBRTag() { - if (gfc.channels_out == 2) - writeheader(gfc, l3_side.private_bits, 3); - else - writeheader(gfc, l3_side.private_bits, 5); + var lame; + var bs; + var v; - for (ch = 0; ch < gfc.channels_out; ch++) { - var band; - for (band = 0; band < 4; band++) { - writeheader(gfc, l3_side.scfsi[ch][band], 1); - } - } + this.setModules = function (_lame, _bs, _v) { + lame = _lame; + bs = _bs; + v = _v; + }; - for (gr = 0; gr < 2; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); - writeheader(gfc, gi.big_values / 2, 9); - writeheader(gfc, gi.global_gain, 8); - writeheader(gfc, gi.scalefac_compress, 4); + var FRAMES_FLAG = 0x0001; + var BYTES_FLAG = 0x0002; + var TOC_FLAG = 0x0004; + var VBR_SCALE_FLAG = 0x0008; - if (gi.block_type != Encoder.NORM_TYPE) { - writeheader(gfc, 1, 1); - /* window_switching_flag */ - writeheader(gfc, gi.block_type, 2); - writeheader(gfc, gi.mixed_block_flag, 1); + var NUMTOCENTRIES = VBRTag.NUMTOCENTRIES; - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); + /** + * (0xB40) the max freeformat 640 32kHz framesize. + */ + var MAXFRAMESIZE = VBRTag.MAXFRAMESIZE; - writeheader(gfc, gi.subblock_gain[0], 3); - writeheader(gfc, gi.subblock_gain[1], 3); - writeheader(gfc, gi.subblock_gain[2], 3); - } else { - writeheader(gfc, 0, 1); - /* window_switching_flag */ - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - if (gi.table_select[2] == 14) - gi.table_select[2] = 16; - writeheader(gfc, gi.table_select[2], 5); + /** + *
+     *    4 bytes for Header Tag
+     *    4 bytes for Header Flags
+     *  100 bytes for entry (toc)
+     *    4 bytes for frame size
+     *    4 bytes for stream size
+     *    4 bytes for VBR scale. a VBR quality indicator: 0=best 100=worst
+     *   20 bytes for LAME tag.  for example, "LAME3.12 (beta 6)"
+     * ___________
+     *  140 bytes
+     * 
+ */ + var VBRHEADERSIZE = (NUMTOCENTRIES + 4 + 4 + 4 + 4 + 4); - writeheader(gfc, gi.region0_count, 4); - writeheader(gfc, gi.region1_count, 3); - } - writeheader(gfc, gi.preflag, 1); - writeheader(gfc, gi.scalefac_scale, 1); - writeheader(gfc, gi.count1table_select, 1); - } - } - } else { - /* MPEG2 */ - writeheader(gfc, (l3_side.main_data_begin), 8); - writeheader(gfc, l3_side.private_bits, gfc.channels_out); + var LAMEHEADERSIZE = (VBRHEADERSIZE + 9 + 1 + 1 + 8 + + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2); - gr = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); - writeheader(gfc, gi.big_values / 2, 9); - writeheader(gfc, gi.global_gain, 8); - writeheader(gfc, gi.scalefac_compress, 9); + /** + * The size of the Xing header MPEG-1, bit rate in kbps. + */ + var XING_BITRATE1 = 128; + /** + * The size of the Xing header MPEG-2, bit rate in kbps. + */ + var XING_BITRATE2 = 64; + /** + * The size of the Xing header MPEG-2.5, bit rate in kbps. + */ + var XING_BITRATE25 = 32; - if (gi.block_type != Encoder.NORM_TYPE) { - writeheader(gfc, 1, 1); - /* window_switching_flag */ - writeheader(gfc, gi.block_type, 2); - writeheader(gfc, gi.mixed_block_flag, 1); + /** + * ISO-8859-1 charset for byte to string operations. + */ + var ISO_8859_1 = null; //Charset.forName("ISO-8859-1"); - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); + /** + * VBR header magic string. + */ + var VBRTag0 = "Xing"; + /** + * VBR header magic string (VBR == VBRMode.vbr_off). + */ + var VBRTag1 = "Info"; - writeheader(gfc, gi.subblock_gain[0], 3); - writeheader(gfc, gi.subblock_gain[1], 3); - writeheader(gfc, gi.subblock_gain[2], 3); - } else { - writeheader(gfc, 0, 1); - /* window_switching_flag */ - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - if (gi.table_select[2] == 14) - gi.table_select[2] = 16; - writeheader(gfc, gi.table_select[2], 5); + /** + * Lookup table for fast CRC-16 computation. Uses the polynomial + * x^16+x^15+x^2+1 + */ + var crc16Lookup = [0x0000, 0xC0C1, 0xC181, 0x0140, + 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, + 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, + 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, + 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, + 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, + 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, + 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, + 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, + 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, + 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, + 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, + 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, + 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, + 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, + 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, + 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, + 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, + 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, + 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, + 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, + 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, + 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, + 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, + 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, + 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, + 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, + 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, + 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, + 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, + 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, + 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, + 0x4100, 0x81C1, 0x8081, 0x4040]; - writeheader(gfc, gi.region0_count, 4); - writeheader(gfc, gi.region1_count, 3); - } + /*********************************************************************** + * Robert Hegemann 2001-01-17 + ***********************************************************************/ - writeheader(gfc, gi.scalefac_scale, 1); - writeheader(gfc, gi.count1table_select, 1); + function addVbr(v, bitrate) { + v.nVbrNumFrames++; + v.sum += bitrate; + v.seen++; + + if (v.seen < v.want) { + return; + } + + if (v.pos < v.size) { + v.bag[v.pos] = v.sum; + v.pos++; + v.seen = 0; + } + if (v.pos == v.size) { + for (var i = 1; i < v.size; i += 2) { + v.bag[i / 2] = v.bag[i]; } + v.want *= 2; + v.pos /= 2; + } + } + + function xingSeekTable(v, t) { + if (v.pos <= 0) + return; + + for (var i = 1; i < NUMTOCENTRIES; ++i) { + var j = i / NUMTOCENTRIES, act, sum; + var indx = 0 | (Math.floor(j * v.pos)); + if (indx > v.pos - 1) + indx = v.pos - 1; + act = v.bag[indx]; + sum = v.sum; + var seek_point = 0 | (256. * act / sum); + if (seek_point > 255) + seek_point = 255; + t[i] = 0xff & seek_point; } + } + + /** + * Add VBR entry, used to fill the VBR TOC entries. + * + * @param gfp + * global flags + */ + this.addVbrFrame = function (gfp) { + var gfc = gfp.internal_flags; + var kbps = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; + addVbr(gfc.VBR_seek_table, kbps); + } - if (gfp.error_protection) { - /* (jo) error_protection: add crc16 information to header */ - CRC_writeheader(gfc, gfc.header[gfc.h_ptr].buf); - } + /** + * Read big endian integer (4-bytes) from header. + * + * @param buf + * header containing the integer + * @param bufPos + * offset into the header + * @return extracted integer + */ + function extractInteger(buf, bufPos) { + var x = buf[bufPos + 0] & 0xff; + x <<= 8; + x |= buf[bufPos + 1] & 0xff; + x <<= 8; + x |= buf[bufPos + 2] & 0xff; + x <<= 8; + x |= buf[bufPos + 3] & 0xff; + return x; + } - { - var old = gfc.h_ptr; + /** + * Write big endian integer (4-bytes) in the header. + * + * @param buf + * header to write the integer into + * @param bufPos + * offset into the header + * @param value + * integer value to write + */ + function createInteger(buf, bufPos, value) { + buf[bufPos + 0] = 0xff & ((value >> 24) & 0xff); + buf[bufPos + 1] = 0xff & ((value >> 16) & 0xff); + buf[bufPos + 2] = 0xff & ((value >> 8) & 0xff); + buf[bufPos + 3] = 0xff & (value & 0xff); + } - gfc.h_ptr = (old + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); - gfc.header[gfc.h_ptr].write_timing = gfc.header[old].write_timing - + bitsPerFrame; + /** + * Write big endian short (2-bytes) in the header. + * + * @param buf + * header to write the integer into + * @param bufPos + * offset into the header + * @param value + * integer value to write + */ + function createShort(buf, bufPos, value) { + buf[bufPos + 0] = 0xff & ((value >> 8) & 0xff); + buf[bufPos + 1] = 0xff & (value & 0xff); + } - if (gfc.h_ptr == gfc.w_ptr) { - /* yikes! we are out of header buffer space */ - System.err - .println("Error: MAX_HEADER_BUF too small in bitstream.c \n"); - } + /** + * Check for magic strings (Xing/Info). + * + * @param buf + * header to check + * @param bufPos + * header offset to check + * @return magic string found + */ + function isVbrTag(buf, bufPos) { + return new String(buf, bufPos, VBRTag0.length(), ISO_8859_1) + .equals(VBRTag0) + || new String(buf, bufPos, VBRTag1.length(), ISO_8859_1) + .equals(VBRTag1); + } - } + function shiftInBitsValue(x, n, v) { + return 0xff & ((x << n) | (v & ~(-1 << n))); } - function huffman_coder_count1(gfc, gi) { - /* Write count1 area */ - var h = Tables.ht[gi.count1table_select + 32]; - var i, bits = 0; + /** + * Construct the MP3 header using the settings of the global flags. + * + * + * + * @param gfp + * global flags + * @param buffer + * header + */ + function setLameTagFrameHeader(gfp, buffer) { + var gfc = gfp.internal_flags; - var ix = gi.big_values; - var xr = gi.big_values; + // MP3 Sync Word + buffer[0] = shiftInBitsValue(buffer[0], 8, 0xff); - for (i = (gi.count1 - gi.big_values) / 4; i > 0; --i) { - var huffbits = 0; - var p = 0, v; + buffer[1] = shiftInBitsValue(buffer[1], 3, 7); + buffer[1] = shiftInBitsValue(buffer[1], 1, + (gfp.out_samplerate < 16000) ? 0 : 1); + // Version + buffer[1] = shiftInBitsValue(buffer[1], 1, gfp.version); + // 01 == Layer 3 + buffer[1] = shiftInBitsValue(buffer[1], 2, 4 - 3); + // Error protection + buffer[1] = shiftInBitsValue(buffer[1], 1, (!gfp.error_protection) ? 1 + : 0); - v = gi.l3_enc[ix + 0]; - if (v != 0) { - p += 8; - if (gi.xr[xr + 0] < 0) - huffbits++; - } + // Bit rate + buffer[2] = shiftInBitsValue(buffer[2], 4, gfc.bitrate_index); + // Frequency + buffer[2] = shiftInBitsValue(buffer[2], 2, gfc.samplerate_index); + // Pad. Bit + buffer[2] = shiftInBitsValue(buffer[2], 1, 0); + // Priv. Bit + buffer[2] = shiftInBitsValue(buffer[2], 1, gfp.extension); - v = gi.l3_enc[ix + 1]; - if (v != 0) { - p += 4; - huffbits *= 2; - if (gi.xr[xr + 1] < 0) - huffbits++; - } + // Mode + buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.mode.ordinal()); + // Mode extension (Used with Joint Stereo) + buffer[3] = shiftInBitsValue(buffer[3], 2, gfc.mode_ext); + // Copy + buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.copyright); + // Original + buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.original); + // Emphasis + buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.emphasis); - v = gi.l3_enc[ix + 2]; - if (v != 0) { - p += 2; - huffbits *= 2; - if (gi.xr[xr + 2] < 0) - huffbits++; - } + /* the default VBR header. 48 kbps layer III, no padding, no crc */ + /* but sampling freq, mode and copyright/copy protection taken */ + /* from first valid frame */ + buffer[0] = 0xff; + var abyte = 0xff & (buffer[1] & 0xf1); + var bitrate; + if (1 == gfp.version) { + bitrate = XING_BITRATE1; + } else { + if (gfp.out_samplerate < 16000) + bitrate = XING_BITRATE25; + else + bitrate = XING_BITRATE2; + } - v = gi.l3_enc[ix + 3]; - if (v != 0) { - p++; - huffbits *= 2; - if (gi.xr[xr + 3] < 0) - huffbits++; - } + if (gfp.VBR == VbrMode.vbr_off) + bitrate = gfp.brate; - ix += 4; - xr += 4; - putbits2(gfc, huffbits + h.table[p], h.hlen[p]); - bits += h.hlen[p]; + var bbyte; + if (gfp.free_format) + bbyte = 0x00; + else + bbyte = 0xff & (16 * lame.BitrateIndex(bitrate, gfp.version, + gfp.out_samplerate)); + + /* + * Use as much of the info from the real frames in the Xing header: + * samplerate, channels, crc, etc... + */ + if (gfp.version == 1) { + /* MPEG1 */ + buffer[1] = 0xff & (abyte | 0x0a); + /* was 0x0b; */ + abyte = 0xff & (buffer[2] & 0x0d); + /* AF keep also private bit */ + buffer[2] = 0xff & (bbyte | abyte); + /* 64kbs MPEG1 frame */ + } else { + /* MPEG2 */ + buffer[1] = 0xff & (abyte | 0x02); + /* was 0x03; */ + abyte = 0xff & (buffer[2] & 0x0d); + /* AF keep also private bit */ + buffer[2] = 0xff & (bbyte | abyte); + /* 64kbs MPEG2 frame */ } - return bits; } /** - * Implements the pseudocode of page 98 of the IS + * Get VBR tag information + * + * @param buf + * header to analyze + * @param bufPos + * offset into the header + * @return VBR tag data */ - function Huffmancode(gfc, tableindex, start, end, gi) { - var h = Tables.ht[tableindex]; - var bits = 0; + this.getVbrTag = function (buf) { + var pTagData = new VBRTagData(); + var bufPos = 0; - if (0 == tableindex) - return bits; + /* get Vbr header data */ + pTagData.flags = 0; + + /* get selected MPEG header data */ + var hId = (buf[bufPos + 1] >> 3) & 1; + var hSrIndex = (buf[bufPos + 2] >> 2) & 3; + var hMode = (buf[bufPos + 3] >> 6) & 3; + var hBitrate = ((buf[bufPos + 2] >> 4) & 0xf); + hBitrate = Tables.bitrate_table[hId][hBitrate]; + + /* check for FFE syncword */ + if ((buf[bufPos + 1] >> 4) == 0xE) + pTagData.samprate = Tables.samplerate_table[2][hSrIndex]; + else + pTagData.samprate = Tables.samplerate_table[hId][hSrIndex]; + + /* determine offset of header */ + if (hId != 0) { + /* mpeg1 */ + if (hMode != 3) + bufPos += (32 + 4); + else + bufPos += (17 + 4); + } else { + /* mpeg2 */ + if (hMode != 3) + bufPos += (17 + 4); + else + bufPos += (9 + 4); + } - for (var i = start; i < end; i += 2) { - var cbits = 0; - var xbits = 0; - var linbits = h.xlen; - var xlen = h.xlen; - var ext = 0; - var x1 = gi.l3_enc[i]; - var x2 = gi.l3_enc[i + 1]; + if (!isVbrTag(buf, bufPos)) + return null; - if (x1 != 0) { - if (gi.xr[i] < 0) - ext++; - cbits--; - } + bufPos += 4; - if (tableindex > 15) { - /* use ESC-words */ - if (x1 > 14) { - var linbits_x1 = x1 - 15; - ext |= linbits_x1 << 1; - xbits = linbits; - x1 = 15; - } + pTagData.hId = hId; - if (x2 > 14) { - var linbits_x2 = x2 - 15; - ext <<= linbits; - ext |= linbits_x2; - xbits += linbits; - x2 = 15; - } - xlen = 16; - } + /* get flags */ + var head_flags = pTagData.flags = extractInteger(buf, bufPos); + bufPos += 4; - if (x2 != 0) { - ext <<= 1; - if (gi.xr[i + 1] < 0) - ext++; - cbits--; - } + if ((head_flags & FRAMES_FLAG) != 0) { + pTagData.frames = extractInteger(buf, bufPos); + bufPos += 4; + } + if ((head_flags & BYTES_FLAG) != 0) { + pTagData.bytes = extractInteger(buf, bufPos); + bufPos += 4; + } - x1 = x1 * xlen + x2; - xbits -= cbits; - cbits += h.hlen[x1]; + if ((head_flags & TOC_FLAG) != 0) { + if (pTagData.toc != null) { + for (var i = 0; i < NUMTOCENTRIES; i++) + pTagData.toc[i] = buf[bufPos + i]; + } + bufPos += NUMTOCENTRIES; + } + pTagData.vbrScale = -1; - putbits2(gfc, h.table[x1], cbits); - putbits2(gfc, ext, xbits); - bits += cbits + xbits; + if ((head_flags & VBR_SCALE_FLAG) != 0) { + pTagData.vbrScale = extractInteger(buf, bufPos); + bufPos += 4; } - return bits; - } - /** - * Note the discussion of huffmancodebits() on pages 28 and 29 of the IS, as - * well as the definitions of the side information on pages 26 and 27. - */ - function ShortHuffmancodebits(gfc, gi) { - var region1Start = 3 * gfc.scalefac_band.s[3]; - if (region1Start > gi.big_values) - region1Start = gi.big_values; + pTagData.headersize = ((hId + 1) * 72000 * hBitrate) + / pTagData.samprate; - /* short blocks do not have a region2 */ - var bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); - bits += Huffmancode(gfc, gi.table_select[1], region1Start, - gi.big_values, gi); - return bits; - } + bufPos += 21; + var encDelay = buf[bufPos + 0] << 4; + encDelay += buf[bufPos + 1] >> 4; + var encPadding = (buf[bufPos + 1] & 0x0F) << 8; + encPadding += buf[bufPos + 2] & 0xff; + /* check for reasonable values (this may be an old Xing header, */ + /* not a INFO tag) */ + if (encDelay < 0 || encDelay > 3000) + encDelay = -1; + if (encPadding < 0 || encPadding > 3000) + encPadding = -1; - function LongHuffmancodebits(gfc, gi) { - var bigvalues, bits; - var region1Start, region2Start; + pTagData.encDelay = encDelay; + pTagData.encPadding = encPadding; - bigvalues = gi.big_values; + /* success */ + return pTagData; + } - var i = gi.region0_count + 1; - region1Start = gfc.scalefac_band.l[i]; - i += gi.region1_count + 1; - region2Start = gfc.scalefac_band.l[i]; + /** + * Initializes the header + * + * @param gfp + * global flags + */ + this.InitVbrTag = function (gfp) { + var gfc = gfp.internal_flags; - if (region1Start > bigvalues) - region1Start = bigvalues; + /** + *
+         * Xing VBR pretends to be a 48kbs layer III frame.  (at 44.1kHz).
+         * (at 48kHz they use 56kbs since 48kbs frame not big enough for
+         * table of contents)
+         * let's always embed Xing header inside a 64kbs layer III frame.
+         * this gives us enough room for a LAME version string too.
+         * size determined by sampling frequency (MPEG1)
+         * 32kHz:    216 bytes@48kbs    288bytes@ 64kbs
+         * 44.1kHz:  156 bytes          208bytes@64kbs     (+1 if padding = 1)
+         * 48kHz:    144 bytes          192
+         *
+         * MPEG 2 values are the same since the framesize and samplerate
+         * are each reduced by a factor of 2.
+         * 
+ */ + var kbps_header; + if (1 == gfp.version) { + kbps_header = XING_BITRATE1; + } else { + if (gfp.out_samplerate < 16000) + kbps_header = XING_BITRATE25; + else + kbps_header = XING_BITRATE2; + } - if (region2Start > bigvalues) - region2Start = bigvalues; + if (gfp.VBR == VbrMode.vbr_off) + kbps_header = gfp.brate; - bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); - bits += Huffmancode(gfc, gi.table_select[1], region1Start, - region2Start, gi); - bits += Huffmancode(gfc, gi.table_select[2], region2Start, bigvalues, - gi); - return bits; - } + // make sure LAME Header fits into Frame + var totalFrameSize = ((gfp.version + 1) * 72000 * kbps_header) + / gfp.out_samplerate; + var headerSize = (gfc.sideinfo_len + LAMEHEADERSIZE); + gfc.VBR_seek_table.TotalFrameSize = totalFrameSize; + if (totalFrameSize < headerSize || totalFrameSize > MAXFRAMESIZE) { + /* disable tag, it wont fit */ + gfp.bWriteVbrTag = false; + return; + } - function writeMainData(gfp) { - var gr, ch, sfb, data_bits, tot_bits = 0; - var gfc = gfp.internal_flags; - var l3_side = gfc.l3_side; + gfc.VBR_seek_table.nVbrNumFrames = 0; + gfc.VBR_seek_table.nBytesWritten = 0; + gfc.VBR_seek_table.sum = 0; - if (gfp.version == 1) { - /* MPEG 1 */ - for (gr = 0; gr < 2; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - var slen1 = Takehiro.slen1_tab[gi.scalefac_compress]; - var slen2 = Takehiro.slen2_tab[gi.scalefac_compress]; - data_bits = 0; - for (sfb = 0; sfb < gi.sfbdivide; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - /* scfsi is used */ - putbits2(gfc, gi.scalefac[sfb], slen1); - data_bits += slen1; - } - for (; sfb < gi.sfbmax; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - /* scfsi is used */ - putbits2(gfc, gi.scalefac[sfb], slen2); - data_bits += slen2; - } + gfc.VBR_seek_table.seen = 0; + gfc.VBR_seek_table.want = 1; + gfc.VBR_seek_table.pos = 0; - if (gi.block_type == Encoder.SHORT_TYPE) { - data_bits += ShortHuffmancodebits(gfc, gi); - } else { - data_bits += LongHuffmancodebits(gfc, gi); - } - data_bits += huffman_coder_count1(gfc, gi); - /* does bitcount in quantize.c agree with actual bit count? */ - tot_bits += data_bits; - } - /* for ch */ - } - /* for gr */ - } else { - /* MPEG 2 */ - gr = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - var i, sfb_partition, scale_bits = 0; - data_bits = 0; - sfb = 0; - sfb_partition = 0; + if (gfc.VBR_seek_table.bag == null) { + gfc.VBR_seek_table.bag = new int[400]; + gfc.VBR_seek_table.size = 400; + } - if (gi.block_type == Encoder.SHORT_TYPE) { - for (; sfb_partition < 4; sfb_partition++) { - var sfbs = gi.sfb_partition_table[sfb_partition] / 3; - var slen = gi.slen[sfb_partition]; - for (i = 0; i < sfbs; i++, sfb++) { - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 0], 0), slen); - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 1], 0), slen); - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 2], 0), slen); - scale_bits += 3 * slen; - } - } - data_bits += ShortHuffmancodebits(gfc, gi); - } else { - for (; sfb_partition < 4; sfb_partition++) { - var sfbs = gi.sfb_partition_table[sfb_partition]; - var slen = gi.slen[sfb_partition]; - for (i = 0; i < sfbs; i++, sfb++) { - putbits2(gfc, Math.max(gi.scalefac[sfb], 0), slen); - scale_bits += slen; - } - } - data_bits += LongHuffmancodebits(gfc, gi); - } - data_bits += huffman_coder_count1(gfc, gi); - /* does bitcount in quantize.c agree with actual bit count? */ - tot_bits += scale_bits + data_bits; - } - /* for ch */ + // write dummy VBR tag of all 0's into bitstream + var buffer = new_byte(MAXFRAMESIZE); + + setLameTagFrameHeader(gfp, buffer); + var n = gfc.VBR_seek_table.TotalFrameSize; + for (var i = 0; i < n; ++i) { + bs.add_dummy_byte(gfp, buffer[i] & 0xff, 1); } - /* for gf */ - return tot_bits; } - /* main_data */ + /** + * Fast CRC-16 computation (uses table crc16Lookup). + * + * @param value + * @param crc + * @return + */ + function crcUpdateLookup(value, crc) { + var tmp = crc ^ value; + crc = (crc >> 8) ^ crc16Lookup[tmp & 0xff]; + return crc; + } - function TotalBytes() { - this.total = 0; + this.updateMusicCRC = function (crc, buffer, bufferPos, size) { + for (var i = 0; i < size; ++i) + crc[0] = crcUpdateLookup(buffer[bufferPos + i], crc[0]); } - /* - * compute the number of bits required to flush all mp3 frames currently in - * the buffer. This should be the same as the reservoir size. Only call this - * routine between frames - i.e. only after all headers and data have been - * added to the buffer by format_bitstream(). - * - * Also compute total_bits_output = size of mp3 buffer (including frame - * headers which may not have yet been send to the mp3 buffer) + number of - * bits needed to flush all mp3 frames. + /** + * Write LAME info: mini version + info on various switches used (Jonathan + * Dee 2001/08/31). * - * total_bytes_output is the size of the mp3 output buffer if - * lame_encode_flush_nogap() was called right now. + * @param gfp + * global flags + * @param musicLength + * music length + * @param streamBuffer + * pointer to output buffer + * @param streamBufferPos + * offset into the output buffer + * @param crc + * computation of CRC-16 of Lame Tag so far (starting at frame + * sync) + * @return number of bytes written to the stream */ - function compute_flushbits(gfp, total_bytes_output) { + function putLameVBR(gfp, musicLength, streamBuffer, streamBufferPos, crc) { var gfc = gfp.internal_flags; - var flushbits, remaining_headers; - var bitsPerFrame; - var last_ptr, first_ptr; - first_ptr = gfc.w_ptr; - /* first header to add to bitstream */ - last_ptr = gfc.h_ptr - 1; - /* last header to add to bitstream */ - if (last_ptr == -1) - last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; + var bytesWritten = 0; - /* add this many bits to bitstream so we can flush all headers */ - flushbits = gfc.header[last_ptr].write_timing - totbit; - total_bytes_output.total = flushbits; + /* encoder delay */ + var encDelay = gfp.encoder_delay; + /* encoder padding */ + var encPadding = gfp.encoder_padding; - if (flushbits >= 0) { - /* if flushbits >= 0, some headers have not yet been written */ - /* reduce flushbits by the size of the headers */ - remaining_headers = 1 + last_ptr - first_ptr; - if (last_ptr < first_ptr) - remaining_headers = 1 + last_ptr - first_ptr - + LameInternalFlags.MAX_HEADER_BUF; - flushbits -= remaining_headers * 8 * gfc.sideinfo_len; + /* recall: gfp.VBR_q is for example set by the switch -V */ + /* gfp.quality by -q, -h, -f, etc */ + var quality = (100 - 10 * gfp.VBR_q - gfp.quality); + + var version = v.getLameVeryShortVersion(); + var vbr; + var revision = 0x00; + var revMethod; + // numbering different in vbr_mode vs. Lame tag + var vbrTypeTranslator = [1, 5, 3, 2, 4, 0, 3]; + var lowpass = 0 | (((gfp.lowpassfreq / 100.0) + .5) > 255 ? 255 + : (gfp.lowpassfreq / 100.0) + .5); + var peakSignalAmplitude = 0; + var radioReplayGain = 0; + var audiophileReplayGain = 0; + var noiseShaping = gfp.internal_flags.noise_shaping; + var stereoMode = 0; + var nonOptimal = 0; + var sourceFreq = 0; + var misc = 0; + var musicCRC = 0; + + // psy model type: Gpsycho or NsPsytune + var expNPsyTune = (gfp.exp_nspsytune & 1) != 0; + var safeJoint = (gfp.exp_nspsytune & 2) != 0; + var noGapMore = false; + var noGapPrevious = false; + var noGapCount = gfp.internal_flags.nogap_total; + var noGapCurr = gfp.internal_flags.nogap_current; + + // 4 bits + var athType = gfp.ATHtype; + var flags = 0; + + // vbr modes + var abrBitrate; + switch (gfp.VBR) { + case vbr_abr: + abrBitrate = gfp.VBR_mean_bitrate_kbps; + break; + case vbr_off: + abrBitrate = gfp.brate; + break; + default: + abrBitrate = gfp.VBR_min_bitrate_kbps; } - /* - * finally, add some bits so that the last frame is complete these bits - * are not necessary to decode the last frame, but some decoders will - * ignore last frame if these bits are missing - */ - bitsPerFrame = self.getframebits(gfp); - flushbits += bitsPerFrame; - total_bytes_output.total += bitsPerFrame; - /* round up: */ - if ((total_bytes_output.total % 8) != 0) - total_bytes_output.total = 1 + (total_bytes_output.total / 8); + // revision and vbr method + if (gfp.VBR.ordinal() < vbrTypeTranslator.length) + vbr = vbrTypeTranslator[gfp.VBR.ordinal()]; else - total_bytes_output.total = (total_bytes_output.total / 8); - total_bytes_output.total += bufByteIdx + 1; + vbr = 0x00; // unknown - if (flushbits < 0) { - System.err.println("strange error flushing buffer ... \n"); - } - return flushbits; - } + revMethod = 0x10 * revision + vbr; - this.flush_bitstream = function (gfp) { - var gfc = gfp.internal_flags; - var l3_side; - var flushbits; - var last_ptr = gfc.h_ptr - 1; - /* last header to add to bitstream */ - if (last_ptr == -1) - last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; - l3_side = gfc.l3_side; + // ReplayGain + if (gfc.findReplayGain) { + if (gfc.RadioGain > 0x1FE) + gfc.RadioGain = 0x1FE; + if (gfc.RadioGain < -0x1FE) + gfc.RadioGain = -0x1FE; - if ((flushbits = compute_flushbits(gfp, new TotalBytes())) < 0) - return; - drain_into_ancillary(gfp, flushbits); + // set name code + radioReplayGain = 0x2000; + // set originator code to `determined automatically' + radioReplayGain |= 0xC00; - /* check that the 100% of the last frame has been written to bitstream */ + if (gfc.RadioGain >= 0) { + // set gain adjustment + radioReplayGain |= gfc.RadioGain; + } else { + // set the sign bit + radioReplayGain |= 0x200; + // set gain adjustment + radioReplayGain |= -gfc.RadioGain; + } + } - /* - * we have padded out all frames with ancillary data, which is the same - * as filling the bitreservoir with ancillary data, so : - */ - gfc.ResvSize = 0; - l3_side.main_data_begin = 0; + // peak sample + if (gfc.findPeakSample) + peakSignalAmplitude = Math + .abs(0 | ((( gfc.PeakSample) / 32767.0) * Math.pow(2, 23) + .5)); - /* save the ReplayGain value */ - if (gfc.findReplayGain) { - var RadioGain = ga.GetTitleGain(gfc.rgdata); - gfc.RadioGain = Math.floor(RadioGain * 10.0 + 0.5) | 0; - /* round to nearest */ + // nogap + if (noGapCount != -1) { + if (noGapCurr > 0) + noGapPrevious = true; + + if (noGapCurr < noGapCount - 1) + noGapMore = true; } - /* find the gain and scale change required for no clipping */ - if (gfc.findPeakSample) { - gfc.noclipGainChange = Math.ceil(Math - .log10(gfc.PeakSample / 32767.0) * 20.0 * 10.0) | 0; - /* round up */ + // flags + flags = athType + ((expNPsyTune ? 1 : 0) << 4) + + ((safeJoint ? 1 : 0) << 5) + ((noGapMore ? 1 : 0) << 6) + + ((noGapPrevious ? 1 : 0) << 7); - if (gfc.noclipGainChange > 0) { - /* clipping occurs */ - if (EQ(gfp.scale, 1.0) || EQ(gfp.scale, 0.0)) - gfc.noclipScale = (Math - .floor((32767.0 / gfc.PeakSample) * 100.0) / 100.0); - /* round down */ - else { - /* - * the user specified his own scaling factor. We could - * suggest the scaling factor of - * (32767.0/gfp.PeakSample)*(gfp.scale) but it's usually - * very inaccurate. So we'd rather not advice him on the - * scaling factor. - */ - gfc.noclipScale = -1; - } - } else - /* no clipping */ - gfc.noclipScale = -1; + if (quality < 0) + quality = 0; + + // stereo mode field (Intensity stereo is not implemented) + switch (gfp.mode) { + case MONO: + stereoMode = 0; + break; + case STEREO: + stereoMode = 1; + break; + case DUAL_CHANNEL: + stereoMode = 2; + break; + case JOINT_STEREO: + if (gfp.force_ms) + stereoMode = 4; + else + stereoMode = 3; + break; + case NOT_SET: + //$FALL-THROUGH$ + default: + stereoMode = 7; + break; + } + + if (gfp.in_samplerate <= 32000) + sourceFreq = 0x00; + else if (gfp.in_samplerate == 48000) + sourceFreq = 0x02; + else if (gfp.in_samplerate > 48000) + sourceFreq = 0x03; + else { + // default is 44100Hz + sourceFreq = 0x01; } - }; - this.add_dummy_byte = function (gfp, val, n) { - var gfc = gfp.internal_flags; - var i; + // Check if the user overrided the default LAME behavior with some + // nasty options + if (gfp.short_blocks == ShortBlock.short_block_forced + || gfp.short_blocks == ShortBlock.short_block_dispensed + || ((gfp.lowpassfreq == -1) && (gfp.highpassfreq == -1)) || /* "-k" */ + (gfp.scale_left < gfp.scale_right) + || (gfp.scale_left > gfp.scale_right) + || (gfp.disable_reservoir && gfp.brate < 320) || gfp.noATH + || gfp.ATHonly || (athType == 0) || gfp.in_samplerate <= 32000) + nonOptimal = 1; - while (n-- > 0) { - putbits_noheaders(gfc, val, 8); + misc = noiseShaping + (stereoMode << 2) + (nonOptimal << 5) + + (sourceFreq << 6); - for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) - gfc.header[i].write_timing += 8; - } - }; + musicCRC = gfc.nMusicCRC; - /** - * This is called after a frame of audio has been quantized and coded. It - * will write the encoded audio to the bitstream. Note that from a layer3 - * encoder's perspective the bit stream is primarily a series of main_data() - * blocks, with header and side information inserted at the proper locations - * to maintain framing. (See Figure A.7 in the IS). - */ - this.format_bitstream = function (gfp) { - var gfc = gfp.internal_flags; - var l3_side; - l3_side = gfc.l3_side; + // Write all this information into the stream - var bitsPerFrame = this.getframebits(gfp); - drain_into_ancillary(gfp, l3_side.resvDrain_pre); + createInteger(streamBuffer, streamBufferPos + bytesWritten, quality); + bytesWritten += 4; - encodeSideInfo2(gfp, bitsPerFrame); - var bits = 8 * gfc.sideinfo_len; - bits += writeMainData(gfp); - drain_into_ancillary(gfp, l3_side.resvDrain_post); - bits += l3_side.resvDrain_post; + for (var j = 0; j < 9; j++) { + streamBuffer[streamBufferPos + bytesWritten + j] = 0xff & version .charAt(j); + } + bytesWritten += 9; - l3_side.main_data_begin += (bitsPerFrame - bits) / 8; + streamBuffer[streamBufferPos + bytesWritten] = 0xff & revMethod; + bytesWritten++; - /* - * compare number of bits needed to clear all buffered mp3 frames with - * what we think the resvsize is: - */ - if (compute_flushbits(gfp, new TotalBytes()) != gfc.ResvSize) { - System.err.println("Internal buffer inconsistency. flushbits <> ResvSize"); - } + streamBuffer[streamBufferPos + bytesWritten] = 0xff & lowpass; + bytesWritten++; - /* - * compare main_data_begin for the next frame with what we think the - * resvsize is: - */ - if ((l3_side.main_data_begin * 8) != gfc.ResvSize) { - System.err.printf("bit reservoir error: \n" - + "l3_side.main_data_begin: %d \n" - + "Resvoir size: %d \n" - + "resv drain (post) %d \n" - + "resv drain (pre) %d \n" - + "header and sideinfo: %d \n" - + "data bits: %d \n" - + "total bits: %d (remainder: %d) \n" - + "bitsperframe: %d \n", - 8 * l3_side.main_data_begin, gfc.ResvSize, - l3_side.resvDrain_post, l3_side.resvDrain_pre, - 8 * gfc.sideinfo_len, bits - l3_side.resvDrain_post - 8 - * gfc.sideinfo_len, bits, bits % 8, bitsPerFrame); + createInteger(streamBuffer, streamBufferPos + bytesWritten, + peakSignalAmplitude); + bytesWritten += 4; - System.err.println("This is a fatal error. It has several possible causes:"); - System.err.println("90%% LAME compiled with buggy version of gcc using advanced optimizations"); - System.err.println(" 9%% Your system is overclocked"); - System.err.println(" 1%% bug in LAME encoding library"); + createShort(streamBuffer, streamBufferPos + bytesWritten, + radioReplayGain); + bytesWritten += 2; - gfc.ResvSize = l3_side.main_data_begin * 8; - } - //; + createShort(streamBuffer, streamBufferPos + bytesWritten, + audiophileReplayGain); + bytesWritten += 2; - if (totbit > 1000000000) { - /* - * to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset - * bit counter - */ - var i; - for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) - gfc.header[i].write_timing -= totbit; - totbit = 0; - } + streamBuffer[streamBufferPos + bytesWritten] = 0xff & flags; + bytesWritten++; - return 0; - }; + if (abrBitrate >= 255) + streamBuffer[streamBufferPos + bytesWritten] = 0xFF; + else + streamBuffer[streamBufferPos + bytesWritten] = 0xff & abrBitrate; + bytesWritten++; - /** - *
-     * copy data out of the internal MP3 bit buffer into a user supplied
-     *       unsigned char buffer.
-     *
-     *       mp3data=0      indicates data in buffer is an id3tags and VBR tags
-     *       mp3data=1      data is real mp3 frame data.
-     * 
- */ - this.copy_buffer = function (gfc, buffer, bufferPos, size, mp3data) { - var minimum = bufByteIdx + 1; - if (minimum <= 0) - return 0; - if (size != 0 && minimum > size) { - /* buffer is too small */ - return -1; - } - System.arraycopy(buf, 0, buffer, bufferPos, minimum); - bufByteIdx = -1; - bufBitIdx = 0; + streamBuffer[streamBufferPos + bytesWritten] = 0xff & (encDelay >> 4); + streamBuffer[streamBufferPos + bytesWritten + 1] = 0xff & ((encDelay << 4) + (encPadding >> 8)); + streamBuffer[streamBufferPos + bytesWritten + 2] = 0xff & encPadding; - if (mp3data != 0) { - var crc = new_int(1); - crc[0] = gfc.nMusicCRC; - vbr.updateMusicCRC(crc, buffer, bufferPos, minimum); - gfc.nMusicCRC = crc[0]; + bytesWritten += 3; - /** - * sum number of bytes belonging to the mp3 stream this info will be - * written into the Xing/LAME header for seeking - */ - if (minimum > 0) { - gfc.VBR_seek_table.nBytesWritten += minimum; - } + streamBuffer[streamBufferPos + bytesWritten] = 0xff & misc; + bytesWritten++; - if (gfc.decode_on_the_fly) { /* decode the frame */ - var pcm_buf = new_float_n([2, 1152]); - var mp3_in = minimum; - var samples_out = -1; - var i; + // unused in rev0 + streamBuffer[streamBufferPos + bytesWritten++] = 0; - /* re-synthesis to pcm. Repeat until we get a samples_out=0 */ - while (samples_out != 0) { + createShort(streamBuffer, streamBufferPos + bytesWritten, gfp.preset); + bytesWritten += 2; - samples_out = mpg.hip_decode1_unclipped(gfc.hip, buffer, - bufferPos, mp3_in, pcm_buf[0], pcm_buf[1]); - /* - * samples_out = 0: need more data to decode samples_out = - * -1: error. Lets assume 0 pcm output samples_out = number - * of samples output - */ + createInteger(streamBuffer, streamBufferPos + bytesWritten, musicLength); + bytesWritten += 4; - /* - * set the lenght of the mp3 input buffer to zero, so that - * in the next iteration of the loop we will be querying - * mpglib about buffered data - */ - mp3_in = 0; + createShort(streamBuffer, streamBufferPos + bytesWritten, musicCRC); + bytesWritten += 2; - if (samples_out == -1) { - /* - * error decoding. Not fatal, but might screw up the - * ReplayGain tag. What should we do? Ignore for now - */ - samples_out = 0; - } - if (samples_out > 0) { - /* process the PCM data */ + // Calculate tag CRC.... must be done here, since it includes previous + // information - /* - * this should not be possible, and indicates we have - * overflown the pcm_buf buffer - */ + for (var i = 0; i < bytesWritten; i++) + crc = crcUpdateLookup(streamBuffer[streamBufferPos + i], crc); - if (gfc.findPeakSample) { - for (i = 0; i < samples_out; i++) { - if (pcm_buf[0][i] > gfc.PeakSample) - gfc.PeakSample = pcm_buf[0][i]; - else if (-pcm_buf[0][i] > gfc.PeakSample) - gfc.PeakSample = -pcm_buf[0][i]; - } - if (gfc.channels_out > 1) - for (i = 0; i < samples_out; i++) { - if (pcm_buf[1][i] > gfc.PeakSample) - gfc.PeakSample = pcm_buf[1][i]; - else if (-pcm_buf[1][i] > gfc.PeakSample) - gfc.PeakSample = -pcm_buf[1][i]; - } - } + createShort(streamBuffer, streamBufferPos + bytesWritten, crc); + bytesWritten += 2; - if (gfc.findReplayGain) - if (ga.AnalyzeSamples(gfc.rgdata, pcm_buf[0], 0, - pcm_buf[1], 0, samples_out, - gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR) - return -6; + return bytesWritten; + } - } - /* if (samples_out>0) */ - } - /* while (samples_out!=0) */ - } - /* if (gfc.decode_on_the_fly) */ + function skipId3v2(fpStream) { + // seek to the beginning of the stream + fpStream.seek(0); + // read 10 bytes in case there's an ID3 version 2 header here + var id3v2Header = new_byte(10); + fpStream.readFully(id3v2Header); + /* does the stream begin with the ID3 version 2 file identifier? */ + var id3v2TagSize; + if (!new String(id3v2Header, "ISO-8859-1").startsWith("ID3")) { + /* + * the tag size (minus the 10-byte header) is encoded into four + * bytes where the most significant bit is clear in each byte + */ + id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21) + | ((id3v2Header[7] & 0x7f) << 14) + | ((id3v2Header[8] & 0x7f) << 7) | (id3v2Header[9] & 0x7f)) + + id3v2Header.length; + } else { + /* no ID3 version 2 tag in this stream */ + id3v2TagSize = 0; + } + return id3v2TagSize; + } + + this.getLameTagFrame = function (gfp, buffer) { + var gfc = gfp.internal_flags; + if (!gfp.bWriteVbrTag) { + return 0; + } + if (gfc.Class_ID != Lame.LAME_ID) { + return 0; + } + if (gfc.VBR_seek_table.pos <= 0) { + return 0; + } + if (buffer.length < gfc.VBR_seek_table.TotalFrameSize) { + return gfc.VBR_seek_table.TotalFrameSize; } - /* if (mp3data) */ - return minimum; - }; - this.init_bit_stream_w = function (gfc) { - buf = new_byte(Lame.LAME_MAXMP3BUFFER); + Arrays.fill(buffer, 0, gfc.VBR_seek_table.TotalFrameSize, 0); - gfc.h_ptr = gfc.w_ptr = 0; - gfc.header[gfc.h_ptr].write_timing = 0; - bufByteIdx = -1; - bufBitIdx = 0; - totbit = 0; - }; + // 4 bytes frame header + setLameTagFrameHeader(gfp, buffer); - // From machine.h + // Create TOC entries + var toc = new_byte(NUMTOCENTRIES); + if (gfp.free_format) { + for (var i = 1; i < NUMTOCENTRIES; ++i) + toc[i] = 0xff & (255 * i / 100); + } else { + xingSeekTable(gfc.VBR_seek_table, toc); + } -} + // Start writing the tag after the zero frame + var streamIndex = gfc.sideinfo_len; + /** + * Note: Xing header specifies that Xing data goes in the ancillary data + * with NO ERROR PROTECTION. If error protecton in enabled, the Xing + * data still starts at the same offset, and now it is in sideinfo data + * block, and thus will not decode correctly by non-Xing tag aware + * players + */ + if (gfp.error_protection) + streamIndex -= 2; + // Put Vbr tag + if (gfp.VBR == VbrMode.vbr_off) { + buffer[streamIndex++] = 0xff & VBRTag1.charAt(0); + buffer[streamIndex++] = 0xff & VBRTag1.charAt(1); + buffer[streamIndex++] = 0xff & VBRTag1.charAt(2); + buffer[streamIndex++] = 0xff & VBRTag1.charAt(3); -/** - * A Vbr header may be present in the ancillary data field of the first frame of - * an mp3 bitstream
- * The Vbr header (optionally) contains - *
    - *
  • frames total number of audio frames in the bitstream - *
  • bytes total number of bytes in the bitstream - *
  • toc table of contents - *
- * - * toc (table of contents) gives seek points for random access.
- * The ith entry determines the seek point for i-percent duration.
- * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes
- * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes - */ -VBRTag.NUMTOCENTRIES = 100; -VBRTag.MAXFRAMESIZE = 2880; + } else { + buffer[streamIndex++] = 0xff & VBRTag0.charAt(0); + buffer[streamIndex++] = 0xff & VBRTag0.charAt(1); + buffer[streamIndex++] = 0xff & VBRTag0.charAt(2); + buffer[streamIndex++] = 0xff & VBRTag0.charAt(3); + } -function VBRTag() { + // Put header flags + createInteger(buffer, streamIndex, FRAMES_FLAG + BYTES_FLAG + TOC_FLAG + + VBR_SCALE_FLAG); + streamIndex += 4; - var lame; - var bs; - var v; + // Put Total Number of frames + createInteger(buffer, streamIndex, gfc.VBR_seek_table.nVbrNumFrames); + streamIndex += 4; - this.setModules = function (_lame, _bs, _v) { - lame = _lame; - bs = _bs; - v = _v; - }; + // Put total audio stream size, including Xing/LAME Header + var streamSize = (gfc.VBR_seek_table.nBytesWritten + gfc.VBR_seek_table.TotalFrameSize); + createInteger(buffer, streamIndex, 0 | streamSize); + streamIndex += 4; - var FRAMES_FLAG = 0x0001; - var BYTES_FLAG = 0x0002; - var TOC_FLAG = 0x0004; - var VBR_SCALE_FLAG = 0x0008; + /* Put TOC */ + System.arraycopy(toc, 0, buffer, streamIndex, toc.length); + streamIndex += toc.length; - var NUMTOCENTRIES = VBRTag.NUMTOCENTRIES; + if (gfp.error_protection) { + // (jo) error_protection: add crc16 information to header + bs.CRC_writeheader(gfc, buffer); + } - /** - * (0xB40) the max freeformat 640 32kHz framesize. - */ - var MAXFRAMESIZE = VBRTag.MAXFRAMESIZE; + // work out CRC so far: initially crc = 0 + var crc = 0x00; + for (var i = 0; i < streamIndex; i++) + crc = crcUpdateLookup(buffer[i], crc); + // Put LAME VBR info + streamIndex += putLameVBR(gfp, streamSize, buffer, streamIndex, crc); + + return gfc.VBR_seek_table.TotalFrameSize; + } /** - *
-     *    4 bytes for Header Tag
-     *    4 bytes for Header Flags
-     *  100 bytes for entry (toc)
-     *    4 bytes for frame size
-     *    4 bytes for stream size
-     *    4 bytes for VBR scale. a VBR quality indicator: 0=best 100=worst
-     *   20 bytes for LAME tag.  for example, "LAME3.12 (beta 6)"
-     * ___________
-     *  140 bytes
-     * 
+ * Write final VBR tag to the file. + * + * @param gfp + * global flags + * @param stream + * stream to add the VBR tag to + * @return 0 (OK), -1 else + * @throws IOException + * I/O error */ - var VBRHEADERSIZE = (NUMTOCENTRIES + 4 + 4 + 4 + 4 + 4); + this.putVbrTag = function (gfp, stream) { + var gfc = gfp.internal_flags; - var LAMEHEADERSIZE = (VBRHEADERSIZE + 9 + 1 + 1 + 8 - + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2); + if (gfc.VBR_seek_table.pos <= 0) + return -1; - /** - * The size of the Xing header MPEG-1, bit rate in kbps. - */ - var XING_BITRATE1 = 128; - /** - * The size of the Xing header MPEG-2, bit rate in kbps. - */ - var XING_BITRATE2 = 64; - /** - * The size of the Xing header MPEG-2.5, bit rate in kbps. - */ - var XING_BITRATE25 = 32; + // Seek to end of file + stream.seek(stream.length()); - /** - * ISO-8859-1 charset for byte to string operations. - */ - var ISO_8859_1 = null; //Charset.forName("ISO-8859-1"); + // Get file size, abort if file has zero length. + if (stream.length() == 0) + return -1; - /** - * VBR header magic string. - */ - var VBRTag0 = "Xing"; - /** - * VBR header magic string (VBR == VBRMode.vbr_off). - */ - var VBRTag1 = "Info"; + // The VBR tag may NOT be located at the beginning of the stream. If an + // ID3 version 2 tag was added, then it must be skipped to write the VBR + // tag data. + var id3v2TagSize = skipId3v2(stream); - /** - * Lookup table for fast CRC-16 computation. Uses the polynomial - * x^16+x^15+x^2+1 - */ - var crc16Lookup = [0x0000, 0xC0C1, 0xC181, 0x0140, - 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, - 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, - 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, - 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, - 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, - 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, - 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, - 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, - 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, - 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, - 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, - 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, - 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, - 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, - 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, - 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, - 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, - 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, - 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, - 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, - 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, - 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, - 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, - 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, - 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, - 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, - 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, - 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, - 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, - 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, - 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, - 0x4100, 0x81C1, 0x8081, 0x4040]; + // Seek to the beginning of the stream + stream.seek(id3v2TagSize); - /*********************************************************************** - * Robert Hegemann 2001-01-17 - ***********************************************************************/ + var buffer = new_byte(MAXFRAMESIZE); + var bytes = getLameTagFrame(gfp, buffer); + if (bytes > buffer.length) { + return -1; + } + + if (bytes < 1) { + return 0; + } + + // Put it all to disk again + stream.write(buffer, 0, bytes); + // success + return 0; + } + +} + + + +BitStream.EQ = function (a, b) { + return (Math.abs(a) > Math.abs(b)) ? (Math.abs((a) - (b)) <= (Math + .abs(a) * 1e-6)) + : (Math.abs((a) - (b)) <= (Math.abs(b) * 1e-6)); +}; + +BitStream.NEQ = function (a, b) { + return !BitStream.EQ(a, b); +}; - function addVbr(v, bitrate) { - v.nVbrNumFrames++; - v.sum += bitrate; - v.seen++; +function BitStream() { + var self = this; + var CRC16_POLYNOMIAL = 0x8005; - if (v.seen < v.want) { - return; - } + /* + * we work with ints, so when doing bit manipulation, we limit ourselves to + * MAX_LENGTH-2 just to be on the safe side + */ + var MAX_LENGTH = 32; - if (v.pos < v.size) { - v.bag[v.pos] = v.sum; - v.pos++; - v.seen = 0; - } - if (v.pos == v.size) { - for (var i = 1; i < v.size; i += 2) { - v.bag[i / 2] = v.bag[i]; - } - v.want *= 2; - v.pos /= 2; - } - } + //GainAnalysis ga; + //MPGLib mpg; + //Version ver; + //VBRTag vbr; + var ga = null; + var mpg = null; + var ver = null; + var vbr = null; - function xingSeekTable(v, t) { - if (v.pos <= 0) - return; + //public final void setModules(GainAnalysis ga, MPGLib mpg, Version ver, + // VBRTag vbr) { - for (var i = 1; i < NUMTOCENTRIES; ++i) { - var j = i / NUMTOCENTRIES, act, sum; - var indx = 0 | (Math.floor(j * v.pos)); - if (indx > v.pos - 1) - indx = v.pos - 1; - act = v.bag[indx]; - sum = v.sum; - var seek_point = 0 | (256. * act / sum); - if (seek_point > 255) - seek_point = 255; - t[i] = 0xff & seek_point; - } - } + this.setModules = function (_ga, _mpg, _ver, _vbr) { + ga = _ga; + mpg = _mpg; + ver = _ver; + vbr = _vbr; + }; /** - * Add VBR entry, used to fill the VBR TOC entries. - * - * @param gfp - * global flags + * Bit stream buffer. */ - this.addVbrFrame = function (gfp) { - var gfc = gfp.internal_flags; - var kbps = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; - addVbr(gfc.VBR_seek_table, kbps); - } + //private byte[] buf; + var buf = null; + /** + * Bit counter of bit stream. + */ + var totbit = 0; + /** + * Pointer to top byte in buffer. + */ + var bufByteIdx = 0; + /** + * Pointer to top bit of top byte in buffer. + */ + var bufBitIdx = 0; /** - * Read big endian integer (4-bytes) from header. - * - * @param buf - * header containing the integer - * @param bufPos - * offset into the header - * @return extracted integer + * compute bitsperframe and mean_bits for a layer III frame */ - function extractInteger(buf, bufPos) { - var x = buf[bufPos + 0] & 0xff; - x <<= 8; - x |= buf[bufPos + 1] & 0xff; - x <<= 8; - x |= buf[bufPos + 2] & 0xff; - x <<= 8; - x |= buf[bufPos + 3] & 0xff; - return x; + this.getframebits = function (gfp) { + var gfc = gfp.internal_flags; + var bit_rate; + + /* get bitrate in kbps [?] */ + if (gfc.bitrate_index != 0) + bit_rate = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; + else + bit_rate = gfp.brate; + + /* main encoding routine toggles padding on and off */ + /* one Layer3 Slot consists of 8 bits */ + var bytes = 0 | (gfp.version + 1) * 72000 * bit_rate / gfp.out_samplerate + gfc.padding; + return 8 * bytes; + }; + + function putheader_bits(gfc) { + System.arraycopy(gfc.header[gfc.w_ptr].buf, 0, buf, bufByteIdx, gfc.sideinfo_len); + bufByteIdx += gfc.sideinfo_len; + totbit += gfc.sideinfo_len * 8; + gfc.w_ptr = (gfc.w_ptr + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); } /** - * Write big endian integer (4-bytes) in the header. - * - * @param buf - * header to write the integer into - * @param bufPos - * offset into the header - * @param value - * integer value to write + * write j bits into the bit stream */ - function createInteger(buf, bufPos, value) { - buf[bufPos + 0] = 0xff & ((value >> 24) & 0xff); - buf[bufPos + 1] = 0xff & ((value >> 16) & 0xff); - buf[bufPos + 2] = 0xff & ((value >> 8) & 0xff); - buf[bufPos + 3] = 0xff & (value & 0xff); + function putbits2(gfc, val, j) { + + while (j > 0) { + var k; + if (bufBitIdx == 0) { + bufBitIdx = 8; + bufByteIdx++; + if (gfc.header[gfc.w_ptr].write_timing == totbit) { + putheader_bits(gfc); + } + buf[bufByteIdx] = 0; + } + + k = Math.min(j, bufBitIdx); + j -= k; + + bufBitIdx -= k; + + /* 32 too large on 32 bit machines */ + + buf[bufByteIdx] |= ((val >> j) << bufBitIdx); + totbit += k; + } } /** - * Write big endian short (2-bytes) in the header. - * - * @param buf - * header to write the integer into - * @param bufPos - * offset into the header - * @param value - * integer value to write + * write j bits into the bit stream, ignoring frame headers */ - function createShort(buf, bufPos, value) { - buf[bufPos + 0] = 0xff & ((value >> 8) & 0xff); - buf[bufPos + 1] = 0xff & (value & 0xff); + function putbits_noheaders(gfc, val, j) { + + while (j > 0) { + var k; + if (bufBitIdx == 0) { + bufBitIdx = 8; + bufByteIdx++; + buf[bufByteIdx] = 0; + } + + k = Math.min(j, bufBitIdx); + j -= k; + + bufBitIdx -= k; + + /* 32 too large on 32 bit machines */ + + buf[bufByteIdx] |= ((val >> j) << bufBitIdx); + totbit += k; + } } /** - * Check for magic strings (Xing/Info). - * - * @param buf - * header to check - * @param bufPos - * header offset to check - * @return magic string found + * Some combinations of bitrate, Fs, and stereo make it impossible to stuff + * out a frame using just main_data, due to the limited number of bits to + * indicate main_data_length. In these situations, we put stuffing bits into + * the ancillary data... */ - function isVbrTag(buf, bufPos) { - return new String(buf, bufPos, VBRTag0.length(), ISO_8859_1) - .equals(VBRTag0) - || new String(buf, bufPos, VBRTag1.length(), ISO_8859_1) - .equals(VBRTag1); - } + function drain_into_ancillary(gfp, remainingBits) { + var gfc = gfp.internal_flags; + var i; + + if (remainingBits >= 8) { + putbits2(gfc, 0x4c, 8); + remainingBits -= 8; + } + if (remainingBits >= 8) { + putbits2(gfc, 0x41, 8); + remainingBits -= 8; + } + if (remainingBits >= 8) { + putbits2(gfc, 0x4d, 8); + remainingBits -= 8; + } + if (remainingBits >= 8) { + putbits2(gfc, 0x45, 8); + remainingBits -= 8; + } + + if (remainingBits >= 32) { + var version = ver.getLameShortVersion(); + if (remainingBits >= 32) + for (i = 0; i < version.length && remainingBits >= 8; ++i) { + remainingBits -= 8; + putbits2(gfc, version.charAt(i), 8); + } + } + + for (; remainingBits >= 1; remainingBits -= 1) { + putbits2(gfc, gfc.ancillary_flag, 1); + gfc.ancillary_flag ^= (!gfp.disable_reservoir ? 1 : 0); + } + - function shiftInBitsValue(x, n, v) { - return 0xff & ((x << n) | (v & ~(-1 << n))); } /** - * Construct the MP3 header using the settings of the global flags. - * - * - * - * @param gfp - * global flags - * @param buffer - * header + * write N bits into the header */ - function setLameTagFrameHeader(gfp, buffer) { - var gfc = gfp.internal_flags; + function writeheader(gfc, val, j) { + var ptr = gfc.header[gfc.h_ptr].ptr; - // MP3 Sync Word - buffer[0] = shiftInBitsValue(buffer[0], 8, 0xff); + while (j > 0) { + var k = Math.min(j, 8 - (ptr & 7)); + j -= k; + /* >> 32 too large for 32 bit machines */ - buffer[1] = shiftInBitsValue(buffer[1], 3, 7); - buffer[1] = shiftInBitsValue(buffer[1], 1, - (gfp.out_samplerate < 16000) ? 0 : 1); - // Version - buffer[1] = shiftInBitsValue(buffer[1], 1, gfp.version); - // 01 == Layer 3 - buffer[1] = shiftInBitsValue(buffer[1], 2, 4 - 3); - // Error protection - buffer[1] = shiftInBitsValue(buffer[1], 1, (!gfp.error_protection) ? 1 - : 0); + gfc.header[gfc.h_ptr].buf[ptr >> 3] |= ((val >> j)) << (8 - (ptr & 7) - k); + ptr += k; + } + gfc.header[gfc.h_ptr].ptr = ptr; + } - // Bit rate - buffer[2] = shiftInBitsValue(buffer[2], 4, gfc.bitrate_index); - // Frequency - buffer[2] = shiftInBitsValue(buffer[2], 2, gfc.samplerate_index); - // Pad. Bit - buffer[2] = shiftInBitsValue(buffer[2], 1, 0); - // Priv. Bit - buffer[2] = shiftInBitsValue(buffer[2], 1, gfp.extension); + function CRC_update(value, crc) { + value <<= 8; + for (var i = 0; i < 8; i++) { + value <<= 1; + crc <<= 1; - // Mode - buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.mode.ordinal()); - // Mode extension (Used with Joint Stereo) - buffer[3] = shiftInBitsValue(buffer[3], 2, gfc.mode_ext); - // Copy - buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.copyright); - // Original - buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.original); - // Emphasis - buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.emphasis); + if ((((crc ^ value) & 0x10000) != 0)) + crc ^= CRC16_POLYNOMIAL; + } + return crc; + } - /* the default VBR header. 48 kbps layer III, no padding, no crc */ - /* but sampling freq, mode and copyright/copy protection taken */ - /* from first valid frame */ - buffer[0] = 0xff; - var abyte = 0xff & (buffer[1] & 0xf1); - var bitrate; - if (1 == gfp.version) { - bitrate = XING_BITRATE1; - } else { - if (gfp.out_samplerate < 16000) - bitrate = XING_BITRATE25; - else - bitrate = XING_BITRATE2; + this.CRC_writeheader = function (gfc, header) { + var crc = 0xffff; + /* (jo) init crc16 for error_protection */ + + crc = CRC_update(header[2] & 0xff, crc); + crc = CRC_update(header[3] & 0xff, crc); + for (var i = 6; i < gfc.sideinfo_len; i++) { + crc = CRC_update(header[i] & 0xff, crc); } - if (gfp.VBR == VbrMode.vbr_off) - bitrate = gfp.brate; + header[4] = (byte)(crc >> 8); + header[5] = (byte)(crc & 255); + }; - var bbyte; - if (gfp.free_format) - bbyte = 0x00; + function encodeSideInfo2(gfp, bitsPerFrame) { + var gfc = gfp.internal_flags; + var l3_side; + var gr, ch; + + l3_side = gfc.l3_side; + gfc.header[gfc.h_ptr].ptr = 0; + Arrays.fill(gfc.header[gfc.h_ptr].buf, 0, gfc.sideinfo_len, 0); + if (gfp.out_samplerate < 16000) + writeheader(gfc, 0xffe, 12); else - bbyte = 0xff & (16 * lame.BitrateIndex(bitrate, gfp.version, - gfp.out_samplerate)); + writeheader(gfc, 0xfff, 12); + writeheader(gfc, (gfp.version), 1); + writeheader(gfc, 4 - 3, 2); + writeheader(gfc, (!gfp.error_protection ? 1 : 0), 1); + writeheader(gfc, (gfc.bitrate_index), 4); + writeheader(gfc, (gfc.samplerate_index), 2); + writeheader(gfc, (gfc.padding), 1); + writeheader(gfc, (gfp.extension), 1); + writeheader(gfc, (gfp.mode.ordinal()), 2); + writeheader(gfc, (gfc.mode_ext), 2); + writeheader(gfc, (gfp.copyright), 1); + writeheader(gfc, (gfp.original), 1); + writeheader(gfc, (gfp.emphasis), 2); + if (gfp.error_protection) { + writeheader(gfc, 0, 16); + /* dummy */ + } - /* - * Use as much of the info from the real frames in the Xing header: - * samplerate, channels, crc, etc... - */ if (gfp.version == 1) { /* MPEG1 */ - buffer[1] = 0xff & (abyte | 0x0a); - /* was 0x0b; */ - abyte = 0xff & (buffer[2] & 0x0d); - /* AF keep also private bit */ - buffer[2] = 0xff & (bbyte | abyte); - /* 64kbs MPEG1 frame */ - } else { - /* MPEG2 */ - buffer[1] = 0xff & (abyte | 0x02); - /* was 0x03; */ - abyte = 0xff & (buffer[2] & 0x0d); - /* AF keep also private bit */ - buffer[2] = 0xff & (bbyte | abyte); - /* 64kbs MPEG2 frame */ - } - } + writeheader(gfc, (l3_side.main_data_begin), 9); - /** - * Get VBR tag information - * - * @param buf - * header to analyze - * @param bufPos - * offset into the header - * @return VBR tag data - */ - this.getVbrTag = function (buf) { - var pTagData = new VBRTagData(); - var bufPos = 0; + if (gfc.channels_out == 2) + writeheader(gfc, l3_side.private_bits, 3); + else + writeheader(gfc, l3_side.private_bits, 5); - /* get Vbr header data */ - pTagData.flags = 0; + for (ch = 0; ch < gfc.channels_out; ch++) { + var band; + for (band = 0; band < 4; band++) { + writeheader(gfc, l3_side.scfsi[ch][band], 1); + } + } - /* get selected MPEG header data */ - var hId = (buf[bufPos + 1] >> 3) & 1; - var hSrIndex = (buf[bufPos + 2] >> 2) & 3; - var hMode = (buf[bufPos + 3] >> 6) & 3; - var hBitrate = ((buf[bufPos + 2] >> 4) & 0xf); - hBitrate = Tables.bitrate_table[hId][hBitrate]; + for (gr = 0; gr < 2; gr++) { + for (ch = 0; ch < gfc.channels_out; ch++) { + var gi = l3_side.tt[gr][ch]; + writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); + writeheader(gfc, gi.big_values / 2, 9); + writeheader(gfc, gi.global_gain, 8); + writeheader(gfc, gi.scalefac_compress, 4); - /* check for FFE syncword */ - if ((buf[bufPos + 1] >> 4) == 0xE) - pTagData.samprate = Tables.samplerate_table[2][hSrIndex]; - else - pTagData.samprate = Tables.samplerate_table[hId][hSrIndex]; + if (gi.block_type != Encoder.NORM_TYPE) { + writeheader(gfc, 1, 1); + /* window_switching_flag */ + writeheader(gfc, gi.block_type, 2); + writeheader(gfc, gi.mixed_block_flag, 1); - /* determine offset of header */ - if (hId != 0) { - /* mpeg1 */ - if (hMode != 3) - bufPos += (32 + 4); - else - bufPos += (17 + 4); - } else { - /* mpeg2 */ - if (hMode != 3) - bufPos += (17 + 4); - else - bufPos += (9 + 4); - } + if (gi.table_select[0] == 14) + gi.table_select[0] = 16; + writeheader(gfc, gi.table_select[0], 5); + if (gi.table_select[1] == 14) + gi.table_select[1] = 16; + writeheader(gfc, gi.table_select[1], 5); - if (!isVbrTag(buf, bufPos)) - return null; + writeheader(gfc, gi.subblock_gain[0], 3); + writeheader(gfc, gi.subblock_gain[1], 3); + writeheader(gfc, gi.subblock_gain[2], 3); + } else { + writeheader(gfc, 0, 1); + /* window_switching_flag */ + if (gi.table_select[0] == 14) + gi.table_select[0] = 16; + writeheader(gfc, gi.table_select[0], 5); + if (gi.table_select[1] == 14) + gi.table_select[1] = 16; + writeheader(gfc, gi.table_select[1], 5); + if (gi.table_select[2] == 14) + gi.table_select[2] = 16; + writeheader(gfc, gi.table_select[2], 5); - bufPos += 4; + writeheader(gfc, gi.region0_count, 4); + writeheader(gfc, gi.region1_count, 3); + } + writeheader(gfc, gi.preflag, 1); + writeheader(gfc, gi.scalefac_scale, 1); + writeheader(gfc, gi.count1table_select, 1); + } + } + } else { + /* MPEG2 */ + writeheader(gfc, (l3_side.main_data_begin), 8); + writeheader(gfc, l3_side.private_bits, gfc.channels_out); - pTagData.hId = hId; + gr = 0; + for (ch = 0; ch < gfc.channels_out; ch++) { + var gi = l3_side.tt[gr][ch]; + writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); + writeheader(gfc, gi.big_values / 2, 9); + writeheader(gfc, gi.global_gain, 8); + writeheader(gfc, gi.scalefac_compress, 9); - /* get flags */ - var head_flags = pTagData.flags = extractInteger(buf, bufPos); - bufPos += 4; + if (gi.block_type != Encoder.NORM_TYPE) { + writeheader(gfc, 1, 1); + /* window_switching_flag */ + writeheader(gfc, gi.block_type, 2); + writeheader(gfc, gi.mixed_block_flag, 1); - if ((head_flags & FRAMES_FLAG) != 0) { - pTagData.frames = extractInteger(buf, bufPos); - bufPos += 4; - } + if (gi.table_select[0] == 14) + gi.table_select[0] = 16; + writeheader(gfc, gi.table_select[0], 5); + if (gi.table_select[1] == 14) + gi.table_select[1] = 16; + writeheader(gfc, gi.table_select[1], 5); + + writeheader(gfc, gi.subblock_gain[0], 3); + writeheader(gfc, gi.subblock_gain[1], 3); + writeheader(gfc, gi.subblock_gain[2], 3); + } else { + writeheader(gfc, 0, 1); + /* window_switching_flag */ + if (gi.table_select[0] == 14) + gi.table_select[0] = 16; + writeheader(gfc, gi.table_select[0], 5); + if (gi.table_select[1] == 14) + gi.table_select[1] = 16; + writeheader(gfc, gi.table_select[1], 5); + if (gi.table_select[2] == 14) + gi.table_select[2] = 16; + writeheader(gfc, gi.table_select[2], 5); - if ((head_flags & BYTES_FLAG) != 0) { - pTagData.bytes = extractInteger(buf, bufPos); - bufPos += 4; - } + writeheader(gfc, gi.region0_count, 4); + writeheader(gfc, gi.region1_count, 3); + } - if ((head_flags & TOC_FLAG) != 0) { - if (pTagData.toc != null) { - for (var i = 0; i < NUMTOCENTRIES; i++) - pTagData.toc[i] = buf[bufPos + i]; + writeheader(gfc, gi.scalefac_scale, 1); + writeheader(gfc, gi.count1table_select, 1); } - bufPos += NUMTOCENTRIES; } - pTagData.vbrScale = -1; - - if ((head_flags & VBR_SCALE_FLAG) != 0) { - pTagData.vbrScale = extractInteger(buf, bufPos); - bufPos += 4; + if (gfp.error_protection) { + /* (jo) error_protection: add crc16 information to header */ + CRC_writeheader(gfc, gfc.header[gfc.h_ptr].buf); } - pTagData.headersize = ((hId + 1) * 72000 * hBitrate) - / pTagData.samprate; + { + var old = gfc.h_ptr; - bufPos += 21; - var encDelay = buf[bufPos + 0] << 4; - encDelay += buf[bufPos + 1] >> 4; - var encPadding = (buf[bufPos + 1] & 0x0F) << 8; - encPadding += buf[bufPos + 2] & 0xff; - /* check for reasonable values (this may be an old Xing header, */ - /* not a INFO tag) */ - if (encDelay < 0 || encDelay > 3000) - encDelay = -1; - if (encPadding < 0 || encPadding > 3000) - encPadding = -1; + gfc.h_ptr = (old + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); + gfc.header[gfc.h_ptr].write_timing = gfc.header[old].write_timing + + bitsPerFrame; - pTagData.encDelay = encDelay; - pTagData.encPadding = encPadding; + if (gfc.h_ptr == gfc.w_ptr) { + /* yikes! we are out of header buffer space */ + System.err + .println("Error: MAX_HEADER_BUF too small in bitstream.c \n"); + } - /* success */ - return pTagData; + } } - /** - * Initializes the header - * - * @param gfp - * global flags - */ - this.InitVbrTag = function (gfp) { - var gfc = gfp.internal_flags; - - /** - *
-         * Xing VBR pretends to be a 48kbs layer III frame.  (at 44.1kHz).
-         * (at 48kHz they use 56kbs since 48kbs frame not big enough for
-         * table of contents)
-         * let's always embed Xing header inside a 64kbs layer III frame.
-         * this gives us enough room for a LAME version string too.
-         * size determined by sampling frequency (MPEG1)
-         * 32kHz:    216 bytes@48kbs    288bytes@ 64kbs
-         * 44.1kHz:  156 bytes          208bytes@64kbs     (+1 if padding = 1)
-         * 48kHz:    144 bytes          192
-         *
-         * MPEG 2 values are the same since the framesize and samplerate
-         * are each reduced by a factor of 2.
-         * 
- */ - var kbps_header; - if (1 == gfp.version) { - kbps_header = XING_BITRATE1; - } else { - if (gfp.out_samplerate < 16000) - kbps_header = XING_BITRATE25; - else - kbps_header = XING_BITRATE2; - } + function huffman_coder_count1(gfc, gi) { + /* Write count1 area */ + var h = Tables.ht[gi.count1table_select + 32]; + var i, bits = 0; - if (gfp.VBR == VbrMode.vbr_off) - kbps_header = gfp.brate; + var ix = gi.big_values; + var xr = gi.big_values; - // make sure LAME Header fits into Frame - var totalFrameSize = ((gfp.version + 1) * 72000 * kbps_header) - / gfp.out_samplerate; - var headerSize = (gfc.sideinfo_len + LAMEHEADERSIZE); - gfc.VBR_seek_table.TotalFrameSize = totalFrameSize; - if (totalFrameSize < headerSize || totalFrameSize > MAXFRAMESIZE) { - /* disable tag, it wont fit */ - gfp.bWriteVbrTag = false; - return; - } + for (i = (gi.count1 - gi.big_values) / 4; i > 0; --i) { + var huffbits = 0; + var p = 0, v; - gfc.VBR_seek_table.nVbrNumFrames = 0; - gfc.VBR_seek_table.nBytesWritten = 0; - gfc.VBR_seek_table.sum = 0; + v = gi.l3_enc[ix + 0]; + if (v != 0) { + p += 8; + if (gi.xr[xr + 0] < 0) + huffbits++; + } - gfc.VBR_seek_table.seen = 0; - gfc.VBR_seek_table.want = 1; - gfc.VBR_seek_table.pos = 0; + v = gi.l3_enc[ix + 1]; + if (v != 0) { + p += 4; + huffbits *= 2; + if (gi.xr[xr + 1] < 0) + huffbits++; + } - if (gfc.VBR_seek_table.bag == null) { - gfc.VBR_seek_table.bag = new int[400]; - gfc.VBR_seek_table.size = 400; - } + v = gi.l3_enc[ix + 2]; + if (v != 0) { + p += 2; + huffbits *= 2; + if (gi.xr[xr + 2] < 0) + huffbits++; + } - // write dummy VBR tag of all 0's into bitstream - var buffer = new_byte(MAXFRAMESIZE); + v = gi.l3_enc[ix + 3]; + if (v != 0) { + p++; + huffbits *= 2; + if (gi.xr[xr + 3] < 0) + huffbits++; + } - setLameTagFrameHeader(gfp, buffer); - var n = gfc.VBR_seek_table.TotalFrameSize; - for (var i = 0; i < n; ++i) { - bs.add_dummy_byte(gfp, buffer[i] & 0xff, 1); + ix += 4; + xr += 4; + putbits2(gfc, huffbits + h.table[p], h.hlen[p]); + bits += h.hlen[p]; } + return bits; } /** - * Fast CRC-16 computation (uses table crc16Lookup). - * - * @param value - * @param crc - * @return - */ - function crcUpdateLookup(value, crc) { - var tmp = crc ^ value; - crc = (crc >> 8) ^ crc16Lookup[tmp & 0xff]; - return crc; - } - - this.updateMusicCRC = function (crc, buffer, bufferPos, size) { - for (var i = 0; i < size; ++i) - crc[0] = crcUpdateLookup(buffer[bufferPos + i], crc[0]); - } - - /** - * Write LAME info: mini version + info on various switches used (Jonathan - * Dee 2001/08/31). - * - * @param gfp - * global flags - * @param musicLength - * music length - * @param streamBuffer - * pointer to output buffer - * @param streamBufferPos - * offset into the output buffer - * @param crc - * computation of CRC-16 of Lame Tag so far (starting at frame - * sync) - * @return number of bytes written to the stream + * Implements the pseudocode of page 98 of the IS */ - function putLameVBR(gfp, musicLength, streamBuffer, streamBufferPos, crc) { - var gfc = gfp.internal_flags; - var bytesWritten = 0; - - /* encoder delay */ - var encDelay = gfp.encoder_delay; - /* encoder padding */ - var encPadding = gfp.encoder_padding; - - /* recall: gfp.VBR_q is for example set by the switch -V */ - /* gfp.quality by -q, -h, -f, etc */ - var quality = (100 - 10 * gfp.VBR_q - gfp.quality); - - var version = v.getLameVeryShortVersion(); - var vbr; - var revision = 0x00; - var revMethod; - // numbering different in vbr_mode vs. Lame tag - var vbrTypeTranslator = [1, 5, 3, 2, 4, 0, 3]; - var lowpass = 0 | (((gfp.lowpassfreq / 100.0) + .5) > 255 ? 255 - : (gfp.lowpassfreq / 100.0) + .5); - var peakSignalAmplitude = 0; - var radioReplayGain = 0; - var audiophileReplayGain = 0; - var noiseShaping = gfp.internal_flags.noise_shaping; - var stereoMode = 0; - var nonOptimal = 0; - var sourceFreq = 0; - var misc = 0; - var musicCRC = 0; - - // psy model type: Gpsycho or NsPsytune - var expNPsyTune = (gfp.exp_nspsytune & 1) != 0; - var safeJoint = (gfp.exp_nspsytune & 2) != 0; - var noGapMore = false; - var noGapPrevious = false; - var noGapCount = gfp.internal_flags.nogap_total; - var noGapCurr = gfp.internal_flags.nogap_current; - - // 4 bits - var athType = gfp.ATHtype; - var flags = 0; - - // vbr modes - var abrBitrate; - switch (gfp.VBR) { - case vbr_abr: - abrBitrate = gfp.VBR_mean_bitrate_kbps; - break; - case vbr_off: - abrBitrate = gfp.brate; - break; - default: - abrBitrate = gfp.VBR_min_bitrate_kbps; - } + function Huffmancode(gfc, tableindex, start, end, gi) { + var h = Tables.ht[tableindex]; + var bits = 0; - // revision and vbr method - if (gfp.VBR.ordinal() < vbrTypeTranslator.length) - vbr = vbrTypeTranslator[gfp.VBR.ordinal()]; - else - vbr = 0x00; // unknown + if (0 == tableindex) + return bits; - revMethod = 0x10 * revision + vbr; + for (var i = start; i < end; i += 2) { + var cbits = 0; + var xbits = 0; + var linbits = h.xlen; + var xlen = h.xlen; + var ext = 0; + var x1 = gi.l3_enc[i]; + var x2 = gi.l3_enc[i + 1]; - // ReplayGain - if (gfc.findReplayGain) { - if (gfc.RadioGain > 0x1FE) - gfc.RadioGain = 0x1FE; - if (gfc.RadioGain < -0x1FE) - gfc.RadioGain = -0x1FE; + if (x1 != 0) { + if (gi.xr[i] < 0) + ext++; + cbits--; + } - // set name code - radioReplayGain = 0x2000; - // set originator code to `determined automatically' - radioReplayGain |= 0xC00; + if (tableindex > 15) { + /* use ESC-words */ + if (x1 > 14) { + var linbits_x1 = x1 - 15; + ext |= linbits_x1 << 1; + xbits = linbits; + x1 = 15; + } - if (gfc.RadioGain >= 0) { - // set gain adjustment - radioReplayGain |= gfc.RadioGain; - } else { - // set the sign bit - radioReplayGain |= 0x200; - // set gain adjustment - radioReplayGain |= -gfc.RadioGain; + if (x2 > 14) { + var linbits_x2 = x2 - 15; + ext <<= linbits; + ext |= linbits_x2; + xbits += linbits; + x2 = 15; + } + xlen = 16; } - } - // peak sample - if (gfc.findPeakSample) - peakSignalAmplitude = Math - .abs(0 | ((( gfc.PeakSample) / 32767.0) * Math.pow(2, 23) + .5)); + if (x2 != 0) { + ext <<= 1; + if (gi.xr[i + 1] < 0) + ext++; + cbits--; + } - // nogap - if (noGapCount != -1) { - if (noGapCurr > 0) - noGapPrevious = true; - if (noGapCurr < noGapCount - 1) - noGapMore = true; + x1 = x1 * xlen + x2; + xbits -= cbits; + cbits += h.hlen[x1]; + + + putbits2(gfc, h.table[x1], cbits); + putbits2(gfc, ext, xbits); + bits += cbits + xbits; } + return bits; + } - // flags - flags = athType + ((expNPsyTune ? 1 : 0) << 4) - + ((safeJoint ? 1 : 0) << 5) + ((noGapMore ? 1 : 0) << 6) - + ((noGapPrevious ? 1 : 0) << 7); + /** + * Note the discussion of huffmancodebits() on pages 28 and 29 of the IS, as + * well as the definitions of the side information on pages 26 and 27. + */ + function ShortHuffmancodebits(gfc, gi) { + var region1Start = 3 * gfc.scalefac_band.s[3]; + if (region1Start > gi.big_values) + region1Start = gi.big_values; - if (quality < 0) - quality = 0; + /* short blocks do not have a region2 */ + var bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); + bits += Huffmancode(gfc, gi.table_select[1], region1Start, + gi.big_values, gi); + return bits; + } - // stereo mode field (Intensity stereo is not implemented) - switch (gfp.mode) { - case MONO: - stereoMode = 0; - break; - case STEREO: - stereoMode = 1; - break; - case DUAL_CHANNEL: - stereoMode = 2; - break; - case JOINT_STEREO: - if (gfp.force_ms) - stereoMode = 4; - else - stereoMode = 3; - break; - case NOT_SET: - //$FALL-THROUGH$ - default: - stereoMode = 7; - break; - } + function LongHuffmancodebits(gfc, gi) { + var bigvalues, bits; + var region1Start, region2Start; - if (gfp.in_samplerate <= 32000) - sourceFreq = 0x00; - else if (gfp.in_samplerate == 48000) - sourceFreq = 0x02; - else if (gfp.in_samplerate > 48000) - sourceFreq = 0x03; - else { - // default is 44100Hz - sourceFreq = 0x01; - } + bigvalues = gi.big_values; - // Check if the user overrided the default LAME behavior with some - // nasty options - if (gfp.short_blocks == ShortBlock.short_block_forced - || gfp.short_blocks == ShortBlock.short_block_dispensed - || ((gfp.lowpassfreq == -1) && (gfp.highpassfreq == -1)) || /* "-k" */ - (gfp.scale_left < gfp.scale_right) - || (gfp.scale_left > gfp.scale_right) - || (gfp.disable_reservoir && gfp.brate < 320) || gfp.noATH - || gfp.ATHonly || (athType == 0) || gfp.in_samplerate <= 32000) - nonOptimal = 1; + var i = gi.region0_count + 1; + region1Start = gfc.scalefac_band.l[i]; + i += gi.region1_count + 1; + region2Start = gfc.scalefac_band.l[i]; - misc = noiseShaping + (stereoMode << 2) + (nonOptimal << 5) - + (sourceFreq << 6); + if (region1Start > bigvalues) + region1Start = bigvalues; - musicCRC = gfc.nMusicCRC; + if (region2Start > bigvalues) + region2Start = bigvalues; - // Write all this information into the stream + bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); + bits += Huffmancode(gfc, gi.table_select[1], region1Start, + region2Start, gi); + bits += Huffmancode(gfc, gi.table_select[2], region2Start, bigvalues, + gi); + return bits; + } - createInteger(streamBuffer, streamBufferPos + bytesWritten, quality); - bytesWritten += 4; + function writeMainData(gfp) { + var gr, ch, sfb, data_bits, tot_bits = 0; + var gfc = gfp.internal_flags; + var l3_side = gfc.l3_side; - for (var j = 0; j < 9; j++) { - streamBuffer[streamBufferPos + bytesWritten + j] = 0xff & version .charAt(j); - } - bytesWritten += 9; + if (gfp.version == 1) { + /* MPEG 1 */ + for (gr = 0; gr < 2; gr++) { + for (ch = 0; ch < gfc.channels_out; ch++) { + var gi = l3_side.tt[gr][ch]; + var slen1 = Takehiro.slen1_tab[gi.scalefac_compress]; + var slen2 = Takehiro.slen2_tab[gi.scalefac_compress]; + data_bits = 0; + for (sfb = 0; sfb < gi.sfbdivide; sfb++) { + if (gi.scalefac[sfb] == -1) + continue; + /* scfsi is used */ + putbits2(gfc, gi.scalefac[sfb], slen1); + data_bits += slen1; + } + for (; sfb < gi.sfbmax; sfb++) { + if (gi.scalefac[sfb] == -1) + continue; + /* scfsi is used */ + putbits2(gfc, gi.scalefac[sfb], slen2); + data_bits += slen2; + } - streamBuffer[streamBufferPos + bytesWritten] = 0xff & revMethod; - bytesWritten++; + if (gi.block_type == Encoder.SHORT_TYPE) { + data_bits += ShortHuffmancodebits(gfc, gi); + } else { + data_bits += LongHuffmancodebits(gfc, gi); + } + data_bits += huffman_coder_count1(gfc, gi); + /* does bitcount in quantize.c agree with actual bit count? */ + tot_bits += data_bits; + } + /* for ch */ + } + /* for gr */ + } else { + /* MPEG 2 */ + gr = 0; + for (ch = 0; ch < gfc.channels_out; ch++) { + var gi = l3_side.tt[gr][ch]; + var i, sfb_partition, scale_bits = 0; + data_bits = 0; + sfb = 0; + sfb_partition = 0; + + if (gi.block_type == Encoder.SHORT_TYPE) { + for (; sfb_partition < 4; sfb_partition++) { + var sfbs = gi.sfb_partition_table[sfb_partition] / 3; + var slen = gi.slen[sfb_partition]; + for (i = 0; i < sfbs; i++, sfb++) { + putbits2(gfc, + Math.max(gi.scalefac[sfb * 3 + 0], 0), slen); + putbits2(gfc, + Math.max(gi.scalefac[sfb * 3 + 1], 0), slen); + putbits2(gfc, + Math.max(gi.scalefac[sfb * 3 + 2], 0), slen); + scale_bits += 3 * slen; + } + } + data_bits += ShortHuffmancodebits(gfc, gi); + } else { + for (; sfb_partition < 4; sfb_partition++) { + var sfbs = gi.sfb_partition_table[sfb_partition]; + var slen = gi.slen[sfb_partition]; + for (i = 0; i < sfbs; i++, sfb++) { + putbits2(gfc, Math.max(gi.scalefac[sfb], 0), slen); + scale_bits += slen; + } + } + data_bits += LongHuffmancodebits(gfc, gi); + } + data_bits += huffman_coder_count1(gfc, gi); + /* does bitcount in quantize.c agree with actual bit count? */ + tot_bits += scale_bits + data_bits; + } + /* for ch */ + } + /* for gf */ + return tot_bits; + } - streamBuffer[streamBufferPos + bytesWritten] = 0xff & lowpass; - bytesWritten++; + /* main_data */ - createInteger(streamBuffer, streamBufferPos + bytesWritten, - peakSignalAmplitude); - bytesWritten += 4; + function TotalBytes() { + this.total = 0; + } - createShort(streamBuffer, streamBufferPos + bytesWritten, - radioReplayGain); - bytesWritten += 2; + /* + * compute the number of bits required to flush all mp3 frames currently in + * the buffer. This should be the same as the reservoir size. Only call this + * routine between frames - i.e. only after all headers and data have been + * added to the buffer by format_bitstream(). + * + * Also compute total_bits_output = size of mp3 buffer (including frame + * headers which may not have yet been send to the mp3 buffer) + number of + * bits needed to flush all mp3 frames. + * + * total_bytes_output is the size of the mp3 output buffer if + * lame_encode_flush_nogap() was called right now. + */ + function compute_flushbits(gfp, total_bytes_output) { + var gfc = gfp.internal_flags; + var flushbits, remaining_headers; + var bitsPerFrame; + var last_ptr, first_ptr; + first_ptr = gfc.w_ptr; + /* first header to add to bitstream */ + last_ptr = gfc.h_ptr - 1; + /* last header to add to bitstream */ + if (last_ptr == -1) + last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; - createShort(streamBuffer, streamBufferPos + bytesWritten, - audiophileReplayGain); - bytesWritten += 2; + /* add this many bits to bitstream so we can flush all headers */ + flushbits = gfc.header[last_ptr].write_timing - totbit; + total_bytes_output.total = flushbits; - streamBuffer[streamBufferPos + bytesWritten] = 0xff & flags; - bytesWritten++; + if (flushbits >= 0) { + /* if flushbits >= 0, some headers have not yet been written */ + /* reduce flushbits by the size of the headers */ + remaining_headers = 1 + last_ptr - first_ptr; + if (last_ptr < first_ptr) + remaining_headers = 1 + last_ptr - first_ptr + + LameInternalFlags.MAX_HEADER_BUF; + flushbits -= remaining_headers * 8 * gfc.sideinfo_len; + } - if (abrBitrate >= 255) - streamBuffer[streamBufferPos + bytesWritten] = 0xFF; + /* + * finally, add some bits so that the last frame is complete these bits + * are not necessary to decode the last frame, but some decoders will + * ignore last frame if these bits are missing + */ + bitsPerFrame = self.getframebits(gfp); + flushbits += bitsPerFrame; + total_bytes_output.total += bitsPerFrame; + /* round up: */ + if ((total_bytes_output.total % 8) != 0) + total_bytes_output.total = 1 + (total_bytes_output.total / 8); else - streamBuffer[streamBufferPos + bytesWritten] = 0xff & abrBitrate; - bytesWritten++; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & (encDelay >> 4); - streamBuffer[streamBufferPos + bytesWritten + 1] = 0xff & ((encDelay << 4) + (encPadding >> 8)); - streamBuffer[streamBufferPos + bytesWritten + 2] = 0xff & encPadding; + total_bytes_output.total = (total_bytes_output.total / 8); + total_bytes_output.total += bufByteIdx + 1; - bytesWritten += 3; + if (flushbits < 0) { + System.err.println("strange error flushing buffer ... \n"); + } + return flushbits; + } - streamBuffer[streamBufferPos + bytesWritten] = 0xff & misc; - bytesWritten++; + this.flush_bitstream = function (gfp) { + var gfc = gfp.internal_flags; + var l3_side; + var flushbits; + var last_ptr = gfc.h_ptr - 1; + /* last header to add to bitstream */ + if (last_ptr == -1) + last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; + l3_side = gfc.l3_side; - // unused in rev0 - streamBuffer[streamBufferPos + bytesWritten++] = 0; + if ((flushbits = compute_flushbits(gfp, new TotalBytes())) < 0) + return; + drain_into_ancillary(gfp, flushbits); - createShort(streamBuffer, streamBufferPos + bytesWritten, gfp.preset); - bytesWritten += 2; + /* check that the 100% of the last frame has been written to bitstream */ - createInteger(streamBuffer, streamBufferPos + bytesWritten, musicLength); - bytesWritten += 4; + /* + * we have padded out all frames with ancillary data, which is the same + * as filling the bitreservoir with ancillary data, so : + */ + gfc.ResvSize = 0; + l3_side.main_data_begin = 0; - createShort(streamBuffer, streamBufferPos + bytesWritten, musicCRC); - bytesWritten += 2; + /* save the ReplayGain value */ + if (gfc.findReplayGain) { + var RadioGain = ga.GetTitleGain(gfc.rgdata); + gfc.RadioGain = Math.floor(RadioGain * 10.0 + 0.5) | 0; + /* round to nearest */ + } - // Calculate tag CRC.... must be done here, since it includes previous - // information + /* find the gain and scale change required for no clipping */ + if (gfc.findPeakSample) { + gfc.noclipGainChange = Math.ceil(Math + .log10(gfc.PeakSample / 32767.0) * 20.0 * 10.0) | 0; + /* round up */ - for (var i = 0; i < bytesWritten; i++) - crc = crcUpdateLookup(streamBuffer[streamBufferPos + i], crc); + if (gfc.noclipGainChange > 0) { + /* clipping occurs */ + if (EQ(gfp.scale, 1.0) || EQ(gfp.scale, 0.0)) + gfc.noclipScale = (Math + .floor((32767.0 / gfc.PeakSample) * 100.0) / 100.0); + /* round down */ + else { + /* + * the user specified his own scaling factor. We could + * suggest the scaling factor of + * (32767.0/gfp.PeakSample)*(gfp.scale) but it's usually + * very inaccurate. So we'd rather not advice him on the + * scaling factor. + */ + gfc.noclipScale = -1; + } + } else + /* no clipping */ + gfc.noclipScale = -1; + } + }; - createShort(streamBuffer, streamBufferPos + bytesWritten, crc); - bytesWritten += 2; + this.add_dummy_byte = function (gfp, val, n) { + var gfc = gfp.internal_flags; + var i; - return bytesWritten; - } + while (n-- > 0) { + putbits_noheaders(gfc, val, 8); - function skipId3v2(fpStream) { - // seek to the beginning of the stream - fpStream.seek(0); - // read 10 bytes in case there's an ID3 version 2 header here - var id3v2Header = new_byte(10); - fpStream.readFully(id3v2Header); - /* does the stream begin with the ID3 version 2 file identifier? */ - var id3v2TagSize; - if (!new String(id3v2Header, "ISO-8859-1").startsWith("ID3")) { - /* - * the tag size (minus the 10-byte header) is encoded into four - * bytes where the most significant bit is clear in each byte - */ - id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21) - | ((id3v2Header[7] & 0x7f) << 14) - | ((id3v2Header[8] & 0x7f) << 7) | (id3v2Header[9] & 0x7f)) - + id3v2Header.length; - } else { - /* no ID3 version 2 tag in this stream */ - id3v2TagSize = 0; + for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) + gfc.header[i].write_timing += 8; } - return id3v2TagSize; - } + }; - this.getLameTagFrame = function (gfp, buffer) { + /** + * This is called after a frame of audio has been quantized and coded. It + * will write the encoded audio to the bitstream. Note that from a layer3 + * encoder's perspective the bit stream is primarily a series of main_data() + * blocks, with header and side information inserted at the proper locations + * to maintain framing. (See Figure A.7 in the IS). + */ + this.format_bitstream = function (gfp) { var gfc = gfp.internal_flags; + var l3_side; + l3_side = gfc.l3_side; - if (!gfp.bWriteVbrTag) { - return 0; - } - if (gfc.Class_ID != Lame.LAME_ID) { - return 0; - } - if (gfc.VBR_seek_table.pos <= 0) { - return 0; - } - if (buffer.length < gfc.VBR_seek_table.TotalFrameSize) { - return gfc.VBR_seek_table.TotalFrameSize; - } + var bitsPerFrame = this.getframebits(gfp); + drain_into_ancillary(gfp, l3_side.resvDrain_pre); - Arrays.fill(buffer, 0, gfc.VBR_seek_table.TotalFrameSize, 0); + encodeSideInfo2(gfp, bitsPerFrame); + var bits = 8 * gfc.sideinfo_len; + bits += writeMainData(gfp); + drain_into_ancillary(gfp, l3_side.resvDrain_post); + bits += l3_side.resvDrain_post; - // 4 bytes frame header - setLameTagFrameHeader(gfp, buffer); + l3_side.main_data_begin += (bitsPerFrame - bits) / 8; - // Create TOC entries - var toc = new_byte(NUMTOCENTRIES); + /* + * compare number of bits needed to clear all buffered mp3 frames with + * what we think the resvsize is: + */ + if (compute_flushbits(gfp, new TotalBytes()) != gfc.ResvSize) { + System.err.println("Internal buffer inconsistency. flushbits <> ResvSize"); + } - if (gfp.free_format) { - for (var i = 1; i < NUMTOCENTRIES; ++i) - toc[i] = 0xff & (255 * i / 100); - } else { - xingSeekTable(gfc.VBR_seek_table, toc); + /* + * compare main_data_begin for the next frame with what we think the + * resvsize is: + */ + if ((l3_side.main_data_begin * 8) != gfc.ResvSize) { + System.err.printf("bit reservoir error: \n" + + "l3_side.main_data_begin: %d \n" + + "Resvoir size: %d \n" + + "resv drain (post) %d \n" + + "resv drain (pre) %d \n" + + "header and sideinfo: %d \n" + + "data bits: %d \n" + + "total bits: %d (remainder: %d) \n" + + "bitsperframe: %d \n", + 8 * l3_side.main_data_begin, gfc.ResvSize, + l3_side.resvDrain_post, l3_side.resvDrain_pre, + 8 * gfc.sideinfo_len, bits - l3_side.resvDrain_post - 8 + * gfc.sideinfo_len, bits, bits % 8, bitsPerFrame); + + System.err.println("This is a fatal error. It has several possible causes:"); + System.err.println("90%% LAME compiled with buggy version of gcc using advanced optimizations"); + System.err.println(" 9%% Your system is overclocked"); + System.err.println(" 1%% bug in LAME encoding library"); + + gfc.ResvSize = l3_side.main_data_begin * 8; } + //; - // Start writing the tag after the zero frame - var streamIndex = gfc.sideinfo_len; - /** - * Note: Xing header specifies that Xing data goes in the ancillary data - * with NO ERROR PROTECTION. If error protecton in enabled, the Xing - * data still starts at the same offset, and now it is in sideinfo data - * block, and thus will not decode correctly by non-Xing tag aware - * players - */ - if (gfp.error_protection) - streamIndex -= 2; + if (totbit > 1000000000) { + /* + * to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset + * bit counter + */ + var i; + for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) + gfc.header[i].write_timing -= totbit; + totbit = 0; + } - // Put Vbr tag - if (gfp.VBR == VbrMode.vbr_off) { - buffer[streamIndex++] = 0xff & VBRTag1.charAt(0); - buffer[streamIndex++] = 0xff & VBRTag1.charAt(1); - buffer[streamIndex++] = 0xff & VBRTag1.charAt(2); - buffer[streamIndex++] = 0xff & VBRTag1.charAt(3); + return 0; + }; - } else { - buffer[streamIndex++] = 0xff & VBRTag0.charAt(0); - buffer[streamIndex++] = 0xff & VBRTag0.charAt(1); - buffer[streamIndex++] = 0xff & VBRTag0.charAt(2); - buffer[streamIndex++] = 0xff & VBRTag0.charAt(3); + /** + *
+     * copy data out of the internal MP3 bit buffer into a user supplied
+     *       unsigned char buffer.
+     *
+     *       mp3data=0      indicates data in buffer is an id3tags and VBR tags
+     *       mp3data=1      data is real mp3 frame data.
+     * 
+ */ + this.copy_buffer = function (gfc, buffer, bufferPos, size, mp3data) { + var minimum = bufByteIdx + 1; + if (minimum <= 0) + return 0; + if (size != 0 && minimum > size) { + /* buffer is too small */ + return -1; } + System.arraycopy(buf, 0, buffer, bufferPos, minimum); + bufByteIdx = -1; + bufBitIdx = 0; - // Put header flags - createInteger(buffer, streamIndex, FRAMES_FLAG + BYTES_FLAG + TOC_FLAG - + VBR_SCALE_FLAG); - streamIndex += 4; + if (mp3data != 0) { + var crc = new_int(1); + crc[0] = gfc.nMusicCRC; + vbr.updateMusicCRC(crc, buffer, bufferPos, minimum); + gfc.nMusicCRC = crc[0]; - // Put Total Number of frames - createInteger(buffer, streamIndex, gfc.VBR_seek_table.nVbrNumFrames); - streamIndex += 4; + /** + * sum number of bytes belonging to the mp3 stream this info will be + * written into the Xing/LAME header for seeking + */ + if (minimum > 0) { + gfc.VBR_seek_table.nBytesWritten += minimum; + } - // Put total audio stream size, including Xing/LAME Header - var streamSize = (gfc.VBR_seek_table.nBytesWritten + gfc.VBR_seek_table.TotalFrameSize); - createInteger(buffer, streamIndex, 0 | streamSize); - streamIndex += 4; + if (gfc.decode_on_the_fly) { /* decode the frame */ + var pcm_buf = new_float_n([2, 1152]); + var mp3_in = minimum; + var samples_out = -1; + var i; - /* Put TOC */ - System.arraycopy(toc, 0, buffer, streamIndex, toc.length); - streamIndex += toc.length; + /* re-synthesis to pcm. Repeat until we get a samples_out=0 */ + while (samples_out != 0) { - if (gfp.error_protection) { - // (jo) error_protection: add crc16 information to header - bs.CRC_writeheader(gfc, buffer); - } + samples_out = mpg.hip_decode1_unclipped(gfc.hip, buffer, + bufferPos, mp3_in, pcm_buf[0], pcm_buf[1]); + /* + * samples_out = 0: need more data to decode samples_out = + * -1: error. Lets assume 0 pcm output samples_out = number + * of samples output + */ - // work out CRC so far: initially crc = 0 - var crc = 0x00; - for (var i = 0; i < streamIndex; i++) - crc = crcUpdateLookup(buffer[i], crc); - // Put LAME VBR info - streamIndex += putLameVBR(gfp, streamSize, buffer, streamIndex, crc); + /* + * set the lenght of the mp3 input buffer to zero, so that + * in the next iteration of the loop we will be querying + * mpglib about buffered data + */ + mp3_in = 0; - return gfc.VBR_seek_table.TotalFrameSize; - } + if (samples_out == -1) { + /* + * error decoding. Not fatal, but might screw up the + * ReplayGain tag. What should we do? Ignore for now + */ + samples_out = 0; + } + if (samples_out > 0) { + /* process the PCM data */ - /** - * Write final VBR tag to the file. - * - * @param gfp - * global flags - * @param stream - * stream to add the VBR tag to - * @return 0 (OK), -1 else - * @throws IOException - * I/O error - */ - this.putVbrTag = function (gfp, stream) { - var gfc = gfp.internal_flags; + /* + * this should not be possible, and indicates we have + * overflown the pcm_buf buffer + */ - if (gfc.VBR_seek_table.pos <= 0) - return -1; + if (gfc.findPeakSample) { + for (i = 0; i < samples_out; i++) { + if (pcm_buf[0][i] > gfc.PeakSample) + gfc.PeakSample = pcm_buf[0][i]; + else if (-pcm_buf[0][i] > gfc.PeakSample) + gfc.PeakSample = -pcm_buf[0][i]; + } + if (gfc.channels_out > 1) + for (i = 0; i < samples_out; i++) { + if (pcm_buf[1][i] > gfc.PeakSample) + gfc.PeakSample = pcm_buf[1][i]; + else if (-pcm_buf[1][i] > gfc.PeakSample) + gfc.PeakSample = -pcm_buf[1][i]; + } + } - // Seek to end of file - stream.seek(stream.length()); + if (gfc.findReplayGain) + if (ga.AnalyzeSamples(gfc.rgdata, pcm_buf[0], 0, + pcm_buf[1], 0, samples_out, + gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR) + return -6; - // Get file size, abort if file has zero length. - if (stream.length() == 0) - return -1; + } + /* if (samples_out>0) */ + } + /* while (samples_out!=0) */ + } + /* if (gfc.decode_on_the_fly) */ - // The VBR tag may NOT be located at the beginning of the stream. If an - // ID3 version 2 tag was added, then it must be skipped to write the VBR - // tag data. - var id3v2TagSize = skipId3v2(stream); + } + /* if (mp3data) */ + return minimum; + }; - // Seek to the beginning of the stream - stream.seek(id3v2TagSize); + this.init_bit_stream_w = function (gfc) { + buf = new_byte(Lame.LAME_MAXMP3BUFFER); - var buffer = new_byte(MAXFRAMESIZE); - var bytes = getLameTagFrame(gfp, buffer); - if (bytes > buffer.length) { - return -1; - } + gfc.h_ptr = gfc.w_ptr = 0; + gfc.header[gfc.h_ptr].write_timing = 0; + bufByteIdx = -1; + bufBitIdx = 0; + totbit = 0; + }; - if (bytes < 1) { - return 0; - } + // From machine.h - // Put it all to disk again - stream.write(buffer, 0, bytes); - // success - return 0; - } } @@ -5135,6 +5135,32 @@ function MeanBits(meanBits) { this.bits = meanBits; } +//package mp3; + +function CalcNoiseResult() { + /** + * sum of quantization noise > masking + */ + this.over_noise = 0.; + /** + * sum of all quantization noise + */ + this.tot_noise = 0.; + /** + * max quantization noise + */ + this.max_noise = 0.; + /** + * number of quantization noise > masking + */ + this.over_count = 0; + /** + * SSD-like cost of distorted bands + */ + this.over_SSD = 0; + this.bits = 0; +} + function VBRQuantize() { var qupvt; var tak; @@ -5147,30 +5173,66 @@ function VBRQuantize() { } -//package mp3; -function CalcNoiseResult() { + +/** + * ATH related stuff, if something new ATH related has to be added, please plug + * it here into the ATH. + */ +function ATH() { + /** + * Method for the auto adjustment. + */ + this.useAdjust = 0; + /** + * factor for tuning the (sample power) point below which adaptive threshold + * of hearing adjustment occurs + */ + this.aaSensitivityP = 0.; + /** + * Lowering based on peak volume, 1 = no lowering. + */ + this.adjust = 0.; + /** + * Limit for dynamic ATH adjust. + */ + this.adjustLimit = 0.; + /** + * Determined to lower x dB each second. + */ + this.decay = 0.; /** - * sum of quantization noise > masking + * Lowest ATH value. */ - this.over_noise = 0.; + this.floor = 0.; /** - * sum of all quantization noise + * ATH for sfbs in long blocks. */ - this.tot_noise = 0.; + this.l = new_float(Encoder.SBMAX_l); /** - * max quantization noise + * ATH for sfbs in short blocks. */ - this.max_noise = 0.; + this.s = new_float(Encoder.SBMAX_s); /** - * number of quantization noise > masking + * ATH for partitioned sfb21 in long blocks. */ - this.over_count = 0; + this.psfb21 = new_float(Encoder.PSFB21); /** - * SSD-like cost of distorted bands + * ATH for partitioned sfb12 in short blocks. */ - this.over_SSD = 0; - this.bits = 0; + this.psfb12 = new_float(Encoder.PSFB12); + /** + * ATH for long block convolution bands. + */ + this.cb_l = new_float(Encoder.CBANDS); + /** + * ATH for short block convolution bands. + */ + this.cb_s = new_float(Encoder.CBANDS); + /** + * Equal loudness weights (based on ATH). + */ + this.eql_w = new_float(Encoder.BLKSIZE / 2); } @@ -5442,110 +5504,6 @@ function LameGlobalFlags() { -/** - * ATH related stuff, if something new ATH related has to be added, please plug - * it here into the ATH. - */ -function ATH() { - /** - * Method for the auto adjustment. - */ - this.useAdjust = 0; - /** - * factor for tuning the (sample power) point below which adaptive threshold - * of hearing adjustment occurs - */ - this.aaSensitivityP = 0.; - /** - * Lowering based on peak volume, 1 = no lowering. - */ - this.adjust = 0.; - /** - * Limit for dynamic ATH adjust. - */ - this.adjustLimit = 0.; - /** - * Determined to lower x dB each second. - */ - this.decay = 0.; - /** - * Lowest ATH value. - */ - this.floor = 0.; - /** - * ATH for sfbs in long blocks. - */ - this.l = new_float(Encoder.SBMAX_l); - /** - * ATH for sfbs in short blocks. - */ - this.s = new_float(Encoder.SBMAX_s); - /** - * ATH for partitioned sfb21 in long blocks. - */ - this.psfb21 = new_float(Encoder.PSFB21); - /** - * ATH for partitioned sfb12 in short blocks. - */ - this.psfb12 = new_float(Encoder.PSFB12); - /** - * ATH for long block convolution bands. - */ - this.cb_l = new_float(Encoder.CBANDS); - /** - * ATH for short block convolution bands. - */ - this.cb_s = new_float(Encoder.CBANDS); - /** - * Equal loudness weights (based on ATH). - */ - this.eql_w = new_float(Encoder.BLKSIZE / 2); -} - - - -function ReplayGain() { - this.linprebuf = new_float(GainAnalysis.MAX_ORDER * 2); - /** - * left input samples, with pre-buffer - */ - this.linpre = 0; - this.lstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - /** - * left "first step" (i.e. post first filter) samples - */ - this.lstep = 0; - this.loutbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - /** - * left "out" (i.e. post second filter) samples - */ - this.lout = 0; - this.rinprebuf = new_float(GainAnalysis.MAX_ORDER * 2); - /** - * right input samples ... - */ - this.rinpre = 0; - this.rstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - this.rstep = 0; - this.routbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - this.rout = 0; - /** - * number of samples required to reach number of milliseconds required - * for RMS window - */ - this.sampleWindow = 0; - this.totsamp = 0; - this.lsum = 0.; - this.rsum = 0.; - this.freqindex = 0; - this.first = 0; - this.A = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)); - this.B = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)); - -} - - - function CBRNewIterationLoop(_quantize) { var quantize = _quantize; this.quantize = quantize; @@ -5614,6 +5572,48 @@ function CBRNewIterationLoop(_quantize) { this.quantize.rv.ResvFrameEnd(gfc, mean_bits); } } + + +function ReplayGain() { + this.linprebuf = new_float(GainAnalysis.MAX_ORDER * 2); + /** + * left input samples, with pre-buffer + */ + this.linpre = 0; + this.lstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); + /** + * left "first step" (i.e. post first filter) samples + */ + this.lstep = 0; + this.loutbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); + /** + * left "out" (i.e. post second filter) samples + */ + this.lout = 0; + this.rinprebuf = new_float(GainAnalysis.MAX_ORDER * 2); + /** + * right input samples ... + */ + this.rinpre = 0; + this.rstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); + this.rstep = 0; + this.routbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); + this.rout = 0; + /** + * number of samples required to reach number of milliseconds required + * for RMS window + */ + this.sampleWindow = 0; + this.totsamp = 0; + this.lsum = 0.; + this.rsum = 0.; + this.freqindex = 0; + this.first = 0; + this.A = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)); + this.B = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)); + +} + //package mp3; /** @@ -6657,6 +6657,15 @@ function QuantizePVT() { } + +function CalcNoiseData() { + this.global_gain = 0; + this.sfb_count1 = 0; + this.step = new_int(39); + this.noise = new_float(39); + this.noise_log = new_float(39); +} + //package mp3; @@ -6748,15 +6757,6 @@ function GrInfo() { } -function CalcNoiseData() { - this.global_gain = 0; - this.sfb_count1 = 0; - this.step = new_int(39); - this.noise = new_float(39); - this.noise_log = new_float(39); -} - - var L3Side = {}; @@ -10074,6 +10074,22 @@ function IIISideInfo() { } +function III_psy_xmin() { + this.l = new_float(Encoder.SBMAX_l); + this.s = new_float_n([Encoder.SBMAX_s, 3]); + + var self = this; + this.assign = function (iii_psy_xmin) { + System.arraycopy(iii_psy_xmin.l, 0, self.l, 0, Encoder.SBMAX_l); + for (var i = 0; i < Encoder.SBMAX_s; i++) { + for (var j = 0; j < 3; j++) { + self.s[i][j] = iii_psy_xmin.s[i][j]; + } + } + } +} + + //package mp3; @@ -10098,22 +10114,6 @@ function NsPsy() { } -function III_psy_xmin() { - this.l = new_float(Encoder.SBMAX_l); - this.s = new_float_n([Encoder.SBMAX_s, 3]); - - var self = this; - this.assign = function (iii_psy_xmin) { - System.arraycopy(iii_psy_xmin.l, 0, self.l, 0, Encoder.SBMAX_l); - for (var i = 0; i < Encoder.SBMAX_s; i++) { - for (var j = 0; j < 3; j++) { - self.s[i][j] = iii_psy_xmin.s[i][j]; - } - } - } -} - - LameInternalFlags.MFSIZE = (3 * 1152 + Encoder.ENCDELAY - Encoder.MDCTDELAY); @@ -15345,7 +15345,6 @@ function Lame() { - function GetAudio() { var parse; var mpg; @@ -15492,7 +15491,6 @@ WavHeader.readHeader = function (dataView) { break; default: throw 'extended fmt chunk not implemented'; - break; } pos += fmtLen; var data = WavHeader.data; @@ -15510,78 +15508,6 @@ WavHeader.readHeader = function (dataView) { return w; }; -function testFullLength() { - var r = fs.readFileSync("testdata/IMG_0373.wav"); - var sampleBuf = new Uint8Array(r).buffer; - var w = WavHeader.readHeader(new DataView(sampleBuf)); - var samples = new Int16Array(sampleBuf, w.dataOffset, w.dataLen / 2); - var remaining = samples.length; - var lameEnc = new Mp3Encoder(); //w.channels, w.sampleRate, 128); - var maxSamples = 1152; - - var fd = fs.openSync("testjs2.mp3", "w"); - var time = new Date().getTime(); - for (var i = 0; remaining >= maxSamples; i += maxSamples) { - var left = samples.subarray(i, i + maxSamples); - var right = samples.subarray(i, i + maxSamples); - - var mp3buf = lameEnc.encodeBuffer(left, right); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - remaining -= maxSamples; - } - var mp3buf = lameEnc.flush(); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - fs.closeSync(fd); - time = new Date().getTime() - time; - console.log('done in ' + time + 'msec'); -} - -function testStereo44100() { - var r1 = fs.readFileSync("testdata/Left44100.wav"); - var r2 = fs.readFileSync("testdata/Right44100.wav"); - var fd = fs.openSync("stereo.mp3", "w"); - - var sampleBuf1 = new Uint8Array(r1).buffer; - var sampleBuf2 = new Uint8Array(r2).buffer; - var w1 = WavHeader.readHeader(new DataView(sampleBuf1)); - var w2 = WavHeader.readHeader(new DataView(sampleBuf2)); - - var samples1 = new Int16Array(sampleBuf1, w1.dataOffset, w1.dataLen / 2); - var samples2 = new Int16Array(sampleBuf2, w2.dataOffset, w2.dataLen / 2); - var remaining1 = samples1.length; - var remaining2 = samples2.length; - - var lameEnc = new Mp3Encoder(2, w1.sampleRate, 128); - var maxSamples = 1152; - - var time = new Date().getTime(); - for (var i = 0; remaining1 >= maxSamples; i += maxSamples) { - var left = samples1.subarray(i, i + maxSamples); - var right = samples2.subarray(i, i + maxSamples); - - var mp3buf = lameEnc.encodeBuffer(left, right); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - remaining1 -= maxSamples; - - } - var mp3buf = lameEnc.flush(); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - fs.closeSync(fd); - time = new Date().getTime() - time; - console.log('done in ' + time + 'msec'); -} - -//testStereo44100(); -//testFullLength(); - L3Side.SFBMAX = (Encoder.SBMAX_s * 3); //testFullLength(); lamejs.Mp3Encoder = Mp3Encoder; diff --git a/lame.min.js b/lame.min.js index 6ebe697..363c7ba 100644 --- a/lame.min.js +++ b/lame.min.js @@ -1,309 +1,307 @@ -function lamejs(){function T(e){return new Int32Array(e)}function K(e){return new Float32Array(e)}function qa(e){if(1==e.length)return K(e[0]);for(var p=e[0],e=e.slice(1),l=[],z=0;zf&&(f=0);9q&&(q+=64);b.exp_nspsytune|=q<<2}0!=a?b.quant_comp=h[f].quant_comp:0=e)return z(b,e,a);b.preset=0;return e}}function U(){function e(q,h,b,n,a,f){for(;0!=a--;)b[n]=1E-10+q[h+ -0]*f[0]-b[n-1]*f[1]+q[h-1]*f[2]-b[n-2]*f[3]+q[h-2]*f[4]-b[n-3]*f[5]+q[h-3]*f[6]-b[n-4]*f[7]+q[h-4]*f[8]-b[n-5]*f[9]+q[h-5]*f[10]-b[n-6]*f[11]+q[h-6]*f[12]-b[n-7]*f[13]+q[h-7]*f[14]-b[n-8]*f[15]+q[h-8]*f[16]-b[n-9]*f[17]+q[h-9]*f[18]-b[n-10]*f[19]+q[h-10]*f[20],++n,++h}function p(e,h,b,n,a,f){for(;0!=a--;)b[n]=e[h+0]*f[0]-b[n-1]*f[1]+e[h-1]*f[2]-b[n-2]*f[3]+e[h-2]*f[4],++n,++h}var l=U.RMS_WINDOW_TIME_NUMERATOR,z=U.RMS_WINDOW_TIME_DENOMINATOR,x=[[0.038575994352,-3.84664617118067,-0.02160367184185,7.81501653005538, --0.00123395316851,-11.34170355132042,-9.291677959E-5,13.05504219327545,-0.01655260341619,-12.28759895145294,0.02161526843274,9.4829380631979,-0.02074045215285,-5.87257861775999,0.00594298065125,2.75465861874613,0.00306428023191,-0.86984376593551,1.2025322027E-4,0.13919314567432,0.00288463683916],[0.0541865640643,-3.47845948550071,-0.02911007808948,6.36317777566148,-0.00848709379851,-8.54751527471874,-0.00851165645469,9.4769360780128,-0.00834990904936,-8.81498681370155,0.02245293253339,6.85401540936998, --0.02596338512915,-4.39470996079559,0.01624864962975,2.19611684890774,-0.00240879051584,-0.75104302451432,0.00674613682247,0.13149317958808,-0.00187763777362],[0.15457299681924,-2.37898834973084,-0.09331049056315,2.84868151156327,-0.06247880153653,-2.64577170229825,0.02163541888798,2.23697657451713,-0.05588393329856,-1.67148153367602,0.04781476674921,1.00595954808547,0.00222312597743,-0.45953458054983,0.03174092540049,0.16378164858596,-0.01390589421898,-0.05032077717131,0.00651420667831,0.0234789740702, --0.00881362733839],[0.30296907319327,-1.61273165137247,-0.22613988682123,1.0797749225997,-0.08587323730772,-0.2565625775407,0.03282930172664,-0.1627671912044,-0.00915702933434,-0.22638893773906,-0.02364141202522,0.39120800788284,-0.00584456039913,-0.22138138954925,0.06276101321749,0.04500235387352,-8.28086748E-6,0.02005851806501,0.00205861885564,0.00302439095741,-0.02950134983287],[0.33642304856132,-1.49858979367799,-0.2557224142557,0.87350271418188,-0.11828570177555,0.12205022308084,0.11921148675203, --0.80774944671438,-0.07834489609479,0.47854794562326,-0.0046997791438,-0.12453458140019,-0.0058950022444,-0.04067510197014,0.05724228140351,0.08333755284107,0.00832043980773,-0.04237348025746,-0.0163538138454,0.02977207319925,-0.0176017656815],[0.4491525660845,-0.62820619233671,-0.14351757464547,0.29661783706366,-0.22784394429749,-0.372563729424,-0.01419140100551,0.00213767857124,0.04078262797139,-0.42029820170918,-0.12398163381748,0.22199650564824,0.04097565135648,0.00613424350682,0.10478503600251, -0.06747620744683,-0.01863887810927,0.05784820375801,-0.03193428438915,0.03222754072173,0.00541907748707],[0.56619470757641,-1.04800335126349,-0.75464456939302,0.29156311971249,0.1624213774223,-0.26806001042947,0.16744243493672,0.00819999645858,-0.18901604199609,0.45054734505008,0.3093178284183,-0.33032403314006,-0.27562961986224,0.0673936833311,0.00647310677246,-0.04784254229033,0.08647503780351,0.01639907836189,-0.0378898455484,0.01807364323573,-0.00588215443421],[0.58100494960553,-0.51035327095184, --0.53174909058578,-0.31863563325245,-0.14289799034253,-0.20256413484477,0.17520704835522,0.1472815413433,0.02377945217615,0.38952639978999,0.15558449135573,-0.23313271880868,-0.25344790059353,-0.05246019024463,0.01628462406333,-0.02505961724053,0.06920467763959,0.02442357316099,-0.03721611395801,0.01818801111503,-0.00749618797172],[0.53648789255105,-0.2504987195602,-0.42163034350696,-0.43193942311114,-0.00275953611929,-0.03424681017675,0.04267842219415,-0.04678328784242,-0.10214864179676,0.26408300200955, -0.14590772289388,0.15113130533216,-0.02459864859345,-0.17556493366449,-0.11202315195388,-0.18823009262115,-0.04060034127,0.05477720428674,0.0478866554818,0.0470440968812,-0.02217936801134]],u=[[0.98621192462708,-1.97223372919527,-1.97242384925416,0.97261396931306,0.98621192462708],[0.98500175787242,-1.96977855582618,-1.97000351574484,0.9702284756635,0.98500175787242],[0.97938932735214,-1.95835380975398,-1.95877865470428,0.95920349965459,0.97938932735214],[0.97531843204928,-1.95002759149878,-1.95063686409857, -0.95124613669835,0.97531843204928],[0.97316523498161,-1.94561023566527,-1.94633046996323,0.94705070426118,0.97316523498161],[0.96454515552826,-1.92783286977036,-1.92909031105652,0.93034775234268,0.96454515552826],[0.96009142950541,-1.91858953033784,-1.92018285901082,0.92177618768381,0.96009142950541],[0.95856916599601,-1.9154210807478,-1.91713833199203,0.91885558323625,0.95856916599601],[0.94597685600279,-1.88903307939452,-1.89195371200558,0.89487434461664,0.94597685600279]];this.InitGainAnalysis= -function(e,h){var b;a:{for(b=0;bq.sampleWindow-q.totsamp?q.sampleWindow-q.totsamp:c;yMAX_ORDER-y&&(B=MAX_ORDER-y)):(l=b+y,k=h,g=a+y,d=n);e(k,l,q.lstepbuf,q.lstep+q.totsamp,B,x[q.reqindex]);e(d,g,q.rstepbuf,q.rstep+q.totsamp,B,x[q.reqindex]);p(q.lstepbuf,q.lstep+q.totsamp,q.loutbuf,q.lout+q.totsamp,B,u[q.reqindex]);p(q.rstepbuf, -q.rstep+q.totsamp,q.routbuf,q.rout+q.totsamp,B,u[q.reqindex]);l=q.lout+q.totsamp;k=q.loutbuf;g=q.rout+q.totsamp;d=q.routbuf;for(var r=B%8;0!=r--;){var s=q,j=s.lsum,i=k[l++];s.lsum=j+i*i;s=q;j=s.rsum;i=d[g++];s.rsum=j+i*i}for(r=B/8;0!=r--;)q.lsum+=k[l+0]*k[l+0]+k[l+1]*k[l+1]+k[l+2]*k[l+2]+k[l+3]*k[l+3]+k[l+4]*k[l+4]+k[l+5]*k[l+5]+k[l+6]*k[l+6]+k[l+7]*k[l+7],l+=8,q.rsum+=d[g+0]*d[g+0]+d[g+1]*d[g+1]+d[g+2]*d[g+2]+d[g+3]*d[g+3]+d[g+4]*d[g+4]+d[g+5]*d[g+5]+d[g+6]*d[g+6]+d[g+7]*d[g+7],g+=8;c-=B;y+=B;q.totsamp+= -B;q.totsamp==q.sampleWindow&&(l=10*U.STEPS_per_dB*Math.log10(0.5*((q.lsum+q.rsum)/q.totsamp)+1E-37),l=0>=l?0:0|l,l>=q.A.length&&(l=q.A.length-1),q.A[l]++,q.lsum=q.rsum=0,N.arraycopy(q.loutbuf,q.totsamp,q.loutbuf,0,MAX_ORDER),N.arraycopy(q.routbuf,q.totsamp,q.routbuf,0,MAX_ORDER),N.arraycopy(q.lstepbuf,q.totsamp,q.lstepbuf,0,MAX_ORDER),N.arraycopy(q.rstepbuf,q.totsamp,q.rstepbuf,0,MAX_ORDER),q.totsamp=0);if(q.totsamp>q.sampleWindow)return GAIN_ANALYSIS_ERROR}f=(a-=h[n])););h=64.82-n/U.STEPS_per_dB}for(b= -0;bh&&(z.ResvMax=h);if(0>z.ResvMax||p.disable_reservoir)z.ResvMax=0;q=l.bits*z.mode_gr+Math.min(z.ResvSize,z.ResvMax);q>x&&(q=x);u.resvDrain_pre=0;null!=z.pinfo&&(z.pinfo.mean_bits=l.bits/2,z.pinfo.resvsize=z.ResvSize);return q};this.ResvMaxBits=function(e,l,D,x){var u=e.internal_flags,q=u.ResvSize,h=u.ResvMax;0!=x&&(q+=l);0!=(u.substep_shaping&1)&&(h*=0.9);D.bits=l;10*q>9*h?(x=q-9*h/10,D.bits+=x,u.substep_shaping|=128):(x=0,u.substep_shaping&=127,!e.disable_reservoir&& -0==(u.substep_shaping&1)&&(D.bits-=0.1*l));e=q<6*u.ResvMax/10?q:6*u.ResvMax/10;e-=x;0>e&&(e=0);return e};this.ResvAdjust=function(e,l){e.ResvSize-=l.part2_3_length+l.part2_length};this.ResvFrameEnd=function(e,l){var D,x=e.l3_side;e.ResvSize+=l*e.mode_gr;var u=0;x.resvDrain_post=0;x.resvDrain_pre=0;if(0!=(D=e.ResvSize%8))u+=D;D=e.ResvSize-u-e.ResvMax;0>=1;0!=a--;)j[i++]=c>b[e++]?0:1,j[i++]=c>b[e++]?0:1}function l(a,c,b,e,j,i){for(var a=a>>1,m=a%2,a=a>>1;0!=a--;){var d,t,g,f,h,n,k;d=b[e++]*c;t=b[e++]*c;h=0|d;g=b[e++]*c;n=0|t;f=b[e++]*c;k=0|g;d+=u.adj43[h];h=0|f;t+=u.adj43[n];j[i++]=0|d;g+=u.adj43[k];j[i++]=0|t;f+=u.adj43[h];j[i++]=0|g;j[i++]=0|f}0!=m&&(d=b[e++]*c,t=b[e++]*c,d+=u.adj43[0|d],t+=u.adj43[0|t],j[i++]=0|d,j[i++]=0|t)}function z(a,c,b,e){var d,i=c,m=d=0;do{var w=a[i++],t=a[i++];d>=16;d>a&&(d=a,c++);e.bits+=d;return c;case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:var i=c,c=h[d-1],w=m=d=0,t=v.ht[c].xlen,g=v.ht[c].hlen,f=v.ht[c+1].hlen,n=v.ht[c+2].hlen;do{var k= -a[i+0]*t+a[i+1],i=i+2;d+=g[k];m+=f[k];w+=n[k]}while(im&&(d=m,a++);d>w&&(d=w,a=c+2);e.bits+=d;return a;default:if(d>ca.IXMAX_VAL)return e.bits=ca.LARGE_BITS,-1;d-=15;for(i=24;32>i&&!(v.ht[i].linmax>=d);i++);for(m=i-8;24>m&&!(v.ht[m].linmax>=d);m++);d=m;w=65536*v.ht[d].xlen+v.ht[i].xlen;m=0;do t=a[c++],g=a[c++],0!=t&&(14>=16;m>a&&(m=a,d=i);e.bits+=m;return d}}function x(a,c,b,d,j,i,m,w){for(var t= -c.big_values,g=2;g=t)break;var h=j[g-2]+c.count1bits;if(b.part2_3_length<=h)break;h=new D(h);f=z(d,f,t,h);h=h.bits;b.part2_3_length<=h||(b.assign(c),b.part2_3_length=h,b.region0_count=i[g-2],b.region1_count=g-2-i[g-2],b.table_select[0]=m[g-2],b.table_select[1]=w[g-2],b.table_select[2]=f)}}var u=null;this.qupvt=null;this.setModules=function(a){u=this.qupvt=a};var q=[[0,0],[0,0],[0,0],[0,0],[0,0],[0,1],[1,1],[1,1],[1,2],[2,2],[2,3],[2,3],[3,4],[3,4], -[3,4],[4,5],[4,5],[4,6],[5,6],[5,6],[5,7],[6,7],[6,7]],h=[1,2,5,7,7,10,10,13,13,13,13,13,13,13,13];this.noquant_count_bits=function(a,c,b){var d=c.l3_enc,j=Math.min(576,c.max_nonzero_coeff+2>>1<<1);null!=b&&(b.sfb_count1=0);for(;1m&&(w=m,c.count1table_select=1);c.count1bits=w;c.big_values= -j;if(0==j)return w;c.block_type==e.SHORT_TYPE?(i=3*a.scalefac_band.s[3],i>c.big_values&&(i=c.big_values),m=c.big_values):c.block_type==e.NORM_TYPE?(i=c.region0_count=a.bv_scf[j-2],m=c.region1_count=a.bv_scf[j-1],m=a.scalefac_band.l[i+m+2],i=a.scalefac_band.l[i+1],mm&&(i=m));i=Math.min(i,j);m=Math.min(m,j);0i)return ca.LARGE_BITS;var i=u.IPOW20(b.global_gain),m,w,t=0,g,f=0,h=0,n=0,k=0,q=j,D=0,J=c,O=0;g=null!=d&&b.global_gain==d.global_gain;w=b.block_type== -e.SHORT_TYPE?38:21;for(m=0;m<=w;m++){var V=-1;if(g||b.block_type==e.NORM_TYPE)V=b.global_gain-(b.scalefac[m]+(0!=b.preflag?u.pretab[m]:0)<b.max_nonzero_coeff&&(m=b.max_nonzero_coeff-t+1,Ba.fill(j,b.max_nonzero_coeff,576,0),da=m,0>da&&(da=0),m=w+1);0==f&&0==h&&(q=j,D=k,J=c,O=n);null!=d&&0=d.sfb_count1&&0=d.step[m]? -(0!=f&&(l(f,i,J,O,q,D),f=0,q=j,D=k,J=c,O=n),h+=da):(0!=h&&(p(h,i,J,O,q,D),h=0,q=j,D=k,J=c,O=n),f+=da);if(0>=da){0!=h&&(p(h,i,J,O,q,D),h=0);0!=f&&(l(f,i,J,O,q,D),f=0);break}}m<=w&&(k+=b.width[m],n+=b.width[m],t+=b.width[m])}0!=f&&l(f,i,J,O,q,D);0!=h&&p(h,i,J,O,q,D);if(0!=(a.substep_shaping&2)){i=0;w=0.634521682242439/u.IPOW20(b.global_gain+b.scalefac_scale);for(t=0;t=w?j[f]:0}}return this.noquant_count_bits(a, -b,d)};this.best_huffman_divide=function(a,c){var b=new gb,d=c.l3_enc,j=T(23),i=T(23),m=T(23),w=T(23);if(!(c.block_type==e.SHORT_TYPE&&1==a.mode_gr)){b.assign(c);if(c.block_type==e.NORM_TYPE){for(var t=c.big_values,g=0;22>=g;g++)j[g]=ca.LARGE_BITS;for(g=0;16>g;g++){var f=a.scalefac_band.l[g+1];if(f>=t)break;for(var h=0,n=new D(h),k=z(d,0,f,n),h=n.bits,l=0;8>l;l++){var p=a.scalefac_band.l[g+l+2];if(p>=t)break;n=h;n=new D(n);p=z(d,f,p,n);n=n.bits;j[g+l]>n&&(j[g+l]=n,i[g+l]=g,m[g+l]=k,w[g+l]=p)}}x(a, -b,c,d,j,i,m,w)}t=b.big_values;if(!(0==t||1<(d[t-2]|d[t-1])))if(t=c.count1+2,!(576b.big_values;t-=4)h=2*(2*(2*d[t-4]+d[t-3])+d[t-2])+d[t-1],g+=v.t32l[h],f+=v.t33l[h];b.big_values=t;b.count1table_select=0;g>f&&(g=f,b.count1table_select=1);b.count1bits=g;b.block_type==e.NORM_TYPE?x(a,b,c,d,j,i,m,w):(b.part2_3_length=g,g=a.scalefac_band.l[8],g>t&&(g=t),0g&&(j=new D(b.part2_3_length), -b.table_select[1]=z(d,g,t,j),b.part2_3_length=j.bits),c.part2_3_length>b.part2_3_length&&c.assign(b))}}};var b=[1,1,1,1,8,2,2,2,4,4,4,8,8,8,16,16],n=[1,2,4,8,1,2,4,8,2,4,8,2,4,8,4,8],a=[0,0,0,0,3,1,1,1,2,2,2,3,3,3,4,4],f=[0,1,2,3,0,1,2,3,1,2,3,1,2,3,2,3];La.slen1_tab=a;La.slen2_tab=f;this.best_scalefac_store=function(c,d,g,s){var j=s.tt[d][g],i,m,w,t=0;for(i=m=0;iw&&0==j.l3_enc[w+m];w++);0==w&&(j.scalefac[i]=t=-2)}if(0==j.scalefac_scale&&0==j.preflag){for(i= -m=0;i>=1);j.scalefac_scale=t=1}}if(0==j.preflag&&j.block_type!=e.SHORT_TYPE&&2==c.mode_gr){for(i=11;ii;i++)s.scfsi[g][i]=0;if(2==c.mode_gr&&1==d&&s.tt[0][g].block_type!=e.SHORT_TYPE&&s.tt[1][g].block_type!= -e.SHORT_TYPE){d=s.tt[1][g];m=s.tt[0][g];for(t=0;ti;i++)-1!=d.scalefac[i]&&(s++,gt;t++)g -i&&(d.part2_length=i,d.scalefac_compress=t));t=0}for(i=0;ic;c++)dj[c])&&(a.part2_length=j[c],a.scalefac_compress=c);return a.part2_length==ca.LARGE_BITS};var d=[[15,15,7,7],[15,15,7,0],[7,3,0,0],[15,31,31,0],[7,7,7,0],[3,3,0,0]];this.scale_bitcount_lsf=function(a,b){var g,s,j,i,m,w,t,f=T(4),h= -b.scalefac;g=0!=b.preflag?2:0;for(w=0;4>w;w++)f[w]=0;if(b.block_type==e.SHORT_TYPE){s=1;var n=u.nr_of_sfb_block[g][s];for(j=t=0;4>j;j++){i=n[j]/3;for(w=0;wm;m++)h[3*t+m]>f[j]&&(f[j]=h[3*t+m])}}else{s=0;n=u.nr_of_sfb_block[g][s];for(j=t=0;4>j;j++){i=n[j];for(w=0;wf[j]&&(f[j]=h[t])}}i=!1;for(j=0;4>j;j++)f[j]>d[g][j]&&(i=!0);if(!i){b.sfb_partition_table=u.nr_of_sfb_block[g][s];for(j=0;4>j;j++)b.slen[j]=c[f[j]];s=b.slen[0];j=b.slen[1];f=b.slen[2];m=b.slen[3];switch(g){case 0:b.scalefac_compress= -(5*s+j<<4)+(f<<2)+m;break;case 1:b.scalefac_compress=400+(5*s+j<<2)+f;break;case 2:b.scalefac_compress=500+3*s+j;break;default:N.err.printf("intensity stereo not implemented yet\n")}}if(!i)for(j=b.part2_length=0;4>j;j++)b.part2_length+=b.slen[j]*b.sfb_partition_table[j];return i};var c=[0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4];this.huffman_init=function(a){for(var c=2;576>=c;c+=2){for(var b=0,d;a.scalefac_band.l[++b]c;)d--;0>d&&(d=q[b][0]);a.bv_scf[c-2]=d;for(d=q[b][1];a.scalefac_band.l[d+ -a.bv_scf[c-2]+2]>c;)d--;0>d&&(d=q[b][1]);a.bv_scf[c-1]=d}}}function ka(){function D(a,b,d){for(;0>d<>3]|=c>>b<<8-(m&7)-d;m+=d}a.header[a.h_ptr].ptr=m}function z(a,c){for(var a=a<<8,b=0;8>b;b++)a<<=1,c<<=1,0!=((c^a)&65536)&&(c^=f);return c}function x(a,c){var b=v.ht[c.count1table_select+32],m,d=0,e=c.big_values,g=c.big_values;for(m=(c.count1-c.big_values)/ -4;0c.xr[g+0]&&f++);y=c.l3_enc[e+1];0!=y&&(B+=4,f*=2,0>c.xr[g+1]&&f++);y=c.l3_enc[e+2];0!=y&&(B+=2,f*=2,0>c.xr[g+2]&&f++);y=c.l3_enc[e+3];0!=y&&(B++,f*=2,0>c.xr[g+3]&&f++);e+=4;g+=4;D(a,f+b.table[B],b.hlen[B]);d+=b.hlen[B]}return d}function u(a,c,b,m,d){var e=v.ht[c],g=0;if(0==c)return g;for(;bd.xr[b]&&n++,f--);15d.xr[b+1]&&n++,f--);k=k*h+r;B-=f;f+=e.hlen[k];D(a,e.table[k],f);D(a,n,B);g+=f+B}return g}function q(a,c){var b=3*a.scalefac_band.s[3];b>c.big_values&&(b=c.big_values);var m=u(a,c.table_select[0],0,b,c);return m+=u(a,c.table_select[1],b,c.big_values,c)}function h(a,c){var b,m,d,e;b=c.big_values;m=c.region0_count+1;d=a.scalefac_band.l[m];m+=c.region1_count+1;e=a.scalefac_band.l[m];d>b&&(d=b);e>b&&(e=b);m=u(a,c.table_select[0],0,d,c);m+=u(a,c.table_select[1],d,e, -c);return m+=u(a,c.table_select[2],e,b,c)}function b(){this.total=0}function n(c,b){var d=c.internal_flags,m,e,g,f;f=d.w_ptr;g=d.h_ptr-1;-1==g&&(g=aa.MAX_HEADER_BUF-1);m=d.header[g].write_timing-B;b.total=m;0<=m&&(e=1+g-f,gm&&N.err.println("strange error flushing buffer ... \n");return m}var a=this,f=32773,J=null,k=null,g=null,d=null;this.setModules= -function(a,c,b,m){J=a;k=c;g=b;d=m};var c=null,B=0,y=0,r=0;this.getframebits=function(a){var c=a.internal_flags;return 8*(0|72E3*(a.version+1)*(0!=c.bitrate_index?v.bitrate_table[a.version][c.bitrate_index]:a.brate)/a.out_samplerate+c.padding)};this.CRC_writeheader=function(a,c){var b;b=z(c[2]&255,65535);b=z(c[3]&255,b);for(var m=6;m>8);c[5]=byte(b&255)};this.flush_bitstream=function(a){var c=a.internal_flags,d,m;d=c.l3_side;if(!(0>(m=n(a,new b))))p(a, -m),c.ResvSize=0,d.main_data_begin=0,c.findReplayGain&&(d=J.GetTitleGain(c.rgdata),c.RadioGain=Math.floor(10*d+0.5)|0),c.findPeakSample&&(c.noclipGainChange=Math.ceil(200*Math.log10(c.PeakSample/32767))|0,c.noclipScale=0>e<a.out_samplerate?l(g,4094,12):l(g,4095,12);l(g,a.version,1);l(g,1,2);l(g,!a.error_protection?1:0,1);l(g,g.bitrate_index,4);l(g,g.samplerate_index,2);l(g,g.padding,1);l(g,a.extension,1);l(g,a.mode.ordinal(),2);l(g,g.mode_ext,2);l(g,a.copyright,1);l(g,a.original, -1);l(g,a.emphasis,2);a.error_protection&&l(g,0,16);if(1==a.version){l(g,f.main_data_begin,9);2==g.channels_out?l(g,f.private_bits,3):l(g,f.private_bits,5);for(k=0;ky;y++)l(g,f.scfsi[k][y],1);for(y=0;2>y;y++)for(k=0;kf;f++)for(k=0;kO;O++)for(var da=R.sfb_partition_table[O]/3,ga=R.slen[O],z=0;zO;O++){da=R.sfb_partition_table[O];ga=R.slen[O];for(z=0;z ResvSize");8*d.main_data_begin!=c.ResvSize&&(N.err.printf("bit reservoir error: \nl3_side.main_data_begin: %d \nResvoir size: %d \nresv drain (post) %d \nresv drain (pre) %d \nheader and sideinfo: %d \ndata bits: %d \ntotal bits: %d (remainder: %d) \nbitsperframe: %d \n",8*d.main_data_begin,c.ResvSize,d.resvDrain_post,d.resvDrain_pre, -8*c.sideinfo_len,g-d.resvDrain_post-8*c.sideinfo_len,g,g%8,m),N.err.println("This is a fatal error. It has several possible causes:"),N.err.println("90%% LAME compiled with buggy version of gcc using advanced optimizations"),N.err.println(" 9%% Your system is overclocked"),N.err.println(" 1%% bug in LAME encoding library"),c.ResvSize=8*d.main_data_begin);if(1E9=f)return 0; -if(0!=m&&f>m)return-1;N.arraycopy(c,0,b,e,f);y=-1;r=0;if(0!=g&&(m=T(1),m[0]=a.nMusicCRC,d.updateMusicCRC(m,b,e,f),a.nMusicCRC=m[0],0a.PeakSample?a.PeakSample=m[0][h]:-m[0][h]>a.PeakSample&&(a.PeakSample=-m[0][h]);if(1a.PeakSample?a.PeakSample= -m[1][h]:-m[1][h]>a.PeakSample&&(a.PeakSample=-m[1][h])}if(a.findReplayGain&&J.AnalyzeSamples(a.rgdata,m[0],0,m[1],0,B,a.channels_out)==U.GAIN_ANALYSIS_ERROR)return-6}return f};this.init_bit_stream_w=function(a){c=new Int8Array(E.LAME_MAXMP3BUFFER);a.h_ptr=a.w_ptr=0;a.header[a.h_ptr].write_timing=0;y=-1;B=r=0}}function Da(){function e(a,b){var d=a[b+0]&255,d=d<<8|a[b+1]&255,d=d<<8,d=d|a[b+2]&255,d=d<<8;return d|=a[b+3]&255}function p(a,b,d){a[b+0]=255&d>>24&255;a[b+1]=255&d>>16&255;a[b+2]=255&d>>8& -255;a[b+3]=255&d&255}function l(a,b,d){a[b+0]=255&d>>8&255;a[b+1]=255&d&255}function z(a,b,d){return 255&(a<a.out_samplerate?0:1);b[1]=z(b[1],1,a.version);b[1]=z(b[1],2,1);b[1]=z(b[1],1,!a.error_protection?1:0);b[2]=z(b[2],4,d.bitrate_index);b[2]=z(b[2],2,d.samplerate_index);b[2]=z(b[2],1,0);b[2]=z(b[2],1,a.extension);b[3]=z(b[3],2,a.mode.ordinal());b[3]=z(b[3],2,d.mode_ext);b[3]=z(b[3],1, -a.copyright);b[3]=z(b[3],1,a.original);b[3]=z(b[3],2,a.emphasis);b[0]=255;var d=255&b[1]&241,e;e=1==a.version?J:16E3>a.out_samplerate?g:k;a.VBR==F.vbr_off&&(e=a.brate);e=a.free_format?0:255&16*q.BitrateIndex(e,a.version,a.out_samplerate);b[1]=1==a.version?255&(d|10):255&(d|2);d=255&b[2]&13;b[2]=255&(e|d)}function u(a,b){return b=b>>8^d[(b^a)&255]}var q,h,b;this.setModules=function(a,d,e){q=a;h=d;b=e};var n=Da.NUMTOCENTRIES,a=Da.MAXFRAMESIZE,f=n+4+4+4+4+4+9+1+1+8+1+1+3+1+1+2+4+2+2,J=128,k=64,g=32, -d=[0,49345,49537,320,49921,960,640,49729,50689,1728,1920,51009,1280,50625,50305,1088,52225,3264,3456,52545,3840,53185,52865,3648,2560,51905,52097,2880,51457,2496,2176,51265,55297,6336,6528,55617,6912,56257,55937,6720,7680,57025,57217,8E3,56577,7616,7296,56385,5120,54465,54657,5440,55041,6080,5760,54849,53761,4800,4992,54081,4352,53697,53377,4160,61441,12480,12672,61761,13056,62401,62081,12864,13824,63169,63361,14144,62721,13760,13440,62529,15360,64705,64897,15680,65281,16320,16E3,65089,64001,15040, -15232,64321,14592,63937,63617,14400,10240,59585,59777,10560,60161,11200,10880,59969,60929,11968,12160,61249,11520,60865,60545,11328,58369,9408,9600,58689,9984,59329,59009,9792,8704,58049,58241,9024,57601,8640,8320,57409,40961,24768,24960,41281,25344,41921,41601,25152,26112,42689,42881,26432,42241,26048,25728,42049,27648,44225,44417,27968,44801,28608,28288,44609,43521,27328,27520,43841,26880,43457,43137,26688,30720,47297,47489,31040,47873,31680,31360,47681,48641,32448,32640,48961,32E3,48577,48257, -31808,46081,29888,30080,46401,30464,47041,46721,30272,29184,45761,45953,29504,45313,29120,28800,45121,20480,37057,37249,20800,37633,21440,21120,37441,38401,22208,22400,38721,21760,38337,38017,21568,39937,23744,23936,40257,24320,40897,40577,24128,23040,39617,39809,23360,39169,22976,22656,38977,34817,18624,18816,35137,19200,35777,35457,19008,19968,36545,36737,20288,36097,19904,19584,35905,17408,33985,34177,17728,34561,18368,18048,34369,33281,17088,17280,33601,16640,33217,32897,16448];this.addVbrFrame= -function(a){var b=a.internal_flags;var d=b.VBR_seek_table,a=v.bitrate_table[a.version][b.bitrate_index];d.nVbrNumFrames++;d.sum+=a;d.seen++;if(!(d.seen>3&1,f=a[d+2]>>2&3,h=a[d+3]>>6&3,i=a[d+2]>>4&15,i=v.bitrate_table[g][i];b.samprate=14==a[d+1]>>4?v.samplerate_table[2][f]:v.samplerate_table[g][f]; -d=0!=g?3!=h?d+36:d+21:3!=h?d+21:d+13;if(!(new String(a,d,4(),null)).equals("Xing")&&!(new String(a,d,4(),null)).equals("Info"))return null;d+=4;b.hId=g;f=b.flags=e(a,d);d+=4;0!=(f&1)&&(b.frames=e(a,d),d+=4);0!=(f&2)&&(b.bytes=e(a,d),d+=4);if(0!=(f&4)){if(null!=b.toc)for(h=0;h>4;i=(a[d+1]&15)<<8;i+=a[d+2]&255;if(0>g||3E3i||3E3b.out_samplerate?g:k;b.VBR==F.vbr_off&&(e=b.brate);e=72E3*(b.version+1)*e/b.out_samplerate;var r=d.sideinfo_len+f;d.VBR_seek_table.TotalFrameSize=e;if(ea)b.bWriteVbrTag=!1;else{d.VBR_seek_table.nVbrNumFrames=0;d.VBR_seek_table.nBytesWritten=0;d.VBR_seek_table.sum=0;d.VBR_seek_table.seen=0;d.VBR_seek_table.want=1;d.VBR_seek_table.pos=0;null==d.VBR_seek_table.bag&&(d.VBR_seek_table.bag=new int[400], -d.VBR_seek_table.size=400);e=new Int8Array(a);x(b,e);d=d.VBR_seek_table.TotalFrameSize;for(r=0;r=e.VBR_seek_table.pos)return 0;if(d.length=j.pos))for(f=1;fj.pos-1&&(i=j.pos-1);i=0|256*j.bag[i]/j.sum;255w.RadioGain&&(w.RadioGain=-510),z=11264,z=0<=w.RadioGain?z|w.RadioGain:z|512|-w.RadioGain);w.findPeakSample&&(C=Math.abs(0|w.PeakSample/32767*Math.pow(2,23)+0.5));-1!=xc&&(0k&&(k=0);switch(a.mode){case MONO:v=0;break;case STEREO:v= -1;break;case DUAL_CHANNEL:v=2;break;case JOINT_STEREO:v=a.force_ms?4:3;break;default:v=7}V=32E3>=a.in_samplerate?0:48E3==a.in_samplerate?2:48E3a.scale_right||a.disable_reservoir&&320>a.brate||a.noATH||a.ATHonly||0==da||32E3>=a.in_samplerate)O=1;da=R+(v<<2)+(O<<5)+(V<<6);v=w.nMusicCRC;p(d,g+i,k);i+=4;for(w=0;9>w;w++)d[g+ -i+w]=255&q.charAt(w);i+=9;d[g+i]=255&J;i++;d[g+i]=255&D;i++;p(d,g+i,C);i+=4;l(d,g+i,z);i+=2;l(d,g+i,0);i+=2;d[g+i]=255&K;i++;d[g+i]=255<=hc?255:255&hc;i++;d[g+i]=255&m>>4;d[g+i+1]=255&(m<<4)+(t>>8);d[g+i+2]=255&t;i+=3;d[g+i]=255&da;i++;d[g+i++]=0;l(d,g+i,a.preset);i+=2;p(d,g+i,j);i+=4;l(d,g+i,v);i+=2;for(j=0;j=d.internal_flags.VBR_seek_table.pos)return-1;b.seek(b.length());if(0==b.length())return-1; -b.seek(0);var g=new Int8Array(10);b.readFully(g);g=(new String(g,"ISO-8859-1")).startsWith("ID3")?0:((g[6]&127)<<21|(g[7]&127)<<14|(g[8]&127)<<7|g[9]&127)+g.length;b.seek(g);var g=new Int8Array(a),e=getLameTagFrame(d,g);if(e>g.length)return-1;if(1>e)return 0;b.write(g,0,e);return 0}}function W(e,p,l,z){this.xlen=e;this.linmax=p;this.table=l;this.hlen=z}function Ha(e){this.bits=e}function Dc(){this.setModules=function(){}}function bc(){this.bits=this.over_SSD=this.over_count=this.max_noise=this.tot_noise= -this.over_noise=0}function Ec(){this.scale_right=this.scale_left=this.scale=this.out_samplerate=this.in_samplerate=this.num_channels=this.num_samples=this.class_id=0;this.decode_only=this.bWriteVbrTag=this.analysis=!1;this.quality=0;this.mode=ia.STEREO;this.write_id3tag_automatic=this.decode_on_the_fly=this.findReplayGain=this.free_format=this.force_ms=!1;this.error_protection=this.emphasis=this.extension=this.original=this.copyright=this.compression_ratio=this.brate=0;this.disable_reservoir=this.strict_ISO= -!1;this.quant_comp_short=this.quant_comp=0;this.experimentalY=!1;this.preset=this.exp_nspsytune=this.experimentalZ=0;this.VBR=null;this.maskingadjust_short=this.maskingadjust=this.highpasswidth=this.lowpasswidth=this.highpassfreq=this.lowpassfreq=this.VBR_hard_min=this.VBR_max_bitrate_kbps=this.VBR_min_bitrate_kbps=this.VBR_mean_bitrate_kbps=this.VBR_q=this.VBR_q_frac=0;this.noATH=this.ATHshort=this.ATHonly=!1;this.athaa_sensitivity=this.athaa_loudapprox=this.athaa_type=this.ATHlower=this.ATHcurve= -this.ATHtype=0;this.short_blocks=null;this.useTemporal=!1;this.msfix=this.interChRatio=0;this.tune=!1;this.lame_allocated_gfp=this.frameNum=this.framesize=this.encoder_padding=this.encoder_delay=this.version=this.tune_value_a=0;this.internal_flags=null}function Fc(){this.floor=this.decay=this.adjustLimit=this.adjust=this.aaSensitivityP=this.useAdjust=0;this.l=K(e.SBMAX_l);this.s=K(e.SBMAX_s);this.psfb21=K(e.PSFB21);this.psfb12=K(e.PSFB12);this.cb_l=K(e.CBANDS);this.cb_s=K(e.CBANDS);this.eql_w=K(e.BLKSIZE/ -2)}function Gc(){this.linprebuf=K(2*U.MAX_ORDER);this.linpre=0;this.lstepbuf=K(U.MAX_SAMPLES_PER_WINDOW+U.MAX_ORDER);this.lstep=0;this.loutbuf=K(U.MAX_SAMPLES_PER_WINDOW+U.MAX_ORDER);this.lout=0;this.rinprebuf=K(2*U.MAX_ORDER);this.rinpre=0;this.rstepbuf=K(U.MAX_SAMPLES_PER_WINDOW+U.MAX_ORDER);this.rstep=0;this.routbuf=K(U.MAX_SAMPLES_PER_WINDOW+U.MAX_ORDER);this.first=this.freqindex=this.rsum=this.lsum=this.totsamp=this.sampleWindow=this.rout=0;this.A=T(0|U.STEPS_per_dB*U.MAX_dB);this.B=T(0|U.STEPS_per_dB* -U.MAX_dB)}function Hc(D){this.quantize=D;this.iteration_loop=function(p,l,D,x){var u=p.internal_flags,q=K(ra.SFBMAX),h=K(576),b=T(2),n,a,f=u.l3_side;n=new Ha(0);this.quantize.rv.ResvFrameBegin(p,n);n=n.bits;for(var J=0;J>2&63;32<=c&&(c-=64);n=Math.pow(10,c/4/10);c=b.exp_nspsytune>>8&63;32<=c&&(c-=64);y=Math.pow(10,c/4/10);c=b.exp_nspsytune>>14&63;32<=c&&(c-=64); -r=Math.pow(10,c/4/10);c=b.exp_nspsytune>>20&63;32<=c&&(c-=64);b=r*Math.pow(10,c/4/10);for(c=0;c=c?n:13>=c?y:20>=c?r:b,d.nsPsy.longfact[c]=s;for(c=0;c=c?n:10>=c?y:11>=c?r:b,d.nsPsy.shortfact[c]=s}};this.on_pe=function(a,b,c,e,f,h){var n=a.internal_flags,j=0,i=T(2),m,j=new Ha(j),a=z.ResvMaxBits(a,e,j,h),j=j.bits,w=j+a;w>aa.MAX_BITS_PER_GRANULE&&(w=aa.MAX_BITS_PER_GRANULE);for(m=h=0;m3*e/4&&(i[m]=3*e/4),0>i[m]&&(i[m]=0),i[m]+c[m]>aa.MAX_BITS_PER_CHANNEL&&(i[m]=Math.max(0,aa.MAX_BITS_PER_CHANNEL-c[m])),h+=i[m];if(h>a)for(m=0;maa.MAX_BITS_PER_GRANULE)for(m=0;mb&&(b=0);0.5aa.MAX_BITS_PER_CHANNEL-a[0]&&(b=aa.MAX_BITS_PER_CHANNEL-a[0]);0>b&&(b=0);125<=a[1]&&(125e&&(a[0]=e*a[0]/b,a[1]=e*a[1]/b)};this.athAdjust=function(a,b,c){var b=X.FAST_LOG10_X(b,10),a=a*a,e=0,b=b-c;1E-20e&&(e=0);b=b*e+(c+90.30873362-94.82444863);return Math.pow(10,0.1*b)};this.calc_xmin=function(a,b,c,f){var h=0,n=a.internal_flags,k,j=0,i=0,m=n.ATH,w=c.xr,t=a.VBR==F.vbr_mtrh? -1:0,l=n.masking_lower;if(a.VBR==F.vbr_mtrh||a.VBR==F.vbr_mt)l=1;for(k=0;k>1;p=0;do{var x;x=w[j]*w[j];p+=x;C+=xq&&i++;k==e.SBPSY_l&&(u=q*n.nsPsy.longfact[k],CV;V++){p=0;D=J>>1;u=da/J;C=2.220446049250313E-16;do x=w[j]*w[j],p+=x,C+=xda&&i++;O==e.SBPSY_s&&(u=da*n.nsPsy.shortfact[O],Cf[h-3+1]&&(f[h-3+1]+=(f[h-3]-f[h-3+1])*n.decay),f[h-3+1]>f[h-3+2]&&(f[h-3+2]+=(f[h-3+1]-f[h-3+2])*n.decay))}return i};this.calc_noise_core=function(a,b,c,e){var f=0,h=b.s,n=a.l3_enc;if(h>a.count1)for(;0!=c--;){var k;k=a.xr[h];h++;f+=k*k;k=a.xr[h];h++;f+=k*k}else if(h>a.big_values){var i=K(2);i[0]=0;for(i[1]=e;0!=c--;)k= -Math.abs(a.xr[h])-i[n[h]],h++,f+=k*k,k=Math.abs(a.xr[h])-i[n[h]],h++,f+=k*k}else for(;0!=c--;)k=Math.abs(a.xr[h])-J[n[h]]*e,h++,f+=k*k,k=Math.abs(a.xr[h])-J[n[h]]*e,h++,f+=k*k;b.s=h;return f};this.calc_noise=function(b,d,c,e,f){var h=0,k=0,j,i,m=0,w=0,t=0,l=-20,q=0,u=b.scalefac,J=0;for(j=e.over_SSD=0;j>1,q+b.width[j]>b.max_nonzero_coeff&&(i=b.max_nonzero_coeff-q+1,i=0>1:0),q=new p(q),D=this.calc_noise_core(b,q,i,D),q=q.s,null!=f&&(f.step[j]=C,f.noise[j]=D),D=c[h++]=D/d[k++],D=X.FAST_LOG10(Math.max(D,1E-20)),null!=f&&(f.noise_log[j]=D));null!=f&&(f.global_gain=b.global_gain);t+=D;0v;v++){m=0;for(i=J;in;++n){var a=e.tt[b][0].xr[n],f=e.tt[b][1].xr[n]; -e.tt[b][0].xr[n]=(a+f)*0.5*X.SQRT2;e.tt[b][1].xr[n]=(a-f)*0.5*X.SQRT2}};this.init_xrpow=function(e,b,n){var a=0,f=0|b.max_nonzero_coeff;b.xrpow_max=0;Ba.fill(n,f,576,0);for(var l=a=0;l<=f;++l){var k=Math.abs(b.xr[l]),a=a+k;n[l]=Math.sqrt(k*Math.sqrt(k));n[l]>b.xrpow_max&&(b.xrpow_max=n[l])}if(1E-20g;g++)for(var d=l;d=k;g--)if(Math.abs(a[g])d;d++){f=!1;for(l=e.PSFB12-1;0<=l&&!f;l--){var k=3*h.scalefac_band.s[12]+(h.scalefac_band.s[13]-h.scalefac_band.s[12])*d+(h.scalefac_band.psfb12[l]-h.scalefac_band.psfb12[0]),g=k+(h.scalefac_band.psfb12[l+1]-h.scalefac_band.psfb12[l]),c=x.athAdjust(n.adjust,n.psfb12[l],n.floor);1E-12=k;g--)if(Math.abs(a[g])< -c)a[g]=0;else{f=!0;break}}}};D.BINSEARCH_NONE=new D(0);D.BINSEARCH_UP=new D(1);D.BINSEARCH_DOWN=new D(2);this.trancate_smallspectrums=function(h,b,n,a){var f=K(ra.SFBMAX);if(!(0==(h.substep_shaping&4)&&b.block_type==e.SHORT_TYPE||0!=(h.substep_shaping&128))){x.calc_noise(b,n,f,new bc,null);for(var l=0;576>l;l++){var k=0;0!=b.l3_enc[l]&&(k=Math.abs(b.xr[l]));a[l]=k}l=0;k=8;b.block_type==e.SHORT_TYPE&&(k=6);do{var g,d,c,p,u=b.width[k],l=l+u;if(!(1<=f[k])&&(Ba.sort(a,l-u,u),!ka.EQ(a[l-1],0))){g=(1-f[k])* -n[k];p=d=0;do{var r;for(c=1;p+cw?(z==D.BINSEARCH_DOWN&&(G=!0),G&&(A/=2),z=D.BINSEARCH_UP,v=A):(z==D.BINSEARCH_UP&&(G=!0),G&&(A/=2),z=D.BINSEARCH_DOWN,v=-A);b.global_gain+=v;0>b.global_gain&&(b.global_gain=0,G=!0);255w&&255>b.global_gain;)b.global_gain++,t=q.count_bits(k,a,b,null);k.CurrentStep[f]=4<=y-b.global_gain?4:2;k.OldValue[f]=b.global_gain;b.part2_3_length=t;if(0==k.noise_shaping)return 100; -x.calc_noise(b,n,c,u,r);u.bits=b.part2_3_length;g.assign(b);f=0;for(N.arraycopy(a,0,d,0,576);!j;){do{w=new bc;A=255;t=0!=(k.substep_shaping&2)?20:3;if(k.sfb21_extra){if(1ga;ga++)L[da+ga]*=E,L[da+ga]>v.xrpow_max&&(v.xrpow_max=L[da+ga]);if(2==R.noise_shaping_amp)break}}if(v=p(G))G=!1;else if(v=2==y.mode_gr?q.scale_bitcount(G):q.scale_bitcount_lsf(y,G)){if(1E;E++)z[C+E]*=1.2968395546510096,z[C+E]>v.xrpow_max&&(v.xrpow_max=z[C+E])}v.scalefac[L]=R>>1}v.preflag=0;v.scalefac_scale=1;v=!1}else if(G.block_type==e.SHORT_TYPE&&0E;E++){V=O=0;for(L=C.sfb_lmax+E;LO&&8>V)){if(7<=C.subblock_gain[E]){z=!0;break b}C.subblock_gain[E]++;O=v.scalefac_band.l[C.sfb_lmax];for(L=C.sfb_lmax+E;L>C.scalefac_scale,0<=da)R[L]=da,O+=3*V;else{R[L]=0;da=x.IPOW20(210+(da<ga;ga++)z[O+ga]*=da,z[O+ga]>C.xrpow_max&&(C.xrpow_max=z[O+ga]);O+=V*(3-E-1)}da=x.IPOW20(202);O+=C.width[L]*(E+1);for(ga=-C.width[L];0>ga;ga++)z[O+ga]*=da,z[O+ga]>C.xrpow_max&&(C.xrpow_max=z[O+ -ga])}}z=!1}v=z||p(G)}v||(v=2==y.mode_gr?q.scale_bitcount(G):q.scale_bitcount_lsf(y,G));G=!v}else G=!0;if(!G)break;0!=g.scalefac_scale&&(A=254);G=l-g.part2_length;if(0>=G)break;for(;(g.part2_3_length=q.count_bits(k,a,g,r))>G&&g.global_gain<=A;)g.global_gain++;if(g.global_gain>A)break;if(0==u.over_count){for(;(g.part2_3_length=q.count_bits(k,a,g,r))>s&&g.global_gain<=A;)g.global_gain++;if(g.global_gain>A)break}x.calc_noise(g,n,c,w,r);w.bits=g.part2_3_length;y=b.block_type!=e.SHORT_TYPE?h.quant_comp: -h.quant_comp_short;A=u;G=w;z=g;v=c;C=void 0;switch(y){default:case 9:0G.max_noise&&10*G.max_noise+G.bits<=10*A.max_noise+A.bits;break;case 0:C=G.over_count=G.max_noise&&0.2=G.max_noise&&0>A.max_noise&&A.max_noise>G.max_noise-0.2&&G.tot_noise=G.max_noise&&0G.max_noise-0.2&&G.tot_noiseG.max_noise-0.1&&G.tot_noise+G.over_noiseG.max_noise-0.15&&G.tot_noise+G.over_noise+G.over_noiset&&0==u.over_count)break;if(3==k.noise_shaping_amp&&i&&30g.global_gain+g.scalefac_scale);3==k.noise_shaping_amp?i?j=!0:(g.assign(b),N.arraycopy(d,0,a,0,576),f=0,m=g.global_gain,i=!0):j=!0}h.VBR==F.vbr_rh||h.VBR==F.vbr_mtrh?N.arraycopy(d,0,a,0,576):0!=(k.substep_shaping&1)&&trancate_smallspectrums(k,b,n,a);return u.over_count}; -this.iteration_finish_one=function(e,b,n){var a=e.l3_side,f=a.tt[b][n];q.best_scalefac_store(e,b,n,a);1==e.use_best_huffman&&q.best_huffman_divide(e,f);z.ResvAdjust(e,f)};this.VBR_encode_granule=function(e,b,n,a,f,l,k){var g=e.internal_flags,d=new gb,c=K(576),p=k,u=k+1,u=(k+l)/2,q,s=0,j=g.sfb21_extra;Ba.fill(d.l3_enc,0);do g.sfb21_extra=u>p-42?!1:j,q=outer_loop(e,b,n,a,f,u),0>=q?(s=1,u=b.part2_3_length,d.assign(b),N.arraycopy(a,0,c,0,576),k=u-32,q=k-l,u=(k+l)/2):(l=u+32,q=k-l,u=(k+l)/2,0!=s&&(s=2, -b.assign(d),N.arraycopy(c,0,a,0,576)));while(12l[c.VBR_max_bitrate]&&(g[j][i]*=l[c.VBR_max_bitrate],g[j][i]/=q),k[j][i]>g[j][i]&&(k[j][i]=g[j][i]);return p};this.bitpressure_strategy=function(h,b,n,a){for(var f=0;fp&&(u[f][q]*=p,u[f][q]/=c);return g};this.calc_target_bits=function(h,b,n,a,f,u){var k=h.internal_flags,g=k.l3_side,d,c;k.bitrate_index=k.VBR_max_bitrate;c=new Ha(0);u[0]=z.ResvFrameBegin(h,c);k.bitrate_index=1;c=l.getframebits(h)-8*k.sideinfo_len;f[0]=c/(k.mode_gr* -k.channels_out);c=1E3*h.VBR_mean_bitrate_kbps*h.framesize;0!=(k.substep_shaping&1)&&(c*=1.09);c/=h.out_samplerate;c-=8*k.sideinfo_len;c/=k.mode_gr*k.channels_out;d=0.93+0.07*(11-h.compression_ratio)/5.5;0.9>d&&(d=0.9);13*c/2?p=3*c/2:0>p&&(p=0);a[h][f]+=p}a[h][f]>aa.MAX_BITS_PER_CHANNEL&&(a[h][f]= -aa.MAX_BITS_PER_CHANNEL);q+=a[h][f]}if(q>aa.MAX_BITS_PER_GRANULE)for(f=0;faa.MAX_BITS_PER_CHANNEL&&(a[h][f]=aa.MAX_BITS_PER_CHANNEL),b+=a[h][f];if(b>u[0])for(h=0;hk;k++){var g,d,c;g=p[f+-10];d=b[h+-224]*g;c=b[e+224]*g;g=p[f+-9];d+=b[h+-160]*g;c+=b[e+160]*g;g=p[f+-8];d+=b[h+-96]*g;c+=b[e+96]*g;g=p[f+-7];d+=b[h+-32]*g;c+=b[e+32]*g;g=p[f+-6];d+=b[h+32]*g;c+=b[e+-32]*g;g=p[f+-5];d+=b[h+96]*g;c+=b[e+-96]*g;g=p[f+-4];d+=b[h+160]*g;c+=b[e+-160]*g;g=p[f+-3];d+=b[h+224]*g;c+=b[e+-224]*g;g=p[f+-2];d+=b[e+-256]*g;c-=b[h+256]*g;g=p[f+-1];d+=b[e+-192]*g;c-=b[h+192]*g;g=p[f+0];d+=b[e+-128]*g;c-=b[h+128]*g;g=p[f+1];d+=b[e+-64]*g;c-= -b[h+64]*g;g=p[f+2];d+=b[e+0]*g;c-=b[h+0]*g;g=p[f+3];d+=b[e+64]*g;c-=b[h+-64]*g;g=p[f+4];d+=b[e+128]*g;c-=b[h+-128]*g;g=p[f+5];d+=b[e+192]*g;c-=b[h+-192]*g;d*=p[f+6];g=c-d;a[30+2*k]=c+d;a[31+2*k]=p[f+7]*g;f+=18;e--;h++}c=b[e+-16]*p[f+-10];d=b[e+-32]*p[f+-2];c+=(b[e+-48]-b[e+16])*p[f+-9];d+=b[e+-96]*p[f+-1];c+=(b[e+-80]+b[e+48])*p[f+-8];d+=b[e+-160]*p[f+0];c+=(b[e+-112]-b[e+80])*p[f+-7];d+=b[e+-224]*p[f+1];c+=(b[e+-144]+b[e+112])*p[f+-6];d-=b[e+32]*p[f+2];c+=(b[e+-176]-b[e+144])*p[f+-5];d-=b[e+96]* -p[f+3];c+=(b[e+-208]+b[e+176])*p[f+-4];d-=b[e+160]*p[f+4];c+=(b[e+-240]-b[e+208])*p[f+-3];d-=b[e+224];b=d-c;e=d+c;c=a[14];d=a[15]-c;a[31]=e+c;a[30]=b+d;a[15]=b-d;a[14]=e-c;d=a[28]-a[0];a[0]+=a[28];a[28]=d*p[f+-36+7];d=a[29]-a[1];a[1]+=a[29];a[29]=d*p[f+-36+7];d=a[26]-a[2];a[2]+=a[26];a[26]=d*p[f+-72+7];d=a[27]-a[3];a[3]+=a[27];a[27]=d*p[f+-72+7];d=a[24]-a[4];a[4]+=a[24];a[24]=d*p[f+-108+7];d=a[25]-a[5];a[5]+=a[25];a[25]=d*p[f+-108+7];d=a[22]-a[6];a[6]+=a[22];a[22]=d*X.SQRT2;d=a[23]-a[7];a[7]+=a[23]; -a[23]=d*X.SQRT2-a[7];a[7]-=a[6];a[22]-=a[7];a[23]-=a[22];d=a[6];a[6]=a[31]-d;a[31]+=d;d=a[7];a[7]=a[30]-d;a[30]+=d;d=a[22];a[22]=a[15]-d;a[15]+=d;d=a[23];a[23]=a[14]-d;a[14]+=d;d=a[20]-a[8];a[8]+=a[20];a[20]=d*p[f+-180+7];d=a[21]-a[9];a[9]+=a[21];a[21]=d*p[f+-180+7];d=a[18]-a[10];a[10]+=a[18];a[18]=d*p[f+-216+7];d=a[19]-a[11];a[11]+=a[19];a[19]=d*p[f+-216+7];d=a[16]-a[12];a[12]+=a[16];a[16]=d*p[f+-252+7];d=a[17]-a[13];a[13]+=a[17];a[17]=d*p[f+-252+7];d=-a[20]+a[24];a[20]+=a[24];a[24]=d*p[f+-216+7]; -d=-a[21]+a[25];a[21]+=a[25];a[25]=d*p[f+-216+7];d=a[4]-a[8];a[4]+=a[8];a[8]=d*p[f+-216+7];d=a[5]-a[9];a[5]+=a[9];a[9]=d*p[f+-216+7];d=a[0]-a[12];a[0]+=a[12];a[12]=d*p[f+-72+7];d=a[1]-a[13];a[1]+=a[13];a[13]=d*p[f+-72+7];d=a[16]-a[28];a[16]+=a[28];a[28]=d*p[f+-72+7];d=-a[17]+a[29];a[17]+=a[29];a[29]=d*p[f+-72+7];d=X.SQRT2*(a[2]-a[10]);a[2]+=a[10];a[10]=d;d=X.SQRT2*(a[3]-a[11]);a[3]+=a[11];a[11]=d;d=X.SQRT2*(-a[18]+a[26]);a[18]+=a[26];a[26]=d-a[18];d=X.SQRT2*(-a[19]+a[27]);a[19]+=a[27];a[27]=d-a[19]; -d=a[2];a[19]-=a[3];a[3]-=d;a[2]=a[31]-d;a[31]+=d;d=a[3];a[11]-=a[19];a[18]-=d;a[3]=a[30]-d;a[30]+=d;d=a[18];a[27]-=a[11];a[19]-=d;a[18]=a[15]-d;a[15]+=d;d=a[19];a[10]-=d;a[19]=a[14]-d;a[14]+=d;d=a[10];a[11]-=d;a[10]=a[23]-d;a[23]+=d;d=a[11];a[26]-=d;a[11]=a[22]-d;a[22]+=d;d=a[26];a[27]-=d;a[26]=a[7]-d;a[7]+=d;d=a[27];a[27]=a[6]-d;a[6]+=d;d=X.SQRT2*(a[0]-a[4]);a[0]+=a[4];a[4]=d;d=X.SQRT2*(a[1]-a[5]);a[1]+=a[5];a[5]=d;d=X.SQRT2*(a[16]-a[20]);a[16]+=a[20];a[20]=d;d=X.SQRT2*(a[17]-a[21]);a[17]+=a[21]; -a[21]=d;d=-X.SQRT2*(a[8]-a[12]);a[8]+=a[12];a[12]=d-a[8];d=-X.SQRT2*(a[9]-a[13]);a[9]+=a[13];a[13]=d-a[9];d=-X.SQRT2*(a[25]-a[29]);a[25]+=a[29];a[29]=d-a[25];d=-X.SQRT2*(a[24]+a[28]);a[24]-=a[28];a[28]=d-a[24];d=a[24]-a[16];a[24]=d;d=a[20]-d;a[20]=d;d=a[28]-d;a[28]=d;d=a[25]-a[17];a[25]=d;d=a[21]-d;a[21]=d;d=a[29]-d;a[29]=d;d=a[17]-a[1];a[17]=d;d=a[9]-d;a[9]=d;d=a[25]-d;a[25]=d;d=a[5]-d;a[5]=d;d=a[21]-d;a[21]=d;d=a[13]-d;a[13]=d;d=a[29]-d;a[29]=d;d=a[1]-a[0];a[1]=d;d=a[16]-d;a[16]=d;d=a[17]-d;a[17]= -d;d=a[8]-d;a[8]=d;d=a[9]-d;a[9]=d;d=a[24]-d;a[24]=d;d=a[25]-d;a[25]=d;d=a[4]-d;a[4]=d;d=a[5]-d;a[5]=d;d=a[20]-d;a[20]=d;d=a[21]-d;a[21]=d;d=a[12]-d;a[12]=d;d=a[13]-d;a[13]=d;d=a[28]-d;a[28]=d;d=a[29]-d;a[29]=d;d=a[0];a[0]+=a[31];a[31]-=d;d=a[1];a[1]+=a[30];a[30]-=d;d=a[16];a[16]+=a[15];a[15]-=d;d=a[17];a[17]+=a[14];a[14]-=d;d=a[8];a[8]+=a[23];a[23]-=d;d=a[9];a[9]+=a[22];a[22]-=d;d=a[24];a[24]+=a[7];a[7]-=d;d=a[25];a[25]+=a[6];a[6]-=d;d=a[4];a[4]+=a[27];a[27]-=d;d=a[5];a[5]+=a[26];a[26]-=d;d=a[20]; -a[20]+=a[11];a[11]-=d;d=a[21];a[21]+=a[10];a[10]-=d;d=a[12];a[12]+=a[19];a[19]-=d;d=a[13];a[13]+=a[18];a[18]-=d;d=a[28];a[28]+=a[3];a[3]-=d;d=a[29];a[29]+=a[2];a[2]-=d}var p=[-0.1482523854003001,32.308141959636465,296.40344946382766,883.1344870032432,11113.947376231741,1057.2713659324597,305.7402417275812,30.825928907280012,3.8533188138216365,59.42900443849514,709.5899960123345,5281.91112291017,-5829.66483675846,-817.6293103748613,-76.91656988279972,-4.594269939176596,0.9063471690191471,0.1960342806591213, --0.15466694054279598,34.324387823855965,301.8067566458425,817.599602898885,11573.795901679885,1181.2520595540152,321.59731579894424,31.232021761053772,3.7107095756221318,53.650946155329365,684.167428119626,5224.56624370173,-6366.391851890084,-908.9766368219582,-89.83068876699639,-5.411397422890401,0.8206787908286602,0.3901806440322567,-0.16070888947830023,36.147034243915876,304.11815768187864,732.7429163887613,11989.60988270091,1300.012278487897,335.28490093152146,31.48816102859945,3.373875931311736, -47.232241542899175,652.7371796173471,5132.414255594984,-6909.087078780055,-1001.9990371107289,-103.62185754286375,-6.104916304710272,0.7416505462720353,0.5805693545089249,-0.16636367662261495,37.751650073343995,303.01103387567713,627.9747488785183,12358.763425278165,1412.2779918482834,346.7496836825721,31.598286663170416,3.1598635433980946,40.57878626349686,616.1671130880391,5007.833007176154,-7454.040671756168,-1095.7960341867115,-118.24411666465777,-6.818469345853504,0.6681786379192989,0.7653668647301797, --0.1716176790982088,39.11551877123304,298.3413246578966,503.5259106886539,12679.589408408976,1516.5821921214542,355.9850766329023,31.395241710249053,2.9164211881972335,33.79716964664243,574.8943997801362,4853.234992253242,-7997.57021486075,-1189.7624067269965,-133.6444792601766,-7.7202770609839915,0.5993769336819237,0.9427934736519954,-0.17645823955292173,40.21879108166477,289.9982036694474,359.3226160751053,12950.259102786438,1612.1013903507662,362.85067106591504,31.045922092242872,2.822222032597987, -26.988862316190684,529.8996541764288,4671.371946949588,-8535.899136645805,-1282.5898586244496,-149.58553632943463,-8.643494270763135,0.5345111359507916,1.111140466039205,-0.36174739330527045,41.04429910497807,277.5463268268618,195.6386023135583,13169.43812144731,1697.6433561479398,367.40983966190305,30.557037410382826,2.531473372857427,20.070154905927314,481.50208566532336,4464.970341588308,-9065.36882077239,-1373.62841526722,-166.1660487028118,-9.58289321133207,0.4729647758913199,1.268786568327291, --0.36970682634889585,41.393213350082036,261.2935935556502,12.935476055240873,13336.131683328815,1772.508612059496,369.76534388639965,29.751323653701338,2.4023193045459172,13.304795348228817,430.5615775526625,4237.0568611071185,-9581.931701634761,-1461.6913552409758,-183.12733958476446,-10.718010163869403,0.41421356237309503,1.414213562373095,-0.37677560326535325,41.619486213528496,241.05423794991074,-187.94665032361226,13450.063605744153,1836.153896465782,369.4908799925761,29.001847876923147,2.0714759319987186, -6.779591200894186,377.7767837205709,3990.386575512536,-10081.709459700915,-1545.947424837898,-200.3762958015653,-11.864482073055006,0.3578057213145241,1.546020906725474,-0.3829366947518991,41.1516456456653,216.47684307105183,-406.1569483347166,13511.136535077321,1887.8076599260432,367.3025214564151,28.136213436723654,1.913880671464418,0.3829366947518991,323.85365704338597,3728.1472257487526,-10561.233882199509,-1625.2025997821418,-217.62525175416,-13.015432208941645,0.3033466836073424,1.66293922460509, --0.5822628872992417,40.35639251440489,188.20071124269245,-640.2706748618148,13519.21490106562,1927.6022433578062,362.8197642637487,26.968821921868447,1.7463817695935329,-5.62650678237171,269.3016715297017,3453.386536448852,-11016.145278780888,-1698.6569643425091,-234.7658734267683,-14.16351421663124,0.2504869601913055,1.76384252869671,-0.5887180101749253,39.23429103868072,155.76096234403798,-889.2492977967378,13475.470561874661,1955.0535223723712,356.4450994756727,25.894952980042156,1.5695032905781554, --11.181939564328772,214.80884394039484,3169.1640829158237,-11443.321309975563,-1765.1588461316153,-251.68908574481912,-15.49755935939164,0.198912367379658,1.847759065022573,-0.7912582233652842,37.39369355329111,119.699486012458,-1151.0956593239027,13380.446257078214,1970.3952110853447,348.01959814116185,24.731487364283044,1.3850130831637748,-16.421408865300393,161.05030052864092,2878.3322807850063,-11838.991423510031,-1823.985884688674,-268.2854986386903,-16.81724543849939,0.1483359875383474,1.913880671464418, --0.7960642926861912,35.2322109610459,80.01928065061526,-1424.0212633405113,13235.794061869668,1973.804052543835,337.9908651258184,23.289159354463873,1.3934255946442087,-21.099669467133474,108.48348407242611,2583.700758091299,-12199.726194855148,-1874.2780658979746,-284.2467154529415,-18.11369784385905,0.09849140335716425,1.961570560806461,-0.998795456205172,32.56307803611191,36.958364584370486,-1706.075448829146,13043.287458812016,1965.3831106103316,326.43182772364605,22.175018750622293,1.198638339011324, --25.371248002043963,57.53505923036915,2288.41886619975,-12522.674544337233,-1914.8400385312243,-299.26241273417224,-19.37805630698734,0.04912684976946725,1.990369453344394,0.0178904535*X.SQRT2/2.384E-6,0.008938074*X.SQRT2/2.384E-6,0.0015673635*X.SQRT2/2.384E-6,0.001228571*X.SQRT2/2.384E-6,4.856585E-4*X.SQRT2/2.384E-6,1.09434E-4*X.SQRT2/2.384E-6,5.0783E-5*X.SQRT2/2.384E-6,6.914E-6*X.SQRT2/2.384E-6,12804.797818791945,1945.5515939597317,313.4244966442953,20.801593959731544,1995.1556208053692,9.000838926174497, --29.20218120805369],l=[[2.382191739347913E-13,6.423305872147834E-13,9.400849094049688E-13,1.122435026096556E-12,1.183840321267481E-12,1.122435026096556E-12,9.40084909404969E-13,6.423305872147839E-13,2.382191739347918E-13,5.456116108943412E-12,4.878985199565852E-12,4.240448995017367E-12,3.559909094758252E-12,2.858043359288075E-12,2.156177623817898E-12,1.475637723558783E-12,8.371015190102974E-13,2.599706096327376E-13,-5.456116108943412E-12,-4.878985199565852E-12,-4.240448995017367E-12,-3.559909094758252E-12, --2.858043359288076E-12,-2.156177623817898E-12,-1.475637723558783E-12,-8.371015190102975E-13,-2.599706096327376E-13,-2.382191739347923E-13,-6.423305872147843E-13,-9.400849094049696E-13,-1.122435026096556E-12,-1.183840321267481E-12,-1.122435026096556E-12,-9.400849094049694E-13,-6.42330587214784E-13,-2.382191739347918E-13],[2.382191739347913E-13,6.423305872147834E-13,9.400849094049688E-13,1.122435026096556E-12,1.183840321267481E-12,1.122435026096556E-12,9.400849094049688E-13,6.423305872147841E-13,2.382191739347918E-13, -5.456116108943413E-12,4.878985199565852E-12,4.240448995017367E-12,3.559909094758253E-12,2.858043359288075E-12,2.156177623817898E-12,1.475637723558782E-12,8.371015190102975E-13,2.599706096327376E-13,-5.461314069809755E-12,-4.921085770524055E-12,-4.343405037091838E-12,-3.732668368707687E-12,-3.093523840190885E-12,-2.430835727329465E-12,-1.734679010007751E-12,-9.74825365660928E-13,-2.797435120168326E-13,0,0,0,0,0,0,-2.283748241799531E-13,-4.037858874020686E-13,-2.146547464825323E-13],[0.1316524975873958, -0.414213562373095,0.7673269879789602,1.091308501069271,1.303225372841206,1.56968557711749,1.920982126971166,2.414213562373094,3.171594802363212,4.510708503662055,7.595754112725146,22.90376554843115,0.984807753012208,0.6427876096865394,0.3420201433256688,0.9396926207859084,-0.1736481776669303,-0.7660444431189779,0.8660254037844387,0.5,-0.5144957554275265,-0.4717319685649723,-0.3133774542039019,-0.1819131996109812,-0.09457419252642064,-0.04096558288530405,-0.01419856857247115,-0.003699974673760037, -0.8574929257125442,0.8817419973177052,0.9496286491027329,0.9833145924917901,0.9955178160675857,0.9991605581781475,0.999899195244447,0.9999931550702802],[0,0,0,0,0,0,2.283748241799531E-13,4.037858874020686E-13,2.146547464825323E-13,5.461314069809755E-12,4.921085770524055E-12,4.343405037091838E-12,3.732668368707687E-12,3.093523840190885E-12,2.430835727329466E-12,1.734679010007751E-12,9.74825365660928E-13,2.797435120168326E-13,-5.456116108943413E-12,-4.878985199565852E-12,-4.240448995017367E-12,-3.559909094758253E-12, --2.858043359288075E-12,-2.156177623817898E-12,-1.475637723558782E-12,-8.371015190102975E-13,-2.599706096327376E-13,-2.382191739347913E-13,-6.423305872147834E-13,-9.400849094049688E-13,-1.122435026096556E-12,-1.183840321267481E-12,-1.122435026096556E-12,-9.400849094049688E-13,-6.423305872147841E-13,-2.382191739347918E-13]],z=l[e.SHORT_TYPE],x=l[e.SHORT_TYPE],u=l[e.SHORT_TYPE],q=l[e.SHORT_TYPE],h=[0,1,16,17,8,9,24,25,4,5,20,21,12,13,28,29,2,3,18,19,10,11,26,27,6,7,22,23,14,15,30,31];this.mdct_sub48= -function(b,n,a){for(var f=286,p=0;ps;s++){v(n,f,y[r]);v(n,f+32,y[r+1]);r+=2;f+=64;for(g=1;32>g;g+=2)y[r-1][g]*=-1}for(g=0;32>g;g++,B+=18){var y=d.block_type,r=b.sb_sample[p][k],j=b.sb_sample[p][1-k];0!=d.mixed_block_flag&&2>g&&(y=0);if(1E-12>b.amp_filter[g])Ba.fill(c,B+0,B+18,0);else{if(1>b.amp_filter[g])for(s=0;18>s;s++)j[s][h[g]]*=b.amp_filter[g];if(y==e.SHORT_TYPE){for(s= --3;0>s;s++){var i=l[e.SHORT_TYPE][s+3];c[B+3*s+9]=r[9+s][h[g]]*i-r[8-s][h[g]];c[B+3*s+18]=r[14-s][h[g]]*i+r[15+s][h[g]];c[B+3*s+10]=r[15+s][h[g]]*i-r[14-s][h[g]];c[B+3*s+19]=j[2-s][h[g]]*i+j[3+s][h[g]];c[B+3*s+11]=j[3+s][h[g]]*i-j[2-s][h[g]];c[B+3*s+20]=j[8-s][h[g]]*i+j[9+s][h[g]]}s=c;r=B;for(i=0;3>i;i++){var m,w,t,A,G;t=s[r+6]*l[e.SHORT_TYPE][0]-s[r+15];j=s[r+0]*l[e.SHORT_TYPE][2]-s[r+9];m=t+j;w=t-j;t=s[r+15]*l[e.SHORT_TYPE][0]+s[r+6];j=s[r+9]*l[e.SHORT_TYPE][2]+s[r+0];A=t+j;G=-t+j;j=2.069978111953089E-11* -(s[r+3]*l[e.SHORT_TYPE][1]-s[r+12]);t=2.069978111953089E-11*(s[r+12]*l[e.SHORT_TYPE][1]+s[r+3]);s[r+0]=1.90752519173728E-11*m+j;s[r+15]=1.90752519173728E-11*-A+t;w*=1.6519652744032674E-11;A=9.537625958686404E-12*A+t;s[r+3]=w-A;s[r+6]=w+A;m=9.537625958686404E-12*m-j;G*=1.6519652744032674E-11;s[r+9]=m+G;s[r+12]=m-G;r++}}else{i=K(18);for(s=-9;0>s;s++)m=l[y][s+27]*j[s+9][h[g]]+l[y][s+36]*j[8-s][h[g]],w=l[y][s+9]*r[s+9][h[g]]-l[y][s+18]*r[8-s][h[g]],i[s+9]=m-w*z[3+s+9],i[s+18]=m*z[3+s+9]+w;var s=c,r=B, -F=G=A=t=w=m=j=void 0,E=void 0,C=void 0,L=void 0;w=i[17]-i[9];A=i[15]-i[11];G=i[14]-i[12];F=i[0]+i[8];E=i[1]+i[7];C=i[2]+i[6];L=i[3]+i[5];s[r+17]=F+C-L-(E-i[4]);m=(F+C-L)*x[19]+(E-i[4]);j=(w-A-G)*x[18];s[r+5]=j+m;s[r+6]=j-m;t=(i[16]-i[10])*x[18];E=E*x[19]+i[4];j=w*x[12]+t+A*x[13]+G*x[14];m=-F*x[16]+E-C*x[17]+L*x[15];s[r+1]=j+m;s[r+2]=j-m;j=w*x[13]-t-A*x[14]+G*x[12];m=-F*x[17]+E-C*x[15]+L*x[16];s[r+9]=j+m;s[r+10]=j-m;j=w*x[14]-t+A*x[12]-G*x[13];m=F*x[15]-E+C*x[16]-L*x[17];s[r+13]=j+m;s[r+14]=j-m;L= -C=E=F=G=A=t=w=void 0;w=i[8]-i[0];A=i[6]-i[2];G=i[5]-i[3];F=i[17]+i[9];E=i[16]+i[10];C=i[15]+i[11];L=i[14]+i[12];s[r+0]=F+C+L+(E+i[13]);j=(F+C+L)*x[19]-(E+i[13]);m=(w-A+G)*x[18];s[r+11]=j+m;s[r+12]=j-m;t=(i[7]-i[1])*x[18];E=i[13]-E*x[19];j=F*x[15]-E+C*x[16]+L*x[17];m=w*x[14]+t+A*x[12]+G*x[13];s[r+3]=j+m;s[r+4]=j-m;j=-F*x[17]+E-C*x[15]-L*x[16];m=w*x[13]+t-A*x[14]-G*x[12];s[r+7]=j+m;s[r+8]=j-m;j=-F*x[16]+E-C*x[17]-L*x[15];m=w*x[12]-t+A*x[13]-G*x[14];s[r+15]=j+m;s[r+16]=j-m}}if(y!=e.SHORT_TYPE&&0!=g)for(s= -7;0<=s;--s)y=c[B+s]*u[20+s]+c[B+-1-s]*q[28+s],r=c[B+s]*q[28+s]-c[B+-1-s]*u[20+s],c[B+-1-s]=y,c[B+s]=r}}n=a;f=286;if(1==b.mode_gr)for(k=0;18>k;k++)N.arraycopy(b.sb_sample[p][1][k],0,b.sb_sample[p][0][k],0,32)}}}function za(){this.thm=new Za;this.en=new Za}function e(){var v=e.FFTOFFSET,p=e.MPG_MD_MS_LR,l=null,z=this.psy=null,x=null,u=null;this.setModules=function(e,b,n,a){l=e;z=this.psy=b;x=a;u=n};var q=new Kc;this.lame_encode_mp3_frame=function(h,b,n,a,f,J){var k=ac([2,2]);k[0][0]=new za;k[0][1]= -new za;k[1][0]=new za;k[1][1]=new za;var g=ac([2,2]);g[0][0]=new za;g[0][1]=new za;g[1][0]=new za;g[1][1]=new za;var d=[null,null],c=h.internal_flags,B=qa([2,4]),y=[0.5,0.5],r=[[0,0],[0,0]],s=[[0,0],[0,0]];d[0]=b;d[1]=n;if(0==c.lame_encode_frame_init){var b=h.internal_flags,j,i;if(0==b.lame_encode_frame_init){var n=K(2014),m=K(2014);b.lame_encode_frame_init=1;for(i=j=0;j<286+576*(1+b.mode_gr);++j)j<576*b.mode_gr?(n[j]=0,2==b.channels_out&&(m[j]=0)):(n[j]=d[0][i],2==b.channels_out&&(m[j]=d[1][i]), -++i);for(i=0;i(c.slot_lag-=c.frac_SpF))c.slot_lag+=h.out_samplerate,c.padding=1;if(0!=c.psymodel){m=[null,null];j=0;i=T(2);for(n=0;n=B?(c.ATH.adjust*=0.075*B+0.925,c.ATH.adjust=B?c.ATH.adjust=B:c.ATH.adjustg;g++)c.nsPsy.pefirbuf[g]=c.nsPsy.pefirbuf[g+1];for(n=s=0;ng;g++)s+=(c.nsPsy.pefirbuf[g]+c.nsPsy.pefirbuf[18-g])*e.fircoef[g];s=3350*c.mode_gr*c.channels_out/s;for(n=0;nf;f++)c.pinfo.pcmdata[b][f]=d[b][f-v]}u.set_frame_pinfo(h,k)}c.bitrate_stereoMode_Hist[c.bitrate_index][4]++;c.bitrate_stereoMode_Hist[15][4]++;2==c.channels_out&&(c.bitrate_stereoMode_Hist[c.bitrate_index][c.mode_ext]++, -c.bitrate_stereoMode_Hist[15][c.mode_ext]++);for(h=0;he;e++)for(var p=0;2>p;p++)this.tt[e][p]=new gb}function Nc(){this.last_en_subshort=qa([4,9]);this.lastAttacks=T(4);this.pefirbuf=K(19);this.longfact=K(e.SBMAX_l);this.shortfact=K(e.SBMAX_s);this.attackthre_s=this.attackthre=0}function Za(){this.l=K(e.SBMAX_l);this.s=qa([e.SBMAX_s,3]);var v=this;this.assign=function(p){N.arraycopy(p.l,0,v.l,0,e.SBMAX_l);for(var l= -0;lz;z++)v.s[l][z]=p.s[l][z]}}function aa(){function v(){this.ptr=this.write_timing=0;this.buf=new Int8Array(p)}var p=40;this.fill_buffer_resample_init=this.iteration_init_init=this.lame_encode_frame_init=this.Class_ID=0;this.mfbuf=qa([2,aa.MFSIZE]);this.full_outer_loop=this.use_best_huffman=this.subblock_gain=this.noise_shaping_stop=this.psymodel=this.substep_shaping=this.noise_shaping_amp=this.noise_shaping=this.highpass2=this.highpass1=this.lowpass2=this.lowpass1=this.mode_ext= -this.samplerate_index=this.bitrate_index=this.VBR_max_bitrate=this.VBR_min_bitrate=this.mf_size=this.mf_samples_to_encode=this.resample_ratio=this.channels_out=this.channels_in=this.mode_gr=0;this.l3_side=new Mc;this.ms_ratio=K(2);this.slot_lag=this.frac_SpF=this.padding=0;this.tag_spec=null;this.nMusicCRC=0;this.OldValue=T(2);this.CurrentStep=T(2);this.masking_lower=0;this.bv_scf=T(576);this.pseudohalf=T(ra.SFBMAX);this.sfb21_extra=!1;this.inbuf_old=Array(2);this.blackfilt=Array(2*aa.BPC+1);this.itime= -new Float64Array(2);this.sideinfo_len=0;this.sb_sample=qa([2,2,18,e.SBLIMIT]);this.amp_filter=K(32);this.header=Array(aa.MAX_HEADER_BUF);this.ResvMax=this.ResvSize=this.ancillary_flag=this.w_ptr=this.h_ptr=0;this.scalefac_band=new la;this.minval_l=K(e.CBANDS);this.minval_s=K(e.CBANDS);this.nb_1=qa([4,e.CBANDS]);this.nb_2=qa([4,e.CBANDS]);this.nb_s1=qa([4,e.CBANDS]);this.nb_s2=qa([4,e.CBANDS]);this.s3_ll=this.s3_ss=null;this.decay=0;this.thm=Array(4);this.en=Array(4);this.tot_ener=K(4);this.loudness_sq= -qa([2,2]);this.loudness_sq_save=K(2);this.mld_l=K(e.SBMAX_l);this.mld_s=K(e.SBMAX_s);this.bm_l=T(e.SBMAX_l);this.bo_l=T(e.SBMAX_l);this.bm_s=T(e.SBMAX_s);this.bo_s=T(e.SBMAX_s);this.npart_s=this.npart_l=0;this.s3ind=va([e.CBANDS,2]);this.s3ind_s=va([e.CBANDS,2]);this.numlines_s=T(e.CBANDS);this.numlines_l=T(e.CBANDS);this.rnumlines_l=K(e.CBANDS);this.mld_cb_l=K(e.CBANDS);this.mld_cb_s=K(e.CBANDS);this.numlines_l_num1=this.numlines_s_num1=0;this.pe=K(4);this.ms_ener_ratio_old=this.ms_ratio_l_old=this.ms_ratio_s_old= -0;this.blocktype_old=T(2);this.nsPsy=new Nc;this.VBR_seek_table=new Lc;this.PSY=this.ATH=null;this.nogap_current=this.nogap_total=0;this.findPeakSample=this.findReplayGain=this.decode_on_the_fly=!0;this.AudiophileGain=this.RadioGain=this.PeakSample=0;this.rgdata=null;this.noclipScale=this.noclipGainChange=0;this.bitrate_stereoMode_Hist=va([16,5]);this.bitrate_blockType_Hist=va([16,6]);this.hip=this.pinfo=null;this.in_buffer_nsamples=0;this.iteration_loop=this.in_buffer_1=this.in_buffer_0=null;for(var l= -0;l>1;c=n;x=n<<1;y=x+c;n=x<<1;a=l;f=a+r;do{var s,j,i,m;j=e[a+0]-e[a+c];s=e[a+0]+e[a+c];m=e[a+x]-e[a+y];i=e[a+x]+e[a+y];e[a+x]=s-i;e[a+0]=s+i;e[a+y]=j-m;e[a+c]=j+m;j=e[f+0]-e[f+c];s=e[f+0]+e[f+c];m=X.SQRT2*e[f+y];i=X.SQRT2*e[f+x];e[f+x]=s-i;e[f+0]=s+i;e[f+y]=j-m;e[f+c]=j+m; -f+=n;a+=n}while(ap;p++){var a=e.BLKSIZE_s/2,f=65535&192*(p+1),z=e.BLKSIZE_s/8-1;do{var k,g,d,c,B,y=x[z<<2]&255;k=l[y]*b[h][n+y+f];B=l[127-y]*b[h][n+y+f+128];g=k-B;k+=B;d=l[y+64]*b[h][n+y+f+64];B=l[63-y]*b[h][n+y+f+192];c=d-B;d+=B;a-=4;q[p][a+0]=k+d;q[p][a+2]=k-d;q[p][a+1]=g+c;q[p][a+3]=g-c;k=l[y+1]*b[h][n+y+f+1];B=l[126-y]*b[h][n+y+f+ -129];g=k-B;k+=B;d=l[y+65]*b[h][n+y+f+65];B=l[62-y]*b[h][n+y+f+193];c=d-B;d+=B;q[p][a+e.BLKSIZE_s/2+0]=k+d;q[p][a+e.BLKSIZE_s/2+2]=k-d;q[p][a+e.BLKSIZE_s/2+1]=g+c;q[p][a+e.BLKSIZE_s/2+3]=g-c}while(0<=--z);v(q[p],a,e.BLKSIZE_s/2)}};this.fft_long=function(l,q,h,b,n){var l=e.BLKSIZE/8-1,a=e.BLKSIZE/2;do{var f,z,k,g,d,c=x[l]&255;f=p[c]*b[h][n+c];d=p[c+512]*b[h][n+c+512];z=f-d;f+=d;k=p[c+256]*b[h][n+c+256];d=p[c+768]*b[h][n+c+768];g=k-d;k+=d;a-=4;q[a+0]=f+k;q[a+2]=f-k;q[a+1]=z+g;q[a+3]=z-g;f=p[c+1]*b[h][n+ -c+1];d=p[c+513]*b[h][n+c+513];z=f-d;f+=d;k=p[c+257]*b[h][n+c+257];d=p[c+769]*b[h][n+c+769];g=k-d;k+=d;q[a+e.BLKSIZE/2+0]=f+k;q[a+e.BLKSIZE/2+2]=f-k;q[a+e.BLKSIZE/2+1]=z+g;q[a+e.BLKSIZE/2+3]=z-g}while(0<=--l);v(q,a,e.BLKSIZE/2)};this.init_fft=function(){for(var u=0;ua)if(b=b*m)return a+b;g=a/b}a+=b;if(6>=d+3){if(g>=i)return a;d=0|X.FAST_LOG10_X(g,16);return a*G[d]}d=0|X.FAST_LOG10_X(g,16);b=0!=f?c.ATH.cb_s[e]*c.ATH.adjust:c.ATH.cb_l[e]*c.ATH.adjust;return ab?(e=1,13>=d&&(e=N[d]),b=X.FAST_LOG10_X(a/b,10/15),a*((A[d]-e)*b+e)):13a&&(a=0);0>b&&(b=0);if(0>=a)return b;if(0>=b)return a;d=b> -a?b/a:a/b;if(-2<=e&&2>=e){if(d>=i)return a+b;e=0|X.FAST_LOG10_X(d,16);return(a+b)*Ca[e]}if(d=t){++f;break}h=a.PSY.bo_s_weight[f];t=1-h;i=h*b[g];h*=d[g];a.en[m].s[f][c]+=i;a.thm[m].s[f][c]+=h;i=t*b[g];h=t*d[g]}for(;f=k){++c;break}i=a.PSY.bo_l_weight[c];k=1-i;g=i*b[f];i*=d[f];a.en[m].l[c]+=g;a.thm[m].l[c]+=i;g=k*b[f];i=k*d[f]}for(;c=e?b:0c;c++){var f=a.thm.s[m][c];if(0 -f&&(d=g>1E10*f?d+C[m]*10*y:d+C[m]*X.FAST_LOG10(g/f))}}return d}function h(a,b){for(var d=281.0575,m=0;mc&&(d=f>1E10*c?d+L[m]*10*y:d+L[m]*X.FAST_LOG10(f/c))}}return d}function b(a,b,e,d,m){var c,f;for(c=f=0;cm&&(f=m);d[c]=f}else d[c]=0;for(c=1;cm&&(f=m),d[c]=f):d[c]=0;f=e[c-1]+e[c];0m&&(f=m),d[c]=f):d[c]=0}function a(a,b,e,d,m,c,f){for(var g=2*c,m=0t&&(h=t);i>l&&(i=l);b[2][k]=h;b[3][k]=i}}function f(a,b){var e;e=0<=a?27*-a:a*b;return-72>=e?0:Math.exp(e*j)}function E(a){0>a&&(a=0);a*=0.001;return 13*Math.atan(0.76*a)+3.5*Math.atan(a* -a/56.25)}function k(a,b,d,m,c,f,g,i,h,k,t,l){var w=K(e.CBANDS+1),j=i/(15h/2){q=h/2;++p;break}}w[p]=i*q;for(q=0;qp&&(p=0),s=0|Math.floor(0.5+t*(A-0.5)),s>h/2&&(s=h/2),d[q]=(n[p]+n[s])/2,b[q]=n[s],g[q]=(j*A-w[b[q]])/(w[b[q]+1]-w[b[q]]),0>g[q]?g[q]=0:1=t?(l=t-0.5,l=8*(l*l-2*l)):l=0;t+=0.474;t=15.811389+7.5*t-17.5*Math.sqrt(1+t*t);-60>=t?t=0:(t=Math.exp((l+t)*j),t/=0.6609193);l=t*m[g];i[k][g]= -l*c[k]}else for(g=0;g=q;++q)w=l+q*(p-l)/1E3,w=f(w,k),n+=w;w=1001/(n*(p-l));for(k=0;ka&&(a=3410);a=Math.max(0.1,a/1E3);return 3.64*Math.pow(a,-0.8)-6.8*Math.exp(-0.6*Math.pow(a-3.4,2))+6*Math.exp(-0.15*Math.pow(a-8.7,2))+0.001*(0.6+0.04*b)*Math.pow(a,4)}var B=new Oc,y=2.302585092994046,r=0.34,s=1/217621504/(e.BLKSIZE/2),j=0.2302585093,i,m,w,t=[1,0.79433,0.63096, -0.63096,0.63096,0.63096,0.63096,0.25119,0.11749],A=[3.3246*3.3246,3.23837*3.23837,9.9500500969,9.0247369744,8.1854926609,7.0440875649,2.46209*2.46209,2.284*2.284,4.4892710641,1.96552*1.96552,1.82335*1.82335,1.69146*1.69146,2.4621061921,2.1508568964,1.37074*1.37074,1.31036*1.31036,1.5691069696,1.4555939904,1.16203*1.16203,1.2715945225,1.09428*1.09428,1.0659*1.0659,1.0779838276,1.0382591025,1],G=[1.7782755904,1.35879*1.35879,1.38454*1.38454,1.39497*1.39497,1.40548*1.40548,1.3537*1.3537,1.6999465924, -1.22321*1.22321,1.3169398564,1],N=[5.5396212496,2.29259*2.29259,4.9868695969,2.12675*2.12675,2.02545*2.02545,1.87894*1.87894,1.74303*1.74303,1.61695*1.61695,2.2499700001,1.39148*1.39148,1.29083*1.29083,1.19746*1.19746,1.2339655056,1.0779838276],Ca=[1.7782755904,1.35879*1.35879,1.38454*1.38454,1.39497*1.39497,1.40548*1.40548,1.3537*1.3537,1.6999465924,1.22321*1.22321,1.3169398564,1],C=[11.8,13.6,17.2,32,46.5,51.3,57.5,67.1,71.5,84.6,97.6,130],L=[6.8,5.8,5.8,6.4,6.5,9.9,12.1,14.4,15,18.9,21.6,26.9, -34.2,40.2,46.8,56.5,60.7,73.9,85.7,93.4,126.1],R=[-1.730326E-17,-0.01703172,-1.349528E-17,0.0418072,-6.73278E-17,-0.0876324,-3.0835E-17,0.1863476,-1.104424E-16,-0.627638];this.L3psycho_anal_ns=function(a,d,m,c,f,g,i,k,w,l){var j=a.internal_flags,r=qa([2,e.BLKSIZE]),A=qa([2,3,e.BLKSIZE_s]),s=K(e.CBANDS+1),C=K(e.CBANDS+1),y=K(e.CBANDS+2),G=T(2),E=T(2),L,I,S,H,J,Ca,N,Z,U=qa([2,576]),Q,W=T(e.CBANDS+2),M=T(e.CBANDS+2);Ba.fill(M,0);L=j.channels_out;a.mode==ia.JOINT_STEREO&&(L=4);Q=a.VBR==F.vbr_off?0==j.ResvMax? -0:0.5*(j.ResvSize/j.ResvMax):a.VBR==F.vbr_rh||a.VBR==F.vbr_mtrh||a.VBR==F.vbr_mt?0.6:1;for(I=0;IH;H++){var oc,ka;oc=aa[tb+H+10];for(J=ka=0;9>J;J+=2)oc+=R[J]*(aa[tb+H+J]+aa[tb+H+21-J]),ka+=R[J+1]*(aa[tb+H+J+1]+aa[tb+H+21-J-1]);U[I][H]=oc+ka}f[c][I].en.assign(j.en[I]);f[c][I].thm.assign(j.thm[I]);2H;H++)ma[H]=j.nsPsy.last_en_subshort[I][H+6],ca[H]=ma[H]/j.nsPsy.last_en_subshort[I][H+4],Pa[0]+=ma[H];if(2==I)for(H=0;576>H;H++){var Ha,zb;Ha=U[0][H];zb=U[1][H];U[0][H]=Ha+zb;U[1][H]=Ha-zb}var Ma=U[I&1],Ab=0;for(H=0;9>H;H++){for(var La=Ab+64,Na=1;Abma[H+3-2]?Na/ma[H+3-2]:ma[H+3-2]>10*Na?ma[H+3-2]/(10*Na):0; -ca[H+3]=Na}if(a.analysis){var Hb=ca[0];for(H=1;12>H;H++)HbH;H++)0==na[H/3]&&ca[H]>xa&&(na[H/3]=H%3+1);for(H=1;4>H;H++)if(1.7>(Pa[H-1]>Pa[H]?Pa[H-1]/Pa[H]:Pa[H]/Pa[H-1]))na[H]=0,1==H&&(na[0]=0);0!=na[0]&&0!=j.nsPsy.lastAttacks[I]&&(na[0]=0);if(3==j.nsPsy.lastAttacks[I]||0!=na[0]+na[1]+na[2]+na[3])ra=0,0!=na[1]&&0!=na[0]&&(na[1]=0),0!=na[2]&&0!=na[1]&&(na[2]=0), -0!=na[3]&&0!=na[2]&&(na[3]=0);2>I?E[I]=ra:0==ra&&(E[0]=E[1]=0);w[I]=j.tot_ener[I];var P=a,Ja=va,Ib=$a,Oa=r,pb=I&1,Ta=A,Qa=I&1,hb=c,Ea=I,sa=d,Da=m,Va=P.internal_flags;if(2>Ea)B.fft_long(Va,Oa[pb],Ea,sa,Da),B.fft_short(Va,Ta[Qa],Ea,sa,Da);else if(2==Ea){for(var ea=e.BLKSIZE-1;0<=ea;--ea){var Jb=Oa[pb+0][ea],Bb=Oa[pb+1][ea];Oa[pb+0][ea]=0.5*(Jb+Bb)*X.SQRT2;Oa[pb+1][ea]=0.5*(Jb-Bb)*X.SQRT2}for(var Fa=2;0<=Fa;--Fa)for(ea=e.BLKSIZE_s-1;0<=ea;--ea)Jb=Ta[Qa+0][Fa][ea],Bb=Ta[Qa+1][Fa][ea],Ta[Qa+0][Fa][ea]= -0.5*(Jb+Bb)*X.SQRT2,Ta[Qa+1][Fa][ea]=0.5*(Jb-Bb)*X.SQRT2}Ja[0]=Oa[pb+0][0];Ja[0]*=Ja[0];for(ea=e.BLKSIZE/2-1;0<=ea;--ea){var Tb=Oa[pb+0][e.BLKSIZE/2-ea],ub=Oa[pb+0][e.BLKSIZE/2+ea];Ja[e.BLKSIZE/2-ea]=0.5*(Tb*Tb+ub*ub)}for(Fa=2;0<=Fa;--Fa){Ib[Fa][0]=Ta[Qa+0][Fa][0];Ib[Fa][0]*=Ib[Fa][0];for(ea=e.BLKSIZE_s/2-1;0<=ea;--ea)Tb=Ta[Qa+0][Fa][e.BLKSIZE_s/2-ea],ub=Ta[Qa+0][Fa][e.BLKSIZE_s/2+ea],Ib[Fa][e.BLKSIZE_s/2-ea]=0.5*(Tb*Tb+ub*ub)}for(var wa=0,ea=11;eaEa&&(Va.loudness_sq[hb][Ea]=Va.loudness_sq_save[Ea],Va.loudness_sq_save[Ea]=v(Ja,Va));b(j,va,s,la,za);n(j,la,za,W);for(Z=0;3>Z;Z++){for(var ic,ua,ab=$a,bb=C,Kb=y,Cb=I,Ub=Z,Y=a.internal_flags,ib=void 0,ja=void 0,ja=ib=0;jamb;mb++)Vb=$.thm[0].s[Ga][mb],Eb=$.thm[1].s[Ga][mb],$.thm[0].s[Ga][mb]+=Eb*wb,$.thm[1].s[Ga][mb]+=Vb*wb}}if(a.mode==ia.JOINT_STEREO){for(var Ra,fa=0;fa1.58*j.thm[1].l[fa]||j.thm[1].l[fa]>1.58*j.thm[0].l[fa])){var Ua=j.mld_l[fa]*j.en[3].l[fa],nb=Math.max(j.thm[2].l[fa],Math.min(j.thm[3].l[fa],Ua)),Ua=j.mld_l[fa]*j.en[2].l[fa],kc=Math.max(j.thm[3].l[fa],Math.min(j.thm[2].l[fa],Ua));j.thm[2].l[fa]=nb;j.thm[3].l[fa]=kc}for(fa= -0;faoa;oa++)j.thm[0].s[fa][oa]>1.58*j.thm[1].s[fa][oa]||j.thm[1].s[fa][oa]>1.58*j.thm[0].s[fa][oa]||(Ua=j.mld_s[fa]*j.en[3].s[fa][oa],nb=Math.max(j.thm[2].s[fa][oa],Math.min(j.thm[3].s[fa][oa],Ua)),Ua=j.mld_s[fa]*j.en[2].s[fa][oa],kc=Math.max(j.thm[3].s[fa][oa],Math.min(j.thm[2].s[fa][oa],Ua)),j.thm[2].s[fa][oa]=nb,j.thm[3].s[fa][oa]=kc);Ra=a.msfix;if(0pa;pa++)Xa=j.ATH.cb_s[j.bm_s[ta]]*Wb,Nb=Math.min(Math.max(j.thm[0].s[ta][pa],Xa),Math.max(j.thm[1].s[ta][pa],Xa)),Ka=Math.max(j.thm[2].s[ta][pa], -Xa),Aa=Math.max(j.thm[3].s[ta][pa],Xa),Nb*FbM;M++){var tb,ka;tb=firbuf[W+M+10];for(var ca=ka=0;9>ca;ca+=2)tb+=U[ca]*(firbuf[W+M+ca]+firbuf[W+M+21-ca]),ka+=U[ca+1]*(firbuf[W+M+ca+1]+firbuf[W+M+21-ca-1]);N[Q][M]=tb+ka}g[f][Q].en.assign(Ca.en[Q]);g[f][Q].thm.assign(Ca.thm[Q]);2M;M++)ma[M]=Ca.nsPsy.last_en_subshort[Q][M+6],ra[M]=ma[M]/Ca.nsPsy.last_en_subshort[Q][M+4],Pa[0]+=ma[M];for(M=0;9>M;M++){for(var va=Ba+64,$a=1;Bama[M+3-2]?$a/ma[M+3-2]:ma[M+3-2]>10*$a?ma[M+3-2]/(10*$a):0;ra[M+3]=$a}for(M=0;3>M;++M){var Ma=ma[3*M+3]+ma[3*M+4]+ma[3*M+5],zb=1;6*ma[3* -M+5]M;M++)DaM;M++)0==F[Q][M/3]&&ra[M]>la&&(F[Q][M/3]=M%3+1);for(M=1;4>M;M++){var Ab=Pa[M-1],La=Pa[M];4E4>Math.max(Ab,La)&&(Ab<1.7*La&&La<1.7*Ab)&&(1==M&&F[Q][0]<=F[Q][M]&&(F[Q][0]=0),F[Q][M]=0)}F[Q][0]<=Ca.nsPsy.lastAttacks[Q]&&(F[Q][0]=0);if(3==Ca.nsPsy.lastAttacks[Q]||0!=F[Q][0]+F[Q][1]+F[Q][2]+F[Q][3])Ha=0,0!=F[Q][1]&& -0!=F[Q][0]&&(F[Q][1]=0),0!=F[Q][2]&&0!=F[Q][1]&&(F[Q][2]=0),0!=F[Q][3]&&0!=F[Q][2]&&(F[Q][3]=0);2>Q?H[Q]=Ha:0==Ha&&(H[0]=H[1]=0);w[Q]=Ca.tot_ener[Q]}var Na=d.internal_flags;d.short_blocks==ya.short_block_coupled&&!(0!=H[0]&&0!=H[1])&&(H[0]=H[1]=0);for(var Hb=0;HbOa)B.fft_long(Ea,Qa[hb], -Oa,m,c);else if(2==Oa)for(var sa=e.BLKSIZE-1;0<=sa;--sa){var gb=Qa[hb+0][sa],Va=Qa[hb+1][sa];Qa[hb+0][sa]=0.5*(gb+Va)*X.SQRT2;Qa[hb+1][sa]=0.5*(gb-Va)*X.SQRT2}Ta[0]=Qa[hb+0][0];Ta[0]*=Ta[0];for(sa=e.BLKSIZE/2-1;0<=sa;--sa){var ea=Qa[hb+0][e.BLKSIZE/2-sa],Jb=Qa[hb+0][e.BLKSIZE/2+sa];Ta[e.BLKSIZE/2-sa]=0.5*(ea*ea+Jb*Jb)}for(var Bb=0,sa=11;saFa&&(ub.loudness_sq[f][Fa]=ub.loudness_sq_save[Fa],ub.loudness_sq_save[Fa]=v(Tb,ub));if(0!=H[Ja]){var wa=r,ic=C,ua=E[P],ab=L[P],bb=P,Kb=K(e.CBANDS),Cb=K(e.CBANDS),Ub=T(e.CBANDS+2),Y=void 0;b(wa,ic,ua,Kb,Cb);n(wa,Kb,Cb,Ub);for(var ib=0,Y=0;Y=Db&&(Db=Wa);0>=kb&&(kb=Wa);Lb=wa.blocktype_old[bb&1]==e.NORM_TYPE?Math.min(kb,Db):kb;ab[Y]=Math.min(Wa,Lb)}wa.nb_2[bb][Y]=wa.nb_1[bb][Y];wa.nb_1[bb][Y]=Wa;ja=Kb[Y];ja*=wa.minval_l[Y];ja*=cc;ab[Y]>ja&&(ab[Y]=ja);1ua[Y]&&(ab[Y]=ua[Y]);1>wa.masking_lower&&(ab[Y]*=wa.masking_lower)}for(;Y$;$++){for(P=0;Pmb&&B.fft_short(kc,Ua[nb],mb,m,c);if(2==mb)for(var oa=e.BLKSIZE_s-1;0<=oa;--oa){var Fb=Ua[nb+0][Ra][oa],dc=Ua[nb+1][Ra][oa];Ua[nb+0][Ra][oa]=0.5*(Fb+dc)*X.SQRT2;Ua[nb+1][Ra][oa]=0.5*(Fb-dc)*X.SQRT2}fa[Ra][0]=Ua[nb+0][Ra][0];fa[Ra][0]*=fa[Ra][0];for(oa=e.BLKSIZE_s/2-1;0<=oa;--oa){var Wb=Ua[nb+0][Ra][e.BLKSIZE_s/2-oa],ta=Ua[nb+0][Ra][e.BLKSIZE_s/2+oa];fa[Ra][e.BLKSIZE_s/2-oa]=0.5*(Wb*Wb+ta*ta)}for(var Nb= -y,Ka=E[P],Aa=L[P],Xa=P,Xb=$,pa=d.internal_flags,db=new float[e.CBANDS],Ia=K(e.CBANDS),Ob=void 0,eb=void 0,ba=void 0,xb=new int[e.CBANDS],ba=eb=0;bafc&&(rb=fc);ec[ha]=rb}else ec[ha]=0;for(ha=1;hafc&&(rb=fc),ec[ha]=rb):ec[ha]=0;Sa=Yb[ha-1]+Yb[ha];0fc&&(rb=fc),ec[ha]=rb):ec[ha]=0;for(eb=ba=0;baGb&&(Aa[ba]=Gb);1Ka[ba]&&(Aa[ba]=Ka[ba]);1>pa.masking_lower&&(Aa[ba]*=pa.masking_lower)}for(;ba$;$++){var Ya=r.thm[P].s[$b][$],Ya=0.8*Ya;if(2<=F[P][$]||1==F[P][$+1])var lc=0!=$?$-1:2,mc=u(r.thm[P].s[$b][lc],Ya,0.36),Ya=Math.min(Ya,mc);else if(1==F[P][$])lc=0!=$?$-1:2,mc=u(r.thm[P].s[$b][lc],Ya,0.18),Ya=Math.min(Ya,mc);else if(0!=$&& -3==F[P][$-1]||0==$&&3==r.nsPsy.lastAttacks[P])lc=2!=$?$+1:0,mc=u(r.thm[P].s[$b][lc],Ya,0.18),Ya=Math.min(Ya,mc);Ya*=I[P][$];zc[$]=Ya}for($=0;3>$;$++)r.thm[P].s[$b][$]=zc[$]}for(P=0;Pc;++c){for(var A=0;AA;++A){for(u=0;uA;A++)b.nsPsy.last_en_subshort[c][A]=10}b.loudness_sq_save[0]=b.loudness_sq_save[1]=0;b.npart_l=k(b.numlines_l,b.bo_l,b.bm_l,n,q,b.mld_l,b.PSY.bo_l_weight,s,e.BLKSIZE,b.scalefac_band.l,e.BLKSIZE/1152,e.SBMAX_l);for(c=0;c=h&&(u=t*(n[c]-h)/(24-h)+j*(24-n[c])/(24-h)),r[c]=Math.pow(10,u/10),b.rnumlines_l[c]=0j&&(t=j);b.ATH.cb_l[c]=t;t=-20+20*n[c]/10;6t&&(t=-15);t-=8;b.minval_l[c]=Math.pow(10,t/10)*b.numlines_l[c]}b.npart_s=k(b.numlines_s,b.bo_s,b.bm_s,n,q,b.mld_s,b.PSY.bo_s_weight,s,e.BLKSIZE_s,b.scalefac_band.s,e.BLKSIZE_s/384,e.SBMAX_s);for(c=A=0;c=h&&(u=p*(n[c]-h)/(24-h)+l*(24-n[c])/(24-h));r[c]=Math.pow(10,u/10);t=Ma.MAX_VALUE;for(u=0;uj&&(t=j);b.ATH.cb_s[c]=t;t=-7+7*n[c]/12;12n[c]&&(t*=1+2.3*Math.log(1-t));-15>t&&(t=-15);t-=8;b.minval_s[c]=Math.pow(10,t/10)*b.numlines_s[c]}b.s3_ss=g(b.s3ind_s,b.npart_s,n,q,r,f);i=Math.pow(10,0.5625);m=Math.pow(10,1.5);w=Math.pow(10,1.5);B.init_fft(b);b.decay=Math.exp(-1*y/(0.01*s/192));c=3.5;0!=(a.exp_nspsytune&2)&&(c=1);0b.npart_l-1&&(b.s3ind[f][1]=b.npart_l-1);b.ATH.decay=Math.pow(10,-1.2*(576*b.mode_gr/s));b.ATH.adjust=0.01;b.ATH.adjustLimit=1;if(-1!=a.ATHtype){A=a.out_samplerate/e.BLKSIZE;for(c=j=f=0;cc&&(b= -2);for(var c=v.bitrate_table[b][1],d=2;14>=d;d++)0c&&(b=2);for(c=0;14>=c;c++)if(0s)return s;p+=s;u+=s;z[0]=c;z[1]=d;if(ka.NEQ(b.scale,0)&&ka.NEQ(b.scale,1))for(s=0;sN.resample_ratio||1.0001aa.BPC&&(za=aa.BPC);var va=1E-4>Math.abs(I.resample_ratio-Math.floor(0.5+I.resample_ratio))?1:0,la=1/I.resample_ratio;1ob&&(ob=0);1Math.abs(Za)?gb/Math.PI:ob*Math.sin(La*gb*Za)/(Math.PI*La*Za);Da+=Ma[M]=La}for(S=0;S<=Z;S++)I.blackfilt[H][S]/=Da}I.fill_buffer_resample_init=1}Da=I.inbuf_old[Ha];for(la=0;la=Ba)break; -Q=S-I.itime[Ha]-(H+0.5*(Z%2));Q=0|Math.floor(2*Q*za+za+0.5);for(S=Ma=0;S<=Z;++S)M=S+H-Z/2,Ma+=(0>M?Da[va+M]:ra[ya+M])*I.blackfilt[Q][S];ca[ia+la]=Ma}xa.num_used=Math.min(Ba,Z+H-Z/2);I.itime[Ha]+=xa.num_used-la*I.resample_ratio;if(xa.num_used>=va)for(S=0;Sr.mf_samples_to_encode&&(r.mf_samples_to_encode=e.ENCDELAY+e.POSTDELAY);r.mf_samples_to_encode+=s;if(r.mf_size>=c){v=q-u;0==q&&(v=0);s=b;v=J.enc.lame_encode_mp3_frame(s,x[0],x[1],l,p,v);s.frameNum++;s=v;if(0>s)return s;p+=s;u+=s;r.mf_size-=b.framesize; -r.mf_samples_to_encode-=b.framesize;for(v=0;vg;g++)if(Math.max(a,b[g+1])!=a){f=b[g+1]; -e=g+1;d=b[g];c=g;break}return f-a>a-d?c:e};this.lame_init_params=function(a){var b=a.internal_flags;b.Class_ID=0;null==b.ATH&&(b.ATH=new Fc);null==b.PSY&&(b.PSY=new D);null==b.rgdata&&(b.rgdata=new Gc);b.channels_in=a.num_channels;1==b.channels_in&&(a.mode=ia.MONO);b.channels_out=a.mode==ia.MONO?1:2;b.mode_ext=e.MPG_MD_MS_LR;a.mode==ia.MONO&&(a.force_ms=!1);a.VBR==F.vbr_off&&(128!=a.VBR_mean_bitrate_kbps&&0==a.brate)&&(a.brate=a.VBR_mean_bitrate_kbps);a.VBR==F.vbr_off||(a.VBR==F.vbr_mtrh||a.VBR== -F.vbr_mt)||(a.free_format=!1);a.VBR==F.vbr_off&&0==a.brate&&ka.EQ(a.compression_ratio,0)&&(a.compression_ratio=11.025);a.VBR==F.vbr_off&&0a.out_samplerate?(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps, -8),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,64)):32E3>a.out_samplerate?(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps,8),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,160)):(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps,32),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,320)));if(0==a.lowpassfreq){var f=16E3;switch(a.VBR){case F.vbr_off:f=new p;q(f,a.brate);f=f.lowerlimit;break;case F.vbr_abr:f=new p;q(f,a.VBR_mean_bitrate_kbps);f=f.lowerlimit; -break;case F.vbr_rh:var h=[19500,19E3,18600,18E3,17500,16E3,15600,14900,12500,1E4,3950];if(0<=a.VBR_q&&9>=a.VBR_q)var f=h[a.VBR_q],h=h[a.VBR_q+1],l=a.VBR_q_frac,f=linear_int(f,h,l);else f=19500;break;default:h=[19500,19E3,18500,18E3,17500,16500,15500,14500,12500,9500,3950],0<=a.VBR_q&&9>=a.VBR_q?(f=h[a.VBR_q],h=h[a.VBR_q+1],l=a.VBR_q_frac,f=linear_int(f,h,l)):f=19500}if(a.mode==ia.MONO&&(a.VBR==F.vbr_off||a.VBR==F.vbr_abr))f*=1.5;a.lowpassfreq=f|0}0==a.out_samplerate&&(2*a.lowpassfreq>a.in_samplerate&& -(a.lowpassfreq=a.in_samplerate/2),f=a.lowpassfreq|0,h=a.in_samplerate,l=44100,48E3<=h?l=48E3:44100<=h?l=44100:32E3<=h?l=32E3:24E3<=h?l=24E3:22050<=h?l=22050:16E3<=h?l=16E3:12E3<=h?l=12E3:11025<=h?l=11025:8E3<=h&&(l=8E3),-1==f?f=l:(15960>=f&&(l=44100),15250>=f&&(l=32E3),11220>=f&&(l=24E3),9970>=f&&(l=22050),7230>=f&&(l=16E3),5420>=f&&(l=12E3),4510>=f&&(l=11025),3970>=f&&(l=8E3),f=h=a.out_samplerate?1:2;a.framesize=576*b.mode_gr;a.encoder_delay=e.ENCDELAY;b.resample_ratio=a.in_samplerate/a.out_samplerate;switch(a.VBR){case F.vbr_mt:case F.vbr_rh:case F.vbr_mtrh:a.compression_ratio=[5.7,6.5,7.3,8.2,10,11.9,13,14,15,16.5][a.VBR_q];break;case F.vbr_abr:a.compression_ratio= -16*a.out_samplerate*b.channels_out/(1E3*a.VBR_mean_bitrate_kbps);break;default:a.compression_ratio=16*a.out_samplerate*b.channels_out/(1E3*a.brate)}a.mode==ia.NOT_SET&&(a.mode=ia.JOINT_STEREO);0b.lowpass1&&(b.lowpass1=0)):b.lowpass1=2*a.lowpassfreq,b.lowpass1/=a.out_samplerate,b.lowpass2/=a.out_samplerate):(b.lowpass1=0,b.lowpass2=0);var f=a.internal_flags,n=32,E=-1;if(0=h;h++)l=h/31,l>=f.lowpass2&&(n=Math.min(n,h)),f.lowpass1=h;h++)l=h/31,l<=f.highpass1&&(E=Math.max(E,h)),f.highpass1h;h++)l=h/31,E=f.highpass2>f.highpass1?1<(f.highpass2-l)/(f.highpass2-f.highpass1+1E-20)?0:0>=(f.highpass2-l)/(f.highpass2-f.highpass1+1E-20)?1:Math.cos(Math.PI/2*((f.highpass2-l)/(f.highpass2-f.highpass1+1E-20))):1,l=f.lowpass2>f.lowpass1?1<(l-f.lowpass1)/(f.lowpass2-f.lowpass1+1E-20)?0:0>=(l-f.lowpass1)/ -(f.lowpass2-f.lowpass1+1E-20)?1:Math.cos(Math.PI/2*((l-f.lowpass1)/(f.lowpass2-f.lowpass1+1E-20))):1,f.amp_filter[h]=E*l;b.samplerate_index=z(a.out_samplerate,a);if(0>b.samplerate_index)return a.internal_flags=null,-1;if(a.VBR==F.vbr_off)if(a.free_format)b.bitrate_index=0;else{if(a.brate=x(a.brate,a.version,a.out_samplerate),b.bitrate_index=u(a.brate,a.version,a.out_samplerate),0>=b.bitrate_index)return a.internal_flags=null,-1}else b.bitrate_index=1;a.analysis&&(a.bWriteVbrTag=!1);null!=b.pinfo&& -(a.bWriteVbrTag=!1);g.init_bit_stream_w(b);f=b.samplerate_index+3*a.version+6*(16E3>a.out_samplerate?1:0);for(h=0;hf;f++)b.nsPsy.pefirbuf[f]=700*b.mode_gr*b.channels_out;-1==a.ATHtype&& -(a.ATHtype=4);switch(a.VBR){case F.vbr_mt:a.VBR=F.vbr_mtrh;case F.vbr_mtrh:null==a.useTemporal&&(a.useTemporal=!1);d.apply_preset(a,500-10*a.VBR_q,0);0>a.quality&&(a.quality=LAME_DEFAULT_QUALITY);5>a.quality&&(a.quality=0);5a.quality&&(a.quality=LAME_DEFAULT_QUALITY);b.iteration_loop=new VBROldIterationLoop(B);break;default:b.sfb21_extra=!1,0>a.quality&&(a.quality=LAME_DEFAULT_QUALITY),f=a.VBR,f==F.vbr_off&&(a.VBR_mean_bitrate_kbps=a.brate),d.apply_preset(a,a.VBR_mean_bitrate_kbps,0),a.VBR=f,b.PSY.mask_adjust=a.maskingadjust,b.PSY.mask_adjust_short=a.maskingadjust_short,b.iteration_loop= -f==F.vbr_off?new Hc(B):new ABRIterationLoop(B)}if(a.VBR!=F.vbr_off){b.VBR_min_bitrate=1;b.VBR_max_bitrate=14;16E3>a.out_samplerate&&(b.VBR_max_bitrate=8);if(0!=a.VBR_min_bitrate_kbps&&(a.VBR_min_bitrate_kbps=x(a.VBR_min_bitrate_kbps,a.version,a.out_samplerate),b.VBR_min_bitrate=u(a.VBR_min_bitrate_kbps,a.version,a.out_samplerate),0>b.VBR_min_bitrate)||0!=a.VBR_max_bitrate_kbps&&(a.VBR_max_bitrate_kbps=x(a.VBR_max_bitrate_kbps,a.version,a.out_samplerate),b.VBR_max_bitrate=u(a.VBR_max_bitrate_kbps, -a.version,a.out_samplerate),0>b.VBR_max_bitrate))return-1;a.VBR_min_bitrate_kbps=v.bitrate_table[a.version][b.VBR_min_bitrate];a.VBR_max_bitrate_kbps=v.bitrate_table[a.version][b.VBR_max_bitrate];a.VBR_mean_bitrate_kbps=Math.min(v.bitrate_table[a.version][b.VBR_max_bitrate],a.VBR_mean_bitrate_kbps);a.VBR_mean_bitrate_kbps=Math.max(v.bitrate_table[a.version][b.VBR_min_bitrate],a.VBR_mean_bitrate_kbps)}a.tune&&(b.PSY.mask_adjust+=a.tune_value_a,b.PSY.mask_adjust_short+=a.tune_value_a);f=a.internal_flags; -switch(a.quality){default:case 9:f.psymodel=0;f.noise_shaping=0;f.noise_shaping_amp=0;f.noise_shaping_stop=0;f.use_best_huffman=0;f.full_outer_loop=0;break;case 8:a.quality=7;case 7:f.psymodel=1;f.noise_shaping=0;f.noise_shaping_amp=0;f.noise_shaping_stop=0;f.use_best_huffman=0;f.full_outer_loop=0;break;case 6:f.psymodel=1;0==f.noise_shaping&&(f.noise_shaping=1);f.noise_shaping_amp=0;f.noise_shaping_stop=0;-1==f.subblock_gain&&(f.subblock_gain=1);f.use_best_huffman=0;f.full_outer_loop=0;break;case 5:f.psymodel= -1;0==f.noise_shaping&&(f.noise_shaping=1);f.noise_shaping_amp=0;f.noise_shaping_stop=0;-1==f.subblock_gain&&(f.subblock_gain=1);f.use_best_huffman=0;f.full_outer_loop=0;break;case 4:f.psymodel=1;0==f.noise_shaping&&(f.noise_shaping=1);f.noise_shaping_amp=0;f.noise_shaping_stop=0;-1==f.subblock_gain&&(f.subblock_gain=1);f.use_best_huffman=1;f.full_outer_loop=0;break;case 3:f.psymodel=1;0==f.noise_shaping&&(f.noise_shaping=1);f.noise_shaping_amp=1;f.noise_shaping_stop=1;-1==f.subblock_gain&&(f.subblock_gain= -1);f.use_best_huffman=1;f.full_outer_loop=0;break;case 2:f.psymodel=1;0==f.noise_shaping&&(f.noise_shaping=1);0==f.substep_shaping&&(f.substep_shaping=2);f.noise_shaping_amp=1;f.noise_shaping_stop=1;-1==f.subblock_gain&&(f.subblock_gain=1);f.use_best_huffman=1;f.full_outer_loop=0;break;case 1:f.psymodel=1;0==f.noise_shaping&&(f.noise_shaping=1);0==f.substep_shaping&&(f.substep_shaping=2);f.noise_shaping_amp=2;f.noise_shaping_stop=1;-1==f.subblock_gain&&(f.subblock_gain=1);f.use_best_huffman=1;f.full_outer_loop= -0;break;case 0:f.psymodel=1,0==f.noise_shaping&&(f.noise_shaping=1),0==f.substep_shaping&&(f.substep_shaping=2),f.noise_shaping_amp=2,f.noise_shaping_stop=1,-1==f.subblock_gain&&(f.subblock_gain=1),f.use_best_huffman=1,f.full_outer_loop=0}b.ATH.useAdjust=0>a.athaa_type?3:a.athaa_type;b.ATH.aaSensitivityP=Math.pow(10,a.athaa_sensitivity/-10);null==a.short_blocks&&(a.short_blocks=ya.short_block_allowed);if(a.short_blocks==ya.short_block_allowed&&(a.mode==ia.JOINT_STEREO||a.mode==ia.STEREO))a.short_blocks= -ya.short_block_coupled;0>a.quant_comp&&(a.quant_comp=1);0>a.quant_comp_short&&(a.quant_comp_short=0);0>a.msfix&&(a.msfix=0);a.exp_nspsytune|=1;0>a.internal_flags.nsPsy.attackthre&&(a.internal_flags.nsPsy.attackthre=Sb.NSATTACKTHRE);0>a.internal_flags.nsPsy.attackthre_s&&(a.internal_flags.nsPsy.attackthre_s=Sb.NSATTACKTHRE_S);0>a.scale&&(a.scale=1);0>a.ATHtype&&(a.ATHtype=4);0>a.ATHcurve&&(a.ATHcurve=4);0>a.athaa_loudapprox&&(a.athaa_loudapprox=2);0>a.interChRatio&&(a.interChRatio=0);null==a.useTemporal&& -(a.useTemporal=!0);b.slot_lag=b.frac_SpF=0;a.VBR==F.vbr_off&&(b.slot_lag=b.frac_SpF=72E3*(a.version+1)*a.brate%a.out_samplerate|0);c.iteration_init(a);y.psymodel_init(a);return 0};this.lame_encode_flush=function(a,b,c,d){var f=a.internal_flags,i=nc([2,1152]),j=0,k,l,n=f.mf_samples_to_encode-e.POSTDELAY,p=h(a);if(1>f.mf_samples_to_encode)return 0;k=0;a.in_samplerate!=a.out_samplerate&&(n+=16*a.out_samplerate/a.in_samplerate);l=a.framesize-n%a.framesize;576>l&&(l+=a.framesize);a.encoder_padding=l;for(l= -(n+l)/a.framesize;0q&&(q=1);j=d-k;0==d&&(j=0);j=this.lame_encode_buffer(a,i[0],i[1],q,b,c,j);c+=j;k+=j;l-=n!=a.frameNum?1:0}f.mf_samples_to_encode=0;if(0>j)return j;j=d-k;0==d&&(j=0);g.flush_bitstream(a);j=g.copy_buffer(f,b,c,j,1);if(0>j)return j;c+=j;k+=j;j=d-k;0==d&&(j=0);if(a.write_id3tag_automatic){s.id3tag_write_v1(a);j=g.copy_buffer(f,b,c,j,0);if(0>j)return j;k+=j}return k};this.lame_encode_buffer= -function(a,c,d,f,e,g,h){var j=a.internal_flags,k=[null,null];if(j.Class_ID!=i)return-3;if(0==f)return 0;if(null==j.in_buffer_0||j.in_buffer_nsamplesMath.abs(p)?Math.abs(e-p)<=1E-6*Math.abs(e):Math.abs(e-p)<=1E-6*Math.abs(p)};ka.NEQ=function(e,p){return!ka.EQ(e,p)};Da.NUMTOCENTRIES=100;Da.MAXFRAMESIZE=2880;var v={t1HB:[1,1,1,0],t2HB:[1,2,1,3,1,1,3,2,0],t3HB:[3,2,1,1,1,1,3,2,0],t5HB:[1, -2,6,5,3,1,4,4,7,5,7,1,6,1,1,0],t6HB:[7,3,5,1,6,2,3,2,5,4,4,1,3,3,2,0],t7HB:[1,2,10,19,16,10,3,3,7,10,5,3,11,4,13,17,8,4,12,11,18,15,11,2,7,6,9,14,3,1,6,4,5,3,2,0],t8HB:[3,4,6,18,12,5,5,1,2,16,9,3,7,3,5,14,7,3,19,17,15,13,10,4,13,5,8,11,5,1,12,4,4,1,1,0],t9HB:[7,5,9,14,15,7,6,4,5,5,6,7,7,6,8,8,8,5,15,6,9,10,5,1,11,7,9,6,4,1,14,4,6,2,6,0],t10HB:[1,2,10,23,35,30,12,17,3,3,8,12,18,21,12,7,11,9,15,21,32,40,19,6,14,13,22,34,46,23,18,7,20,19,33,47,27,22,9,3,31,22,41,26,21,20,5,3,14,13,10,11,16,6,5,1,9,8, -7,8,4,4,2,0],t11HB:[3,4,10,24,34,33,21,15,5,3,4,10,32,17,11,10,11,7,13,18,30,31,20,5,25,11,19,59,27,18,12,5,35,33,31,58,30,16,7,5,28,26,32,19,17,15,8,14,14,12,9,13,14,9,4,1,11,4,6,6,6,3,2,0],t12HB:[9,6,16,33,41,39,38,26,7,5,6,9,23,16,26,11,17,7,11,14,21,30,10,7,17,10,15,12,18,28,14,5,32,13,22,19,18,16,9,5,40,17,31,29,17,13,4,2,27,12,11,15,10,7,4,1,27,12,8,12,6,3,1,0],t13HB:[1,5,14,21,34,51,46,71,42,52,68,52,67,44,43,19,3,4,12,19,31,26,44,33,31,24,32,24,31,35,22,14,15,13,23,36,59,49,77,65,29,40,30, -40,27,33,42,16,22,20,37,61,56,79,73,64,43,76,56,37,26,31,25,14,35,16,60,57,97,75,114,91,54,73,55,41,48,53,23,24,58,27,50,96,76,70,93,84,77,58,79,29,74,49,41,17,47,45,78,74,115,94,90,79,69,83,71,50,59,38,36,15,72,34,56,95,92,85,91,90,86,73,77,65,51,44,43,42,43,20,30,44,55,78,72,87,78,61,46,54,37,30,20,16,53,25,41,37,44,59,54,81,66,76,57,54,37,18,39,11,35,33,31,57,42,82,72,80,47,58,55,21,22,26,38,22,53,25,23,38,70,60,51,36,55,26,34,23,27,14,9,7,34,32,28,39,49,75,30,52,48,40,52,28,18,17,9,5,45,21,34, -64,56,50,49,45,31,19,12,15,10,7,6,3,48,23,20,39,36,35,53,21,16,23,13,10,6,1,4,2,16,15,17,27,25,20,29,11,17,12,16,8,1,1,0,1],t15HB:[7,12,18,53,47,76,124,108,89,123,108,119,107,81,122,63,13,5,16,27,46,36,61,51,42,70,52,83,65,41,59,36,19,17,15,24,41,34,59,48,40,64,50,78,62,80,56,33,29,28,25,43,39,63,55,93,76,59,93,72,54,75,50,29,52,22,42,40,67,57,95,79,72,57,89,69,49,66,46,27,77,37,35,66,58,52,91,74,62,48,79,63,90,62,40,38,125,32,60,56,50,92,78,65,55,87,71,51,73,51,70,30,109,53,49,94,88,75,66,122,91, -73,56,42,64,44,21,25,90,43,41,77,73,63,56,92,77,66,47,67,48,53,36,20,71,34,67,60,58,49,88,76,67,106,71,54,38,39,23,15,109,53,51,47,90,82,58,57,48,72,57,41,23,27,62,9,86,42,40,37,70,64,52,43,70,55,42,25,29,18,11,11,118,68,30,55,50,46,74,65,49,39,24,16,22,13,14,7,91,44,39,38,34,63,52,45,31,52,28,19,14,8,9,3,123,60,58,53,47,43,32,22,37,24,17,12,15,10,2,1,71,37,34,30,28,20,17,26,21,16,10,6,8,6,2,0],t16HB:[1,5,14,44,74,63,110,93,172,149,138,242,225,195,376,17,3,4,12,20,35,62,53,47,83,75,68,119,201,107, -207,9,15,13,23,38,67,58,103,90,161,72,127,117,110,209,206,16,45,21,39,69,64,114,99,87,158,140,252,212,199,387,365,26,75,36,68,65,115,101,179,164,155,264,246,226,395,382,362,9,66,30,59,56,102,185,173,265,142,253,232,400,388,378,445,16,111,54,52,100,184,178,160,133,257,244,228,217,385,366,715,10,98,48,91,88,165,157,148,261,248,407,397,372,380,889,884,8,85,84,81,159,156,143,260,249,427,401,392,383,727,713,708,7,154,76,73,141,131,256,245,426,406,394,384,735,359,710,352,11,139,129,67,125,247,233,229,219, -393,743,737,720,885,882,439,4,243,120,118,115,227,223,396,746,742,736,721,712,706,223,436,6,202,224,222,218,216,389,386,381,364,888,443,707,440,437,1728,4,747,211,210,208,370,379,734,723,714,1735,883,877,876,3459,865,2,377,369,102,187,726,722,358,711,709,866,1734,871,3458,870,434,0,12,10,7,11,10,17,11,9,13,12,10,7,5,3,1,3],t24HB:[15,13,46,80,146,262,248,434,426,669,653,649,621,517,1032,88,14,12,21,38,71,130,122,216,209,198,327,345,319,297,279,42,47,22,41,74,68,128,120,221,207,194,182,340,315,295, -541,18,81,39,75,70,134,125,116,220,204,190,178,325,311,293,271,16,147,72,69,135,127,118,112,210,200,188,352,323,306,285,540,14,263,66,129,126,119,114,214,202,192,180,341,317,301,281,262,12,249,123,121,117,113,215,206,195,185,347,330,308,291,272,520,10,435,115,111,109,211,203,196,187,353,332,313,298,283,531,381,17,427,212,208,205,201,193,186,177,169,320,303,286,268,514,377,16,335,199,197,191,189,181,174,333,321,305,289,275,521,379,371,11,668,184,183,179,175,344,331,314,304,290,277,530,383,373,366, -10,652,346,171,168,164,318,309,299,287,276,263,513,375,368,362,6,648,322,316,312,307,302,292,284,269,261,512,376,370,364,359,4,620,300,296,294,288,282,273,266,515,380,374,369,365,361,357,2,1033,280,278,274,267,264,259,382,378,372,367,363,360,358,356,0,43,20,19,17,15,13,11,9,7,6,4,7,5,3,1,3],t32HB:[1,10,8,20,12,20,16,32,14,12,24,0,28,16,24,16],t33HB:[15,28,26,48,22,40,36,64,14,24,20,32,12,16,8,0],t1l:[1,4,3,5],t2l:[1,4,7,4,5,7,6,7,8],t3l:[2,3,7,4,4,7,6,7,8],t5l:[1,4,7,8,4,5,8,9,7,8,9,10,8,8,9,10], -t6l:[3,4,6,8,4,4,6,7,5,6,7,8,7,7,8,9],t7l:[1,4,7,9,9,10,4,6,8,9,9,10,7,7,9,10,10,11,8,9,10,11,11,11,8,9,10,11,11,12,9,10,11,12,12,12],t8l:[2,4,7,9,9,10,4,4,6,10,10,10,7,6,8,10,10,11,9,10,10,11,11,12,9,9,10,11,12,12,10,10,11,11,13,13],t9l:[3,4,6,7,9,10,4,5,6,7,8,10,5,6,7,8,9,10,7,7,8,9,9,10,8,8,9,9,10,11,9,9,10,10,11,11],t10l:[1,4,7,9,10,10,10,11,4,6,8,9,10,11,10,10,7,8,9,10,11,12,11,11,8,9,10,11,12,12,11,12,9,10,11,12,12,12,12,12,10,11,12,12,13,13,12,13,9,10,11,12,12,12,13,13,10,10,11,12,12,13,13, -13],t11l:[2,4,6,8,9,10,9,10,4,5,6,8,10,10,9,10,6,7,8,9,10,11,10,10,8,8,9,11,10,12,10,11,9,10,10,11,11,12,11,12,9,10,11,12,12,13,12,13,9,9,9,10,11,12,12,12,9,9,10,11,12,12,12,12],t12l:[4,4,6,8,9,10,10,10,4,5,6,7,9,9,10,10,6,6,7,8,9,10,9,10,7,7,8,8,9,10,10,10,8,8,9,9,10,10,10,11,9,9,10,10,10,11,10,11,9,9,9,10,10,11,11,12,10,10,10,11,11,11,11,12],t13l:[1,5,7,8,9,10,10,11,10,11,12,12,13,13,14,14,4,6,8,9,10,10,11,11,11,11,12,12,13,14,14,14,7,8,9,10,11,11,12,12,11,12,12,13,13,14,15,15,8,9,10,11,11,12,12, -12,12,13,13,13,13,14,15,15,9,9,11,11,12,12,13,13,12,13,13,14,14,15,15,16,10,10,11,12,12,12,13,13,13,13,14,13,15,15,16,16,10,11,12,12,13,13,13,13,13,14,14,14,15,15,16,16,11,11,12,13,13,13,14,14,14,14,15,15,15,16,18,18,10,10,11,12,12,13,13,14,14,14,14,15,15,16,17,17,11,11,12,12,13,13,13,15,14,15,15,16,16,16,18,17,11,12,12,13,13,14,14,15,14,15,16,15,16,17,18,19,12,12,12,13,14,14,14,14,15,15,15,16,17,17,17,18,12,13,13,14,14,15,14,15,16,16,17,17,17,18,18,18,13,13,14,15,15,15,16,16,16,16,16,17,18,17,18, -18,14,14,14,15,15,15,17,16,16,19,17,17,17,19,18,18,13,14,15,16,16,16,17,16,17,17,18,18,21,20,21,18],t15l:[3,5,6,8,8,9,10,10,10,11,11,12,12,12,13,14,5,5,7,8,9,9,10,10,10,11,11,12,12,12,13,13,6,7,7,8,9,9,10,10,10,11,11,12,12,13,13,13,7,8,8,9,9,10,10,11,11,11,12,12,12,13,13,13,8,8,9,9,10,10,11,11,11,11,12,12,12,13,13,13,9,9,9,10,10,10,11,11,11,11,12,12,13,13,13,14,10,9,10,10,10,11,11,11,11,12,12,12,13,13,14,14,10,10,10,11,11,11,11,12,12,12,12,12,13,13,13,14,10,10,10,11,11,11,11,12,12,12,12,13,13,14, -14,14,10,10,11,11,11,11,12,12,12,13,13,13,13,14,14,14,11,11,11,11,12,12,12,12,12,13,13,13,13,14,15,14,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,15,12,12,11,12,12,12,13,13,13,13,13,13,14,14,15,15,12,12,12,12,12,13,13,13,13,14,14,14,14,14,15,15,13,13,13,13,13,13,13,13,14,14,14,14,15,15,14,15,13,13,13,13,13,13,13,14,14,14,14,14,15,15,15,15],t16_5l:[1,5,7,9,10,10,11,11,12,12,12,13,13,13,14,11,4,6,8,9,10,11,11,11,12,12,12,13,14,13,14,11,7,8,9,10,11,11,12,12,13,12,13,13,13,14,14,12,9,9,10,11,11,12,12, -12,13,13,14,14,14,15,15,13,10,10,11,11,12,12,13,13,13,14,14,14,15,15,15,12,10,10,11,11,12,13,13,14,13,14,14,15,15,15,16,13,11,11,11,12,13,13,13,13,14,14,14,14,15,15,16,13,11,11,12,12,13,13,13,14,14,15,15,15,15,17,17,13,11,12,12,13,13,13,14,14,15,15,15,15,16,16,16,13,12,12,12,13,13,14,14,15,15,15,15,16,15,16,15,14,12,13,12,13,14,14,14,14,15,16,16,16,17,17,16,13,13,13,13,13,14,14,15,16,16,16,16,16,16,15,16,14,13,14,14,14,14,15,15,15,15,17,16,16,16,16,18,14,15,14,14,14,15,15,16,16,16,18,17,17,17,19, -17,14,14,15,13,14,16,16,15,16,16,17,18,17,19,17,16,14,11,11,11,12,12,13,13,13,14,14,14,14,14,14,14,12],t16l:[1,5,7,9,10,10,11,11,12,12,12,13,13,13,14,10,4,6,8,9,10,11,11,11,12,12,12,13,14,13,14,10,7,8,9,10,11,11,12,12,13,12,13,13,13,14,14,11,9,9,10,11,11,12,12,12,13,13,14,14,14,15,15,12,10,10,11,11,12,12,13,13,13,14,14,14,15,15,15,11,10,10,11,11,12,13,13,14,13,14,14,15,15,15,16,12,11,11,11,12,13,13,13,13,14,14,14,14,15,15,16,12,11,11,12,12,13,13,13,14,14,15,15,15,15,17,17,12,11,12,12,13,13,13,14, -14,15,15,15,15,16,16,16,12,12,12,12,13,13,14,14,15,15,15,15,16,15,16,15,13,12,13,12,13,14,14,14,14,15,16,16,16,17,17,16,12,13,13,13,13,14,14,15,16,16,16,16,16,16,15,16,13,13,14,14,14,14,15,15,15,15,17,16,16,16,16,18,13,15,14,14,14,15,15,16,16,16,18,17,17,17,19,17,13,14,15,13,14,16,16,15,16,16,17,18,17,19,17,16,13,10,10,10,11,11,12,12,12,13,13,13,13,13,13,13,10],t24l:[4,5,7,8,9,10,10,11,11,12,12,12,12,12,13,10,5,6,7,8,9,10,10,11,11,11,12,12,12,12,12,10,7,7,8,9,9,10,10,11,11,11,11,12,12,12,13,9,8,8, -9,9,10,10,10,11,11,11,11,12,12,12,12,9,9,9,9,10,10,10,10,11,11,11,12,12,12,12,13,9,10,9,10,10,10,10,11,11,11,11,12,12,12,12,12,9,10,10,10,10,10,11,11,11,11,12,12,12,12,12,13,9,11,10,10,10,11,11,11,11,12,12,12,12,12,13,13,10,11,11,11,11,11,11,11,11,11,12,12,12,12,13,13,10,11,11,11,11,11,11,11,12,12,12,12,12,13,13,13,10,12,11,11,11,11,12,12,12,12,12,12,13,13,13,13,10,12,12,11,11,11,12,12,12,12,12,12,13,13,13,13,10,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,10,12,12,12,12,12,12,12,12,13,13,13,13,13, -13,13,10,13,12,12,12,12,12,12,13,13,13,13,13,13,13,13,10,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,6],t32l:[1,5,5,7,5,8,7,9,5,7,7,9,7,9,9,10],t33l:[4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8]};v.ht=[new W(0,0,null,null),new W(2,0,v.t1HB,v.t1l),new W(3,0,v.t2HB,v.t2l),new W(3,0,v.t3HB,v.t3l),new W(0,0,null,null),new W(4,0,v.t5HB,v.t5l),new W(4,0,v.t6HB,v.t6l),new W(6,0,v.t7HB,v.t7l),new W(6,0,v.t8HB,v.t8l),new W(6,0,v.t9HB,v.t9l),new W(8,0,v.t10HB,v.t10l),new W(8,0,v.t11HB,v.t11l),new W(8,0,v.t12HB,v.t12l),new W(16, -0,v.t13HB,v.t13l),new W(0,0,null,v.t16_5l),new W(16,0,v.t15HB,v.t15l),new W(1,1,v.t16HB,v.t16l),new W(2,3,v.t16HB,v.t16l),new W(3,7,v.t16HB,v.t16l),new W(4,15,v.t16HB,v.t16l),new W(6,63,v.t16HB,v.t16l),new W(8,255,v.t16HB,v.t16l),new W(10,1023,v.t16HB,v.t16l),new W(13,8191,v.t16HB,v.t16l),new W(4,15,v.t24HB,v.t24l),new W(5,31,v.t24HB,v.t24l),new W(6,63,v.t24HB,v.t24l),new W(7,127,v.t24HB,v.t24l),new W(8,255,v.t24HB,v.t24l),new W(9,511,v.t24HB,v.t24l),new W(11,2047,v.t24HB,v.t24l),new W(13,8191,v.t24HB, -v.t24l),new W(0,0,v.t32HB,v.t32l),new W(0,0,v.t33HB,v.t33l)];v.largetbl=[65540,327685,458759,589832,655369,655370,720906,720907,786443,786444,786444,851980,851980,851980,917517,655370,262149,393222,524295,589832,655369,720906,720906,720907,786443,786443,786444,851980,917516,851980,917516,655370,458759,524295,589832,655369,720905,720906,786442,786443,851979,786443,851979,851980,851980,917516,917517,720905,589832,589832,655369,720905,720906,786442,786442,786443,851979,851979,917515,917516,917516,983052, -983052,786441,655369,655369,720905,720906,786442,786442,851978,851979,851979,917515,917516,917516,983052,983052,983053,720905,655370,655369,720906,720906,786442,851978,851979,917515,851979,917515,917516,983052,983052,983052,1048588,786441,720906,720906,720906,786442,851978,851979,851979,851979,917515,917516,917516,917516,983052,983052,1048589,786441,720907,720906,786442,786442,851979,851979,851979,917515,917516,983052,983052,983052,983052,1114125,1114125,786442,720907,786443,786443,851979,851979, -851979,917515,917515,983051,983052,983052,983052,1048588,1048589,1048589,786442,786443,786443,786443,851979,851979,917515,917515,983052,983052,983052,983052,1048588,983053,1048589,983053,851978,786444,851979,786443,851979,917515,917516,917516,917516,983052,1048588,1048588,1048589,1114125,1114125,1048589,786442,851980,851980,851979,851979,917515,917516,983052,1048588,1048588,1048588,1048588,1048589,1048589,983053,1048589,851978,851980,917516,917516,917516,917516,983052,983052,983052,983052,1114124, -1048589,1048589,1048589,1048589,1179661,851978,983052,917516,917516,917516,983052,983052,1048588,1048588,1048589,1179661,1114125,1114125,1114125,1245197,1114125,851978,917517,983052,851980,917516,1048588,1048588,983052,1048589,1048589,1114125,1179661,1114125,1245197,1114125,1048589,851978,655369,655369,655369,720905,720905,786441,786441,786441,851977,851977,851977,851978,851978,851978,851978,655366];v.table23=[65538,262147,458759,262148,327684,458759,393222,458759,524296];v.table56=[65539,262148, -458758,524296,262148,327684,524294,589831,458757,524294,589831,655368,524295,524295,589832,655369];v.bitrate_table=[[0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,-1],[0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,-1],[0,8,16,24,32,40,48,56,64,-1,-1,-1,-1,-1,-1,-1]];v.samplerate_table=[[22050,24E3,16E3,-1],[44100,48E3,32E3,-1],[11025,12E3,8E3,-1]];v.scfsi_band=[0,6,11,16,21];ca.Q_MAX=257;ca.Q_MAX2=116;ca.LARGE_BITS=1E5;ca.IXMAX_VAL=8206;var ra={};ra.SFBMAX=3*e.SBMAX_s;e.ENCDELAY=576;e.POSTDELAY= -1152;e.MDCTDELAY=48;e.FFTOFFSET=224+e.MDCTDELAY;e.DECDELAY=528;e.SBLIMIT=32;e.CBANDS=64;e.SBPSY_l=21;e.SBPSY_s=12;e.SBMAX_l=22;e.SBMAX_s=13;e.PSFB21=6;e.PSFB12=6;e.BLKSIZE=1024;e.HBLKSIZE=e.BLKSIZE/2+1;e.BLKSIZE_s=256;e.HBLKSIZE_s=e.BLKSIZE_s/2+1;e.NORM_TYPE=0;e.START_TYPE=1;e.SHORT_TYPE=2;e.STOP_TYPE=3;e.MPG_MD_LR_LR=0;e.MPG_MD_LR_I=1;e.MPG_MD_MS_LR=2;e.MPG_MD_MS_I=3;e.fircoef=[-0.1039435,-0.1892065,-0.0432472*5,-0.155915,3.898045E-17,0.0467745*5,0.50455,0.756825,0.187098*5];aa.MFSIZE=3456+e.ENCDELAY- -e.MDCTDELAY;aa.MAX_HEADER_BUF=256;aa.MAX_BITS_PER_CHANNEL=4095;aa.MAX_BITS_PER_GRANULE=7680;aa.BPC=320;xa.RIFF=Rb("RIFF");xa.WAVE=Rb("WAVE");xa.fmt_=Rb("fmt ");xa.data=Rb("data");xa.readHeader=function(e){var p=new xa,l=e.getUint32(0,!1);if(xa.RIFF==l&&(e.getUint32(4,!0),xa.WAVE==e.getUint32(8,!1)&&xa.fmt_==e.getUint32(12,!1))){var v=e.getUint32(16,!0),x=20;switch(v){case 16:case 18:p.channels=e.getUint16(x+2,!0);p.sampleRate=e.getUint32(x+4,!0);break;default:throw"extended fmt chunk not implemented"; -}for(var x=x+v,v=xa.data,u=0;v!=l;){l=e.getUint32(x,!1);u=e.getUint32(x+4,!0);if(v==l)break;x+=u+8}p.dataLen=u;p.dataOffset=x+8;return p}};ra.SFBMAX=3*e.SBMAX_s;lamejs.Mp3Encoder=function(e,p,l){3!=arguments.length&&(console.error("WARN: Mp3Encoder(channels, samplerate, kbps) not specified"),e=1,p=44100,l=128);var v=new E,x=new Pc,u=new U,q=new ka,h=new Bc,b=new ca,n=new Jc,a=new Da,f=new Ac,F=new Sc,k=new Cc,g=new La,d=new Qc,c=new Rc;v.setModules(u,q,h,b,n,a,f,F,c);q.setModules(u,c,f,a);F.setModules(q, -f);h.setModules(v);n.setModules(q,k,b,g);b.setModules(g,k,v.enc.psy);k.setModules(q);g.setModules(b);a.setModules(v,q,f);x.setModules(d,c);d.setModules(f,F,h);var B=v.lame_init();B.num_channels=e;B.in_samplerate=p;B.brate=l;B.mode=ia.STEREO;B.quality=3;B.bWriteVbrTag=!1;B.disable_reservoir=!0;B.write_id3tag_automatic=!1;v.lame_init_params(B);var y=1152,r=0|1.25*y+7200,s=new Int8Array(r);this.encodeBuffer=function(a,b){1==e&&(b=a);a.length>y&&(y=a.length,r=0|1.25*y+7200,s=new Int8Array(r));var c=v.lame_encode_buffer(B, -a,b,a.length,s,0,r);return new Int8Array(s.subarray(0,c))};this.flush=function(){var a=v.lame_encode_flush(B,s,0,r);return new Int8Array(s.subarray(0,a))}};lamejs.WavHeader=xa}lamejs(); +function lamejs(){function U(f){return new Int32Array(f)}function G(f){return new Float32Array(f)}function ha(f){if(1==f.length)return G(f[0]);var k=f[0];f=f.slice(1);for(var r=[],x=0;x>=1;0!=a--;)g[l++]=e>c[b++]?0:1,g[l++]=e>c[b++]?0:1}function r(a,e,c,b,g,l){a>>=1;var h=a%2;for(a>>=1;0!=a--;){var p=c[b++]*e;var m=c[b++]*e;var n=0|p;var d=c[b++]*e;var z=0|m;var E=c[b++]*e;var f=0|d;p+=u.adj43[n];n=0|E;m+=u.adj43[z];g[l++]=0|p;d+=u.adj43[f];g[l++]=0|m;E+=u.adj43[n];g[l++]=0|d;g[l++]=0|E}0!=h&&(p=c[b++]*e,m=c[b++]*e,p+=u.adj43[0|p],m+=u.adj43[0|m],g[l++]=0|p,g[l++]=0|m)}function K(a,e,c,b){var m,g= +e,h=m=0;do{var p=a[g++],n=a[g++];m>=16;m>a&&(m=a,e++);b.bits+=m;return e;case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:g=e;e=d[m-1];var p=h=m=0,n=v.ht[e].xlen,l=v.ht[e].hlen, +f=v.ht[e+1].hlen,q=v.ht[e+2].hlen;do{var D=a[g+0]*n+a[g+1],g=g+2;m+=l[D];h+=f[D];p+=q[D]}while(gh&&(m=h,a++);m>p&&(m=p,a=e+2);b.bits+=m;return a;default:if(m>Y.IXMAX_VAL)return b.bits=Y.LARGE_BITS,-1;m-=15;for(g=24;32>g&&!(v.ht[g].linmax>=m);g++);for(h=g-8;24>h&&!(v.ht[h].linmax>=m);h++);m=h;p=65536*v.ht[m].xlen+v.ht[g].xlen;h=0;do n=a[e++],l=a[e++],0!=n&&(14>=16;h>a&&(h=a,m=g);b.bits+=h;return m}} +function C(a,e,b,c,g,l,h,p){for(var m=e.big_values,n=2;n=m)break;var E=g[n-2]+e.count1bits;if(b.part2_3_length<=E)break;E=new x(E);d=K(c,d,m,E);E=E.bits;b.part2_3_length<=E||(b.assign(e),b.part2_3_length=E,b.region0_count=l[n-2],b.region1_count=n-2-l[n-2],b.table_select[0]=h[n-2],b.table_select[1]=p[n-2],b.table_select[2]=d)}}var u=null;this.qupvt=null;this.setModules=function(a){u=this.qupvt=a};var fa=[[0,0],[0,0],[0,0],[0,0],[0,0],[0,1],[1,1],[1, +1],[1,2],[2,2],[2,3],[2,3],[3,4],[3,4],[3,4],[4,5],[4,5],[4,6],[5,6],[5,6],[5,7],[6,7],[6,7]],d=[1,2,5,7,7,10,10,13,13,13,13,13,13,13,13];this.noquant_count_bits=function(a,e,b){var c=e.l3_enc,m=Math.min(576,e.max_nonzero_coeff+2>>1<<1);null!=b&&(b.sfb_count1=0);for(;1h&&(p=h,e.count1table_select= +1);e.count1bits=p;e.big_values=m;if(0==m)return p;e.block_type==f.SHORT_TYPE?(g=3*a.scalefac_band.s[3],g>e.big_values&&(g=e.big_values),h=e.big_values):e.block_type==f.NORM_TYPE?(g=e.region0_count=a.bv_scf[m-2],h=e.region1_count=a.bv_scf[m-1],h=a.scalefac_band.l[g+h+2],g=a.scalefac_band.l[g+1],hh&&(g=h));g=Math.min(g,m);h=Math.min(h,m);0g)return Y.LARGE_BITS;var g=u.IPOW20(c.global_gain),h,p=0,n=0,l=0,d=0,q=0,w=m,t=0,D=e,H=0;var B=null!=b&&c.global_gain==b.global_gain; +var Q=c.block_type==f.SHORT_TYPE?38:21;for(h=0;h<=Q;h++){var V=-1;if(B||c.block_type==f.NORM_TYPE)V=c.global_gain-(c.scalefac[h]+(0!=c.preflag?u.pretab[h]:0)<c.max_nonzero_coeff&&(h=c.max_nonzero_coeff-p+1,qa.fill(m,c.max_nonzero_coeff,576,0),N=h,0>N&&(N=0),h=Q+1);0==n&&0==l&&(w=m,t=q,D=e,H=d);null!=b&&0=b.sfb_count1&&0=b.step[h]?(0!=n&&(r(n,g,D,H,w,t),n=0,w=m,t=q,D=e,H=d),l+=N):(0!=l&&(k(l,g,D,H,w,t),l=0,w=m,t=q,D=e,H=d),n+=N);if(0>=N){0!=l&&(k(l,g,D,H,w,t),l=0);0!=n&&(r(n,g,D,H,w,t),n=0);break}}h<=Q&&(q+=c.width[h],d+=c.width[h],p+=c.width[h])}0!=n&&r(n,g,D,H,w,t);0!=l&&k(l,g,D,H,w,t);if(0!=(a.substep_shaping&2))for(g=0,Q=.634521682242439/u.IPOW20(c.global_gain+c.scalefac_scale),p=0;p=Q?m[n]:0;return this.noquant_count_bits(a, +c,b)};this.best_huffman_divide=function(a,e){var c=new rb,b=e.l3_enc,g=U(23),l=U(23),h=U(23),p=U(23);if(e.block_type!=f.SHORT_TYPE||1!=a.mode_gr){c.assign(e);if(e.block_type==f.NORM_TYPE){for(var d=e.big_values,q=0;22>=q;q++)g[q]=Y.LARGE_BITS;for(q=0;16>q;q++){var w=a.scalefac_band.l[q+1];if(w>=d)break;for(var t=0,D=new x(t),k=K(b,0,w,D),t=D.bits,I=0;8>I;I++){var H=a.scalefac_band.l[q+I+2];if(H>=d)break;D=t;D=new x(D);H=K(b,w,H,D);D=D.bits;g[q+I]>D&&(g[q+I]=D,l[q+I]=q,h[q+I]=k,p[q+I]=H)}}C(a,c,e, +b,g,l,h,p)}d=c.big_values;if(!(0==d||1<(b[d-2]|b[d-1])||(d=e.count1+2,576c.big_values;d-=4)t=2*(2*(2*b[d-4]+b[d-3])+b[d-2])+b[d-1],q+=v.t32l[t],w+=v.t33l[t];c.big_values=d;c.count1table_select=0;q>w&&(q=w,c.count1table_select=1);c.count1bits=q;c.block_type==f.NORM_TYPE?C(a,c,e,b,g,l,h,p):(c.part2_3_length=q,q=a.scalefac_band.l[8],q>d&&(q=d),0q&&(a=new x(c.part2_3_length), +c.table_select[1]=K(b,q,d,a),c.part2_3_length=a.bits),e.part2_3_length>c.part2_3_length&&e.assign(c))}}};var c=[1,1,1,1,8,2,2,2,4,4,4,8,8,8,16,16],w=[1,2,4,8,1,2,4,8,2,4,8,2,4,8,4,8],a=[0,0,0,0,3,1,1,1,2,2,2,3,3,3,4,4],b=[0,1,2,3,0,1,2,3,1,2,3,1,2,3,2,3];fb.slen1_tab=a;fb.slen2_tab=b;this.best_scalefac_store=function(e,g,m,n){var l=n.tt[g][m],d,h,p=0;for(d=h=0;dq&&0==l.l3_enc[q+h];q++);0==q&&(l.scalefac[d]=p=-2)}if(0==l.scalefac_scale&&0==l.preflag){for(d= +h=0;d>=1);l.scalefac_scale=p=1}}if(0==l.preflag&&l.block_type!=f.SHORT_TYPE&&2==e.mode_gr){for(d=11;dd;d++)n.scfsi[m][d]=0;if(2==e.mode_gr&&1==g&&n.tt[0][m].block_type!=f.SHORT_TYPE&&n.tt[1][m].block_type!= +f.SHORT_TYPE){g=n.tt[1][m];h=n.tt[0][m];for(p=0;pd;d++)-1!=g.scalefac[d]&&(n++,mp;p++)m +d&&(g.part2_length=d,g.scalefac_compress=p));p=0}for(d=0;db;b++)gt[b]&&(a.part2_length=t[b],a.scalefac_compress=b);return a.part2_length==Y.LARGE_BITS};var q=[[15,15,7,7],[15,15,7,0],[7,3,0,0],[15,31,31,0],[7,7,7,0],[3,3,0,0]];this.scale_bitcount_lsf=function(a,e){var b,c,d,l,h=U(4),p=e.scalefac;a= +0!=e.preflag?2:0;for(d=0;4>d;d++)h[d]=0;if(e.block_type==f.SHORT_TYPE){var A=1;var w=u.nr_of_sfb_block[a][A];for(b=l=0;4>b;b++){var t=w[b]/3;for(d=0;dc;c++)p[3*l+c]>h[b]&&(h[b]=p[3*l+c])}}else for(A=0,w=u.nr_of_sfb_block[a][A],b=l=0;4>b;b++)for(t=w[b],d=0;dh[b]&&(h[b]=p[l]);w=!1;for(b=0;4>b;b++)h[b]>q[a][b]&&(w=!0);if(!w){e.sfb_partition_table=u.nr_of_sfb_block[a][A];for(b=0;4>b;b++)e.slen[b]=g[h[b]];A=e.slen[0];b=e.slen[1];h=e.slen[2];t=e.slen[3];switch(a){case 0:e.scalefac_compress= +(5*A+b<<4)+(h<<2)+t;break;case 1:e.scalefac_compress=400+(5*A+b<<2)+h;break;case 2:e.scalefac_compress=500+3*A+b;break;default:S.err.printf("intensity stereo not implemented yet\n")}}if(!w)for(b=e.part2_length=0;4>b;b++)e.part2_length+=e.slen[b]*e.sfb_partition_table[b];return w};var g=[0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4];this.huffman_init=function(a){for(var e=2;576>=e;e+=2){for(var b=0,c;a.scalefac_band.l[++b]e;)c--;0>c&&(c=fa[b][0]);a.bv_scf[e-2]=c;for(c= +fa[b][1];a.scalefac_band.l[c+a.bv_scf[e-2]+2]>e;)c--;0>c&&(c=fa[b][1]);a.bv_scf[e-1]=c}}}function ca(){function f(d,c,f,a,b,k){for(;0!=b--;)f[a]=1E-10+d[c+0]*k[0]-f[a-1]*k[1]+d[c-1]*k[2]-f[a-2]*k[3]+d[c-2]*k[4]-f[a-3]*k[5]+d[c-3]*k[6]-f[a-4]*k[7]+d[c-4]*k[8]-f[a-5]*k[9]+d[c-5]*k[10]-f[a-6]*k[11]+d[c-6]*k[12]-f[a-7]*k[13]+d[c-7]*k[14]-f[a-8]*k[15]+d[c-8]*k[16]-f[a-9]*k[17]+d[c-9]*k[18]-f[a-10]*k[19]+d[c-10]*k[20],++a,++c}function k(d,c,f,a,b,k){for(;0!=b--;)f[a]=d[c+0]*k[0]-f[a-1]*k[1]+d[c-1]*k[2]- +f[a-2]*k[3]+d[c-2]*k[4],++a,++c}function r(d){return d*d}var K=ca.RMS_WINDOW_TIME_NUMERATOR,C=ca.RMS_WINDOW_TIME_DENOMINATOR,u=[[.038575994352,-3.84664617118067,-.02160367184185,7.81501653005538,-.00123395316851,-11.34170355132042,-9.291677959E-5,13.05504219327545,-.01655260341619,-12.28759895145294,.02161526843274,9.4829380631979,-.02074045215285,-5.87257861775999,.00594298065125,2.75465861874613,.00306428023191,-.86984376593551,1.2025322027E-4,.13919314567432,.00288463683916],[.0541865640643,-3.47845948550071, +-.02911007808948,6.36317777566148,-.00848709379851,-8.54751527471874,-.00851165645469,9.4769360780128,-.00834990904936,-8.81498681370155,.02245293253339,6.85401540936998,-.02596338512915,-4.39470996079559,.01624864962975,2.19611684890774,-.00240879051584,-.75104302451432,.00674613682247,.13149317958808,-.00187763777362],[.15457299681924,-2.37898834973084,-.09331049056315,2.84868151156327,-.06247880153653,-2.64577170229825,.02163541888798,2.23697657451713,-.05588393329856,-1.67148153367602,.04781476674921, +1.00595954808547,.00222312597743,-.45953458054983,.03174092540049,.16378164858596,-.01390589421898,-.05032077717131,.00651420667831,.0234789740702,-.00881362733839],[.30296907319327,-1.61273165137247,-.22613988682123,1.0797749225997,-.08587323730772,-.2565625775407,.03282930172664,-.1627671912044,-.00915702933434,-.22638893773906,-.02364141202522,.39120800788284,-.00584456039913,-.22138138954925,.06276101321749,.04500235387352,-8.28086748E-6,.02005851806501,.00205861885564,.00302439095741,-.02950134983287], +[.33642304856132,-1.49858979367799,-.2557224142557,.87350271418188,-.11828570177555,.12205022308084,.11921148675203,-.80774944671438,-.07834489609479,.47854794562326,-.0046997791438,-.12453458140019,-.0058950022444,-.04067510197014,.05724228140351,.08333755284107,.00832043980773,-.04237348025746,-.0163538138454,.02977207319925,-.0176017656815],[.4491525660845,-.62820619233671,-.14351757464547,.29661783706366,-.22784394429749,-.372563729424,-.01419140100551,.00213767857124,.04078262797139,-.42029820170918, +-.12398163381748,.22199650564824,.04097565135648,.00613424350682,.10478503600251,.06747620744683,-.01863887810927,.05784820375801,-.03193428438915,.03222754072173,.00541907748707],[.56619470757641,-1.04800335126349,-.75464456939302,.29156311971249,.1624213774223,-.26806001042947,.16744243493672,.00819999645858,-.18901604199609,.45054734505008,.3093178284183,-.33032403314006,-.27562961986224,.0673936833311,.00647310677246,-.04784254229033,.08647503780351,.01639907836189,-.0378898455484,.01807364323573, +-.00588215443421],[.58100494960553,-.51035327095184,-.53174909058578,-.31863563325245,-.14289799034253,-.20256413484477,.17520704835522,.1472815413433,.02377945217615,.38952639978999,.15558449135573,-.23313271880868,-.25344790059353,-.05246019024463,.01628462406333,-.02505961724053,.06920467763959,.02442357316099,-.03721611395801,.01818801111503,-.00749618797172],[.53648789255105,-.2504987195602,-.42163034350696,-.43193942311114,-.00275953611929,-.03424681017675,.04267842219415,-.04678328784242,-.10214864179676, +.26408300200955,.14590772289388,.15113130533216,-.02459864859345,-.17556493366449,-.11202315195388,-.18823009262115,-.04060034127,.05477720428674,.0478866554818,.0470440968812,-.02217936801134]],v=[[.98621192462708,-1.97223372919527,-1.97242384925416,.97261396931306,.98621192462708],[.98500175787242,-1.96977855582618,-1.97000351574484,.9702284756635,.98500175787242],[.97938932735214,-1.95835380975398,-1.95877865470428,.95920349965459,.97938932735214],[.97531843204928,-1.95002759149878,-1.95063686409857, +.95124613669835,.97531843204928],[.97316523498161,-1.94561023566527,-1.94633046996323,.94705070426118,.97316523498161],[.96454515552826,-1.92783286977036,-1.92909031105652,.93034775234268,.96454515552826],[.96009142950541,-1.91858953033784,-1.92018285901082,.92177618768381,.96009142950541],[.95856916599601,-1.9154210807478,-1.91713833199203,.91885558323625,.95856916599601],[.94597685600279,-1.88903307939452,-1.89195371200558,.89487434461664,.94597685600279]];this.InitGainAnalysis=function(d,c){a:{for(var f= +0;fd.sampleWindow-d.totsamp?d.sampleWindow-d.totsamp:q;if(lMAX_ORDER-l&&(g=MAX_ORDER-l)}else e=w+l,t=c,D=b+l,m=a;f(t,e,d.lstepbuf,d.lstep+d.totsamp,g,u[d.reqindex]);f(m,D,d.rstepbuf,d.rstep+d.totsamp,g,u[d.reqindex]);k(d.lstepbuf,d.lstep+d.totsamp,d.loutbuf,d.lout+d.totsamp,g,v[d.reqindex]);k(d.rstepbuf,d.rstep+d.totsamp,d.routbuf,d.rout+ +d.totsamp,g,v[d.reqindex]);e=d.lout+d.totsamp;t=d.loutbuf;D=d.rout+d.totsamp;m=d.routbuf;for(var n=g%8;0!=n--;)d.lsum+=r(t[e++]),d.rsum+=r(m[D++]);for(n=g/8;0!=n--;)d.lsum+=r(t[e+0])+r(t[e+1])+r(t[e+2])+r(t[e+3])+r(t[e+4])+r(t[e+5])+r(t[e+6])+r(t[e+7]),e+=8,d.rsum+=r(m[D+0])+r(m[D+1])+r(m[D+2])+r(m[D+3])+r(m[D+4])+r(m[D+5])+r(m[D+6])+r(m[D+7]),D+=8;q-=g;l+=g;d.totsamp+=g;d.totsamp==d.sampleWindow&&(e=10*ca.STEPS_per_dB*Math.log10((d.lsum+d.rsum)/d.totsamp*.5+1E-37),e=0>=e?0:0|e,e>=d.A.length&&(e= +d.A.length-1),d.A[e]++,d.lsum=d.rsum=0,S.arraycopy(d.loutbuf,d.totsamp,d.loutbuf,0,MAX_ORDER),S.arraycopy(d.routbuf,d.totsamp,d.routbuf,0,MAX_ORDER),S.arraycopy(d.lstepbuf,d.totsamp,d.lstepbuf,0,MAX_ORDER),S.arraycopy(d.rstepbuf,d.totsamp,d.rstepbuf,0,MAX_ORDER),d.totsamp=0);if(d.totsamp>d.sampleWindow)return GAIN_ANALYSIS_ERROR}B=(b-=c[a])););c=64.82-a/ca.STEPS_per_dB}for(f=0;fb&&(b=0);9w&&(w+=64);c.exp_nspsytune|=w<<2}0!=a?c.quant_comp=d[b].quant_comp:0=d)return K(c,d,a);c.preset=0;return d}}function xc(){var f;this.setModules= +function(k){f=k};this.ResvFrameBegin=function(k,r){var x=k.internal_flags,C=x.l3_side,u=f.getframebits(k);r.bits=(u-8*x.sideinfo_len)/x.mode_gr;var v=2048*x.mode_gr-8;if(320v&&(x.ResvMax=v);if(0>x.ResvMax||k.disable_reservoir)x.ResvMax=0;k=r.bits*x.mode_gr+Math.min(x.ResvSize,x.ResvMax);k>d&&(k=d);C.resvDrain_pre=0;null!=x.pinfo&&(x.pinfo.mean_bits= +r.bits/2,x.pinfo.resvsize=x.ResvSize);return k};this.ResvMaxBits=function(f,r,x,C){var k=f.internal_flags,v=k.ResvSize,d=k.ResvMax;0!=C&&(v+=r);0!=(k.substep_shaping&1)&&(d*=.9);x.bits=r;10*v>9*d?(C=v-9*d/10,x.bits+=C,k.substep_shaping|=128):(C=0,k.substep_shaping&=127,f.disable_reservoir||0!=(k.substep_shaping&1)||(x.bits-=.1*r));f=v<6*k.ResvMax/10?v:6*k.ResvMax/10;f-=C;0>f&&(f=0);return f};this.ResvAdjust=function(f,r){f.ResvSize-=r.part2_3_length+r.part2_length};this.ResvFrameEnd=function(f,r){var k, +x=f.l3_side;f.ResvSize+=r*f.mode_gr;r=0;x.resvDrain_post=0;x.resvDrain_pre=0;0!=(k=f.ResvSize%8)&&(r+=k);k=f.ResvSize-r-f.ResvMax;0>24&255;a[b+1]=c>>16&255;a[b+2]=c>>8&255;a[b+3]=c&255}function r(a,b,c){a[b+0]=c>>8&255; +a[b+1]=c&255}function K(a,b,c){return 255&(a<a.out_samplerate?0:1);b[1]=K(b[1],1,a.version);b[1]=K(b[1],2,1);b[1]=K(b[1],1,a.error_protection?0:1);b[2]=K(b[2],4,e.bitrate_index);b[2]=K(b[2],2,e.samplerate_index);b[2]=K(b[2],1,0);b[2]=K(b[2],1,a.extension);b[3]=K(b[3],2,a.mode.ordinal());b[3]=K(b[3],2,e.mode_ext);b[3]=K(b[3],1,a.copyright);b[3]=K(b[3],1,a.original);b[3]=K(b[3],2,a.emphasis); +b[0]=255;var e=b[1]&241;var c=1==a.version?128:16E3>a.out_samplerate?32:64;a.VBR==J.vbr_off&&(c=a.brate);c=a.free_format?0:255&16*G.BitrateIndex(c,a.version,a.out_samplerate);b[1]=1==a.version?255&(e|10):255&(e|2);e=b[2]&13;b[2]=255&(c|e)}function u(a,b){return b=b>>8^B[(b^a)&255]}var G,d,c;this.setModules=function(a,b,f){G=a;d=b;c=f};var w=gb.NUMTOCENTRIES,a=gb.MAXFRAMESIZE,b=w+4+4+4+4+4+9+1+1+8+1+1+3+1+1+2+4+2+2,B=[0,49345,49537,320,49921,960,640,49729,50689,1728,1920,51009,1280,50625,50305,1088, +52225,3264,3456,52545,3840,53185,52865,3648,2560,51905,52097,2880,51457,2496,2176,51265,55297,6336,6528,55617,6912,56257,55937,6720,7680,57025,57217,8E3,56577,7616,7296,56385,5120,54465,54657,5440,55041,6080,5760,54849,53761,4800,4992,54081,4352,53697,53377,4160,61441,12480,12672,61761,13056,62401,62081,12864,13824,63169,63361,14144,62721,13760,13440,62529,15360,64705,64897,15680,65281,16320,16E3,65089,64001,15040,15232,64321,14592,63937,63617,14400,10240,59585,59777,10560,60161,11200,10880,59969, +60929,11968,12160,61249,11520,60865,60545,11328,58369,9408,9600,58689,9984,59329,59009,9792,8704,58049,58241,9024,57601,8640,8320,57409,40961,24768,24960,41281,25344,41921,41601,25152,26112,42689,42881,26432,42241,26048,25728,42049,27648,44225,44417,27968,44801,28608,28288,44609,43521,27328,27520,43841,26880,43457,43137,26688,30720,47297,47489,31040,47873,31680,31360,47681,48641,32448,32640,48961,32E3,48577,48257,31808,46081,29888,30080,46401,30464,47041,46721,30272,29184,45761,45953,29504,45313, +29120,28800,45121,20480,37057,37249,20800,37633,21440,21120,37441,38401,22208,22400,38721,21760,38337,38017,21568,39937,23744,23936,40257,24320,40897,40577,24128,23040,39617,39809,23360,39169,22976,22656,38977,34817,18624,18816,35137,19200,35777,35457,19008,19968,36545,36737,20288,36097,19904,19584,35905,17408,33985,34177,17728,34561,18368,18048,34369,33281,17088,17280,33601,16640,33217,32897,16448];this.addVbrFrame=function(a){var b=a.internal_flags;var e=b.VBR_seek_table;a=v.bitrate_table[a.version][b.bitrate_index]; +e.nVbrNumFrames++;e.sum+=a;e.seen++;if(!(e.seen>3&1,d=a[e+2]>>2&3,k=a[e+3]>>6&3,m=a[e+2]>>4&15,m=v.bitrate_table[c][m];b.samprate=14==a[e+1]>>4?v.samplerate_table[2][d]:v.samplerate_table[c][d];d=e=0!=c?3!=k?e+36:e+21:3!=k?e+21:e+13;if(!(new String(a,d,4(),null)).equals("Xing")&&!(new String(a, +d,4(),null)).equals("Info"))return null;e+=4;b.hId=c;d=b.flags=f(a,e);e+=4;0!=(d&1)&&(b.frames=f(a,e),e+=4);0!=(d&2)&&(b.bytes=f(a,e),e+=4);if(0!=(d&4)){if(null!=b.toc)for(k=0;k>4;m=(a[e+1]&15)<<8;m+=a[e+2]&255;if(0>c||3E3m||3E3e.out_samplerate?32:64;e.VBR==J.vbr_off&&(f=e.brate);f=72E3*(e.version+1)*f/e.out_samplerate;var g=c.sideinfo_len+b;c.VBR_seek_table.TotalFrameSize=f;if(fa)e.bWriteVbrTag=!1;else for(c.VBR_seek_table.nVbrNumFrames=0,c.VBR_seek_table.nBytesWritten=0,c.VBR_seek_table.sum=0,c.VBR_seek_table.seen=0,c.VBR_seek_table.want=1,c.VBR_seek_table.pos=0,null==c.VBR_seek_table.bag&&(c.VBR_seek_table.bag=new int[400],c.VBR_seek_table.size=400),f=new Int8Array(a),C(e,f),c=c.VBR_seek_table.TotalFrameSize, +g=0;g=e.VBR_seek_table.pos)return 0;if(b.length=l.pos))for(f=1;fl.pos-1&&(m=l.pos-1);m=0|256*l.bag[m]/l.sum;255z.RadioGain&&(z.RadioGain=-510),x=11264,x=0<=z.RadioGain?x|z.RadioGain:x|512|-z.RadioGain);z.findPeakSample&&(B=Math.abs(0|z.PeakSample/32767*Math.pow(2,23)+.5));-1!=V&&(0h&&(h=0);switch(a.mode){case MONO:M=0;break;case STEREO:M=1;break;case DUAL_CHANNEL:M=2;break;case JOINT_STEREO:M=a.force_ms?4:3;break;default:M= +7}I=32E3>=a.in_samplerate?0:48E3==a.in_samplerate?2:48E3a.scale_right||a.disable_reservoir&&320>a.brate||a.noATH||a.ATHonly||0==v||32E3>=a.in_samplerate)X=1;R=R+(M<<2)+(X<<5)+(I<<6);z=z.nMusicCRC;k(b,g+m,h);m+=4;for(h=0;9>h;h++)b[g+m+h]=255&p.charAt(h);m+=9;b[g+m]=255&A;m++;b[g+m]=255&y;m++;k(b,g+m,B);m+=4;r(b,g+m, +x);m+=2;r(b,g+m,0);m+=2;b[g+m]=255&H;m++;b[g+m]=255<=Qa?255:255&Qa;m++;b[g+m]=255&n>>4;b[g+m+1]=255&(n<<4)+(E>>8);b[g+m+2]=255&E;m+=3;b[g+m]=255&R;m++;b[g+m++]=0;r(b,g+m,a.preset);m+=2;k(b,g+m,l);m+=4;r(b,g+m,z);m+=2;for(a=0;a=b.internal_flags.VBR_seek_table.pos)return-1;c.seek(c.length());if(0==c.length())return-1;c.seek(0);var e=new Int8Array(10);c.readFully(e);e=(new String(e,"ISO-8859-1")).startsWith("ID3")? +0:((e[6]&127)<<21|(e[7]&127)<<14|(e[8]&127)<<7|e[9]&127)+e.length;c.seek(e);e=new Int8Array(a);b=getLameTagFrame(b,e);if(b>e.length)return-1;if(1>b)return 0;c.write(e,0,b);return 0}}function da(){function x(a,b,c){for(;0>c<>3]|=b>>c<<8-(e&7)-h;e+=h}a.header[a.h_ptr].ptr=e}function K(a,b){a<<=8;for(var c=0;8>c;c++)a<<=1,b<<=1,0!=((b^a)& +65536)&&(b^=32773);return b}function C(a,b){var c=v.ht[b.count1table_select+32],e,h=0,d=b.big_values,g=b.big_values;for(e=(b.count1-b.big_values)/4;0b.xr[g+0]&&f++);n=b.l3_enc[d+1];0!=n&&(m+=4,f*=2,0>b.xr[g+1]&&f++);n=b.l3_enc[d+2];0!=n&&(m+=2,f*=2,0>b.xr[g+2]&&f++);n=b.l3_enc[d+3];0!=n&&(m++,f*=2,0>b.xr[g+3]&&f++);d+=4;g+=4;x(a,f+c.table[m],c.hlen[m]);h+=c.hlen[m]}return h}function u(a,b,c,e,h){var d=v.ht[b],g=0;if(0==b)return g;for(;ch.xr[c]&&q++,f--);15h.xr[c+1]&&q++,f--);I=I*l+k;m-=f;f+=d.hlen[I];x(a,d.table[I],f);x(a,q,m);g+=f+m}return g}function G(a,b){var c=3*a.scalefac_band.s[3];c>b.big_values&&(c=b.big_values);var e=u(a,b.table_select[0],0,c,b);return e+=u(a,b.table_select[1],c,b.big_values,b)}function d(a,b){var c=b.big_values;var e=b.region0_count+1;var h=a.scalefac_band.l[e]; +e+=b.region1_count+1;var d=a.scalefac_band.l[e];h>c&&(h=c);d>c&&(d=c);e=u(a,b.table_select[0],0,h,b);e+=u(a,b.table_select[1],h,d,b);return e+=u(a,b.table_select[2],d,c,b)}function c(){this.total=0}function w(b,c){var e=b.internal_flags;var d=e.w_ptr;var h=e.h_ptr-1;-1==h&&(h=ia.MAX_HEADER_BUF-1);var f=e.header[h].write_timing-g;c.total=f;if(0<=f){var m=1+h-d;hf&&S.err.println("strange error flushing buffer ... \n");return f}var a=this,b=null,B=null,e=null,l=null;this.setModules=function(a,c,d,f){b=a;B=c;e=d;l=f};var q=null,g=0,t=0,D=0;this.getframebits=function(a){var b=a.internal_flags;return 8*(0|72E3*(a.version+1)*(0!=b.bitrate_index?v.bitrate_table[a.version][b.bitrate_index]:a.brate)/a.out_samplerate+b.padding)};this.CRC_writeheader=function(a,b){var c=K(b[2]&255,65535);c=K(b[3]&255,c);for(var e=6;e> +8);b[5]=byte(c&255)};this.flush_bitstream=function(a){var e=a.internal_flags,d;var f=e.l3_side;0>(d=w(a,new c))||(k(a,d),e.ResvSize=0,f.main_data_begin=0,e.findReplayGain&&(f=b.GetTitleGain(e.rgdata),e.RadioGain=Math.floor(10*f+.5)|0),e.findPeakSample&&(e.noclipGainChange=Math.ceil(200*Math.log10(e.PeakSample/32767))|0,0>h<a.out_samplerate?r(p,4094,12):r(p,4095,12);r(p,a.version,1);r(p,1,2);r(p,a.error_protection? +0:1,1);r(p,p.bitrate_index,4);r(p,p.samplerate_index,2);r(p,p.padding,1);r(p,a.extension,1);r(p,a.mode.ordinal(),2);r(p,p.mode_ext,2);r(p,a.copyright,1);r(p,a.original,1);r(p,a.emphasis,2);a.error_protection&&r(p,0,16);if(1==a.version){r(p,t.main_data_begin,9);2==p.channels_out?r(p,t.private_bits,3):r(p,t.private_bits,5);for(q=0;qh;h++)r(p,t.scfsi[q][h],1);for(l=0;2>l;l++)for(q=0;qq;q++)for(h=0;hN;N++)for(M=t.sfb_partition_table[N]/3,H=t.slen[N],Q=0;QN;N++)for(M=t.sfb_partition_table[N], +H=t.slen[N],Q=0;Q ResvSize");8*e.main_data_begin!=b.ResvSize&&(S.err.printf("bit reservoir error: \nl3_side.main_data_begin: %d \nResvoir size: %d \nresv drain (post) %d \nresv drain (pre) %d \nheader and sideinfo: %d \ndata bits: %d \ntotal bits: %d (remainder: %d) \nbitsperframe: %d \n", +8*e.main_data_begin,b.ResvSize,e.resvDrain_post,e.resvDrain_pre,8*b.sideinfo_len,p-e.resvDrain_post-8*b.sideinfo_len,p,p%8,m),S.err.println("This is a fatal error. It has several possible causes:"),S.err.println("90%% LAME compiled with buggy version of gcc using advanced optimizations"),S.err.println(" 9%% Your system is overclocked"),S.err.println(" 1%% bug in LAME encoding library"),b.ResvSize=8*e.main_data_begin);if(1E9=f)return 0;if(0!=d&&f>d)return-1;S.arraycopy(q,0,c,e,f);t=-1;D=0;if(0!=h&&(d=U(1),d[0]=a.nMusicCRC,l.updateMusicCRC(d,c,e,f),a.nMusicCRC=d[0],0a.PeakSample?a.PeakSample=d[0][m]:-d[0][m]>a.PeakSample&&(a.PeakSample=-d[0][m]);if(1< +a.channels_out)for(m=0;ma.PeakSample?a.PeakSample=d[1][m]:-d[1][m]>a.PeakSample&&(a.PeakSample=-d[1][m])}if(a.findReplayGain&&b.AnalyzeSamples(a.rgdata,d[0],0,d[1],0,g,a.channels_out)==ca.GAIN_ANALYSIS_ERROR)return-6}}return f};this.init_bit_stream_w=function(a){q=new Int8Array(W.LAME_MAXMP3BUFFER);a.h_ptr=a.w_ptr=0;a.header[a.h_ptr].write_timing=0;t=-1;g=D=0}}function ba(f,k,r,v){this.xlen=f;this.linmax=k;this.table=r;this.hlen=v}function Fa(f){this.bits=f}function Fb(){this.bits= +this.over_SSD=this.over_count=this.max_noise=this.tot_noise=this.over_noise=0}function yc(){this.setModules=function(f,k){}}function zc(){this.floor=this.decay=this.adjustLimit=this.adjust=this.aaSensitivityP=this.useAdjust=0;this.l=G(f.SBMAX_l);this.s=G(f.SBMAX_s);this.psfb21=G(f.PSFB21);this.psfb12=G(f.PSFB12);this.cb_l=G(f.CBANDS);this.cb_s=G(f.CBANDS);this.eql_w=G(f.BLKSIZE/2)}function Ac(){this.scale_right=this.scale_left=this.scale=this.out_samplerate=this.in_samplerate=this.num_channels=this.num_samples= +this.class_id=0;this.decode_only=this.bWriteVbrTag=this.analysis=!1;this.quality=0;this.mode=ka.STEREO;this.write_id3tag_automatic=this.decode_on_the_fly=this.findReplayGain=this.free_format=this.force_ms=!1;this.error_protection=this.emphasis=this.extension=this.original=this.copyright=this.compression_ratio=this.brate=0;this.disable_reservoir=this.strict_ISO=!1;this.quant_comp_short=this.quant_comp=0;this.experimentalY=!1;this.preset=this.exp_nspsytune=this.experimentalZ=0;this.VBR=null;this.maskingadjust_short= +this.maskingadjust=this.highpasswidth=this.lowpasswidth=this.highpassfreq=this.lowpassfreq=this.VBR_hard_min=this.VBR_max_bitrate_kbps=this.VBR_min_bitrate_kbps=this.VBR_mean_bitrate_kbps=this.VBR_q=this.VBR_q_frac=0;this.noATH=this.ATHshort=this.ATHonly=!1;this.athaa_sensitivity=this.athaa_loudapprox=this.athaa_type=this.ATHlower=this.ATHcurve=this.ATHtype=0;this.short_blocks=null;this.useTemporal=!1;this.msfix=this.interChRatio=0;this.tune=!1;this.lame_allocated_gfp=this.frameNum=this.framesize= +this.encoder_padding=this.encoder_delay=this.version=this.tune_value_a=0;this.internal_flags=null}function Bc(x){this.quantize=x;this.iteration_loop=function(k,r,x,v){var u=k.internal_flags,C=G(ra.SFBMAX),d=G(576),c=U(2),w=u.l3_side;var a=new Fa(0);this.quantize.rv.ResvFrameBegin(k,a);a=a.bits;for(var b=0;b>2&63;32<=q&&(q-=64); +k=Math.pow(10,q/4/10);q=c.exp_nspsytune>>8&63;32<=q&&(q-=64);m=Math.pow(10,q/4/10);q=c.exp_nspsytune>>14&63;32<=q&&(q-=64);n=Math.pow(10,q/4/10);q=c.exp_nspsytune>>20&63;32<=q&&(q-=64);z=n*Math.pow(10,q/4/10);for(q=0;q=q?k:13>=q?m:20>=q?n:z,e.nsPsy.longfact[q]=c;for(q=0;q=q?k:10>=q?m:11>=q?n:z,e.nsPsy.shortfact[q]=c}};this.on_pe=function(a,b,c,d,f,k){var e=a.internal_flags,g=0,l=U(2),q,g=new Fa(g);a=v.ResvMaxBits(a,d,g,k);var g=g.bits,h=g+a;h>ia.MAX_BITS_PER_GRANULE&& +(h=ia.MAX_BITS_PER_GRANULE);for(q=k=0;q3*d/4&&(l[q]=3*d/4),0>l[q]&&(l[q]=0),l[q]+c[q]>ia.MAX_BITS_PER_CHANNEL&&(l[q]=Math.max(0,ia.MAX_BITS_PER_CHANNEL-c[q])),k+=l[q];if(k>a)for(q=0;qia.MAX_BITS_PER_GRANULE)for(q=0;qb&&(b=0);.5ia.MAX_BITS_PER_CHANNEL-a[0]&&(b=ia.MAX_BITS_PER_CHANNEL-a[0]);0>b&&(b=0);125<=a[1]&&(125d&&(a[0]=d*a[0]/b,a[1]=d*a[1]/b)};this.athAdjust=function(a,b,c){b=Z.FAST_LOG10_X(b,10);a*=a;var e=0;b-=c;1E-20e&&(e=0);return Math.pow(10,.1*(b*e+(c+90.30873362-94.82444863)))}; +this.calc_xmin=function(a,b,c,d){var e=0,g=a.internal_flags,m,l=0,q=0,k=g.ATH,h=c.xr,p=a.VBR==J.vbr_mtrh?1:0,A=g.masking_lower;if(a.VBR==J.vbr_mtrh||a.VBR==J.vbr_mt)A=1;for(m=0;m>1;var I=0;do{var H=h[l]*h[l];I+=H;x+=Hw&&q++;m==f.SBPSY_l&&(u=w*g.nsPsy.longfact[m],xQ;Q++){I=0;u=r>>1;B=V/r;x=2.220446049250313E-16;do H=h[l]*h[l],I+=H,x+=HV&&q++;M==f.SBPSY_s&&(u=V*g.nsPsy.shortfact[M],xd[e-3+1]&&(d[e-3+1]+=(d[e-3]-d[e-3+1])*g.decay),d[e-3+1]>d[e-3+2]&&(d[e-3+2]+=(d[e-3+1]-d[e-3+2])*g.decay))}return q};this.calc_noise_core=function(a,c,d,f){var e=0,g=c.s,m=a.l3_enc;if(g>a.count1)for(;0!=d--;){var l=a.xr[g]; +g++;e+=l*l;l=a.xr[g];g++;e+=l*l}else if(g>a.big_values){var q=G(2);q[0]=0;for(q[1]=f;0!=d--;)l=Math.abs(a.xr[g])-q[m[g]],g++,e+=l*l,l=Math.abs(a.xr[g])-q[m[g]],g++,e+=l*l}else for(;0!=d--;)l=Math.abs(a.xr[g])-b[m[g]]*f,g++,e+=l*l,l=Math.abs(a.xr[g])-b[m[g]]*f,g++,e+=l*l;c.s=g;return e};this.calc_noise=function(a,b,d,f,t){var e=0,g=0,l,q=0,r=0,h=0,p=-20,A=0,y=a.scalefac,x=0;for(l=f.over_SSD=0;l>1;A+a.width[l]>a.max_nonzero_coeff&&(v=a.max_nonzero_coeff-A+1,v=0>1:0);A=new k(A);u=this.calc_noise_core(a,A,v,u);A=A.s;null!=t&&(t.step[l]=B,t.noise[l]=u);u=d[e++]=u/b[g++];u=Z.FAST_LOG10(Math.max(u,1E-20));null!=t&&(t.noise_log[l]=u)}null!=t&&(t.global_gain=a.global_gain);h+=u;0H;H++){l=0;for(I=B;If;++f){var a=d.tt[c][0].xr[f],b=d.tt[c][1].xr[f];d.tt[c][0].xr[f]=.5*(a+b)*Z.SQRT2;d.tt[c][1].xr[f]=.5*(a-b)*Z.SQRT2}};this.init_xrpow=function(d,c,f){var a=0|c.max_nonzero_coeff;c.xrpow_max=0;qa.fill(f,a,576,0);for(var b,k=b=0;k<=a;++k){var e=Math.abs(c.xr[k]);b+=e;f[k]=Math.sqrt(e*Math.sqrt(e));f[k]>c.xrpow_max&&(c.xrpow_max=f[k])}if(1E-20l;l++)for(var q=r;q=c;e--)if(Math.abs(a[e])l;l++)for(b=!1,r=f.PSFB12-1;0<=r&&!b;r--)for(c=3*d.scalefac_band.s[12]+(d.scalefac_band.s[13]-d.scalefac_band.s[12])*l+(d.scalefac_band.psfb12[r]-d.scalefac_band.psfb12[0]),e=c+(d.scalefac_band.psfb12[r+1]-d.scalefac_band.psfb12[r]), +q=C.athAdjust(k.adjust,k.psfb12[r],k.floor),1E-12=c;e--)if(Math.abs(a[e])r;r++){var e=0;0!=c.l3_enc[r]&&(e=Math.abs(c.xr[r]));a[r]=e}r=0;e= +8;c.block_type==f.SHORT_TYPE&&(e=6);do{var l,q,g=c.width[e],r=r+g;if(!(1<=b[e]||(qa.sort(a,r-g,g),da.EQ(a[r-1],0)))){var t=(1-b[e])*k[e];var w=l=0;do{for(q=1;w+qh?(O==x.BINSEARCH_DOWN&&(A=!0),A&&(p/=2),O=x.BINSEARCH_UP,F=p):(O==x.BINSEARCH_UP&&(A=!0),A&&(p/=2),O=x.BINSEARCH_DOWN,F=-p);c.global_gain+=F;0>c.global_gain&&(c.global_gain=0,A=!0);255h&&255>c.global_gain;)c.global_gain++,F=fa.count_bits(e, +a,c,null);e.CurrentStep[b]=4<=y-c.global_gain?4:2;e.OldValue[b]=c.global_gain;c.part2_3_length=F;if(0==e.noise_shaping)return 100;C.calc_noise(c,r,g,t,w);t.bits=c.part2_3_length;l.assign(c);b=0;for(S.arraycopy(a,0,q,0,576);!n;){do{h=new Fb;A=255;p=0!=(e.substep_shaping&2)?20:3;if(e.sfb21_extra){if(1la;la++)I[N+la]*=M,I[N+la]>R.xrpow_max&&(R.xrpow_max=I[N+la]);if(2==H.noise_shaping_amp)break}}if(M=k(y))y=!1;else if(M= +2==O.mode_gr?fa.scale_bitcount(y):fa.scale_bitcount_lsf(O,y)){if(1H;H++)F[R+H]*=1.2968395546510096,F[R+H]>M.xrpow_max&&(M.xrpow_max=F[R+H]);M.scalefac[X]=I>>1}M.preflag=0;M.scalefac_scale=1;M=!1}else if(y.block_type==f.SHORT_TYPE&&0H;H++){V=Q=0;for(F=R.sfb_lmax+H;FQ&&8>V)){if(7<=R.subblock_gain[H]){F=!0;break b}R.subblock_gain[H]++;Q=M.scalefac_band.l[R.sfb_lmax];for(F=R.sfb_lmax+H;F>R.scalefac_scale,0<=N)I[F]=N,Q+=3*V;else{I[F]=0;N=C.IPOW20(210+(N<la;la++)X[Q+la]*=N,X[Q+la]>R.xrpow_max&&(R.xrpow_max=X[Q+la]);Q+=V*(3-H-1)}N=C.IPOW20(202); +Q+=R.width[F]*(H+1);for(la=-R.width[F];0>la;la++)X[Q+la]*=N,X[Q+la]>R.xrpow_max&&(R.xrpow_max=X[Q+la])}}F=!1}M=F||k(y)}M||(M=2==O.mode_gr?fa.scale_bitcount(y):fa.scale_bitcount_lsf(O,y));y=!M}else y=!0;if(!y)break;0!=l.scalefac_scale&&(A=254);y=u-l.part2_length;if(0>=y)break;for(;(l.part2_3_length=fa.count_bits(e,a,l,w))>y&&l.global_gain<=A;)l.global_gain++;if(l.global_gain>A)break;if(0==t.over_count){for(;(l.part2_3_length=fa.count_bits(e,a,l,w))>m&&l.global_gain<=A;)l.global_gain++;if(l.global_gain> +A)break}C.calc_noise(l,r,g,h,w);h.bits=l.part2_3_length;O=c.block_type!=f.SHORT_TYPE?d.quant_comp:d.quant_comp_short;A=t;y=h;M=l;F=g;switch(O){default:case 9:0y.max_noise&&10*y.max_noise+y.bits<=10*A.max_noise+A.bits;break;case 0:O=y.over_count=y.max_noise&&.2=y.max_noise&&0>A.max_noise&&A.max_noise>y.max_noise-.2&&y.tot_noise=y.max_noise&&0y.max_noise-.2&&y.tot_noisey.max_noise-.1&&y.tot_noise+y.over_noisey.max_noise-.15&&y.tot_noise+y.over_noise+y.over_noisep&&0==t.over_count)break;if(3==e.noise_shaping_amp&&B&&30l.global_gain+l.scalefac_scale);3==e.noise_shaping_amp?B?n=!0:(l.assign(c),S.arraycopy(q,0,a,0,576),b=0,v=l.global_gain,B=!0):n=!0}d.VBR==J.vbr_rh||d.VBR==J.vbr_mtrh?S.arraycopy(q, +0,a,0,576):0!=(e.substep_shaping&1)&&trancate_smallspectrums(e,c,r,a);return t.over_count};this.iteration_finish_one=function(d,c,f){var a=d.l3_side,b=a.tt[c][f];fa.best_scalefac_store(d,c,f,a);1==d.use_best_huffman&&fa.best_huffman_divide(d,b);v.ResvAdjust(d,b)};this.VBR_encode_granule=function(d,c,f,a,b,k,e){var l=d.internal_flags,q=new rb,g=G(576),r=e,w=(e+k)/2,m=0,n=l.sfb21_extra;qa.fill(q.l3_enc,0);do{l.sfb21_extra=w>r-42?!1:n;var u=outer_loop(d,c,f,a,b,w);0>=u?(m=1,e=c.part2_3_length,q.assign(c), +S.arraycopy(a,0,g,0,576),e-=32,u=e-k,w=(e+k)/2):(k=w+32,u=e-k,w=(e+k)/2,0!=m&&(m=2,c.assign(q),S.arraycopy(g,0,a,0,576)))}while(12r[g.VBR_max_bitrate]&&(l[n][u]*=r[g.VBR_max_bitrate],l[n][u]/=w),e[n][u]>l[n][u]&&(e[n][u]=l[n][u]);return t};this.bitpressure_strategy=function(d,c,k,a){for(var b=0;bt&&(r[b][u]*=t,r[b][u]/=g);return q};this.calc_target_bits=function(d,c,k,a,b,u){var e=d.internal_flags,l=e.l3_side;e.bitrate_index=e.VBR_max_bitrate;var q=new Fa(0); +u[0]=v.ResvFrameBegin(d,q);e.bitrate_index=1;q=r.getframebits(d)-8*e.sideinfo_len;b[0]=q/(e.mode_gr*e.channels_out);q=d.VBR_mean_bitrate_kbps*d.framesize*1E3;0!=(e.substep_shaping&1)&&(q*=1.09);q/=d.out_samplerate;q-=8*e.sideinfo_len;q/=e.mode_gr*e.channels_out;var g=.93+.07*(11-d.compression_ratio)/5.5;.9>g&&(g=.9);13*q/2?w=3*q/2:0>w&&(w=0);a[d][b]+=w}a[d][b]>ia.MAX_BITS_PER_CHANNEL&&(a[d][b]=ia.MAX_BITS_PER_CHANNEL);t+=a[d][b]}if(t>ia.MAX_BITS_PER_GRANULE)for(b=0;bia.MAX_BITS_PER_CHANNEL&&(a[d][b]=ia.MAX_BITS_PER_CHANNEL),c+=a[d][b];if(c>u[0])for(d= +0;dq;q++){var g=k[e+-10];f=c[l+-224]*g;b=c[d+224]*g;g=k[e+-9];f+=c[l+-160]*g;b+=c[d+160]*g;g=k[e+-8];f+=c[l+-96]*g;b+=c[d+96]*g;g=k[e+-7];f+=c[l+-32]*g;b+=c[d+32]*g;g=k[e+-6];f+=c[l+32]*g;b+=c[d+-32]*g;g=k[e+-5];f+=c[l+96]*g;b+=c[d+-96]*g;g=k[e+-4];f+=c[l+160]*g;b+=c[d+-160]*g;g=k[e+-3];f+=c[l+224]*g;b+=c[d+-224]*g;g=k[e+-2];f+=c[d+-256]*g;b-=c[l+256]*g;g=k[e+ +-1];f+=c[d+-192]*g;b-=c[l+192]*g;g=k[e+0];f+=c[d+-128]*g;b-=c[l+128]*g;g=k[e+1];f+=c[d+-64]*g;b-=c[l+64]*g;g=k[e+2];f+=c[d+0]*g;b-=c[l+0]*g;g=k[e+3];f+=c[d+64]*g;b-=c[l+-64]*g;g=k[e+4];f+=c[d+128]*g;b-=c[l+-128]*g;g=k[e+5];f+=c[d+192]*g;b-=c[l+-192]*g;f*=k[e+6];g=b-f;a[30+2*q]=b+f;a[31+2*q]=k[e+7]*g;e+=18;d--;l++}b=c[d+-16]*k[e+-10];f=c[d+-32]*k[e+-2];b+=(c[d+-48]-c[d+16])*k[e+-9];f+=c[d+-96]*k[e+-1];b+=(c[d+-80]+c[d+48])*k[e+-8];f+=c[d+-160]*k[e+0];b+=(c[d+-112]-c[d+80])*k[e+-7];f+=c[d+-224]*k[e+ +1];b+=(c[d+-144]+c[d+112])*k[e+-6];f-=c[d+32]*k[e+2];b+=(c[d+-176]-c[d+144])*k[e+-5];f-=c[d+96]*k[e+3];b+=(c[d+-208]+c[d+176])*k[e+-4];f-=c[d+160]*k[e+4];b+=(c[d+-240]-c[d+208])*k[e+-3];f-=c[d+224];c=f-b;d=f+b;b=a[14];f=a[15]-b;a[31]=d+b;a[30]=c+f;a[15]=c-f;a[14]=d-b;b=a[28]-a[0];a[0]+=a[28];a[28]=b*k[e+-36+7];b=a[29]-a[1];a[1]+=a[29];a[29]=b*k[e+-36+7];b=a[26]-a[2];a[2]+=a[26];a[26]=b*k[e+-72+7];b=a[27]-a[3];a[3]+=a[27];a[27]=b*k[e+-72+7];b=a[24]-a[4];a[4]+=a[24];a[24]=b*k[e+-108+7];b=a[25]-a[5]; +a[5]+=a[25];a[25]=b*k[e+-108+7];b=a[22]-a[6];a[6]+=a[22];a[22]=b*Z.SQRT2;b=a[23]-a[7];a[7]+=a[23];a[23]=b*Z.SQRT2-a[7];a[7]-=a[6];a[22]-=a[7];a[23]-=a[22];b=a[6];a[6]=a[31]-b;a[31]+=b;b=a[7];a[7]=a[30]-b;a[30]+=b;b=a[22];a[22]=a[15]-b;a[15]+=b;b=a[23];a[23]=a[14]-b;a[14]+=b;b=a[20]-a[8];a[8]+=a[20];a[20]=b*k[e+-180+7];b=a[21]-a[9];a[9]+=a[21];a[21]=b*k[e+-180+7];b=a[18]-a[10];a[10]+=a[18];a[18]=b*k[e+-216+7];b=a[19]-a[11];a[11]+=a[19];a[19]=b*k[e+-216+7];b=a[16]-a[12];a[12]+=a[16];a[16]=b*k[e+-252+ +7];b=a[17]-a[13];a[13]+=a[17];a[17]=b*k[e+-252+7];b=-a[20]+a[24];a[20]+=a[24];a[24]=b*k[e+-216+7];b=-a[21]+a[25];a[21]+=a[25];a[25]=b*k[e+-216+7];b=a[4]-a[8];a[4]+=a[8];a[8]=b*k[e+-216+7];b=a[5]-a[9];a[5]+=a[9];a[9]=b*k[e+-216+7];b=a[0]-a[12];a[0]+=a[12];a[12]=b*k[e+-72+7];b=a[1]-a[13];a[1]+=a[13];a[13]=b*k[e+-72+7];b=a[16]-a[28];a[16]+=a[28];a[28]=b*k[e+-72+7];b=-a[17]+a[29];a[17]+=a[29];a[29]=b*k[e+-72+7];b=Z.SQRT2*(a[2]-a[10]);a[2]+=a[10];a[10]=b;b=Z.SQRT2*(a[3]-a[11]);a[3]+=a[11];a[11]=b;b=Z.SQRT2* +(-a[18]+a[26]);a[18]+=a[26];a[26]=b-a[18];b=Z.SQRT2*(-a[19]+a[27]);a[19]+=a[27];a[27]=b-a[19];b=a[2];a[19]-=a[3];a[3]-=b;a[2]=a[31]-b;a[31]+=b;b=a[3];a[11]-=a[19];a[18]-=b;a[3]=a[30]-b;a[30]+=b;b=a[18];a[27]-=a[11];a[19]-=b;a[18]=a[15]-b;a[15]+=b;b=a[19];a[10]-=b;a[19]=a[14]-b;a[14]+=b;b=a[10];a[11]-=b;a[10]=a[23]-b;a[23]+=b;b=a[11];a[26]-=b;a[11]=a[22]-b;a[22]+=b;b=a[26];a[27]-=b;a[26]=a[7]-b;a[7]+=b;b=a[27];a[27]=a[6]-b;a[6]+=b;b=Z.SQRT2*(a[0]-a[4]);a[0]+=a[4];a[4]=b;b=Z.SQRT2*(a[1]-a[5]);a[1]+= +a[5];a[5]=b;b=Z.SQRT2*(a[16]-a[20]);a[16]+=a[20];a[20]=b;b=Z.SQRT2*(a[17]-a[21]);a[17]+=a[21];a[21]=b;b=-Z.SQRT2*(a[8]-a[12]);a[8]+=a[12];a[12]=b-a[8];b=-Z.SQRT2*(a[9]-a[13]);a[9]+=a[13];a[13]=b-a[9];b=-Z.SQRT2*(a[25]-a[29]);a[25]+=a[29];a[29]=b-a[25];b=-Z.SQRT2*(a[24]+a[28]);a[24]-=a[28];a[28]=b-a[24];b=a[24]-a[16];a[24]=b;b=a[20]-b;a[20]=b;b=a[28]-b;a[28]=b;b=a[25]-a[17];a[25]=b;b=a[21]-b;a[21]=b;b=a[29]-b;a[29]=b;b=a[17]-a[1];a[17]=b;b=a[9]-b;a[9]=b;b=a[25]-b;a[25]=b;b=a[5]-b;a[5]=b;b=a[21]-b; +a[21]=b;b=a[13]-b;a[13]=b;b=a[29]-b;a[29]=b;b=a[1]-a[0];a[1]=b;b=a[16]-b;a[16]=b;b=a[17]-b;a[17]=b;b=a[8]-b;a[8]=b;b=a[9]-b;a[9]=b;b=a[24]-b;a[24]=b;b=a[25]-b;a[25]=b;b=a[4]-b;a[4]=b;b=a[5]-b;a[5]=b;b=a[20]-b;a[20]=b;b=a[21]-b;a[21]=b;b=a[12]-b;a[12]=b;b=a[13]-b;a[13]=b;b=a[28]-b;a[28]=b;b=a[29]-b;a[29]=b;b=a[0];a[0]+=a[31];a[31]-=b;b=a[1];a[1]+=a[30];a[30]-=b;b=a[16];a[16]+=a[15];a[15]-=b;b=a[17];a[17]+=a[14];a[14]-=b;b=a[8];a[8]+=a[23];a[23]-=b;b=a[9];a[9]+=a[22];a[22]-=b;b=a[24];a[24]+=a[7];a[7]-= +b;b=a[25];a[25]+=a[6];a[6]-=b;b=a[4];a[4]+=a[27];a[27]-=b;b=a[5];a[5]+=a[26];a[26]-=b;b=a[20];a[20]+=a[11];a[11]-=b;b=a[21];a[21]+=a[10];a[10]-=b;b=a[12];a[12]+=a[19];a[19]-=b;b=a[13];a[13]+=a[18];a[18]-=b;b=a[28];a[28]+=a[3];a[3]-=b;b=a[29];a[29]+=a[2];a[2]-=b}var k=[-.1482523854003001,32.308141959636465,296.40344946382766,883.1344870032432,11113.947376231741,1057.2713659324597,305.7402417275812,30.825928907280012,3.8533188138216365,59.42900443849514,709.5899960123345,5281.91112291017,-5829.66483675846, +-817.6293103748613,-76.91656988279972,-4.594269939176596,.9063471690191471,.1960342806591213,-.15466694054279598,34.324387823855965,301.8067566458425,817.599602898885,11573.795901679885,1181.2520595540152,321.59731579894424,31.232021761053772,3.7107095756221318,53.650946155329365,684.167428119626,5224.56624370173,-6366.391851890084,-908.9766368219582,-89.83068876699639,-5.411397422890401,.8206787908286602,.3901806440322567,-.16070888947830023,36.147034243915876,304.11815768187864,732.7429163887613, +11989.60988270091,1300.012278487897,335.28490093152146,31.48816102859945,3.373875931311736,47.232241542899175,652.7371796173471,5132.414255594984,-6909.087078780055,-1001.9990371107289,-103.62185754286375,-6.104916304710272,.7416505462720353,.5805693545089249,-.16636367662261495,37.751650073343995,303.01103387567713,627.9747488785183,12358.763425278165,1412.2779918482834,346.7496836825721,31.598286663170416,3.1598635433980946,40.57878626349686,616.1671130880391,5007.833007176154,-7454.040671756168, +-1095.7960341867115,-118.24411666465777,-6.818469345853504,.6681786379192989,.7653668647301797,-.1716176790982088,39.11551877123304,298.3413246578966,503.5259106886539,12679.589408408976,1516.5821921214542,355.9850766329023,31.395241710249053,2.9164211881972335,33.79716964664243,574.8943997801362,4853.234992253242,-7997.57021486075,-1189.7624067269965,-133.6444792601766,-7.7202770609839915,.5993769336819237,.9427934736519954,-.17645823955292173,40.21879108166477,289.9982036694474,359.3226160751053, +12950.259102786438,1612.1013903507662,362.85067106591504,31.045922092242872,2.822222032597987,26.988862316190684,529.8996541764288,4671.371946949588,-8535.899136645805,-1282.5898586244496,-149.58553632943463,-8.643494270763135,.5345111359507916,1.111140466039205,-.36174739330527045,41.04429910497807,277.5463268268618,195.6386023135583,13169.43812144731,1697.6433561479398,367.40983966190305,30.557037410382826,2.531473372857427,20.070154905927314,481.50208566532336,4464.970341588308,-9065.36882077239, +-1373.62841526722,-166.1660487028118,-9.58289321133207,.4729647758913199,1.268786568327291,-.36970682634889585,41.393213350082036,261.2935935556502,12.935476055240873,13336.131683328815,1772.508612059496,369.76534388639965,29.751323653701338,2.4023193045459172,13.304795348228817,430.5615775526625,4237.0568611071185,-9581.931701634761,-1461.6913552409758,-183.12733958476446,-10.718010163869403,.41421356237309503,1.414213562373095,-.37677560326535325,41.619486213528496,241.05423794991074,-187.94665032361226, +13450.063605744153,1836.153896465782,369.4908799925761,29.001847876923147,2.0714759319987186,6.779591200894186,377.7767837205709,3990.386575512536,-10081.709459700915,-1545.947424837898,-200.3762958015653,-11.864482073055006,.3578057213145241,1.546020906725474,-.3829366947518991,41.1516456456653,216.47684307105183,-406.1569483347166,13511.136535077321,1887.8076599260432,367.3025214564151,28.136213436723654,1.913880671464418,.3829366947518991,323.85365704338597,3728.1472257487526,-10561.233882199509, +-1625.2025997821418,-217.62525175416,-13.015432208941645,.3033466836073424,1.66293922460509,-.5822628872992417,40.35639251440489,188.20071124269245,-640.2706748618148,13519.21490106562,1927.6022433578062,362.8197642637487,26.968821921868447,1.7463817695935329,-5.62650678237171,269.3016715297017,3453.386536448852,-11016.145278780888,-1698.6569643425091,-234.7658734267683,-14.16351421663124,.2504869601913055,1.76384252869671,-.5887180101749253,39.23429103868072,155.76096234403798,-889.2492977967378, +13475.470561874661,1955.0535223723712,356.4450994756727,25.894952980042156,1.5695032905781554,-11.181939564328772,214.80884394039484,3169.1640829158237,-11443.321309975563,-1765.1588461316153,-251.68908574481912,-15.49755935939164,.198912367379658,1.847759065022573,-.7912582233652842,37.39369355329111,119.699486012458,-1151.0956593239027,13380.446257078214,1970.3952110853447,348.01959814116185,24.731487364283044,1.3850130831637748,-16.421408865300393,161.05030052864092,2878.3322807850063,-11838.991423510031, +-1823.985884688674,-268.2854986386903,-16.81724543849939,.1483359875383474,1.913880671464418,-.7960642926861912,35.2322109610459,80.01928065061526,-1424.0212633405113,13235.794061869668,1973.804052543835,337.9908651258184,23.289159354463873,1.3934255946442087,-21.099669467133474,108.48348407242611,2583.700758091299,-12199.726194855148,-1874.2780658979746,-284.2467154529415,-18.11369784385905,.09849140335716425,1.961570560806461,-.998795456205172,32.56307803611191,36.958364584370486,-1706.075448829146, +13043.287458812016,1965.3831106103316,326.43182772364605,22.175018750622293,1.198638339011324,-25.371248002043963,57.53505923036915,2288.41886619975,-12522.674544337233,-1914.8400385312243,-299.26241273417224,-19.37805630698734,.04912684976946725,1.990369453344394,.0178904535*Z.SQRT2/2.384E-6,.008938074*Z.SQRT2/2.384E-6,.0015673635*Z.SQRT2/2.384E-6,.001228571*Z.SQRT2/2.384E-6,4.856585E-4*Z.SQRT2/2.384E-6,1.09434E-4*Z.SQRT2/2.384E-6,5.0783E-5*Z.SQRT2/2.384E-6,6.914E-6*Z.SQRT2/2.384E-6,12804.797818791945, +1945.5515939597317,313.4244966442953,20.801593959731544,1995.1556208053692,9.000838926174497,-29.20218120805369],r=[[2.382191739347913E-13,6.423305872147834E-13,9.400849094049688E-13,1.122435026096556E-12,1.183840321267481E-12,1.122435026096556E-12,9.40084909404969E-13,6.423305872147839E-13,2.382191739347918E-13,5.456116108943412E-12,4.878985199565852E-12,4.240448995017367E-12,3.559909094758252E-12,2.858043359288075E-12,2.156177623817898E-12,1.475637723558783E-12,8.371015190102974E-13,2.599706096327376E-13, +-5.456116108943412E-12,-4.878985199565852E-12,-4.240448995017367E-12,-3.559909094758252E-12,-2.858043359288076E-12,-2.156177623817898E-12,-1.475637723558783E-12,-8.371015190102975E-13,-2.599706096327376E-13,-2.382191739347923E-13,-6.423305872147843E-13,-9.400849094049696E-13,-1.122435026096556E-12,-1.183840321267481E-12,-1.122435026096556E-12,-9.400849094049694E-13,-6.42330587214784E-13,-2.382191739347918E-13],[2.382191739347913E-13,6.423305872147834E-13,9.400849094049688E-13,1.122435026096556E-12, +1.183840321267481E-12,1.122435026096556E-12,9.400849094049688E-13,6.423305872147841E-13,2.382191739347918E-13,5.456116108943413E-12,4.878985199565852E-12,4.240448995017367E-12,3.559909094758253E-12,2.858043359288075E-12,2.156177623817898E-12,1.475637723558782E-12,8.371015190102975E-13,2.599706096327376E-13,-5.461314069809755E-12,-4.921085770524055E-12,-4.343405037091838E-12,-3.732668368707687E-12,-3.093523840190885E-12,-2.430835727329465E-12,-1.734679010007751E-12,-9.74825365660928E-13,-2.797435120168326E-13, +0,0,0,0,0,0,-2.283748241799531E-13,-4.037858874020686E-13,-2.146547464825323E-13],[.1316524975873958,.414213562373095,.7673269879789602,1.091308501069271,1.303225372841206,1.56968557711749,1.920982126971166,2.414213562373094,3.171594802363212,4.510708503662055,7.595754112725146,22.90376554843115,.984807753012208,.6427876096865394,.3420201433256688,.9396926207859084,-.1736481776669303,-.7660444431189779,.8660254037844387,.5,-.5144957554275265,-.4717319685649723,-.3133774542039019,-.1819131996109812, +-.09457419252642064,-.04096558288530405,-.01419856857247115,-.003699974673760037,.8574929257125442,.8817419973177052,.9496286491027329,.9833145924917901,.9955178160675857,.9991605581781475,.999899195244447,.9999931550702802],[0,0,0,0,0,0,2.283748241799531E-13,4.037858874020686E-13,2.146547464825323E-13,5.461314069809755E-12,4.921085770524055E-12,4.343405037091838E-12,3.732668368707687E-12,3.093523840190885E-12,2.430835727329466E-12,1.734679010007751E-12,9.74825365660928E-13,2.797435120168326E-13, +-5.456116108943413E-12,-4.878985199565852E-12,-4.240448995017367E-12,-3.559909094758253E-12,-2.858043359288075E-12,-2.156177623817898E-12,-1.475637723558782E-12,-8.371015190102975E-13,-2.599706096327376E-13,-2.382191739347913E-13,-6.423305872147834E-13,-9.400849094049688E-13,-1.122435026096556E-12,-1.183840321267481E-12,-1.122435026096556E-12,-9.400849094049688E-13,-6.423305872147841E-13,-2.382191739347918E-13]],v=r[f.SHORT_TYPE],C=r[f.SHORT_TYPE],u=r[f.SHORT_TYPE],J=r[f.SHORT_TYPE],d=[0,1,16,17, +8,9,24,25,4,5,20,21,12,13,28,29,2,3,18,19,10,11,26,27,6,7,22,23,14,15,30,31];this.mdct_sub48=function(c,k,a){for(var b=286,w=0;wn;n++)for(x(k,b,D[m]),x(k,b+32,D[m+1]),m+=2,b+=64,l=1;32>l;l+=2)D[m-1][l]*=-1;for(l=0;32>l;l++,t+=18){var D=q.block_type,m=c.sb_sample[w][e],z=c.sb_sample[w][1-e];0!=q.mixed_block_flag&&2>l&&(D=0);if(1E-12>c.amp_filter[l])qa.fill(g,t+0,t+18,0);else{if(1> +c.amp_filter[l])for(n=0;18>n;n++)z[n][d[l]]*=c.amp_filter[l];if(D==f.SHORT_TYPE){for(n=-3;0>n;n++){var E=r[f.SHORT_TYPE][n+3];g[t+3*n+9]=m[9+n][d[l]]*E-m[8-n][d[l]];g[t+3*n+18]=m[14-n][d[l]]*E+m[15+n][d[l]];g[t+3*n+10]=m[15+n][d[l]]*E-m[14-n][d[l]];g[t+3*n+19]=z[2-n][d[l]]*E+z[3+n][d[l]];g[t+3*n+11]=z[3+n][d[l]]*E-z[2-n][d[l]];g[t+3*n+20]=z[8-n][d[l]]*E+z[9+n][d[l]]}n=g;m=t;for(E=0;3>E;E++){var h=n[m+6]*r[f.SHORT_TYPE][0]-n[m+15];z=n[m+0]*r[f.SHORT_TYPE][2]-n[m+9];var p=h+z;var A=h-z;h=n[m+15]*r[f.SHORT_TYPE][0]+ +n[m+6];z=n[m+9]*r[f.SHORT_TYPE][2]+n[m+0];var y=h+z;var O=-h+z;z=2.069978111953089E-11*(n[m+3]*r[f.SHORT_TYPE][1]-n[m+12]);h=2.069978111953089E-11*(n[m+12]*r[f.SHORT_TYPE][1]+n[m+3]);n[m+0]=1.90752519173728E-11*p+z;n[m+15]=1.90752519173728E-11*-y+h;A*=1.6519652744032674E-11;y=9.537625958686404E-12*y+h;n[m+3]=A-y;n[m+6]=A+y;p=9.537625958686404E-12*p-z;O*=1.6519652744032674E-11;n[m+9]=p+O;n[m+12]=p-O;m++}}else{E=G(18);for(n=-9;0>n;n++)p=r[D][n+27]*z[n+9][d[l]]+r[D][n+36]*z[8-n][d[l]],A=r[D][n+9]*m[n+ +9][d[l]]-r[D][n+18]*m[8-n][d[l]],E[n+9]=p-A*v[3+n+9],E[n+18]=p*v[3+n+9]+A;var n=g,m=t;p=E;var F=p[17]-p[9];var R=p[15]-p[11];var X=p[14]-p[12];O=p[0]+p[8];y=p[1]+p[7];h=p[2]+p[6];A=p[3]+p[5];n[m+17]=O+h-A-(y-p[4]);E=(O+h-A)*C[19]+(y-p[4]);z=(F-R-X)*C[18];n[m+5]=z+E;n[m+6]=z-E;var I=(p[16]-p[10])*C[18];y=y*C[19]+p[4];z=F*C[12]+I+R*C[13]+X*C[14];E=-O*C[16]+y-h*C[17]+A*C[15];n[m+1]=z+E;n[m+2]=z-E;z=F*C[13]-I-R*C[14]+X*C[12];E=-O*C[17]+y-h*C[15]+A*C[16];n[m+9]=z+E;n[m+10]=z-E;z=F*C[14]-I+R*C[12]-X*C[13]; +E=O*C[15]-y+h*C[16]-A*C[17];n[m+13]=z+E;n[m+14]=z-E;F=p[8]-p[0];R=p[6]-p[2];X=p[5]-p[3];O=p[17]+p[9];y=p[16]+p[10];h=p[15]+p[11];A=p[14]+p[12];n[m+0]=O+h+A+(y+p[13]);z=(O+h+A)*C[19]-(y+p[13]);E=(F-R+X)*C[18];n[m+11]=z+E;n[m+12]=z-E;I=(p[7]-p[1])*C[18];y=p[13]-y*C[19];z=O*C[15]-y+h*C[16]+A*C[17];E=F*C[14]+I+R*C[12]+X*C[13];n[m+3]=z+E;n[m+4]=z-E;z=-O*C[17]+y-h*C[15]-A*C[16];E=F*C[13]+I-R*C[14]-X*C[12];n[m+7]=z+E;n[m+8]=z-E;z=-O*C[16]+y-h*C[17]-A*C[15];E=F*C[12]-I+R*C[13]-X*C[14];n[m+15]=z+E;n[m+16]= +z-E}}if(D!=f.SHORT_TYPE&&0!=l)for(n=7;0<=n;--n)D=g[t+n]*u[20+n]+g[t+-1-n]*J[28+n],m=g[t+n]*J[28+n]-g[t+-1-n]*u[20+n],g[t+-1-n]=D,g[t+n]=m}}k=a;b=286;if(1==c.mode_gr)for(e=0;18>e;e++)S.arraycopy(c.sb_sample[w][1][e],0,c.sb_sample[w][0][e],0,32)}}}function za(){this.thm=new tb;this.en=new tb}function f(){var x=f.FFTOFFSET,k=f.MPG_MD_MS_LR,r=null,v=this.psy=null,C=null,u=null;this.setModules=function(d,c,f,a){r=d;v=this.psy=c;C=a;u=f};var fa=new Fc;this.lame_encode_mp3_frame=function(d,c,w,a,b,B){var e= +Tb([2,2]);e[0][0]=new za;e[0][1]=new za;e[1][0]=new za;e[1][1]=new za;var l=Tb([2,2]);l[0][0]=new za;l[0][1]=new za;l[1][0]=new za;l[1][1]=new za;var q=[null,null],g=d.internal_flags,t=ha([2,4]),D=[.5,.5],m=[[0,0],[0,0]],n=[[0,0],[0,0]];q[0]=c;q[1]=w;if(0==g.lame_encode_frame_init){c=d.internal_flags;var z,E;if(0==c.lame_encode_frame_init){w=G(2014);var h=G(2014);c.lame_encode_frame_init=1;for(E=z=0;z<286+576*(1+c.mode_gr);++z)z<576*c.mode_gr?(w[z]=0,2==c.channels_out&&(h[z]=0)):(w[z]=q[0][E],2== +c.channels_out&&(h[z]=q[1][E]),++E);for(E=0;E(g.slot_lag-=g.frac_SpF)&&(g.slot_lag+=d.out_samplerate,g.padding=1);if(0!=g.psymodel)for(h=[null,null],z=0,E=U(2),w=0;w=t?(g.ATH.adjust*=.075*t+.925,g.ATH.adjust=t?g.ATH.adjust=t:g.ATH.adjustl;l++)g.nsPsy.pefirbuf[l]=g.nsPsy.pefirbuf[l+1];for(w=n=0;wl;l++)n+=(g.nsPsy.pefirbuf[l]+g.nsPsy.pefirbuf[18-l])*f.fircoef[l];n=3350*g.mode_gr*g.channels_out/n;for(w=0;wb;b++)g.pinfo.pcmdata[c][b]=q[c][b-x]}u.set_frame_pinfo(d,e)}g.bitrate_stereoMode_Hist[g.bitrate_index][4]++;g.bitrate_stereoMode_Hist[15][4]++;2==g.channels_out&&(g.bitrate_stereoMode_Hist[g.bitrate_index][g.mode_ext]++, +g.bitrate_stereoMode_Hist[15][g.mode_ext]++);for(d=0;df;f++)for(var k=0;2>k;k++)this.tt[f][k]=new rb}function tb(){this.l=G(f.SBMAX_l);this.s=ha([f.SBMAX_s,3]);var x=this;this.assign=function(k){S.arraycopy(k.l,0,x.l,0,f.SBMAX_l);for(var r=0;rv;v++)x.s[r][v]=k.s[r][v]}}function Ic(){this.last_en_subshort=ha([4,9]);this.lastAttacks=U(4);this.pefirbuf=G(19);this.longfact=G(f.SBMAX_l); +this.shortfact=G(f.SBMAX_s);this.attackthre_s=this.attackthre=0}function ia(){function x(){this.ptr=this.write_timing=0;this.buf=new Int8Array(40)}this.fill_buffer_resample_init=this.iteration_init_init=this.lame_encode_frame_init=this.Class_ID=0;this.mfbuf=ha([2,ia.MFSIZE]);this.full_outer_loop=this.use_best_huffman=this.subblock_gain=this.noise_shaping_stop=this.psymodel=this.substep_shaping=this.noise_shaping_amp=this.noise_shaping=this.highpass2=this.highpass1=this.lowpass2=this.lowpass1=this.mode_ext= +this.samplerate_index=this.bitrate_index=this.VBR_max_bitrate=this.VBR_min_bitrate=this.mf_size=this.mf_samples_to_encode=this.resample_ratio=this.channels_out=this.channels_in=this.mode_gr=0;this.l3_side=new Hc;this.ms_ratio=G(2);this.slot_lag=this.frac_SpF=this.padding=0;this.tag_spec=null;this.nMusicCRC=0;this.OldValue=U(2);this.CurrentStep=U(2);this.masking_lower=0;this.bv_scf=U(576);this.pseudohalf=U(ra.SFBMAX);this.sfb21_extra=!1;this.inbuf_old=Array(2);this.blackfilt=Array(2*ia.BPC+1);this.itime= +new Float64Array(2);this.sideinfo_len=0;this.sb_sample=ha([2,2,18,f.SBLIMIT]);this.amp_filter=G(32);this.header=Array(ia.MAX_HEADER_BUF);this.ResvMax=this.ResvSize=this.ancillary_flag=this.w_ptr=this.h_ptr=0;this.scalefac_band=new ma;this.minval_l=G(f.CBANDS);this.minval_s=G(f.CBANDS);this.nb_1=ha([4,f.CBANDS]);this.nb_2=ha([4,f.CBANDS]);this.nb_s1=ha([4,f.CBANDS]);this.nb_s2=ha([4,f.CBANDS]);this.s3_ll=this.s3_ss=null;this.decay=0;this.thm=Array(4);this.en=Array(4);this.tot_ener=G(4);this.loudness_sq= +ha([2,2]);this.loudness_sq_save=G(2);this.mld_l=G(f.SBMAX_l);this.mld_s=G(f.SBMAX_s);this.bm_l=U(f.SBMAX_l);this.bo_l=U(f.SBMAX_l);this.bm_s=U(f.SBMAX_s);this.bo_s=U(f.SBMAX_s);this.npart_s=this.npart_l=0;this.s3ind=Ua([f.CBANDS,2]);this.s3ind_s=Ua([f.CBANDS,2]);this.numlines_s=U(f.CBANDS);this.numlines_l=U(f.CBANDS);this.rnumlines_l=G(f.CBANDS);this.mld_cb_l=G(f.CBANDS);this.mld_cb_s=G(f.CBANDS);this.numlines_l_num1=this.numlines_s_num1=0;this.pe=G(4);this.ms_ener_ratio_old=this.ms_ratio_l_old=this.ms_ratio_s_old= +0;this.blocktype_old=U(2);this.nsPsy=new Ic;this.VBR_seek_table=new Gc;this.PSY=this.ATH=null;this.nogap_current=this.nogap_total=0;this.findPeakSample=this.findReplayGain=this.decode_on_the_fly=!0;this.AudiophileGain=this.RadioGain=this.PeakSample=0;this.rgdata=null;this.noclipScale=this.noclipGainChange=0;this.bitrate_stereoMode_Hist=Ua([16,5]);this.bitrate_blockType_Hist=Ua([16,6]);this.hip=this.pinfo=null;this.in_buffer_nsamples=0;this.iteration_loop=this.in_buffer_1=this.in_buffer_0=null;for(var k= +0;k>1;var e=a;var l=a<<1;var q=l+e;a=l<<1;var g=k;var t=g+u;do{var x=f[g+0]-f[g+e];var m=f[g+0]+f[g+e];var n=f[g+l]-f[g+q];var C=f[g+l]+f[g+q];f[g+l]=m-C;f[g+0]=m+C;f[g+q]=x-n;f[g+e]=x+n;x=f[t+0]-f[t+e];m=f[t+0]+f[t+e];n=Z.SQRT2*f[t+q];C=Z.SQRT2*f[t+l];f[t+l]=m-C;f[t+0]=m+C;f[t+ +q]=x-n;f[t+e]=x+n;t+=a;g+=a}while(gk;k++){var a=f.BLKSIZE_s/2,b=65535&192*(k+1),u=f.BLKSIZE_s/8-1;do{var e=C[u<<2]&255;var l=r[e]*c[d][w+e+b];var q=r[127-e]*c[d][w+e+b+128];var g=l-q;l+=q;var t=r[e+64]*c[d][w+e+b+64];q=r[63-e]*c[d][w+e+b+192];var D=t-q;t+=q;a-=4;v[k][a+0]=l+t;v[k][a+2]=l-t;v[k][a+1]=g+D;v[k][a+3]=g-D;l=r[e+ +1]*c[d][w+e+b+1];q=r[126-e]*c[d][w+e+b+129];g=l-q;l+=q;t=r[e+65]*c[d][w+e+b+65];q=r[62-e]*c[d][w+e+b+193];D=t-q;t+=q;v[k][a+f.BLKSIZE_s/2+0]=l+t;v[k][a+f.BLKSIZE_s/2+2]=l-t;v[k][a+f.BLKSIZE_s/2+1]=g+D;v[k][a+f.BLKSIZE_s/2+3]=g-D}while(0<=--u);x(v[k],a,f.BLKSIZE_s/2)}};this.fft_long=function(r,v,d,c,w){r=f.BLKSIZE/8-1;var a=f.BLKSIZE/2;do{var b=C[r]&255;var u=k[b]*c[d][w+b];var e=k[b+512]*c[d][w+b+512];var l=u-e;u+=e;var q=k[b+256]*c[d][w+b+256];e=k[b+768]*c[d][w+b+768];var g=q-e;q+=e;a-=4;v[a+0]= +u+q;v[a+2]=u-q;v[a+1]=l+g;v[a+3]=l-g;u=k[b+1]*c[d][w+b+1];e=k[b+513]*c[d][w+b+513];l=u-e;u+=e;q=k[b+257]*c[d][w+b+257];e=k[b+769]*c[d][w+b+769];g=q-e;q+=e;v[a+f.BLKSIZE/2+0]=u+q;v[a+f.BLKSIZE/2+2]=u-q;v[a+f.BLKSIZE/2+1]=l+g;v[a+f.BLKSIZE/2+3]=l-g}while(0<=--r);x(v,a,f.BLKSIZE/2)};this.init_fft=function(u){for(u=0;ua)if(b=b*n)return a+b;g=a/b}a+=b;if(6>=f+3){if(g>=m)return a;f=0|Z.FAST_LOG10_X(g,16);return a*p[f]}f=0|Z.FAST_LOG10_X(g,16);b=0!=e?d.ATH.cb_s[c]*d.ATH.adjust:d.ATH.cb_l[c]*d.ATH.adjust;return ab?(c=1,13>=f&&(c=A[f]),b=Z.FAST_LOG10_X(a/b,10/15),a*((h[f]-c)*b+c)):13a&&(a=0);0>b&&(b=0);if(0>= +a)return b;if(0>=b)return a;var f=b>a?b/a:a/b;if(-2<=c&&2>=c){if(f>=m)return a+b;c=0|Z.FAST_LOG10_X(f,16);return(a+b)*y[c]}if(f=m){++h;break}k=a.PSY.bo_s_weight[h];m=1-k;p=k*b[g];k*=c[g];a.en[d].s[h][e]+=p;a.thm[d].s[h][e]+=k;p=m*b[g];k=m*c[g]}for(;h=l){++e;break}p=a.PSY.bo_l_weight[e];l=1-p;g=p*b[h];p*=c[h];a.en[d].l[e]+=g;a.thm[d].l[e]+=p;g=l*b[h];p=l*c[h]}for(;e=c?b:0e;e++){var h=a.thm.s[d][e];if(0h&&(c=g>1E10*h?c+23.02585092994046*O[d]:c+O[d]*Z.FAST_LOG10(g/h))}}return c}function d(a,b){for(var c=281.0575,d=0;de&&(c=h>1E10*e?c+23.02585092994046*F[d]:c+F[d]*Z.FAST_LOG10(h/e))}}return c}function c(a,b,c,d,f){var e,h;for(e=h=0;ef&&(g=f);d[e]=g}else d[e]=0;for(e=1;ef&&(g=f),d[e]=g):d[e]=0;h=c[e-1]+c[e];0f&&(g=f),d[e]=g):d[e]=0}function a(a,b,c,e,d,f,h){var g= +2*f;d=0m&&(k=m);p>q&&(p=q);b[2][l]=k;b[3][l]=p}}function b(a,b){a=0<=a?27*-a:a*b;return-72>=a?0:Math.exp(.2302585093*a)}function B(a){0> +a&&(a=0);a*=.001;return 13*Math.atan(.76*a)+3.5*Math.atan(a*a/56.25)}function e(a,b,c,e,d,h,g,p,k,l,m,q){var A=G(f.CBANDS+1),r=p/(15B(p*w)-y&&w<=k/2;w++);a[n]=w-u;for(Q=n+1;uk/2){u=k/2;++n;break}}A[n]=p*u;for(y=0;yn&&(n=0),w=0|Math.floor(.5+m*(u-.5)),w>k/2&&(w=k/2),c[y]=(t[n]+t[w])/2,b[y]=t[w],g[y]=(r*u-A[b[y]])/(A[b[y]+ +1]-A[b[y]]),0>g[y]?g[y]=0:1=m){var q=m-.5;q=8*(q*q-2*q)}else q=0;m+=.474;m=15.811389+7.5*m-17.5*Math.sqrt(1+m*m);-60>=m?q=0:(m=Math.exp(.2302585093* +(q+m)),q=m/.6609193);m=q*d[g];p[l][g]=m*h[l]}else for(g=0;g=n;++n)A=m+n*(r-m)/1E3,A=b(A,l),t+=A;A=1001/(t*(r-m));for(l=0;la&&(a=3410);a=Math.max(.1,a/1E3);return 3.64*Math.pow(a,-.8)-6.8*Math.exp(-.6*Math.pow(a-3.4,2))+6*Math.exp(-.15*Math.pow(a-8.7,2))+.001*(.6+.04*b)*Math.pow(a,4)}var t=new Jc,D=1/217621504/(f.BLKSIZE/2),m,n,z,E=[1,.79433,.63096,.63096,.63096,.63096,.63096,.25119,.11749],h=[3.3246* +3.3246,3.23837*3.23837,9.9500500969,9.0247369744,8.1854926609,7.0440875649,2.46209*2.46209,2.284*2.284,4.4892710641,1.96552*1.96552,1.82335*1.82335,1.69146*1.69146,2.4621061921,2.1508568964,1.37074*1.37074,1.31036*1.31036,1.5691069696,1.4555939904,1.16203*1.16203,1.2715945225,1.09428*1.09428,1.0659*1.0659,1.0779838276,1.0382591025,1],p=[1.7782755904,1.35879*1.35879,1.38454*1.38454,1.39497*1.39497,1.40548*1.40548,1.3537*1.3537,1.6999465924,1.22321*1.22321,1.3169398564,1],A=[5.5396212496,2.29259*2.29259, +4.9868695969,2.12675*2.12675,2.02545*2.02545,1.87894*1.87894,1.74303*1.74303,1.61695*1.61695,2.2499700001,1.39148*1.39148,1.29083*1.29083,1.19746*1.19746,1.2339655056,1.0779838276],y=[1.7782755904,1.35879*1.35879,1.38454*1.38454,1.39497*1.39497,1.40548*1.40548,1.3537*1.3537,1.6999465924,1.22321*1.22321,1.3169398564,1],O=[11.8,13.6,17.2,32,46.5,51.3,57.5,67.1,71.5,84.6,97.6,130],F=[6.8,5.8,5.8,6.4,6.5,9.9,12.1,14.4,15,18.9,21.6,26.9,34.2,40.2,46.8,56.5,60.7,73.9,85.7,93.4,126.1],R=[-1.730326E-17,-.01703172, +-1.349528E-17,.0418072,-6.73278E-17,-.0876324,-3.0835E-17,.1863476,-1.104424E-16,-.627638];this.L3psycho_anal_ns=function(a,b,e,h,g,p,l,m,q,A){var r,n=a.internal_flags,y=ha([2,f.BLKSIZE]),Q=ha([2,3,f.BLKSIZE_s]),I=G(f.CBANDS+1),H=G(f.CBANDS+1),V=G(f.CBANDS+2),O=U(2),D=U(2),z,M,B,X,F,N,K,la=ha([2,576]),S=U(f.CBANDS+2),ca=U(f.CBANDS+2);qa.fill(ca,0);var fa=n.channels_out;a.mode==ka.JOINT_STEREO&&(fa=4);var T=a.VBR==J.vbr_off?0==n.ResvMax?0:n.ResvSize/n.ResvMax*.5:a.VBR==J.vbr_rh||a.VBR==J.vbr_mtrh|| +a.VBR==J.vbr_mt?.6:1;for(z=0;zB;B++){var ba;var ia=Qa[L+B+10];for(X=ba=0;9>X;X+=2)ia+=R[X]*(Qa[L+B+X]+Qa[L+B+21-X]),ba+=R[X+1]*(Qa[L+B+X+1]+Qa[L+B+21-X-1]);la[z][B]=ia+ba}g[h][z].en.assign(n.en[z]);g[h][z].thm.assign(n.thm[z]);2B;B++)Ka[B]=n.nsPsy.last_en_subshort[z][B+6],Da[B]=Ka[B]/n.nsPsy.last_en_subshort[z][B+4],da[0]+=Ka[B];if(2==z)for(B=0;576>B;B++){var za=la[0][B];var Ub=la[1][B];la[0][B]=za+Ub;la[1][B]=za-Ub}var Za=la[z&1],bc=0;for(B=0;9>B;B++){var Ua=bc+64;for(r=1;bcKa[B+3-2]?r/Ka[B+3-2]:Ka[B+3-2]>10*r?Ka[B+3-2]/(10*r):0;Da[B+3]=r}if(a.analysis){var Fa=Da[0];for(B=1;12>B;B++)FaB;B++)0==ya[B/3]&&Da[B]>sb&&(ya[B/3]=B%3+1);for(B=1;4>B;B++)1.7>(da[B-1]>da[B]?da[B-1]/da[B]:da[B]/da[B-1])&&(ya[B]=0,1==B&&(ya[0]=0));0!=ya[0]&&0!=n.nsPsy.lastAttacks[z]&&(ya[0]=0);if(3==n.nsPsy.lastAttacks[z]||0!=ya[0]+ya[1]+ya[2]+ya[3])Y=0,0!=ya[1]&&0!=ya[0]&&(ya[1]=0),0!=ya[2]&&0!=ya[1]&&(ya[2]=0),0!=ya[3]&&0!=ya[2]&&(ya[3]=0);2>z?D[z]=Y:0==Y&&(D[0]=D[1]=0);q[z]=n.tot_ener[z];var ub=void 0, +Vb=void 0,ob=void 0,P=void 0,jc=a,Ia=xa,Gb=ma,Ra=y,La=z&1,Ma=Q,Sa=z&1,va=h,Na=z,fb=b,gb=e,Va=jc.internal_flags;if(2>Na)t.fft_long(Va,Ra[La],Na,fb,gb),t.fft_short(Va,Ma[Sa],Na,fb,gb);else if(2==Na){for(var ja=f.BLKSIZE-1;0<=ja;--ja)ub=Ra[La+0][ja],Vb=Ra[La+1][ja],Ra[La+0][ja]=(ub+Vb)*Z.SQRT2*.5,Ra[La+1][ja]=(ub-Vb)*Z.SQRT2*.5;for(var Ca=2;0<=Ca;--Ca)for(ja=f.BLKSIZE_s-1;0<=ja;--ja)ub=Ma[Sa+0][Ca][ja],Vb=Ma[Sa+1][Ca][ja],Ma[Sa+0][Ca][ja]=(ub+Vb)*Z.SQRT2*.5,Ma[Sa+1][Ca][ja]=(ub-Vb)*Z.SQRT2*.5}Ia[0]= +Ra[La+0][0];Ia[0]*=Ia[0];for(ja=f.BLKSIZE/2-1;0<=ja;--ja)ob=Ra[La+0][f.BLKSIZE/2-ja],P=Ra[La+0][f.BLKSIZE/2+ja],Ia[f.BLKSIZE/2-ja]=.5*(ob*ob+P*P);for(Ca=2;0<=Ca;--Ca)for(Gb[Ca][0]=Ma[Sa+0][Ca][0],Gb[Ca][0]*=Gb[Ca][0],ja=f.BLKSIZE_s/2-1;0<=ja;--ja)ob=Ma[Sa+0][Ca][f.BLKSIZE_s/2-ja],P=Ma[Sa+0][Ca][f.BLKSIZE_s/2+ja],Gb[Ca][f.BLKSIZE_s/2-ja]=.5*(ob*ob+P*P);for(var rb=0,ja=11;jaNa&&(Va.loudness_sq[va][Na]=Va.loudness_sq_save[Na],Va.loudness_sq_save[Na]=x(Ia,Va));c(n,xa,I,ac,ra);w(n,ac,ra,S);for(K=0;3>K;K++){for(var Hb,aa,sa=void 0,ta=void 0,Wb=void 0,Ab=ma,Ta=H,$a=V,vb=z,Fb=K,Ga=a.internal_flags,sa=ta=0;sakb;kb++)oa=Oa.thm[0].s[Aa][kb],Jb= +Oa.thm[1].s[Aa][kb],Oa.thm[0].s[Aa][kb]+=Jb*Cb,Oa.thm[1].s[Aa][kb]+=oa*Cb}}if(a.mode==ka.JOINT_STEREO){for(var Db,Kb,Ja,Xa,ea=0;ea1.58*n.thm[1].l[ea]||n.thm[1].l[ea]>1.58*n.thm[0].l[ea]||(Xa=n.mld_l[ea]*n.en[3].l[ea],Ja=Math.max(n.thm[2].l[ea],Math.min(n.thm[3].l[ea],Xa)),Xa=n.mld_l[ea]*n.en[2].l[ea],Kb=Math.max(n.thm[3].l[ea],Math.min(n.thm[2].l[ea],Xa)),n.thm[2].l[ea]=Ja,n.thm[3].l[ea]=Kb);for(ea=0;eaBa;Ba++)n.thm[0].s[ea][Ba]>1.58*n.thm[1].s[ea][Ba]|| +n.thm[1].s[ea][Ba]>1.58*n.thm[0].s[ea][Ba]||(Xa=n.mld_s[ea]*n.en[3].s[ea][Ba],Ja=Math.max(n.thm[2].s[ea][Ba],Math.min(n.thm[3].s[ea][Ba],Xa)),Xa=n.mld_s[ea]*n.en[2].s[ea][Ba],Kb=Math.max(n.thm[3].s[ea][Ba],Math.min(n.thm[2].s[ea][Ba],Xa)),n.thm[2].s[ea][Ba]=Ja,n.thm[3].s[ea][Ba]=Kb);Db=a.msfix;if(0mb;mb++)bb=n.ATH.cb_s[n.bm_s[wa]]*lb,Eb=Math.min(Math.max(n.thm[0].s[wa][mb],bb),Math.max(n.thm[1].s[wa][mb],bb)),db=Math.max(n.thm[2].s[wa][mb],bb),cb=Math.max(n.thm[3].s[wa][mb],bb),Eb*LbL;L++){var ba; +var ia=firbuf[Qa+L+10];for(var da=ba=0;9>da;da+=2)ia+=X[da]*(firbuf[Qa+L+da]+firbuf[Qa+L+21-da]),ba+=X[da+1]*(firbuf[Qa+L+da+1]+firbuf[Qa+L+21-da-1]);la[T][L]=ia+ba}p[g][T].en.assign(S.en[T]);p[g][T].thm.assign(S.thm[T]);2L;L++)Da[L]=S.nsPsy.last_en_subshort[T][L+6],Y[L]=Da[L]/S.nsPsy.last_en_subshort[T][L+4],ra[0]+=Da[L];for(L=0;9>L;L++){for(var za=qa+64,Za=1;qaDa[L+3-2]?Za/Da[L+3-2]:Da[L+3-2]>10*Za?Da[L+3-2]/(10*Za):0;Y[L+3]=Za}for(L=0;3>L;++L){var Ua=Da[3*L+3]+Da[3*L+4]+Da[3*L+5],Ub=1;6*Da[3*L+5]L;L++)fb< +Y[L]&&(fb=Y[L]);S.pinfo.ers[g][T]=S.pinfo.ers_save[T];S.pinfo.ers_save[T]=fb}for(L=0;12>L;L++)0==N[T][L/3]&&Y[L]>ya&&(N[T][L/3]=L%3+1);for(L=1;4>L;L++){var gb=ra[L-1],ub=ra[L];4E4>Math.max(gb,ub)&&gb<1.7*ub&&ub<1.7*gb&&(1==L&&N[T][0]<=N[T][L]&&(N[T][0]=0),N[T][L]=0)}N[T][0]<=S.nsPsy.lastAttacks[T]&&(N[T][0]=0);if(3==S.nsPsy.lastAttacks[T]||0!=N[T][0]+N[T][1]+N[T][2]+N[T][3])ma=0,0!=N[T][1]&&0!=N[T][0]&&(N[T][1]=0),0!=N[T][2]&&0!=N[T][1]&&(N[T][2]=0),0!=N[T][3]&&0!=N[T][2]&&(N[T][3]=0);2>T?K[T]=ma: +0==ma&&(K[0]=K[1]=0);n[T]=S.tot_ener[T]}var sb=b.internal_flags;b.short_blocks!=pa.short_block_coupled||0!=K[0]&&0!=K[1]||(K[0]=K[1]=0);for(var ob=0;obIa)t.fft_long(Sa,La[Ma],Ia,e,h);else if(2==Ia)for(var va=f.BLKSIZE-1;0<=va;--va){var Na=La[Ma+0][va],tb=La[Ma+1][va];La[Ma+0][va]=(Na+tb)* +Z.SQRT2*.5;La[Ma+1][va]=(Na-tb)*Z.SQRT2*.5}Ra[0]=La[Ma+0][0];Ra[0]*=Ra[0];for(va=f.BLKSIZE/2-1;0<=va;--va){var zb=La[Ma+0][f.BLKSIZE/2-va],Va=La[Ma+0][f.BLKSIZE/2+va];Ra[f.BLKSIZE/2-va]=.5*(zb*zb+Va*Va)}for(var ja=0,va=11;vaCa&& +(Hb.loudness_sq[g][Ca]=Hb.loudness_sq_save[Ca],Hb.loudness_sq_save[Ca]=x(Fb,Hb));if(0!=K[Q]){var aa=void 0,sa=void 0,ta=z,Wb=V,Ab=M[P],Ta=R[P],$a=P,vb=G(f.CBANDS),Tb=G(f.CBANDS),Ga=U(f.CBANDS+2);c(ta,Wb,Ab,vb,Tb);w(ta,vb,Tb,Ga);for(var Ib=0,aa=0;aa=Qb&&(Qb=ab);0>=jb&&(jb=ab);sa=ta.blocktype_old[$a&1]==f.NORM_TYPE?Math.min(jb,Qb):jb;Ta[aa]=Math.min(ab,sa)}ta.nb_2[$a][aa]=ta.nb_1[$a][aa];ta.nb_1[$a][aa]=ab;ib=vb[aa];ib*=ta.minval_l[aa];ib*=xb;Ta[aa]>ib&&(Ta[aa]=ib);1Ab[aa]&&(Ta[aa]=Ab[aa]);1>ta.masking_lower&& +(Ta[aa]*=ta.masking_lower)}for(;aaoa;oa++){for(P=0;PKb&&t.fft_short(Lb,ea[Ba],Kb,e,h);if(2==Kb)for(var Ha=f.BLKSIZE_s-1;0<=Ha;--Ha){var bb=ea[Ba+0][Ja][Ha],cb=ea[Ba+1][Ja][Ha];ea[Ba+0][Ja][Ha]=(bb+cb)*Z.SQRT2*.5;ea[Ba+1][Ja][Ha]=(bb-cb)*Z.SQRT2*.5}Xa[Ja][0]=ea[Ba+0][Ja][0];Xa[Ja][0]*=Xa[Ja][0];for(Ha=f.BLKSIZE_s/2-1;0<=Ha;--Ha){var db=ea[Ba+0][Ja][f.BLKSIZE_s/2-Ha],Eb=ea[Ba+0][Ja][f.BLKSIZE_s/2+Ha];Xa[Ja][f.BLKSIZE_s/2-Ha]=.5*(db*db+Eb*Eb)}for(var ga=void 0,lb=void 0,wa=void 0,mb=I,Wa=M[P],ua=R[P], +Mb=P,cc=oa,Ea=b.internal_flags,Nb=new float[f.CBANDS],kc=G(f.CBANDS),dc=new int[f.CBANDS],ga=lb=0;gaYb&& +(nb=Yb),Xb[na]=nb):Xb[na]=0;for(na=1;naYb&&(nb=Yb),Xb[na]=nb):Xb[na]=0;Pa=Rb[na-1]+Rb[na];0Yb&&(nb=Yb),Xb[na]=nb):Xb[na]=0;for(lb=ga=0;gaZb&&(ua[ga]=Zb);1Wa[ga]&&(ua[ga]=Wa[ga]);1>Ea.masking_lower&&(ua[ga]*=Ea.masking_lower)}for(;gaoa;oa++){var eb=z.thm[P].s[Sb][oa],eb=.8*eb;if(2<=N[P][oa]||1==N[P][oa+1])y=0!=oa?oa-1:2,A=u(z.thm[P].s[Sb][y],eb,.36),eb=Math.min(eb,A);else if(1==N[P][oa])y=0!=oa?oa-1:2,A=u(z.thm[P].s[Sb][y],eb,.18),eb=Math.min(eb,A);else if(0!=oa&&3==N[P][oa- +1]||0==oa&&3==z.nsPsy.lastAttacks[P])y=2!=oa?oa+1:0,A=u(z.thm[P].s[Sb][y],eb,.18),eb=Math.min(eb,A);eb*=F[P][oa];vc[oa]=eb}for(oa=0;3>oa;oa++)z.thm[P].s[Sb][oa]=vc[oa]}for(P=0;Ph;++h){for(var v=0;vv;++v){for(c=0;cv;v++)d.nsPsy.last_en_subshort[h][v]=10}d.loudness_sq_save[0]=d.loudness_sq_save[1]=0;d.npart_l=e(d.numlines_l,d.bo_l,d.bm_l,u,y,d.mld_l,d.PSY.bo_l_weight,x,f.BLKSIZE,d.scalefac_band.l,f.BLKSIZE/1152,f.SBMAX_l);for(h=0;h=p&&(c=k*(u[h]-p)/(24-p)+b*(24-u[h])/(24-p)),w[h]=Math.pow(10,c/10),d.rnumlines_l[h]=0b&&(k=b);d.ATH.cb_l[h]=k;k=-20+20*u[h]/10;6k&&(k=-15);k-=8;d.minval_l[h]=Math.pow(10,k/10)*d.numlines_l[h]}d.npart_s=e(d.numlines_s,d.bo_s,d.bm_s,u,y,d.mld_s,d.PSY.bo_s_weight,x,f.BLKSIZE_s,d.scalefac_band.s,f.BLKSIZE_s/384,f.SBMAX_s);for(h=v=0;h=p&&(c=r*(u[h]-p)/(24-p)+A*(24-u[h])/(24-p));w[h]=Math.pow(10,c/10);k=sb.MAX_VALUE;for(c=0;cb&&(k=b);d.ATH.cb_s[h]=k;k=-7+7*u[h]/12;12u[h]&&(k*=1+2.3*Math.log(1-k));-15>k&&(k=-15);k-=8;d.minval_s[h]=Math.pow(10,k/10)*d.numlines_s[h]}d.s3_ss=l(d.s3ind_s,d.npart_s,u,y,w,g);m=Math.pow(10,.5625);n=Math.pow(10,1.5);z=Math.pow(10,1.5);t.init_fft(d);d.decay=Math.exp(-2.302585092994046/(.01*x/192));h=3.5;0!=(a.exp_nspsytune&2)&&(h=1);0 +d.npart_l-1&&(d.s3ind[g][1]=d.npart_l-1);d.ATH.decay=Math.pow(10,576*d.mode_gr/x*-1.2);d.ATH.adjust=.01;d.ATH.adjustLimit=1;if(-1!=a.ATHtype){v=a.out_samplerate/f.BLKSIZE;for(h=b=g=0;h=a?1:Math.cos(Math.PI/2*a)}function C(a,b){switch(a){case 44100:return b.version=1,0;case 48E3:return b.version=1;case 32E3:return b.version=1,2;case 22050:return b.version=0;case 24E3:return b.version=0,1;case 16E3:return b.version=0,2;case 11025:return b.version=0;case 12E3:return b.version=0,1;case 8E3:return b.version=0,2;default:return b.version= +0,-1}}function u(a,b,c){16E3>c&&(b=2);c=v.bitrate_table[b][1];for(var d=2;14>=d;d++)0c&&(b=2);for(c=0;14>=c;c++)if(0y)return y;r+=y;p+=y;u[0]=g;u[1]=k;if(da.NEQ(d.scale,0)&&da.NEQ(d.scale,1))for(y= +0;yD.resample_ratio|| +1.0001ia.BPC&&(ra=ia.BPC);var pa=1E-4>Math.abs(Y.resample_ratio-Math.floor(.5+Y.resample_ratio))?1:0;var qa=1/Y.resample_ratio;1za&&(za=0);1Math.abs(Ka)?Ua/Math.PI:za*Math.sin(ma*Ua*Ka)/(Math.PI*ma*Ka))}for(F=0;F<=ma;F++)Y.blackfilt[ha][F]/=xa}Y.fill_buffer_resample_init=1}xa=Y.inbuf_old[ka];for(qa=0;qa=ba)break;T=F-Y.itime[ka]-(ha+ma%2*.5);T=0|Math.floor(2*T*ra+ra+.5);for(F=Fa=0;F<=ma;++F)L=F+ha-ma/2,Fa+=(0>L?xa[pa+L]:U[Z+L])*Y.blackfilt[T][F];J[S+qa]=Fa}fa.num_used=Math.min(ba,ma+ha-ma/2);Y.itime[ka]+=fa.num_used-qa*Y.resample_ratio;if(fa.num_used>=pa)for(F=0;Fh.mf_samples_to_encode&&(h.mf_samples_to_encode=f.ENCDELAY+f.POSTDELAY);h.mf_samples_to_encode+=y;if(h.mf_size>=g){x=t-p;0==t&&(x=0);y=d;x=e.enc.lame_encode_mp3_frame(y,A[0],A[1],n,r,x);y.frameNum++;y=x;if(0>y)return y; +r+=y;p+=y;h.mf_size-=d.framesize;h.mf_samples_to_encode-=d.framesize;for(x=0;xf;f++)if(Math.max(a,b[f+ +1])!=a){c=b[f+1];d=f+1;e=b[f];h=f;break}return c-a>a-e?h:d};this.lame_init_params=function(a){var b=a.internal_flags;b.Class_ID=0;null==b.ATH&&(b.ATH=new zc);null==b.PSY&&(b.PSY=new x);null==b.rgdata&&(b.rgdata=new Cc);b.channels_in=a.num_channels;1==b.channels_in&&(a.mode=ka.MONO);b.channels_out=a.mode==ka.MONO?1:2;b.mode_ext=f.MPG_MD_MS_LR;a.mode==ka.MONO&&(a.force_ms=!1);a.VBR==J.vbr_off&&128!=a.VBR_mean_bitrate_kbps&&0==a.brate&&(a.brate=a.VBR_mean_bitrate_kbps);a.VBR!=J.vbr_off&&a.VBR!=J.vbr_mtrh&& +a.VBR!=J.vbr_mt&&(a.free_format=!1);a.VBR==J.vbr_off&&0==a.brate&&da.EQ(a.compression_ratio,0)&&(a.compression_ratio=11.025);a.VBR==J.vbr_off&&0a.out_samplerate?(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps, +8),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,64)):32E3>a.out_samplerate?(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps,8),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,160)):(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps,32),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,320)));if(0==a.lowpassfreq){switch(a.VBR){case J.vbr_off:var c=new k;d(c,a.brate);c=c.lowerlimit;break;case J.vbr_abr:c=new k;d(c,a.VBR_mean_bitrate_kbps);c=c.lowerlimit;break; +case J.vbr_rh:var e=[19500,19E3,18600,18E3,17500,16E3,15600,14900,12500,1E4,3950];if(0<=a.VBR_q&&9>=a.VBR_q){c=e[a.VBR_q];var h=e[a.VBR_q+1];e=a.VBR_q_frac;c=linear_int(c,h,e)}else c=19500;break;default:e=[19500,19E3,18500,18E3,17500,16500,15500,14500,12500,9500,3950],0<=a.VBR_q&&9>=a.VBR_q?(c=e[a.VBR_q],h=e[a.VBR_q+1],e=a.VBR_q_frac,c=linear_int(c,h,e)):c=19500}a.mode!=ka.MONO||a.VBR!=J.vbr_off&&a.VBR!=J.vbr_abr||(c*=1.5);a.lowpassfreq=c|0}0==a.out_samplerate&&(2*a.lowpassfreq>a.in_samplerate&&(a.lowpassfreq= +a.in_samplerate/2),c=a.lowpassfreq|0,e=a.in_samplerate,h=44100,48E3<=e?h=48E3:44100<=e?h=44100:32E3<=e?h=32E3:24E3<=e?h=24E3:22050<=e?h=22050:16E3<=e?h=16E3:12E3<=e?h=12E3:11025<=e?h=11025:8E3<=e&&(h=8E3),-1==c?c=h:(15960>=c&&(h=44100),15250>=c&&(h=32E3),11220>=c&&(h=24E3),9970>=c&&(h=22050),7230>=c&&(h=16E3),5420>=c&&(h=12E3),4510>=c&&(h=11025),3970>=c&&(h=8E3),c=e=a.out_samplerate?1:2;a.framesize=576*b.mode_gr;a.encoder_delay=f.ENCDELAY;b.resample_ratio=a.in_samplerate/a.out_samplerate;switch(a.VBR){case J.vbr_mt:case J.vbr_rh:case J.vbr_mtrh:a.compression_ratio=[5.7,6.5,7.3,8.2,10,11.9,13,14,15,16.5][a.VBR_q];break;case J.vbr_abr:a.compression_ratio=16*a.out_samplerate* +b.channels_out/(1E3*a.VBR_mean_bitrate_kbps);break;default:a.compression_ratio=16*a.out_samplerate*b.channels_out/(1E3*a.brate)}a.mode==ka.NOT_SET&&(a.mode=ka.JOINT_STEREO);0b.lowpass1&&(b.lowpass1=0)):b.lowpass1=2*a.lowpassfreq,b.lowpass1/=a.out_samplerate,b.lowpass2/=a.out_samplerate):(b.lowpass1=0,b.lowpass2=0);c=a.internal_flags;var r=32,w=-1;if(0=e;e++)h=e/31,h>=c.lowpass2&&(r=Math.min(r,e)),c.lowpass1=e;e++)h=e/31,h<=c.highpass1&&(w=Math.max(w,e)),c.highpass1e;e++)h=e/31,w=c.highpass2>c.highpass1?K((c.highpass2-h)/(c.highpass2-c.highpass1+1E-20)):1,h=c.lowpass2>c.lowpass1?K((h-c.lowpass1)/(c.lowpass2-c.lowpass1+1E-20)):1,c.amp_filter[e]=w*h;b.samplerate_index=C(a.out_samplerate,a);if(0>b.samplerate_index)return a.internal_flags=null,-1;if(a.VBR==J.vbr_off)if(a.free_format)b.bitrate_index= +0;else{if(a.brate=u(a.brate,a.version,a.out_samplerate),b.bitrate_index=U(a.brate,a.version,a.out_samplerate),0>=b.bitrate_index)return a.internal_flags=null,-1}else b.bitrate_index=1;a.analysis&&(a.bWriteVbrTag=!1);null!=b.pinfo&&(a.bWriteVbrTag=!1);q.init_bit_stream_w(b);c=b.samplerate_index+3*a.version+6*(16E3>a.out_samplerate?1:0);for(e=0;ec;c++)b.nsPsy.pefirbuf[c]=700*b.mode_gr*b.channels_out;-1==a.ATHtype&&(a.ATHtype=4);switch(a.VBR){case J.vbr_mt:a.VBR=J.vbr_mtrh;case J.vbr_mtrh:null==a.useTemporal&&(a.useTemporal=!1);g.apply_preset(a,500-10*a.VBR_q,0);0>a.quality&&(a.quality=LAME_DEFAULT_QUALITY);5>a.quality&&(a.quality=0);5a.quality&&(a.quality=LAME_DEFAULT_QUALITY);b.iteration_loop=new VBROldIterationLoop(D);break;default:b.sfb21_extra=!1,0>a.quality&&(a.quality= +LAME_DEFAULT_QUALITY),c=a.VBR,c==J.vbr_off&&(a.VBR_mean_bitrate_kbps=a.brate),g.apply_preset(a,a.VBR_mean_bitrate_kbps,0),a.VBR=c,b.PSY.mask_adjust=a.maskingadjust,b.PSY.mask_adjust_short=a.maskingadjust_short,b.iteration_loop=c==J.vbr_off?new Bc(D):new ABRIterationLoop(D)}if(a.VBR!=J.vbr_off){b.VBR_min_bitrate=1;b.VBR_max_bitrate=14;16E3>a.out_samplerate&&(b.VBR_max_bitrate=8);if(0!=a.VBR_min_bitrate_kbps&&(a.VBR_min_bitrate_kbps=u(a.VBR_min_bitrate_kbps,a.version,a.out_samplerate),b.VBR_min_bitrate= +U(a.VBR_min_bitrate_kbps,a.version,a.out_samplerate),0>b.VBR_min_bitrate)||0!=a.VBR_max_bitrate_kbps&&(a.VBR_max_bitrate_kbps=u(a.VBR_max_bitrate_kbps,a.version,a.out_samplerate),b.VBR_max_bitrate=U(a.VBR_max_bitrate_kbps,a.version,a.out_samplerate),0>b.VBR_max_bitrate))return-1;a.VBR_min_bitrate_kbps=v.bitrate_table[a.version][b.VBR_min_bitrate];a.VBR_max_bitrate_kbps=v.bitrate_table[a.version][b.VBR_max_bitrate];a.VBR_mean_bitrate_kbps=Math.min(v.bitrate_table[a.version][b.VBR_max_bitrate],a.VBR_mean_bitrate_kbps); +a.VBR_mean_bitrate_kbps=Math.max(v.bitrate_table[a.version][b.VBR_min_bitrate],a.VBR_mean_bitrate_kbps)}a.tune&&(b.PSY.mask_adjust+=a.tune_value_a,b.PSY.mask_adjust_short+=a.tune_value_a);c=a.internal_flags;switch(a.quality){default:case 9:c.psymodel=0;c.noise_shaping=0;c.noise_shaping_amp=0;c.noise_shaping_stop=0;c.use_best_huffman=0;c.full_outer_loop=0;break;case 8:a.quality=7;case 7:c.psymodel=1;c.noise_shaping=0;c.noise_shaping_amp=0;c.noise_shaping_stop=0;c.use_best_huffman=0;c.full_outer_loop= +0;break;case 6:c.psymodel=1;0==c.noise_shaping&&(c.noise_shaping=1);c.noise_shaping_amp=0;c.noise_shaping_stop=0;-1==c.subblock_gain&&(c.subblock_gain=1);c.use_best_huffman=0;c.full_outer_loop=0;break;case 5:c.psymodel=1;0==c.noise_shaping&&(c.noise_shaping=1);c.noise_shaping_amp=0;c.noise_shaping_stop=0;-1==c.subblock_gain&&(c.subblock_gain=1);c.use_best_huffman=0;c.full_outer_loop=0;break;case 4:c.psymodel=1;0==c.noise_shaping&&(c.noise_shaping=1);c.noise_shaping_amp=0;c.noise_shaping_stop=0;-1== +c.subblock_gain&&(c.subblock_gain=1);c.use_best_huffman=1;c.full_outer_loop=0;break;case 3:c.psymodel=1;0==c.noise_shaping&&(c.noise_shaping=1);c.noise_shaping_amp=1;c.noise_shaping_stop=1;-1==c.subblock_gain&&(c.subblock_gain=1);c.use_best_huffman=1;c.full_outer_loop=0;break;case 2:c.psymodel=1;0==c.noise_shaping&&(c.noise_shaping=1);0==c.substep_shaping&&(c.substep_shaping=2);c.noise_shaping_amp=1;c.noise_shaping_stop=1;-1==c.subblock_gain&&(c.subblock_gain=1);c.use_best_huffman=1;c.full_outer_loop= +0;break;case 1:c.psymodel=1;0==c.noise_shaping&&(c.noise_shaping=1);0==c.substep_shaping&&(c.substep_shaping=2);c.noise_shaping_amp=2;c.noise_shaping_stop=1;-1==c.subblock_gain&&(c.subblock_gain=1);c.use_best_huffman=1;c.full_outer_loop=0;break;case 0:c.psymodel=1,0==c.noise_shaping&&(c.noise_shaping=1),0==c.substep_shaping&&(c.substep_shaping=2),c.noise_shaping_amp=2,c.noise_shaping_stop=1,-1==c.subblock_gain&&(c.subblock_gain=1),c.use_best_huffman=1,c.full_outer_loop=0}b.ATH.useAdjust=0>a.athaa_type? +3:a.athaa_type;b.ATH.aaSensitivityP=Math.pow(10,a.athaa_sensitivity/-10);null==a.short_blocks&&(a.short_blocks=pa.short_block_allowed);a.short_blocks!=pa.short_block_allowed||a.mode!=ka.JOINT_STEREO&&a.mode!=ka.STEREO||(a.short_blocks=pa.short_block_coupled);0>a.quant_comp&&(a.quant_comp=1);0>a.quant_comp_short&&(a.quant_comp_short=0);0>a.msfix&&(a.msfix=0);a.exp_nspsytune|=1;0>a.internal_flags.nsPsy.attackthre&&(a.internal_flags.nsPsy.attackthre=$b.NSATTACKTHRE);0>a.internal_flags.nsPsy.attackthre_s&& +(a.internal_flags.nsPsy.attackthre_s=$b.NSATTACKTHRE_S);0>a.scale&&(a.scale=1);0>a.ATHtype&&(a.ATHtype=4);0>a.ATHcurve&&(a.ATHcurve=4);0>a.athaa_loudapprox&&(a.athaa_loudapprox=2);0>a.interChRatio&&(a.interChRatio=0);null==a.useTemporal&&(a.useTemporal=!0);b.slot_lag=b.frac_SpF=0;a.VBR==J.vbr_off&&(b.slot_lag=b.frac_SpF=72E3*(a.version+1)*a.brate%a.out_samplerate|0);t.iteration_init(a);m.psymodel_init(a);return 0};this.lame_encode_flush=function(a,b,d,e){var g=a.internal_flags,h=fc([2,1152]),k=0, +l=g.mf_samples_to_encode-f.POSTDELAY,m=c(a);if(1>g.mf_samples_to_encode)return 0;var n=0;a.in_samplerate!=a.out_samplerate&&(l+=16*a.out_samplerate/a.in_samplerate);var p=a.framesize-l%a.framesize;576>p&&(p+=a.framesize);a.encoder_padding=p;for(p=(l+p)/a.framesize;0r&&(r=1);k=e-n;0==e&&(k=0);k=this.lame_encode_buffer(a,h[0],h[1],r,b,d,k);d+=k;n+=k;p-=l!=a.frameNum?1:0}g.mf_samples_to_encode=0;if(0> +k)return k;k=e-n;0==e&&(k=0);q.flush_bitstream(a);k=q.copy_buffer(g,b,d,k,1);if(0>k)return k;d+=k;n+=k;k=e-n;0==e&&(k=0);if(a.write_id3tag_automatic){z.id3tag_write_v1(a);k=q.copy_buffer(g,b,d,k,0);if(0>k)return k;n+=k}return n};this.lame_encode_buffer=function(a,b,c,d,e,f,g){var h=a.internal_flags,k=[null,null];if(4294479419!=h.Class_ID)return-3;if(0==d)return 0;if(null==h.in_buffer_0||h.in_buffer_nsamplesMath.abs(k)?Math.abs(f-k)<=1E-6*Math.abs(f):Math.abs(f-k)<=1E-6*Math.abs(k)};da.NEQ=function(f,k){return!da.EQ(f,k)};var v={t1HB:[1,1,1,0],t2HB:[1,2,1,3,1,1,3,2,0],t3HB:[3,2,1,1,1,1,3,2,0],t5HB:[1,2,6,5,3,1,4,4,7,5,7,1,6,1,1,0],t6HB:[7,3,5,1,6,2,3,2,5,4,4,1,3,3,2,0],t7HB:[1,2,10,19,16,10,3,3,7,10,5,3,11,4,13,17,8,4,12,11,18,15,11,2,7,6,9,14,3,1,6,4,5,3,2,0],t8HB:[3,4,6,18,12,5,5,1,2,16,9,3,7,3,5,14,7,3,19,17,15,13, +10,4,13,5,8,11,5,1,12,4,4,1,1,0],t9HB:[7,5,9,14,15,7,6,4,5,5,6,7,7,6,8,8,8,5,15,6,9,10,5,1,11,7,9,6,4,1,14,4,6,2,6,0],t10HB:[1,2,10,23,35,30,12,17,3,3,8,12,18,21,12,7,11,9,15,21,32,40,19,6,14,13,22,34,46,23,18,7,20,19,33,47,27,22,9,3,31,22,41,26,21,20,5,3,14,13,10,11,16,6,5,1,9,8,7,8,4,4,2,0],t11HB:[3,4,10,24,34,33,21,15,5,3,4,10,32,17,11,10,11,7,13,18,30,31,20,5,25,11,19,59,27,18,12,5,35,33,31,58,30,16,7,5,28,26,32,19,17,15,8,14,14,12,9,13,14,9,4,1,11,4,6,6,6,3,2,0],t12HB:[9,6,16,33,41,39,38,26, +7,5,6,9,23,16,26,11,17,7,11,14,21,30,10,7,17,10,15,12,18,28,14,5,32,13,22,19,18,16,9,5,40,17,31,29,17,13,4,2,27,12,11,15,10,7,4,1,27,12,8,12,6,3,1,0],t13HB:[1,5,14,21,34,51,46,71,42,52,68,52,67,44,43,19,3,4,12,19,31,26,44,33,31,24,32,24,31,35,22,14,15,13,23,36,59,49,77,65,29,40,30,40,27,33,42,16,22,20,37,61,56,79,73,64,43,76,56,37,26,31,25,14,35,16,60,57,97,75,114,91,54,73,55,41,48,53,23,24,58,27,50,96,76,70,93,84,77,58,79,29,74,49,41,17,47,45,78,74,115,94,90,79,69,83,71,50,59,38,36,15,72,34,56,95, +92,85,91,90,86,73,77,65,51,44,43,42,43,20,30,44,55,78,72,87,78,61,46,54,37,30,20,16,53,25,41,37,44,59,54,81,66,76,57,54,37,18,39,11,35,33,31,57,42,82,72,80,47,58,55,21,22,26,38,22,53,25,23,38,70,60,51,36,55,26,34,23,27,14,9,7,34,32,28,39,49,75,30,52,48,40,52,28,18,17,9,5,45,21,34,64,56,50,49,45,31,19,12,15,10,7,6,3,48,23,20,39,36,35,53,21,16,23,13,10,6,1,4,2,16,15,17,27,25,20,29,11,17,12,16,8,1,1,0,1],t15HB:[7,12,18,53,47,76,124,108,89,123,108,119,107,81,122,63,13,5,16,27,46,36,61,51,42,70,52,83, +65,41,59,36,19,17,15,24,41,34,59,48,40,64,50,78,62,80,56,33,29,28,25,43,39,63,55,93,76,59,93,72,54,75,50,29,52,22,42,40,67,57,95,79,72,57,89,69,49,66,46,27,77,37,35,66,58,52,91,74,62,48,79,63,90,62,40,38,125,32,60,56,50,92,78,65,55,87,71,51,73,51,70,30,109,53,49,94,88,75,66,122,91,73,56,42,64,44,21,25,90,43,41,77,73,63,56,92,77,66,47,67,48,53,36,20,71,34,67,60,58,49,88,76,67,106,71,54,38,39,23,15,109,53,51,47,90,82,58,57,48,72,57,41,23,27,62,9,86,42,40,37,70,64,52,43,70,55,42,25,29,18,11,11,118,68, +30,55,50,46,74,65,49,39,24,16,22,13,14,7,91,44,39,38,34,63,52,45,31,52,28,19,14,8,9,3,123,60,58,53,47,43,32,22,37,24,17,12,15,10,2,1,71,37,34,30,28,20,17,26,21,16,10,6,8,6,2,0],t16HB:[1,5,14,44,74,63,110,93,172,149,138,242,225,195,376,17,3,4,12,20,35,62,53,47,83,75,68,119,201,107,207,9,15,13,23,38,67,58,103,90,161,72,127,117,110,209,206,16,45,21,39,69,64,114,99,87,158,140,252,212,199,387,365,26,75,36,68,65,115,101,179,164,155,264,246,226,395,382,362,9,66,30,59,56,102,185,173,265,142,253,232,400,388, +378,445,16,111,54,52,100,184,178,160,133,257,244,228,217,385,366,715,10,98,48,91,88,165,157,148,261,248,407,397,372,380,889,884,8,85,84,81,159,156,143,260,249,427,401,392,383,727,713,708,7,154,76,73,141,131,256,245,426,406,394,384,735,359,710,352,11,139,129,67,125,247,233,229,219,393,743,737,720,885,882,439,4,243,120,118,115,227,223,396,746,742,736,721,712,706,223,436,6,202,224,222,218,216,389,386,381,364,888,443,707,440,437,1728,4,747,211,210,208,370,379,734,723,714,1735,883,877,876,3459,865,2,377, +369,102,187,726,722,358,711,709,866,1734,871,3458,870,434,0,12,10,7,11,10,17,11,9,13,12,10,7,5,3,1,3],t24HB:[15,13,46,80,146,262,248,434,426,669,653,649,621,517,1032,88,14,12,21,38,71,130,122,216,209,198,327,345,319,297,279,42,47,22,41,74,68,128,120,221,207,194,182,340,315,295,541,18,81,39,75,70,134,125,116,220,204,190,178,325,311,293,271,16,147,72,69,135,127,118,112,210,200,188,352,323,306,285,540,14,263,66,129,126,119,114,214,202,192,180,341,317,301,281,262,12,249,123,121,117,113,215,206,195,185, +347,330,308,291,272,520,10,435,115,111,109,211,203,196,187,353,332,313,298,283,531,381,17,427,212,208,205,201,193,186,177,169,320,303,286,268,514,377,16,335,199,197,191,189,181,174,333,321,305,289,275,521,379,371,11,668,184,183,179,175,344,331,314,304,290,277,530,383,373,366,10,652,346,171,168,164,318,309,299,287,276,263,513,375,368,362,6,648,322,316,312,307,302,292,284,269,261,512,376,370,364,359,4,620,300,296,294,288,282,273,266,515,380,374,369,365,361,357,2,1033,280,278,274,267,264,259,382,378, +372,367,363,360,358,356,0,43,20,19,17,15,13,11,9,7,6,4,7,5,3,1,3],t32HB:[1,10,8,20,12,20,16,32,14,12,24,0,28,16,24,16],t33HB:[15,28,26,48,22,40,36,64,14,24,20,32,12,16,8,0],t1l:[1,4,3,5],t2l:[1,4,7,4,5,7,6,7,8],t3l:[2,3,7,4,4,7,6,7,8],t5l:[1,4,7,8,4,5,8,9,7,8,9,10,8,8,9,10],t6l:[3,4,6,8,4,4,6,7,5,6,7,8,7,7,8,9],t7l:[1,4,7,9,9,10,4,6,8,9,9,10,7,7,9,10,10,11,8,9,10,11,11,11,8,9,10,11,11,12,9,10,11,12,12,12],t8l:[2,4,7,9,9,10,4,4,6,10,10,10,7,6,8,10,10,11,9,10,10,11,11,12,9,9,10,11,12,12,10,10,11,11, +13,13],t9l:[3,4,6,7,9,10,4,5,6,7,8,10,5,6,7,8,9,10,7,7,8,9,9,10,8,8,9,9,10,11,9,9,10,10,11,11],t10l:[1,4,7,9,10,10,10,11,4,6,8,9,10,11,10,10,7,8,9,10,11,12,11,11,8,9,10,11,12,12,11,12,9,10,11,12,12,12,12,12,10,11,12,12,13,13,12,13,9,10,11,12,12,12,13,13,10,10,11,12,12,13,13,13],t11l:[2,4,6,8,9,10,9,10,4,5,6,8,10,10,9,10,6,7,8,9,10,11,10,10,8,8,9,11,10,12,10,11,9,10,10,11,11,12,11,12,9,10,11,12,12,13,12,13,9,9,9,10,11,12,12,12,9,9,10,11,12,12,12,12],t12l:[4,4,6,8,9,10,10,10,4,5,6,7,9,9,10,10,6,6,7, +8,9,10,9,10,7,7,8,8,9,10,10,10,8,8,9,9,10,10,10,11,9,9,10,10,10,11,10,11,9,9,9,10,10,11,11,12,10,10,10,11,11,11,11,12],t13l:[1,5,7,8,9,10,10,11,10,11,12,12,13,13,14,14,4,6,8,9,10,10,11,11,11,11,12,12,13,14,14,14,7,8,9,10,11,11,12,12,11,12,12,13,13,14,15,15,8,9,10,11,11,12,12,12,12,13,13,13,13,14,15,15,9,9,11,11,12,12,13,13,12,13,13,14,14,15,15,16,10,10,11,12,12,12,13,13,13,13,14,13,15,15,16,16,10,11,12,12,13,13,13,13,13,14,14,14,15,15,16,16,11,11,12,13,13,13,14,14,14,14,15,15,15,16,18,18,10,10,11, +12,12,13,13,14,14,14,14,15,15,16,17,17,11,11,12,12,13,13,13,15,14,15,15,16,16,16,18,17,11,12,12,13,13,14,14,15,14,15,16,15,16,17,18,19,12,12,12,13,14,14,14,14,15,15,15,16,17,17,17,18,12,13,13,14,14,15,14,15,16,16,17,17,17,18,18,18,13,13,14,15,15,15,16,16,16,16,16,17,18,17,18,18,14,14,14,15,15,15,17,16,16,19,17,17,17,19,18,18,13,14,15,16,16,16,17,16,17,17,18,18,21,20,21,18],t15l:[3,5,6,8,8,9,10,10,10,11,11,12,12,12,13,14,5,5,7,8,9,9,10,10,10,11,11,12,12,12,13,13,6,7,7,8,9,9,10,10,10,11,11,12,12,13, +13,13,7,8,8,9,9,10,10,11,11,11,12,12,12,13,13,13,8,8,9,9,10,10,11,11,11,11,12,12,12,13,13,13,9,9,9,10,10,10,11,11,11,11,12,12,13,13,13,14,10,9,10,10,10,11,11,11,11,12,12,12,13,13,14,14,10,10,10,11,11,11,11,12,12,12,12,12,13,13,13,14,10,10,10,11,11,11,11,12,12,12,12,13,13,14,14,14,10,10,11,11,11,11,12,12,12,13,13,13,13,14,14,14,11,11,11,11,12,12,12,12,12,13,13,13,13,14,15,14,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,15,12,12,11,12,12,12,13,13,13,13,13,13,14,14,15,15,12,12,12,12,12,13,13,13,13,14, +14,14,14,14,15,15,13,13,13,13,13,13,13,13,14,14,14,14,15,15,14,15,13,13,13,13,13,13,13,14,14,14,14,14,15,15,15,15],t16_5l:[1,5,7,9,10,10,11,11,12,12,12,13,13,13,14,11,4,6,8,9,10,11,11,11,12,12,12,13,14,13,14,11,7,8,9,10,11,11,12,12,13,12,13,13,13,14,14,12,9,9,10,11,11,12,12,12,13,13,14,14,14,15,15,13,10,10,11,11,12,12,13,13,13,14,14,14,15,15,15,12,10,10,11,11,12,13,13,14,13,14,14,15,15,15,16,13,11,11,11,12,13,13,13,13,14,14,14,14,15,15,16,13,11,11,12,12,13,13,13,14,14,15,15,15,15,17,17,13,11,12,12, +13,13,13,14,14,15,15,15,15,16,16,16,13,12,12,12,13,13,14,14,15,15,15,15,16,15,16,15,14,12,13,12,13,14,14,14,14,15,16,16,16,17,17,16,13,13,13,13,13,14,14,15,16,16,16,16,16,16,15,16,14,13,14,14,14,14,15,15,15,15,17,16,16,16,16,18,14,15,14,14,14,15,15,16,16,16,18,17,17,17,19,17,14,14,15,13,14,16,16,15,16,16,17,18,17,19,17,16,14,11,11,11,12,12,13,13,13,14,14,14,14,14,14,14,12],t16l:[1,5,7,9,10,10,11,11,12,12,12,13,13,13,14,10,4,6,8,9,10,11,11,11,12,12,12,13,14,13,14,10,7,8,9,10,11,11,12,12,13,12,13,13, +13,14,14,11,9,9,10,11,11,12,12,12,13,13,14,14,14,15,15,12,10,10,11,11,12,12,13,13,13,14,14,14,15,15,15,11,10,10,11,11,12,13,13,14,13,14,14,15,15,15,16,12,11,11,11,12,13,13,13,13,14,14,14,14,15,15,16,12,11,11,12,12,13,13,13,14,14,15,15,15,15,17,17,12,11,12,12,13,13,13,14,14,15,15,15,15,16,16,16,12,12,12,12,13,13,14,14,15,15,15,15,16,15,16,15,13,12,13,12,13,14,14,14,14,15,16,16,16,17,17,16,12,13,13,13,13,14,14,15,16,16,16,16,16,16,15,16,13,13,14,14,14,14,15,15,15,15,17,16,16,16,16,18,13,15,14,14,14, +15,15,16,16,16,18,17,17,17,19,17,13,14,15,13,14,16,16,15,16,16,17,18,17,19,17,16,13,10,10,10,11,11,12,12,12,13,13,13,13,13,13,13,10],t24l:[4,5,7,8,9,10,10,11,11,12,12,12,12,12,13,10,5,6,7,8,9,10,10,11,11,11,12,12,12,12,12,10,7,7,8,9,9,10,10,11,11,11,11,12,12,12,13,9,8,8,9,9,10,10,10,11,11,11,11,12,12,12,12,9,9,9,9,10,10,10,10,11,11,11,12,12,12,12,13,9,10,9,10,10,10,10,11,11,11,11,12,12,12,12,12,9,10,10,10,10,10,11,11,11,11,12,12,12,12,12,13,9,11,10,10,10,11,11,11,11,12,12,12,12,12,13,13,10,11,11, +11,11,11,11,11,11,11,12,12,12,12,13,13,10,11,11,11,11,11,11,11,12,12,12,12,12,13,13,13,10,12,11,11,11,11,12,12,12,12,12,12,13,13,13,13,10,12,12,11,11,11,12,12,12,12,12,12,13,13,13,13,10,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,10,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,10,13,12,12,12,12,12,12,13,13,13,13,13,13,13,13,10,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,6],t32l:[1,5,5,7,5,8,7,9,5,7,7,9,7,9,9,10],t33l:[4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8]};v.ht=[new ba(0,0,null,null),new ba(2,0,v.t1HB,v.t1l),new ba(3, +0,v.t2HB,v.t2l),new ba(3,0,v.t3HB,v.t3l),new ba(0,0,null,null),new ba(4,0,v.t5HB,v.t5l),new ba(4,0,v.t6HB,v.t6l),new ba(6,0,v.t7HB,v.t7l),new ba(6,0,v.t8HB,v.t8l),new ba(6,0,v.t9HB,v.t9l),new ba(8,0,v.t10HB,v.t10l),new ba(8,0,v.t11HB,v.t11l),new ba(8,0,v.t12HB,v.t12l),new ba(16,0,v.t13HB,v.t13l),new ba(0,0,null,v.t16_5l),new ba(16,0,v.t15HB,v.t15l),new ba(1,1,v.t16HB,v.t16l),new ba(2,3,v.t16HB,v.t16l),new ba(3,7,v.t16HB,v.t16l),new ba(4,15,v.t16HB,v.t16l),new ba(6,63,v.t16HB,v.t16l),new ba(8,255, +v.t16HB,v.t16l),new ba(10,1023,v.t16HB,v.t16l),new ba(13,8191,v.t16HB,v.t16l),new ba(4,15,v.t24HB,v.t24l),new ba(5,31,v.t24HB,v.t24l),new ba(6,63,v.t24HB,v.t24l),new ba(7,127,v.t24HB,v.t24l),new ba(8,255,v.t24HB,v.t24l),new ba(9,511,v.t24HB,v.t24l),new ba(11,2047,v.t24HB,v.t24l),new ba(13,8191,v.t24HB,v.t24l),new ba(0,0,v.t32HB,v.t32l),new ba(0,0,v.t33HB,v.t33l)];v.largetbl=[65540,327685,458759,589832,655369,655370,720906,720907,786443,786444,786444,851980,851980,851980,917517,655370,262149,393222, +524295,589832,655369,720906,720906,720907,786443,786443,786444,851980,917516,851980,917516,655370,458759,524295,589832,655369,720905,720906,786442,786443,851979,786443,851979,851980,851980,917516,917517,720905,589832,589832,655369,720905,720906,786442,786442,786443,851979,851979,917515,917516,917516,983052,983052,786441,655369,655369,720905,720906,786442,786442,851978,851979,851979,917515,917516,917516,983052,983052,983053,720905,655370,655369,720906,720906,786442,851978,851979,917515,851979,917515, +917516,983052,983052,983052,1048588,786441,720906,720906,720906,786442,851978,851979,851979,851979,917515,917516,917516,917516,983052,983052,1048589,786441,720907,720906,786442,786442,851979,851979,851979,917515,917516,983052,983052,983052,983052,1114125,1114125,786442,720907,786443,786443,851979,851979,851979,917515,917515,983051,983052,983052,983052,1048588,1048589,1048589,786442,786443,786443,786443,851979,851979,917515,917515,983052,983052,983052,983052,1048588,983053,1048589,983053,851978,786444, +851979,786443,851979,917515,917516,917516,917516,983052,1048588,1048588,1048589,1114125,1114125,1048589,786442,851980,851980,851979,851979,917515,917516,983052,1048588,1048588,1048588,1048588,1048589,1048589,983053,1048589,851978,851980,917516,917516,917516,917516,983052,983052,983052,983052,1114124,1048589,1048589,1048589,1048589,1179661,851978,983052,917516,917516,917516,983052,983052,1048588,1048588,1048589,1179661,1114125,1114125,1114125,1245197,1114125,851978,917517,983052,851980,917516,1048588, +1048588,983052,1048589,1048589,1114125,1179661,1114125,1245197,1114125,1048589,851978,655369,655369,655369,720905,720905,786441,786441,786441,851977,851977,851977,851978,851978,851978,851978,655366];v.table23=[65538,262147,458759,262148,327684,458759,393222,458759,524296];v.table56=[65539,262148,458758,524296,262148,327684,524294,589831,458757,524294,589831,655368,524295,524295,589832,655369];v.bitrate_table=[[0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,-1],[0,32,40,48,56,64,80,96,112,128,160, +192,224,256,320,-1],[0,8,16,24,32,40,48,56,64,-1,-1,-1,-1,-1,-1,-1]];v.samplerate_table=[[22050,24E3,16E3,-1],[44100,48E3,32E3,-1],[11025,12E3,8E3,-1]];v.scfsi_band=[0,6,11,16,21];Y.Q_MAX=257;Y.Q_MAX2=116;Y.LARGE_BITS=1E5;Y.IXMAX_VAL=8206;var ra={};ra.SFBMAX=3*f.SBMAX_s;f.ENCDELAY=576;f.POSTDELAY=1152;f.MDCTDELAY=48;f.FFTOFFSET=224+f.MDCTDELAY;f.DECDELAY=528;f.SBLIMIT=32;f.CBANDS=64;f.SBPSY_l=21;f.SBPSY_s=12;f.SBMAX_l=22;f.SBMAX_s=13;f.PSFB21=6;f.PSFB12=6;f.BLKSIZE=1024;f.HBLKSIZE=f.BLKSIZE/2+1;f.BLKSIZE_s= +256;f.HBLKSIZE_s=f.BLKSIZE_s/2+1;f.NORM_TYPE=0;f.START_TYPE=1;f.SHORT_TYPE=2;f.STOP_TYPE=3;f.MPG_MD_LR_LR=0;f.MPG_MD_LR_I=1;f.MPG_MD_MS_LR=2;f.MPG_MD_MS_I=3;f.fircoef=[-.1039435,-.1892065,-.0432472*5,-.155915,3.898045E-17,.0467745*5,.50455,.756825,.187098*5];ia.MFSIZE=3456+f.ENCDELAY-f.MDCTDELAY;ia.MAX_HEADER_BUF=256;ia.MAX_BITS_PER_CHANNEL=4095;ia.MAX_BITS_PER_GRANULE=7680;ia.BPC=320;xa.RIFF=zb("RIFF");xa.WAVE=zb("WAVE");xa.fmt_=zb("fmt ");xa.data=zb("data");xa.readHeader=function(f){var k=new xa, +r=f.getUint32(0,!1);if(xa.RIFF==r&&(f.getUint32(4,!0),xa.WAVE==f.getUint32(8,!1)&&xa.fmt_==f.getUint32(12,!1))){var v=f.getUint32(16,!0),x=20;switch(v){case 16:case 18:k.channels=f.getUint16(x+2,!0);k.sampleRate=f.getUint32(x+4,!0);break;default:throw"extended fmt chunk not implemented";}for(var x=x+v,v=xa.data,u=0;v!=r;){r=f.getUint32(x,!1);u=f.getUint32(x+4,!0);if(v==r)break;x+=u+8}k.dataLen=u;k.dataOffset=x+8;return k}};ra.SFBMAX=3*f.SBMAX_s;lamejs.Mp3Encoder=function(f,k,r){3!=arguments.length&& +(console.error("WARN: Mp3Encoder(channels, samplerate, kbps) not specified"),f=1,k=44100,r=128);var v=new W,x=new Kc,u=new ca,G=new da,d=new wc,c=new Y,w=new Ec,a=new gb,b=new ic,B=new Nc,e=new xc,l=new fb,q=new Lc,g=new Mc;v.setModules(u,G,d,c,w,a,b,B,g);G.setModules(u,g,b,a);B.setModules(G,b);d.setModules(v);w.setModules(G,e,c,l);c.setModules(l,e,v.enc.psy);e.setModules(G);l.setModules(c);a.setModules(v,G,b);x.setModules(q,g);q.setModules(b,B,d);var t=v.lame_init();t.num_channels=f;t.in_samplerate= +k;t.brate=r;t.mode=ka.STEREO;t.quality=3;t.bWriteVbrTag=!1;t.disable_reservoir=!0;t.write_id3tag_automatic=!1;v.lame_init_params(t);var D=1152,m=0|1.25*D+7200,n=new Int8Array(m);this.encodeBuffer=function(a,b){1==f&&(b=a);a.length>D&&(D=a.length,m=0|1.25*D+7200,n=new Int8Array(m));a=v.lame_encode_buffer(t,a,b,a.length,n,0,m);return new Int8Array(n.subarray(0,a))};this.flush=function(){var a=v.lame_encode_flush(t,n,0,m);return new Int8Array(n.subarray(0,a))}};lamejs.WavHeader=xa}lamejs(); diff --git a/makeall.sh b/makeall.sh index a129cd6..c9c2bc2 100644 --- a/makeall.sh +++ b/makeall.sh @@ -1,6 +1,6 @@ ( echo 'function lamejs() {' -browserify --list src/js/lametest.js | grep lamejs | grep -v node_modules | xargs cat | grep -v -e 'common\..*;' -e 'require(' -e 'module.exports.*;$' | sed 's/^module.exports = {/var module_exports = {/'; +browserify --list src/js/index.js | grep lamejs | grep -v node_modules | xargs cat | grep -v -e 'common\..*;' -e 'require(' -e 'module.exports.*;$' | sed 's/^module.exports = {/var module_exports = {/'; echo 'L3Side.SFBMAX = (Encoder.SBMAX_s * 3);' echo '//testFullLength();' echo 'lamejs.Mp3Encoder = Mp3Encoder;' diff --git a/package.json b/package.json index 34e3df6..4987ea1 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,13 @@ "name": "lamejs", "version": "1.1.0", "description": "Pure JavaScript MP3 Encoder", - "main": "src/js/lametest.js", + "main": "src/js/index.js", "directories": { "doc": "doc", "test": "test" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 0" + "test": "node src/js/Tests.js" }, "repository": { "type": "git", diff --git a/src/js/Tests.js b/src/js/Tests.js new file mode 100644 index 0000000..e65e23c --- /dev/null +++ b/src/js/Tests.js @@ -0,0 +1,84 @@ +var fs = require("fs"); +var path = require("path") +var common = require("./common.js"); + +var lamejs = require("./index"); + +var WavHeader = lamejs.WavHeader; +var Mp3Encoder = lamejs.Mp3Encoder; + +var assert = common.assert; + +function testFullLength() { + var r = fs.readFileSync(path.join("testdata", "Left44100.wav")); + var sampleBuf = new Uint8Array(r).buffer; + var w = WavHeader.readHeader(new DataView(sampleBuf)); + var samples = new Int16Array(sampleBuf, w.dataOffset, w.dataLen / 2); + var remaining = samples.length; + var lameEnc = new Mp3Encoder(); //w.channels, w.sampleRate, 128); + var maxSamples = 1152; + + var fd = fs.openSync(path.join("testdata", "testjs2.mp3"), "w"); + var time = new Date().getTime(); + for (var i = 0; remaining >= maxSamples; i += maxSamples) { + var left = samples.subarray(i, i + maxSamples); + var right = samples.subarray(i, i + maxSamples); + + var mp3buf = lameEnc.encodeBuffer(left, right); + if (mp3buf.length > 0) { + fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); + } + remaining -= maxSamples; + } + var mp3buf = lameEnc.flush(); + if (mp3buf.length > 0) { + fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); + } + fs.closeSync(fd); + time = new Date().getTime() - time; + console.log('done in ' + time + 'msec'); +} + +function testStereo44100() { + var r1 = fs.readFileSync(path.join("testdata", "Left44100.wav")); + var r2 = fs.readFileSync(path.join("testdata", "Right44100.wav")); + var fd = fs.openSync(path.join("testdata", "stereo.mp3"), "w"); + + var sampleBuf1 = new Uint8Array(r1).buffer; + var sampleBuf2 = new Uint8Array(r2).buffer; + var w1 = WavHeader.readHeader(new DataView(sampleBuf1)); + var w2 = WavHeader.readHeader(new DataView(sampleBuf2)); + + var samples1 = new Int16Array(sampleBuf1, w1.dataOffset, w1.dataLen / 2); + var samples2 = new Int16Array(sampleBuf2, w2.dataOffset, w2.dataLen / 2); + var remaining1 = samples1.length; + var remaining2 = samples2.length; + assert(remaining1 == remaining2); + assert(w1.sampleRate == w2.sampleRate); + + var lameEnc = new Mp3Encoder(2, w1.sampleRate, 128); + var maxSamples = 1152; + + var time = new Date().getTime(); + for (var i = 0; remaining1 >= maxSamples; i += maxSamples) { + var left = samples1.subarray(i, i + maxSamples); + var right = samples2.subarray(i, i + maxSamples); + + var mp3buf = lameEnc.encodeBuffer(left, right); + if (mp3buf.length > 0) { + fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); + } + remaining1 -= maxSamples; + + } + var mp3buf = lameEnc.flush(); + if (mp3buf.length > 0) { + fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); + } + fs.closeSync(fd); + time = new Date().getTime() - time; + console.log('done in ' + time + 'msec'); +} + +testStereo44100(); +testFullLength(); \ No newline at end of file diff --git a/src/js/lametest.js b/src/js/index.js similarity index 66% rename from src/js/lametest.js rename to src/js/index.js index a0847e7..7539d66 100644 --- a/src/js/lametest.js +++ b/src/js/index.js @@ -1,6 +1,3 @@ -require('use-strict'); - -fs = require('fs'); var common = require('./common.js'); var System = common.System; var VbrMode = common.VbrMode; @@ -178,7 +175,6 @@ WavHeader.readHeader = function (dataView) { break; default: throw 'extended fmt chunk not implemented'; - break; } pos += fmtLen; var data = WavHeader.data; @@ -196,79 +192,5 @@ WavHeader.readHeader = function (dataView) { return w; }; -function testFullLength() { - var r = fs.readFileSync("testdata/IMG_0373.wav"); - var sampleBuf = new Uint8Array(r).buffer; - var w = WavHeader.readHeader(new DataView(sampleBuf)); - var samples = new Int16Array(sampleBuf, w.dataOffset, w.dataLen / 2); - var remaining = samples.length; - var lameEnc = new Mp3Encoder(); //w.channels, w.sampleRate, 128); - var maxSamples = 1152; - - var fd = fs.openSync("testjs2.mp3", "w"); - var time = new Date().getTime(); - for (var i = 0; remaining >= maxSamples; i += maxSamples) { - var left = samples.subarray(i, i + maxSamples); - var right = samples.subarray(i, i + maxSamples); - - var mp3buf = lameEnc.encodeBuffer(left, right); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - remaining -= maxSamples; - } - var mp3buf = lameEnc.flush(); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - fs.closeSync(fd); - time = new Date().getTime() - time; - console.log('done in ' + time + 'msec'); -} - -function testStereo44100() { - var r1 = fs.readFileSync("testdata/Left44100.wav"); - var r2 = fs.readFileSync("testdata/Right44100.wav"); - var fd = fs.openSync("stereo.mp3", "w"); - - var sampleBuf1 = new Uint8Array(r1).buffer; - var sampleBuf2 = new Uint8Array(r2).buffer; - var w1 = WavHeader.readHeader(new DataView(sampleBuf1)); - var w2 = WavHeader.readHeader(new DataView(sampleBuf2)); - - var samples1 = new Int16Array(sampleBuf1, w1.dataOffset, w1.dataLen / 2); - var samples2 = new Int16Array(sampleBuf2, w2.dataOffset, w2.dataLen / 2); - var remaining1 = samples1.length; - var remaining2 = samples2.length; - assert(remaining1 == remaining2); - assert(w1.sampleRate == w2.sampleRate); - - var lameEnc = new Mp3Encoder(2, w1.sampleRate, 128); - var maxSamples = 1152; - - var time = new Date().getTime(); - for (var i = 0; remaining1 >= maxSamples; i += maxSamples) { - var left = samples1.subarray(i, i + maxSamples); - var right = samples2.subarray(i, i + maxSamples); - - var mp3buf = lameEnc.encodeBuffer(left, right); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - remaining1 -= maxSamples; - - } - var mp3buf = lameEnc.flush(); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - fs.closeSync(fd); - time = new Date().getTime() - time; - console.log('done in ' + time + 'msec'); -} - -//testStereo44100(); -//testFullLength(); - module.exports.Mp3Encoder = Mp3Encoder; module.exports.WavHeader = WavHeader;