- var common = require('./common.js');
- var System = common.System;
- var VbrMode = common.VbrMode;
- var Float = common.Float;
- var ShortBlock = common.ShortBlock;
- var Util = common.Util;
- var Arrays = common.Arrays;
- var new_array_n = common.new_array_n;
- var new_byte = common.new_byte;
- var new_double = common.new_double;
- var new_float = common.new_float;
- var new_float_n = common.new_float_n;
- var new_int = common.new_int;
- var new_int_n = common.new_int_n;
- var assert = common.assert;
-
- /**
- * ENCDELAY The encoder delay.
- *
- * Minimum allowed is MDCTDELAY (see below)
- *
- * The first 96 samples will be attenuated, so using a value less than 96
- * will result in corrupt data for the first 96-ENCDELAY samples.
- *
- * suggested: 576 set to 1160 to sync with FhG.
- */
- Encoder.ENCDELAY = 576;
- /**
- * make sure there is at least one complete frame after the last frame
- * containing real data
- *
- * Using a value of 288 would be sufficient for a a very sophisticated
- * decoder that can decode granule-by-granule instead of frame by frame. But
- * lets not assume this, and assume the decoder will not decode frame N
- * unless it also has data for frame N+1
- */
- Encoder.POSTDELAY = 1152;
-
- /**
- * delay of the MDCT used in mdct.c original ISO routines had a delay of
- * 528! Takehiro's routines:
- */
- Encoder.MDCTDELAY = 48;
- Encoder.FFTOFFSET = (224 + Encoder.MDCTDELAY);
-
- /**
- * Most decoders, including the one we use, have a delay of 528 samples.
- */
- Encoder.DECDELAY = 528;
-
- /**
- * number of subbands
- */
- Encoder.SBLIMIT = 32;
-
- /**
- * parition bands bands
- */
- Encoder.CBANDS = 64;
-
- /**
- * number of critical bands/scale factor bands where masking is computed
- */
- Encoder.SBPSY_l = 21;
- Encoder.SBPSY_s = 12;
-
- /**
- * total number of scalefactor bands encoded
- */
- Encoder.SBMAX_l = 22;
- Encoder.SBMAX_s = 13;
- Encoder.PSFB21 = 6;
- Encoder.PSFB12 = 6;
-
- /**
- * FFT sizes
- */
- Encoder.BLKSIZE = 1024;
- Encoder.HBLKSIZE = (Encoder.BLKSIZE / 2 + 1);
- Encoder.BLKSIZE_s = 256;
- Encoder.HBLKSIZE_s = (Encoder.BLKSIZE_s / 2 + 1);
-
- Encoder.NORM_TYPE = 0;
- Encoder.START_TYPE = 1;
- Encoder.SHORT_TYPE = 2;
- Encoder.STOP_TYPE = 3;
-
- /**
- * <PRE>
- * Mode Extention:
- * When we are in stereo mode, there are 4 possible methods to store these
- * two channels. The stereo modes -m? are using a subset of them.
- *
- * -ms: MPG_MD_LR_LR
- * -mj: MPG_MD_LR_LR and MPG_MD_MS_LR
- * -mf: MPG_MD_MS_LR
- * -mi: all
- * </PRE>
- */
- Encoder.MPG_MD_LR_LR = 0;
- Encoder.MPG_MD_LR_I = 1;
- Encoder.MPG_MD_MS_LR = 2;
- Encoder.MPG_MD_MS_I = 3;
-
- Encoder.fircoef = [-0.0207887 * 5, -0.0378413 * 5,
- -0.0432472 * 5, -0.031183 * 5, 7.79609e-18 * 5, 0.0467745 * 5,
- 0.10091 * 5, 0.151365 * 5, 0.187098 * 5];
-
- function Encoder () {
- var NewMDCT = require('./NewMDCT.js');
- var III_psy_ratio = require('./III_psy_ratio.js');
- var MPEGMode = require('./MPEGMode.js');
- var FFTOFFSET = Encoder.FFTOFFSET;
- var MPG_MD_MS_LR = Encoder.MPG_MD_MS_LR;
- //BitStream bs;
- //PsyModel psy;
- //VBRTag vbr;
- //QuantizePVT qupvt;
- var bs = null;
- this.psy = null;
- var psy = null;
- var vbr = null;
- var qupvt = null;
-
- //public final void setModules(BitStream bs, PsyModel psy, QuantizePVT qupvt,
- // VBRTag vbr) {
- this.setModules = function (_bs, _psy, _qupvt, _vbr) {
- bs = _bs;
- this.psy = _psy;
- psy = _psy;
- vbr = _vbr;
- qupvt = _qupvt;
- };
-
- var newMDCT = new NewMDCT();
-
- /***********************************************************************
- *
- * encoder and decoder delays
- *
- ***********************************************************************/
-
- /**
- * <PRE>
- * layer III enc->dec delay: 1056 (1057?) (observed)
- * layer II enc->dec delay: 480 (481?) (observed)
- *
- * polyphase 256-16 (dec or enc) = 240
- * mdct 256+32 (9*32) (dec or enc) = 288
- * total: 512+16
- *
- * My guess is that delay of polyphase filterbank is actualy 240.5
- * (there are technical reasons for this, see postings in mp3encoder).
- * So total Encode+Decode delay = ENCDELAY + 528 + 1
- * </PRE>
- */
-
-
- /**
- * auto-adjust of ATH, useful for low volume Gabriel Bouvigne 3 feb 2001
- *
- * modifies some values in gfp.internal_flags.ATH (gfc.ATH)
- */
- //private void adjust_ATH(final LameInternalFlags gfc) {
- function adjust_ATH (gfc) {
- var gr2_max, max_pow;
-
- if (gfc.ATH.useAdjust == 0) {
- gfc.ATH.adjust = 1.0;
- /* no adjustment */
- return;
- }
-
- /* jd - 2001 mar 12, 27, jun 30 */
- /* loudness based on equal loudness curve; */
- /* use granule with maximum combined loudness */
- max_pow = gfc.loudness_sq[0][0];
- gr2_max = gfc.loudness_sq[1][0];
- if (gfc.channels_out == 2) {
- max_pow += gfc.loudness_sq[0][1];
- gr2_max += gfc.loudness_sq[1][1];
- } else {
- max_pow += max_pow;
- gr2_max += gr2_max;
- }
- if (gfc.mode_gr == 2) {
- max_pow = Math.max(max_pow, gr2_max);
- }
- max_pow *= 0.5;
- /* max_pow approaches 1.0 for full band noise */
-
- /* jd - 2001 mar 31, jun 30 */
- /* user tuning of ATH adjustment region */
- max_pow *= gfc.ATH.aaSensitivityP;
-
- /*
- * adjust ATH depending on range of maximum value
- */
-
- /* jd - 2001 feb27, mar12,20, jun30, jul22 */
- /* continuous curves based on approximation */
- /* to GB's original values. */
- /* For an increase in approximate loudness, */
- /* set ATH adjust to adjust_limit immediately */
- /* after a delay of one frame. */
- /* For a loudness decrease, reduce ATH adjust */
- /* towards adjust_limit gradually. */
- /* max_pow is a loudness squared or a power. */
- if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */
- if (gfc.ATH.adjust >= 1.0) {
- gfc.ATH.adjust = 1.0;
- } else {
- /* preceding frame has lower ATH adjust; */
- /* ascend only to the preceding adjust_limit */
- /* in case there is leading low volume */
- if (gfc.ATH.adjust < gfc.ATH.adjustLimit) {
- gfc.ATH.adjust = gfc.ATH.adjustLimit;
- }
- }
- gfc.ATH.adjustLimit = 1.0;
- } else { /* adjustment curve */
- /* about 32 dB maximum adjust (0.000625) */
- var adj_lim_new = 31.98 * max_pow + 0.000625;
- if (gfc.ATH.adjust >= adj_lim_new) { /* descend gradually */
- gfc.ATH.adjust *= adj_lim_new * 0.075 + 0.925;
- if (gfc.ATH.adjust < adj_lim_new) { /* stop descent */
- gfc.ATH.adjust = adj_lim_new;
- }
- } else { /* ascend */
- if (gfc.ATH.adjustLimit >= adj_lim_new) {
- gfc.ATH.adjust = adj_lim_new;
- } else {
- /* preceding frame has lower ATH adjust; */
- /* ascend only to the preceding adjust_limit */
- if (gfc.ATH.adjust < gfc.ATH.adjustLimit) {
- gfc.ATH.adjust = gfc.ATH.adjustLimit;
- }
- }
- }
- gfc.ATH.adjustLimit = adj_lim_new;
- }
- }
-
- /**
- * <PRE>
- * some simple statistics
- *
- * bitrate index 0: free bitrate . not allowed in VBR mode
- * : bitrates, kbps depending on MPEG version
- * bitrate index 15: forbidden
- *
- * mode_ext:
- * 0: LR
- * 1: LR-i
- * 2: MS
- * 3: MS-i
- * </PRE>
- */
- function updateStats (gfc) {
- var gr, ch;
- assert(0 <= gfc.bitrate_index && gfc.bitrate_index < 16);
- assert(0 <= gfc.mode_ext && gfc.mode_ext < 4);
-
- /* count bitrate indices */
- gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][4]++;
- gfc.bitrate_stereoMode_Hist[15][4]++;
-
- /* count 'em for every mode extension in case of 2 channel encoding */
- if (gfc.channels_out == 2) {
- gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][gfc.mode_ext]++;
- gfc.bitrate_stereoMode_Hist[15][gfc.mode_ext]++;
- }
- for (gr = 0; gr < gfc.mode_gr; ++gr) {
- for (ch = 0; ch < gfc.channels_out; ++ch) {
- var bt = gfc.l3_side.tt[gr][ch].block_type | 0;
- if (gfc.l3_side.tt[gr][ch].mixed_block_flag != 0)
- bt = 4;
- gfc.bitrate_blockType_Hist[gfc.bitrate_index][bt]++;
- gfc.bitrate_blockType_Hist[gfc.bitrate_index][5]++;
- gfc.bitrate_blockType_Hist[15][bt]++;
- gfc.bitrate_blockType_Hist[15][5]++;
- }
- }
- }
-
- function lame_encode_frame_init (gfp, inbuf) {
- var gfc = gfp.internal_flags;
-
- var ch, gr;
-
- if (gfc.lame_encode_frame_init == 0) {
- /* prime the MDCT/polyphase filterbank with a short block */
- var i, j;
- var primebuff0 = new_float(286 + 1152 + 576);
- var primebuff1 = new_float(286 + 1152 + 576);
- gfc.lame_encode_frame_init = 1;
- for (i = 0, j = 0; i < 286 + 576 * (1 + gfc.mode_gr); ++i) {
- if (i < 576 * gfc.mode_gr) {
- primebuff0[i] = 0;
- if (gfc.channels_out == 2)
- primebuff1[i] = 0;
- } else {
- primebuff0[i] = inbuf[0][j];
- if (gfc.channels_out == 2)
- primebuff1[i] = inbuf[1][j];
- ++j;
- }
- }
- /* polyphase filtering / mdct */
- for (gr = 0; gr < gfc.mode_gr; gr++) {
- for (ch = 0; ch < gfc.channels_out; ch++) {
- gfc.l3_side.tt[gr][ch].block_type = Encoder.SHORT_TYPE;
- }
- }
- newMDCT.mdct_sub48(gfc, primebuff0, primebuff1);
-
- /* check FFT will not use a negative starting offset */
- assert(576 >= Encoder.FFTOFFSET);
- /* check if we have enough data for FFT */
- assert(gfc.mf_size >= (Encoder.BLKSIZE + gfp.framesize - Encoder.FFTOFFSET));
- /* check if we have enough data for polyphase filterbank */
- assert(gfc.mf_size >= (512 + gfp.framesize - 32));
- }
-
- }
-
- /**
- * <PRE>
- * encodeframe() Layer 3
- *
- * encode a single frame
- *
- *
- * lame_encode_frame()
- *
- *
- * gr 0 gr 1
- * inbuf: |--------------|--------------|--------------|
- *
- *
- * Polyphase (18 windows, each shifted 32)
- * gr 0:
- * window1 <----512---.
- * window18 <----512---.
- *
- * gr 1:
- * window1 <----512---.
- * window18 <----512---.
- *
- *
- *
- * MDCT output: |--------------|--------------|--------------|
- *
- * FFT's <---------1024---------.
- * <---------1024-------.
- *
- *
- *
- * inbuf = buffer of PCM data size=MP3 framesize
- * encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY
- * so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]
- *
- * psy-model FFT has a 1 granule delay, so we feed it data for the
- * next granule.
- * FFT is centered over granule: 224+576+224
- * So FFT starts at: 576-224-MDCTDELAY
- *
- * MPEG2: FFT ends at: BLKSIZE+576-224-MDCTDELAY (1328)
- * MPEG1: FFT ends at: BLKSIZE+2*576-224-MDCTDELAY (1904)
- *
- * MPEG2: polyphase first window: [0..511]
- * 18th window: [544..1055] (1056)
- * MPEG1: 36th window: [1120..1631] (1632)
- * data needed: 512+framesize-32
- *
- * A close look newmdct.c shows that the polyphase filterbank
- * only uses data from [0..510] for each window. Perhaps because the window
- * used by the filterbank is zero for the last point, so Takehiro's
- * code doesn't bother to compute with it.
- *
- * FFT starts at 576-224-MDCTDELAY (304) = 576-FFTOFFSET
- *
- * </PRE>
- */
-
-
- this.lame_encode_mp3_frame = function (gfp, inbuf_l, inbuf_r, mp3buf, mp3bufPos, mp3buf_size) {
- var mp3count;
- var masking_LR = new_array_n([2, 2]);
- /*
- * LR masking &
- * energy
- */
- masking_LR[0][0] = new III_psy_ratio();
- masking_LR[0][1] = new III_psy_ratio();
- masking_LR[1][0] = new III_psy_ratio();
- masking_LR[1][1] = new III_psy_ratio();
- var masking_MS = new_array_n([2, 2]);
- /* MS masking & energy */
- masking_MS[0][0] = new III_psy_ratio();
- masking_MS[0][1] = new III_psy_ratio();
- masking_MS[1][0] = new III_psy_ratio();
- masking_MS[1][1] = new III_psy_ratio();
- //III_psy_ratio masking[][];
- var masking;
- /* pointer to selected maskings */
- var inbuf = [null, null];
- var gfc = gfp.internal_flags;
-
- var tot_ener = new_float_n([2, 4]);
- var ms_ener_ratio = [.5, .5];
- var pe = [[0., 0.], [0., 0.]];
- var pe_MS = [[0., 0.], [0., 0.]];
-
- //float[][] pe_use;
- var pe_use;
-
- var ch, gr;
-
- inbuf[0] = inbuf_l;
- inbuf[1] = inbuf_r;
-
- if (gfc.lame_encode_frame_init == 0) {
- /* first run? */
- lame_encode_frame_init(gfp, inbuf);
-
- }
-
- /********************** padding *****************************/
- /**
- * <PRE>
- * padding method as described in
- * "MPEG-Layer3 / Bitstream Syntax and Decoding"
- * by Martin Sieler, Ralph Sperschneider
- *
- * note: there is no padding for the very first frame
- *
- * Robert Hegemann 2000-06-22
- * </PRE>
- */
- gfc.padding = 0;
- if ((gfc.slot_lag -= gfc.frac_SpF) < 0) {
- gfc.slot_lag += gfp.out_samplerate;
- gfc.padding = 1;
- }
-
- /****************************************
- * Stage 1: psychoacoustic model *
- ****************************************/
-
- if (gfc.psymodel != 0) {
- /*
- * psychoacoustic model psy model has a 1 granule (576) delay that
- * we must compensate for (mt 6/99).
- */
- var ret;
- var bufp = [null, null];
- /* address of beginning of left & right granule */
- var bufpPos = 0;
- /* address of beginning of left & right granule */
- var blocktype = new_int(2);
-
- for (gr = 0; gr < gfc.mode_gr; gr++) {
-
- for (ch = 0; ch < gfc.channels_out; ch++) {
- bufp[ch] = inbuf[ch];
- bufpPos = 576 + gr * 576 - Encoder.FFTOFFSET;
- }
- if (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) {
- ret = psy.L3psycho_anal_vbr(gfp, bufp, bufpPos, gr,
- masking_LR, masking_MS, pe[gr], pe_MS[gr],
- tot_ener[gr], blocktype);
- } else {
- ret = psy.L3psycho_anal_ns(gfp, bufp, bufpPos, gr,
- masking_LR, masking_MS, pe[gr], pe_MS[gr],
- tot_ener[gr], blocktype);
- }
- if (ret != 0)
- return -4;
-
- if (gfp.mode == MPEGMode.JOINT_STEREO) {
- ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3];
- if (ms_ener_ratio[gr] > 0)
- ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr];
- }
-
- /* block type flags */
- for (ch = 0; ch < gfc.channels_out; ch++) {
- var cod_info = gfc.l3_side.tt[gr][ch];
- cod_info.block_type = blocktype[ch];
- cod_info.mixed_block_flag = 0;
- }
- }
- } else {
- /* no psy model */
- for (gr = 0; gr < gfc.mode_gr; gr++)
- for (ch = 0; ch < gfc.channels_out; ch++) {
- gfc.l3_side.tt[gr][ch].block_type = Encoder.NORM_TYPE;
- gfc.l3_side.tt[gr][ch].mixed_block_flag = 0;
- pe_MS[gr][ch] = pe[gr][ch] = 700;
- }
- }
-
- /* auto-adjust of ATH, useful for low volume */
- adjust_ATH(gfc);
-
- /****************************************
- * Stage 2: MDCT *
- ****************************************/
-
- /* polyphase filtering / mdct */
- newMDCT.mdct_sub48(gfc, inbuf[0], inbuf[1]);
-
- /****************************************
- * Stage 3: MS/LR decision *
- ****************************************/
-
- /* Here will be selected MS or LR coding of the 2 stereo channels */
- gfc.mode_ext = Encoder.MPG_MD_LR_LR;
-
- if (gfp.force_ms) {
- gfc.mode_ext = Encoder.MPG_MD_MS_LR;
- } else if (gfp.mode == MPEGMode.JOINT_STEREO) {
- /*
- * ms_ratio = is scaled, for historical reasons, to look like a
- * ratio of side_channel / total. 0 = signal is 100% mono .5 = L & R
- * uncorrelated
- */
-
- /**
- * <PRE>
- * [0] and [1] are the results for the two granules in MPEG-1,
- * in MPEG-2 it's only a faked averaging of the same value
- * _prev is the value of the last granule of the previous frame
- * _next is the value of the first granule of the next frame
- * </PRE>
- */
-
- var sum_pe_MS = 0.;
- var sum_pe_LR = 0.;
- for (gr = 0; gr < gfc.mode_gr; gr++) {
- for (ch = 0; ch < gfc.channels_out; ch++) {
- sum_pe_MS += pe_MS[gr][ch];
- sum_pe_LR += pe[gr][ch];
- }
- }
-
- /* based on PE: M/S coding would not use much more bits than L/R */
- if (sum_pe_MS <= 1.00 * sum_pe_LR) {
-
- var gi0 = gfc.l3_side.tt[0];
- var gi1 = gfc.l3_side.tt[gfc.mode_gr - 1];
-
- if (gi0[0].block_type == gi0[1].block_type
- && gi1[0].block_type == gi1[1].block_type) {
-
- gfc.mode_ext = Encoder.MPG_MD_MS_LR;
- }
- }
- }
-
- /* bit and noise allocation */
- if (gfc.mode_ext == MPG_MD_MS_LR) {
- masking = masking_MS;
- /* use MS masking */
- pe_use = pe_MS;
- } else {
- masking = masking_LR;
- /* use LR masking */
- pe_use = pe;
- }
-
- /* copy data for MP3 frame analyzer */
- if (gfp.analysis && gfc.pinfo != null) {
- for (gr = 0; gr < gfc.mode_gr; gr++) {
- for (ch = 0; ch < gfc.channels_out; ch++) {
- gfc.pinfo.ms_ratio[gr] = gfc.ms_ratio[gr];
- gfc.pinfo.ms_ener_ratio[gr] = ms_ener_ratio[gr];
- gfc.pinfo.blocktype[gr][ch] = gfc.l3_side.tt[gr][ch].block_type;
- gfc.pinfo.pe[gr][ch] = pe_use[gr][ch];
- System.arraycopy(gfc.l3_side.tt[gr][ch].xr, 0,
- gfc.pinfo.xr[gr][ch], 0, 576);
- /*
- * in psymodel, LR and MS data was stored in pinfo. switch
- * to MS data:
- */
- if (gfc.mode_ext == MPG_MD_MS_LR) {
- gfc.pinfo.ers[gr][ch] = gfc.pinfo.ers[gr][ch + 2];
- System.arraycopy(gfc.pinfo.energy[gr][ch + 2], 0,
- gfc.pinfo.energy[gr][ch], 0,
- gfc.pinfo.energy[gr][ch].length);
- }
- }
- }
- }
-
- /****************************************
- * Stage 4: quantization loop *
- ****************************************/
-
- if (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_abr) {
-
- var i;
- var f;
-
- for (i = 0; i < 18; i++)
- gfc.nsPsy.pefirbuf[i] = gfc.nsPsy.pefirbuf[i + 1];
-
- f = 0.0;
- for (gr = 0; gr < gfc.mode_gr; gr++)
- for (ch = 0; ch < gfc.channels_out; ch++)
- f += pe_use[gr][ch];
- gfc.nsPsy.pefirbuf[18] = f;
-
- f = gfc.nsPsy.pefirbuf[9];
- for (i = 0; i < 9; i++)
- f += (gfc.nsPsy.pefirbuf[i] + gfc.nsPsy.pefirbuf[18 - i])
- * Encoder.fircoef[i];
-
- f = (670 * 5 * gfc.mode_gr * gfc.channels_out) / f;
- for (gr = 0; gr < gfc.mode_gr; gr++) {
- for (ch = 0; ch < gfc.channels_out; ch++) {
- pe_use[gr][ch] *= f;
- }
- }
- }
- gfc.iteration_loop.iteration_loop(gfp, pe_use, ms_ener_ratio, masking);
-
- /****************************************
- * Stage 5: bitstream formatting *
- ****************************************/
-
- /* write the frame to the bitstream */
- bs.format_bitstream(gfp);
-
- /* copy mp3 bit buffer into array */
- mp3count = bs.copy_buffer(gfc, mp3buf, mp3bufPos, mp3buf_size, 1);
-
- if (gfp.bWriteVbrTag)
- vbr.addVbrFrame(gfp);
-
- if (gfp.analysis && gfc.pinfo != null) {
- for (ch = 0; ch < gfc.channels_out; ch++) {
- var j;
- for (j = 0; j < FFTOFFSET; j++)
- gfc.pinfo.pcmdata[ch][j] = gfc.pinfo.pcmdata[ch][j
- + gfp.framesize];
- for (j = FFTOFFSET; j < 1600; j++) {
- gfc.pinfo.pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET];
- }
- }
- qupvt.set_frame_pinfo(gfp, masking);
- }
-
- updateStats(gfc);
-
- return mp3count;
- }
- }
-
-
- module.exports = Encoder;