1441 |
ariadna |
1 |
function lamejs() {
|
|
|
2 |
function new_byte(count) {
|
|
|
3 |
return new Int8Array(count);
|
|
|
4 |
}
|
|
|
5 |
|
|
|
6 |
function new_short(count) {
|
|
|
7 |
return new Int16Array(count);
|
|
|
8 |
}
|
|
|
9 |
|
|
|
10 |
function new_int(count) {
|
|
|
11 |
return new Int32Array(count);
|
|
|
12 |
}
|
|
|
13 |
|
|
|
14 |
function new_float(count) {
|
|
|
15 |
return new Float32Array(count);
|
|
|
16 |
}
|
|
|
17 |
|
|
|
18 |
function new_double(count) {
|
|
|
19 |
return new Float64Array(count);
|
|
|
20 |
}
|
|
|
21 |
|
|
|
22 |
function new_float_n(args) {
|
|
|
23 |
if (args.length == 1) {
|
|
|
24 |
return new_float(args[0]);
|
|
|
25 |
}
|
|
|
26 |
var sz = args[0];
|
|
|
27 |
args = args.slice(1);
|
|
|
28 |
var A = [];
|
|
|
29 |
for (var i = 0; i < sz; i++) {
|
|
|
30 |
A.push(new_float_n(args));
|
|
|
31 |
}
|
|
|
32 |
return A;
|
|
|
33 |
}
|
|
|
34 |
function new_int_n(args) {
|
|
|
35 |
if (args.length == 1) {
|
|
|
36 |
return new_int(args[0]);
|
|
|
37 |
}
|
|
|
38 |
var sz = args[0];
|
|
|
39 |
args = args.slice(1);
|
|
|
40 |
var A = [];
|
|
|
41 |
for (var i = 0; i < sz; i++) {
|
|
|
42 |
A.push(new_int_n(args));
|
|
|
43 |
}
|
|
|
44 |
return A;
|
|
|
45 |
}
|
|
|
46 |
|
|
|
47 |
function new_short_n(args) {
|
|
|
48 |
if (args.length == 1) {
|
|
|
49 |
return new_short(args[0]);
|
|
|
50 |
}
|
|
|
51 |
var sz = args[0];
|
|
|
52 |
args = args.slice(1);
|
|
|
53 |
var A = [];
|
|
|
54 |
for (var i = 0; i < sz; i++) {
|
|
|
55 |
A.push(new_short_n(args));
|
|
|
56 |
}
|
|
|
57 |
return A;
|
|
|
58 |
}
|
|
|
59 |
|
|
|
60 |
function new_array_n(args) {
|
|
|
61 |
if (args.length == 1) {
|
|
|
62 |
return new Array(args[0]);
|
|
|
63 |
}
|
|
|
64 |
var sz = args[0];
|
|
|
65 |
args = args.slice(1);
|
|
|
66 |
var A = [];
|
|
|
67 |
for (var i = 0; i < sz; i++) {
|
|
|
68 |
A.push(new_array_n(args));
|
|
|
69 |
}
|
|
|
70 |
return A;
|
|
|
71 |
}
|
|
|
72 |
|
|
|
73 |
|
|
|
74 |
var Arrays = {};
|
|
|
75 |
|
|
|
76 |
Arrays.fill = function (a, fromIndex, toIndex, val) {
|
|
|
77 |
if (arguments.length == 2) {
|
|
|
78 |
for (var i = 0; i < a.length; i++) {
|
|
|
79 |
a[i] = arguments[1];
|
|
|
80 |
}
|
|
|
81 |
} else {
|
|
|
82 |
for (var i = fromIndex; i < toIndex; i++) {
|
|
|
83 |
a[i] = val;
|
|
|
84 |
}
|
|
|
85 |
}
|
|
|
86 |
};
|
|
|
87 |
|
|
|
88 |
var System = {};
|
|
|
89 |
|
|
|
90 |
System.arraycopy = function (src, srcPos, dest, destPos, length) {
|
|
|
91 |
var srcEnd = srcPos + length;
|
|
|
92 |
while (srcPos < srcEnd)
|
|
|
93 |
dest[destPos++] = src[srcPos++];
|
|
|
94 |
};
|
|
|
95 |
|
|
|
96 |
|
|
|
97 |
var Util = {};
|
|
|
98 |
Util.SQRT2 = 1.41421356237309504880;
|
|
|
99 |
Util.FAST_LOG10 = function (x) {
|
|
|
100 |
return Math.log10(x);
|
|
|
101 |
};
|
|
|
102 |
|
|
|
103 |
Util.FAST_LOG10_X = function (x, y) {
|
|
|
104 |
return Math.log10(x) * y;
|
|
|
105 |
};
|
|
|
106 |
|
|
|
107 |
function ShortBlock(ordinal) {
|
|
|
108 |
this.ordinal = ordinal;
|
|
|
109 |
}
|
|
|
110 |
/**
|
|
|
111 |
* LAME may use them, even different block types for L/R.
|
|
|
112 |
*/
|
|
|
113 |
ShortBlock.short_block_allowed = new ShortBlock(0);
|
|
|
114 |
/**
|
|
|
115 |
* LAME may use them, but always same block types in L/R.
|
|
|
116 |
*/
|
|
|
117 |
ShortBlock.short_block_coupled = new ShortBlock(1);
|
|
|
118 |
/**
|
|
|
119 |
* LAME will not use short blocks, long blocks only.
|
|
|
120 |
*/
|
|
|
121 |
ShortBlock.short_block_dispensed = new ShortBlock(2);
|
|
|
122 |
/**
|
|
|
123 |
* LAME will not use long blocks, short blocks only.
|
|
|
124 |
*/
|
|
|
125 |
ShortBlock.short_block_forced = new ShortBlock(3);
|
|
|
126 |
|
|
|
127 |
var Float = {};
|
|
|
128 |
Float.MAX_VALUE = 3.4028235e+38;
|
|
|
129 |
|
|
|
130 |
function VbrMode(ordinal) {
|
|
|
131 |
this.ordinal = ordinal;
|
|
|
132 |
}
|
|
|
133 |
VbrMode.vbr_off = new VbrMode(0);
|
|
|
134 |
VbrMode.vbr_mt = new VbrMode(1);
|
|
|
135 |
VbrMode.vbr_rh = new VbrMode(2);
|
|
|
136 |
VbrMode.vbr_abr = new VbrMode(3);
|
|
|
137 |
VbrMode.vbr_mtrh = new VbrMode(4);
|
|
|
138 |
VbrMode.vbr_default = VbrMode.vbr_mtrh;
|
|
|
139 |
|
|
|
140 |
var assert = function (x) {
|
|
|
141 |
//console.assert(x);
|
|
|
142 |
};
|
|
|
143 |
|
|
|
144 |
var module_exports = {
|
|
|
145 |
"System": System,
|
|
|
146 |
"VbrMode": VbrMode,
|
|
|
147 |
"Float": Float,
|
|
|
148 |
"ShortBlock": ShortBlock,
|
|
|
149 |
"Util": Util,
|
|
|
150 |
"Arrays": Arrays,
|
|
|
151 |
"new_array_n": new_array_n,
|
|
|
152 |
"new_byte": new_byte,
|
|
|
153 |
"new_double": new_double,
|
|
|
154 |
"new_float": new_float,
|
|
|
155 |
"new_float_n": new_float_n,
|
|
|
156 |
"new_int": new_int,
|
|
|
157 |
"new_int_n": new_int_n,
|
|
|
158 |
"new_short": new_short,
|
|
|
159 |
"new_short_n": new_short_n,
|
|
|
160 |
"assert": assert
|
|
|
161 |
};
|
|
|
162 |
//package mp3;
|
|
|
163 |
|
|
|
164 |
/* MPEG modes */
|
|
|
165 |
function MPEGMode(ordinal) {
|
|
|
166 |
var _ordinal = ordinal;
|
|
|
167 |
this.ordinal = function () {
|
|
|
168 |
return _ordinal;
|
|
|
169 |
}
|
|
|
170 |
}
|
|
|
171 |
|
|
|
172 |
MPEGMode.STEREO = new MPEGMode(0);
|
|
|
173 |
MPEGMode.JOINT_STEREO = new MPEGMode(1);
|
|
|
174 |
MPEGMode.DUAL_CHANNEL = new MPEGMode(2);
|
|
|
175 |
MPEGMode.MONO = new MPEGMode(3);
|
|
|
176 |
MPEGMode.NOT_SET = new MPEGMode(4);
|
|
|
177 |
|
|
|
178 |
function Version() {
|
|
|
179 |
|
|
|
180 |
/**
|
|
|
181 |
* URL for the LAME website.
|
|
|
182 |
*/
|
|
|
183 |
var LAME_URL = "http://www.mp3dev.org/";
|
|
|
184 |
|
|
|
185 |
/**
|
|
|
186 |
* Major version number.
|
|
|
187 |
*/
|
|
|
188 |
var LAME_MAJOR_VERSION = 3;
|
|
|
189 |
/**
|
|
|
190 |
* Minor version number.
|
|
|
191 |
*/
|
|
|
192 |
var LAME_MINOR_VERSION = 98;
|
|
|
193 |
/**
|
|
|
194 |
* Patch level.
|
|
|
195 |
*/
|
|
|
196 |
var LAME_PATCH_VERSION = 4;
|
|
|
197 |
|
|
|
198 |
/**
|
|
|
199 |
* Major version number.
|
|
|
200 |
*/
|
|
|
201 |
var PSY_MAJOR_VERSION = 0;
|
|
|
202 |
/**
|
|
|
203 |
* Minor version number.
|
|
|
204 |
*/
|
|
|
205 |
var PSY_MINOR_VERSION = 93;
|
|
|
206 |
|
|
|
207 |
/**
|
|
|
208 |
* A string which describes the version of LAME.
|
|
|
209 |
*
|
|
|
210 |
* @return string which describes the version of LAME
|
|
|
211 |
*/
|
|
|
212 |
this.getLameVersion = function () {
|
|
|
213 |
// primary to write screen reports
|
|
|
214 |
return (LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "." + LAME_PATCH_VERSION);
|
|
|
215 |
}
|
|
|
216 |
|
|
|
217 |
/**
|
|
|
218 |
* The short version of the LAME version string.
|
|
|
219 |
*
|
|
|
220 |
* @return short version of the LAME version string
|
|
|
221 |
*/
|
|
|
222 |
this.getLameShortVersion = function () {
|
|
|
223 |
// Adding date and time to version string makes it harder for output
|
|
|
224 |
// validation
|
|
|
225 |
return (LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "." + LAME_PATCH_VERSION);
|
|
|
226 |
}
|
|
|
227 |
|
|
|
228 |
/**
|
|
|
229 |
* The shortest version of the LAME version string.
|
|
|
230 |
*
|
|
|
231 |
* @return shortest version of the LAME version string
|
|
|
232 |
*/
|
|
|
233 |
this.getLameVeryShortVersion = function () {
|
|
|
234 |
// Adding date and time to version string makes it harder for output
|
|
|
235 |
return ("LAME" + LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "r");
|
|
|
236 |
}
|
|
|
237 |
|
|
|
238 |
/**
|
|
|
239 |
* String which describes the version of GPSYCHO
|
|
|
240 |
*
|
|
|
241 |
* @return string which describes the version of GPSYCHO
|
|
|
242 |
*/
|
|
|
243 |
this.getPsyVersion = function () {
|
|
|
244 |
return (PSY_MAJOR_VERSION + "." + PSY_MINOR_VERSION);
|
|
|
245 |
}
|
|
|
246 |
|
|
|
247 |
/**
|
|
|
248 |
* String which is a URL for the LAME website.
|
|
|
249 |
*
|
|
|
250 |
* @return string which is a URL for the LAME website
|
|
|
251 |
*/
|
|
|
252 |
this.getLameUrl = function () {
|
|
|
253 |
return LAME_URL;
|
|
|
254 |
}
|
|
|
255 |
|
|
|
256 |
/**
|
|
|
257 |
* Quite useless for a java version, however we are compatible ;-)
|
|
|
258 |
*
|
|
|
259 |
* @return "32bits"
|
|
|
260 |
*/
|
|
|
261 |
this.getLameOsBitness = function () {
|
|
|
262 |
return "32bits";
|
|
|
263 |
}
|
|
|
264 |
|
|
|
265 |
}
|
|
|
266 |
|
|
|
267 |
/*
|
|
|
268 |
* ReplayGainAnalysis - analyzes input samples and give the recommended dB change
|
|
|
269 |
* Copyright (C) 2001 David Robinson and Glen Sawyer
|
|
|
270 |
* Improvements and optimizations added by Frank Klemm, and by Marcel Muller
|
|
|
271 |
*
|
|
|
272 |
* This library is free software; you can redistribute it and/or
|
|
|
273 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
274 |
* License as published by the Free Software Foundation; either
|
|
|
275 |
* version 2.1 of the License, or (at your option) any later version.
|
|
|
276 |
*
|
|
|
277 |
* This library is distributed in the hope that it will be useful,
|
|
|
278 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
279 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
280 |
* Lesser General Public License for more details.
|
|
|
281 |
*
|
|
|
282 |
* You should have received a copy of the GNU Lesser General Public
|
|
|
283 |
* License along with this library; if not, write to the Free Software
|
|
|
284 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
285 |
*
|
|
|
286 |
* concept and filter values by David Robinson (David@Robinson.org)
|
|
|
287 |
* -- blame him if you think the idea is flawed
|
|
|
288 |
* original coding by Glen Sawyer (mp3gain@hotmail.com)
|
|
|
289 |
* -- blame him if you think this runs too slowly, or the coding is otherwise flawed
|
|
|
290 |
*
|
|
|
291 |
* lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ )
|
|
|
292 |
* -- credit him for all the _good_ programming ;)
|
|
|
293 |
*
|
|
|
294 |
*
|
|
|
295 |
* For an explanation of the concepts and the basic algorithms involved, go to:
|
|
|
296 |
* http://www.replaygain.org/
|
|
|
297 |
*/
|
|
|
298 |
|
|
|
299 |
/*
|
|
|
300 |
* Here's the deal. Call
|
|
|
301 |
*
|
|
|
302 |
* InitGainAnalysis ( long samplefreq );
|
|
|
303 |
*
|
|
|
304 |
* to initialize everything. Call
|
|
|
305 |
*
|
|
|
306 |
* AnalyzeSamples ( var Float_t* left_samples,
|
|
|
307 |
* var Float_t* right_samples,
|
|
|
308 |
* size_t num_samples,
|
|
|
309 |
* int num_channels );
|
|
|
310 |
*
|
|
|
311 |
* as many times as you want, with as many or as few samples as you want.
|
|
|
312 |
* If mono, pass the sample buffer in through left_samples, leave
|
|
|
313 |
* right_samples NULL, and make sure num_channels = 1.
|
|
|
314 |
*
|
|
|
315 |
* GetTitleGain()
|
|
|
316 |
*
|
|
|
317 |
* will return the recommended dB level change for all samples analyzed
|
|
|
318 |
* SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis().
|
|
|
319 |
*
|
|
|
320 |
* GetAlbumGain()
|
|
|
321 |
*
|
|
|
322 |
* will return the recommended dB level change for all samples analyzed
|
|
|
323 |
* since InitGainAnalysis() was called and finalized with GetTitleGain().
|
|
|
324 |
*
|
|
|
325 |
* Pseudo-code to process an album:
|
|
|
326 |
*
|
|
|
327 |
* Float_t l_samples [4096];
|
|
|
328 |
* Float_t r_samples [4096];
|
|
|
329 |
* size_t num_samples;
|
|
|
330 |
* unsigned int num_songs;
|
|
|
331 |
* unsigned int i;
|
|
|
332 |
*
|
|
|
333 |
* InitGainAnalysis ( 44100 );
|
|
|
334 |
* for ( i = 1; i <= num_songs; i++ ) {
|
|
|
335 |
* while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 )
|
|
|
336 |
* AnalyzeSamples ( left_samples, right_samples, num_samples, 2 );
|
|
|
337 |
* fprintf ("Recommended dB change for song %2d: %+6.2 dB\n", i, GetTitleGain() );
|
|
|
338 |
* }
|
|
|
339 |
* fprintf ("Recommended dB change for whole album: %+6.2 dB\n", GetAlbumGain() );
|
|
|
340 |
*/
|
|
|
341 |
|
|
|
342 |
/*
|
|
|
343 |
* So here's the main source of potential code confusion:
|
|
|
344 |
*
|
|
|
345 |
* The filters applied to the incoming samples are IIR filters,
|
|
|
346 |
* meaning they rely on up to <filter order> number of previous samples
|
|
|
347 |
* AND up to <filter order> number of previous filtered samples.
|
|
|
348 |
*
|
|
|
349 |
* I set up the AnalyzeSamples routine to minimize memory usage and interface
|
|
|
350 |
* complexity. The speed isn't compromised too much (I don't think), but the
|
|
|
351 |
* internal complexity is higher than it should be for such a relatively
|
|
|
352 |
* simple routine.
|
|
|
353 |
*
|
|
|
354 |
* Optimization/clarity suggestions are welcome.
|
|
|
355 |
*/
|
|
|
356 |
|
|
|
357 |
/**
|
|
|
358 |
* Table entries per dB
|
|
|
359 |
*/
|
|
|
360 |
GainAnalysis.STEPS_per_dB = 100.;
|
|
|
361 |
/**
|
|
|
362 |
* Table entries for 0...MAX_dB (normal max. values are 70...80 dB)
|
|
|
363 |
*/
|
|
|
364 |
GainAnalysis.MAX_dB = 120.;
|
|
|
365 |
GainAnalysis.GAIN_NOT_ENOUGH_SAMPLES = -24601;
|
|
|
366 |
GainAnalysis.GAIN_ANALYSIS_ERROR = 0;
|
|
|
367 |
GainAnalysis.GAIN_ANALYSIS_OK = 1;
|
|
|
368 |
GainAnalysis.INIT_GAIN_ANALYSIS_ERROR = 0;
|
|
|
369 |
GainAnalysis.INIT_GAIN_ANALYSIS_OK = 1;
|
|
|
370 |
|
|
|
371 |
GainAnalysis.YULE_ORDER = 10;
|
|
|
372 |
GainAnalysis.MAX_ORDER = GainAnalysis.YULE_ORDER;
|
|
|
373 |
|
|
|
374 |
GainAnalysis.MAX_SAMP_FREQ = 48000;
|
|
|
375 |
GainAnalysis.RMS_WINDOW_TIME_NUMERATOR = 1;
|
|
|
376 |
GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR = 20;
|
|
|
377 |
GainAnalysis.MAX_SAMPLES_PER_WINDOW = ((GainAnalysis.MAX_SAMP_FREQ * GainAnalysis.RMS_WINDOW_TIME_NUMERATOR) / GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR + 1);
|
|
|
378 |
|
|
|
379 |
function GainAnalysis() {
|
|
|
380 |
/**
|
|
|
381 |
* calibration value for 89dB
|
|
|
382 |
*/
|
|
|
383 |
var PINK_REF = 64.82;
|
|
|
384 |
|
|
|
385 |
var YULE_ORDER = GainAnalysis.YULE_ORDER;
|
|
|
386 |
/**
|
|
|
387 |
* percentile which is louder than the proposed level
|
|
|
388 |
*/
|
|
|
389 |
var RMS_PERCENTILE = 0.95;
|
|
|
390 |
/**
|
|
|
391 |
* maximum allowed sample frequency [Hz]
|
|
|
392 |
*/
|
|
|
393 |
var MAX_SAMP_FREQ = GainAnalysis.MAX_SAMP_FREQ;
|
|
|
394 |
var RMS_WINDOW_TIME_NUMERATOR = GainAnalysis.RMS_WINDOW_TIME_NUMERATOR;
|
|
|
395 |
/**
|
|
|
396 |
* numerator / denominator = time slice size [s]
|
|
|
397 |
*/
|
|
|
398 |
var RMS_WINDOW_TIME_DENOMINATOR = GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR;
|
|
|
399 |
/**
|
|
|
400 |
* max. Samples per Time slice
|
|
|
401 |
*/
|
|
|
402 |
var MAX_SAMPLES_PER_WINDOW = GainAnalysis.MAX_SAMPLES_PER_WINDOW;
|
|
|
403 |
|
|
|
404 |
|
|
|
405 |
var ABYule = [
|
|
|
406 |
[0.03857599435200, -3.84664617118067, -0.02160367184185,
|
|
|
407 |
7.81501653005538, -0.00123395316851, -11.34170355132042,
|
|
|
408 |
-0.00009291677959, 13.05504219327545, -0.01655260341619,
|
|
|
409 |
-12.28759895145294, 0.02161526843274, 9.48293806319790,
|
|
|
410 |
-0.02074045215285, -5.87257861775999, 0.00594298065125,
|
|
|
411 |
2.75465861874613, 0.00306428023191, -0.86984376593551,
|
|
|
412 |
0.00012025322027, 0.13919314567432, 0.00288463683916],
|
|
|
413 |
[0.05418656406430, -3.47845948550071, -0.02911007808948,
|
|
|
414 |
6.36317777566148, -0.00848709379851, -8.54751527471874,
|
|
|
415 |
-0.00851165645469, 9.47693607801280, -0.00834990904936,
|
|
|
416 |
-8.81498681370155, 0.02245293253339, 6.85401540936998,
|
|
|
417 |
-0.02596338512915, -4.39470996079559, 0.01624864962975,
|
|
|
418 |
2.19611684890774, -0.00240879051584, -0.75104302451432,
|
|
|
419 |
0.00674613682247, 0.13149317958808, -0.00187763777362],
|
|
|
420 |
[0.15457299681924, -2.37898834973084, -0.09331049056315,
|
|
|
421 |
2.84868151156327, -0.06247880153653, -2.64577170229825,
|
|
|
422 |
0.02163541888798, 2.23697657451713, -0.05588393329856,
|
|
|
423 |
-1.67148153367602, 0.04781476674921, 1.00595954808547,
|
|
|
424 |
0.00222312597743, -0.45953458054983, 0.03174092540049,
|
|
|
425 |
0.16378164858596, -0.01390589421898, -0.05032077717131,
|
|
|
426 |
0.00651420667831, 0.02347897407020, -0.00881362733839],
|
|
|
427 |
[0.30296907319327, -1.61273165137247, -0.22613988682123,
|
|
|
428 |
1.07977492259970, -0.08587323730772, -0.25656257754070,
|
|
|
429 |
0.03282930172664, -0.16276719120440, -0.00915702933434,
|
|
|
430 |
-0.22638893773906, -0.02364141202522, 0.39120800788284,
|
|
|
431 |
-0.00584456039913, -0.22138138954925, 0.06276101321749,
|
|
|
432 |
0.04500235387352, -0.00000828086748, 0.02005851806501,
|
|
|
433 |
0.00205861885564, 0.00302439095741, -0.02950134983287],
|
|
|
434 |
[0.33642304856132, -1.49858979367799, -0.25572241425570,
|
|
|
435 |
0.87350271418188, -0.11828570177555, 0.12205022308084,
|
|
|
436 |
0.11921148675203, -0.80774944671438, -0.07834489609479,
|
|
|
437 |
0.47854794562326, -0.00469977914380, -0.12453458140019,
|
|
|
438 |
-0.00589500224440, -0.04067510197014, 0.05724228140351,
|
|
|
439 |
0.08333755284107, 0.00832043980773, -0.04237348025746,
|
|
|
440 |
-0.01635381384540, 0.02977207319925, -0.01760176568150],
|
|
|
441 |
[0.44915256608450, -0.62820619233671, -0.14351757464547,
|
|
|
442 |
0.29661783706366, -0.22784394429749, -0.37256372942400,
|
|
|
443 |
-0.01419140100551, 0.00213767857124, 0.04078262797139,
|
|
|
444 |
-0.42029820170918, -0.12398163381748, 0.22199650564824,
|
|
|
445 |
0.04097565135648, 0.00613424350682, 0.10478503600251,
|
|
|
446 |
0.06747620744683, -0.01863887810927, 0.05784820375801,
|
|
|
447 |
-0.03193428438915, 0.03222754072173, 0.00541907748707],
|
|
|
448 |
[0.56619470757641, -1.04800335126349, -0.75464456939302,
|
|
|
449 |
0.29156311971249, 0.16242137742230, -0.26806001042947,
|
|
|
450 |
0.16744243493672, 0.00819999645858, -0.18901604199609,
|
|
|
451 |
0.45054734505008, 0.30931782841830, -0.33032403314006,
|
|
|
452 |
-0.27562961986224, 0.06739368333110, 0.00647310677246,
|
|
|
453 |
-0.04784254229033, 0.08647503780351, 0.01639907836189,
|
|
|
454 |
-0.03788984554840, 0.01807364323573, -0.00588215443421],
|
|
|
455 |
[0.58100494960553, -0.51035327095184, -0.53174909058578,
|
|
|
456 |
-0.31863563325245, -0.14289799034253, -0.20256413484477,
|
|
|
457 |
0.17520704835522, 0.14728154134330, 0.02377945217615,
|
|
|
458 |
0.38952639978999, 0.15558449135573, -0.23313271880868,
|
|
|
459 |
-0.25344790059353, -0.05246019024463, 0.01628462406333,
|
|
|
460 |
-0.02505961724053, 0.06920467763959, 0.02442357316099,
|
|
|
461 |
-0.03721611395801, 0.01818801111503, -0.00749618797172],
|
|
|
462 |
[0.53648789255105, -0.25049871956020, -0.42163034350696,
|
|
|
463 |
-0.43193942311114, -0.00275953611929, -0.03424681017675,
|
|
|
464 |
0.04267842219415, -0.04678328784242, -0.10214864179676,
|
|
|
465 |
0.26408300200955, 0.14590772289388, 0.15113130533216,
|
|
|
466 |
-0.02459864859345, -0.17556493366449, -0.11202315195388,
|
|
|
467 |
-0.18823009262115, -0.04060034127000, 0.05477720428674,
|
|
|
468 |
0.04788665548180, 0.04704409688120, -0.02217936801134]];
|
|
|
469 |
|
|
|
470 |
var ABButter = [
|
|
|
471 |
[0.98621192462708, -1.97223372919527, -1.97242384925416,
|
|
|
472 |
0.97261396931306, 0.98621192462708],
|
|
|
473 |
[0.98500175787242, -1.96977855582618, -1.97000351574484,
|
|
|
474 |
0.97022847566350, 0.98500175787242],
|
|
|
475 |
[0.97938932735214, -1.95835380975398, -1.95877865470428,
|
|
|
476 |
0.95920349965459, 0.97938932735214],
|
|
|
477 |
[0.97531843204928, -1.95002759149878, -1.95063686409857,
|
|
|
478 |
0.95124613669835, 0.97531843204928],
|
|
|
479 |
[0.97316523498161, -1.94561023566527, -1.94633046996323,
|
|
|
480 |
0.94705070426118, 0.97316523498161],
|
|
|
481 |
[0.96454515552826, -1.92783286977036, -1.92909031105652,
|
|
|
482 |
0.93034775234268, 0.96454515552826],
|
|
|
483 |
[0.96009142950541, -1.91858953033784, -1.92018285901082,
|
|
|
484 |
0.92177618768381, 0.96009142950541],
|
|
|
485 |
[0.95856916599601, -1.91542108074780, -1.91713833199203,
|
|
|
486 |
0.91885558323625, 0.95856916599601],
|
|
|
487 |
[0.94597685600279, -1.88903307939452, -1.89195371200558,
|
|
|
488 |
0.89487434461664, 0.94597685600279]];
|
|
|
489 |
|
|
|
490 |
|
|
|
491 |
/**
|
|
|
492 |
* When calling this procedure, make sure that ip[-order] and op[-order]
|
|
|
493 |
* point to real data
|
|
|
494 |
*/
|
|
|
495 |
//private void filterYule(final float[] input, int inputPos, float[] output,
|
|
|
496 |
//int outputPos, int nSamples, final float[] kernel) {
|
|
|
497 |
function filterYule(input, inputPos, output, outputPos, nSamples, kernel) {
|
|
|
498 |
|
|
|
499 |
while ((nSamples--) != 0) {
|
|
|
500 |
/* 1e-10 is a hack to avoid slowdown because of denormals */
|
|
|
501 |
output[outputPos] = 1e-10 + input[inputPos + 0] * kernel[0]
|
|
|
502 |
- output[outputPos - 1] * kernel[1] + input[inputPos - 1]
|
|
|
503 |
* kernel[2] - output[outputPos - 2] * kernel[3]
|
|
|
504 |
+ input[inputPos - 2] * kernel[4] - output[outputPos - 3]
|
|
|
505 |
* kernel[5] + input[inputPos - 3] * kernel[6]
|
|
|
506 |
- output[outputPos - 4] * kernel[7] + input[inputPos - 4]
|
|
|
507 |
* kernel[8] - output[outputPos - 5] * kernel[9]
|
|
|
508 |
+ input[inputPos - 5] * kernel[10] - output[outputPos - 6]
|
|
|
509 |
* kernel[11] + input[inputPos - 6] * kernel[12]
|
|
|
510 |
- output[outputPos - 7] * kernel[13] + input[inputPos - 7]
|
|
|
511 |
* kernel[14] - output[outputPos - 8] * kernel[15]
|
|
|
512 |
+ input[inputPos - 8] * kernel[16] - output[outputPos - 9]
|
|
|
513 |
* kernel[17] + input[inputPos - 9] * kernel[18]
|
|
|
514 |
- output[outputPos - 10] * kernel[19]
|
|
|
515 |
+ input[inputPos - 10] * kernel[20];
|
|
|
516 |
++outputPos;
|
|
|
517 |
++inputPos;
|
|
|
518 |
}
|
|
|
519 |
}
|
|
|
520 |
|
|
|
521 |
//private void filterButter(final float[] input, int inputPos,
|
|
|
522 |
// float[] output, int outputPos, int nSamples, final float[] kernel) {
|
|
|
523 |
function filterButter(input, inputPos, output, outputPos, nSamples, kernel) {
|
|
|
524 |
|
|
|
525 |
while ((nSamples--) != 0) {
|
|
|
526 |
output[outputPos] = input[inputPos + 0] * kernel[0]
|
|
|
527 |
- output[outputPos - 1] * kernel[1] + input[inputPos - 1]
|
|
|
528 |
* kernel[2] - output[outputPos - 2] * kernel[3]
|
|
|
529 |
+ input[inputPos - 2] * kernel[4];
|
|
|
530 |
++outputPos;
|
|
|
531 |
++inputPos;
|
|
|
532 |
}
|
|
|
533 |
}
|
|
|
534 |
|
|
|
535 |
/**
|
|
|
536 |
* @return INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if
|
|
|
537 |
* not
|
|
|
538 |
*/
|
|
|
539 |
function ResetSampleFrequency(rgData, samplefreq) {
|
|
|
540 |
/* zero out initial values */
|
|
|
541 |
for (var i = 0; i < MAX_ORDER; i++)
|
|
|
542 |
rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.;
|
|
|
543 |
|
|
|
544 |
switch (0 | (samplefreq)) {
|
|
|
545 |
case 48000:
|
|
|
546 |
rgData.reqindex = 0;
|
|
|
547 |
break;
|
|
|
548 |
case 44100:
|
|
|
549 |
rgData.reqindex = 1;
|
|
|
550 |
break;
|
|
|
551 |
case 32000:
|
|
|
552 |
rgData.reqindex = 2;
|
|
|
553 |
break;
|
|
|
554 |
case 24000:
|
|
|
555 |
rgData.reqindex = 3;
|
|
|
556 |
break;
|
|
|
557 |
case 22050:
|
|
|
558 |
rgData.reqindex = 4;
|
|
|
559 |
break;
|
|
|
560 |
case 16000:
|
|
|
561 |
rgData.reqindex = 5;
|
|
|
562 |
break;
|
|
|
563 |
case 12000:
|
|
|
564 |
rgData.reqindex = 6;
|
|
|
565 |
break;
|
|
|
566 |
case 11025:
|
|
|
567 |
rgData.reqindex = 7;
|
|
|
568 |
break;
|
|
|
569 |
case 8000:
|
|
|
570 |
rgData.reqindex = 8;
|
|
|
571 |
break;
|
|
|
572 |
default:
|
|
|
573 |
return INIT_GAIN_ANALYSIS_ERROR;
|
|
|
574 |
}
|
|
|
575 |
|
|
|
576 |
rgData.sampleWindow = 0 | ((samplefreq * RMS_WINDOW_TIME_NUMERATOR
|
|
|
577 |
+ RMS_WINDOW_TIME_DENOMINATOR - 1) / RMS_WINDOW_TIME_DENOMINATOR);
|
|
|
578 |
|
|
|
579 |
rgData.lsum = 0.;
|
|
|
580 |
rgData.rsum = 0.;
|
|
|
581 |
rgData.totsamp = 0;
|
|
|
582 |
|
|
|
583 |
Arrays.ill(rgData.A, 0);
|
|
|
584 |
|
|
|
585 |
return INIT_GAIN_ANALYSIS_OK;
|
|
|
586 |
}
|
|
|
587 |
|
|
|
588 |
this.InitGainAnalysis = function (rgData, samplefreq) {
|
|
|
589 |
if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) {
|
|
|
590 |
return INIT_GAIN_ANALYSIS_ERROR;
|
|
|
591 |
}
|
|
|
592 |
|
|
|
593 |
rgData.linpre = MAX_ORDER;
|
|
|
594 |
rgData.rinpre = MAX_ORDER;
|
|
|
595 |
rgData.lstep = MAX_ORDER;
|
|
|
596 |
rgData.rstep = MAX_ORDER;
|
|
|
597 |
rgData.lout = MAX_ORDER;
|
|
|
598 |
rgData.rout = MAX_ORDER;
|
|
|
599 |
|
|
|
600 |
Arrays.fill(rgData.B, 0);
|
|
|
601 |
|
|
|
602 |
return INIT_GAIN_ANALYSIS_OK;
|
|
|
603 |
};
|
|
|
604 |
|
|
|
605 |
/**
|
|
|
606 |
* square
|
|
|
607 |
*/
|
|
|
608 |
function fsqr(d) {
|
|
|
609 |
return d * d;
|
|
|
610 |
}
|
|
|
611 |
|
|
|
612 |
this.AnalyzeSamples = function (rgData, left_samples, left_samplesPos, right_samples, right_samplesPos, num_samples,
|
|
|
613 |
num_channels) {
|
|
|
614 |
var curleft;
|
|
|
615 |
var curleftBase;
|
|
|
616 |
var curright;
|
|
|
617 |
var currightBase;
|
|
|
618 |
var batchsamples;
|
|
|
619 |
var cursamples;
|
|
|
620 |
var cursamplepos;
|
|
|
621 |
|
|
|
622 |
if (num_samples == 0)
|
|
|
623 |
return GAIN_ANALYSIS_OK;
|
|
|
624 |
|
|
|
625 |
cursamplepos = 0;
|
|
|
626 |
batchsamples = num_samples;
|
|
|
627 |
|
|
|
628 |
switch (num_channels) {
|
|
|
629 |
case 1:
|
|
|
630 |
right_samples = left_samples;
|
|
|
631 |
right_samplesPos = left_samplesPos;
|
|
|
632 |
break;
|
|
|
633 |
case 2:
|
|
|
634 |
break;
|
|
|
635 |
default:
|
|
|
636 |
return GAIN_ANALYSIS_ERROR;
|
|
|
637 |
}
|
|
|
638 |
|
|
|
639 |
if (num_samples < MAX_ORDER) {
|
|
|
640 |
System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf,
|
|
|
641 |
MAX_ORDER, num_samples);
|
|
|
642 |
System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf,
|
|
|
643 |
MAX_ORDER, num_samples);
|
|
|
644 |
} else {
|
|
|
645 |
System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf,
|
|
|
646 |
MAX_ORDER, MAX_ORDER);
|
|
|
647 |
System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf,
|
|
|
648 |
MAX_ORDER, MAX_ORDER);
|
|
|
649 |
}
|
|
|
650 |
|
|
|
651 |
while (batchsamples > 0) {
|
|
|
652 |
cursamples = batchsamples > rgData.sampleWindow - rgData.totsamp ? rgData.sampleWindow
|
|
|
653 |
- rgData.totsamp
|
|
|
654 |
: batchsamples;
|
|
|
655 |
if (cursamplepos < MAX_ORDER) {
|
|
|
656 |
curleft = rgData.linpre + cursamplepos;
|
|
|
657 |
curleftBase = rgData.linprebuf;
|
|
|
658 |
curright = rgData.rinpre + cursamplepos;
|
|
|
659 |
currightBase = rgData.rinprebuf;
|
|
|
660 |
if (cursamples > MAX_ORDER - cursamplepos)
|
|
|
661 |
cursamples = MAX_ORDER - cursamplepos;
|
|
|
662 |
} else {
|
|
|
663 |
curleft = left_samplesPos + cursamplepos;
|
|
|
664 |
curleftBase = left_samples;
|
|
|
665 |
curright = right_samplesPos + cursamplepos;
|
|
|
666 |
currightBase = right_samples;
|
|
|
667 |
}
|
|
|
668 |
|
|
|
669 |
filterYule(curleftBase, curleft, rgData.lstepbuf, rgData.lstep
|
|
|
670 |
+ rgData.totsamp, cursamples, ABYule[rgData.reqindex]);
|
|
|
671 |
filterYule(currightBase, curright, rgData.rstepbuf, rgData.rstep
|
|
|
672 |
+ rgData.totsamp, cursamples, ABYule[rgData.reqindex]);
|
|
|
673 |
|
|
|
674 |
filterButter(rgData.lstepbuf, rgData.lstep + rgData.totsamp,
|
|
|
675 |
rgData.loutbuf, rgData.lout + rgData.totsamp, cursamples,
|
|
|
676 |
ABButter[rgData.reqindex]);
|
|
|
677 |
filterButter(rgData.rstepbuf, rgData.rstep + rgData.totsamp,
|
|
|
678 |
rgData.routbuf, rgData.rout + rgData.totsamp, cursamples,
|
|
|
679 |
ABButter[rgData.reqindex]);
|
|
|
680 |
|
|
|
681 |
curleft = rgData.lout + rgData.totsamp;
|
|
|
682 |
/* Get the squared values */
|
|
|
683 |
curleftBase = rgData.loutbuf;
|
|
|
684 |
curright = rgData.rout + rgData.totsamp;
|
|
|
685 |
currightBase = rgData.routbuf;
|
|
|
686 |
|
|
|
687 |
var i = cursamples % 8;
|
|
|
688 |
while ((i--) != 0) {
|
|
|
689 |
rgData.lsum += fsqr(curleftBase[curleft++]);
|
|
|
690 |
rgData.rsum += fsqr(currightBase[curright++]);
|
|
|
691 |
}
|
|
|
692 |
i = cursamples / 8;
|
|
|
693 |
while ((i--) != 0) {
|
|
|
694 |
rgData.lsum += fsqr(curleftBase[curleft + 0])
|
|
|
695 |
+ fsqr(curleftBase[curleft + 1])
|
|
|
696 |
+ fsqr(curleftBase[curleft + 2])
|
|
|
697 |
+ fsqr(curleftBase[curleft + 3])
|
|
|
698 |
+ fsqr(curleftBase[curleft + 4])
|
|
|
699 |
+ fsqr(curleftBase[curleft + 5])
|
|
|
700 |
+ fsqr(curleftBase[curleft + 6])
|
|
|
701 |
+ fsqr(curleftBase[curleft + 7]);
|
|
|
702 |
curleft += 8;
|
|
|
703 |
rgData.rsum += fsqr(currightBase[curright + 0])
|
|
|
704 |
+ fsqr(currightBase[curright + 1])
|
|
|
705 |
+ fsqr(currightBase[curright + 2])
|
|
|
706 |
+ fsqr(currightBase[curright + 3])
|
|
|
707 |
+ fsqr(currightBase[curright + 4])
|
|
|
708 |
+ fsqr(currightBase[curright + 5])
|
|
|
709 |
+ fsqr(currightBase[curright + 6])
|
|
|
710 |
+ fsqr(currightBase[curright + 7]);
|
|
|
711 |
curright += 8;
|
|
|
712 |
}
|
|
|
713 |
|
|
|
714 |
batchsamples -= cursamples;
|
|
|
715 |
cursamplepos += cursamples;
|
|
|
716 |
rgData.totsamp += cursamples;
|
|
|
717 |
if (rgData.totsamp == rgData.sampleWindow) {
|
|
|
718 |
/* Get the Root Mean Square (RMS) for this set of samples */
|
|
|
719 |
var val = GainAnalysis.STEPS_per_dB
|
|
|
720 |
* 10.
|
|
|
721 |
* Math.log10((rgData.lsum + rgData.rsum)
|
|
|
722 |
/ rgData.totsamp * 0.5 + 1.e-37);
|
|
|
723 |
var ival = (val <= 0) ? 0 : 0 | val;
|
|
|
724 |
if (ival >= rgData.A.length)
|
|
|
725 |
ival = rgData.A.length - 1;
|
|
|
726 |
rgData.A[ival]++;
|
|
|
727 |
rgData.lsum = rgData.rsum = 0.;
|
|
|
728 |
|
|
|
729 |
System.arraycopy(rgData.loutbuf, rgData.totsamp,
|
|
|
730 |
rgData.loutbuf, 0, MAX_ORDER);
|
|
|
731 |
System.arraycopy(rgData.routbuf, rgData.totsamp,
|
|
|
732 |
rgData.routbuf, 0, MAX_ORDER);
|
|
|
733 |
System.arraycopy(rgData.lstepbuf, rgData.totsamp,
|
|
|
734 |
rgData.lstepbuf, 0, MAX_ORDER);
|
|
|
735 |
System.arraycopy(rgData.rstepbuf, rgData.totsamp,
|
|
|
736 |
rgData.rstepbuf, 0, MAX_ORDER);
|
|
|
737 |
rgData.totsamp = 0;
|
|
|
738 |
}
|
|
|
739 |
if (rgData.totsamp > rgData.sampleWindow) {
|
|
|
740 |
/*
|
|
|
741 |
* somehow I really screwed up: Error in programming! Contact
|
|
|
742 |
* author about totsamp > sampleWindow
|
|
|
743 |
*/
|
|
|
744 |
return GAIN_ANALYSIS_ERROR;
|
|
|
745 |
}
|
|
|
746 |
}
|
|
|
747 |
if (num_samples < MAX_ORDER) {
|
|
|
748 |
System.arraycopy(rgData.linprebuf, num_samples, rgData.linprebuf,
|
|
|
749 |
0, MAX_ORDER - num_samples);
|
|
|
750 |
System.arraycopy(rgData.rinprebuf, num_samples, rgData.rinprebuf,
|
|
|
751 |
0, MAX_ORDER - num_samples);
|
|
|
752 |
System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf,
|
|
|
753 |
MAX_ORDER - num_samples, num_samples);
|
|
|
754 |
System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf,
|
|
|
755 |
MAX_ORDER - num_samples, num_samples);
|
|
|
756 |
} else {
|
|
|
757 |
System.arraycopy(left_samples, left_samplesPos + num_samples
|
|
|
758 |
- MAX_ORDER, rgData.linprebuf, 0, MAX_ORDER);
|
|
|
759 |
System.arraycopy(right_samples, right_samplesPos + num_samples
|
|
|
760 |
- MAX_ORDER, rgData.rinprebuf, 0, MAX_ORDER);
|
|
|
761 |
}
|
|
|
762 |
|
|
|
763 |
return GAIN_ANALYSIS_OK;
|
|
|
764 |
};
|
|
|
765 |
|
|
|
766 |
function analyzeResult(Array, len) {
|
|
|
767 |
var i;
|
|
|
768 |
|
|
|
769 |
var elems = 0;
|
|
|
770 |
for (i = 0; i < len; i++)
|
|
|
771 |
elems += Array[i];
|
|
|
772 |
if (elems == 0)
|
|
|
773 |
return GAIN_NOT_ENOUGH_SAMPLES;
|
|
|
774 |
|
|
|
775 |
var upper = 0 | Math.ceil(elems * (1. - RMS_PERCENTILE));
|
|
|
776 |
for (i = len; i-- > 0;) {
|
|
|
777 |
if ((upper -= Array[i]) <= 0)
|
|
|
778 |
break;
|
|
|
779 |
}
|
|
|
780 |
|
|
|
781 |
//return (float) ((float) PINK_REF - (float) i / (float) STEPS_per_dB);
|
|
|
782 |
return (PINK_REF - i / GainAnalysis.STEPS_per_dB);
|
|
|
783 |
}
|
|
|
784 |
|
|
|
785 |
this.GetTitleGain = function (rgData) {
|
|
|
786 |
var retval = analyzeResult(rgData.A, rgData.A.length);
|
|
|
787 |
|
|
|
788 |
for (var i = 0; i < rgData.A.length; i++) {
|
|
|
789 |
rgData.B[i] += rgData.A[i];
|
|
|
790 |
rgData.A[i] = 0;
|
|
|
791 |
}
|
|
|
792 |
|
|
|
793 |
for (var i = 0; i < MAX_ORDER; i++)
|
|
|
794 |
rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.;
|
|
|
795 |
|
|
|
796 |
rgData.totsamp = 0;
|
|
|
797 |
rgData.lsum = rgData.rsum = 0.;
|
|
|
798 |
return retval;
|
|
|
799 |
}
|
|
|
800 |
|
|
|
801 |
}
|
|
|
802 |
|
|
|
803 |
|
|
|
804 |
function Presets() {
|
|
|
805 |
function VBRPresets(qual, comp, compS,
|
|
|
806 |
y, shThreshold, shThresholdS,
|
|
|
807 |
adj, adjShort, lower,
|
|
|
808 |
curve, sens, inter,
|
|
|
809 |
joint, mod, fix) {
|
|
|
810 |
this.vbr_q = qual;
|
|
|
811 |
this.quant_comp = comp;
|
|
|
812 |
this.quant_comp_s = compS;
|
|
|
813 |
this.expY = y;
|
|
|
814 |
this.st_lrm = shThreshold;
|
|
|
815 |
this.st_s = shThresholdS;
|
|
|
816 |
this.masking_adj = adj;
|
|
|
817 |
this.masking_adj_short = adjShort;
|
|
|
818 |
this.ath_lower = lower;
|
|
|
819 |
this.ath_curve = curve;
|
|
|
820 |
this.ath_sensitivity = sens;
|
|
|
821 |
this.interch = inter;
|
|
|
822 |
this.safejoint = joint;
|
|
|
823 |
this.sfb21mod = mod;
|
|
|
824 |
this.msfix = fix;
|
|
|
825 |
}
|
|
|
826 |
|
|
|
827 |
function ABRPresets(kbps, comp, compS,
|
|
|
828 |
joint, fix, shThreshold,
|
|
|
829 |
shThresholdS, bass, sc,
|
|
|
830 |
mask, lower, curve,
|
|
|
831 |
interCh, sfScale) {
|
|
|
832 |
this.quant_comp = comp;
|
|
|
833 |
this.quant_comp_s = compS;
|
|
|
834 |
this.safejoint = joint;
|
|
|
835 |
this.nsmsfix = fix;
|
|
|
836 |
this.st_lrm = shThreshold;
|
|
|
837 |
this.st_s = shThresholdS;
|
|
|
838 |
this.nsbass = bass;
|
|
|
839 |
this.scale = sc;
|
|
|
840 |
this.masking_adj = mask;
|
|
|
841 |
this.ath_lower = lower;
|
|
|
842 |
this.ath_curve = curve;
|
|
|
843 |
this.interch = interCh;
|
|
|
844 |
this.sfscale = sfScale;
|
|
|
845 |
}
|
|
|
846 |
|
|
|
847 |
var lame;
|
|
|
848 |
|
|
|
849 |
this.setModules = function (_lame) {
|
|
|
850 |
lame = _lame;
|
|
|
851 |
};
|
|
|
852 |
|
|
|
853 |
/**
|
|
|
854 |
* <PRE>
|
|
|
855 |
* Switch mappings for VBR mode VBR_RH
|
|
|
856 |
* 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
|
|
|
857 |
* </PRE>
|
|
|
858 |
*/
|
|
|
859 |
var vbr_old_switch_map = [
|
|
|
860 |
new VBRPresets(0, 9, 9, 0, 5.20, 125.0, -4.2, -6.3, 4.8, 1, 0, 0, 2, 21, 0.97),
|
|
|
861 |
new VBRPresets(1, 9, 9, 0, 5.30, 125.0, -3.6, -5.6, 4.5, 1.5, 0, 0, 2, 21, 1.35),
|
|
|
862 |
new VBRPresets(2, 9, 9, 0, 5.60, 125.0, -2.2, -3.5, 2.8, 2, 0, 0, 2, 21, 1.49),
|
|
|
863 |
new VBRPresets(3, 9, 9, 1, 5.80, 130.0, -1.8, -2.8, 2.6, 3, -4, 0, 2, 20, 1.64),
|
|
|
864 |
new VBRPresets(4, 9, 9, 1, 6.00, 135.0, -0.7, -1.1, 1.1, 3.5, -8, 0, 2, 0, 1.79),
|
|
|
865 |
new VBRPresets(5, 9, 9, 1, 6.40, 140.0, 0.5, 0.4, -7.5, 4, -12, 0.0002, 0, 0, 1.95),
|
|
|
866 |
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),
|
|
|
867 |
new VBRPresets(7, 9, 9, 1, 6.60, 145.0, 0.8, 0.75, -19.7, 8, -22, 0.0006, 0, 0, 2.70),
|
|
|
868 |
new VBRPresets(8, 9, 9, 1, 6.60, 145.0, 1.2, 1.15, -27.5, 10, -23, 0.0007, 0, 0, 0),
|
|
|
869 |
new VBRPresets(9, 9, 9, 1, 6.60, 145.0, 1.6, 1.6, -36, 11, -25, 0.0008, 0, 0, 0),
|
|
|
870 |
new VBRPresets(10, 9, 9, 1, 6.60, 145.0, 2.0, 2.0, -36, 12, -25, 0.0008, 0, 0, 0)
|
|
|
871 |
];
|
|
|
872 |
|
|
|
873 |
/**
|
|
|
874 |
* <PRE>
|
|
|
875 |
* 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
|
|
|
876 |
* </PRE>
|
|
|
877 |
*/
|
|
|
878 |
var vbr_psy_switch_map = [
|
|
|
879 |
new VBRPresets(0, 9, 9, 0, 4.20, 25.0, -7.0, -4.0, 7.5, 1, 0, 0, 2, 26, 0.97),
|
|
|
880 |
new VBRPresets(1, 9, 9, 0, 4.20, 25.0, -5.6, -3.6, 4.5, 1.5, 0, 0, 2, 21, 1.35),
|
|
|
881 |
new VBRPresets(2, 9, 9, 0, 4.20, 25.0, -4.4, -1.8, 2, 2, 0, 0, 2, 18, 1.49),
|
|
|
882 |
new VBRPresets(3, 9, 9, 1, 4.20, 25.0, -3.4, -1.25, 1.1, 3, -4, 0, 2, 15, 1.64),
|
|
|
883 |
new VBRPresets(4, 9, 9, 1, 4.20, 25.0, -2.2, 0.1, 0, 3.5, -8, 0, 2, 0, 1.79),
|
|
|
884 |
new VBRPresets(5, 9, 9, 1, 4.20, 25.0, -1.0, 1.65, -7.7, 4, -12, 0.0002, 0, 0, 1.95),
|
|
|
885 |
new VBRPresets(6, 9, 9, 1, 4.20, 25.0, -0.0, 2.47, -7.7, 6.5, -19, 0.0004, 0, 0, 2),
|
|
|
886 |
new VBRPresets(7, 9, 9, 1, 4.20, 25.0, 0.5, 2.0, -14.5, 8, -22, 0.0006, 0, 0, 2),
|
|
|
887 |
new VBRPresets(8, 9, 9, 1, 4.20, 25.0, 1.0, 2.4, -22.0, 10, -23, 0.0007, 0, 0, 2),
|
|
|
888 |
new VBRPresets(9, 9, 9, 1, 4.20, 25.0, 1.5, 2.95, -30.0, 11, -25, 0.0008, 0, 0, 2),
|
|
|
889 |
new VBRPresets(10, 9, 9, 1, 4.20, 25.0, 2.0, 2.95, -36.0, 12, -30, 0.0008, 0, 0, 2)
|
|
|
890 |
];
|
|
|
891 |
|
|
|
892 |
function apply_vbr_preset(gfp, a, enforce) {
|
|
|
893 |
var vbr_preset = gfp.VBR == VbrMode.vbr_rh ? vbr_old_switch_map
|
|
|
894 |
: vbr_psy_switch_map;
|
|
|
895 |
|
|
|
896 |
var x = gfp.VBR_q_frac;
|
|
|
897 |
var p = vbr_preset[a];
|
|
|
898 |
var q = vbr_preset[a + 1];
|
|
|
899 |
var set = p;
|
|
|
900 |
|
|
|
901 |
// NOOP(vbr_q);
|
|
|
902 |
// NOOP(quant_comp);
|
|
|
903 |
// NOOP(quant_comp_s);
|
|
|
904 |
// NOOP(expY);
|
|
|
905 |
p.st_lrm = p.st_lrm + x * (q.st_lrm - p.st_lrm);
|
|
|
906 |
// LERP(st_lrm);
|
|
|
907 |
p.st_s = p.st_s + x * (q.st_s - p.st_s);
|
|
|
908 |
// LERP(st_s);
|
|
|
909 |
p.masking_adj = p.masking_adj + x * (q.masking_adj - p.masking_adj);
|
|
|
910 |
// LERP(masking_adj);
|
|
|
911 |
p.masking_adj_short = p.masking_adj_short + x
|
|
|
912 |
* (q.masking_adj_short - p.masking_adj_short);
|
|
|
913 |
// LERP(masking_adj_short);
|
|
|
914 |
p.ath_lower = p.ath_lower + x * (q.ath_lower - p.ath_lower);
|
|
|
915 |
// LERP(ath_lower);
|
|
|
916 |
p.ath_curve = p.ath_curve + x * (q.ath_curve - p.ath_curve);
|
|
|
917 |
// LERP(ath_curve);
|
|
|
918 |
p.ath_sensitivity = p.ath_sensitivity + x
|
|
|
919 |
* (q.ath_sensitivity - p.ath_sensitivity);
|
|
|
920 |
// LERP(ath_sensitivity);
|
|
|
921 |
p.interch = p.interch + x * (q.interch - p.interch);
|
|
|
922 |
// LERP(interch);
|
|
|
923 |
// NOOP(safejoint);
|
|
|
924 |
// NOOP(sfb21mod);
|
|
|
925 |
p.msfix = p.msfix + x * (q.msfix - p.msfix);
|
|
|
926 |
// LERP(msfix);
|
|
|
927 |
|
|
|
928 |
lame_set_VBR_q(gfp, set.vbr_q);
|
|
|
929 |
|
|
|
930 |
if (enforce != 0)
|
|
|
931 |
gfp.quant_comp = set.quant_comp;
|
|
|
932 |
else if (!(Math.abs(gfp.quant_comp - -1) > 0))
|
|
|
933 |
gfp.quant_comp = set.quant_comp;
|
|
|
934 |
// SET_OPTION(quant_comp, set.quant_comp, -1);
|
|
|
935 |
if (enforce != 0)
|
|
|
936 |
gfp.quant_comp_short = set.quant_comp_s;
|
|
|
937 |
else if (!(Math.abs(gfp.quant_comp_short - -1) > 0))
|
|
|
938 |
gfp.quant_comp_short = set.quant_comp_s;
|
|
|
939 |
// SET_OPTION(quant_comp_short, set.quant_comp_s, -1);
|
|
|
940 |
if (set.expY != 0) {
|
|
|
941 |
gfp.experimentalY = set.expY != 0;
|
|
|
942 |
}
|
|
|
943 |
if (enforce != 0)
|
|
|
944 |
gfp.internal_flags.nsPsy.attackthre = set.st_lrm;
|
|
|
945 |
else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0))
|
|
|
946 |
gfp.internal_flags.nsPsy.attackthre = set.st_lrm;
|
|
|
947 |
// SET_OPTION(short_threshold_lrm, set.st_lrm, -1);
|
|
|
948 |
if (enforce != 0)
|
|
|
949 |
gfp.internal_flags.nsPsy.attackthre_s = set.st_s;
|
|
|
950 |
else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0))
|
|
|
951 |
gfp.internal_flags.nsPsy.attackthre_s = set.st_s;
|
|
|
952 |
// SET_OPTION(short_threshold_s, set.st_s, -1);
|
|
|
953 |
if (enforce != 0)
|
|
|
954 |
gfp.maskingadjust = set.masking_adj;
|
|
|
955 |
else if (!(Math.abs(gfp.maskingadjust - 0) > 0))
|
|
|
956 |
gfp.maskingadjust = set.masking_adj;
|
|
|
957 |
// SET_OPTION(maskingadjust, set.masking_adj, 0);
|
|
|
958 |
if (enforce != 0)
|
|
|
959 |
gfp.maskingadjust_short = set.masking_adj_short;
|
|
|
960 |
else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0))
|
|
|
961 |
gfp.maskingadjust_short = set.masking_adj_short;
|
|
|
962 |
// SET_OPTION(maskingadjust_short, set.masking_adj_short, 0);
|
|
|
963 |
if (enforce != 0)
|
|
|
964 |
gfp.ATHlower = -set.ath_lower / 10.0;
|
|
|
965 |
else if (!(Math.abs((-gfp.ATHlower * 10.0) - 0) > 0))
|
|
|
966 |
gfp.ATHlower = -set.ath_lower / 10.0;
|
|
|
967 |
// SET_OPTION(ATHlower, set.ath_lower, 0);
|
|
|
968 |
if (enforce != 0)
|
|
|
969 |
gfp.ATHcurve = set.ath_curve;
|
|
|
970 |
else if (!(Math.abs(gfp.ATHcurve - -1) > 0))
|
|
|
971 |
gfp.ATHcurve = set.ath_curve;
|
|
|
972 |
// SET_OPTION(ATHcurve, set.ath_curve, -1);
|
|
|
973 |
if (enforce != 0)
|
|
|
974 |
gfp.athaa_sensitivity = set.ath_sensitivity;
|
|
|
975 |
else if (!(Math.abs(gfp.athaa_sensitivity - -1) > 0))
|
|
|
976 |
gfp.athaa_sensitivity = set.ath_sensitivity;
|
|
|
977 |
// SET_OPTION(athaa_sensitivity, set.ath_sensitivity, 0);
|
|
|
978 |
if (set.interch > 0) {
|
|
|
979 |
if (enforce != 0)
|
|
|
980 |
gfp.interChRatio = set.interch;
|
|
|
981 |
else if (!(Math.abs(gfp.interChRatio - -1) > 0))
|
|
|
982 |
gfp.interChRatio = set.interch;
|
|
|
983 |
// SET_OPTION(interChRatio, set.interch, -1);
|
|
|
984 |
}
|
|
|
985 |
|
|
|
986 |
/* parameters for which there is no proper set/get interface */
|
|
|
987 |
if (set.safejoint > 0) {
|
|
|
988 |
gfp.exp_nspsytune = gfp.exp_nspsytune | set.safejoint;
|
|
|
989 |
}
|
|
|
990 |
if (set.sfb21mod > 0) {
|
|
|
991 |
gfp.exp_nspsytune = gfp.exp_nspsytune | (set.sfb21mod << 20);
|
|
|
992 |
}
|
|
|
993 |
if (enforce != 0)
|
|
|
994 |
gfp.msfix = set.msfix;
|
|
|
995 |
else if (!(Math.abs(gfp.msfix - -1) > 0))
|
|
|
996 |
gfp.msfix = set.msfix;
|
|
|
997 |
// SET_OPTION(msfix, set.msfix, -1);
|
|
|
998 |
|
|
|
999 |
if (enforce == 0) {
|
|
|
1000 |
gfp.VBR_q = a;
|
|
|
1001 |
gfp.VBR_q_frac = x;
|
|
|
1002 |
}
|
|
|
1003 |
}
|
|
|
1004 |
|
|
|
1005 |
/**
|
|
|
1006 |
* <PRE>
|
|
|
1007 |
* Switch mappings for ABR mode
|
|
|
1008 |
*
|
|
|
1009 |
* kbps quant q_s safejoint nsmsfix st_lrm st_s ns-bass scale msk ath_lwr ath_curve interch , sfscale
|
|
|
1010 |
* </PRE>
|
|
|
1011 |
*/
|
|
|
1012 |
var abr_switch_map = [
|
|
|
1013 |
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 */
|
|
|
1014 |
new ABRPresets(16, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -25.0, 11, 0.0010, 1), /* 16 */
|
|
|
1015 |
new ABRPresets(24, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -20.0, 11, 0.0010, 1), /* 24 */
|
|
|
1016 |
new ABRPresets(32, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -15.0, 11, 0.0010, 1), /* 32 */
|
|
|
1017 |
new ABRPresets(40, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 40 */
|
|
|
1018 |
new ABRPresets(48, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 48 */
|
|
|
1019 |
new ABRPresets(56, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -6.0, 11, 0.0008, 1), /* 56 */
|
|
|
1020 |
new ABRPresets(64, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -2.0, 11, 0.0008, 1), /* 64 */
|
|
|
1021 |
new ABRPresets(80, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, .0, 8, 0.0007, 1), /* 80 */
|
|
|
1022 |
new ABRPresets(96, 9, 9, 0, 2.50, 6.60, 145, 0, 0.95, 0, 1.0, 5.5, 0.0006, 1), /* 96 */
|
|
|
1023 |
new ABRPresets(112, 9, 9, 0, 2.25, 6.60, 145, 0, 0.95, 0, 2.0, 4.5, 0.0005, 1), /* 112 */
|
|
|
1024 |
new ABRPresets(128, 9, 9, 0, 1.95, 6.40, 140, 0, 0.95, 0, 3.0, 4, 0.0002, 1), /* 128 */
|
|
|
1025 |
new ABRPresets(160, 9, 9, 1, 1.79, 6.00, 135, 0, 0.95, -2, 5.0, 3.5, 0, 1), /* 160 */
|
|
|
1026 |
new ABRPresets(192, 9, 9, 1, 1.49, 5.60, 125, 0, 0.97, -4, 7.0, 3, 0, 0), /* 192 */
|
|
|
1027 |
new ABRPresets(224, 9, 9, 1, 1.25, 5.20, 125, 0, 0.98, -6, 9.0, 2, 0, 0), /* 224 */
|
|
|
1028 |
new ABRPresets(256, 9, 9, 1, 0.97, 5.20, 125, 0, 1.00, -8, 10.0, 1, 0, 0), /* 256 */
|
|
|
1029 |
new ABRPresets(320, 9, 9, 1, 0.90, 5.20, 125, 0, 1.00, -10, 12.0, 0, 0, 0) /* 320 */
|
|
|
1030 |
];
|
|
|
1031 |
|
|
|
1032 |
function apply_abr_preset(gfp, preset, enforce) {
|
|
|
1033 |
/* Variables for the ABR stuff */
|
|
|
1034 |
var actual_bitrate = preset;
|
|
|
1035 |
|
|
|
1036 |
var r = lame.nearestBitrateFullIndex(preset);
|
|
|
1037 |
|
|
|
1038 |
gfp.VBR = VbrMode.vbr_abr;
|
|
|
1039 |
gfp.VBR_mean_bitrate_kbps = actual_bitrate;
|
|
|
1040 |
gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, 320);
|
|
|
1041 |
gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, 8);
|
|
|
1042 |
gfp.brate = gfp.VBR_mean_bitrate_kbps;
|
|
|
1043 |
if (gfp.VBR_mean_bitrate_kbps > 320) {
|
|
|
1044 |
gfp.disable_reservoir = true;
|
|
|
1045 |
}
|
|
|
1046 |
|
|
|
1047 |
/* parameters for which there is no proper set/get interface */
|
|
|
1048 |
if (abr_switch_map[r].safejoint > 0)
|
|
|
1049 |
gfp.exp_nspsytune = gfp.exp_nspsytune | 2;
|
|
|
1050 |
/* safejoint */
|
|
|
1051 |
|
|
|
1052 |
if (abr_switch_map[r].sfscale > 0) {
|
|
|
1053 |
gfp.internal_flags.noise_shaping = 2;
|
|
|
1054 |
}
|
|
|
1055 |
/* ns-bass tweaks */
|
|
|
1056 |
if (Math.abs(abr_switch_map[r].nsbass) > 0) {
|
|
|
1057 |
var k = (int)(abr_switch_map[r].nsbass * 4);
|
|
|
1058 |
if (k < 0)
|
|
|
1059 |
k += 64;
|
|
|
1060 |
gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 2);
|
|
|
1061 |
}
|
|
|
1062 |
|
|
|
1063 |
if (enforce != 0)
|
|
|
1064 |
gfp.quant_comp = abr_switch_map[r].quant_comp;
|
|
|
1065 |
else if (!(Math.abs(gfp.quant_comp - -1) > 0))
|
|
|
1066 |
gfp.quant_comp = abr_switch_map[r].quant_comp;
|
|
|
1067 |
// SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1);
|
|
|
1068 |
if (enforce != 0)
|
|
|
1069 |
gfp.quant_comp_short = abr_switch_map[r].quant_comp_s;
|
|
|
1070 |
else if (!(Math.abs(gfp.quant_comp_short - -1) > 0))
|
|
|
1071 |
gfp.quant_comp_short = abr_switch_map[r].quant_comp_s;
|
|
|
1072 |
// SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1);
|
|
|
1073 |
|
|
|
1074 |
if (enforce != 0)
|
|
|
1075 |
gfp.msfix = abr_switch_map[r].nsmsfix;
|
|
|
1076 |
else if (!(Math.abs(gfp.msfix - -1) > 0))
|
|
|
1077 |
gfp.msfix = abr_switch_map[r].nsmsfix;
|
|
|
1078 |
// SET_OPTION(msfix, abr_switch_map[r].nsmsfix, -1);
|
|
|
1079 |
|
|
|
1080 |
if (enforce != 0)
|
|
|
1081 |
gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm;
|
|
|
1082 |
else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0))
|
|
|
1083 |
gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm;
|
|
|
1084 |
// SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1);
|
|
|
1085 |
if (enforce != 0)
|
|
|
1086 |
gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s;
|
|
|
1087 |
else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0))
|
|
|
1088 |
gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s;
|
|
|
1089 |
// SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1);
|
|
|
1090 |
|
|
|
1091 |
/*
|
|
|
1092 |
* ABR seems to have big problems with clipping, especially at low
|
|
|
1093 |
* bitrates
|
|
|
1094 |
*/
|
|
|
1095 |
/*
|
|
|
1096 |
* so we compensate for that here by using a scale value depending on
|
|
|
1097 |
* bitrate
|
|
|
1098 |
*/
|
|
|
1099 |
if (enforce != 0)
|
|
|
1100 |
gfp.scale = abr_switch_map[r].scale;
|
|
|
1101 |
else if (!(Math.abs(gfp.scale - -1) > 0))
|
|
|
1102 |
gfp.scale = abr_switch_map[r].scale;
|
|
|
1103 |
// SET_OPTION(scale, abr_switch_map[r].scale, -1);
|
|
|
1104 |
|
|
|
1105 |
if (enforce != 0)
|
|
|
1106 |
gfp.maskingadjust = abr_switch_map[r].masking_adj;
|
|
|
1107 |
else if (!(Math.abs(gfp.maskingadjust - 0) > 0))
|
|
|
1108 |
gfp.maskingadjust = abr_switch_map[r].masking_adj;
|
|
|
1109 |
// SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0);
|
|
|
1110 |
if (abr_switch_map[r].masking_adj > 0) {
|
|
|
1111 |
if (enforce != 0)
|
|
|
1112 |
gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9);
|
|
|
1113 |
else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0))
|
|
|
1114 |
gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9);
|
|
|
1115 |
// SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj *
|
|
|
1116 |
// .9, 0);
|
|
|
1117 |
} else {
|
|
|
1118 |
if (enforce != 0)
|
|
|
1119 |
gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1);
|
|
|
1120 |
else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0))
|
|
|
1121 |
gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1);
|
|
|
1122 |
// SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj *
|
|
|
1123 |
// 1.1, 0);
|
|
|
1124 |
}
|
|
|
1125 |
|
|
|
1126 |
if (enforce != 0)
|
|
|
1127 |
gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.;
|
|
|
1128 |
else if (!(Math.abs((-gfp.ATHlower * 10.) - 0) > 0))
|
|
|
1129 |
gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.;
|
|
|
1130 |
// SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0);
|
|
|
1131 |
if (enforce != 0)
|
|
|
1132 |
gfp.ATHcurve = abr_switch_map[r].ath_curve;
|
|
|
1133 |
else if (!(Math.abs(gfp.ATHcurve - -1) > 0))
|
|
|
1134 |
gfp.ATHcurve = abr_switch_map[r].ath_curve;
|
|
|
1135 |
// SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1);
|
|
|
1136 |
|
|
|
1137 |
if (enforce != 0)
|
|
|
1138 |
gfp.interChRatio = abr_switch_map[r].interch;
|
|
|
1139 |
else if (!(Math.abs(gfp.interChRatio - -1) > 0))
|
|
|
1140 |
gfp.interChRatio = abr_switch_map[r].interch;
|
|
|
1141 |
// SET_OPTION(interChRatio, abr_switch_map[r].interch, -1);
|
|
|
1142 |
|
|
|
1143 |
return preset;
|
|
|
1144 |
}
|
|
|
1145 |
|
|
|
1146 |
this.apply_preset = function(gfp, preset, enforce) {
|
|
|
1147 |
/* translate legacy presets */
|
|
|
1148 |
switch (preset) {
|
|
|
1149 |
case Lame.R3MIX:
|
|
|
1150 |
{
|
|
|
1151 |
preset = Lame.V3;
|
|
|
1152 |
gfp.VBR = VbrMode.vbr_mtrh;
|
|
|
1153 |
break;
|
|
|
1154 |
}
|
|
|
1155 |
case Lame.MEDIUM:
|
|
|
1156 |
{
|
|
|
1157 |
preset = Lame.V4;
|
|
|
1158 |
gfp.VBR = VbrMode.vbr_rh;
|
|
|
1159 |
break;
|
|
|
1160 |
}
|
|
|
1161 |
case Lame.MEDIUM_FAST:
|
|
|
1162 |
{
|
|
|
1163 |
preset = Lame.V4;
|
|
|
1164 |
gfp.VBR = VbrMode.vbr_mtrh;
|
|
|
1165 |
break;
|
|
|
1166 |
}
|
|
|
1167 |
case Lame.STANDARD:
|
|
|
1168 |
{
|
|
|
1169 |
preset = Lame.V2;
|
|
|
1170 |
gfp.VBR = VbrMode.vbr_rh;
|
|
|
1171 |
break;
|
|
|
1172 |
}
|
|
|
1173 |
case Lame.STANDARD_FAST:
|
|
|
1174 |
{
|
|
|
1175 |
preset = Lame.V2;
|
|
|
1176 |
gfp.VBR = VbrMode.vbr_mtrh;
|
|
|
1177 |
break;
|
|
|
1178 |
}
|
|
|
1179 |
case Lame.EXTREME:
|
|
|
1180 |
{
|
|
|
1181 |
preset = Lame.V0;
|
|
|
1182 |
gfp.VBR = VbrMode.vbr_rh;
|
|
|
1183 |
break;
|
|
|
1184 |
}
|
|
|
1185 |
case Lame.EXTREME_FAST:
|
|
|
1186 |
{
|
|
|
1187 |
preset = Lame.V0;
|
|
|
1188 |
gfp.VBR = VbrMode.vbr_mtrh;
|
|
|
1189 |
break;
|
|
|
1190 |
}
|
|
|
1191 |
case Lame.INSANE:
|
|
|
1192 |
{
|
|
|
1193 |
preset = 320;
|
|
|
1194 |
gfp.preset = preset;
|
|
|
1195 |
apply_abr_preset(gfp, preset, enforce);
|
|
|
1196 |
gfp.VBR = VbrMode.vbr_off;
|
|
|
1197 |
return preset;
|
|
|
1198 |
}
|
|
|
1199 |
}
|
|
|
1200 |
|
|
|
1201 |
gfp.preset = preset;
|
|
|
1202 |
{
|
|
|
1203 |
switch (preset) {
|
|
|
1204 |
case Lame.V9:
|
|
|
1205 |
apply_vbr_preset(gfp, 9, enforce);
|
|
|
1206 |
return preset;
|
|
|
1207 |
case Lame.V8:
|
|
|
1208 |
apply_vbr_preset(gfp, 8, enforce);
|
|
|
1209 |
return preset;
|
|
|
1210 |
case Lame.V7:
|
|
|
1211 |
apply_vbr_preset(gfp, 7, enforce);
|
|
|
1212 |
return preset;
|
|
|
1213 |
case Lame.V6:
|
|
|
1214 |
apply_vbr_preset(gfp, 6, enforce);
|
|
|
1215 |
return preset;
|
|
|
1216 |
case Lame.V5:
|
|
|
1217 |
apply_vbr_preset(gfp, 5, enforce);
|
|
|
1218 |
return preset;
|
|
|
1219 |
case Lame.V4:
|
|
|
1220 |
apply_vbr_preset(gfp, 4, enforce);
|
|
|
1221 |
return preset;
|
|
|
1222 |
case Lame.V3:
|
|
|
1223 |
apply_vbr_preset(gfp, 3, enforce);
|
|
|
1224 |
return preset;
|
|
|
1225 |
case Lame.V2:
|
|
|
1226 |
apply_vbr_preset(gfp, 2, enforce);
|
|
|
1227 |
return preset;
|
|
|
1228 |
case Lame.V1:
|
|
|
1229 |
apply_vbr_preset(gfp, 1, enforce);
|
|
|
1230 |
return preset;
|
|
|
1231 |
case Lame.V0:
|
|
|
1232 |
apply_vbr_preset(gfp, 0, enforce);
|
|
|
1233 |
return preset;
|
|
|
1234 |
default:
|
|
|
1235 |
break;
|
|
|
1236 |
}
|
|
|
1237 |
}
|
|
|
1238 |
if (8 <= preset && preset <= 320) {
|
|
|
1239 |
return apply_abr_preset(gfp, preset, enforce);
|
|
|
1240 |
}
|
|
|
1241 |
|
|
|
1242 |
/* no corresponding preset found */
|
|
|
1243 |
gfp.preset = 0;
|
|
|
1244 |
return preset;
|
|
|
1245 |
}
|
|
|
1246 |
|
|
|
1247 |
// Rest from getset.c:
|
|
|
1248 |
|
|
|
1249 |
/**
|
|
|
1250 |
* VBR quality level.<BR>
|
|
|
1251 |
* 0 = highest<BR>
|
|
|
1252 |
* 9 = lowest
|
|
|
1253 |
*/
|
|
|
1254 |
function lame_set_VBR_q(gfp, VBR_q) {
|
|
|
1255 |
var ret = 0;
|
|
|
1256 |
|
|
|
1257 |
if (0 > VBR_q) {
|
|
|
1258 |
/* Unknown VBR quality level! */
|
|
|
1259 |
ret = -1;
|
|
|
1260 |
VBR_q = 0;
|
|
|
1261 |
}
|
|
|
1262 |
if (9 < VBR_q) {
|
|
|
1263 |
ret = -1;
|
|
|
1264 |
VBR_q = 9;
|
|
|
1265 |
}
|
|
|
1266 |
|
|
|
1267 |
gfp.VBR_q = VBR_q;
|
|
|
1268 |
gfp.VBR_q_frac = 0;
|
|
|
1269 |
return ret;
|
|
|
1270 |
}
|
|
|
1271 |
|
|
|
1272 |
}
|
|
|
1273 |
|
|
|
1274 |
/*
|
|
|
1275 |
* MP3 huffman table selecting and bit counting
|
|
|
1276 |
*
|
|
|
1277 |
* Copyright (c) 1999-2005 Takehiro TOMINAGA
|
|
|
1278 |
* Copyright (c) 2002-2005 Gabriel Bouvigne
|
|
|
1279 |
*
|
|
|
1280 |
* This library is free software; you can redistribute it and/or
|
|
|
1281 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
1282 |
* License as published by the Free Software Foundation; either
|
|
|
1283 |
* version 2 of the License, or (at your option) any later version.
|
|
|
1284 |
*
|
|
|
1285 |
* This library is distributed in the hope that it will be useful,
|
|
|
1286 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
1287 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
1288 |
* Library General Public License for more details.
|
|
|
1289 |
*
|
|
|
1290 |
* You should have received a copy of the GNU Lesser General Public
|
|
|
1291 |
* License along with this library; if not, write to the
|
|
|
1292 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
1293 |
* Boston, MA 02111-1307, USA.
|
|
|
1294 |
*/
|
|
|
1295 |
|
|
|
1296 |
/* $Id: Takehiro.java,v 1.26 2011/05/24 20:48:06 kenchis Exp $ */
|
|
|
1297 |
|
|
|
1298 |
//package mp3;
|
|
|
1299 |
|
|
|
1300 |
//import java.util.Arrays;
|
|
|
1301 |
|
|
|
1302 |
|
|
|
1303 |
|
|
|
1304 |
function Takehiro() {
|
|
|
1305 |
|
|
|
1306 |
var qupvt = null;
|
|
|
1307 |
this.qupvt = null;
|
|
|
1308 |
|
|
|
1309 |
this.setModules = function (_qupvt) {
|
|
|
1310 |
this.qupvt = _qupvt;
|
|
|
1311 |
qupvt = _qupvt;
|
|
|
1312 |
}
|
|
|
1313 |
|
|
|
1314 |
function Bits(b) {
|
|
|
1315 |
this.bits = 0 | b;
|
|
|
1316 |
}
|
|
|
1317 |
|
|
|
1318 |
var subdv_table = [[0, 0], /* 0 bands */
|
|
|
1319 |
[0, 0], /* 1 bands */
|
|
|
1320 |
[0, 0], /* 2 bands */
|
|
|
1321 |
[0, 0], /* 3 bands */
|
|
|
1322 |
[0, 0], /* 4 bands */
|
|
|
1323 |
[0, 1], /* 5 bands */
|
|
|
1324 |
[1, 1], /* 6 bands */
|
|
|
1325 |
[1, 1], /* 7 bands */
|
|
|
1326 |
[1, 2], /* 8 bands */
|
|
|
1327 |
[2, 2], /* 9 bands */
|
|
|
1328 |
[2, 3], /* 10 bands */
|
|
|
1329 |
[2, 3], /* 11 bands */
|
|
|
1330 |
[3, 4], /* 12 bands */
|
|
|
1331 |
[3, 4], /* 13 bands */
|
|
|
1332 |
[3, 4], /* 14 bands */
|
|
|
1333 |
[4, 5], /* 15 bands */
|
|
|
1334 |
[4, 5], /* 16 bands */
|
|
|
1335 |
[4, 6], /* 17 bands */
|
|
|
1336 |
[5, 6], /* 18 bands */
|
|
|
1337 |
[5, 6], /* 19 bands */
|
|
|
1338 |
[5, 7], /* 20 bands */
|
|
|
1339 |
[6, 7], /* 21 bands */
|
|
|
1340 |
[6, 7], /* 22 bands */
|
|
|
1341 |
];
|
|
|
1342 |
|
|
|
1343 |
/**
|
|
|
1344 |
* nonlinear quantization of xr More accurate formula than the ISO formula.
|
|
|
1345 |
* Takes into account the fact that we are quantizing xr . ix, but we want
|
|
|
1346 |
* ix^4/3 to be as close as possible to x^4/3. (taking the nearest int would
|
|
|
1347 |
* mean ix is as close as possible to xr, which is different.)
|
|
|
1348 |
*
|
|
|
1349 |
* From Segher Boessenkool <segher@eastsite.nl> 11/1999
|
|
|
1350 |
*
|
|
|
1351 |
* 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro Tominaga.
|
|
|
1352 |
* If you need the ASM code, check CVS circa Aug 2000.
|
|
|
1353 |
*
|
|
|
1354 |
* 01/2004: Optimizations by Gabriel Bouvigne
|
|
|
1355 |
*/
|
|
|
1356 |
function quantize_lines_xrpow_01(l, istep, xr, xrPos, ix, ixPos) {
|
|
|
1357 |
var compareval0 = (1.0 - 0.4054) / istep;
|
|
|
1358 |
|
|
|
1359 |
l = l >> 1;
|
|
|
1360 |
while ((l--) != 0) {
|
|
|
1361 |
ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1;
|
|
|
1362 |
ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1;
|
|
|
1363 |
}
|
|
|
1364 |
}
|
|
|
1365 |
|
|
|
1366 |
/**
|
|
|
1367 |
* XRPOW_FTOI is a macro to convert floats to ints.<BR>
|
|
|
1368 |
* if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]<BR>
|
|
|
1369 |
* ROUNDFAC= -0.0946<BR>
|
|
|
1370 |
*
|
|
|
1371 |
* if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]<BR>
|
|
|
1372 |
* ROUNDFAC=0.4054<BR>
|
|
|
1373 |
*
|
|
|
1374 |
* Note: using floor() or 0| is extremely slow. On machines where the
|
|
|
1375 |
* TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile to write
|
|
|
1376 |
* some ASM for XRPOW_FTOI().
|
|
|
1377 |
*/
|
|
|
1378 |
function quantize_lines_xrpow(l, istep, xr, xrPos, ix, ixPos) {
|
|
|
1379 |
|
|
|
1380 |
l = l >> 1;
|
|
|
1381 |
var remaining = l % 2;
|
|
|
1382 |
l = l >> 1;
|
|
|
1383 |
while (l-- != 0) {
|
|
|
1384 |
var x0, x1, x2, x3;
|
|
|
1385 |
var rx0, rx1, rx2, rx3;
|
|
|
1386 |
|
|
|
1387 |
x0 = xr[xrPos++] * istep;
|
|
|
1388 |
x1 = xr[xrPos++] * istep;
|
|
|
1389 |
rx0 = 0 | x0;
|
|
|
1390 |
x2 = xr[xrPos++] * istep;
|
|
|
1391 |
rx1 = 0 | x1;
|
|
|
1392 |
x3 = xr[xrPos++] * istep;
|
|
|
1393 |
rx2 = 0 | x2;
|
|
|
1394 |
x0 += qupvt.adj43[rx0];
|
|
|
1395 |
rx3 = 0 | x3;
|
|
|
1396 |
x1 += qupvt.adj43[rx1];
|
|
|
1397 |
ix[ixPos++] = 0 | x0;
|
|
|
1398 |
x2 += qupvt.adj43[rx2];
|
|
|
1399 |
ix[ixPos++] = 0 | x1;
|
|
|
1400 |
x3 += qupvt.adj43[rx3];
|
|
|
1401 |
ix[ixPos++] = 0 | x2;
|
|
|
1402 |
ix[ixPos++] = 0 | x3;
|
|
|
1403 |
}
|
|
|
1404 |
if (remaining != 0) {
|
|
|
1405 |
var x0, x1;
|
|
|
1406 |
var rx0, rx1;
|
|
|
1407 |
|
|
|
1408 |
x0 = xr[xrPos++] * istep;
|
|
|
1409 |
x1 = xr[xrPos++] * istep;
|
|
|
1410 |
rx0 = 0 | x0;
|
|
|
1411 |
rx1 = 0 | x1;
|
|
|
1412 |
x0 += qupvt.adj43[rx0];
|
|
|
1413 |
x1 += qupvt.adj43[rx1];
|
|
|
1414 |
ix[ixPos++] = 0 | x0;
|
|
|
1415 |
ix[ixPos++] = 0 | x1;
|
|
|
1416 |
}
|
|
|
1417 |
}
|
|
|
1418 |
|
|
|
1419 |
/**
|
|
|
1420 |
* Quantization function This function will select which lines to quantize
|
|
|
1421 |
* and call the proper quantization function
|
|
|
1422 |
*/
|
|
|
1423 |
function quantize_xrpow(xp, pi, istep, codInfo, prevNoise) {
|
|
|
1424 |
/* quantize on xr^(3/4) instead of xr */
|
|
|
1425 |
var sfb;
|
|
|
1426 |
var sfbmax;
|
|
|
1427 |
var j = 0;
|
|
|
1428 |
var prev_data_use;
|
|
|
1429 |
var accumulate = 0;
|
|
|
1430 |
var accumulate01 = 0;
|
|
|
1431 |
var xpPos = 0;
|
|
|
1432 |
var iData = pi;
|
|
|
1433 |
var iDataPos = 0;
|
|
|
1434 |
var acc_iData = iData;
|
|
|
1435 |
var acc_iDataPos = 0;
|
|
|
1436 |
var acc_xp = xp;
|
|
|
1437 |
var acc_xpPos = 0;
|
|
|
1438 |
|
|
|
1439 |
/*
|
|
|
1440 |
* Reusing previously computed data does not seems to work if global
|
|
|
1441 |
* gain is changed. Finding why it behaves this way would allow to use a
|
|
|
1442 |
* cache of previously computed values (let's 10 cached values per sfb)
|
|
|
1443 |
* that would probably provide a noticeable speedup
|
|
|
1444 |
*/
|
|
|
1445 |
prev_data_use = (prevNoise != null && (codInfo.global_gain == prevNoise.global_gain));
|
|
|
1446 |
|
|
|
1447 |
if (codInfo.block_type == Encoder.SHORT_TYPE)
|
|
|
1448 |
sfbmax = 38;
|
|
|
1449 |
else
|
|
|
1450 |
sfbmax = 21;
|
|
|
1451 |
|
|
|
1452 |
for (sfb = 0; sfb <= sfbmax; sfb++) {
|
|
|
1453 |
var step = -1;
|
|
|
1454 |
|
|
|
1455 |
if (prev_data_use || codInfo.block_type == Encoder.NORM_TYPE) {
|
|
|
1456 |
step = codInfo.global_gain
|
|
|
1457 |
- ((codInfo.scalefac[sfb] + (codInfo.preflag != 0 ? qupvt.pretab[sfb]
|
|
|
1458 |
: 0)) << (codInfo.scalefac_scale + 1))
|
|
|
1459 |
- codInfo.subblock_gain[codInfo.window[sfb]] * 8;
|
|
|
1460 |
}
|
|
|
1461 |
if (prev_data_use && (prevNoise.step[sfb] == step)) {
|
|
|
1462 |
/*
|
|
|
1463 |
* do not recompute this part, but compute accumulated lines
|
|
|
1464 |
*/
|
|
|
1465 |
if (accumulate != 0) {
|
|
|
1466 |
quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos,
|
|
|
1467 |
acc_iData, acc_iDataPos);
|
|
|
1468 |
accumulate = 0;
|
|
|
1469 |
}
|
|
|
1470 |
if (accumulate01 != 0) {
|
|
|
1471 |
quantize_lines_xrpow_01(accumulate01, istep, acc_xp,
|
|
|
1472 |
acc_xpPos, acc_iData, acc_iDataPos);
|
|
|
1473 |
accumulate01 = 0;
|
|
|
1474 |
}
|
|
|
1475 |
} else { /* should compute this part */
|
|
|
1476 |
var l = codInfo.width[sfb];
|
|
|
1477 |
|
|
|
1478 |
if ((j + codInfo.width[sfb]) > codInfo.max_nonzero_coeff) {
|
|
|
1479 |
/* do not compute upper zero part */
|
|
|
1480 |
var usefullsize;
|
|
|
1481 |
usefullsize = codInfo.max_nonzero_coeff - j + 1;
|
|
|
1482 |
Arrays.fill(pi, codInfo.max_nonzero_coeff, 576, 0);
|
|
|
1483 |
l = usefullsize;
|
|
|
1484 |
|
|
|
1485 |
if (l < 0) {
|
|
|
1486 |
l = 0;
|
|
|
1487 |
}
|
|
|
1488 |
|
|
|
1489 |
/* no need to compute higher sfb values */
|
|
|
1490 |
sfb = sfbmax + 1;
|
|
|
1491 |
}
|
|
|
1492 |
|
|
|
1493 |
/* accumulate lines to quantize */
|
|
|
1494 |
if (0 == accumulate && 0 == accumulate01) {
|
|
|
1495 |
acc_iData = iData;
|
|
|
1496 |
acc_iDataPos = iDataPos;
|
|
|
1497 |
acc_xp = xp;
|
|
|
1498 |
acc_xpPos = xpPos;
|
|
|
1499 |
}
|
|
|
1500 |
if (prevNoise != null && prevNoise.sfb_count1 > 0
|
|
|
1501 |
&& sfb >= prevNoise.sfb_count1
|
|
|
1502 |
&& prevNoise.step[sfb] > 0
|
|
|
1503 |
&& step >= prevNoise.step[sfb]) {
|
|
|
1504 |
|
|
|
1505 |
if (accumulate != 0) {
|
|
|
1506 |
quantize_lines_xrpow(accumulate, istep, acc_xp,
|
|
|
1507 |
acc_xpPos, acc_iData, acc_iDataPos);
|
|
|
1508 |
accumulate = 0;
|
|
|
1509 |
acc_iData = iData;
|
|
|
1510 |
acc_iDataPos = iDataPos;
|
|
|
1511 |
acc_xp = xp;
|
|
|
1512 |
acc_xpPos = xpPos;
|
|
|
1513 |
}
|
|
|
1514 |
accumulate01 += l;
|
|
|
1515 |
} else {
|
|
|
1516 |
if (accumulate01 != 0) {
|
|
|
1517 |
quantize_lines_xrpow_01(accumulate01, istep, acc_xp,
|
|
|
1518 |
acc_xpPos, acc_iData, acc_iDataPos);
|
|
|
1519 |
accumulate01 = 0;
|
|
|
1520 |
acc_iData = iData;
|
|
|
1521 |
acc_iDataPos = iDataPos;
|
|
|
1522 |
acc_xp = xp;
|
|
|
1523 |
acc_xpPos = xpPos;
|
|
|
1524 |
}
|
|
|
1525 |
accumulate += l;
|
|
|
1526 |
}
|
|
|
1527 |
|
|
|
1528 |
if (l <= 0) {
|
|
|
1529 |
/*
|
|
|
1530 |
* rh: 20040215 may happen due to "prev_data_use"
|
|
|
1531 |
* optimization
|
|
|
1532 |
*/
|
|
|
1533 |
if (accumulate01 != 0) {
|
|
|
1534 |
quantize_lines_xrpow_01(accumulate01, istep, acc_xp,
|
|
|
1535 |
acc_xpPos, acc_iData, acc_iDataPos);
|
|
|
1536 |
accumulate01 = 0;
|
|
|
1537 |
}
|
|
|
1538 |
if (accumulate != 0) {
|
|
|
1539 |
quantize_lines_xrpow(accumulate, istep, acc_xp,
|
|
|
1540 |
acc_xpPos, acc_iData, acc_iDataPos);
|
|
|
1541 |
accumulate = 0;
|
|
|
1542 |
}
|
|
|
1543 |
|
|
|
1544 |
break;
|
|
|
1545 |
/* ends for-loop */
|
|
|
1546 |
}
|
|
|
1547 |
}
|
|
|
1548 |
if (sfb <= sfbmax) {
|
|
|
1549 |
iDataPos += codInfo.width[sfb];
|
|
|
1550 |
xpPos += codInfo.width[sfb];
|
|
|
1551 |
j += codInfo.width[sfb];
|
|
|
1552 |
}
|
|
|
1553 |
}
|
|
|
1554 |
if (accumulate != 0) { /* last data part */
|
|
|
1555 |
quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos,
|
|
|
1556 |
acc_iData, acc_iDataPos);
|
|
|
1557 |
accumulate = 0;
|
|
|
1558 |
}
|
|
|
1559 |
if (accumulate01 != 0) { /* last data part */
|
|
|
1560 |
quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_xpPos,
|
|
|
1561 |
acc_iData, acc_iDataPos);
|
|
|
1562 |
accumulate01 = 0;
|
|
|
1563 |
}
|
|
|
1564 |
|
|
|
1565 |
}
|
|
|
1566 |
|
|
|
1567 |
/**
|
|
|
1568 |
* ix_max
|
|
|
1569 |
*/
|
|
|
1570 |
function ix_max(ix, ixPos, endPos) {
|
|
|
1571 |
var max1 = 0, max2 = 0;
|
|
|
1572 |
|
|
|
1573 |
do {
|
|
|
1574 |
var x1 = ix[ixPos++];
|
|
|
1575 |
var x2 = ix[ixPos++];
|
|
|
1576 |
if (max1 < x1)
|
|
|
1577 |
max1 = x1;
|
|
|
1578 |
|
|
|
1579 |
if (max2 < x2)
|
|
|
1580 |
max2 = x2;
|
|
|
1581 |
} while (ixPos < endPos);
|
|
|
1582 |
if (max1 < max2)
|
|
|
1583 |
max1 = max2;
|
|
|
1584 |
return max1;
|
|
|
1585 |
}
|
|
|
1586 |
|
|
|
1587 |
function count_bit_ESC(ix, ixPos, end, t1, t2, s) {
|
|
|
1588 |
/* ESC-table is used */
|
|
|
1589 |
var linbits = Tables.ht[t1].xlen * 65536 + Tables.ht[t2].xlen;
|
|
|
1590 |
var sum = 0, sum2;
|
|
|
1591 |
|
|
|
1592 |
do {
|
|
|
1593 |
var x = ix[ixPos++];
|
|
|
1594 |
var y = ix[ixPos++];
|
|
|
1595 |
|
|
|
1596 |
if (x != 0) {
|
|
|
1597 |
if (x > 14) {
|
|
|
1598 |
x = 15;
|
|
|
1599 |
sum += linbits;
|
|
|
1600 |
}
|
|
|
1601 |
x *= 16;
|
|
|
1602 |
}
|
|
|
1603 |
|
|
|
1604 |
if (y != 0) {
|
|
|
1605 |
if (y > 14) {
|
|
|
1606 |
y = 15;
|
|
|
1607 |
sum += linbits;
|
|
|
1608 |
}
|
|
|
1609 |
x += y;
|
|
|
1610 |
}
|
|
|
1611 |
|
|
|
1612 |
sum += Tables.largetbl[x];
|
|
|
1613 |
} while (ixPos < end);
|
|
|
1614 |
|
|
|
1615 |
sum2 = sum & 0xffff;
|
|
|
1616 |
sum >>= 16;
|
|
|
1617 |
|
|
|
1618 |
if (sum > sum2) {
|
|
|
1619 |
sum = sum2;
|
|
|
1620 |
t1 = t2;
|
|
|
1621 |
}
|
|
|
1622 |
|
|
|
1623 |
s.bits += sum;
|
|
|
1624 |
return t1;
|
|
|
1625 |
}
|
|
|
1626 |
|
|
|
1627 |
function count_bit_noESC(ix, ixPos, end, s) {
|
|
|
1628 |
/* No ESC-words */
|
|
|
1629 |
var sum1 = 0;
|
|
|
1630 |
var hlen1 = Tables.ht[1].hlen;
|
|
|
1631 |
|
|
|
1632 |
do {
|
|
|
1633 |
var x = ix[ixPos + 0] * 2 + ix[ixPos + 1];
|
|
|
1634 |
ixPos += 2;
|
|
|
1635 |
sum1 += hlen1[x];
|
|
|
1636 |
} while (ixPos < end);
|
|
|
1637 |
|
|
|
1638 |
s.bits += sum1;
|
|
|
1639 |
return 1;
|
|
|
1640 |
}
|
|
|
1641 |
|
|
|
1642 |
function count_bit_noESC_from2(ix, ixPos, end, t1, s) {
|
|
|
1643 |
/* No ESC-words */
|
|
|
1644 |
var sum = 0, sum2;
|
|
|
1645 |
var xlen = Tables.ht[t1].xlen;
|
|
|
1646 |
var hlen;
|
|
|
1647 |
if (t1 == 2)
|
|
|
1648 |
hlen = Tables.table23;
|
|
|
1649 |
else
|
|
|
1650 |
hlen = Tables.table56;
|
|
|
1651 |
|
|
|
1652 |
do {
|
|
|
1653 |
var x = ix[ixPos + 0] * xlen + ix[ixPos + 1];
|
|
|
1654 |
ixPos += 2;
|
|
|
1655 |
sum += hlen[x];
|
|
|
1656 |
} while (ixPos < end);
|
|
|
1657 |
|
|
|
1658 |
sum2 = sum & 0xffff;
|
|
|
1659 |
sum >>= 16;
|
|
|
1660 |
|
|
|
1661 |
if (sum > sum2) {
|
|
|
1662 |
sum = sum2;
|
|
|
1663 |
t1++;
|
|
|
1664 |
}
|
|
|
1665 |
|
|
|
1666 |
s.bits += sum;
|
|
|
1667 |
return t1;
|
|
|
1668 |
}
|
|
|
1669 |
|
|
|
1670 |
function count_bit_noESC_from3(ix, ixPos, end, t1, s) {
|
|
|
1671 |
/* No ESC-words */
|
|
|
1672 |
var sum1 = 0;
|
|
|
1673 |
var sum2 = 0;
|
|
|
1674 |
var sum3 = 0;
|
|
|
1675 |
var xlen = Tables.ht[t1].xlen;
|
|
|
1676 |
var hlen1 = Tables.ht[t1].hlen;
|
|
|
1677 |
var hlen2 = Tables.ht[t1 + 1].hlen;
|
|
|
1678 |
var hlen3 = Tables.ht[t1 + 2].hlen;
|
|
|
1679 |
|
|
|
1680 |
do {
|
|
|
1681 |
var x = ix[ixPos + 0] * xlen + ix[ixPos + 1];
|
|
|
1682 |
ixPos += 2;
|
|
|
1683 |
sum1 += hlen1[x];
|
|
|
1684 |
sum2 += hlen2[x];
|
|
|
1685 |
sum3 += hlen3[x];
|
|
|
1686 |
} while (ixPos < end);
|
|
|
1687 |
var t = t1;
|
|
|
1688 |
if (sum1 > sum2) {
|
|
|
1689 |
sum1 = sum2;
|
|
|
1690 |
t++;
|
|
|
1691 |
}
|
|
|
1692 |
if (sum1 > sum3) {
|
|
|
1693 |
sum1 = sum3;
|
|
|
1694 |
t = t1 + 2;
|
|
|
1695 |
}
|
|
|
1696 |
s.bits += sum1;
|
|
|
1697 |
|
|
|
1698 |
return t;
|
|
|
1699 |
}
|
|
|
1700 |
|
|
|
1701 |
/*************************************************************************/
|
|
|
1702 |
/* choose table */
|
|
|
1703 |
/*************************************************************************/
|
|
|
1704 |
|
|
|
1705 |
var huf_tbl_noESC = [1, 2, 5, 7, 7, 10, 10, 13, 13,
|
|
|
1706 |
13, 13, 13, 13, 13, 13];
|
|
|
1707 |
|
|
|
1708 |
/**
|
|
|
1709 |
* Choose the Huffman table that will encode ix[begin..end] with the fewest
|
|
|
1710 |
* bits.
|
|
|
1711 |
*
|
|
|
1712 |
* Note: This code contains knowledge about the sizes and characteristics of
|
|
|
1713 |
* the Huffman tables as defined in the IS (Table B.7), and will not work
|
|
|
1714 |
* with any arbitrary tables.
|
|
|
1715 |
*/
|
|
|
1716 |
function choose_table(ix, ixPos, endPos, s) {
|
|
|
1717 |
var max = ix_max(ix, ixPos, endPos);
|
|
|
1718 |
|
|
|
1719 |
switch (max) {
|
|
|
1720 |
case 0:
|
|
|
1721 |
return max;
|
|
|
1722 |
|
|
|
1723 |
case 1:
|
|
|
1724 |
return count_bit_noESC(ix, ixPos, endPos, s);
|
|
|
1725 |
|
|
|
1726 |
case 2:
|
|
|
1727 |
case 3:
|
|
|
1728 |
return count_bit_noESC_from2(ix, ixPos, endPos,
|
|
|
1729 |
huf_tbl_noESC[max - 1], s);
|
|
|
1730 |
|
|
|
1731 |
case 4:
|
|
|
1732 |
case 5:
|
|
|
1733 |
case 6:
|
|
|
1734 |
case 7:
|
|
|
1735 |
case 8:
|
|
|
1736 |
case 9:
|
|
|
1737 |
case 10:
|
|
|
1738 |
case 11:
|
|
|
1739 |
case 12:
|
|
|
1740 |
case 13:
|
|
|
1741 |
case 14:
|
|
|
1742 |
case 15:
|
|
|
1743 |
return count_bit_noESC_from3(ix, ixPos, endPos,
|
|
|
1744 |
huf_tbl_noESC[max - 1], s);
|
|
|
1745 |
|
|
|
1746 |
default:
|
|
|
1747 |
/* try tables with linbits */
|
|
|
1748 |
if (max > QuantizePVT.IXMAX_VAL) {
|
|
|
1749 |
s.bits = QuantizePVT.LARGE_BITS;
|
|
|
1750 |
return -1;
|
|
|
1751 |
}
|
|
|
1752 |
max -= 15;
|
|
|
1753 |
var choice2;
|
|
|
1754 |
for (choice2 = 24; choice2 < 32; choice2++) {
|
|
|
1755 |
if (Tables.ht[choice2].linmax >= max) {
|
|
|
1756 |
break;
|
|
|
1757 |
}
|
|
|
1758 |
}
|
|
|
1759 |
var choice;
|
|
|
1760 |
for (choice = choice2 - 8; choice < 24; choice++) {
|
|
|
1761 |
if (Tables.ht[choice].linmax >= max) {
|
|
|
1762 |
break;
|
|
|
1763 |
}
|
|
|
1764 |
}
|
|
|
1765 |
return count_bit_ESC(ix, ixPos, endPos, choice, choice2, s);
|
|
|
1766 |
}
|
|
|
1767 |
}
|
|
|
1768 |
|
|
|
1769 |
/**
|
|
|
1770 |
* count_bit
|
|
|
1771 |
*/
|
|
|
1772 |
this.noquant_count_bits = function (gfc, gi, prev_noise) {
|
|
|
1773 |
var ix = gi.l3_enc;
|
|
|
1774 |
var i = Math.min(576, ((gi.max_nonzero_coeff + 2) >> 1) << 1);
|
|
|
1775 |
|
|
|
1776 |
if (prev_noise != null)
|
|
|
1777 |
prev_noise.sfb_count1 = 0;
|
|
|
1778 |
|
|
|
1779 |
/* Determine count1 region */
|
|
|
1780 |
for (; i > 1; i -= 2)
|
|
|
1781 |
if ((ix[i - 1] | ix[i - 2]) != 0)
|
|
|
1782 |
break;
|
|
|
1783 |
gi.count1 = i;
|
|
|
1784 |
|
|
|
1785 |
/* Determines the number of bits to encode the quadruples. */
|
|
|
1786 |
var a1 = 0;
|
|
|
1787 |
var a2 = 0;
|
|
|
1788 |
for (; i > 3; i -= 4) {
|
|
|
1789 |
var p;
|
|
|
1790 |
/* hack to check if all values <= 1 */
|
|
|
1791 |
//throw "TODO: HACK if ((((long) ix[i - 1] | (long) ix[i - 2] | (long) ix[i - 3] | (long) ix[i - 4]) & 0xffffffffL) > 1L "
|
|
|
1792 |
//if (true) {
|
|
|
1793 |
if (((ix[i - 1] | ix[i - 2] | ix[i - 3] | ix[i - 4]) & 0x7fffffff) > 1) {
|
|
|
1794 |
break;
|
|
|
1795 |
}
|
|
|
1796 |
p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + ix[i - 1];
|
|
|
1797 |
a1 += Tables.t32l[p];
|
|
|
1798 |
a2 += Tables.t33l[p];
|
|
|
1799 |
}
|
|
|
1800 |
var bits = a1;
|
|
|
1801 |
gi.count1table_select = 0;
|
|
|
1802 |
if (a1 > a2) {
|
|
|
1803 |
bits = a2;
|
|
|
1804 |
gi.count1table_select = 1;
|
|
|
1805 |
}
|
|
|
1806 |
|
|
|
1807 |
gi.count1bits = bits;
|
|
|
1808 |
gi.big_values = i;
|
|
|
1809 |
if (i == 0)
|
|
|
1810 |
return bits;
|
|
|
1811 |
|
|
|
1812 |
if (gi.block_type == Encoder.SHORT_TYPE) {
|
|
|
1813 |
a1 = 3 * gfc.scalefac_band.s[3];
|
|
|
1814 |
if (a1 > gi.big_values)
|
|
|
1815 |
a1 = gi.big_values;
|
|
|
1816 |
a2 = gi.big_values;
|
|
|
1817 |
|
|
|
1818 |
} else if (gi.block_type == Encoder.NORM_TYPE) {
|
|
|
1819 |
/* bv_scf has 576 entries (0..575) */
|
|
|
1820 |
a1 = gi.region0_count = gfc.bv_scf[i - 2];
|
|
|
1821 |
a2 = gi.region1_count = gfc.bv_scf[i - 1];
|
|
|
1822 |
|
|
|
1823 |
a2 = gfc.scalefac_band.l[a1 + a2 + 2];
|
|
|
1824 |
a1 = gfc.scalefac_band.l[a1 + 1];
|
|
|
1825 |
if (a2 < i) {
|
|
|
1826 |
var bi = new Bits(bits);
|
|
|
1827 |
gi.table_select[2] = choose_table(ix, a2, i, bi);
|
|
|
1828 |
bits = bi.bits;
|
|
|
1829 |
}
|
|
|
1830 |
} else {
|
|
|
1831 |
gi.region0_count = 7;
|
|
|
1832 |
/* gi.region1_count = SBPSY_l - 7 - 1; */
|
|
|
1833 |
gi.region1_count = Encoder.SBMAX_l - 1 - 7 - 1;
|
|
|
1834 |
a1 = gfc.scalefac_band.l[7 + 1];
|
|
|
1835 |
a2 = i;
|
|
|
1836 |
if (a1 > a2) {
|
|
|
1837 |
a1 = a2;
|
|
|
1838 |
}
|
|
|
1839 |
}
|
|
|
1840 |
|
|
|
1841 |
/* have to allow for the case when bigvalues < region0 < region1 */
|
|
|
1842 |
/* (and region0, region1 are ignored) */
|
|
|
1843 |
a1 = Math.min(a1, i);
|
|
|
1844 |
a2 = Math.min(a2, i);
|
|
|
1845 |
|
|
|
1846 |
|
|
|
1847 |
/* Count the number of bits necessary to code the bigvalues region. */
|
|
|
1848 |
if (0 < a1) {
|
|
|
1849 |
var bi = new Bits(bits);
|
|
|
1850 |
gi.table_select[0] = choose_table(ix, 0, a1, bi);
|
|
|
1851 |
bits = bi.bits;
|
|
|
1852 |
}
|
|
|
1853 |
if (a1 < a2) {
|
|
|
1854 |
var bi = new Bits(bits);
|
|
|
1855 |
gi.table_select[1] = choose_table(ix, a1, a2, bi);
|
|
|
1856 |
bits = bi.bits;
|
|
|
1857 |
}
|
|
|
1858 |
if (gfc.use_best_huffman == 2) {
|
|
|
1859 |
gi.part2_3_length = bits;
|
|
|
1860 |
best_huffman_divide(gfc, gi);
|
|
|
1861 |
bits = gi.part2_3_length;
|
|
|
1862 |
}
|
|
|
1863 |
|
|
|
1864 |
if (prev_noise != null) {
|
|
|
1865 |
if (gi.block_type == Encoder.NORM_TYPE) {
|
|
|
1866 |
var sfb = 0;
|
|
|
1867 |
while (gfc.scalefac_band.l[sfb] < gi.big_values) {
|
|
|
1868 |
sfb++;
|
|
|
1869 |
}
|
|
|
1870 |
prev_noise.sfb_count1 = sfb;
|
|
|
1871 |
}
|
|
|
1872 |
}
|
|
|
1873 |
|
|
|
1874 |
return bits;
|
|
|
1875 |
}
|
|
|
1876 |
|
|
|
1877 |
this.count_bits = function (gfc, xr, gi, prev_noise) {
|
|
|
1878 |
var ix = gi.l3_enc;
|
|
|
1879 |
|
|
|
1880 |
/* since quantize_xrpow uses table lookup, we need to check this first: */
|
|
|
1881 |
var w = (QuantizePVT.IXMAX_VAL) / qupvt.IPOW20(gi.global_gain);
|
|
|
1882 |
|
|
|
1883 |
if (gi.xrpow_max > w)
|
|
|
1884 |
return QuantizePVT.LARGE_BITS;
|
|
|
1885 |
|
|
|
1886 |
quantize_xrpow(xr, ix, qupvt.IPOW20(gi.global_gain), gi, prev_noise);
|
|
|
1887 |
|
|
|
1888 |
if ((gfc.substep_shaping & 2) != 0) {
|
|
|
1889 |
var j = 0;
|
|
|
1890 |
/* 0.634521682242439 = 0.5946*2**(.5*0.1875) */
|
|
|
1891 |
var gain = gi.global_gain + gi.scalefac_scale;
|
|
|
1892 |
var roundfac = 0.634521682242439 / qupvt.IPOW20(gain);
|
|
|
1893 |
for (var sfb = 0; sfb < gi.sfbmax; sfb++) {
|
|
|
1894 |
var width = gi.width[sfb];
|
|
|
1895 |
if (0 == gfc.pseudohalf[sfb]) {
|
|
|
1896 |
j += width;
|
|
|
1897 |
} else {
|
|
|
1898 |
var k;
|
|
|
1899 |
for (k = j, j += width; k < j; ++k) {
|
|
|
1900 |
ix[k] = (xr[k] >= roundfac) ? ix[k] : 0;
|
|
|
1901 |
}
|
|
|
1902 |
}
|
|
|
1903 |
}
|
|
|
1904 |
}
|
|
|
1905 |
return this.noquant_count_bits(gfc, gi, prev_noise);
|
|
|
1906 |
}
|
|
|
1907 |
|
|
|
1908 |
/**
|
|
|
1909 |
* re-calculate the best scalefac_compress using scfsi the saved bits are
|
|
|
1910 |
* kept in the bit reservoir.
|
|
|
1911 |
*/
|
|
|
1912 |
function recalc_divide_init(gfc, cod_info, ix, r01_bits, r01_div, r0_tbl, r1_tbl) {
|
|
|
1913 |
var bigv = cod_info.big_values;
|
|
|
1914 |
|
|
|
1915 |
for (var r0 = 0; r0 <= 7 + 15; r0++) {
|
|
|
1916 |
r01_bits[r0] = QuantizePVT.LARGE_BITS;
|
|
|
1917 |
}
|
|
|
1918 |
|
|
|
1919 |
for (var r0 = 0; r0 < 16; r0++) {
|
|
|
1920 |
var a1 = gfc.scalefac_band.l[r0 + 1];
|
|
|
1921 |
if (a1 >= bigv)
|
|
|
1922 |
break;
|
|
|
1923 |
var r0bits = 0;
|
|
|
1924 |
var bi = new Bits(r0bits);
|
|
|
1925 |
var r0t = choose_table(ix, 0, a1, bi);
|
|
|
1926 |
r0bits = bi.bits;
|
|
|
1927 |
|
|
|
1928 |
for (var r1 = 0; r1 < 8; r1++) {
|
|
|
1929 |
var a2 = gfc.scalefac_band.l[r0 + r1 + 2];
|
|
|
1930 |
if (a2 >= bigv)
|
|
|
1931 |
break;
|
|
|
1932 |
var bits = r0bits;
|
|
|
1933 |
bi = new Bits(bits);
|
|
|
1934 |
var r1t = choose_table(ix, a1, a2, bi);
|
|
|
1935 |
bits = bi.bits;
|
|
|
1936 |
if (r01_bits[r0 + r1] > bits) {
|
|
|
1937 |
r01_bits[r0 + r1] = bits;
|
|
|
1938 |
r01_div[r0 + r1] = r0;
|
|
|
1939 |
r0_tbl[r0 + r1] = r0t;
|
|
|
1940 |
r1_tbl[r0 + r1] = r1t;
|
|
|
1941 |
}
|
|
|
1942 |
}
|
|
|
1943 |
}
|
|
|
1944 |
}
|
|
|
1945 |
|
|
|
1946 |
function recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl) {
|
|
|
1947 |
var bigv = cod_info2.big_values;
|
|
|
1948 |
|
|
|
1949 |
for (var r2 = 2; r2 < Encoder.SBMAX_l + 1; r2++) {
|
|
|
1950 |
var a2 = gfc.scalefac_band.l[r2];
|
|
|
1951 |
if (a2 >= bigv)
|
|
|
1952 |
break;
|
|
|
1953 |
var bits = r01_bits[r2 - 2] + cod_info2.count1bits;
|
|
|
1954 |
if (gi.part2_3_length <= bits)
|
|
|
1955 |
break;
|
|
|
1956 |
|
|
|
1957 |
var bi = new Bits(bits);
|
|
|
1958 |
var r2t = choose_table(ix, a2, bigv, bi);
|
|
|
1959 |
bits = bi.bits;
|
|
|
1960 |
if (gi.part2_3_length <= bits)
|
|
|
1961 |
continue;
|
|
|
1962 |
|
|
|
1963 |
gi.assign(cod_info2);
|
|
|
1964 |
gi.part2_3_length = bits;
|
|
|
1965 |
gi.region0_count = r01_div[r2 - 2];
|
|
|
1966 |
gi.region1_count = r2 - 2 - r01_div[r2 - 2];
|
|
|
1967 |
gi.table_select[0] = r0_tbl[r2 - 2];
|
|
|
1968 |
gi.table_select[1] = r1_tbl[r2 - 2];
|
|
|
1969 |
gi.table_select[2] = r2t;
|
|
|
1970 |
}
|
|
|
1971 |
}
|
|
|
1972 |
|
|
|
1973 |
this.best_huffman_divide = function (gfc, gi) {
|
|
|
1974 |
var cod_info2 = new GrInfo();
|
|
|
1975 |
var ix = gi.l3_enc;
|
|
|
1976 |
var r01_bits = new_int(7 + 15 + 1);
|
|
|
1977 |
var r01_div = new_int(7 + 15 + 1);
|
|
|
1978 |
var r0_tbl = new_int(7 + 15 + 1);
|
|
|
1979 |
var r1_tbl = new_int(7 + 15 + 1);
|
|
|
1980 |
|
|
|
1981 |
/* SHORT BLOCK stuff fails for MPEG2 */
|
|
|
1982 |
if (gi.block_type == Encoder.SHORT_TYPE && gfc.mode_gr == 1)
|
|
|
1983 |
return;
|
|
|
1984 |
|
|
|
1985 |
cod_info2.assign(gi);
|
|
|
1986 |
if (gi.block_type == Encoder.NORM_TYPE) {
|
|
|
1987 |
recalc_divide_init(gfc, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl);
|
|
|
1988 |
recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div,
|
|
|
1989 |
r0_tbl, r1_tbl);
|
|
|
1990 |
}
|
|
|
1991 |
var i = cod_info2.big_values;
|
|
|
1992 |
if (i == 0 || (ix[i - 2] | ix[i - 1]) > 1)
|
|
|
1993 |
return;
|
|
|
1994 |
|
|
|
1995 |
i = gi.count1 + 2;
|
|
|
1996 |
if (i > 576)
|
|
|
1997 |
return;
|
|
|
1998 |
|
|
|
1999 |
/* Determines the number of bits to encode the quadruples. */
|
|
|
2000 |
cod_info2.assign(gi);
|
|
|
2001 |
cod_info2.count1 = i;
|
|
|
2002 |
var a1 = 0;
|
|
|
2003 |
var a2 = 0;
|
|
|
2004 |
|
|
|
2005 |
|
|
|
2006 |
for (; i > cod_info2.big_values; i -= 4) {
|
|
|
2007 |
var p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2
|
|
|
2008 |
+ ix[i - 1];
|
|
|
2009 |
a1 += Tables.t32l[p];
|
|
|
2010 |
a2 += Tables.t33l[p];
|
|
|
2011 |
}
|
|
|
2012 |
cod_info2.big_values = i;
|
|
|
2013 |
|
|
|
2014 |
cod_info2.count1table_select = 0;
|
|
|
2015 |
if (a1 > a2) {
|
|
|
2016 |
a1 = a2;
|
|
|
2017 |
cod_info2.count1table_select = 1;
|
|
|
2018 |
}
|
|
|
2019 |
|
|
|
2020 |
cod_info2.count1bits = a1;
|
|
|
2021 |
|
|
|
2022 |
if (cod_info2.block_type == Encoder.NORM_TYPE)
|
|
|
2023 |
recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div,
|
|
|
2024 |
r0_tbl, r1_tbl);
|
|
|
2025 |
else {
|
|
|
2026 |
/* Count the number of bits necessary to code the bigvalues region. */
|
|
|
2027 |
cod_info2.part2_3_length = a1;
|
|
|
2028 |
a1 = gfc.scalefac_band.l[7 + 1];
|
|
|
2029 |
if (a1 > i) {
|
|
|
2030 |
a1 = i;
|
|
|
2031 |
}
|
|
|
2032 |
if (a1 > 0) {
|
|
|
2033 |
var bi = new Bits(cod_info2.part2_3_length);
|
|
|
2034 |
cod_info2.table_select[0] = choose_table(ix, 0, a1, bi);
|
|
|
2035 |
cod_info2.part2_3_length = bi.bits;
|
|
|
2036 |
}
|
|
|
2037 |
if (i > a1) {
|
|
|
2038 |
var bi = new Bits(cod_info2.part2_3_length);
|
|
|
2039 |
cod_info2.table_select[1] = choose_table(ix, a1, i, bi);
|
|
|
2040 |
cod_info2.part2_3_length = bi.bits;
|
|
|
2041 |
}
|
|
|
2042 |
if (gi.part2_3_length > cod_info2.part2_3_length)
|
|
|
2043 |
gi.assign(cod_info2);
|
|
|
2044 |
}
|
|
|
2045 |
}
|
|
|
2046 |
|
|
|
2047 |
var slen1_n = [1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16];
|
|
|
2048 |
var slen2_n = [1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8];
|
|
|
2049 |
var slen1_tab = [0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4];
|
|
|
2050 |
var slen2_tab = [0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3];
|
|
|
2051 |
Takehiro.slen1_tab = slen1_tab;
|
|
|
2052 |
Takehiro.slen2_tab = slen2_tab;
|
|
|
2053 |
|
|
|
2054 |
function scfsi_calc(ch, l3_side) {
|
|
|
2055 |
var sfb;
|
|
|
2056 |
var gi = l3_side.tt[1][ch];
|
|
|
2057 |
var g0 = l3_side.tt[0][ch];
|
|
|
2058 |
|
|
|
2059 |
for (var i = 0; i < Tables.scfsi_band.length - 1; i++) {
|
|
|
2060 |
for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) {
|
|
|
2061 |
if (g0.scalefac[sfb] != gi.scalefac[sfb]
|
|
|
2062 |
&& gi.scalefac[sfb] >= 0)
|
|
|
2063 |
break;
|
|
|
2064 |
}
|
|
|
2065 |
if (sfb == Tables.scfsi_band[i + 1]) {
|
|
|
2066 |
for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) {
|
|
|
2067 |
gi.scalefac[sfb] = -1;
|
|
|
2068 |
}
|
|
|
2069 |
l3_side.scfsi[ch][i] = 1;
|
|
|
2070 |
}
|
|
|
2071 |
}
|
|
|
2072 |
var s1 = 0;
|
|
|
2073 |
var c1 = 0;
|
|
|
2074 |
for (sfb = 0; sfb < 11; sfb++) {
|
|
|
2075 |
if (gi.scalefac[sfb] == -1)
|
|
|
2076 |
continue;
|
|
|
2077 |
c1++;
|
|
|
2078 |
if (s1 < gi.scalefac[sfb])
|
|
|
2079 |
s1 = gi.scalefac[sfb];
|
|
|
2080 |
}
|
|
|
2081 |
var s2 = 0;
|
|
|
2082 |
var c2 = 0;
|
|
|
2083 |
for (; sfb < Encoder.SBPSY_l; sfb++) {
|
|
|
2084 |
if (gi.scalefac[sfb] == -1)
|
|
|
2085 |
continue;
|
|
|
2086 |
c2++;
|
|
|
2087 |
if (s2 < gi.scalefac[sfb])
|
|
|
2088 |
s2 = gi.scalefac[sfb];
|
|
|
2089 |
}
|
|
|
2090 |
|
|
|
2091 |
for (var i = 0; i < 16; i++) {
|
|
|
2092 |
if (s1 < slen1_n[i] && s2 < slen2_n[i]) {
|
|
|
2093 |
var c = slen1_tab[i] * c1 + slen2_tab[i] * c2;
|
|
|
2094 |
if (gi.part2_length > c) {
|
|
|
2095 |
gi.part2_length = c;
|
|
|
2096 |
gi.scalefac_compress = i;
|
|
|
2097 |
}
|
|
|
2098 |
}
|
|
|
2099 |
}
|
|
|
2100 |
}
|
|
|
2101 |
|
|
|
2102 |
/**
|
|
|
2103 |
* Find the optimal way to store the scalefactors. Only call this routine
|
|
|
2104 |
* after final scalefactors have been chosen and the channel/granule will
|
|
|
2105 |
* not be re-encoded.
|
|
|
2106 |
*/
|
|
|
2107 |
this.best_scalefac_store = function (gfc, gr, ch, l3_side) {
|
|
|
2108 |
/* use scalefac_scale if we can */
|
|
|
2109 |
var gi = l3_side.tt[gr][ch];
|
|
|
2110 |
var sfb, i, j, l;
|
|
|
2111 |
var recalc = 0;
|
|
|
2112 |
|
|
|
2113 |
/*
|
|
|
2114 |
* remove scalefacs from bands with ix=0. This idea comes from the AAC
|
|
|
2115 |
* ISO docs. added mt 3/00
|
|
|
2116 |
*/
|
|
|
2117 |
/* check if l3_enc=0 */
|
|
|
2118 |
j = 0;
|
|
|
2119 |
for (sfb = 0; sfb < gi.sfbmax; sfb++) {
|
|
|
2120 |
var width = gi.width[sfb];
|
|
|
2121 |
j += width;
|
|
|
2122 |
for (l = -width; l < 0; l++) {
|
|
|
2123 |
if (gi.l3_enc[l + j] != 0)
|
|
|
2124 |
break;
|
|
|
2125 |
}
|
|
|
2126 |
if (l == 0)
|
|
|
2127 |
gi.scalefac[sfb] = recalc = -2;
|
|
|
2128 |
/* anything goes. */
|
|
|
2129 |
/*
|
|
|
2130 |
* only best_scalefac_store and calc_scfsi know--and only they
|
|
|
2131 |
* should know--about the magic number -2.
|
|
|
2132 |
*/
|
|
|
2133 |
}
|
|
|
2134 |
|
|
|
2135 |
if (0 == gi.scalefac_scale && 0 == gi.preflag) {
|
|
|
2136 |
var s = 0;
|
|
|
2137 |
for (sfb = 0; sfb < gi.sfbmax; sfb++)
|
|
|
2138 |
if (gi.scalefac[sfb] > 0)
|
|
|
2139 |
s |= gi.scalefac[sfb];
|
|
|
2140 |
|
|
|
2141 |
if (0 == (s & 1) && s != 0) {
|
|
|
2142 |
for (sfb = 0; sfb < gi.sfbmax; sfb++)
|
|
|
2143 |
if (gi.scalefac[sfb] > 0)
|
|
|
2144 |
gi.scalefac[sfb] >>= 1;
|
|
|
2145 |
|
|
|
2146 |
gi.scalefac_scale = recalc = 1;
|
|
|
2147 |
}
|
|
|
2148 |
}
|
|
|
2149 |
|
|
|
2150 |
if (0 == gi.preflag && gi.block_type != Encoder.SHORT_TYPE
|
|
|
2151 |
&& gfc.mode_gr == 2) {
|
|
|
2152 |
for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++)
|
|
|
2153 |
if (gi.scalefac[sfb] < qupvt.pretab[sfb]
|
|
|
2154 |
&& gi.scalefac[sfb] != -2)
|
|
|
2155 |
break;
|
|
|
2156 |
if (sfb == Encoder.SBPSY_l) {
|
|
|
2157 |
for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++)
|
|
|
2158 |
if (gi.scalefac[sfb] > 0)
|
|
|
2159 |
gi.scalefac[sfb] -= qupvt.pretab[sfb];
|
|
|
2160 |
|
|
|
2161 |
gi.preflag = recalc = 1;
|
|
|
2162 |
}
|
|
|
2163 |
}
|
|
|
2164 |
|
|
|
2165 |
for (i = 0; i < 4; i++)
|
|
|
2166 |
l3_side.scfsi[ch][i] = 0;
|
|
|
2167 |
|
|
|
2168 |
if (gfc.mode_gr == 2 && gr == 1
|
|
|
2169 |
&& l3_side.tt[0][ch].block_type != Encoder.SHORT_TYPE
|
|
|
2170 |
&& l3_side.tt[1][ch].block_type != Encoder.SHORT_TYPE) {
|
|
|
2171 |
scfsi_calc(ch, l3_side);
|
|
|
2172 |
recalc = 0;
|
|
|
2173 |
}
|
|
|
2174 |
for (sfb = 0; sfb < gi.sfbmax; sfb++) {
|
|
|
2175 |
if (gi.scalefac[sfb] == -2) {
|
|
|
2176 |
gi.scalefac[sfb] = 0;
|
|
|
2177 |
/* if anything goes, then 0 is a good choice */
|
|
|
2178 |
}
|
|
|
2179 |
}
|
|
|
2180 |
if (recalc != 0) {
|
|
|
2181 |
if (gfc.mode_gr == 2) {
|
|
|
2182 |
this.scale_bitcount(gi);
|
|
|
2183 |
} else {
|
|
|
2184 |
this.scale_bitcount_lsf(gfc, gi);
|
|
|
2185 |
}
|
|
|
2186 |
}
|
|
|
2187 |
}
|
|
|
2188 |
|
|
|
2189 |
function all_scalefactors_not_negative(scalefac, n) {
|
|
|
2190 |
for (var i = 0; i < n; ++i) {
|
|
|
2191 |
if (scalefac[i] < 0)
|
|
|
2192 |
return false;
|
|
|
2193 |
}
|
|
|
2194 |
return true;
|
|
|
2195 |
}
|
|
|
2196 |
|
|
|
2197 |
/**
|
|
|
2198 |
* number of bits used to encode scalefacs.
|
|
|
2199 |
*
|
|
|
2200 |
* 18*slen1_tab[i] + 18*slen2_tab[i]
|
|
|
2201 |
*/
|
|
|
2202 |
var scale_short = [0, 18, 36, 54, 54, 36, 54, 72,
|
|
|
2203 |
54, 72, 90, 72, 90, 108, 108, 126];
|
|
|
2204 |
|
|
|
2205 |
/**
|
|
|
2206 |
* number of bits used to encode scalefacs.
|
|
|
2207 |
*
|
|
|
2208 |
* 17*slen1_tab[i] + 18*slen2_tab[i]
|
|
|
2209 |
*/
|
|
|
2210 |
var scale_mixed = [0, 18, 36, 54, 51, 35, 53, 71,
|
|
|
2211 |
52, 70, 88, 69, 87, 105, 104, 122];
|
|
|
2212 |
|
|
|
2213 |
/**
|
|
|
2214 |
* number of bits used to encode scalefacs.
|
|
|
2215 |
*
|
|
|
2216 |
* 11*slen1_tab[i] + 10*slen2_tab[i]
|
|
|
2217 |
*/
|
|
|
2218 |
var scale_long = [0, 10, 20, 30, 33, 21, 31, 41, 32, 42,
|
|
|
2219 |
52, 43, 53, 63, 64, 74];
|
|
|
2220 |
|
|
|
2221 |
/**
|
|
|
2222 |
* Also calculates the number of bits necessary to code the scalefactors.
|
|
|
2223 |
*/
|
|
|
2224 |
this.scale_bitcount = function (cod_info) {
|
|
|
2225 |
var k, sfb, max_slen1 = 0, max_slen2 = 0;
|
|
|
2226 |
|
|
|
2227 |
/* maximum values */
|
|
|
2228 |
var tab;
|
|
|
2229 |
var scalefac = cod_info.scalefac;
|
|
|
2230 |
|
|
|
2231 |
|
|
|
2232 |
if (cod_info.block_type == Encoder.SHORT_TYPE) {
|
|
|
2233 |
tab = scale_short;
|
|
|
2234 |
if (cod_info.mixed_block_flag != 0)
|
|
|
2235 |
tab = scale_mixed;
|
|
|
2236 |
} else { /* block_type == 1,2,or 3 */
|
|
|
2237 |
tab = scale_long;
|
|
|
2238 |
if (0 == cod_info.preflag) {
|
|
|
2239 |
for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++)
|
|
|
2240 |
if (scalefac[sfb] < qupvt.pretab[sfb])
|
|
|
2241 |
break;
|
|
|
2242 |
|
|
|
2243 |
if (sfb == Encoder.SBPSY_l) {
|
|
|
2244 |
cod_info.preflag = 1;
|
|
|
2245 |
for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++)
|
|
|
2246 |
scalefac[sfb] -= qupvt.pretab[sfb];
|
|
|
2247 |
}
|
|
|
2248 |
}
|
|
|
2249 |
}
|
|
|
2250 |
|
|
|
2251 |
for (sfb = 0; sfb < cod_info.sfbdivide; sfb++)
|
|
|
2252 |
if (max_slen1 < scalefac[sfb])
|
|
|
2253 |
max_slen1 = scalefac[sfb];
|
|
|
2254 |
|
|
|
2255 |
for (; sfb < cod_info.sfbmax; sfb++)
|
|
|
2256 |
if (max_slen2 < scalefac[sfb])
|
|
|
2257 |
max_slen2 = scalefac[sfb];
|
|
|
2258 |
|
|
|
2259 |
/*
|
|
|
2260 |
* from Takehiro TOMINAGA <tominaga@isoternet.org> 10/99 loop over *all*
|
|
|
2261 |
* posible values of scalefac_compress to find the one which uses the
|
|
|
2262 |
* smallest number of bits. ISO would stop at first valid index
|
|
|
2263 |
*/
|
|
|
2264 |
cod_info.part2_length = QuantizePVT.LARGE_BITS;
|
|
|
2265 |
for (k = 0; k < 16; k++) {
|
|
|
2266 |
if (max_slen1 < slen1_n[k] && max_slen2 < slen2_n[k]
|
|
|
2267 |
&& cod_info.part2_length > tab[k]) {
|
|
|
2268 |
cod_info.part2_length = tab[k];
|
|
|
2269 |
cod_info.scalefac_compress = k;
|
|
|
2270 |
}
|
|
|
2271 |
}
|
|
|
2272 |
return cod_info.part2_length == QuantizePVT.LARGE_BITS;
|
|
|
2273 |
}
|
|
|
2274 |
|
|
|
2275 |
/**
|
|
|
2276 |
* table of largest scalefactor values for MPEG2
|
|
|
2277 |
*/
|
|
|
2278 |
var max_range_sfac_tab = [[15, 15, 7, 7],
|
|
|
2279 |
[15, 15, 7, 0], [7, 3, 0, 0], [15, 31, 31, 0],
|
|
|
2280 |
[7, 7, 7, 0], [3, 3, 0, 0]];
|
|
|
2281 |
|
|
|
2282 |
/**
|
|
|
2283 |
* Also counts the number of bits to encode the scalefacs but for MPEG 2
|
|
|
2284 |
* Lower sampling frequencies (24, 22.05 and 16 kHz.)
|
|
|
2285 |
*
|
|
|
2286 |
* This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS,
|
|
|
2287 |
* "Audio Decoding Layer III"
|
|
|
2288 |
*/
|
|
|
2289 |
this.scale_bitcount_lsf = function (gfc, cod_info) {
|
|
|
2290 |
var table_number, row_in_table, partition, nr_sfb, window;
|
|
|
2291 |
var over;
|
|
|
2292 |
var i, sfb;
|
|
|
2293 |
var max_sfac = new_int(4);
|
|
|
2294 |
//var partition_table;
|
|
|
2295 |
var scalefac = cod_info.scalefac;
|
|
|
2296 |
|
|
|
2297 |
/*
|
|
|
2298 |
* Set partition table. Note that should try to use table one, but do
|
|
|
2299 |
* not yet...
|
|
|
2300 |
*/
|
|
|
2301 |
if (cod_info.preflag != 0)
|
|
|
2302 |
table_number = 2;
|
|
|
2303 |
else
|
|
|
2304 |
table_number = 0;
|
|
|
2305 |
|
|
|
2306 |
for (i = 0; i < 4; i++)
|
|
|
2307 |
max_sfac[i] = 0;
|
|
|
2308 |
|
|
|
2309 |
if (cod_info.block_type == Encoder.SHORT_TYPE) {
|
|
|
2310 |
row_in_table = 1;
|
|
|
2311 |
var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table];
|
|
|
2312 |
for (sfb = 0, partition = 0; partition < 4; partition++) {
|
|
|
2313 |
nr_sfb = partition_table[partition] / 3;
|
|
|
2314 |
for (i = 0; i < nr_sfb; i++, sfb++)
|
|
|
2315 |
for (window = 0; window < 3; window++)
|
|
|
2316 |
if (scalefac[sfb * 3 + window] > max_sfac[partition])
|
|
|
2317 |
max_sfac[partition] = scalefac[sfb * 3 + window];
|
|
|
2318 |
}
|
|
|
2319 |
} else {
|
|
|
2320 |
row_in_table = 0;
|
|
|
2321 |
var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table];
|
|
|
2322 |
for (sfb = 0, partition = 0; partition < 4; partition++) {
|
|
|
2323 |
nr_sfb = partition_table[partition];
|
|
|
2324 |
for (i = 0; i < nr_sfb; i++, sfb++)
|
|
|
2325 |
if (scalefac[sfb] > max_sfac[partition])
|
|
|
2326 |
max_sfac[partition] = scalefac[sfb];
|
|
|
2327 |
}
|
|
|
2328 |
}
|
|
|
2329 |
|
|
|
2330 |
for (over = false, partition = 0; partition < 4; partition++) {
|
|
|
2331 |
if (max_sfac[partition] > max_range_sfac_tab[table_number][partition])
|
|
|
2332 |
over = true;
|
|
|
2333 |
}
|
|
|
2334 |
if (!over) {
|
|
|
2335 |
var slen1, slen2, slen3, slen4;
|
|
|
2336 |
|
|
|
2337 |
cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table];
|
|
|
2338 |
for (partition = 0; partition < 4; partition++)
|
|
|
2339 |
cod_info.slen[partition] = log2tab[max_sfac[partition]];
|
|
|
2340 |
|
|
|
2341 |
/* set scalefac_compress */
|
|
|
2342 |
slen1 = cod_info.slen[0];
|
|
|
2343 |
slen2 = cod_info.slen[1];
|
|
|
2344 |
slen3 = cod_info.slen[2];
|
|
|
2345 |
slen4 = cod_info.slen[3];
|
|
|
2346 |
|
|
|
2347 |
switch (table_number) {
|
|
|
2348 |
case 0:
|
|
|
2349 |
cod_info.scalefac_compress = (((slen1 * 5) + slen2) << 4)
|
|
|
2350 |
+ (slen3 << 2) + slen4;
|
|
|
2351 |
break;
|
|
|
2352 |
|
|
|
2353 |
case 1:
|
|
|
2354 |
cod_info.scalefac_compress = 400 + (((slen1 * 5) + slen2) << 2)
|
|
|
2355 |
+ slen3;
|
|
|
2356 |
break;
|
|
|
2357 |
|
|
|
2358 |
case 2:
|
|
|
2359 |
cod_info.scalefac_compress = 500 + (slen1 * 3) + slen2;
|
|
|
2360 |
break;
|
|
|
2361 |
|
|
|
2362 |
default:
|
|
|
2363 |
System.err.printf("intensity stereo not implemented yet\n");
|
|
|
2364 |
break;
|
|
|
2365 |
}
|
|
|
2366 |
}
|
|
|
2367 |
if (!over) {
|
|
|
2368 |
cod_info.part2_length = 0;
|
|
|
2369 |
for (partition = 0; partition < 4; partition++)
|
|
|
2370 |
cod_info.part2_length += cod_info.slen[partition]
|
|
|
2371 |
* cod_info.sfb_partition_table[partition];
|
|
|
2372 |
}
|
|
|
2373 |
return over;
|
|
|
2374 |
}
|
|
|
2375 |
|
|
|
2376 |
/*
|
|
|
2377 |
* Since no bands have been over-amplified, we can set scalefac_compress and
|
|
|
2378 |
* slen[] for the formatter
|
|
|
2379 |
*/
|
|
|
2380 |
var log2tab = [0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
|
|
|
2381 |
4, 4, 4, 4];
|
|
|
2382 |
|
|
|
2383 |
this.huffman_init = function (gfc) {
|
|
|
2384 |
for (var i = 2; i <= 576; i += 2) {
|
|
|
2385 |
var scfb_anz = 0, bv_index;
|
|
|
2386 |
while (gfc.scalefac_band.l[++scfb_anz] < i)
|
|
|
2387 |
;
|
|
|
2388 |
|
|
|
2389 |
bv_index = subdv_table[scfb_anz][0]; // .region0_count
|
|
|
2390 |
while (gfc.scalefac_band.l[bv_index + 1] > i)
|
|
|
2391 |
bv_index--;
|
|
|
2392 |
|
|
|
2393 |
if (bv_index < 0) {
|
|
|
2394 |
/*
|
|
|
2395 |
* this is an indication that everything is going to be encoded
|
|
|
2396 |
* as region0: bigvalues < region0 < region1 so lets set
|
|
|
2397 |
* region0, region1 to some value larger than bigvalues
|
|
|
2398 |
*/
|
|
|
2399 |
bv_index = subdv_table[scfb_anz][0]; // .region0_count
|
|
|
2400 |
}
|
|
|
2401 |
|
|
|
2402 |
gfc.bv_scf[i - 2] = bv_index;
|
|
|
2403 |
|
|
|
2404 |
bv_index = subdv_table[scfb_anz][1]; // .region1_count
|
|
|
2405 |
while (gfc.scalefac_band.l[bv_index + gfc.bv_scf[i - 2] + 2] > i)
|
|
|
2406 |
bv_index--;
|
|
|
2407 |
|
|
|
2408 |
if (bv_index < 0) {
|
|
|
2409 |
bv_index = subdv_table[scfb_anz][1]; // .region1_count
|
|
|
2410 |
}
|
|
|
2411 |
|
|
|
2412 |
gfc.bv_scf[i - 1] = bv_index;
|
|
|
2413 |
}
|
|
|
2414 |
}
|
|
|
2415 |
}
|
|
|
2416 |
|
|
|
2417 |
/*
|
|
|
2418 |
* bit reservoir source file
|
|
|
2419 |
*
|
|
|
2420 |
* Copyright (c) 1999-2000 Mark Taylor
|
|
|
2421 |
*
|
|
|
2422 |
* This library is free software; you can redistribute it and/or
|
|
|
2423 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
2424 |
* License as published by the Free Software Foundation; either
|
|
|
2425 |
* version 2 of the License, or (at your option) any later version.
|
|
|
2426 |
*
|
|
|
2427 |
* This library is distributed in the hope that it will be useful,
|
|
|
2428 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
2429 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
2430 |
* Library General Public License for more details.
|
|
|
2431 |
*
|
|
|
2432 |
* You should have received a copy of the GNU Lesser General Public
|
|
|
2433 |
* License along with this library; if not, write to the
|
|
|
2434 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
2435 |
* Boston, MA 02111-1307, USA.
|
|
|
2436 |
*/
|
|
|
2437 |
|
|
|
2438 |
/* $Id: Reservoir.java,v 1.9 2011/05/24 20:48:06 kenchis Exp $ */
|
|
|
2439 |
|
|
|
2440 |
//package mp3;
|
|
|
2441 |
|
|
|
2442 |
/**
|
|
|
2443 |
* ResvFrameBegin:<BR>
|
|
|
2444 |
* Called (repeatedly) at the beginning of a frame. Updates the maximum size of
|
|
|
2445 |
* the reservoir, and checks to make sure main_data_begin was set properly by
|
|
|
2446 |
* the formatter<BR>
|
|
|
2447 |
* Background information:
|
|
|
2448 |
*
|
|
|
2449 |
* This is the original text from the ISO standard. Because of sooo many bugs
|
|
|
2450 |
* and irritations correcting comments are added in brackets []. A '^W' means
|
|
|
2451 |
* you should remove the last word.
|
|
|
2452 |
*
|
|
|
2453 |
* <PRE>
|
|
|
2454 |
* 1. The following rule can be used to calculate the maximum
|
|
|
2455 |
* number of bits used for one granule [^W frame]:<BR>
|
|
|
2456 |
* At the highest possible bitrate of Layer III (320 kbps
|
|
|
2457 |
* per stereo signal [^W^W^W], 48 kHz) the frames must be of
|
|
|
2458 |
* [^W^W^W are designed to have] constant length, i.e.
|
|
|
2459 |
* one buffer [^W^W the frame] length is:<BR>
|
|
|
2460 |
*
|
|
|
2461 |
* 320 kbps * 1152/48 kHz = 7680 bit = 960 byte
|
|
|
2462 |
*
|
|
|
2463 |
* This value is used as the maximum buffer per channel [^W^W] at
|
|
|
2464 |
* lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps
|
|
|
2465 |
* stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit
|
|
|
2466 |
* [per granule and channel] at 48 kHz sampling frequency.
|
|
|
2467 |
* This means that there is a maximum deviation (short time buffer
|
|
|
2468 |
* [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps.
|
|
|
2469 |
* The actual deviation is equal to the number of bytes [with the
|
|
|
2470 |
* meaning of octets] denoted by the main_data_end offset pointer.
|
|
|
2471 |
* The actual maximum deviation is (2^9-1)*8 bit = 4088 bits
|
|
|
2472 |
* [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits].
|
|
|
2473 |
* ... The xchange of buffer bits between the left and right channel
|
|
|
2474 |
* is allowed without restrictions [exception: dual channel].
|
|
|
2475 |
* Because of the [constructed] constraint on the buffer size
|
|
|
2476 |
* main_data_end is always set to 0 in the case of bit_rate_index==14,
|
|
|
2477 |
* i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case
|
|
|
2478 |
* all data are allocated between adjacent header [^W sync] words
|
|
|
2479 |
* [, i.e. there is no buffering at all].
|
|
|
2480 |
* </PRE>
|
|
|
2481 |
*/
|
|
|
2482 |
|
|
|
2483 |
|
|
|
2484 |
function Reservoir() {
|
|
|
2485 |
var bs;
|
|
|
2486 |
|
|
|
2487 |
this.setModules = function(_bs) {
|
|
|
2488 |
bs = _bs;
|
|
|
2489 |
}
|
|
|
2490 |
|
|
|
2491 |
this.ResvFrameBegin = function(gfp, mean_bits) {
|
|
|
2492 |
var gfc = gfp.internal_flags;
|
|
|
2493 |
var maxmp3buf;
|
|
|
2494 |
var l3_side = gfc.l3_side;
|
|
|
2495 |
|
|
|
2496 |
var frameLength = bs.getframebits(gfp);
|
|
|
2497 |
mean_bits.bits = (frameLength - gfc.sideinfo_len * 8) / gfc.mode_gr;
|
|
|
2498 |
|
|
|
2499 |
/**
|
|
|
2500 |
* <PRE>
|
|
|
2501 |
* Meaning of the variables:
|
|
|
2502 |
* resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1))
|
|
|
2503 |
* Number of bits can be stored in previous frame(s) due to
|
|
|
2504 |
* counter size constaints
|
|
|
2505 |
* maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5))
|
|
|
2506 |
* Number of bits allowed to encode one frame (you can take 8*511 bit
|
|
|
2507 |
* from the bit reservoir and at most 8*1440 bit from the current
|
|
|
2508 |
* frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible
|
|
|
2509 |
* value for MPEG-1 and -2)
|
|
|
2510 |
*
|
|
|
2511 |
* maximum allowed granule/channel size times 4 = 8*2047 bits.,
|
|
|
2512 |
* so this is the absolute maximum supported by the format.
|
|
|
2513 |
*
|
|
|
2514 |
*
|
|
|
2515 |
* fullFrameBits: maximum number of bits available for encoding
|
|
|
2516 |
* the current frame.
|
|
|
2517 |
*
|
|
|
2518 |
* mean_bits: target number of bits per granule.
|
|
|
2519 |
*
|
|
|
2520 |
* frameLength:
|
|
|
2521 |
*
|
|
|
2522 |
* gfc.ResvMax: maximum allowed reservoir
|
|
|
2523 |
*
|
|
|
2524 |
* gfc.ResvSize: current reservoir size
|
|
|
2525 |
*
|
|
|
2526 |
* l3_side.resvDrain_pre:
|
|
|
2527 |
* ancillary data to be added to previous frame:
|
|
|
2528 |
* (only usefull in VBR modes if it is possible to have
|
|
|
2529 |
* maxmp3buf < fullFrameBits)). Currently disabled,
|
|
|
2530 |
* see #define NEW_DRAIN
|
|
|
2531 |
* 2010-02-13: RH now enabled, it seems to be needed for CBR too,
|
|
|
2532 |
* as there exists one example, where the FhG decoder
|
|
|
2533 |
* can't decode a -b320 CBR file anymore.
|
|
|
2534 |
*
|
|
|
2535 |
* l3_side.resvDrain_post:
|
|
|
2536 |
* ancillary data to be added to this frame:
|
|
|
2537 |
*
|
|
|
2538 |
* </PRE>
|
|
|
2539 |
*/
|
|
|
2540 |
|
|
|
2541 |
/* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */
|
|
|
2542 |
var resvLimit = (8 * 256) * gfc.mode_gr - 8;
|
|
|
2543 |
|
|
|
2544 |
/*
|
|
|
2545 |
* maximum allowed frame size. dont use more than this number of bits,
|
|
|
2546 |
* even if the frame has the space for them:
|
|
|
2547 |
*/
|
|
|
2548 |
if (gfp.brate > 320) {
|
|
|
2549 |
/* in freeformat the buffer is constant */
|
|
|
2550 |
maxmp3buf = 8 * ((int) ((gfp.brate * 1000)
|
|
|
2551 |
/ (gfp.out_samplerate / 1152) / 8 + .5));
|
|
|
2552 |
} else {
|
|
|
2553 |
/*
|
|
|
2554 |
* all mp3 decoders should have enough buffer to handle this value:
|
|
|
2555 |
* size of a 320kbps 32kHz frame
|
|
|
2556 |
*/
|
|
|
2557 |
maxmp3buf = 8 * 1440;
|
|
|
2558 |
|
|
|
2559 |
/*
|
|
|
2560 |
* Bouvigne suggests this more lax interpretation of the ISO doc
|
|
|
2561 |
* instead of using 8*960.
|
|
|
2562 |
*/
|
|
|
2563 |
|
|
|
2564 |
if (gfp.strict_ISO) {
|
|
|
2565 |
maxmp3buf = 8 * ((int) (320000 / (gfp.out_samplerate / 1152) / 8 + .5));
|
|
|
2566 |
}
|
|
|
2567 |
}
|
|
|
2568 |
|
|
|
2569 |
gfc.ResvMax = maxmp3buf - frameLength;
|
|
|
2570 |
if (gfc.ResvMax > resvLimit)
|
|
|
2571 |
gfc.ResvMax = resvLimit;
|
|
|
2572 |
if (gfc.ResvMax < 0 || gfp.disable_reservoir)
|
|
|
2573 |
gfc.ResvMax = 0;
|
|
|
2574 |
|
|
|
2575 |
var fullFrameBits = mean_bits.bits * gfc.mode_gr
|
|
|
2576 |
+ Math.min(gfc.ResvSize, gfc.ResvMax);
|
|
|
2577 |
|
|
|
2578 |
if (fullFrameBits > maxmp3buf)
|
|
|
2579 |
fullFrameBits = maxmp3buf;
|
|
|
2580 |
|
|
|
2581 |
|
|
|
2582 |
l3_side.resvDrain_pre = 0;
|
|
|
2583 |
|
|
|
2584 |
// frame analyzer code
|
|
|
2585 |
if (gfc.pinfo != null) {
|
|
|
2586 |
/*
|
|
|
2587 |
* expected bits per channel per granule [is this also right for
|
|
|
2588 |
* mono/stereo, MPEG-1/2 ?]
|
|
|
2589 |
*/
|
|
|
2590 |
gfc.pinfo.mean_bits = mean_bits.bits / 2;
|
|
|
2591 |
gfc.pinfo.resvsize = gfc.ResvSize;
|
|
|
2592 |
}
|
|
|
2593 |
|
|
|
2594 |
return fullFrameBits;
|
|
|
2595 |
}
|
|
|
2596 |
|
|
|
2597 |
/**
|
|
|
2598 |
* returns targ_bits: target number of bits to use for 1 granule<BR>
|
|
|
2599 |
* extra_bits: amount extra available from reservoir<BR>
|
|
|
2600 |
* Mark Taylor 4/99
|
|
|
2601 |
*/
|
|
|
2602 |
this.ResvMaxBits = function(gfp, mean_bits, targ_bits, cbr) {
|
|
|
2603 |
var gfc = gfp.internal_flags;
|
|
|
2604 |
var add_bits;
|
|
|
2605 |
var ResvSize = gfc.ResvSize, ResvMax = gfc.ResvMax;
|
|
|
2606 |
|
|
|
2607 |
/* compensate the saved bits used in the 1st granule */
|
|
|
2608 |
if (cbr != 0)
|
|
|
2609 |
ResvSize += mean_bits;
|
|
|
2610 |
|
|
|
2611 |
if ((gfc.substep_shaping & 1) != 0)
|
|
|
2612 |
ResvMax *= 0.9;
|
|
|
2613 |
|
|
|
2614 |
targ_bits.bits = mean_bits;
|
|
|
2615 |
|
|
|
2616 |
/* extra bits if the reservoir is almost full */
|
|
|
2617 |
if (ResvSize * 10 > ResvMax * 9) {
|
|
|
2618 |
add_bits = ResvSize - (ResvMax * 9) / 10;
|
|
|
2619 |
targ_bits.bits += add_bits;
|
|
|
2620 |
gfc.substep_shaping |= 0x80;
|
|
|
2621 |
} else {
|
|
|
2622 |
add_bits = 0;
|
|
|
2623 |
gfc.substep_shaping &= 0x7f;
|
|
|
2624 |
/*
|
|
|
2625 |
* build up reservoir. this builds the reservoir a little slower
|
|
|
2626 |
* than FhG. It could simple be mean_bits/15, but this was rigged to
|
|
|
2627 |
* always produce 100 (the old value) at 128kbs
|
|
|
2628 |
*/
|
|
|
2629 |
if (!gfp.disable_reservoir && 0 == (gfc.substep_shaping & 1))
|
|
|
2630 |
targ_bits.bits -= .1 * mean_bits;
|
|
|
2631 |
}
|
|
|
2632 |
|
|
|
2633 |
/* amount from the reservoir we are allowed to use. ISO says 6/10 */
|
|
|
2634 |
var extra_bits = (ResvSize < (gfc.ResvMax * 6) / 10 ? ResvSize
|
|
|
2635 |
: (gfc.ResvMax * 6) / 10);
|
|
|
2636 |
extra_bits -= add_bits;
|
|
|
2637 |
|
|
|
2638 |
if (extra_bits < 0)
|
|
|
2639 |
extra_bits = 0;
|
|
|
2640 |
return extra_bits;
|
|
|
2641 |
}
|
|
|
2642 |
|
|
|
2643 |
/**
|
|
|
2644 |
* Called after a granule's bit allocation. Readjusts the size of the
|
|
|
2645 |
* reservoir to reflect the granule's usage.
|
|
|
2646 |
*/
|
|
|
2647 |
this.ResvAdjust = function(gfc, gi) {
|
|
|
2648 |
gfc.ResvSize -= gi.part2_3_length + gi.part2_length;
|
|
|
2649 |
}
|
|
|
2650 |
|
|
|
2651 |
/**
|
|
|
2652 |
* Called after all granules in a frame have been allocated. Makes sure that
|
|
|
2653 |
* the reservoir size is within limits, possibly by adding stuffing bits.
|
|
|
2654 |
*/
|
|
|
2655 |
this.ResvFrameEnd = function(gfc, mean_bits) {
|
|
|
2656 |
var over_bits;
|
|
|
2657 |
var l3_side = gfc.l3_side;
|
|
|
2658 |
|
|
|
2659 |
gfc.ResvSize += mean_bits * gfc.mode_gr;
|
|
|
2660 |
var stuffingBits = 0;
|
|
|
2661 |
l3_side.resvDrain_post = 0;
|
|
|
2662 |
l3_side.resvDrain_pre = 0;
|
|
|
2663 |
|
|
|
2664 |
/* we must be byte aligned */
|
|
|
2665 |
if ((over_bits = gfc.ResvSize % 8) != 0)
|
|
|
2666 |
stuffingBits += over_bits;
|
|
|
2667 |
|
|
|
2668 |
over_bits = (gfc.ResvSize - stuffingBits) - gfc.ResvMax;
|
|
|
2669 |
if (over_bits > 0) {
|
|
|
2670 |
stuffingBits += over_bits;
|
|
|
2671 |
}
|
|
|
2672 |
|
|
|
2673 |
/*
|
|
|
2674 |
* NOTE: enabling the NEW_DRAIN code fixes some problems with FhG
|
|
|
2675 |
* decoder shipped with MS Windows operating systems. Using this, it is
|
|
|
2676 |
* even possible to use Gabriel's lax buffer consideration again, which
|
|
|
2677 |
* assumes, any decoder should have a buffer large enough for a 320 kbps
|
|
|
2678 |
* frame at 32 kHz sample rate.
|
|
|
2679 |
*
|
|
|
2680 |
* old drain code: lame -b320 BlackBird.wav --. does not play with
|
|
|
2681 |
* GraphEdit.exe using FhG decoder V1.5 Build 50
|
|
|
2682 |
*
|
|
|
2683 |
* new drain code: lame -b320 BlackBird.wav --. plays fine with
|
|
|
2684 |
* GraphEdit.exe using FhG decoder V1.5 Build 50
|
|
|
2685 |
*
|
|
|
2686 |
* Robert Hegemann, 2010-02-13.
|
|
|
2687 |
*/
|
|
|
2688 |
/*
|
|
|
2689 |
* drain as many bits as possible into previous frame ancillary data In
|
|
|
2690 |
* particular, in VBR mode ResvMax may have changed, and we have to make
|
|
|
2691 |
* sure main_data_begin does not create a reservoir bigger than ResvMax
|
|
|
2692 |
* mt 4/00
|
|
|
2693 |
*/
|
|
|
2694 |
{
|
|
|
2695 |
var mdb_bytes = Math.min(l3_side.main_data_begin * 8, stuffingBits) / 8;
|
|
|
2696 |
l3_side.resvDrain_pre += 8 * mdb_bytes;
|
|
|
2697 |
stuffingBits -= 8 * mdb_bytes;
|
|
|
2698 |
gfc.ResvSize -= 8 * mdb_bytes;
|
|
|
2699 |
l3_side.main_data_begin -= mdb_bytes;
|
|
|
2700 |
}
|
|
|
2701 |
/* drain the rest into this frames ancillary data */
|
|
|
2702 |
l3_side.resvDrain_post += stuffingBits;
|
|
|
2703 |
gfc.ResvSize -= stuffingBits;
|
|
|
2704 |
}
|
|
|
2705 |
}
|
|
|
2706 |
|
|
|
2707 |
|
|
|
2708 |
|
|
|
2709 |
BitStream.EQ = function (a, b) {
|
|
|
2710 |
return (Math.abs(a) > Math.abs(b)) ? (Math.abs((a) - (b)) <= (Math
|
|
|
2711 |
.abs(a) * 1e-6))
|
|
|
2712 |
: (Math.abs((a) - (b)) <= (Math.abs(b) * 1e-6));
|
|
|
2713 |
};
|
|
|
2714 |
|
|
|
2715 |
BitStream.NEQ = function (a, b) {
|
|
|
2716 |
return !BitStream.EQ(a, b);
|
|
|
2717 |
};
|
|
|
2718 |
|
|
|
2719 |
function BitStream() {
|
|
|
2720 |
var self = this;
|
|
|
2721 |
var CRC16_POLYNOMIAL = 0x8005;
|
|
|
2722 |
|
|
|
2723 |
/*
|
|
|
2724 |
* we work with ints, so when doing bit manipulation, we limit ourselves to
|
|
|
2725 |
* MAX_LENGTH-2 just to be on the safe side
|
|
|
2726 |
*/
|
|
|
2727 |
var MAX_LENGTH = 32;
|
|
|
2728 |
|
|
|
2729 |
//GainAnalysis ga;
|
|
|
2730 |
//MPGLib mpg;
|
|
|
2731 |
//Version ver;
|
|
|
2732 |
//VBRTag vbr;
|
|
|
2733 |
var ga = null;
|
|
|
2734 |
var mpg = null;
|
|
|
2735 |
var ver = null;
|
|
|
2736 |
var vbr = null;
|
|
|
2737 |
|
|
|
2738 |
//public final void setModules(GainAnalysis ga, MPGLib mpg, Version ver,
|
|
|
2739 |
// VBRTag vbr) {
|
|
|
2740 |
|
|
|
2741 |
this.setModules = function (_ga, _mpg, _ver, _vbr) {
|
|
|
2742 |
ga = _ga;
|
|
|
2743 |
mpg = _mpg;
|
|
|
2744 |
ver = _ver;
|
|
|
2745 |
vbr = _vbr;
|
|
|
2746 |
};
|
|
|
2747 |
|
|
|
2748 |
/**
|
|
|
2749 |
* Bit stream buffer.
|
|
|
2750 |
*/
|
|
|
2751 |
//private byte[] buf;
|
|
|
2752 |
var buf = null;
|
|
|
2753 |
/**
|
|
|
2754 |
* Bit counter of bit stream.
|
|
|
2755 |
*/
|
|
|
2756 |
var totbit = 0;
|
|
|
2757 |
/**
|
|
|
2758 |
* Pointer to top byte in buffer.
|
|
|
2759 |
*/
|
|
|
2760 |
var bufByteIdx = 0;
|
|
|
2761 |
/**
|
|
|
2762 |
* Pointer to top bit of top byte in buffer.
|
|
|
2763 |
*/
|
|
|
2764 |
var bufBitIdx = 0;
|
|
|
2765 |
|
|
|
2766 |
/**
|
|
|
2767 |
* compute bitsperframe and mean_bits for a layer III frame
|
|
|
2768 |
*/
|
|
|
2769 |
this.getframebits = function (gfp) {
|
|
|
2770 |
var gfc = gfp.internal_flags;
|
|
|
2771 |
var bit_rate;
|
|
|
2772 |
|
|
|
2773 |
/* get bitrate in kbps [?] */
|
|
|
2774 |
if (gfc.bitrate_index != 0)
|
|
|
2775 |
bit_rate = Tables.bitrate_table[gfp.version][gfc.bitrate_index];
|
|
|
2776 |
else
|
|
|
2777 |
bit_rate = gfp.brate;
|
|
|
2778 |
|
|
|
2779 |
/* main encoding routine toggles padding on and off */
|
|
|
2780 |
/* one Layer3 Slot consists of 8 bits */
|
|
|
2781 |
var bytes = 0 | (gfp.version + 1) * 72000 * bit_rate / gfp.out_samplerate + gfc.padding;
|
|
|
2782 |
return 8 * bytes;
|
|
|
2783 |
};
|
|
|
2784 |
|
|
|
2785 |
function putheader_bits(gfc) {
|
|
|
2786 |
System.arraycopy(gfc.header[gfc.w_ptr].buf, 0, buf, bufByteIdx, gfc.sideinfo_len);
|
|
|
2787 |
bufByteIdx += gfc.sideinfo_len;
|
|
|
2788 |
totbit += gfc.sideinfo_len * 8;
|
|
|
2789 |
gfc.w_ptr = (gfc.w_ptr + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1);
|
|
|
2790 |
}
|
|
|
2791 |
|
|
|
2792 |
/**
|
|
|
2793 |
* write j bits into the bit stream
|
|
|
2794 |
*/
|
|
|
2795 |
function putbits2(gfc, val, j) {
|
|
|
2796 |
|
|
|
2797 |
while (j > 0) {
|
|
|
2798 |
var k;
|
|
|
2799 |
if (bufBitIdx == 0) {
|
|
|
2800 |
bufBitIdx = 8;
|
|
|
2801 |
bufByteIdx++;
|
|
|
2802 |
if (gfc.header[gfc.w_ptr].write_timing == totbit) {
|
|
|
2803 |
putheader_bits(gfc);
|
|
|
2804 |
}
|
|
|
2805 |
buf[bufByteIdx] = 0;
|
|
|
2806 |
}
|
|
|
2807 |
|
|
|
2808 |
k = Math.min(j, bufBitIdx);
|
|
|
2809 |
j -= k;
|
|
|
2810 |
|
|
|
2811 |
bufBitIdx -= k;
|
|
|
2812 |
|
|
|
2813 |
/* 32 too large on 32 bit machines */
|
|
|
2814 |
|
|
|
2815 |
buf[bufByteIdx] |= ((val >> j) << bufBitIdx);
|
|
|
2816 |
totbit += k;
|
|
|
2817 |
}
|
|
|
2818 |
}
|
|
|
2819 |
|
|
|
2820 |
/**
|
|
|
2821 |
* write j bits into the bit stream, ignoring frame headers
|
|
|
2822 |
*/
|
|
|
2823 |
function putbits_noheaders(gfc, val, j) {
|
|
|
2824 |
|
|
|
2825 |
while (j > 0) {
|
|
|
2826 |
var k;
|
|
|
2827 |
if (bufBitIdx == 0) {
|
|
|
2828 |
bufBitIdx = 8;
|
|
|
2829 |
bufByteIdx++;
|
|
|
2830 |
buf[bufByteIdx] = 0;
|
|
|
2831 |
}
|
|
|
2832 |
|
|
|
2833 |
k = Math.min(j, bufBitIdx);
|
|
|
2834 |
j -= k;
|
|
|
2835 |
|
|
|
2836 |
bufBitIdx -= k;
|
|
|
2837 |
|
|
|
2838 |
/* 32 too large on 32 bit machines */
|
|
|
2839 |
|
|
|
2840 |
buf[bufByteIdx] |= ((val >> j) << bufBitIdx);
|
|
|
2841 |
totbit += k;
|
|
|
2842 |
}
|
|
|
2843 |
}
|
|
|
2844 |
|
|
|
2845 |
/**
|
|
|
2846 |
* Some combinations of bitrate, Fs, and stereo make it impossible to stuff
|
|
|
2847 |
* out a frame using just main_data, due to the limited number of bits to
|
|
|
2848 |
* indicate main_data_length. In these situations, we put stuffing bits into
|
|
|
2849 |
* the ancillary data...
|
|
|
2850 |
*/
|
|
|
2851 |
function drain_into_ancillary(gfp, remainingBits) {
|
|
|
2852 |
var gfc = gfp.internal_flags;
|
|
|
2853 |
var i;
|
|
|
2854 |
|
|
|
2855 |
if (remainingBits >= 8) {
|
|
|
2856 |
putbits2(gfc, 0x4c, 8);
|
|
|
2857 |
remainingBits -= 8;
|
|
|
2858 |
}
|
|
|
2859 |
if (remainingBits >= 8) {
|
|
|
2860 |
putbits2(gfc, 0x41, 8);
|
|
|
2861 |
remainingBits -= 8;
|
|
|
2862 |
}
|
|
|
2863 |
if (remainingBits >= 8) {
|
|
|
2864 |
putbits2(gfc, 0x4d, 8);
|
|
|
2865 |
remainingBits -= 8;
|
|
|
2866 |
}
|
|
|
2867 |
if (remainingBits >= 8) {
|
|
|
2868 |
putbits2(gfc, 0x45, 8);
|
|
|
2869 |
remainingBits -= 8;
|
|
|
2870 |
}
|
|
|
2871 |
|
|
|
2872 |
if (remainingBits >= 32) {
|
|
|
2873 |
var version = ver.getLameShortVersion();
|
|
|
2874 |
if (remainingBits >= 32)
|
|
|
2875 |
for (i = 0; i < version.length && remainingBits >= 8; ++i) {
|
|
|
2876 |
remainingBits -= 8;
|
|
|
2877 |
putbits2(gfc, version.charAt(i), 8);
|
|
|
2878 |
}
|
|
|
2879 |
}
|
|
|
2880 |
|
|
|
2881 |
for (; remainingBits >= 1; remainingBits -= 1) {
|
|
|
2882 |
putbits2(gfc, gfc.ancillary_flag, 1);
|
|
|
2883 |
gfc.ancillary_flag ^= (!gfp.disable_reservoir ? 1 : 0);
|
|
|
2884 |
}
|
|
|
2885 |
|
|
|
2886 |
|
|
|
2887 |
}
|
|
|
2888 |
|
|
|
2889 |
/**
|
|
|
2890 |
* write N bits into the header
|
|
|
2891 |
*/
|
|
|
2892 |
function writeheader(gfc, val, j) {
|
|
|
2893 |
var ptr = gfc.header[gfc.h_ptr].ptr;
|
|
|
2894 |
|
|
|
2895 |
while (j > 0) {
|
|
|
2896 |
var k = Math.min(j, 8 - (ptr & 7));
|
|
|
2897 |
j -= k;
|
|
|
2898 |
/* >> 32 too large for 32 bit machines */
|
|
|
2899 |
|
|
|
2900 |
gfc.header[gfc.h_ptr].buf[ptr >> 3] |= ((val >> j)) << (8 - (ptr & 7) - k);
|
|
|
2901 |
ptr += k;
|
|
|
2902 |
}
|
|
|
2903 |
gfc.header[gfc.h_ptr].ptr = ptr;
|
|
|
2904 |
}
|
|
|
2905 |
|
|
|
2906 |
function CRC_update(value, crc) {
|
|
|
2907 |
value <<= 8;
|
|
|
2908 |
for (var i = 0; i < 8; i++) {
|
|
|
2909 |
value <<= 1;
|
|
|
2910 |
crc <<= 1;
|
|
|
2911 |
|
|
|
2912 |
if ((((crc ^ value) & 0x10000) != 0))
|
|
|
2913 |
crc ^= CRC16_POLYNOMIAL;
|
|
|
2914 |
}
|
|
|
2915 |
return crc;
|
|
|
2916 |
}
|
|
|
2917 |
|
|
|
2918 |
this.CRC_writeheader = function (gfc, header) {
|
|
|
2919 |
var crc = 0xffff;
|
|
|
2920 |
/* (jo) init crc16 for error_protection */
|
|
|
2921 |
|
|
|
2922 |
crc = CRC_update(header[2] & 0xff, crc);
|
|
|
2923 |
crc = CRC_update(header[3] & 0xff, crc);
|
|
|
2924 |
for (var i = 6; i < gfc.sideinfo_len; i++) {
|
|
|
2925 |
crc = CRC_update(header[i] & 0xff, crc);
|
|
|
2926 |
}
|
|
|
2927 |
|
|
|
2928 |
header[4] = (byte)(crc >> 8);
|
|
|
2929 |
header[5] = (byte)(crc & 255);
|
|
|
2930 |
};
|
|
|
2931 |
|
|
|
2932 |
function encodeSideInfo2(gfp, bitsPerFrame) {
|
|
|
2933 |
var gfc = gfp.internal_flags;
|
|
|
2934 |
var l3_side;
|
|
|
2935 |
var gr, ch;
|
|
|
2936 |
|
|
|
2937 |
l3_side = gfc.l3_side;
|
|
|
2938 |
gfc.header[gfc.h_ptr].ptr = 0;
|
|
|
2939 |
Arrays.fill(gfc.header[gfc.h_ptr].buf, 0, gfc.sideinfo_len, 0);
|
|
|
2940 |
if (gfp.out_samplerate < 16000)
|
|
|
2941 |
writeheader(gfc, 0xffe, 12);
|
|
|
2942 |
else
|
|
|
2943 |
writeheader(gfc, 0xfff, 12);
|
|
|
2944 |
writeheader(gfc, (gfp.version), 1);
|
|
|
2945 |
writeheader(gfc, 4 - 3, 2);
|
|
|
2946 |
writeheader(gfc, (!gfp.error_protection ? 1 : 0), 1);
|
|
|
2947 |
writeheader(gfc, (gfc.bitrate_index), 4);
|
|
|
2948 |
writeheader(gfc, (gfc.samplerate_index), 2);
|
|
|
2949 |
writeheader(gfc, (gfc.padding), 1);
|
|
|
2950 |
writeheader(gfc, (gfp.extension), 1);
|
|
|
2951 |
writeheader(gfc, (gfp.mode.ordinal()), 2);
|
|
|
2952 |
writeheader(gfc, (gfc.mode_ext), 2);
|
|
|
2953 |
writeheader(gfc, (gfp.copyright), 1);
|
|
|
2954 |
writeheader(gfc, (gfp.original), 1);
|
|
|
2955 |
writeheader(gfc, (gfp.emphasis), 2);
|
|
|
2956 |
if (gfp.error_protection) {
|
|
|
2957 |
writeheader(gfc, 0, 16);
|
|
|
2958 |
/* dummy */
|
|
|
2959 |
}
|
|
|
2960 |
|
|
|
2961 |
if (gfp.version == 1) {
|
|
|
2962 |
/* MPEG1 */
|
|
|
2963 |
writeheader(gfc, (l3_side.main_data_begin), 9);
|
|
|
2964 |
|
|
|
2965 |
if (gfc.channels_out == 2)
|
|
|
2966 |
writeheader(gfc, l3_side.private_bits, 3);
|
|
|
2967 |
else
|
|
|
2968 |
writeheader(gfc, l3_side.private_bits, 5);
|
|
|
2969 |
|
|
|
2970 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
2971 |
var band;
|
|
|
2972 |
for (band = 0; band < 4; band++) {
|
|
|
2973 |
writeheader(gfc, l3_side.scfsi[ch][band], 1);
|
|
|
2974 |
}
|
|
|
2975 |
}
|
|
|
2976 |
|
|
|
2977 |
for (gr = 0; gr < 2; gr++) {
|
|
|
2978 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
2979 |
var gi = l3_side.tt[gr][ch];
|
|
|
2980 |
writeheader(gfc, gi.part2_3_length + gi.part2_length, 12);
|
|
|
2981 |
writeheader(gfc, gi.big_values / 2, 9);
|
|
|
2982 |
writeheader(gfc, gi.global_gain, 8);
|
|
|
2983 |
writeheader(gfc, gi.scalefac_compress, 4);
|
|
|
2984 |
|
|
|
2985 |
if (gi.block_type != Encoder.NORM_TYPE) {
|
|
|
2986 |
writeheader(gfc, 1, 1);
|
|
|
2987 |
/* window_switching_flag */
|
|
|
2988 |
writeheader(gfc, gi.block_type, 2);
|
|
|
2989 |
writeheader(gfc, gi.mixed_block_flag, 1);
|
|
|
2990 |
|
|
|
2991 |
if (gi.table_select[0] == 14)
|
|
|
2992 |
gi.table_select[0] = 16;
|
|
|
2993 |
writeheader(gfc, gi.table_select[0], 5);
|
|
|
2994 |
if (gi.table_select[1] == 14)
|
|
|
2995 |
gi.table_select[1] = 16;
|
|
|
2996 |
writeheader(gfc, gi.table_select[1], 5);
|
|
|
2997 |
|
|
|
2998 |
writeheader(gfc, gi.subblock_gain[0], 3);
|
|
|
2999 |
writeheader(gfc, gi.subblock_gain[1], 3);
|
|
|
3000 |
writeheader(gfc, gi.subblock_gain[2], 3);
|
|
|
3001 |
} else {
|
|
|
3002 |
writeheader(gfc, 0, 1);
|
|
|
3003 |
/* window_switching_flag */
|
|
|
3004 |
if (gi.table_select[0] == 14)
|
|
|
3005 |
gi.table_select[0] = 16;
|
|
|
3006 |
writeheader(gfc, gi.table_select[0], 5);
|
|
|
3007 |
if (gi.table_select[1] == 14)
|
|
|
3008 |
gi.table_select[1] = 16;
|
|
|
3009 |
writeheader(gfc, gi.table_select[1], 5);
|
|
|
3010 |
if (gi.table_select[2] == 14)
|
|
|
3011 |
gi.table_select[2] = 16;
|
|
|
3012 |
writeheader(gfc, gi.table_select[2], 5);
|
|
|
3013 |
|
|
|
3014 |
writeheader(gfc, gi.region0_count, 4);
|
|
|
3015 |
writeheader(gfc, gi.region1_count, 3);
|
|
|
3016 |
}
|
|
|
3017 |
writeheader(gfc, gi.preflag, 1);
|
|
|
3018 |
writeheader(gfc, gi.scalefac_scale, 1);
|
|
|
3019 |
writeheader(gfc, gi.count1table_select, 1);
|
|
|
3020 |
}
|
|
|
3021 |
}
|
|
|
3022 |
} else {
|
|
|
3023 |
/* MPEG2 */
|
|
|
3024 |
writeheader(gfc, (l3_side.main_data_begin), 8);
|
|
|
3025 |
writeheader(gfc, l3_side.private_bits, gfc.channels_out);
|
|
|
3026 |
|
|
|
3027 |
gr = 0;
|
|
|
3028 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
3029 |
var gi = l3_side.tt[gr][ch];
|
|
|
3030 |
writeheader(gfc, gi.part2_3_length + gi.part2_length, 12);
|
|
|
3031 |
writeheader(gfc, gi.big_values / 2, 9);
|
|
|
3032 |
writeheader(gfc, gi.global_gain, 8);
|
|
|
3033 |
writeheader(gfc, gi.scalefac_compress, 9);
|
|
|
3034 |
|
|
|
3035 |
if (gi.block_type != Encoder.NORM_TYPE) {
|
|
|
3036 |
writeheader(gfc, 1, 1);
|
|
|
3037 |
/* window_switching_flag */
|
|
|
3038 |
writeheader(gfc, gi.block_type, 2);
|
|
|
3039 |
writeheader(gfc, gi.mixed_block_flag, 1);
|
|
|
3040 |
|
|
|
3041 |
if (gi.table_select[0] == 14)
|
|
|
3042 |
gi.table_select[0] = 16;
|
|
|
3043 |
writeheader(gfc, gi.table_select[0], 5);
|
|
|
3044 |
if (gi.table_select[1] == 14)
|
|
|
3045 |
gi.table_select[1] = 16;
|
|
|
3046 |
writeheader(gfc, gi.table_select[1], 5);
|
|
|
3047 |
|
|
|
3048 |
writeheader(gfc, gi.subblock_gain[0], 3);
|
|
|
3049 |
writeheader(gfc, gi.subblock_gain[1], 3);
|
|
|
3050 |
writeheader(gfc, gi.subblock_gain[2], 3);
|
|
|
3051 |
} else {
|
|
|
3052 |
writeheader(gfc, 0, 1);
|
|
|
3053 |
/* window_switching_flag */
|
|
|
3054 |
if (gi.table_select[0] == 14)
|
|
|
3055 |
gi.table_select[0] = 16;
|
|
|
3056 |
writeheader(gfc, gi.table_select[0], 5);
|
|
|
3057 |
if (gi.table_select[1] == 14)
|
|
|
3058 |
gi.table_select[1] = 16;
|
|
|
3059 |
writeheader(gfc, gi.table_select[1], 5);
|
|
|
3060 |
if (gi.table_select[2] == 14)
|
|
|
3061 |
gi.table_select[2] = 16;
|
|
|
3062 |
writeheader(gfc, gi.table_select[2], 5);
|
|
|
3063 |
|
|
|
3064 |
writeheader(gfc, gi.region0_count, 4);
|
|
|
3065 |
writeheader(gfc, gi.region1_count, 3);
|
|
|
3066 |
}
|
|
|
3067 |
|
|
|
3068 |
writeheader(gfc, gi.scalefac_scale, 1);
|
|
|
3069 |
writeheader(gfc, gi.count1table_select, 1);
|
|
|
3070 |
}
|
|
|
3071 |
}
|
|
|
3072 |
|
|
|
3073 |
if (gfp.error_protection) {
|
|
|
3074 |
/* (jo) error_protection: add crc16 information to header */
|
|
|
3075 |
CRC_writeheader(gfc, gfc.header[gfc.h_ptr].buf);
|
|
|
3076 |
}
|
|
|
3077 |
|
|
|
3078 |
{
|
|
|
3079 |
var old = gfc.h_ptr;
|
|
|
3080 |
|
|
|
3081 |
gfc.h_ptr = (old + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1);
|
|
|
3082 |
gfc.header[gfc.h_ptr].write_timing = gfc.header[old].write_timing
|
|
|
3083 |
+ bitsPerFrame;
|
|
|
3084 |
|
|
|
3085 |
if (gfc.h_ptr == gfc.w_ptr) {
|
|
|
3086 |
/* yikes! we are out of header buffer space */
|
|
|
3087 |
System.err
|
|
|
3088 |
.println("Error: MAX_HEADER_BUF too small in bitstream.c \n");
|
|
|
3089 |
}
|
|
|
3090 |
|
|
|
3091 |
}
|
|
|
3092 |
}
|
|
|
3093 |
|
|
|
3094 |
function huffman_coder_count1(gfc, gi) {
|
|
|
3095 |
/* Write count1 area */
|
|
|
3096 |
var h = Tables.ht[gi.count1table_select + 32];
|
|
|
3097 |
var i, bits = 0;
|
|
|
3098 |
|
|
|
3099 |
var ix = gi.big_values;
|
|
|
3100 |
var xr = gi.big_values;
|
|
|
3101 |
|
|
|
3102 |
for (i = (gi.count1 - gi.big_values) / 4; i > 0; --i) {
|
|
|
3103 |
var huffbits = 0;
|
|
|
3104 |
var p = 0, v;
|
|
|
3105 |
|
|
|
3106 |
v = gi.l3_enc[ix + 0];
|
|
|
3107 |
if (v != 0) {
|
|
|
3108 |
p += 8;
|
|
|
3109 |
if (gi.xr[xr + 0] < 0)
|
|
|
3110 |
huffbits++;
|
|
|
3111 |
}
|
|
|
3112 |
|
|
|
3113 |
v = gi.l3_enc[ix + 1];
|
|
|
3114 |
if (v != 0) {
|
|
|
3115 |
p += 4;
|
|
|
3116 |
huffbits *= 2;
|
|
|
3117 |
if (gi.xr[xr + 1] < 0)
|
|
|
3118 |
huffbits++;
|
|
|
3119 |
}
|
|
|
3120 |
|
|
|
3121 |
v = gi.l3_enc[ix + 2];
|
|
|
3122 |
if (v != 0) {
|
|
|
3123 |
p += 2;
|
|
|
3124 |
huffbits *= 2;
|
|
|
3125 |
if (gi.xr[xr + 2] < 0)
|
|
|
3126 |
huffbits++;
|
|
|
3127 |
}
|
|
|
3128 |
|
|
|
3129 |
v = gi.l3_enc[ix + 3];
|
|
|
3130 |
if (v != 0) {
|
|
|
3131 |
p++;
|
|
|
3132 |
huffbits *= 2;
|
|
|
3133 |
if (gi.xr[xr + 3] < 0)
|
|
|
3134 |
huffbits++;
|
|
|
3135 |
}
|
|
|
3136 |
|
|
|
3137 |
ix += 4;
|
|
|
3138 |
xr += 4;
|
|
|
3139 |
putbits2(gfc, huffbits + h.table[p], h.hlen[p]);
|
|
|
3140 |
bits += h.hlen[p];
|
|
|
3141 |
}
|
|
|
3142 |
return bits;
|
|
|
3143 |
}
|
|
|
3144 |
|
|
|
3145 |
/**
|
|
|
3146 |
* Implements the pseudocode of page 98 of the IS
|
|
|
3147 |
*/
|
|
|
3148 |
function Huffmancode(gfc, tableindex, start, end, gi) {
|
|
|
3149 |
var h = Tables.ht[tableindex];
|
|
|
3150 |
var bits = 0;
|
|
|
3151 |
|
|
|
3152 |
if (0 == tableindex)
|
|
|
3153 |
return bits;
|
|
|
3154 |
|
|
|
3155 |
for (var i = start; i < end; i += 2) {
|
|
|
3156 |
var cbits = 0;
|
|
|
3157 |
var xbits = 0;
|
|
|
3158 |
var linbits = h.xlen;
|
|
|
3159 |
var xlen = h.xlen;
|
|
|
3160 |
var ext = 0;
|
|
|
3161 |
var x1 = gi.l3_enc[i];
|
|
|
3162 |
var x2 = gi.l3_enc[i + 1];
|
|
|
3163 |
|
|
|
3164 |
if (x1 != 0) {
|
|
|
3165 |
if (gi.xr[i] < 0)
|
|
|
3166 |
ext++;
|
|
|
3167 |
cbits--;
|
|
|
3168 |
}
|
|
|
3169 |
|
|
|
3170 |
if (tableindex > 15) {
|
|
|
3171 |
/* use ESC-words */
|
|
|
3172 |
if (x1 > 14) {
|
|
|
3173 |
var linbits_x1 = x1 - 15;
|
|
|
3174 |
ext |= linbits_x1 << 1;
|
|
|
3175 |
xbits = linbits;
|
|
|
3176 |
x1 = 15;
|
|
|
3177 |
}
|
|
|
3178 |
|
|
|
3179 |
if (x2 > 14) {
|
|
|
3180 |
var linbits_x2 = x2 - 15;
|
|
|
3181 |
ext <<= linbits;
|
|
|
3182 |
ext |= linbits_x2;
|
|
|
3183 |
xbits += linbits;
|
|
|
3184 |
x2 = 15;
|
|
|
3185 |
}
|
|
|
3186 |
xlen = 16;
|
|
|
3187 |
}
|
|
|
3188 |
|
|
|
3189 |
if (x2 != 0) {
|
|
|
3190 |
ext <<= 1;
|
|
|
3191 |
if (gi.xr[i + 1] < 0)
|
|
|
3192 |
ext++;
|
|
|
3193 |
cbits--;
|
|
|
3194 |
}
|
|
|
3195 |
|
|
|
3196 |
|
|
|
3197 |
x1 = x1 * xlen + x2;
|
|
|
3198 |
xbits -= cbits;
|
|
|
3199 |
cbits += h.hlen[x1];
|
|
|
3200 |
|
|
|
3201 |
|
|
|
3202 |
putbits2(gfc, h.table[x1], cbits);
|
|
|
3203 |
putbits2(gfc, ext, xbits);
|
|
|
3204 |
bits += cbits + xbits;
|
|
|
3205 |
}
|
|
|
3206 |
return bits;
|
|
|
3207 |
}
|
|
|
3208 |
|
|
|
3209 |
/**
|
|
|
3210 |
* Note the discussion of huffmancodebits() on pages 28 and 29 of the IS, as
|
|
|
3211 |
* well as the definitions of the side information on pages 26 and 27.
|
|
|
3212 |
*/
|
|
|
3213 |
function ShortHuffmancodebits(gfc, gi) {
|
|
|
3214 |
var region1Start = 3 * gfc.scalefac_band.s[3];
|
|
|
3215 |
if (region1Start > gi.big_values)
|
|
|
3216 |
region1Start = gi.big_values;
|
|
|
3217 |
|
|
|
3218 |
/* short blocks do not have a region2 */
|
|
|
3219 |
var bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi);
|
|
|
3220 |
bits += Huffmancode(gfc, gi.table_select[1], region1Start,
|
|
|
3221 |
gi.big_values, gi);
|
|
|
3222 |
return bits;
|
|
|
3223 |
}
|
|
|
3224 |
|
|
|
3225 |
function LongHuffmancodebits(gfc, gi) {
|
|
|
3226 |
var bigvalues, bits;
|
|
|
3227 |
var region1Start, region2Start;
|
|
|
3228 |
|
|
|
3229 |
bigvalues = gi.big_values;
|
|
|
3230 |
|
|
|
3231 |
var i = gi.region0_count + 1;
|
|
|
3232 |
region1Start = gfc.scalefac_band.l[i];
|
|
|
3233 |
i += gi.region1_count + 1;
|
|
|
3234 |
region2Start = gfc.scalefac_band.l[i];
|
|
|
3235 |
|
|
|
3236 |
if (region1Start > bigvalues)
|
|
|
3237 |
region1Start = bigvalues;
|
|
|
3238 |
|
|
|
3239 |
if (region2Start > bigvalues)
|
|
|
3240 |
region2Start = bigvalues;
|
|
|
3241 |
|
|
|
3242 |
bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi);
|
|
|
3243 |
bits += Huffmancode(gfc, gi.table_select[1], region1Start,
|
|
|
3244 |
region2Start, gi);
|
|
|
3245 |
bits += Huffmancode(gfc, gi.table_select[2], region2Start, bigvalues,
|
|
|
3246 |
gi);
|
|
|
3247 |
return bits;
|
|
|
3248 |
}
|
|
|
3249 |
|
|
|
3250 |
function writeMainData(gfp) {
|
|
|
3251 |
var gr, ch, sfb, data_bits, tot_bits = 0;
|
|
|
3252 |
var gfc = gfp.internal_flags;
|
|
|
3253 |
var l3_side = gfc.l3_side;
|
|
|
3254 |
|
|
|
3255 |
if (gfp.version == 1) {
|
|
|
3256 |
/* MPEG 1 */
|
|
|
3257 |
for (gr = 0; gr < 2; gr++) {
|
|
|
3258 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
3259 |
var gi = l3_side.tt[gr][ch];
|
|
|
3260 |
var slen1 = Takehiro.slen1_tab[gi.scalefac_compress];
|
|
|
3261 |
var slen2 = Takehiro.slen2_tab[gi.scalefac_compress];
|
|
|
3262 |
data_bits = 0;
|
|
|
3263 |
for (sfb = 0; sfb < gi.sfbdivide; sfb++) {
|
|
|
3264 |
if (gi.scalefac[sfb] == -1)
|
|
|
3265 |
continue;
|
|
|
3266 |
/* scfsi is used */
|
|
|
3267 |
putbits2(gfc, gi.scalefac[sfb], slen1);
|
|
|
3268 |
data_bits += slen1;
|
|
|
3269 |
}
|
|
|
3270 |
for (; sfb < gi.sfbmax; sfb++) {
|
|
|
3271 |
if (gi.scalefac[sfb] == -1)
|
|
|
3272 |
continue;
|
|
|
3273 |
/* scfsi is used */
|
|
|
3274 |
putbits2(gfc, gi.scalefac[sfb], slen2);
|
|
|
3275 |
data_bits += slen2;
|
|
|
3276 |
}
|
|
|
3277 |
|
|
|
3278 |
if (gi.block_type == Encoder.SHORT_TYPE) {
|
|
|
3279 |
data_bits += ShortHuffmancodebits(gfc, gi);
|
|
|
3280 |
} else {
|
|
|
3281 |
data_bits += LongHuffmancodebits(gfc, gi);
|
|
|
3282 |
}
|
|
|
3283 |
data_bits += huffman_coder_count1(gfc, gi);
|
|
|
3284 |
/* does bitcount in quantize.c agree with actual bit count? */
|
|
|
3285 |
tot_bits += data_bits;
|
|
|
3286 |
}
|
|
|
3287 |
/* for ch */
|
|
|
3288 |
}
|
|
|
3289 |
/* for gr */
|
|
|
3290 |
} else {
|
|
|
3291 |
/* MPEG 2 */
|
|
|
3292 |
gr = 0;
|
|
|
3293 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
3294 |
var gi = l3_side.tt[gr][ch];
|
|
|
3295 |
var i, sfb_partition, scale_bits = 0;
|
|
|
3296 |
data_bits = 0;
|
|
|
3297 |
sfb = 0;
|
|
|
3298 |
sfb_partition = 0;
|
|
|
3299 |
|
|
|
3300 |
if (gi.block_type == Encoder.SHORT_TYPE) {
|
|
|
3301 |
for (; sfb_partition < 4; sfb_partition++) {
|
|
|
3302 |
var sfbs = gi.sfb_partition_table[sfb_partition] / 3;
|
|
|
3303 |
var slen = gi.slen[sfb_partition];
|
|
|
3304 |
for (i = 0; i < sfbs; i++, sfb++) {
|
|
|
3305 |
putbits2(gfc,
|
|
|
3306 |
Math.max(gi.scalefac[sfb * 3 + 0], 0), slen);
|
|
|
3307 |
putbits2(gfc,
|
|
|
3308 |
Math.max(gi.scalefac[sfb * 3 + 1], 0), slen);
|
|
|
3309 |
putbits2(gfc,
|
|
|
3310 |
Math.max(gi.scalefac[sfb * 3 + 2], 0), slen);
|
|
|
3311 |
scale_bits += 3 * slen;
|
|
|
3312 |
}
|
|
|
3313 |
}
|
|
|
3314 |
data_bits += ShortHuffmancodebits(gfc, gi);
|
|
|
3315 |
} else {
|
|
|
3316 |
for (; sfb_partition < 4; sfb_partition++) {
|
|
|
3317 |
var sfbs = gi.sfb_partition_table[sfb_partition];
|
|
|
3318 |
var slen = gi.slen[sfb_partition];
|
|
|
3319 |
for (i = 0; i < sfbs; i++, sfb++) {
|
|
|
3320 |
putbits2(gfc, Math.max(gi.scalefac[sfb], 0), slen);
|
|
|
3321 |
scale_bits += slen;
|
|
|
3322 |
}
|
|
|
3323 |
}
|
|
|
3324 |
data_bits += LongHuffmancodebits(gfc, gi);
|
|
|
3325 |
}
|
|
|
3326 |
data_bits += huffman_coder_count1(gfc, gi);
|
|
|
3327 |
/* does bitcount in quantize.c agree with actual bit count? */
|
|
|
3328 |
tot_bits += scale_bits + data_bits;
|
|
|
3329 |
}
|
|
|
3330 |
/* for ch */
|
|
|
3331 |
}
|
|
|
3332 |
/* for gf */
|
|
|
3333 |
return tot_bits;
|
|
|
3334 |
}
|
|
|
3335 |
|
|
|
3336 |
/* main_data */
|
|
|
3337 |
|
|
|
3338 |
function TotalBytes() {
|
|
|
3339 |
this.total = 0;
|
|
|
3340 |
}
|
|
|
3341 |
|
|
|
3342 |
/*
|
|
|
3343 |
* compute the number of bits required to flush all mp3 frames currently in
|
|
|
3344 |
* the buffer. This should be the same as the reservoir size. Only call this
|
|
|
3345 |
* routine between frames - i.e. only after all headers and data have been
|
|
|
3346 |
* added to the buffer by format_bitstream().
|
|
|
3347 |
*
|
|
|
3348 |
* Also compute total_bits_output = size of mp3 buffer (including frame
|
|
|
3349 |
* headers which may not have yet been send to the mp3 buffer) + number of
|
|
|
3350 |
* bits needed to flush all mp3 frames.
|
|
|
3351 |
*
|
|
|
3352 |
* total_bytes_output is the size of the mp3 output buffer if
|
|
|
3353 |
* lame_encode_flush_nogap() was called right now.
|
|
|
3354 |
*/
|
|
|
3355 |
function compute_flushbits(gfp, total_bytes_output) {
|
|
|
3356 |
var gfc = gfp.internal_flags;
|
|
|
3357 |
var flushbits, remaining_headers;
|
|
|
3358 |
var bitsPerFrame;
|
|
|
3359 |
var last_ptr, first_ptr;
|
|
|
3360 |
first_ptr = gfc.w_ptr;
|
|
|
3361 |
/* first header to add to bitstream */
|
|
|
3362 |
last_ptr = gfc.h_ptr - 1;
|
|
|
3363 |
/* last header to add to bitstream */
|
|
|
3364 |
if (last_ptr == -1)
|
|
|
3365 |
last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1;
|
|
|
3366 |
|
|
|
3367 |
/* add this many bits to bitstream so we can flush all headers */
|
|
|
3368 |
flushbits = gfc.header[last_ptr].write_timing - totbit;
|
|
|
3369 |
total_bytes_output.total = flushbits;
|
|
|
3370 |
|
|
|
3371 |
if (flushbits >= 0) {
|
|
|
3372 |
/* if flushbits >= 0, some headers have not yet been written */
|
|
|
3373 |
/* reduce flushbits by the size of the headers */
|
|
|
3374 |
remaining_headers = 1 + last_ptr - first_ptr;
|
|
|
3375 |
if (last_ptr < first_ptr)
|
|
|
3376 |
remaining_headers = 1 + last_ptr - first_ptr
|
|
|
3377 |
+ LameInternalFlags.MAX_HEADER_BUF;
|
|
|
3378 |
flushbits -= remaining_headers * 8 * gfc.sideinfo_len;
|
|
|
3379 |
}
|
|
|
3380 |
|
|
|
3381 |
/*
|
|
|
3382 |
* finally, add some bits so that the last frame is complete these bits
|
|
|
3383 |
* are not necessary to decode the last frame, but some decoders will
|
|
|
3384 |
* ignore last frame if these bits are missing
|
|
|
3385 |
*/
|
|
|
3386 |
bitsPerFrame = self.getframebits(gfp);
|
|
|
3387 |
flushbits += bitsPerFrame;
|
|
|
3388 |
total_bytes_output.total += bitsPerFrame;
|
|
|
3389 |
/* round up: */
|
|
|
3390 |
if ((total_bytes_output.total % 8) != 0)
|
|
|
3391 |
total_bytes_output.total = 1 + (total_bytes_output.total / 8);
|
|
|
3392 |
else
|
|
|
3393 |
total_bytes_output.total = (total_bytes_output.total / 8);
|
|
|
3394 |
total_bytes_output.total += bufByteIdx + 1;
|
|
|
3395 |
|
|
|
3396 |
if (flushbits < 0) {
|
|
|
3397 |
System.err.println("strange error flushing buffer ... \n");
|
|
|
3398 |
}
|
|
|
3399 |
return flushbits;
|
|
|
3400 |
}
|
|
|
3401 |
|
|
|
3402 |
this.flush_bitstream = function (gfp) {
|
|
|
3403 |
var gfc = gfp.internal_flags;
|
|
|
3404 |
var l3_side;
|
|
|
3405 |
var flushbits;
|
|
|
3406 |
var last_ptr = gfc.h_ptr - 1;
|
|
|
3407 |
/* last header to add to bitstream */
|
|
|
3408 |
if (last_ptr == -1)
|
|
|
3409 |
last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1;
|
|
|
3410 |
l3_side = gfc.l3_side;
|
|
|
3411 |
|
|
|
3412 |
if ((flushbits = compute_flushbits(gfp, new TotalBytes())) < 0)
|
|
|
3413 |
return;
|
|
|
3414 |
drain_into_ancillary(gfp, flushbits);
|
|
|
3415 |
|
|
|
3416 |
/* check that the 100% of the last frame has been written to bitstream */
|
|
|
3417 |
|
|
|
3418 |
/*
|
|
|
3419 |
* we have padded out all frames with ancillary data, which is the same
|
|
|
3420 |
* as filling the bitreservoir with ancillary data, so :
|
|
|
3421 |
*/
|
|
|
3422 |
gfc.ResvSize = 0;
|
|
|
3423 |
l3_side.main_data_begin = 0;
|
|
|
3424 |
|
|
|
3425 |
/* save the ReplayGain value */
|
|
|
3426 |
if (gfc.findReplayGain) {
|
|
|
3427 |
var RadioGain = ga.GetTitleGain(gfc.rgdata);
|
|
|
3428 |
gfc.RadioGain = Math.floor(RadioGain * 10.0 + 0.5) | 0;
|
|
|
3429 |
/* round to nearest */
|
|
|
3430 |
}
|
|
|
3431 |
|
|
|
3432 |
/* find the gain and scale change required for no clipping */
|
|
|
3433 |
if (gfc.findPeakSample) {
|
|
|
3434 |
gfc.noclipGainChange = Math.ceil(Math
|
|
|
3435 |
.log10(gfc.PeakSample / 32767.0) * 20.0 * 10.0) | 0;
|
|
|
3436 |
/* round up */
|
|
|
3437 |
|
|
|
3438 |
if (gfc.noclipGainChange > 0) {
|
|
|
3439 |
/* clipping occurs */
|
|
|
3440 |
if (EQ(gfp.scale, 1.0) || EQ(gfp.scale, 0.0))
|
|
|
3441 |
gfc.noclipScale = (Math
|
|
|
3442 |
.floor((32767.0 / gfc.PeakSample) * 100.0) / 100.0);
|
|
|
3443 |
/* round down */
|
|
|
3444 |
else {
|
|
|
3445 |
/*
|
|
|
3446 |
* the user specified his own scaling factor. We could
|
|
|
3447 |
* suggest the scaling factor of
|
|
|
3448 |
* (32767.0/gfp.PeakSample)*(gfp.scale) but it's usually
|
|
|
3449 |
* very inaccurate. So we'd rather not advice him on the
|
|
|
3450 |
* scaling factor.
|
|
|
3451 |
*/
|
|
|
3452 |
gfc.noclipScale = -1;
|
|
|
3453 |
}
|
|
|
3454 |
} else
|
|
|
3455 |
/* no clipping */
|
|
|
3456 |
gfc.noclipScale = -1;
|
|
|
3457 |
}
|
|
|
3458 |
};
|
|
|
3459 |
|
|
|
3460 |
this.add_dummy_byte = function (gfp, val, n) {
|
|
|
3461 |
var gfc = gfp.internal_flags;
|
|
|
3462 |
var i;
|
|
|
3463 |
|
|
|
3464 |
while (n-- > 0) {
|
|
|
3465 |
putbits_noheaders(gfc, val, 8);
|
|
|
3466 |
|
|
|
3467 |
for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i)
|
|
|
3468 |
gfc.header[i].write_timing += 8;
|
|
|
3469 |
}
|
|
|
3470 |
};
|
|
|
3471 |
|
|
|
3472 |
/**
|
|
|
3473 |
* This is called after a frame of audio has been quantized and coded. It
|
|
|
3474 |
* will write the encoded audio to the bitstream. Note that from a layer3
|
|
|
3475 |
* encoder's perspective the bit stream is primarily a series of main_data()
|
|
|
3476 |
* blocks, with header and side information inserted at the proper locations
|
|
|
3477 |
* to maintain framing. (See Figure A.7 in the IS).
|
|
|
3478 |
*/
|
|
|
3479 |
this.format_bitstream = function (gfp) {
|
|
|
3480 |
var gfc = gfp.internal_flags;
|
|
|
3481 |
var l3_side;
|
|
|
3482 |
l3_side = gfc.l3_side;
|
|
|
3483 |
|
|
|
3484 |
var bitsPerFrame = this.getframebits(gfp);
|
|
|
3485 |
drain_into_ancillary(gfp, l3_side.resvDrain_pre);
|
|
|
3486 |
|
|
|
3487 |
encodeSideInfo2(gfp, bitsPerFrame);
|
|
|
3488 |
var bits = 8 * gfc.sideinfo_len;
|
|
|
3489 |
bits += writeMainData(gfp);
|
|
|
3490 |
drain_into_ancillary(gfp, l3_side.resvDrain_post);
|
|
|
3491 |
bits += l3_side.resvDrain_post;
|
|
|
3492 |
|
|
|
3493 |
l3_side.main_data_begin += (bitsPerFrame - bits) / 8;
|
|
|
3494 |
|
|
|
3495 |
/*
|
|
|
3496 |
* compare number of bits needed to clear all buffered mp3 frames with
|
|
|
3497 |
* what we think the resvsize is:
|
|
|
3498 |
*/
|
|
|
3499 |
if (compute_flushbits(gfp, new TotalBytes()) != gfc.ResvSize) {
|
|
|
3500 |
System.err.println("Internal buffer inconsistency. flushbits <> ResvSize");
|
|
|
3501 |
}
|
|
|
3502 |
|
|
|
3503 |
/*
|
|
|
3504 |
* compare main_data_begin for the next frame with what we think the
|
|
|
3505 |
* resvsize is:
|
|
|
3506 |
*/
|
|
|
3507 |
if ((l3_side.main_data_begin * 8) != gfc.ResvSize) {
|
|
|
3508 |
System.err.printf("bit reservoir error: \n"
|
|
|
3509 |
+ "l3_side.main_data_begin: %d \n"
|
|
|
3510 |
+ "Resvoir size: %d \n"
|
|
|
3511 |
+ "resv drain (post) %d \n"
|
|
|
3512 |
+ "resv drain (pre) %d \n"
|
|
|
3513 |
+ "header and sideinfo: %d \n"
|
|
|
3514 |
+ "data bits: %d \n"
|
|
|
3515 |
+ "total bits: %d (remainder: %d) \n"
|
|
|
3516 |
+ "bitsperframe: %d \n",
|
|
|
3517 |
8 * l3_side.main_data_begin, gfc.ResvSize,
|
|
|
3518 |
l3_side.resvDrain_post, l3_side.resvDrain_pre,
|
|
|
3519 |
8 * gfc.sideinfo_len, bits - l3_side.resvDrain_post - 8
|
|
|
3520 |
* gfc.sideinfo_len, bits, bits % 8, bitsPerFrame);
|
|
|
3521 |
|
|
|
3522 |
System.err.println("This is a fatal error. It has several possible causes:");
|
|
|
3523 |
System.err.println("90%% LAME compiled with buggy version of gcc using advanced optimizations");
|
|
|
3524 |
System.err.println(" 9%% Your system is overclocked");
|
|
|
3525 |
System.err.println(" 1%% bug in LAME encoding library");
|
|
|
3526 |
|
|
|
3527 |
gfc.ResvSize = l3_side.main_data_begin * 8;
|
|
|
3528 |
}
|
|
|
3529 |
//;
|
|
|
3530 |
|
|
|
3531 |
if (totbit > 1000000000) {
|
|
|
3532 |
/*
|
|
|
3533 |
* to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset
|
|
|
3534 |
* bit counter
|
|
|
3535 |
*/
|
|
|
3536 |
var i;
|
|
|
3537 |
for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i)
|
|
|
3538 |
gfc.header[i].write_timing -= totbit;
|
|
|
3539 |
totbit = 0;
|
|
|
3540 |
}
|
|
|
3541 |
|
|
|
3542 |
return 0;
|
|
|
3543 |
};
|
|
|
3544 |
|
|
|
3545 |
/**
|
|
|
3546 |
* <PRE>
|
|
|
3547 |
* copy data out of the internal MP3 bit buffer into a user supplied
|
|
|
3548 |
* unsigned char buffer.
|
|
|
3549 |
*
|
|
|
3550 |
* mp3data=0 indicates data in buffer is an id3tags and VBR tags
|
|
|
3551 |
* mp3data=1 data is real mp3 frame data.
|
|
|
3552 |
* </PRE>
|
|
|
3553 |
*/
|
|
|
3554 |
this.copy_buffer = function (gfc, buffer, bufferPos, size, mp3data) {
|
|
|
3555 |
var minimum = bufByteIdx + 1;
|
|
|
3556 |
if (minimum <= 0)
|
|
|
3557 |
return 0;
|
|
|
3558 |
if (size != 0 && minimum > size) {
|
|
|
3559 |
/* buffer is too small */
|
|
|
3560 |
return -1;
|
|
|
3561 |
}
|
|
|
3562 |
System.arraycopy(buf, 0, buffer, bufferPos, minimum);
|
|
|
3563 |
bufByteIdx = -1;
|
|
|
3564 |
bufBitIdx = 0;
|
|
|
3565 |
|
|
|
3566 |
if (mp3data != 0) {
|
|
|
3567 |
var crc = new_int(1);
|
|
|
3568 |
crc[0] = gfc.nMusicCRC;
|
|
|
3569 |
vbr.updateMusicCRC(crc, buffer, bufferPos, minimum);
|
|
|
3570 |
gfc.nMusicCRC = crc[0];
|
|
|
3571 |
|
|
|
3572 |
/**
|
|
|
3573 |
* sum number of bytes belonging to the mp3 stream this info will be
|
|
|
3574 |
* written into the Xing/LAME header for seeking
|
|
|
3575 |
*/
|
|
|
3576 |
if (minimum > 0) {
|
|
|
3577 |
gfc.VBR_seek_table.nBytesWritten += minimum;
|
|
|
3578 |
}
|
|
|
3579 |
|
|
|
3580 |
if (gfc.decode_on_the_fly) { /* decode the frame */
|
|
|
3581 |
var pcm_buf = new_float_n([2, 1152]);
|
|
|
3582 |
var mp3_in = minimum;
|
|
|
3583 |
var samples_out = -1;
|
|
|
3584 |
var i;
|
|
|
3585 |
|
|
|
3586 |
/* re-synthesis to pcm. Repeat until we get a samples_out=0 */
|
|
|
3587 |
while (samples_out != 0) {
|
|
|
3588 |
|
|
|
3589 |
samples_out = mpg.hip_decode1_unclipped(gfc.hip, buffer,
|
|
|
3590 |
bufferPos, mp3_in, pcm_buf[0], pcm_buf[1]);
|
|
|
3591 |
/*
|
|
|
3592 |
* samples_out = 0: need more data to decode samples_out =
|
|
|
3593 |
* -1: error. Lets assume 0 pcm output samples_out = number
|
|
|
3594 |
* of samples output
|
|
|
3595 |
*/
|
|
|
3596 |
|
|
|
3597 |
/*
|
|
|
3598 |
* set the lenght of the mp3 input buffer to zero, so that
|
|
|
3599 |
* in the next iteration of the loop we will be querying
|
|
|
3600 |
* mpglib about buffered data
|
|
|
3601 |
*/
|
|
|
3602 |
mp3_in = 0;
|
|
|
3603 |
|
|
|
3604 |
if (samples_out == -1) {
|
|
|
3605 |
/*
|
|
|
3606 |
* error decoding. Not fatal, but might screw up the
|
|
|
3607 |
* ReplayGain tag. What should we do? Ignore for now
|
|
|
3608 |
*/
|
|
|
3609 |
samples_out = 0;
|
|
|
3610 |
}
|
|
|
3611 |
if (samples_out > 0) {
|
|
|
3612 |
/* process the PCM data */
|
|
|
3613 |
|
|
|
3614 |
/*
|
|
|
3615 |
* this should not be possible, and indicates we have
|
|
|
3616 |
* overflown the pcm_buf buffer
|
|
|
3617 |
*/
|
|
|
3618 |
|
|
|
3619 |
if (gfc.findPeakSample) {
|
|
|
3620 |
for (i = 0; i < samples_out; i++) {
|
|
|
3621 |
if (pcm_buf[0][i] > gfc.PeakSample)
|
|
|
3622 |
gfc.PeakSample = pcm_buf[0][i];
|
|
|
3623 |
else if (-pcm_buf[0][i] > gfc.PeakSample)
|
|
|
3624 |
gfc.PeakSample = -pcm_buf[0][i];
|
|
|
3625 |
}
|
|
|
3626 |
if (gfc.channels_out > 1)
|
|
|
3627 |
for (i = 0; i < samples_out; i++) {
|
|
|
3628 |
if (pcm_buf[1][i] > gfc.PeakSample)
|
|
|
3629 |
gfc.PeakSample = pcm_buf[1][i];
|
|
|
3630 |
else if (-pcm_buf[1][i] > gfc.PeakSample)
|
|
|
3631 |
gfc.PeakSample = -pcm_buf[1][i];
|
|
|
3632 |
}
|
|
|
3633 |
}
|
|
|
3634 |
|
|
|
3635 |
if (gfc.findReplayGain)
|
|
|
3636 |
if (ga.AnalyzeSamples(gfc.rgdata, pcm_buf[0], 0,
|
|
|
3637 |
pcm_buf[1], 0, samples_out,
|
|
|
3638 |
gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR)
|
|
|
3639 |
return -6;
|
|
|
3640 |
|
|
|
3641 |
}
|
|
|
3642 |
/* if (samples_out>0) */
|
|
|
3643 |
}
|
|
|
3644 |
/* while (samples_out!=0) */
|
|
|
3645 |
}
|
|
|
3646 |
/* if (gfc.decode_on_the_fly) */
|
|
|
3647 |
|
|
|
3648 |
}
|
|
|
3649 |
/* if (mp3data) */
|
|
|
3650 |
return minimum;
|
|
|
3651 |
};
|
|
|
3652 |
|
|
|
3653 |
this.init_bit_stream_w = function (gfc) {
|
|
|
3654 |
buf = new_byte(Lame.LAME_MAXMP3BUFFER);
|
|
|
3655 |
|
|
|
3656 |
gfc.h_ptr = gfc.w_ptr = 0;
|
|
|
3657 |
gfc.header[gfc.h_ptr].write_timing = 0;
|
|
|
3658 |
bufByteIdx = -1;
|
|
|
3659 |
bufBitIdx = 0;
|
|
|
3660 |
totbit = 0;
|
|
|
3661 |
};
|
|
|
3662 |
|
|
|
3663 |
// From machine.h
|
|
|
3664 |
|
|
|
3665 |
|
|
|
3666 |
}
|
|
|
3667 |
|
|
|
3668 |
|
|
|
3669 |
/**
|
|
|
3670 |
* A Vbr header may be present in the ancillary data field of the first frame of
|
|
|
3671 |
* an mp3 bitstream<BR>
|
|
|
3672 |
* The Vbr header (optionally) contains
|
|
|
3673 |
* <UL>
|
|
|
3674 |
* <LI>frames total number of audio frames in the bitstream
|
|
|
3675 |
* <LI>bytes total number of bytes in the bitstream
|
|
|
3676 |
* <LI>toc table of contents
|
|
|
3677 |
* </UL>
|
|
|
3678 |
*
|
|
|
3679 |
* toc (table of contents) gives seek points for random access.<BR>
|
|
|
3680 |
* The ith entry determines the seek point for i-percent duration.<BR>
|
|
|
3681 |
* seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes<BR>
|
|
|
3682 |
* e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes
|
|
|
3683 |
*/
|
|
|
3684 |
VBRTag.NUMTOCENTRIES = 100;
|
|
|
3685 |
VBRTag.MAXFRAMESIZE = 2880;
|
|
|
3686 |
|
|
|
3687 |
function VBRTag() {
|
|
|
3688 |
|
|
|
3689 |
var lame;
|
|
|
3690 |
var bs;
|
|
|
3691 |
var v;
|
|
|
3692 |
|
|
|
3693 |
this.setModules = function (_lame, _bs, _v) {
|
|
|
3694 |
lame = _lame;
|
|
|
3695 |
bs = _bs;
|
|
|
3696 |
v = _v;
|
|
|
3697 |
};
|
|
|
3698 |
|
|
|
3699 |
var FRAMES_FLAG = 0x0001;
|
|
|
3700 |
var BYTES_FLAG = 0x0002;
|
|
|
3701 |
var TOC_FLAG = 0x0004;
|
|
|
3702 |
var VBR_SCALE_FLAG = 0x0008;
|
|
|
3703 |
|
|
|
3704 |
var NUMTOCENTRIES = VBRTag.NUMTOCENTRIES;
|
|
|
3705 |
|
|
|
3706 |
/**
|
|
|
3707 |
* (0xB40) the max freeformat 640 32kHz framesize.
|
|
|
3708 |
*/
|
|
|
3709 |
var MAXFRAMESIZE = VBRTag.MAXFRAMESIZE;
|
|
|
3710 |
|
|
|
3711 |
/**
|
|
|
3712 |
* <PRE>
|
|
|
3713 |
* 4 bytes for Header Tag
|
|
|
3714 |
* 4 bytes for Header Flags
|
|
|
3715 |
* 100 bytes for entry (toc)
|
|
|
3716 |
* 4 bytes for frame size
|
|
|
3717 |
* 4 bytes for stream size
|
|
|
3718 |
* 4 bytes for VBR scale. a VBR quality indicator: 0=best 100=worst
|
|
|
3719 |
* 20 bytes for LAME tag. for example, "LAME3.12 (beta 6)"
|
|
|
3720 |
* ___________
|
|
|
3721 |
* 140 bytes
|
|
|
3722 |
* </PRE>
|
|
|
3723 |
*/
|
|
|
3724 |
var VBRHEADERSIZE = (NUMTOCENTRIES + 4 + 4 + 4 + 4 + 4);
|
|
|
3725 |
|
|
|
3726 |
var LAMEHEADERSIZE = (VBRHEADERSIZE + 9 + 1 + 1 + 8
|
|
|
3727 |
+ 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2);
|
|
|
3728 |
|
|
|
3729 |
/**
|
|
|
3730 |
* The size of the Xing header MPEG-1, bit rate in kbps.
|
|
|
3731 |
*/
|
|
|
3732 |
var XING_BITRATE1 = 128;
|
|
|
3733 |
/**
|
|
|
3734 |
* The size of the Xing header MPEG-2, bit rate in kbps.
|
|
|
3735 |
*/
|
|
|
3736 |
var XING_BITRATE2 = 64;
|
|
|
3737 |
/**
|
|
|
3738 |
* The size of the Xing header MPEG-2.5, bit rate in kbps.
|
|
|
3739 |
*/
|
|
|
3740 |
var XING_BITRATE25 = 32;
|
|
|
3741 |
|
|
|
3742 |
/**
|
|
|
3743 |
* ISO-8859-1 charset for byte to string operations.
|
|
|
3744 |
*/
|
|
|
3745 |
var ISO_8859_1 = null; //Charset.forName("ISO-8859-1");
|
|
|
3746 |
|
|
|
3747 |
/**
|
|
|
3748 |
* VBR header magic string.
|
|
|
3749 |
*/
|
|
|
3750 |
var VBRTag0 = "Xing";
|
|
|
3751 |
/**
|
|
|
3752 |
* VBR header magic string (VBR == VBRMode.vbr_off).
|
|
|
3753 |
*/
|
|
|
3754 |
var VBRTag1 = "Info";
|
|
|
3755 |
|
|
|
3756 |
/**
|
|
|
3757 |
* Lookup table for fast CRC-16 computation. Uses the polynomial
|
|
|
3758 |
* x^16+x^15+x^2+1
|
|
|
3759 |
*/
|
|
|
3760 |
var crc16Lookup = [0x0000, 0xC0C1, 0xC181, 0x0140,
|
|
|
3761 |
0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741,
|
|
|
3762 |
0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41,
|
|
|
3763 |
0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40,
|
|
|
3764 |
0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941,
|
|
|
3765 |
0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40,
|
|
|
3766 |
0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540,
|
|
|
3767 |
0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341,
|
|
|
3768 |
0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141,
|
|
|
3769 |
0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740,
|
|
|
3770 |
0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40,
|
|
|
3771 |
0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41,
|
|
|
3772 |
0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940,
|
|
|
3773 |
0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41,
|
|
|
3774 |
0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541,
|
|
|
3775 |
0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340,
|
|
|
3776 |
0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141,
|
|
|
3777 |
0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740,
|
|
|
3778 |
0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40,
|
|
|
3779 |
0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41,
|
|
|
3780 |
0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940,
|
|
|
3781 |
0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41,
|
|
|
3782 |
0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541,
|
|
|
3783 |
0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340,
|
|
|
3784 |
0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140,
|
|
|
3785 |
0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741,
|
|
|
3786 |
0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41,
|
|
|
3787 |
0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40,
|
|
|
3788 |
0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941,
|
|
|
3789 |
0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40,
|
|
|
3790 |
0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540,
|
|
|
3791 |
0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341,
|
|
|
3792 |
0x4100, 0x81C1, 0x8081, 0x4040];
|
|
|
3793 |
|
|
|
3794 |
/***********************************************************************
|
|
|
3795 |
* Robert Hegemann 2001-01-17
|
|
|
3796 |
***********************************************************************/
|
|
|
3797 |
|
|
|
3798 |
function addVbr(v, bitrate) {
|
|
|
3799 |
v.nVbrNumFrames++;
|
|
|
3800 |
v.sum += bitrate;
|
|
|
3801 |
v.seen++;
|
|
|
3802 |
|
|
|
3803 |
if (v.seen < v.want) {
|
|
|
3804 |
return;
|
|
|
3805 |
}
|
|
|
3806 |
|
|
|
3807 |
if (v.pos < v.size) {
|
|
|
3808 |
v.bag[v.pos] = v.sum;
|
|
|
3809 |
v.pos++;
|
|
|
3810 |
v.seen = 0;
|
|
|
3811 |
}
|
|
|
3812 |
if (v.pos == v.size) {
|
|
|
3813 |
for (var i = 1; i < v.size; i += 2) {
|
|
|
3814 |
v.bag[i / 2] = v.bag[i];
|
|
|
3815 |
}
|
|
|
3816 |
v.want *= 2;
|
|
|
3817 |
v.pos /= 2;
|
|
|
3818 |
}
|
|
|
3819 |
}
|
|
|
3820 |
|
|
|
3821 |
function xingSeekTable(v, t) {
|
|
|
3822 |
if (v.pos <= 0)
|
|
|
3823 |
return;
|
|
|
3824 |
|
|
|
3825 |
for (var i = 1; i < NUMTOCENTRIES; ++i) {
|
|
|
3826 |
var j = i / NUMTOCENTRIES, act, sum;
|
|
|
3827 |
var indx = 0 | (Math.floor(j * v.pos));
|
|
|
3828 |
if (indx > v.pos - 1)
|
|
|
3829 |
indx = v.pos - 1;
|
|
|
3830 |
act = v.bag[indx];
|
|
|
3831 |
sum = v.sum;
|
|
|
3832 |
var seek_point = 0 | (256. * act / sum);
|
|
|
3833 |
if (seek_point > 255)
|
|
|
3834 |
seek_point = 255;
|
|
|
3835 |
t[i] = 0xff & seek_point;
|
|
|
3836 |
}
|
|
|
3837 |
}
|
|
|
3838 |
|
|
|
3839 |
/**
|
|
|
3840 |
* Add VBR entry, used to fill the VBR TOC entries.
|
|
|
3841 |
*
|
|
|
3842 |
* @param gfp
|
|
|
3843 |
* global flags
|
|
|
3844 |
*/
|
|
|
3845 |
this.addVbrFrame = function (gfp) {
|
|
|
3846 |
var gfc = gfp.internal_flags;
|
|
|
3847 |
var kbps = Tables.bitrate_table[gfp.version][gfc.bitrate_index];
|
|
|
3848 |
addVbr(gfc.VBR_seek_table, kbps);
|
|
|
3849 |
}
|
|
|
3850 |
|
|
|
3851 |
/**
|
|
|
3852 |
* Read big endian integer (4-bytes) from header.
|
|
|
3853 |
*
|
|
|
3854 |
* @param buf
|
|
|
3855 |
* header containing the integer
|
|
|
3856 |
* @param bufPos
|
|
|
3857 |
* offset into the header
|
|
|
3858 |
* @return extracted integer
|
|
|
3859 |
*/
|
|
|
3860 |
function extractInteger(buf, bufPos) {
|
|
|
3861 |
var x = buf[bufPos + 0] & 0xff;
|
|
|
3862 |
x <<= 8;
|
|
|
3863 |
x |= buf[bufPos + 1] & 0xff;
|
|
|
3864 |
x <<= 8;
|
|
|
3865 |
x |= buf[bufPos + 2] & 0xff;
|
|
|
3866 |
x <<= 8;
|
|
|
3867 |
x |= buf[bufPos + 3] & 0xff;
|
|
|
3868 |
return x;
|
|
|
3869 |
}
|
|
|
3870 |
|
|
|
3871 |
/**
|
|
|
3872 |
* Write big endian integer (4-bytes) in the header.
|
|
|
3873 |
*
|
|
|
3874 |
* @param buf
|
|
|
3875 |
* header to write the integer into
|
|
|
3876 |
* @param bufPos
|
|
|
3877 |
* offset into the header
|
|
|
3878 |
* @param value
|
|
|
3879 |
* integer value to write
|
|
|
3880 |
*/
|
|
|
3881 |
function createInteger(buf, bufPos, value) {
|
|
|
3882 |
buf[bufPos + 0] = 0xff & ((value >> 24) & 0xff);
|
|
|
3883 |
buf[bufPos + 1] = 0xff & ((value >> 16) & 0xff);
|
|
|
3884 |
buf[bufPos + 2] = 0xff & ((value >> 8) & 0xff);
|
|
|
3885 |
buf[bufPos + 3] = 0xff & (value & 0xff);
|
|
|
3886 |
}
|
|
|
3887 |
|
|
|
3888 |
/**
|
|
|
3889 |
* Write big endian short (2-bytes) in the header.
|
|
|
3890 |
*
|
|
|
3891 |
* @param buf
|
|
|
3892 |
* header to write the integer into
|
|
|
3893 |
* @param bufPos
|
|
|
3894 |
* offset into the header
|
|
|
3895 |
* @param value
|
|
|
3896 |
* integer value to write
|
|
|
3897 |
*/
|
|
|
3898 |
function createShort(buf, bufPos, value) {
|
|
|
3899 |
buf[bufPos + 0] = 0xff & ((value >> 8) & 0xff);
|
|
|
3900 |
buf[bufPos + 1] = 0xff & (value & 0xff);
|
|
|
3901 |
}
|
|
|
3902 |
|
|
|
3903 |
/**
|
|
|
3904 |
* Check for magic strings (Xing/Info).
|
|
|
3905 |
*
|
|
|
3906 |
* @param buf
|
|
|
3907 |
* header to check
|
|
|
3908 |
* @param bufPos
|
|
|
3909 |
* header offset to check
|
|
|
3910 |
* @return magic string found
|
|
|
3911 |
*/
|
|
|
3912 |
function isVbrTag(buf, bufPos) {
|
|
|
3913 |
return new String(buf, bufPos, VBRTag0.length(), ISO_8859_1)
|
|
|
3914 |
.equals(VBRTag0)
|
|
|
3915 |
|| new String(buf, bufPos, VBRTag1.length(), ISO_8859_1)
|
|
|
3916 |
.equals(VBRTag1);
|
|
|
3917 |
}
|
|
|
3918 |
|
|
|
3919 |
function shiftInBitsValue(x, n, v) {
|
|
|
3920 |
return 0xff & ((x << n) | (v & ~(-1 << n)));
|
|
|
3921 |
}
|
|
|
3922 |
|
|
|
3923 |
/**
|
|
|
3924 |
* Construct the MP3 header using the settings of the global flags.
|
|
|
3925 |
*
|
|
|
3926 |
* <img src="1000px-Mp3filestructure.svg.png">
|
|
|
3927 |
*
|
|
|
3928 |
* @param gfp
|
|
|
3929 |
* global flags
|
|
|
3930 |
* @param buffer
|
|
|
3931 |
* header
|
|
|
3932 |
*/
|
|
|
3933 |
function setLameTagFrameHeader(gfp, buffer) {
|
|
|
3934 |
var gfc = gfp.internal_flags;
|
|
|
3935 |
|
|
|
3936 |
// MP3 Sync Word
|
|
|
3937 |
buffer[0] = shiftInBitsValue(buffer[0], 8, 0xff);
|
|
|
3938 |
|
|
|
3939 |
buffer[1] = shiftInBitsValue(buffer[1], 3, 7);
|
|
|
3940 |
buffer[1] = shiftInBitsValue(buffer[1], 1,
|
|
|
3941 |
(gfp.out_samplerate < 16000) ? 0 : 1);
|
|
|
3942 |
// Version
|
|
|
3943 |
buffer[1] = shiftInBitsValue(buffer[1], 1, gfp.version);
|
|
|
3944 |
// 01 == Layer 3
|
|
|
3945 |
buffer[1] = shiftInBitsValue(buffer[1], 2, 4 - 3);
|
|
|
3946 |
// Error protection
|
|
|
3947 |
buffer[1] = shiftInBitsValue(buffer[1], 1, (!gfp.error_protection) ? 1
|
|
|
3948 |
: 0);
|
|
|
3949 |
|
|
|
3950 |
// Bit rate
|
|
|
3951 |
buffer[2] = shiftInBitsValue(buffer[2], 4, gfc.bitrate_index);
|
|
|
3952 |
// Frequency
|
|
|
3953 |
buffer[2] = shiftInBitsValue(buffer[2], 2, gfc.samplerate_index);
|
|
|
3954 |
// Pad. Bit
|
|
|
3955 |
buffer[2] = shiftInBitsValue(buffer[2], 1, 0);
|
|
|
3956 |
// Priv. Bit
|
|
|
3957 |
buffer[2] = shiftInBitsValue(buffer[2], 1, gfp.extension);
|
|
|
3958 |
|
|
|
3959 |
// Mode
|
|
|
3960 |
buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.mode.ordinal());
|
|
|
3961 |
// Mode extension (Used with Joint Stereo)
|
|
|
3962 |
buffer[3] = shiftInBitsValue(buffer[3], 2, gfc.mode_ext);
|
|
|
3963 |
// Copy
|
|
|
3964 |
buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.copyright);
|
|
|
3965 |
// Original
|
|
|
3966 |
buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.original);
|
|
|
3967 |
// Emphasis
|
|
|
3968 |
buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.emphasis);
|
|
|
3969 |
|
|
|
3970 |
/* the default VBR header. 48 kbps layer III, no padding, no crc */
|
|
|
3971 |
/* but sampling freq, mode and copyright/copy protection taken */
|
|
|
3972 |
/* from first valid frame */
|
|
|
3973 |
buffer[0] = 0xff;
|
|
|
3974 |
var abyte = 0xff & (buffer[1] & 0xf1);
|
|
|
3975 |
var bitrate;
|
|
|
3976 |
if (1 == gfp.version) {
|
|
|
3977 |
bitrate = XING_BITRATE1;
|
|
|
3978 |
} else {
|
|
|
3979 |
if (gfp.out_samplerate < 16000)
|
|
|
3980 |
bitrate = XING_BITRATE25;
|
|
|
3981 |
else
|
|
|
3982 |
bitrate = XING_BITRATE2;
|
|
|
3983 |
}
|
|
|
3984 |
|
|
|
3985 |
if (gfp.VBR == VbrMode.vbr_off)
|
|
|
3986 |
bitrate = gfp.brate;
|
|
|
3987 |
|
|
|
3988 |
var bbyte;
|
|
|
3989 |
if (gfp.free_format)
|
|
|
3990 |
bbyte = 0x00;
|
|
|
3991 |
else
|
|
|
3992 |
bbyte = 0xff & (16 * lame.BitrateIndex(bitrate, gfp.version,
|
|
|
3993 |
gfp.out_samplerate));
|
|
|
3994 |
|
|
|
3995 |
/*
|
|
|
3996 |
* Use as much of the info from the real frames in the Xing header:
|
|
|
3997 |
* samplerate, channels, crc, etc...
|
|
|
3998 |
*/
|
|
|
3999 |
if (gfp.version == 1) {
|
|
|
4000 |
/* MPEG1 */
|
|
|
4001 |
buffer[1] = 0xff & (abyte | 0x0a);
|
|
|
4002 |
/* was 0x0b; */
|
|
|
4003 |
abyte = 0xff & (buffer[2] & 0x0d);
|
|
|
4004 |
/* AF keep also private bit */
|
|
|
4005 |
buffer[2] = 0xff & (bbyte | abyte);
|
|
|
4006 |
/* 64kbs MPEG1 frame */
|
|
|
4007 |
} else {
|
|
|
4008 |
/* MPEG2 */
|
|
|
4009 |
buffer[1] = 0xff & (abyte | 0x02);
|
|
|
4010 |
/* was 0x03; */
|
|
|
4011 |
abyte = 0xff & (buffer[2] & 0x0d);
|
|
|
4012 |
/* AF keep also private bit */
|
|
|
4013 |
buffer[2] = 0xff & (bbyte | abyte);
|
|
|
4014 |
/* 64kbs MPEG2 frame */
|
|
|
4015 |
}
|
|
|
4016 |
}
|
|
|
4017 |
|
|
|
4018 |
/**
|
|
|
4019 |
* Get VBR tag information
|
|
|
4020 |
*
|
|
|
4021 |
* @param buf
|
|
|
4022 |
* header to analyze
|
|
|
4023 |
* @param bufPos
|
|
|
4024 |
* offset into the header
|
|
|
4025 |
* @return VBR tag data
|
|
|
4026 |
*/
|
|
|
4027 |
this.getVbrTag = function (buf) {
|
|
|
4028 |
var pTagData = new VBRTagData();
|
|
|
4029 |
var bufPos = 0;
|
|
|
4030 |
|
|
|
4031 |
/* get Vbr header data */
|
|
|
4032 |
pTagData.flags = 0;
|
|
|
4033 |
|
|
|
4034 |
/* get selected MPEG header data */
|
|
|
4035 |
var hId = (buf[bufPos + 1] >> 3) & 1;
|
|
|
4036 |
var hSrIndex = (buf[bufPos + 2] >> 2) & 3;
|
|
|
4037 |
var hMode = (buf[bufPos + 3] >> 6) & 3;
|
|
|
4038 |
var hBitrate = ((buf[bufPos + 2] >> 4) & 0xf);
|
|
|
4039 |
hBitrate = Tables.bitrate_table[hId][hBitrate];
|
|
|
4040 |
|
|
|
4041 |
/* check for FFE syncword */
|
|
|
4042 |
if ((buf[bufPos + 1] >> 4) == 0xE)
|
|
|
4043 |
pTagData.samprate = Tables.samplerate_table[2][hSrIndex];
|
|
|
4044 |
else
|
|
|
4045 |
pTagData.samprate = Tables.samplerate_table[hId][hSrIndex];
|
|
|
4046 |
|
|
|
4047 |
/* determine offset of header */
|
|
|
4048 |
if (hId != 0) {
|
|
|
4049 |
/* mpeg1 */
|
|
|
4050 |
if (hMode != 3)
|
|
|
4051 |
bufPos += (32 + 4);
|
|
|
4052 |
else
|
|
|
4053 |
bufPos += (17 + 4);
|
|
|
4054 |
} else {
|
|
|
4055 |
/* mpeg2 */
|
|
|
4056 |
if (hMode != 3)
|
|
|
4057 |
bufPos += (17 + 4);
|
|
|
4058 |
else
|
|
|
4059 |
bufPos += (9 + 4);
|
|
|
4060 |
}
|
|
|
4061 |
|
|
|
4062 |
if (!isVbrTag(buf, bufPos))
|
|
|
4063 |
return null;
|
|
|
4064 |
|
|
|
4065 |
bufPos += 4;
|
|
|
4066 |
|
|
|
4067 |
pTagData.hId = hId;
|
|
|
4068 |
|
|
|
4069 |
/* get flags */
|
|
|
4070 |
var head_flags = pTagData.flags = extractInteger(buf, bufPos);
|
|
|
4071 |
bufPos += 4;
|
|
|
4072 |
|
|
|
4073 |
if ((head_flags & FRAMES_FLAG) != 0) {
|
|
|
4074 |
pTagData.frames = extractInteger(buf, bufPos);
|
|
|
4075 |
bufPos += 4;
|
|
|
4076 |
}
|
|
|
4077 |
|
|
|
4078 |
if ((head_flags & BYTES_FLAG) != 0) {
|
|
|
4079 |
pTagData.bytes = extractInteger(buf, bufPos);
|
|
|
4080 |
bufPos += 4;
|
|
|
4081 |
}
|
|
|
4082 |
|
|
|
4083 |
if ((head_flags & TOC_FLAG) != 0) {
|
|
|
4084 |
if (pTagData.toc != null) {
|
|
|
4085 |
for (var i = 0; i < NUMTOCENTRIES; i++)
|
|
|
4086 |
pTagData.toc[i] = buf[bufPos + i];
|
|
|
4087 |
}
|
|
|
4088 |
bufPos += NUMTOCENTRIES;
|
|
|
4089 |
}
|
|
|
4090 |
|
|
|
4091 |
pTagData.vbrScale = -1;
|
|
|
4092 |
|
|
|
4093 |
if ((head_flags & VBR_SCALE_FLAG) != 0) {
|
|
|
4094 |
pTagData.vbrScale = extractInteger(buf, bufPos);
|
|
|
4095 |
bufPos += 4;
|
|
|
4096 |
}
|
|
|
4097 |
|
|
|
4098 |
pTagData.headersize = ((hId + 1) * 72000 * hBitrate)
|
|
|
4099 |
/ pTagData.samprate;
|
|
|
4100 |
|
|
|
4101 |
bufPos += 21;
|
|
|
4102 |
var encDelay = buf[bufPos + 0] << 4;
|
|
|
4103 |
encDelay += buf[bufPos + 1] >> 4;
|
|
|
4104 |
var encPadding = (buf[bufPos + 1] & 0x0F) << 8;
|
|
|
4105 |
encPadding += buf[bufPos + 2] & 0xff;
|
|
|
4106 |
/* check for reasonable values (this may be an old Xing header, */
|
|
|
4107 |
/* not a INFO tag) */
|
|
|
4108 |
if (encDelay < 0 || encDelay > 3000)
|
|
|
4109 |
encDelay = -1;
|
|
|
4110 |
if (encPadding < 0 || encPadding > 3000)
|
|
|
4111 |
encPadding = -1;
|
|
|
4112 |
|
|
|
4113 |
pTagData.encDelay = encDelay;
|
|
|
4114 |
pTagData.encPadding = encPadding;
|
|
|
4115 |
|
|
|
4116 |
/* success */
|
|
|
4117 |
return pTagData;
|
|
|
4118 |
}
|
|
|
4119 |
|
|
|
4120 |
/**
|
|
|
4121 |
* Initializes the header
|
|
|
4122 |
*
|
|
|
4123 |
* @param gfp
|
|
|
4124 |
* global flags
|
|
|
4125 |
*/
|
|
|
4126 |
this.InitVbrTag = function (gfp) {
|
|
|
4127 |
var gfc = gfp.internal_flags;
|
|
|
4128 |
|
|
|
4129 |
/**
|
|
|
4130 |
* <PRE>
|
|
|
4131 |
* Xing VBR pretends to be a 48kbs layer III frame. (at 44.1kHz).
|
|
|
4132 |
* (at 48kHz they use 56kbs since 48kbs frame not big enough for
|
|
|
4133 |
* table of contents)
|
|
|
4134 |
* let's always embed Xing header inside a 64kbs layer III frame.
|
|
|
4135 |
* this gives us enough room for a LAME version string too.
|
|
|
4136 |
* size determined by sampling frequency (MPEG1)
|
|
|
4137 |
* 32kHz: 216 bytes@48kbs 288bytes@ 64kbs
|
|
|
4138 |
* 44.1kHz: 156 bytes 208bytes@64kbs (+1 if padding = 1)
|
|
|
4139 |
* 48kHz: 144 bytes 192
|
|
|
4140 |
*
|
|
|
4141 |
* MPEG 2 values are the same since the framesize and samplerate
|
|
|
4142 |
* are each reduced by a factor of 2.
|
|
|
4143 |
* </PRE>
|
|
|
4144 |
*/
|
|
|
4145 |
var kbps_header;
|
|
|
4146 |
if (1 == gfp.version) {
|
|
|
4147 |
kbps_header = XING_BITRATE1;
|
|
|
4148 |
} else {
|
|
|
4149 |
if (gfp.out_samplerate < 16000)
|
|
|
4150 |
kbps_header = XING_BITRATE25;
|
|
|
4151 |
else
|
|
|
4152 |
kbps_header = XING_BITRATE2;
|
|
|
4153 |
}
|
|
|
4154 |
|
|
|
4155 |
if (gfp.VBR == VbrMode.vbr_off)
|
|
|
4156 |
kbps_header = gfp.brate;
|
|
|
4157 |
|
|
|
4158 |
// make sure LAME Header fits into Frame
|
|
|
4159 |
var totalFrameSize = ((gfp.version + 1) * 72000 * kbps_header)
|
|
|
4160 |
/ gfp.out_samplerate;
|
|
|
4161 |
var headerSize = (gfc.sideinfo_len + LAMEHEADERSIZE);
|
|
|
4162 |
gfc.VBR_seek_table.TotalFrameSize = totalFrameSize;
|
|
|
4163 |
if (totalFrameSize < headerSize || totalFrameSize > MAXFRAMESIZE) {
|
|
|
4164 |
/* disable tag, it wont fit */
|
|
|
4165 |
gfp.bWriteVbrTag = false;
|
|
|
4166 |
return;
|
|
|
4167 |
}
|
|
|
4168 |
|
|
|
4169 |
gfc.VBR_seek_table.nVbrNumFrames = 0;
|
|
|
4170 |
gfc.VBR_seek_table.nBytesWritten = 0;
|
|
|
4171 |
gfc.VBR_seek_table.sum = 0;
|
|
|
4172 |
|
|
|
4173 |
gfc.VBR_seek_table.seen = 0;
|
|
|
4174 |
gfc.VBR_seek_table.want = 1;
|
|
|
4175 |
gfc.VBR_seek_table.pos = 0;
|
|
|
4176 |
|
|
|
4177 |
if (gfc.VBR_seek_table.bag == null) {
|
|
|
4178 |
gfc.VBR_seek_table.bag = new int[400];
|
|
|
4179 |
gfc.VBR_seek_table.size = 400;
|
|
|
4180 |
}
|
|
|
4181 |
|
|
|
4182 |
// write dummy VBR tag of all 0's into bitstream
|
|
|
4183 |
var buffer = new_byte(MAXFRAMESIZE);
|
|
|
4184 |
|
|
|
4185 |
setLameTagFrameHeader(gfp, buffer);
|
|
|
4186 |
var n = gfc.VBR_seek_table.TotalFrameSize;
|
|
|
4187 |
for (var i = 0; i < n; ++i) {
|
|
|
4188 |
bs.add_dummy_byte(gfp, buffer[i] & 0xff, 1);
|
|
|
4189 |
}
|
|
|
4190 |
}
|
|
|
4191 |
|
|
|
4192 |
/**
|
|
|
4193 |
* Fast CRC-16 computation (uses table crc16Lookup).
|
|
|
4194 |
*
|
|
|
4195 |
* @param value
|
|
|
4196 |
* @param crc
|
|
|
4197 |
* @return
|
|
|
4198 |
*/
|
|
|
4199 |
function crcUpdateLookup(value, crc) {
|
|
|
4200 |
var tmp = crc ^ value;
|
|
|
4201 |
crc = (crc >> 8) ^ crc16Lookup[tmp & 0xff];
|
|
|
4202 |
return crc;
|
|
|
4203 |
}
|
|
|
4204 |
|
|
|
4205 |
this.updateMusicCRC = function (crc, buffer, bufferPos, size) {
|
|
|
4206 |
for (var i = 0; i < size; ++i)
|
|
|
4207 |
crc[0] = crcUpdateLookup(buffer[bufferPos + i], crc[0]);
|
|
|
4208 |
}
|
|
|
4209 |
|
|
|
4210 |
/**
|
|
|
4211 |
* Write LAME info: mini version + info on various switches used (Jonathan
|
|
|
4212 |
* Dee 2001/08/31).
|
|
|
4213 |
*
|
|
|
4214 |
* @param gfp
|
|
|
4215 |
* global flags
|
|
|
4216 |
* @param musicLength
|
|
|
4217 |
* music length
|
|
|
4218 |
* @param streamBuffer
|
|
|
4219 |
* pointer to output buffer
|
|
|
4220 |
* @param streamBufferPos
|
|
|
4221 |
* offset into the output buffer
|
|
|
4222 |
* @param crc
|
|
|
4223 |
* computation of CRC-16 of Lame Tag so far (starting at frame
|
|
|
4224 |
* sync)
|
|
|
4225 |
* @return number of bytes written to the stream
|
|
|
4226 |
*/
|
|
|
4227 |
function putLameVBR(gfp, musicLength, streamBuffer, streamBufferPos, crc) {
|
|
|
4228 |
var gfc = gfp.internal_flags;
|
|
|
4229 |
var bytesWritten = 0;
|
|
|
4230 |
|
|
|
4231 |
/* encoder delay */
|
|
|
4232 |
var encDelay = gfp.encoder_delay;
|
|
|
4233 |
/* encoder padding */
|
|
|
4234 |
var encPadding = gfp.encoder_padding;
|
|
|
4235 |
|
|
|
4236 |
/* recall: gfp.VBR_q is for example set by the switch -V */
|
|
|
4237 |
/* gfp.quality by -q, -h, -f, etc */
|
|
|
4238 |
var quality = (100 - 10 * gfp.VBR_q - gfp.quality);
|
|
|
4239 |
|
|
|
4240 |
var version = v.getLameVeryShortVersion();
|
|
|
4241 |
var vbr;
|
|
|
4242 |
var revision = 0x00;
|
|
|
4243 |
var revMethod;
|
|
|
4244 |
// numbering different in vbr_mode vs. Lame tag
|
|
|
4245 |
var vbrTypeTranslator = [1, 5, 3, 2, 4, 0, 3];
|
|
|
4246 |
var lowpass = 0 | (((gfp.lowpassfreq / 100.0) + .5) > 255 ? 255
|
|
|
4247 |
: (gfp.lowpassfreq / 100.0) + .5);
|
|
|
4248 |
var peakSignalAmplitude = 0;
|
|
|
4249 |
var radioReplayGain = 0;
|
|
|
4250 |
var audiophileReplayGain = 0;
|
|
|
4251 |
var noiseShaping = gfp.internal_flags.noise_shaping;
|
|
|
4252 |
var stereoMode = 0;
|
|
|
4253 |
var nonOptimal = 0;
|
|
|
4254 |
var sourceFreq = 0;
|
|
|
4255 |
var misc = 0;
|
|
|
4256 |
var musicCRC = 0;
|
|
|
4257 |
|
|
|
4258 |
// psy model type: Gpsycho or NsPsytune
|
|
|
4259 |
var expNPsyTune = (gfp.exp_nspsytune & 1) != 0;
|
|
|
4260 |
var safeJoint = (gfp.exp_nspsytune & 2) != 0;
|
|
|
4261 |
var noGapMore = false;
|
|
|
4262 |
var noGapPrevious = false;
|
|
|
4263 |
var noGapCount = gfp.internal_flags.nogap_total;
|
|
|
4264 |
var noGapCurr = gfp.internal_flags.nogap_current;
|
|
|
4265 |
|
|
|
4266 |
// 4 bits
|
|
|
4267 |
var athType = gfp.ATHtype;
|
|
|
4268 |
var flags = 0;
|
|
|
4269 |
|
|
|
4270 |
// vbr modes
|
|
|
4271 |
var abrBitrate;
|
|
|
4272 |
switch (gfp.VBR) {
|
|
|
4273 |
case vbr_abr:
|
|
|
4274 |
abrBitrate = gfp.VBR_mean_bitrate_kbps;
|
|
|
4275 |
break;
|
|
|
4276 |
case vbr_off:
|
|
|
4277 |
abrBitrate = gfp.brate;
|
|
|
4278 |
break;
|
|
|
4279 |
default:
|
|
|
4280 |
abrBitrate = gfp.VBR_min_bitrate_kbps;
|
|
|
4281 |
}
|
|
|
4282 |
|
|
|
4283 |
// revision and vbr method
|
|
|
4284 |
if (gfp.VBR.ordinal() < vbrTypeTranslator.length)
|
|
|
4285 |
vbr = vbrTypeTranslator[gfp.VBR.ordinal()];
|
|
|
4286 |
else
|
|
|
4287 |
vbr = 0x00; // unknown
|
|
|
4288 |
|
|
|
4289 |
revMethod = 0x10 * revision + vbr;
|
|
|
4290 |
|
|
|
4291 |
// ReplayGain
|
|
|
4292 |
if (gfc.findReplayGain) {
|
|
|
4293 |
if (gfc.RadioGain > 0x1FE)
|
|
|
4294 |
gfc.RadioGain = 0x1FE;
|
|
|
4295 |
if (gfc.RadioGain < -0x1FE)
|
|
|
4296 |
gfc.RadioGain = -0x1FE;
|
|
|
4297 |
|
|
|
4298 |
// set name code
|
|
|
4299 |
radioReplayGain = 0x2000;
|
|
|
4300 |
// set originator code to `determined automatically'
|
|
|
4301 |
radioReplayGain |= 0xC00;
|
|
|
4302 |
|
|
|
4303 |
if (gfc.RadioGain >= 0) {
|
|
|
4304 |
// set gain adjustment
|
|
|
4305 |
radioReplayGain |= gfc.RadioGain;
|
|
|
4306 |
} else {
|
|
|
4307 |
// set the sign bit
|
|
|
4308 |
radioReplayGain |= 0x200;
|
|
|
4309 |
// set gain adjustment
|
|
|
4310 |
radioReplayGain |= -gfc.RadioGain;
|
|
|
4311 |
}
|
|
|
4312 |
}
|
|
|
4313 |
|
|
|
4314 |
// peak sample
|
|
|
4315 |
if (gfc.findPeakSample)
|
|
|
4316 |
peakSignalAmplitude = Math
|
|
|
4317 |
.abs(0 | ((( gfc.PeakSample) / 32767.0) * Math.pow(2, 23) + .5));
|
|
|
4318 |
|
|
|
4319 |
// nogap
|
|
|
4320 |
if (noGapCount != -1) {
|
|
|
4321 |
if (noGapCurr > 0)
|
|
|
4322 |
noGapPrevious = true;
|
|
|
4323 |
|
|
|
4324 |
if (noGapCurr < noGapCount - 1)
|
|
|
4325 |
noGapMore = true;
|
|
|
4326 |
}
|
|
|
4327 |
|
|
|
4328 |
// flags
|
|
|
4329 |
flags = athType + ((expNPsyTune ? 1 : 0) << 4)
|
|
|
4330 |
+ ((safeJoint ? 1 : 0) << 5) + ((noGapMore ? 1 : 0) << 6)
|
|
|
4331 |
+ ((noGapPrevious ? 1 : 0) << 7);
|
|
|
4332 |
|
|
|
4333 |
if (quality < 0)
|
|
|
4334 |
quality = 0;
|
|
|
4335 |
|
|
|
4336 |
// stereo mode field (Intensity stereo is not implemented)
|
|
|
4337 |
switch (gfp.mode) {
|
|
|
4338 |
case MONO:
|
|
|
4339 |
stereoMode = 0;
|
|
|
4340 |
break;
|
|
|
4341 |
case STEREO:
|
|
|
4342 |
stereoMode = 1;
|
|
|
4343 |
break;
|
|
|
4344 |
case DUAL_CHANNEL:
|
|
|
4345 |
stereoMode = 2;
|
|
|
4346 |
break;
|
|
|
4347 |
case JOINT_STEREO:
|
|
|
4348 |
if (gfp.force_ms)
|
|
|
4349 |
stereoMode = 4;
|
|
|
4350 |
else
|
|
|
4351 |
stereoMode = 3;
|
|
|
4352 |
break;
|
|
|
4353 |
case NOT_SET:
|
|
|
4354 |
//$FALL-THROUGH$
|
|
|
4355 |
default:
|
|
|
4356 |
stereoMode = 7;
|
|
|
4357 |
break;
|
|
|
4358 |
}
|
|
|
4359 |
|
|
|
4360 |
if (gfp.in_samplerate <= 32000)
|
|
|
4361 |
sourceFreq = 0x00;
|
|
|
4362 |
else if (gfp.in_samplerate == 48000)
|
|
|
4363 |
sourceFreq = 0x02;
|
|
|
4364 |
else if (gfp.in_samplerate > 48000)
|
|
|
4365 |
sourceFreq = 0x03;
|
|
|
4366 |
else {
|
|
|
4367 |
// default is 44100Hz
|
|
|
4368 |
sourceFreq = 0x01;
|
|
|
4369 |
}
|
|
|
4370 |
|
|
|
4371 |
// Check if the user overrided the default LAME behavior with some
|
|
|
4372 |
// nasty options
|
|
|
4373 |
if (gfp.short_blocks == ShortBlock.short_block_forced
|
|
|
4374 |
|| gfp.short_blocks == ShortBlock.short_block_dispensed
|
|
|
4375 |
|| ((gfp.lowpassfreq == -1) && (gfp.highpassfreq == -1)) || /* "-k" */
|
|
|
4376 |
(gfp.scale_left < gfp.scale_right)
|
|
|
4377 |
|| (gfp.scale_left > gfp.scale_right)
|
|
|
4378 |
|| (gfp.disable_reservoir && gfp.brate < 320) || gfp.noATH
|
|
|
4379 |
|| gfp.ATHonly || (athType == 0) || gfp.in_samplerate <= 32000)
|
|
|
4380 |
nonOptimal = 1;
|
|
|
4381 |
|
|
|
4382 |
misc = noiseShaping + (stereoMode << 2) + (nonOptimal << 5)
|
|
|
4383 |
+ (sourceFreq << 6);
|
|
|
4384 |
|
|
|
4385 |
musicCRC = gfc.nMusicCRC;
|
|
|
4386 |
|
|
|
4387 |
// Write all this information into the stream
|
|
|
4388 |
|
|
|
4389 |
createInteger(streamBuffer, streamBufferPos + bytesWritten, quality);
|
|
|
4390 |
bytesWritten += 4;
|
|
|
4391 |
|
|
|
4392 |
for (var j = 0; j < 9; j++) {
|
|
|
4393 |
streamBuffer[streamBufferPos + bytesWritten + j] = 0xff & version .charAt(j);
|
|
|
4394 |
}
|
|
|
4395 |
bytesWritten += 9;
|
|
|
4396 |
|
|
|
4397 |
streamBuffer[streamBufferPos + bytesWritten] = 0xff & revMethod;
|
|
|
4398 |
bytesWritten++;
|
|
|
4399 |
|
|
|
4400 |
streamBuffer[streamBufferPos + bytesWritten] = 0xff & lowpass;
|
|
|
4401 |
bytesWritten++;
|
|
|
4402 |
|
|
|
4403 |
createInteger(streamBuffer, streamBufferPos + bytesWritten,
|
|
|
4404 |
peakSignalAmplitude);
|
|
|
4405 |
bytesWritten += 4;
|
|
|
4406 |
|
|
|
4407 |
createShort(streamBuffer, streamBufferPos + bytesWritten,
|
|
|
4408 |
radioReplayGain);
|
|
|
4409 |
bytesWritten += 2;
|
|
|
4410 |
|
|
|
4411 |
createShort(streamBuffer, streamBufferPos + bytesWritten,
|
|
|
4412 |
audiophileReplayGain);
|
|
|
4413 |
bytesWritten += 2;
|
|
|
4414 |
|
|
|
4415 |
streamBuffer[streamBufferPos + bytesWritten] = 0xff & flags;
|
|
|
4416 |
bytesWritten++;
|
|
|
4417 |
|
|
|
4418 |
if (abrBitrate >= 255)
|
|
|
4419 |
streamBuffer[streamBufferPos + bytesWritten] = 0xFF;
|
|
|
4420 |
else
|
|
|
4421 |
streamBuffer[streamBufferPos + bytesWritten] = 0xff & abrBitrate;
|
|
|
4422 |
bytesWritten++;
|
|
|
4423 |
|
|
|
4424 |
streamBuffer[streamBufferPos + bytesWritten] = 0xff & (encDelay >> 4);
|
|
|
4425 |
streamBuffer[streamBufferPos + bytesWritten + 1] = 0xff & ((encDelay << 4) + (encPadding >> 8));
|
|
|
4426 |
streamBuffer[streamBufferPos + bytesWritten + 2] = 0xff & encPadding;
|
|
|
4427 |
|
|
|
4428 |
bytesWritten += 3;
|
|
|
4429 |
|
|
|
4430 |
streamBuffer[streamBufferPos + bytesWritten] = 0xff & misc;
|
|
|
4431 |
bytesWritten++;
|
|
|
4432 |
|
|
|
4433 |
// unused in rev0
|
|
|
4434 |
streamBuffer[streamBufferPos + bytesWritten++] = 0;
|
|
|
4435 |
|
|
|
4436 |
createShort(streamBuffer, streamBufferPos + bytesWritten, gfp.preset);
|
|
|
4437 |
bytesWritten += 2;
|
|
|
4438 |
|
|
|
4439 |
createInteger(streamBuffer, streamBufferPos + bytesWritten, musicLength);
|
|
|
4440 |
bytesWritten += 4;
|
|
|
4441 |
|
|
|
4442 |
createShort(streamBuffer, streamBufferPos + bytesWritten, musicCRC);
|
|
|
4443 |
bytesWritten += 2;
|
|
|
4444 |
|
|
|
4445 |
// Calculate tag CRC.... must be done here, since it includes previous
|
|
|
4446 |
// information
|
|
|
4447 |
|
|
|
4448 |
for (var i = 0; i < bytesWritten; i++)
|
|
|
4449 |
crc = crcUpdateLookup(streamBuffer[streamBufferPos + i], crc);
|
|
|
4450 |
|
|
|
4451 |
createShort(streamBuffer, streamBufferPos + bytesWritten, crc);
|
|
|
4452 |
bytesWritten += 2;
|
|
|
4453 |
|
|
|
4454 |
return bytesWritten;
|
|
|
4455 |
}
|
|
|
4456 |
|
|
|
4457 |
function skipId3v2(fpStream) {
|
|
|
4458 |
// seek to the beginning of the stream
|
|
|
4459 |
fpStream.seek(0);
|
|
|
4460 |
// read 10 bytes in case there's an ID3 version 2 header here
|
|
|
4461 |
var id3v2Header = new_byte(10);
|
|
|
4462 |
fpStream.readFully(id3v2Header);
|
|
|
4463 |
/* does the stream begin with the ID3 version 2 file identifier? */
|
|
|
4464 |
var id3v2TagSize;
|
|
|
4465 |
if (!new String(id3v2Header, "ISO-8859-1").startsWith("ID3")) {
|
|
|
4466 |
/*
|
|
|
4467 |
* the tag size (minus the 10-byte header) is encoded into four
|
|
|
4468 |
* bytes where the most significant bit is clear in each byte
|
|
|
4469 |
*/
|
|
|
4470 |
id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21)
|
|
|
4471 |
| ((id3v2Header[7] & 0x7f) << 14)
|
|
|
4472 |
| ((id3v2Header[8] & 0x7f) << 7) | (id3v2Header[9] & 0x7f))
|
|
|
4473 |
+ id3v2Header.length;
|
|
|
4474 |
} else {
|
|
|
4475 |
/* no ID3 version 2 tag in this stream */
|
|
|
4476 |
id3v2TagSize = 0;
|
|
|
4477 |
}
|
|
|
4478 |
return id3v2TagSize;
|
|
|
4479 |
}
|
|
|
4480 |
|
|
|
4481 |
this.getLameTagFrame = function (gfp, buffer) {
|
|
|
4482 |
var gfc = gfp.internal_flags;
|
|
|
4483 |
|
|
|
4484 |
if (!gfp.bWriteVbrTag) {
|
|
|
4485 |
return 0;
|
|
|
4486 |
}
|
|
|
4487 |
if (gfc.Class_ID != Lame.LAME_ID) {
|
|
|
4488 |
return 0;
|
|
|
4489 |
}
|
|
|
4490 |
if (gfc.VBR_seek_table.pos <= 0) {
|
|
|
4491 |
return 0;
|
|
|
4492 |
}
|
|
|
4493 |
if (buffer.length < gfc.VBR_seek_table.TotalFrameSize) {
|
|
|
4494 |
return gfc.VBR_seek_table.TotalFrameSize;
|
|
|
4495 |
}
|
|
|
4496 |
|
|
|
4497 |
Arrays.fill(buffer, 0, gfc.VBR_seek_table.TotalFrameSize, 0);
|
|
|
4498 |
|
|
|
4499 |
// 4 bytes frame header
|
|
|
4500 |
setLameTagFrameHeader(gfp, buffer);
|
|
|
4501 |
|
|
|
4502 |
// Create TOC entries
|
|
|
4503 |
var toc = new_byte(NUMTOCENTRIES);
|
|
|
4504 |
|
|
|
4505 |
if (gfp.free_format) {
|
|
|
4506 |
for (var i = 1; i < NUMTOCENTRIES; ++i)
|
|
|
4507 |
toc[i] = 0xff & (255 * i / 100);
|
|
|
4508 |
} else {
|
|
|
4509 |
xingSeekTable(gfc.VBR_seek_table, toc);
|
|
|
4510 |
}
|
|
|
4511 |
|
|
|
4512 |
// Start writing the tag after the zero frame
|
|
|
4513 |
var streamIndex = gfc.sideinfo_len;
|
|
|
4514 |
/**
|
|
|
4515 |
* Note: Xing header specifies that Xing data goes in the ancillary data
|
|
|
4516 |
* with NO ERROR PROTECTION. If error protecton in enabled, the Xing
|
|
|
4517 |
* data still starts at the same offset, and now it is in sideinfo data
|
|
|
4518 |
* block, and thus will not decode correctly by non-Xing tag aware
|
|
|
4519 |
* players
|
|
|
4520 |
*/
|
|
|
4521 |
if (gfp.error_protection)
|
|
|
4522 |
streamIndex -= 2;
|
|
|
4523 |
|
|
|
4524 |
// Put Vbr tag
|
|
|
4525 |
if (gfp.VBR == VbrMode.vbr_off) {
|
|
|
4526 |
buffer[streamIndex++] = 0xff & VBRTag1.charAt(0);
|
|
|
4527 |
buffer[streamIndex++] = 0xff & VBRTag1.charAt(1);
|
|
|
4528 |
buffer[streamIndex++] = 0xff & VBRTag1.charAt(2);
|
|
|
4529 |
buffer[streamIndex++] = 0xff & VBRTag1.charAt(3);
|
|
|
4530 |
|
|
|
4531 |
} else {
|
|
|
4532 |
buffer[streamIndex++] = 0xff & VBRTag0.charAt(0);
|
|
|
4533 |
buffer[streamIndex++] = 0xff & VBRTag0.charAt(1);
|
|
|
4534 |
buffer[streamIndex++] = 0xff & VBRTag0.charAt(2);
|
|
|
4535 |
buffer[streamIndex++] = 0xff & VBRTag0.charAt(3);
|
|
|
4536 |
}
|
|
|
4537 |
|
|
|
4538 |
// Put header flags
|
|
|
4539 |
createInteger(buffer, streamIndex, FRAMES_FLAG + BYTES_FLAG + TOC_FLAG
|
|
|
4540 |
+ VBR_SCALE_FLAG);
|
|
|
4541 |
streamIndex += 4;
|
|
|
4542 |
|
|
|
4543 |
// Put Total Number of frames
|
|
|
4544 |
createInteger(buffer, streamIndex, gfc.VBR_seek_table.nVbrNumFrames);
|
|
|
4545 |
streamIndex += 4;
|
|
|
4546 |
|
|
|
4547 |
// Put total audio stream size, including Xing/LAME Header
|
|
|
4548 |
var streamSize = (gfc.VBR_seek_table.nBytesWritten + gfc.VBR_seek_table.TotalFrameSize);
|
|
|
4549 |
createInteger(buffer, streamIndex, 0 | streamSize);
|
|
|
4550 |
streamIndex += 4;
|
|
|
4551 |
|
|
|
4552 |
/* Put TOC */
|
|
|
4553 |
System.arraycopy(toc, 0, buffer, streamIndex, toc.length);
|
|
|
4554 |
streamIndex += toc.length;
|
|
|
4555 |
|
|
|
4556 |
if (gfp.error_protection) {
|
|
|
4557 |
// (jo) error_protection: add crc16 information to header
|
|
|
4558 |
bs.CRC_writeheader(gfc, buffer);
|
|
|
4559 |
}
|
|
|
4560 |
|
|
|
4561 |
// work out CRC so far: initially crc = 0
|
|
|
4562 |
var crc = 0x00;
|
|
|
4563 |
for (var i = 0; i < streamIndex; i++)
|
|
|
4564 |
crc = crcUpdateLookup(buffer[i], crc);
|
|
|
4565 |
// Put LAME VBR info
|
|
|
4566 |
streamIndex += putLameVBR(gfp, streamSize, buffer, streamIndex, crc);
|
|
|
4567 |
|
|
|
4568 |
return gfc.VBR_seek_table.TotalFrameSize;
|
|
|
4569 |
}
|
|
|
4570 |
|
|
|
4571 |
/**
|
|
|
4572 |
* Write final VBR tag to the file.
|
|
|
4573 |
*
|
|
|
4574 |
* @param gfp
|
|
|
4575 |
* global flags
|
|
|
4576 |
* @param stream
|
|
|
4577 |
* stream to add the VBR tag to
|
|
|
4578 |
* @return 0 (OK), -1 else
|
|
|
4579 |
* @throws IOException
|
|
|
4580 |
* I/O error
|
|
|
4581 |
*/
|
|
|
4582 |
this.putVbrTag = function (gfp, stream) {
|
|
|
4583 |
var gfc = gfp.internal_flags;
|
|
|
4584 |
|
|
|
4585 |
if (gfc.VBR_seek_table.pos <= 0)
|
|
|
4586 |
return -1;
|
|
|
4587 |
|
|
|
4588 |
// Seek to end of file
|
|
|
4589 |
stream.seek(stream.length());
|
|
|
4590 |
|
|
|
4591 |
// Get file size, abort if file has zero length.
|
|
|
4592 |
if (stream.length() == 0)
|
|
|
4593 |
return -1;
|
|
|
4594 |
|
|
|
4595 |
// The VBR tag may NOT be located at the beginning of the stream. If an
|
|
|
4596 |
// ID3 version 2 tag was added, then it must be skipped to write the VBR
|
|
|
4597 |
// tag data.
|
|
|
4598 |
var id3v2TagSize = skipId3v2(stream);
|
|
|
4599 |
|
|
|
4600 |
// Seek to the beginning of the stream
|
|
|
4601 |
stream.seek(id3v2TagSize);
|
|
|
4602 |
|
|
|
4603 |
var buffer = new_byte(MAXFRAMESIZE);
|
|
|
4604 |
var bytes = getLameTagFrame(gfp, buffer);
|
|
|
4605 |
if (bytes > buffer.length) {
|
|
|
4606 |
return -1;
|
|
|
4607 |
}
|
|
|
4608 |
|
|
|
4609 |
if (bytes < 1) {
|
|
|
4610 |
return 0;
|
|
|
4611 |
}
|
|
|
4612 |
|
|
|
4613 |
// Put it all to disk again
|
|
|
4614 |
stream.write(buffer, 0, bytes);
|
|
|
4615 |
// success
|
|
|
4616 |
return 0;
|
|
|
4617 |
}
|
|
|
4618 |
|
|
|
4619 |
}
|
|
|
4620 |
|
|
|
4621 |
function HuffCodeTab(len, max, tab, hl) {
|
|
|
4622 |
this.xlen = len;
|
|
|
4623 |
this.linmax = max;
|
|
|
4624 |
this.table = tab;
|
|
|
4625 |
this.hlen = hl;
|
|
|
4626 |
}
|
|
|
4627 |
|
|
|
4628 |
var Tables = {};
|
|
|
4629 |
|
|
|
4630 |
|
|
|
4631 |
Tables.t1HB = [
|
|
|
4632 |
1, 1,
|
|
|
4633 |
1, 0
|
|
|
4634 |
];
|
|
|
4635 |
|
|
|
4636 |
Tables.t2HB = [
|
|
|
4637 |
1, 2, 1,
|
|
|
4638 |
3, 1, 1,
|
|
|
4639 |
3, 2, 0
|
|
|
4640 |
];
|
|
|
4641 |
|
|
|
4642 |
Tables.t3HB = [
|
|
|
4643 |
3, 2, 1,
|
|
|
4644 |
1, 1, 1,
|
|
|
4645 |
3, 2, 0
|
|
|
4646 |
];
|
|
|
4647 |
|
|
|
4648 |
Tables.t5HB = [
|
|
|
4649 |
1, 2, 6, 5,
|
|
|
4650 |
3, 1, 4, 4,
|
|
|
4651 |
7, 5, 7, 1,
|
|
|
4652 |
6, 1, 1, 0
|
|
|
4653 |
];
|
|
|
4654 |
|
|
|
4655 |
Tables.t6HB = [
|
|
|
4656 |
7, 3, 5, 1,
|
|
|
4657 |
6, 2, 3, 2,
|
|
|
4658 |
5, 4, 4, 1,
|
|
|
4659 |
3, 3, 2, 0
|
|
|
4660 |
];
|
|
|
4661 |
|
|
|
4662 |
Tables.t7HB = [
|
|
|
4663 |
1, 2, 10, 19, 16, 10,
|
|
|
4664 |
3, 3, 7, 10, 5, 3,
|
|
|
4665 |
11, 4, 13, 17, 8, 4,
|
|
|
4666 |
12, 11, 18, 15, 11, 2,
|
|
|
4667 |
7, 6, 9, 14, 3, 1,
|
|
|
4668 |
6, 4, 5, 3, 2, 0
|
|
|
4669 |
];
|
|
|
4670 |
|
|
|
4671 |
Tables.t8HB = [
|
|
|
4672 |
3, 4, 6, 18, 12, 5,
|
|
|
4673 |
5, 1, 2, 16, 9, 3,
|
|
|
4674 |
7, 3, 5, 14, 7, 3,
|
|
|
4675 |
19, 17, 15, 13, 10, 4,
|
|
|
4676 |
13, 5, 8, 11, 5, 1,
|
|
|
4677 |
12, 4, 4, 1, 1, 0
|
|
|
4678 |
];
|
|
|
4679 |
|
|
|
4680 |
Tables.t9HB = [
|
|
|
4681 |
7, 5, 9, 14, 15, 7,
|
|
|
4682 |
6, 4, 5, 5, 6, 7,
|
|
|
4683 |
7, 6, 8, 8, 8, 5,
|
|
|
4684 |
15, 6, 9, 10, 5, 1,
|
|
|
4685 |
11, 7, 9, 6, 4, 1,
|
|
|
4686 |
14, 4, 6, 2, 6, 0
|
|
|
4687 |
];
|
|
|
4688 |
|
|
|
4689 |
Tables.t10HB = [
|
|
|
4690 |
1, 2, 10, 23, 35, 30, 12, 17,
|
|
|
4691 |
3, 3, 8, 12, 18, 21, 12, 7,
|
|
|
4692 |
11, 9, 15, 21, 32, 40, 19, 6,
|
|
|
4693 |
14, 13, 22, 34, 46, 23, 18, 7,
|
|
|
4694 |
20, 19, 33, 47, 27, 22, 9, 3,
|
|
|
4695 |
31, 22, 41, 26, 21, 20, 5, 3,
|
|
|
4696 |
14, 13, 10, 11, 16, 6, 5, 1,
|
|
|
4697 |
9, 8, 7, 8, 4, 4, 2, 0
|
|
|
4698 |
];
|
|
|
4699 |
|
|
|
4700 |
Tables.t11HB = [
|
|
|
4701 |
3, 4, 10, 24, 34, 33, 21, 15,
|
|
|
4702 |
5, 3, 4, 10, 32, 17, 11, 10,
|
|
|
4703 |
11, 7, 13, 18, 30, 31, 20, 5,
|
|
|
4704 |
25, 11, 19, 59, 27, 18, 12, 5,
|
|
|
4705 |
35, 33, 31, 58, 30, 16, 7, 5,
|
|
|
4706 |
28, 26, 32, 19, 17, 15, 8, 14,
|
|
|
4707 |
14, 12, 9, 13, 14, 9, 4, 1,
|
|
|
4708 |
11, 4, 6, 6, 6, 3, 2, 0
|
|
|
4709 |
];
|
|
|
4710 |
|
|
|
4711 |
Tables.t12HB = [
|
|
|
4712 |
9, 6, 16, 33, 41, 39, 38, 26,
|
|
|
4713 |
7, 5, 6, 9, 23, 16, 26, 11,
|
|
|
4714 |
17, 7, 11, 14, 21, 30, 10, 7,
|
|
|
4715 |
17, 10, 15, 12, 18, 28, 14, 5,
|
|
|
4716 |
32, 13, 22, 19, 18, 16, 9, 5,
|
|
|
4717 |
40, 17, 31, 29, 17, 13, 4, 2,
|
|
|
4718 |
27, 12, 11, 15, 10, 7, 4, 1,
|
|
|
4719 |
27, 12, 8, 12, 6, 3, 1, 0
|
|
|
4720 |
];
|
|
|
4721 |
|
|
|
4722 |
Tables.t13HB = [
|
|
|
4723 |
1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19,
|
|
|
4724 |
3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14,
|
|
|
4725 |
15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16,
|
|
|
4726 |
22, 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14,
|
|
|
4727 |
35, 16, 60, 57, 97, 75, 114, 91, 54, 73, 55, 41, 48, 53, 23, 24,
|
|
|
4728 |
58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17,
|
|
|
4729 |
47, 45, 78, 74, 115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15,
|
|
|
4730 |
72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42,
|
|
|
4731 |
43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16,
|
|
|
4732 |
53, 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11,
|
|
|
4733 |
35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22,
|
|
|
4734 |
53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7,
|
|
|
4735 |
34, 32, 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5,
|
|
|
4736 |
45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3,
|
|
|
4737 |
48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2,
|
|
|
4738 |
16, 15, 17, 27, 25, 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1
|
|
|
4739 |
];
|
|
|
4740 |
|
|
|
4741 |
Tables.t15HB = [
|
|
|
4742 |
7, 12, 18, 53, 47, 76, 124, 108, 89, 123, 108, 119, 107, 81, 122, 63,
|
|
|
4743 |
13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36,
|
|
|
4744 |
19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, 33,
|
|
|
4745 |
29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29,
|
|
|
4746 |
52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27,
|
|
|
4747 |
77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38,
|
|
|
4748 |
125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30,
|
|
|
4749 |
109, 53, 49, 94, 88, 75, 66, 122, 91, 73, 56, 42, 64, 44, 21, 25,
|
|
|
4750 |
90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20,
|
|
|
4751 |
71, 34, 67, 60, 58, 49, 88, 76, 67, 106, 71, 54, 38, 39, 23, 15,
|
|
|
4752 |
109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9,
|
|
|
4753 |
86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11,
|
|
|
4754 |
118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7,
|
|
|
4755 |
91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3,
|
|
|
4756 |
123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1,
|
|
|
4757 |
71, 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0
|
|
|
4758 |
];
|
|
|
4759 |
|
|
|
4760 |
Tables.t16HB = [
|
|
|
4761 |
1, 5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17,
|
|
|
4762 |
3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68, 119, 201, 107, 207, 9,
|
|
|
4763 |
15, 13, 23, 38, 67, 58, 103, 90, 161, 72, 127, 117, 110, 209, 206, 16,
|
|
|
4764 |
45, 21, 39, 69, 64, 114, 99, 87, 158, 140, 252, 212, 199, 387, 365, 26,
|
|
|
4765 |
75, 36, 68, 65, 115, 101, 179, 164, 155, 264, 246, 226, 395, 382, 362, 9,
|
|
|
4766 |
66, 30, 59, 56, 102, 185, 173, 265, 142, 253, 232, 400, 388, 378, 445, 16,
|
|
|
4767 |
111, 54, 52, 100, 184, 178, 160, 133, 257, 244, 228, 217, 385, 366, 715, 10,
|
|
|
4768 |
98, 48, 91, 88, 165, 157, 148, 261, 248, 407, 397, 372, 380, 889, 884, 8,
|
|
|
4769 |
85, 84, 81, 159, 156, 143, 260, 249, 427, 401, 392, 383, 727, 713, 708, 7,
|
|
|
4770 |
154, 76, 73, 141, 131, 256, 245, 426, 406, 394, 384, 735, 359, 710, 352, 11,
|
|
|
4771 |
139, 129, 67, 125, 247, 233, 229, 219, 393, 743, 737, 720, 885, 882, 439, 4,
|
|
|
4772 |
243, 120, 118, 115, 227, 223, 396, 746, 742, 736, 721, 712, 706, 223, 436, 6,
|
|
|
4773 |
202, 224, 222, 218, 216, 389, 386, 381, 364, 888, 443, 707, 440, 437, 1728, 4,
|
|
|
4774 |
747, 211, 210, 208, 370, 379, 734, 723, 714, 1735, 883, 877, 876, 3459, 865, 2,
|
|
|
4775 |
377, 369, 102, 187, 726, 722, 358, 711, 709, 866, 1734, 871, 3458, 870, 434, 0,
|
|
|
4776 |
12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3
|
|
|
4777 |
];
|
|
|
4778 |
|
|
|
4779 |
Tables.t24HB = [
|
|
|
4780 |
15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88,
|
|
|
4781 |
14, 12, 21, 38, 71, 130, 122, 216, 209, 198, 327, 345, 319, 297, 279, 42,
|
|
|
4782 |
47, 22, 41, 74, 68, 128, 120, 221, 207, 194, 182, 340, 315, 295, 541, 18,
|
|
|
4783 |
81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293, 271, 16,
|
|
|
4784 |
147, 72, 69, 135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285, 540, 14,
|
|
|
4785 |
263, 66, 129, 126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281, 262, 12,
|
|
|
4786 |
249, 123, 121, 117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272, 520, 10,
|
|
|
4787 |
435, 115, 111, 109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531, 381, 17,
|
|
|
4788 |
427, 212, 208, 205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514, 377, 16,
|
|
|
4789 |
335, 199, 197, 191, 189, 181, 174, 333, 321, 305, 289, 275, 521, 379, 371, 11,
|
|
|
4790 |
668, 184, 183, 179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373, 366, 10,
|
|
|
4791 |
652, 346, 171, 168, 164, 318, 309, 299, 287, 276, 263, 513, 375, 368, 362, 6,
|
|
|
4792 |
648, 322, 316, 312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364, 359, 4,
|
|
|
4793 |
620, 300, 296, 294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361, 357, 2,
|
|
|
4794 |
1033, 280, 278, 274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358, 356, 0,
|
|
|
4795 |
43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3
|
|
|
4796 |
];
|
|
|
4797 |
|
|
|
4798 |
Tables.t32HB = [
|
|
|
4799 |
1 << 0, 5 << 1, 4 << 1, 5 << 2, 6 << 1, 5 << 2, 4 << 2, 4 << 3,
|
|
|
4800 |
7 << 1, 3 << 2, 6 << 2, 0 << 3, 7 << 2, 2 << 3, 3 << 3, 1 << 4
|
|
|
4801 |
];
|
|
|
4802 |
|
|
|
4803 |
Tables.t33HB = [
|
|
|
4804 |
15 << 0, 14 << 1, 13 << 1, 12 << 2, 11 << 1, 10 << 2, 9 << 2, 8 << 3,
|
|
|
4805 |
7 << 1, 6 << 2, 5 << 2, 4 << 3, 3 << 2, 2 << 3, 1 << 3, 0 << 4
|
|
|
4806 |
];
|
|
|
4807 |
|
|
|
4808 |
Tables.t1l = [
|
|
|
4809 |
1, 4,
|
|
|
4810 |
3, 5
|
|
|
4811 |
];
|
|
|
4812 |
|
|
|
4813 |
Tables.t2l = [
|
|
|
4814 |
1, 4, 7,
|
|
|
4815 |
4, 5, 7,
|
|
|
4816 |
6, 7, 8
|
|
|
4817 |
];
|
|
|
4818 |
|
|
|
4819 |
Tables.t3l = [
|
|
|
4820 |
2, 3, 7,
|
|
|
4821 |
4, 4, 7,
|
|
|
4822 |
6, 7, 8
|
|
|
4823 |
];
|
|
|
4824 |
|
|
|
4825 |
Tables.t5l = [
|
|
|
4826 |
1, 4, 7, 8,
|
|
|
4827 |
4, 5, 8, 9,
|
|
|
4828 |
7, 8, 9, 10,
|
|
|
4829 |
8, 8, 9, 10
|
|
|
4830 |
];
|
|
|
4831 |
|
|
|
4832 |
Tables.t6l = [
|
|
|
4833 |
3, 4, 6, 8,
|
|
|
4834 |
4, 4, 6, 7,
|
|
|
4835 |
5, 6, 7, 8,
|
|
|
4836 |
7, 7, 8, 9
|
|
|
4837 |
];
|
|
|
4838 |
|
|
|
4839 |
Tables.t7l = [
|
|
|
4840 |
1, 4, 7, 9, 9, 10,
|
|
|
4841 |
4, 6, 8, 9, 9, 10,
|
|
|
4842 |
7, 7, 9, 10, 10, 11,
|
|
|
4843 |
8, 9, 10, 11, 11, 11,
|
|
|
4844 |
8, 9, 10, 11, 11, 12,
|
|
|
4845 |
9, 10, 11, 12, 12, 12
|
|
|
4846 |
];
|
|
|
4847 |
|
|
|
4848 |
Tables.t8l = [
|
|
|
4849 |
2, 4, 7, 9, 9, 10,
|
|
|
4850 |
4, 4, 6, 10, 10, 10,
|
|
|
4851 |
7, 6, 8, 10, 10, 11,
|
|
|
4852 |
9, 10, 10, 11, 11, 12,
|
|
|
4853 |
9, 9, 10, 11, 12, 12,
|
|
|
4854 |
10, 10, 11, 11, 13, 13
|
|
|
4855 |
];
|
|
|
4856 |
|
|
|
4857 |
Tables.t9l = [
|
|
|
4858 |
3, 4, 6, 7, 9, 10,
|
|
|
4859 |
4, 5, 6, 7, 8, 10,
|
|
|
4860 |
5, 6, 7, 8, 9, 10,
|
|
|
4861 |
7, 7, 8, 9, 9, 10,
|
|
|
4862 |
8, 8, 9, 9, 10, 11,
|
|
|
4863 |
9, 9, 10, 10, 11, 11
|
|
|
4864 |
];
|
|
|
4865 |
|
|
|
4866 |
Tables.t10l = [
|
|
|
4867 |
1, 4, 7, 9, 10, 10, 10, 11,
|
|
|
4868 |
4, 6, 8, 9, 10, 11, 10, 10,
|
|
|
4869 |
7, 8, 9, 10, 11, 12, 11, 11,
|
|
|
4870 |
8, 9, 10, 11, 12, 12, 11, 12,
|
|
|
4871 |
9, 10, 11, 12, 12, 12, 12, 12,
|
|
|
4872 |
10, 11, 12, 12, 13, 13, 12, 13,
|
|
|
4873 |
9, 10, 11, 12, 12, 12, 13, 13,
|
|
|
4874 |
10, 10, 11, 12, 12, 13, 13, 13
|
|
|
4875 |
];
|
|
|
4876 |
|
|
|
4877 |
Tables.t11l = [
|
|
|
4878 |
2, 4, 6, 8, 9, 10, 9, 10,
|
|
|
4879 |
4, 5, 6, 8, 10, 10, 9, 10,
|
|
|
4880 |
6, 7, 8, 9, 10, 11, 10, 10,
|
|
|
4881 |
8, 8, 9, 11, 10, 12, 10, 11,
|
|
|
4882 |
9, 10, 10, 11, 11, 12, 11, 12,
|
|
|
4883 |
9, 10, 11, 12, 12, 13, 12, 13,
|
|
|
4884 |
9, 9, 9, 10, 11, 12, 12, 12,
|
|
|
4885 |
9, 9, 10, 11, 12, 12, 12, 12
|
|
|
4886 |
];
|
|
|
4887 |
|
|
|
4888 |
Tables.t12l = [
|
|
|
4889 |
4, 4, 6, 8, 9, 10, 10, 10,
|
|
|
4890 |
4, 5, 6, 7, 9, 9, 10, 10,
|
|
|
4891 |
6, 6, 7, 8, 9, 10, 9, 10,
|
|
|
4892 |
7, 7, 8, 8, 9, 10, 10, 10,
|
|
|
4893 |
8, 8, 9, 9, 10, 10, 10, 11,
|
|
|
4894 |
9, 9, 10, 10, 10, 11, 10, 11,
|
|
|
4895 |
9, 9, 9, 10, 10, 11, 11, 12,
|
|
|
4896 |
10, 10, 10, 11, 11, 11, 11, 12
|
|
|
4897 |
];
|
|
|
4898 |
|
|
|
4899 |
Tables.t13l = [
|
|
|
4900 |
1, 5, 7, 8, 9, 10, 10, 11, 10, 11, 12, 12, 13, 13, 14, 14,
|
|
|
4901 |
4, 6, 8, 9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 14, 14, 14,
|
|
|
4902 |
7, 8, 9, 10, 11, 11, 12, 12, 11, 12, 12, 13, 13, 14, 15, 15,
|
|
|
4903 |
8, 9, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 15,
|
|
|
4904 |
9, 9, 11, 11, 12, 12, 13, 13, 12, 13, 13, 14, 14, 15, 15, 16,
|
|
|
4905 |
10, 10, 11, 12, 12, 12, 13, 13, 13, 13, 14, 13, 15, 15, 16, 16,
|
|
|
4906 |
10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16,
|
|
|
4907 |
11, 11, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 18, 18,
|
|
|
4908 |
10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 17,
|
|
|
4909 |
11, 11, 12, 12, 13, 13, 13, 15, 14, 15, 15, 16, 16, 16, 18, 17,
|
|
|
4910 |
11, 12, 12, 13, 13, 14, 14, 15, 14, 15, 16, 15, 16, 17, 18, 19,
|
|
|
4911 |
12, 12, 12, 13, 14, 14, 14, 14, 15, 15, 15, 16, 17, 17, 17, 18,
|
|
|
4912 |
12, 13, 13, 14, 14, 15, 14, 15, 16, 16, 17, 17, 17, 18, 18, 18,
|
|
|
4913 |
13, 13, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 17, 18, 18,
|
|
|
4914 |
14, 14, 14, 15, 15, 15, 17, 16, 16, 19, 17, 17, 17, 19, 18, 18,
|
|
|
4915 |
13, 14, 15, 16, 16, 16, 17, 16, 17, 17, 18, 18, 21, 20, 21, 18
|
|
|
4916 |
];
|
|
|
4917 |
|
|
|
4918 |
Tables.t15l = [
|
|
|
4919 |
3, 5, 6, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 14,
|
|
|
4920 |
5, 5, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13,
|
|
|
4921 |
6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13,
|
|
|
4922 |
7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13,
|
|
|
4923 |
8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13,
|
|
|
4924 |
9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14,
|
|
|
4925 |
10, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14,
|
|
|
4926 |
10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 14,
|
|
|
4927 |
10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14,
|
|
|
4928 |
10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14,
|
|
|
4929 |
11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 14,
|
|
|
4930 |
11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15,
|
|
|
4931 |
12, 12, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 15, 15,
|
|
|
4932 |
12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15,
|
|
|
4933 |
13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 14, 15,
|
|
|
4934 |
13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15
|
|
|
4935 |
];
|
|
|
4936 |
|
|
|
4937 |
Tables.t16_5l = [
|
|
|
4938 |
1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 11,
|
|
|
4939 |
4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 11,
|
|
|
4940 |
7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 12,
|
|
|
4941 |
9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 13,
|
|
|
4942 |
10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 12,
|
|
|
4943 |
10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 13,
|
|
|
4944 |
11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 13,
|
|
|
4945 |
11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 13,
|
|
|
4946 |
11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 13,
|
|
|
4947 |
12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 14,
|
|
|
4948 |
12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 13,
|
|
|
4949 |
13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 14,
|
|
|
4950 |
13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 14,
|
|
|
4951 |
15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 14,
|
|
|
4952 |
14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 14,
|
|
|
4953 |
11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 12
|
|
|
4954 |
];
|
|
|
4955 |
|
|
|
4956 |
Tables.t16l = [
|
|
|
4957 |
1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 10,
|
|
|
4958 |
4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 10,
|
|
|
4959 |
7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 11,
|
|
|
4960 |
9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 12,
|
|
|
4961 |
10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 11,
|
|
|
4962 |
10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 12,
|
|
|
4963 |
11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 12,
|
|
|
4964 |
11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 12,
|
|
|
4965 |
11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 12,
|
|
|
4966 |
12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 13,
|
|
|
4967 |
12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 12,
|
|
|
4968 |
13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 13,
|
|
|
4969 |
13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 13,
|
|
|
4970 |
15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 13,
|
|
|
4971 |
14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 13,
|
|
|
4972 |
10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10
|
|
|
4973 |
];
|
|
|
4974 |
|
|
|
4975 |
Tables.t24l = [
|
|
|
4976 |
4, 5, 7, 8, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 13, 10,
|
|
|
4977 |
5, 6, 7, 8, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 10,
|
|
|
4978 |
7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 9,
|
|
|
4979 |
8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 9,
|
|
|
4980 |
9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 9,
|
|
|
4981 |
10, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 9,
|
|
|
4982 |
10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 9,
|
|
|
4983 |
11, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 10,
|
|
|
4984 |
11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 10,
|
|
|
4985 |
11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 10,
|
|
|
4986 |
12, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10,
|
|
|
4987 |
12, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10,
|
|
|
4988 |
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 10,
|
|
|
4989 |
12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10,
|
|
|
4990 |
13, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 10,
|
|
|
4991 |
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 6
|
|
|
4992 |
];
|
|
|
4993 |
|
|
|
4994 |
Tables.t32l = [
|
|
|
4995 |
1 + 0, 4 + 1, 4 + 1, 5 + 2, 4 + 1, 6 + 2, 5 + 2, 6 + 3,
|
|
|
4996 |
4 + 1, 5 + 2, 5 + 2, 6 + 3, 5 + 2, 6 + 3, 6 + 3, 6 + 4
|
|
|
4997 |
];
|
|
|
4998 |
|
|
|
4999 |
Tables.t33l = [
|
|
|
5000 |
4 + 0, 4 + 1, 4 + 1, 4 + 2, 4 + 1, 4 + 2, 4 + 2, 4 + 3,
|
|
|
5001 |
4 + 1, 4 + 2, 4 + 2, 4 + 3, 4 + 2, 4 + 3, 4 + 3, 4 + 4
|
|
|
5002 |
];
|
|
|
5003 |
|
|
|
5004 |
Tables.ht = [
|
|
|
5005 |
/* xlen, linmax, table, hlen */
|
|
|
5006 |
new HuffCodeTab(0, 0, null, null),
|
|
|
5007 |
new HuffCodeTab(2, 0, Tables.t1HB, Tables.t1l),
|
|
|
5008 |
new HuffCodeTab(3, 0, Tables.t2HB, Tables.t2l),
|
|
|
5009 |
new HuffCodeTab(3, 0, Tables.t3HB, Tables.t3l),
|
|
|
5010 |
new HuffCodeTab(0, 0, null, null), /* Apparently not used */
|
|
|
5011 |
new HuffCodeTab(4, 0, Tables.t5HB, Tables.t5l),
|
|
|
5012 |
new HuffCodeTab(4, 0, Tables.t6HB, Tables.t6l),
|
|
|
5013 |
new HuffCodeTab(6, 0, Tables.t7HB, Tables.t7l),
|
|
|
5014 |
new HuffCodeTab(6, 0, Tables.t8HB, Tables.t8l),
|
|
|
5015 |
new HuffCodeTab(6, 0, Tables.t9HB, Tables.t9l),
|
|
|
5016 |
new HuffCodeTab(8, 0, Tables.t10HB, Tables.t10l),
|
|
|
5017 |
new HuffCodeTab(8, 0, Tables.t11HB, Tables.t11l),
|
|
|
5018 |
new HuffCodeTab(8, 0, Tables.t12HB, Tables.t12l),
|
|
|
5019 |
new HuffCodeTab(16, 0, Tables.t13HB, Tables.t13l),
|
|
|
5020 |
new HuffCodeTab(0, 0, null, Tables.t16_5l), /* Apparently not used */
|
|
|
5021 |
new HuffCodeTab(16, 0, Tables.t15HB, Tables.t15l),
|
|
|
5022 |
|
|
|
5023 |
new HuffCodeTab(1, 1, Tables.t16HB, Tables.t16l),
|
|
|
5024 |
new HuffCodeTab(2, 3, Tables.t16HB, Tables.t16l),
|
|
|
5025 |
new HuffCodeTab(3, 7, Tables.t16HB, Tables.t16l),
|
|
|
5026 |
new HuffCodeTab(4, 15, Tables.t16HB, Tables.t16l),
|
|
|
5027 |
new HuffCodeTab(6, 63, Tables.t16HB, Tables.t16l),
|
|
|
5028 |
new HuffCodeTab(8, 255, Tables.t16HB, Tables.t16l),
|
|
|
5029 |
new HuffCodeTab(10, 1023, Tables.t16HB, Tables.t16l),
|
|
|
5030 |
new HuffCodeTab(13, 8191, Tables.t16HB, Tables.t16l),
|
|
|
5031 |
|
|
|
5032 |
new HuffCodeTab(4, 15, Tables.t24HB, Tables.t24l),
|
|
|
5033 |
new HuffCodeTab(5, 31, Tables.t24HB, Tables.t24l),
|
|
|
5034 |
new HuffCodeTab(6, 63, Tables.t24HB, Tables.t24l),
|
|
|
5035 |
new HuffCodeTab(7, 127, Tables.t24HB, Tables.t24l),
|
|
|
5036 |
new HuffCodeTab(8, 255, Tables.t24HB, Tables.t24l),
|
|
|
5037 |
new HuffCodeTab(9, 511, Tables.t24HB, Tables.t24l),
|
|
|
5038 |
new HuffCodeTab(11, 2047, Tables.t24HB, Tables.t24l),
|
|
|
5039 |
new HuffCodeTab(13, 8191, Tables.t24HB, Tables.t24l),
|
|
|
5040 |
|
|
|
5041 |
new HuffCodeTab(0, 0, Tables.t32HB, Tables.t32l),
|
|
|
5042 |
new HuffCodeTab(0, 0, Tables.t33HB, Tables.t33l),
|
|
|
5043 |
];
|
|
|
5044 |
|
|
|
5045 |
/**
|
|
|
5046 |
* <CODE>
|
|
|
5047 |
* for (i = 0; i < 16*16; i++) [
|
|
|
5048 |
* largetbl[i] = ((ht[16].hlen[i]) << 16) + ht[24].hlen[i];
|
|
|
5049 |
* ]
|
|
|
5050 |
* </CODE>
|
|
|
5051 |
*
|
|
|
5052 |
*/
|
|
|
5053 |
Tables.largetbl = [
|
|
|
5054 |
0x010004, 0x050005, 0x070007, 0x090008, 0x0a0009, 0x0a000a, 0x0b000a, 0x0b000b,
|
|
|
5055 |
0x0c000b, 0x0c000c, 0x0c000c, 0x0d000c, 0x0d000c, 0x0d000c, 0x0e000d, 0x0a000a,
|
|
|
5056 |
0x040005, 0x060006, 0x080007, 0x090008, 0x0a0009, 0x0b000a, 0x0b000a, 0x0b000b,
|
|
|
5057 |
0x0c000b, 0x0c000b, 0x0c000c, 0x0d000c, 0x0e000c, 0x0d000c, 0x0e000c, 0x0a000a,
|
|
|
5058 |
0x070007, 0x080007, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000b,
|
|
|
5059 |
0x0d000b, 0x0c000b, 0x0d000b, 0x0d000c, 0x0d000c, 0x0e000c, 0x0e000d, 0x0b0009,
|
|
|
5060 |
0x090008, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0c000b,
|
|
|
5061 |
0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0c0009,
|
|
|
5062 |
0x0a0009, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000a, 0x0d000b,
|
|
|
5063 |
0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000d, 0x0b0009,
|
|
|
5064 |
0x0a000a, 0x0a0009, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0e000b,
|
|
|
5065 |
0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0c0009,
|
|
|
5066 |
0x0b000a, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0d000b, 0x0d000b,
|
|
|
5067 |
0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000d, 0x0c0009,
|
|
|
5068 |
0x0b000b, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b,
|
|
|
5069 |
0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x11000d, 0x11000d, 0x0c000a,
|
|
|
5070 |
0x0b000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b,
|
|
|
5071 |
0x0f000b, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000d, 0x10000d, 0x0c000a,
|
|
|
5072 |
0x0c000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, 0x0f000c,
|
|
|
5073 |
0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0f000d, 0x10000d, 0x0f000d, 0x0d000a,
|
|
|
5074 |
0x0c000c, 0x0d000b, 0x0c000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c,
|
|
|
5075 |
0x0f000c, 0x10000c, 0x10000c, 0x10000d, 0x11000d, 0x11000d, 0x10000d, 0x0c000a,
|
|
|
5076 |
0x0d000c, 0x0d000c, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x10000c,
|
|
|
5077 |
0x10000c, 0x10000c, 0x10000c, 0x10000d, 0x10000d, 0x0f000d, 0x10000d, 0x0d000a,
|
|
|
5078 |
0x0d000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c,
|
|
|
5079 |
0x0f000c, 0x11000c, 0x10000d, 0x10000d, 0x10000d, 0x10000d, 0x12000d, 0x0d000a,
|
|
|
5080 |
0x0f000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000c,
|
|
|
5081 |
0x10000d, 0x12000d, 0x11000d, 0x11000d, 0x11000d, 0x13000d, 0x11000d, 0x0d000a,
|
|
|
5082 |
0x0e000d, 0x0f000c, 0x0d000c, 0x0e000c, 0x10000c, 0x10000c, 0x0f000c, 0x10000d,
|
|
|
5083 |
0x10000d, 0x11000d, 0x12000d, 0x11000d, 0x13000d, 0x11000d, 0x10000d, 0x0d000a,
|
|
|
5084 |
0x0a0009, 0x0a0009, 0x0a0009, 0x0b0009, 0x0b0009, 0x0c0009, 0x0c0009, 0x0c0009,
|
|
|
5085 |
0x0d0009, 0x0d0009, 0x0d0009, 0x0d000a, 0x0d000a, 0x0d000a, 0x0d000a, 0x0a0006
|
|
|
5086 |
];
|
|
|
5087 |
/**
|
|
|
5088 |
* <CODE>
|
|
|
5089 |
* for (i = 0; i < 3*3; i++) [
|
|
|
5090 |
* table23[i] = ((ht[2].hlen[i]) << 16) + ht[3].hlen[i];
|
|
|
5091 |
* ]
|
|
|
5092 |
* </CODE>
|
|
|
5093 |
*
|
|
|
5094 |
*/
|
|
|
5095 |
Tables.table23 = [
|
|
|
5096 |
0x010002, 0x040003, 0x070007,
|
|
|
5097 |
0x040004, 0x050004, 0x070007,
|
|
|
5098 |
0x060006, 0x070007, 0x080008
|
|
|
5099 |
];
|
|
|
5100 |
|
|
|
5101 |
/**
|
|
|
5102 |
* <CODE>
|
|
|
5103 |
* for (i = 0; i < 4*4; i++) [
|
|
|
5104 |
* table56[i] = ((ht[5].hlen[i]) << 16) + ht[6].hlen[i];
|
|
|
5105 |
* ]
|
|
|
5106 |
* </CODE>
|
|
|
5107 |
*
|
|
|
5108 |
*/
|
|
|
5109 |
Tables.table56 = [
|
|
|
5110 |
0x010003, 0x040004, 0x070006, 0x080008, 0x040004, 0x050004, 0x080006, 0x090007,
|
|
|
5111 |
0x070005, 0x080006, 0x090007, 0x0a0008, 0x080007, 0x080007, 0x090008, 0x0a0009
|
|
|
5112 |
];
|
|
|
5113 |
|
|
|
5114 |
Tables.bitrate_table = [
|
|
|
5115 |
[0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1], /* MPEG 2 */
|
|
|
5116 |
[0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1], /* MPEG 1 */
|
|
|
5117 |
[0, 8, 16, 24, 32, 40, 48, 56, 64, -1, -1, -1, -1, -1, -1, -1], /* MPEG 2.5 */
|
|
|
5118 |
];
|
|
|
5119 |
|
|
|
5120 |
/**
|
|
|
5121 |
* MPEG 2, MPEG 1, MPEG 2.5.
|
|
|
5122 |
*/
|
|
|
5123 |
Tables.samplerate_table = [
|
|
|
5124 |
[22050, 24000, 16000, -1],
|
|
|
5125 |
[44100, 48000, 32000, -1],
|
|
|
5126 |
[11025, 12000, 8000, -1],
|
|
|
5127 |
];
|
|
|
5128 |
|
|
|
5129 |
/**
|
|
|
5130 |
* This is the scfsi_band table from 2.4.2.7 of the IS.
|
|
|
5131 |
*/
|
|
|
5132 |
Tables.scfsi_band = [0, 6, 11, 16, 21];
|
|
|
5133 |
|
|
|
5134 |
function MeanBits(meanBits) {
|
|
|
5135 |
this.bits = meanBits;
|
|
|
5136 |
}
|
|
|
5137 |
|
|
|
5138 |
function VBRQuantize() {
|
|
|
5139 |
var qupvt;
|
|
|
5140 |
var tak;
|
|
|
5141 |
|
|
|
5142 |
this.setModules = function (_qupvt, _tk) {
|
|
|
5143 |
qupvt = _qupvt;
|
|
|
5144 |
tak = _tk;
|
|
|
5145 |
}
|
|
|
5146 |
//TODO
|
|
|
5147 |
|
|
|
5148 |
}
|
|
|
5149 |
|
|
|
5150 |
//package mp3;
|
|
|
5151 |
|
|
|
5152 |
function CalcNoiseResult() {
|
|
|
5153 |
/**
|
|
|
5154 |
* sum of quantization noise > masking
|
|
|
5155 |
*/
|
|
|
5156 |
this.over_noise = 0.;
|
|
|
5157 |
/**
|
|
|
5158 |
* sum of all quantization noise
|
|
|
5159 |
*/
|
|
|
5160 |
this.tot_noise = 0.;
|
|
|
5161 |
/**
|
|
|
5162 |
* max quantization noise
|
|
|
5163 |
*/
|
|
|
5164 |
this.max_noise = 0.;
|
|
|
5165 |
/**
|
|
|
5166 |
* number of quantization noise > masking
|
|
|
5167 |
*/
|
|
|
5168 |
this.over_count = 0;
|
|
|
5169 |
/**
|
|
|
5170 |
* SSD-like cost of distorted bands
|
|
|
5171 |
*/
|
|
|
5172 |
this.over_SSD = 0;
|
|
|
5173 |
this.bits = 0;
|
|
|
5174 |
}
|
|
|
5175 |
|
|
|
5176 |
|
|
|
5177 |
function LameGlobalFlags() {
|
|
|
5178 |
|
|
|
5179 |
this.class_id = 0;
|
|
|
5180 |
|
|
|
5181 |
/* input description */
|
|
|
5182 |
|
|
|
5183 |
/**
|
|
|
5184 |
* number of samples. default=-1
|
|
|
5185 |
*/
|
|
|
5186 |
this.num_samples = 0;
|
|
|
5187 |
/**
|
|
|
5188 |
* input number of channels. default=2
|
|
|
5189 |
*/
|
|
|
5190 |
this.num_channels = 0;
|
|
|
5191 |
/**
|
|
|
5192 |
* input_samp_rate in Hz. default=44.1 kHz
|
|
|
5193 |
*/
|
|
|
5194 |
this.in_samplerate = 0;
|
|
|
5195 |
/**
|
|
|
5196 |
* output_samp_rate. default: LAME picks best value at least not used for
|
|
|
5197 |
* MP3 decoding: Remember 44.1 kHz MP3s and AC97
|
|
|
5198 |
*/
|
|
|
5199 |
this.out_samplerate = 0;
|
|
|
5200 |
/**
|
|
|
5201 |
* scale input by this amount before encoding at least not used for MP3
|
|
|
5202 |
* decoding
|
|
|
5203 |
*/
|
|
|
5204 |
this.scale = 0.;
|
|
|
5205 |
/**
|
|
|
5206 |
* scale input of channel 0 (left) by this amount before encoding
|
|
|
5207 |
*/
|
|
|
5208 |
this.scale_left = 0.;
|
|
|
5209 |
/**
|
|
|
5210 |
* scale input of channel 1 (right) by this amount before encoding
|
|
|
5211 |
*/
|
|
|
5212 |
this.scale_right = 0.;
|
|
|
5213 |
|
|
|
5214 |
/* general control params */
|
|
|
5215 |
/**
|
|
|
5216 |
* collect data for a MP3 frame analyzer?
|
|
|
5217 |
*/
|
|
|
5218 |
this.analysis = false;
|
|
|
5219 |
/**
|
|
|
5220 |
* add Xing VBR tag?
|
|
|
5221 |
*/
|
|
|
5222 |
this.bWriteVbrTag = false;
|
|
|
5223 |
|
|
|
5224 |
/**
|
|
|
5225 |
* use lame/mpglib to convert mp3 to wav
|
|
|
5226 |
*/
|
|
|
5227 |
this.decode_only = false;
|
|
|
5228 |
/**
|
|
|
5229 |
* quality setting 0=best, 9=worst default=5
|
|
|
5230 |
*/
|
|
|
5231 |
this.quality = 0;
|
|
|
5232 |
/**
|
|
|
5233 |
* see enum default = LAME picks best value
|
|
|
5234 |
*/
|
|
|
5235 |
this.mode = MPEGMode.STEREO;
|
|
|
5236 |
/**
|
|
|
5237 |
* force M/S mode. requires mode=1
|
|
|
5238 |
*/
|
|
|
5239 |
this.force_ms = false;
|
|
|
5240 |
/**
|
|
|
5241 |
* use free format? default=0
|
|
|
5242 |
*/
|
|
|
5243 |
this.free_format = false;
|
|
|
5244 |
/**
|
|
|
5245 |
* find the RG value? default=0
|
|
|
5246 |
*/
|
|
|
5247 |
this.findReplayGain = false;
|
|
|
5248 |
/**
|
|
|
5249 |
* decode on the fly? default=0
|
|
|
5250 |
*/
|
|
|
5251 |
this.decode_on_the_fly = false;
|
|
|
5252 |
/**
|
|
|
5253 |
* 1 (default) writes ID3 tags, 0 not
|
|
|
5254 |
*/
|
|
|
5255 |
this.write_id3tag_automatic = false;
|
|
|
5256 |
|
|
|
5257 |
/*
|
|
|
5258 |
* set either brate>0 or compression_ratio>0, LAME will compute the value of
|
|
|
5259 |
* the variable not set. Default is compression_ratio = 11.025
|
|
|
5260 |
*/
|
|
|
5261 |
/**
|
|
|
5262 |
* bitrate
|
|
|
5263 |
*/
|
|
|
5264 |
this.brate = 0;
|
|
|
5265 |
/**
|
|
|
5266 |
* sizeof(wav file)/sizeof(mp3 file)
|
|
|
5267 |
*/
|
|
|
5268 |
this.compression_ratio = 0.;
|
|
|
5269 |
|
|
|
5270 |
/* frame params */
|
|
|
5271 |
/**
|
|
|
5272 |
* mark as copyright. default=0
|
|
|
5273 |
*/
|
|
|
5274 |
this.copyright = 0;
|
|
|
5275 |
/**
|
|
|
5276 |
* mark as original. default=1
|
|
|
5277 |
*/
|
|
|
5278 |
this.original = 0;
|
|
|
5279 |
/**
|
|
|
5280 |
* the MP3 'private extension' bit. Meaningless
|
|
|
5281 |
*/
|
|
|
5282 |
this.extension = 0;
|
|
|
5283 |
/**
|
|
|
5284 |
* Input PCM is emphased PCM (for instance from one of the rarely emphased
|
|
|
5285 |
* CDs), it is STRONGLY not recommended to use this, because psycho does not
|
|
|
5286 |
* take it into account, and last but not least many decoders don't care
|
|
|
5287 |
* about these bits
|
|
|
5288 |
*/
|
|
|
5289 |
this.emphasis = 0;
|
|
|
5290 |
/**
|
|
|
5291 |
* use 2 bytes per frame for a CRC checksum. default=0
|
|
|
5292 |
*/
|
|
|
5293 |
this.error_protection = 0;
|
|
|
5294 |
/**
|
|
|
5295 |
* enforce ISO spec as much as possible
|
|
|
5296 |
*/
|
|
|
5297 |
this.strict_ISO = false;
|
|
|
5298 |
|
|
|
5299 |
/**
|
|
|
5300 |
* use bit reservoir?
|
|
|
5301 |
*/
|
|
|
5302 |
this.disable_reservoir = false;
|
|
|
5303 |
|
|
|
5304 |
/* quantization/noise shaping */
|
|
|
5305 |
this.quant_comp = 0;
|
|
|
5306 |
this.quant_comp_short = 0;
|
|
|
5307 |
this.experimentalY = false;
|
|
|
5308 |
this.experimentalZ = 0;
|
|
|
5309 |
this.exp_nspsytune = 0;
|
|
|
5310 |
|
|
|
5311 |
this.preset = 0;
|
|
|
5312 |
|
|
|
5313 |
/* VBR control */
|
|
|
5314 |
this.VBR = null;
|
|
|
5315 |
/**
|
|
|
5316 |
* Range [0,...,1[
|
|
|
5317 |
*/
|
|
|
5318 |
this.VBR_q_frac = 0.;
|
|
|
5319 |
/**
|
|
|
5320 |
* Range [0,...,9]
|
|
|
5321 |
*/
|
|
|
5322 |
this.VBR_q = 0;
|
|
|
5323 |
this.VBR_mean_bitrate_kbps = 0;
|
|
|
5324 |
this.VBR_min_bitrate_kbps = 0;
|
|
|
5325 |
this.VBR_max_bitrate_kbps = 0;
|
|
|
5326 |
/**
|
|
|
5327 |
* strictly enforce VBR_min_bitrate normaly, it will be violated for analog
|
|
|
5328 |
* silence
|
|
|
5329 |
*/
|
|
|
5330 |
this.VBR_hard_min = 0;
|
|
|
5331 |
|
|
|
5332 |
/* resampling and filtering */
|
|
|
5333 |
|
|
|
5334 |
/**
|
|
|
5335 |
* freq in Hz. 0=lame choses. -1=no filter
|
|
|
5336 |
*/
|
|
|
5337 |
this.lowpassfreq = 0;
|
|
|
5338 |
/**
|
|
|
5339 |
* freq in Hz. 0=lame choses. -1=no filter
|
|
|
5340 |
*/
|
|
|
5341 |
this.highpassfreq = 0;
|
|
|
5342 |
/**
|
|
|
5343 |
* freq width of filter, in Hz (default=15%)
|
|
|
5344 |
*/
|
|
|
5345 |
this.lowpasswidth = 0;
|
|
|
5346 |
/**
|
|
|
5347 |
* freq width of filter, in Hz (default=15%)
|
|
|
5348 |
*/
|
|
|
5349 |
this.highpasswidth = 0;
|
|
|
5350 |
|
|
|
5351 |
/*
|
|
|
5352 |
* psycho acoustics and other arguments which you should not change unless
|
|
|
5353 |
* you know what you are doing
|
|
|
5354 |
*/
|
|
|
5355 |
|
|
|
5356 |
this.maskingadjust = 0.;
|
|
|
5357 |
this.maskingadjust_short = 0.;
|
|
|
5358 |
/**
|
|
|
5359 |
* only use ATH
|
|
|
5360 |
*/
|
|
|
5361 |
this.ATHonly = false;
|
|
|
5362 |
/**
|
|
|
5363 |
* only use ATH for short blocks
|
|
|
5364 |
*/
|
|
|
5365 |
this.ATHshort = false;
|
|
|
5366 |
/**
|
|
|
5367 |
* disable ATH
|
|
|
5368 |
*/
|
|
|
5369 |
this.noATH = false;
|
|
|
5370 |
/**
|
|
|
5371 |
* select ATH formula
|
|
|
5372 |
*/
|
|
|
5373 |
this.ATHtype = 0;
|
|
|
5374 |
/**
|
|
|
5375 |
* change ATH formula 4 shape
|
|
|
5376 |
*/
|
|
|
5377 |
this.ATHcurve = 0.;
|
|
|
5378 |
/**
|
|
|
5379 |
* lower ATH by this many db
|
|
|
5380 |
*/
|
|
|
5381 |
this.ATHlower = 0.;
|
|
|
5382 |
/**
|
|
|
5383 |
* select ATH auto-adjust scheme
|
|
|
5384 |
*/
|
|
|
5385 |
this.athaa_type = 0;
|
|
|
5386 |
/**
|
|
|
5387 |
* select ATH auto-adjust loudness calc
|
|
|
5388 |
*/
|
|
|
5389 |
this.athaa_loudapprox = 0;
|
|
|
5390 |
/**
|
|
|
5391 |
* dB, tune active region of auto-level
|
|
|
5392 |
*/
|
|
|
5393 |
this.athaa_sensitivity = 0.;
|
|
|
5394 |
this.short_blocks = null;
|
|
|
5395 |
/**
|
|
|
5396 |
* use temporal masking effect
|
|
|
5397 |
*/
|
|
|
5398 |
this.useTemporal = false;
|
|
|
5399 |
this.interChRatio = 0.;
|
|
|
5400 |
/**
|
|
|
5401 |
* Naoki's adjustment of Mid/Side maskings
|
|
|
5402 |
*/
|
|
|
5403 |
this.msfix = 0.;
|
|
|
5404 |
|
|
|
5405 |
/**
|
|
|
5406 |
* 0 off, 1 on
|
|
|
5407 |
*/
|
|
|
5408 |
this.tune = false;
|
|
|
5409 |
/**
|
|
|
5410 |
* used to pass values for debugging and stuff
|
|
|
5411 |
*/
|
|
|
5412 |
this.tune_value_a = 0.;
|
|
|
5413 |
|
|
|
5414 |
/************************************************************************/
|
|
|
5415 |
/* internal variables, do not set... */
|
|
|
5416 |
/* provided because they may be of use to calling application */
|
|
|
5417 |
/************************************************************************/
|
|
|
5418 |
|
|
|
5419 |
/**
|
|
|
5420 |
* 0=MPEG-2/2.5 1=MPEG-1
|
|
|
5421 |
*/
|
|
|
5422 |
this.version = 0;
|
|
|
5423 |
this.encoder_delay = 0;
|
|
|
5424 |
/**
|
|
|
5425 |
* number of samples of padding appended to input
|
|
|
5426 |
*/
|
|
|
5427 |
this.encoder_padding = 0;
|
|
|
5428 |
this.framesize = 0;
|
|
|
5429 |
/**
|
|
|
5430 |
* number of frames encoded
|
|
|
5431 |
*/
|
|
|
5432 |
this.frameNum = 0;
|
|
|
5433 |
/**
|
|
|
5434 |
* is this struct owned by calling program or lame?
|
|
|
5435 |
*/
|
|
|
5436 |
this.lame_allocated_gfp = 0;
|
|
|
5437 |
/**************************************************************************/
|
|
|
5438 |
/* more internal variables are stored in this structure: */
|
|
|
5439 |
/**************************************************************************/
|
|
|
5440 |
this.internal_flags = null;
|
|
|
5441 |
}
|
|
|
5442 |
|
|
|
5443 |
|
|
|
5444 |
|
|
|
5445 |
function ReplayGain() {
|
|
|
5446 |
this.linprebuf = new_float(GainAnalysis.MAX_ORDER * 2);
|
|
|
5447 |
/**
|
|
|
5448 |
* left input samples, with pre-buffer
|
|
|
5449 |
*/
|
|
|
5450 |
this.linpre = 0;
|
|
|
5451 |
this.lstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER);
|
|
|
5452 |
/**
|
|
|
5453 |
* left "first step" (i.e. post first filter) samples
|
|
|
5454 |
*/
|
|
|
5455 |
this.lstep = 0;
|
|
|
5456 |
this.loutbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER);
|
|
|
5457 |
/**
|
|
|
5458 |
* left "out" (i.e. post second filter) samples
|
|
|
5459 |
*/
|
|
|
5460 |
this.lout = 0;
|
|
|
5461 |
this.rinprebuf = new_float(GainAnalysis.MAX_ORDER * 2);
|
|
|
5462 |
/**
|
|
|
5463 |
* right input samples ...
|
|
|
5464 |
*/
|
|
|
5465 |
this.rinpre = 0;
|
|
|
5466 |
this.rstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER);
|
|
|
5467 |
this.rstep = 0;
|
|
|
5468 |
this.routbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER);
|
|
|
5469 |
this.rout = 0;
|
|
|
5470 |
/**
|
|
|
5471 |
* number of samples required to reach number of milliseconds required
|
|
|
5472 |
* for RMS window
|
|
|
5473 |
*/
|
|
|
5474 |
this.sampleWindow = 0;
|
|
|
5475 |
this.totsamp = 0;
|
|
|
5476 |
this.lsum = 0.;
|
|
|
5477 |
this.rsum = 0.;
|
|
|
5478 |
this.freqindex = 0;
|
|
|
5479 |
this.first = 0;
|
|
|
5480 |
this.A = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB));
|
|
|
5481 |
this.B = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB));
|
|
|
5482 |
|
|
|
5483 |
}
|
|
|
5484 |
|
|
|
5485 |
|
|
|
5486 |
|
|
|
5487 |
function CBRNewIterationLoop(_quantize) {
|
|
|
5488 |
var quantize = _quantize;
|
|
|
5489 |
this.quantize = quantize;
|
|
|
5490 |
this.iteration_loop = function(gfp, pe, ms_ener_ratio, ratio) {
|
|
|
5491 |
var gfc = gfp.internal_flags;
|
|
|
5492 |
var l3_xmin = new_float(L3Side.SFBMAX);
|
|
|
5493 |
var xrpow = new_float(576);
|
|
|
5494 |
var targ_bits = new_int(2);
|
|
|
5495 |
var mean_bits = 0, max_bits;
|
|
|
5496 |
var l3_side = gfc.l3_side;
|
|
|
5497 |
|
|
|
5498 |
var mb = new MeanBits(mean_bits);
|
|
|
5499 |
this.quantize.rv.ResvFrameBegin(gfp, mb);
|
|
|
5500 |
mean_bits = mb.bits;
|
|
|
5501 |
|
|
|
5502 |
/* quantize! */
|
|
|
5503 |
for (var gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
5504 |
|
|
|
5505 |
/*
|
|
|
5506 |
* calculate needed bits
|
|
|
5507 |
*/
|
|
|
5508 |
max_bits = this.quantize.qupvt.on_pe(gfp, pe, targ_bits, mean_bits,
|
|
|
5509 |
gr, gr);
|
|
|
5510 |
|
|
|
5511 |
if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) {
|
|
|
5512 |
this.quantize.ms_convert(gfc.l3_side, gr);
|
|
|
5513 |
this.quantize.qupvt.reduce_side(targ_bits, ms_ener_ratio[gr],
|
|
|
5514 |
mean_bits, max_bits);
|
|
|
5515 |
}
|
|
|
5516 |
|
|
|
5517 |
for (var ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
5518 |
var adjust, masking_lower_db;
|
|
|
5519 |
var cod_info = l3_side.tt[gr][ch];
|
|
|
5520 |
|
|
|
5521 |
if (cod_info.block_type != Encoder.SHORT_TYPE) {
|
|
|
5522 |
// NORM, START or STOP type
|
|
|
5523 |
adjust = 0;
|
|
|
5524 |
masking_lower_db = gfc.PSY.mask_adjust - adjust;
|
|
|
5525 |
} else {
|
|
|
5526 |
adjust = 0;
|
|
|
5527 |
masking_lower_db = gfc.PSY.mask_adjust_short - adjust;
|
|
|
5528 |
}
|
|
|
5529 |
gfc.masking_lower = Math.pow(10.0,
|
|
|
5530 |
masking_lower_db * 0.1);
|
|
|
5531 |
|
|
|
5532 |
/*
|
|
|
5533 |
* init_outer_loop sets up cod_info, scalefac and xrpow
|
|
|
5534 |
*/
|
|
|
5535 |
this.quantize.init_outer_loop(gfc, cod_info);
|
|
|
5536 |
if (this.quantize.init_xrpow(gfc, cod_info, xrpow)) {
|
|
|
5537 |
/*
|
|
|
5538 |
* xr contains energy we will have to encode calculate the
|
|
|
5539 |
* masking abilities find some good quantization in
|
|
|
5540 |
* outer_loop
|
|
|
5541 |
*/
|
|
|
5542 |
this.quantize.qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info,
|
|
|
5543 |
l3_xmin);
|
|
|
5544 |
this.quantize.outer_loop(gfp, cod_info, l3_xmin, xrpow, ch,
|
|
|
5545 |
targ_bits[ch]);
|
|
|
5546 |
}
|
|
|
5547 |
|
|
|
5548 |
this.quantize.iteration_finish_one(gfc, gr, ch);
|
|
|
5549 |
} /* for ch */
|
|
|
5550 |
} /* for gr */
|
|
|
5551 |
|
|
|
5552 |
this.quantize.rv.ResvFrameEnd(gfc, mean_bits);
|
|
|
5553 |
}
|
|
|
5554 |
}
|
|
|
5555 |
|
|
|
5556 |
|
|
|
5557 |
/**
|
|
|
5558 |
* ATH related stuff, if something new ATH related has to be added, please plug
|
|
|
5559 |
* it here into the ATH.
|
|
|
5560 |
*/
|
|
|
5561 |
function ATH() {
|
|
|
5562 |
/**
|
|
|
5563 |
* Method for the auto adjustment.
|
|
|
5564 |
*/
|
|
|
5565 |
this.useAdjust = 0;
|
|
|
5566 |
/**
|
|
|
5567 |
* factor for tuning the (sample power) point below which adaptive threshold
|
|
|
5568 |
* of hearing adjustment occurs
|
|
|
5569 |
*/
|
|
|
5570 |
this.aaSensitivityP = 0.;
|
|
|
5571 |
/**
|
|
|
5572 |
* Lowering based on peak volume, 1 = no lowering.
|
|
|
5573 |
*/
|
|
|
5574 |
this.adjust = 0.;
|
|
|
5575 |
/**
|
|
|
5576 |
* Limit for dynamic ATH adjust.
|
|
|
5577 |
*/
|
|
|
5578 |
this.adjustLimit = 0.;
|
|
|
5579 |
/**
|
|
|
5580 |
* Determined to lower x dB each second.
|
|
|
5581 |
*/
|
|
|
5582 |
this.decay = 0.;
|
|
|
5583 |
/**
|
|
|
5584 |
* Lowest ATH value.
|
|
|
5585 |
*/
|
|
|
5586 |
this.floor = 0.;
|
|
|
5587 |
/**
|
|
|
5588 |
* ATH for sfbs in long blocks.
|
|
|
5589 |
*/
|
|
|
5590 |
this.l = new_float(Encoder.SBMAX_l);
|
|
|
5591 |
/**
|
|
|
5592 |
* ATH for sfbs in short blocks.
|
|
|
5593 |
*/
|
|
|
5594 |
this.s = new_float(Encoder.SBMAX_s);
|
|
|
5595 |
/**
|
|
|
5596 |
* ATH for partitioned sfb21 in long blocks.
|
|
|
5597 |
*/
|
|
|
5598 |
this.psfb21 = new_float(Encoder.PSFB21);
|
|
|
5599 |
/**
|
|
|
5600 |
* ATH for partitioned sfb12 in short blocks.
|
|
|
5601 |
*/
|
|
|
5602 |
this.psfb12 = new_float(Encoder.PSFB12);
|
|
|
5603 |
/**
|
|
|
5604 |
* ATH for long block convolution bands.
|
|
|
5605 |
*/
|
|
|
5606 |
this.cb_l = new_float(Encoder.CBANDS);
|
|
|
5607 |
/**
|
|
|
5608 |
* ATH for short block convolution bands.
|
|
|
5609 |
*/
|
|
|
5610 |
this.cb_s = new_float(Encoder.CBANDS);
|
|
|
5611 |
/**
|
|
|
5612 |
* Equal loudness weights (based on ATH).
|
|
|
5613 |
*/
|
|
|
5614 |
this.eql_w = new_float(Encoder.BLKSIZE / 2);
|
|
|
5615 |
}
|
|
|
5616 |
|
|
|
5617 |
//package mp3;
|
|
|
5618 |
|
|
|
5619 |
/**
|
|
|
5620 |
* Layer III side information.
|
|
|
5621 |
*
|
|
|
5622 |
* @author Ken
|
|
|
5623 |
*
|
|
|
5624 |
*/
|
|
|
5625 |
|
|
|
5626 |
|
|
|
5627 |
|
|
|
5628 |
function ScaleFac(arrL, arrS, arr21, arr12) {
|
|
|
5629 |
|
|
|
5630 |
this.l = new_int(1 + Encoder.SBMAX_l);
|
|
|
5631 |
this.s = new_int(1 + Encoder.SBMAX_s);
|
|
|
5632 |
this.psfb21 = new_int(1 + Encoder.PSFB21);
|
|
|
5633 |
this.psfb12 = new_int(1 + Encoder.PSFB12);
|
|
|
5634 |
var l = this.l;
|
|
|
5635 |
var s = this.s;
|
|
|
5636 |
|
|
|
5637 |
if (arguments.length == 4) {
|
|
|
5638 |
//public ScaleFac(final int[] arrL, final int[] arrS, final int[] arr21,
|
|
|
5639 |
// final int[] arr12) {
|
|
|
5640 |
this.arrL = arguments[0];
|
|
|
5641 |
this.arrS = arguments[1];
|
|
|
5642 |
this.arr21 = arguments[2];
|
|
|
5643 |
this.arr12 = arguments[3];
|
|
|
5644 |
|
|
|
5645 |
System.arraycopy(this.arrL, 0, l, 0, Math.min(this.arrL.length, this.l.length));
|
|
|
5646 |
System.arraycopy(this.arrS, 0, s, 0, Math.min(this.arrS.length, this.s.length));
|
|
|
5647 |
System.arraycopy(this.arr21, 0, this.psfb21, 0, Math.min(this.arr21.length, this.psfb21.length));
|
|
|
5648 |
System.arraycopy(this.arr12, 0, this.psfb12, 0, Math.min(this.arr12.length, this.psfb12.length));
|
|
|
5649 |
}
|
|
|
5650 |
}
|
|
|
5651 |
|
|
|
5652 |
/*
|
|
|
5653 |
* quantize_pvt source file
|
|
|
5654 |
*
|
|
|
5655 |
* Copyright (c) 1999-2002 Takehiro Tominaga
|
|
|
5656 |
* Copyright (c) 2000-2002 Robert Hegemann
|
|
|
5657 |
* Copyright (c) 2001 Naoki Shibata
|
|
|
5658 |
* Copyright (c) 2002-2005 Gabriel Bouvigne
|
|
|
5659 |
*
|
|
|
5660 |
* This library is free software; you can redistribute it and/or
|
|
|
5661 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
5662 |
* License as published by the Free Software Foundation; either
|
|
|
5663 |
* version 2 of the License, or (at your option) any later version.
|
|
|
5664 |
*
|
|
|
5665 |
* This library is distributed in the hope that it will be useful,
|
|
|
5666 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
5667 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
5668 |
* Library General Public License for more details.
|
|
|
5669 |
*
|
|
|
5670 |
* You should have received a copy of the GNU Lesser General Public
|
|
|
5671 |
* License along with this library; if not, write to the
|
|
|
5672 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
5673 |
* Boston, MA 02111-1307, USA.
|
|
|
5674 |
*/
|
|
|
5675 |
|
|
|
5676 |
/* $Id: QuantizePVT.java,v 1.24 2011/05/24 20:48:06 kenchis Exp $ */
|
|
|
5677 |
|
|
|
5678 |
|
|
|
5679 |
QuantizePVT.Q_MAX = (256 + 1);
|
|
|
5680 |
QuantizePVT.Q_MAX2 = 116;
|
|
|
5681 |
QuantizePVT.LARGE_BITS = 100000;
|
|
|
5682 |
QuantizePVT.IXMAX_VAL = 8206;
|
|
|
5683 |
|
|
|
5684 |
function QuantizePVT() {
|
|
|
5685 |
|
|
|
5686 |
var tak = null;
|
|
|
5687 |
var rv = null;
|
|
|
5688 |
var psy = null;
|
|
|
5689 |
|
|
|
5690 |
this.setModules = function (_tk, _rv, _psy) {
|
|
|
5691 |
tak = _tk;
|
|
|
5692 |
rv = _rv;
|
|
|
5693 |
psy = _psy;
|
|
|
5694 |
};
|
|
|
5695 |
|
|
|
5696 |
function POW20(x) {
|
|
|
5697 |
return pow20[x + QuantizePVT.Q_MAX2];
|
|
|
5698 |
}
|
|
|
5699 |
|
|
|
5700 |
this.IPOW20 = function (x) {
|
|
|
5701 |
return ipow20[x];
|
|
|
5702 |
}
|
|
|
5703 |
|
|
|
5704 |
/**
|
|
|
5705 |
* smallest such that 1.0+DBL_EPSILON != 1.0
|
|
|
5706 |
*/
|
|
|
5707 |
var DBL_EPSILON = 2.2204460492503131e-016;
|
|
|
5708 |
|
|
|
5709 |
/**
|
|
|
5710 |
* ix always <= 8191+15. see count_bits()
|
|
|
5711 |
*/
|
|
|
5712 |
var IXMAX_VAL = QuantizePVT.IXMAX_VAL;
|
|
|
5713 |
|
|
|
5714 |
var PRECALC_SIZE = (IXMAX_VAL + 2);
|
|
|
5715 |
|
|
|
5716 |
var Q_MAX = QuantizePVT.Q_MAX;
|
|
|
5717 |
|
|
|
5718 |
|
|
|
5719 |
/**
|
|
|
5720 |
* <CODE>
|
|
|
5721 |
* minimum possible number of
|
|
|
5722 |
* -cod_info.global_gain + ((scalefac[] + (cod_info.preflag ? pretab[sfb] : 0))
|
|
|
5723 |
* << (cod_info.scalefac_scale + 1)) + cod_info.subblock_gain[cod_info.window[sfb]] * 8;
|
|
|
5724 |
*
|
|
|
5725 |
* for long block, 0+((15+3)<<2) = 18*4 = 72
|
|
|
5726 |
* for short block, 0+(15<<2)+7*8 = 15*4+56 = 116
|
|
|
5727 |
* </CODE>
|
|
|
5728 |
*/
|
|
|
5729 |
var Q_MAX2 = QuantizePVT.Q_MAX2;
|
|
|
5730 |
|
|
|
5731 |
var LARGE_BITS = QuantizePVT.LARGE_BITS;
|
|
|
5732 |
|
|
|
5733 |
|
|
|
5734 |
/**
|
|
|
5735 |
* Assuming dynamic range=96dB, this value should be 92
|
|
|
5736 |
*/
|
|
|
5737 |
var NSATHSCALE = 100;
|
|
|
5738 |
|
|
|
5739 |
/**
|
|
|
5740 |
* The following table is used to implement the scalefactor partitioning for
|
|
|
5741 |
* MPEG2 as described in section 2.4.3.2 of the IS. The indexing corresponds
|
|
|
5742 |
* to the way the tables are presented in the IS:
|
|
|
5743 |
*
|
|
|
5744 |
* [table_number][row_in_table][column of nr_of_sfb]
|
|
|
5745 |
*/
|
|
|
5746 |
this.nr_of_sfb_block = [
|
|
|
5747 |
[[6, 5, 5, 5], [9, 9, 9, 9], [6, 9, 9, 9]],
|
|
|
5748 |
[[6, 5, 7, 3], [9, 9, 12, 6], [6, 9, 12, 6]],
|
|
|
5749 |
[[11, 10, 0, 0], [18, 18, 0, 0], [15, 18, 0, 0]],
|
|
|
5750 |
[[7, 7, 7, 0], [12, 12, 12, 0], [6, 15, 12, 0]],
|
|
|
5751 |
[[6, 6, 6, 3], [12, 9, 9, 6], [6, 12, 9, 6]],
|
|
|
5752 |
[[8, 8, 5, 0], [15, 12, 9, 0], [6, 18, 9, 0]]];
|
|
|
5753 |
|
|
|
5754 |
/**
|
|
|
5755 |
* Table B.6: layer3 preemphasis
|
|
|
5756 |
*/
|
|
|
5757 |
var pretab = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
|
|
5758 |
2, 2, 3, 3, 3, 2, 0];
|
|
|
5759 |
this.pretab = pretab;
|
|
|
5760 |
|
|
|
5761 |
/**
|
|
|
5762 |
* Here are MPEG1 Table B.8 and MPEG2 Table B.1 -- Layer III scalefactor
|
|
|
5763 |
* bands. <BR>
|
|
|
5764 |
* Index into this using a method such as:<BR>
|
|
|
5765 |
* idx = fr_ps.header.sampling_frequency + (fr_ps.header.version * 3)
|
|
|
5766 |
*/
|
|
|
5767 |
this.sfBandIndex = [
|
|
|
5768 |
// Table B.2.b: 22.05 kHz
|
|
|
5769 |
new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
|
|
|
5770 |
522, 576],
|
|
|
5771 |
[0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192]
|
|
|
5772 |
, [0, 0, 0, 0, 0, 0, 0] // sfb21 pseudo sub bands
|
|
|
5773 |
, [0, 0, 0, 0, 0, 0, 0] // sfb12 pseudo sub bands
|
|
|
5774 |
),
|
|
|
5775 |
/* Table B.2.c: 24 kHz */ /* docs: 332. mpg123(broken): 330 */
|
|
|
5776 |
new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464,
|
|
|
5777 |
540, 576],
|
|
|
5778 |
[0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192]
|
|
|
5779 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */
|
|
|
5780 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */
|
|
|
5781 |
),
|
|
|
5782 |
/* Table B.2.a: 16 kHz */
|
|
|
5783 |
new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
|
|
|
5784 |
522, 576],
|
|
|
5785 |
[0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192]
|
|
|
5786 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */
|
|
|
5787 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */
|
|
|
5788 |
),
|
|
|
5789 |
/* Table B.8.b: 44.1 kHz */
|
|
|
5790 |
new ScaleFac([0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418,
|
|
|
5791 |
576],
|
|
|
5792 |
[0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192]
|
|
|
5793 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */
|
|
|
5794 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */
|
|
|
5795 |
),
|
|
|
5796 |
/* Table B.8.c: 48 kHz */
|
|
|
5797 |
new ScaleFac([0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384,
|
|
|
5798 |
576],
|
|
|
5799 |
[0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192]
|
|
|
5800 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */
|
|
|
5801 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */
|
|
|
5802 |
),
|
|
|
5803 |
/* Table B.8.a: 32 kHz */
|
|
|
5804 |
new ScaleFac([0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550,
|
|
|
5805 |
576],
|
|
|
5806 |
[0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192]
|
|
|
5807 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */
|
|
|
5808 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */
|
|
|
5809 |
),
|
|
|
5810 |
/* MPEG-2.5 11.025 kHz */
|
|
|
5811 |
new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
|
|
|
5812 |
522, 576],
|
|
|
5813 |
[0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3,
|
|
|
5814 |
402 / 3, 522 / 3, 576 / 3]
|
|
|
5815 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */
|
|
|
5816 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */
|
|
|
5817 |
),
|
|
|
5818 |
/* MPEG-2.5 12 kHz */
|
|
|
5819 |
new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
|
|
|
5820 |
522, 576],
|
|
|
5821 |
[0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3,
|
|
|
5822 |
402 / 3, 522 / 3, 576 / 3]
|
|
|
5823 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */
|
|
|
5824 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */
|
|
|
5825 |
),
|
|
|
5826 |
/* MPEG-2.5 8 kHz */
|
|
|
5827 |
new ScaleFac([0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570,
|
|
|
5828 |
572, 574, 576],
|
|
|
5829 |
[0 / 3, 24 / 3, 48 / 3, 72 / 3, 108 / 3, 156 / 3, 216 / 3, 288 / 3, 372 / 3, 480 / 3, 486 / 3,
|
|
|
5830 |
492 / 3, 498 / 3, 576 / 3]
|
|
|
5831 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */
|
|
|
5832 |
, [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */
|
|
|
5833 |
)
|
|
|
5834 |
];
|
|
|
5835 |
|
|
|
5836 |
var pow20 = new_float(Q_MAX + Q_MAX2 + 1);
|
|
|
5837 |
var ipow20 = new_float(Q_MAX);
|
|
|
5838 |
var pow43 = new_float(PRECALC_SIZE);
|
|
|
5839 |
|
|
|
5840 |
var adj43 = new_float(PRECALC_SIZE);
|
|
|
5841 |
this.adj43 = adj43;
|
|
|
5842 |
|
|
|
5843 |
/**
|
|
|
5844 |
* <PRE>
|
|
|
5845 |
* compute the ATH for each scalefactor band cd range: 0..96db
|
|
|
5846 |
*
|
|
|
5847 |
* Input: 3.3kHz signal 32767 amplitude (3.3kHz is where ATH is smallest =
|
|
|
5848 |
* -5db) longblocks: sfb=12 en0/bw=-11db max_en0 = 1.3db shortblocks: sfb=5
|
|
|
5849 |
* -9db 0db
|
|
|
5850 |
*
|
|
|
5851 |
* Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) longblocks: amp=1
|
|
|
5852 |
* sfb=12 en0/bw=-103 db max_en0 = -92db amp=32767 sfb=12 -12 db -1.4db
|
|
|
5853 |
*
|
|
|
5854 |
* Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) shortblocks: amp=1
|
|
|
5855 |
* sfb=5 en0/bw= -99 -86 amp=32767 sfb=5 -9 db 4db
|
|
|
5856 |
*
|
|
|
5857 |
*
|
|
|
5858 |
* MAX energy of largest wave at 3.3kHz = 1db AVE energy of largest wave at
|
|
|
5859 |
* 3.3kHz = -11db Let's take AVE: -11db = maximum signal in sfb=12. Dynamic
|
|
|
5860 |
* range of CD: 96db. Therefor energy of smallest audible wave in sfb=12 =
|
|
|
5861 |
* -11 - 96 = -107db = ATH at 3.3kHz.
|
|
|
5862 |
*
|
|
|
5863 |
* ATH formula for this wave: -5db. To adjust to LAME scaling, we need ATH =
|
|
|
5864 |
* ATH_formula - 103 (db) ATH = ATH * 2.5e-10 (ener)
|
|
|
5865 |
* </PRE>
|
|
|
5866 |
*/
|
|
|
5867 |
function ATHmdct(gfp, f) {
|
|
|
5868 |
var ath = psy.ATHformula(f, gfp);
|
|
|
5869 |
|
|
|
5870 |
ath -= NSATHSCALE;
|
|
|
5871 |
|
|
|
5872 |
/* modify the MDCT scaling for the ATH and convert to energy */
|
|
|
5873 |
ath = Math.pow(10.0, ath / 10.0 + gfp.ATHlower);
|
|
|
5874 |
return ath;
|
|
|
5875 |
}
|
|
|
5876 |
|
|
|
5877 |
function compute_ath(gfp) {
|
|
|
5878 |
var ATH_l = gfp.internal_flags.ATH.l;
|
|
|
5879 |
var ATH_psfb21 = gfp.internal_flags.ATH.psfb21;
|
|
|
5880 |
var ATH_s = gfp.internal_flags.ATH.s;
|
|
|
5881 |
var ATH_psfb12 = gfp.internal_flags.ATH.psfb12;
|
|
|
5882 |
var gfc = gfp.internal_flags;
|
|
|
5883 |
var samp_freq = gfp.out_samplerate;
|
|
|
5884 |
|
|
|
5885 |
for (var sfb = 0; sfb < Encoder.SBMAX_l; sfb++) {
|
|
|
5886 |
var start = gfc.scalefac_band.l[sfb];
|
|
|
5887 |
var end = gfc.scalefac_band.l[sfb + 1];
|
|
|
5888 |
ATH_l[sfb] = Float.MAX_VALUE;
|
|
|
5889 |
for (var i = start; i < end; i++) {
|
|
|
5890 |
var freq = i * samp_freq / (2 * 576);
|
|
|
5891 |
var ATH_f = ATHmdct(gfp, freq);
|
|
|
5892 |
/* freq in kHz */
|
|
|
5893 |
ATH_l[sfb] = Math.min(ATH_l[sfb], ATH_f);
|
|
|
5894 |
}
|
|
|
5895 |
}
|
|
|
5896 |
|
|
|
5897 |
for (var sfb = 0; sfb < Encoder.PSFB21; sfb++) {
|
|
|
5898 |
var start = gfc.scalefac_band.psfb21[sfb];
|
|
|
5899 |
var end = gfc.scalefac_band.psfb21[sfb + 1];
|
|
|
5900 |
ATH_psfb21[sfb] = Float.MAX_VALUE;
|
|
|
5901 |
for (var i = start; i < end; i++) {
|
|
|
5902 |
var freq = i * samp_freq / (2 * 576);
|
|
|
5903 |
var ATH_f = ATHmdct(gfp, freq);
|
|
|
5904 |
/* freq in kHz */
|
|
|
5905 |
ATH_psfb21[sfb] = Math.min(ATH_psfb21[sfb], ATH_f);
|
|
|
5906 |
}
|
|
|
5907 |
}
|
|
|
5908 |
|
|
|
5909 |
for (var sfb = 0; sfb < Encoder.SBMAX_s; sfb++) {
|
|
|
5910 |
var start = gfc.scalefac_band.s[sfb];
|
|
|
5911 |
var end = gfc.scalefac_band.s[sfb + 1];
|
|
|
5912 |
ATH_s[sfb] = Float.MAX_VALUE;
|
|
|
5913 |
for (var i = start; i < end; i++) {
|
|
|
5914 |
var freq = i * samp_freq / (2 * 192);
|
|
|
5915 |
var ATH_f = ATHmdct(gfp, freq);
|
|
|
5916 |
/* freq in kHz */
|
|
|
5917 |
ATH_s[sfb] = Math.min(ATH_s[sfb], ATH_f);
|
|
|
5918 |
}
|
|
|
5919 |
ATH_s[sfb] *= (gfc.scalefac_band.s[sfb + 1] - gfc.scalefac_band.s[sfb]);
|
|
|
5920 |
}
|
|
|
5921 |
|
|
|
5922 |
for (var sfb = 0; sfb < Encoder.PSFB12; sfb++) {
|
|
|
5923 |
var start = gfc.scalefac_band.psfb12[sfb];
|
|
|
5924 |
var end = gfc.scalefac_band.psfb12[sfb + 1];
|
|
|
5925 |
ATH_psfb12[sfb] = Float.MAX_VALUE;
|
|
|
5926 |
for (var i = start; i < end; i++) {
|
|
|
5927 |
var freq = i * samp_freq / (2 * 192);
|
|
|
5928 |
var ATH_f = ATHmdct(gfp, freq);
|
|
|
5929 |
/* freq in kHz */
|
|
|
5930 |
ATH_psfb12[sfb] = Math.min(ATH_psfb12[sfb], ATH_f);
|
|
|
5931 |
}
|
|
|
5932 |
/* not sure about the following */
|
|
|
5933 |
ATH_psfb12[sfb] *= (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]);
|
|
|
5934 |
}
|
|
|
5935 |
|
|
|
5936 |
/*
|
|
|
5937 |
* no-ATH mode: reduce ATH to -200 dB
|
|
|
5938 |
*/
|
|
|
5939 |
if (gfp.noATH) {
|
|
|
5940 |
for (var sfb = 0; sfb < Encoder.SBMAX_l; sfb++) {
|
|
|
5941 |
ATH_l[sfb] = 1E-20;
|
|
|
5942 |
}
|
|
|
5943 |
for (var sfb = 0; sfb < Encoder.PSFB21; sfb++) {
|
|
|
5944 |
ATH_psfb21[sfb] = 1E-20;
|
|
|
5945 |
}
|
|
|
5946 |
for (var sfb = 0; sfb < Encoder.SBMAX_s; sfb++) {
|
|
|
5947 |
ATH_s[sfb] = 1E-20;
|
|
|
5948 |
}
|
|
|
5949 |
for (var sfb = 0; sfb < Encoder.PSFB12; sfb++) {
|
|
|
5950 |
ATH_psfb12[sfb] = 1E-20;
|
|
|
5951 |
}
|
|
|
5952 |
}
|
|
|
5953 |
|
|
|
5954 |
/*
|
|
|
5955 |
* work in progress, don't rely on it too much
|
|
|
5956 |
*/
|
|
|
5957 |
gfc.ATH.floor = 10. * Math.log10(ATHmdct(gfp, -1.));
|
|
|
5958 |
}
|
|
|
5959 |
|
|
|
5960 |
/**
|
|
|
5961 |
* initialization for iteration_loop
|
|
|
5962 |
*/
|
|
|
5963 |
this.iteration_init = function (gfp) {
|
|
|
5964 |
var gfc = gfp.internal_flags;
|
|
|
5965 |
var l3_side = gfc.l3_side;
|
|
|
5966 |
var i;
|
|
|
5967 |
|
|
|
5968 |
if (gfc.iteration_init_init == 0) {
|
|
|
5969 |
gfc.iteration_init_init = 1;
|
|
|
5970 |
|
|
|
5971 |
l3_side.main_data_begin = 0;
|
|
|
5972 |
compute_ath(gfp);
|
|
|
5973 |
|
|
|
5974 |
pow43[0] = 0.0;
|
|
|
5975 |
for (i = 1; i < PRECALC_SIZE; i++)
|
|
|
5976 |
pow43[i] = Math.pow(i, 4.0 / 3.0);
|
|
|
5977 |
|
|
|
5978 |
for (i = 0; i < PRECALC_SIZE - 1; i++)
|
|
|
5979 |
adj43[i] = ((i + 1) - Math.pow(
|
|
|
5980 |
0.5 * (pow43[i] + pow43[i + 1]), 0.75));
|
|
|
5981 |
adj43[i] = 0.5;
|
|
|
5982 |
|
|
|
5983 |
for (i = 0; i < Q_MAX; i++)
|
|
|
5984 |
ipow20[i] = Math.pow(2.0, (i - 210) * -0.1875);
|
|
|
5985 |
for (i = 0; i <= Q_MAX + Q_MAX2; i++)
|
|
|
5986 |
pow20[i] = Math.pow(2.0, (i - 210 - Q_MAX2) * 0.25);
|
|
|
5987 |
|
|
|
5988 |
tak.huffman_init(gfc);
|
|
|
5989 |
|
|
|
5990 |
{
|
|
|
5991 |
var bass, alto, treble, sfb21;
|
|
|
5992 |
|
|
|
5993 |
i = (gfp.exp_nspsytune >> 2) & 63;
|
|
|
5994 |
if (i >= 32)
|
|
|
5995 |
i -= 64;
|
|
|
5996 |
bass = Math.pow(10, i / 4.0 / 10.0);
|
|
|
5997 |
|
|
|
5998 |
i = (gfp.exp_nspsytune >> 8) & 63;
|
|
|
5999 |
if (i >= 32)
|
|
|
6000 |
i -= 64;
|
|
|
6001 |
alto = Math.pow(10, i / 4.0 / 10.0);
|
|
|
6002 |
|
|
|
6003 |
i = (gfp.exp_nspsytune >> 14) & 63;
|
|
|
6004 |
if (i >= 32)
|
|
|
6005 |
i -= 64;
|
|
|
6006 |
treble = Math.pow(10, i / 4.0 / 10.0);
|
|
|
6007 |
|
|
|
6008 |
/*
|
|
|
6009 |
* to be compatible with Naoki's original code, the next 6 bits
|
|
|
6010 |
* define only the amount of changing treble for sfb21
|
|
|
6011 |
*/
|
|
|
6012 |
i = (gfp.exp_nspsytune >> 20) & 63;
|
|
|
6013 |
if (i >= 32)
|
|
|
6014 |
i -= 64;
|
|
|
6015 |
sfb21 = treble * Math.pow(10, i / 4.0 / 10.0);
|
|
|
6016 |
for (i = 0; i < Encoder.SBMAX_l; i++) {
|
|
|
6017 |
var f;
|
|
|
6018 |
if (i <= 6)
|
|
|
6019 |
f = bass;
|
|
|
6020 |
else if (i <= 13)
|
|
|
6021 |
f = alto;
|
|
|
6022 |
else if (i <= 20)
|
|
|
6023 |
f = treble;
|
|
|
6024 |
else
|
|
|
6025 |
f = sfb21;
|
|
|
6026 |
|
|
|
6027 |
gfc.nsPsy.longfact[i] = f;
|
|
|
6028 |
}
|
|
|
6029 |
for (i = 0; i < Encoder.SBMAX_s; i++) {
|
|
|
6030 |
var f;
|
|
|
6031 |
if (i <= 5)
|
|
|
6032 |
f = bass;
|
|
|
6033 |
else if (i <= 10)
|
|
|
6034 |
f = alto;
|
|
|
6035 |
else if (i <= 11)
|
|
|
6036 |
f = treble;
|
|
|
6037 |
else
|
|
|
6038 |
f = sfb21;
|
|
|
6039 |
|
|
|
6040 |
gfc.nsPsy.shortfact[i] = f;
|
|
|
6041 |
}
|
|
|
6042 |
}
|
|
|
6043 |
}
|
|
|
6044 |
}
|
|
|
6045 |
|
|
|
6046 |
/**
|
|
|
6047 |
* allocate bits among 2 channels based on PE<BR>
|
|
|
6048 |
* mt 6/99<BR>
|
|
|
6049 |
* bugfixes rh 8/01: often allocated more than the allowed 4095 bits
|
|
|
6050 |
*/
|
|
|
6051 |
this.on_pe = function (gfp, pe,
|
|
|
6052 |
targ_bits, mean_bits, gr, cbr) {
|
|
|
6053 |
var gfc = gfp.internal_flags;
|
|
|
6054 |
var tbits = 0, bits;
|
|
|
6055 |
var add_bits = new_int(2);
|
|
|
6056 |
var ch;
|
|
|
6057 |
|
|
|
6058 |
/* allocate targ_bits for granule */
|
|
|
6059 |
var mb = new MeanBits(tbits);
|
|
|
6060 |
var extra_bits = rv.ResvMaxBits(gfp, mean_bits, mb, cbr);
|
|
|
6061 |
tbits = mb.bits;
|
|
|
6062 |
/* maximum allowed bits for this granule */
|
|
|
6063 |
var max_bits = tbits + extra_bits;
|
|
|
6064 |
if (max_bits > LameInternalFlags.MAX_BITS_PER_GRANULE) {
|
|
|
6065 |
// hard limit per granule
|
|
|
6066 |
max_bits = LameInternalFlags.MAX_BITS_PER_GRANULE;
|
|
|
6067 |
}
|
|
|
6068 |
for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch) {
|
|
|
6069 |
/******************************************************************
|
|
|
6070 |
* allocate bits for each channel
|
|
|
6071 |
******************************************************************/
|
|
|
6072 |
targ_bits[ch] = Math.min(LameInternalFlags.MAX_BITS_PER_CHANNEL,
|
|
|
6073 |
tbits / gfc.channels_out);
|
|
|
6074 |
|
|
|
6075 |
add_bits[ch] = 0 | (targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch]);
|
|
|
6076 |
|
|
|
6077 |
/* at most increase bits by 1.5*average */
|
|
|
6078 |
if (add_bits[ch] > mean_bits * 3 / 4)
|
|
|
6079 |
add_bits[ch] = mean_bits * 3 / 4;
|
|
|
6080 |
if (add_bits[ch] < 0)
|
|
|
6081 |
add_bits[ch] = 0;
|
|
|
6082 |
|
|
|
6083 |
if (add_bits[ch] + targ_bits[ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL)
|
|
|
6084 |
add_bits[ch] = Math.max(0,
|
|
|
6085 |
LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[ch]);
|
|
|
6086 |
|
|
|
6087 |
bits += add_bits[ch];
|
|
|
6088 |
}
|
|
|
6089 |
if (bits > extra_bits) {
|
|
|
6090 |
for (ch = 0; ch < gfc.channels_out; ++ch) {
|
|
|
6091 |
add_bits[ch] = extra_bits * add_bits[ch] / bits;
|
|
|
6092 |
}
|
|
|
6093 |
}
|
|
|
6094 |
|
|
|
6095 |
for (ch = 0; ch < gfc.channels_out; ++ch) {
|
|
|
6096 |
targ_bits[ch] += add_bits[ch];
|
|
|
6097 |
extra_bits -= add_bits[ch];
|
|
|
6098 |
}
|
|
|
6099 |
|
|
|
6100 |
for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch) {
|
|
|
6101 |
bits += targ_bits[ch];
|
|
|
6102 |
}
|
|
|
6103 |
if (bits > LameInternalFlags.MAX_BITS_PER_GRANULE) {
|
|
|
6104 |
var sum = 0;
|
|
|
6105 |
for (ch = 0; ch < gfc.channels_out; ++ch) {
|
|
|
6106 |
targ_bits[ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE;
|
|
|
6107 |
targ_bits[ch] /= bits;
|
|
|
6108 |
sum += targ_bits[ch];
|
|
|
6109 |
}
|
|
|
6110 |
}
|
|
|
6111 |
|
|
|
6112 |
return max_bits;
|
|
|
6113 |
}
|
|
|
6114 |
|
|
|
6115 |
this.reduce_side = function (targ_bits, ms_ener_ratio, mean_bits, max_bits) {
|
|
|
6116 |
|
|
|
6117 |
/*
|
|
|
6118 |
* ms_ener_ratio = 0: allocate 66/33 mid/side fac=.33 ms_ener_ratio =.5:
|
|
|
6119 |
* allocate 50/50 mid/side fac= 0
|
|
|
6120 |
*/
|
|
|
6121 |
/* 75/25 split is fac=.5 */
|
|
|
6122 |
var fac = .33 * (.5 - ms_ener_ratio) / .5;
|
|
|
6123 |
if (fac < 0)
|
|
|
6124 |
fac = 0;
|
|
|
6125 |
if (fac > .5)
|
|
|
6126 |
fac = .5;
|
|
|
6127 |
|
|
|
6128 |
/* number of bits to move from side channel to mid channel */
|
|
|
6129 |
/* move_bits = fac*targ_bits[1]; */
|
|
|
6130 |
var move_bits = 0 | (fac * .5 * (targ_bits[0] + targ_bits[1]));
|
|
|
6131 |
|
|
|
6132 |
if (move_bits > LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[0]) {
|
|
|
6133 |
move_bits = LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[0];
|
|
|
6134 |
}
|
|
|
6135 |
if (move_bits < 0)
|
|
|
6136 |
move_bits = 0;
|
|
|
6137 |
|
|
|
6138 |
if (targ_bits[1] >= 125) {
|
|
|
6139 |
/* dont reduce side channel below 125 bits */
|
|
|
6140 |
if (targ_bits[1] - move_bits > 125) {
|
|
|
6141 |
|
|
|
6142 |
/* if mid channel already has 2x more than average, dont bother */
|
|
|
6143 |
/* mean_bits = bits per granule (for both channels) */
|
|
|
6144 |
if (targ_bits[0] < mean_bits)
|
|
|
6145 |
targ_bits[0] += move_bits;
|
|
|
6146 |
targ_bits[1] -= move_bits;
|
|
|
6147 |
} else {
|
|
|
6148 |
targ_bits[0] += targ_bits[1] - 125;
|
|
|
6149 |
targ_bits[1] = 125;
|
|
|
6150 |
}
|
|
|
6151 |
}
|
|
|
6152 |
|
|
|
6153 |
move_bits = targ_bits[0] + targ_bits[1];
|
|
|
6154 |
if (move_bits > max_bits) {
|
|
|
6155 |
targ_bits[0] = (max_bits * targ_bits[0]) / move_bits;
|
|
|
6156 |
targ_bits[1] = (max_bits * targ_bits[1]) / move_bits;
|
|
|
6157 |
}
|
|
|
6158 |
};
|
|
|
6159 |
|
|
|
6160 |
/**
|
|
|
6161 |
* Robert Hegemann 2001-04-27:
|
|
|
6162 |
* this adjusts the ATH, keeping the original noise floor
|
|
|
6163 |
* affects the higher frequencies more than the lower ones
|
|
|
6164 |
*/
|
|
|
6165 |
this.athAdjust = function (a, x, athFloor) {
|
|
|
6166 |
/*
|
|
|
6167 |
* work in progress
|
|
|
6168 |
*/
|
|
|
6169 |
var o = 90.30873362;
|
|
|
6170 |
var p = 94.82444863;
|
|
|
6171 |
var u = Util.FAST_LOG10_X(x, 10.0);
|
|
|
6172 |
var v = a * a;
|
|
|
6173 |
var w = 0.0;
|
|
|
6174 |
u -= athFloor;
|
|
|
6175 |
/* undo scaling */
|
|
|
6176 |
if (v > 1E-20)
|
|
|
6177 |
w = 1. + Util.FAST_LOG10_X(v, 10.0 / o);
|
|
|
6178 |
if (w < 0)
|
|
|
6179 |
w = 0.;
|
|
|
6180 |
u *= w;
|
|
|
6181 |
u += athFloor + o - p;
|
|
|
6182 |
/* redo scaling */
|
|
|
6183 |
|
|
|
6184 |
return Math.pow(10., 0.1 * u);
|
|
|
6185 |
};
|
|
|
6186 |
|
|
|
6187 |
/**
|
|
|
6188 |
* Calculate the allowed distortion for each scalefactor band, as determined
|
|
|
6189 |
* by the psychoacoustic model. xmin(sb) = ratio(sb) * en(sb) / bw(sb)
|
|
|
6190 |
*
|
|
|
6191 |
* returns number of sfb's with energy > ATH
|
|
|
6192 |
*/
|
|
|
6193 |
this.calc_xmin = function (gfp, ratio, cod_info, pxmin) {
|
|
|
6194 |
var pxminPos = 0;
|
|
|
6195 |
var gfc = gfp.internal_flags;
|
|
|
6196 |
var gsfb, j = 0, ath_over = 0;
|
|
|
6197 |
var ATH = gfc.ATH;
|
|
|
6198 |
var xr = cod_info.xr;
|
|
|
6199 |
var enable_athaa_fix = (gfp.VBR == VbrMode.vbr_mtrh) ? 1 : 0;
|
|
|
6200 |
var masking_lower = gfc.masking_lower;
|
|
|
6201 |
|
|
|
6202 |
if (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) {
|
|
|
6203 |
/* was already done in PSY-Model */
|
|
|
6204 |
masking_lower = 1.0;
|
|
|
6205 |
}
|
|
|
6206 |
|
|
|
6207 |
for (gsfb = 0; gsfb < cod_info.psy_lmax; gsfb++) {
|
|
|
6208 |
var en0, xmin;
|
|
|
6209 |
var rh1, rh2;
|
|
|
6210 |
var width, l;
|
|
|
6211 |
|
|
|
6212 |
if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh)
|
|
|
6213 |
xmin = athAdjust(ATH.adjust, ATH.l[gsfb], ATH.floor);
|
|
|
6214 |
else
|
|
|
6215 |
xmin = ATH.adjust * ATH.l[gsfb];
|
|
|
6216 |
|
|
|
6217 |
width = cod_info.width[gsfb];
|
|
|
6218 |
rh1 = xmin / width;
|
|
|
6219 |
rh2 = DBL_EPSILON;
|
|
|
6220 |
l = width >> 1;
|
|
|
6221 |
en0 = 0.0;
|
|
|
6222 |
do {
|
|
|
6223 |
var xa, xb;
|
|
|
6224 |
xa = xr[j] * xr[j];
|
|
|
6225 |
en0 += xa;
|
|
|
6226 |
rh2 += (xa < rh1) ? xa : rh1;
|
|
|
6227 |
j++;
|
|
|
6228 |
xb = xr[j] * xr[j];
|
|
|
6229 |
en0 += xb;
|
|
|
6230 |
rh2 += (xb < rh1) ? xb : rh1;
|
|
|
6231 |
j++;
|
|
|
6232 |
} while (--l > 0);
|
|
|
6233 |
if (en0 > xmin)
|
|
|
6234 |
ath_over++;
|
|
|
6235 |
|
|
|
6236 |
if (gsfb == Encoder.SBPSY_l) {
|
|
|
6237 |
var x = xmin * gfc.nsPsy.longfact[gsfb];
|
|
|
6238 |
if (rh2 < x) {
|
|
|
6239 |
rh2 = x;
|
|
|
6240 |
}
|
|
|
6241 |
}
|
|
|
6242 |
if (enable_athaa_fix != 0) {
|
|
|
6243 |
xmin = rh2;
|
|
|
6244 |
}
|
|
|
6245 |
if (!gfp.ATHonly) {
|
|
|
6246 |
var e = ratio.en.l[gsfb];
|
|
|
6247 |
if (e > 0.0) {
|
|
|
6248 |
var x;
|
|
|
6249 |
x = en0 * ratio.thm.l[gsfb] * masking_lower / e;
|
|
|
6250 |
if (enable_athaa_fix != 0)
|
|
|
6251 |
x *= gfc.nsPsy.longfact[gsfb];
|
|
|
6252 |
if (xmin < x)
|
|
|
6253 |
xmin = x;
|
|
|
6254 |
}
|
|
|
6255 |
}
|
|
|
6256 |
if (enable_athaa_fix != 0)
|
|
|
6257 |
pxmin[pxminPos++] = xmin;
|
|
|
6258 |
else
|
|
|
6259 |
pxmin[pxminPos++] = xmin * gfc.nsPsy.longfact[gsfb];
|
|
|
6260 |
}
|
|
|
6261 |
/* end of long block loop */
|
|
|
6262 |
|
|
|
6263 |
/* use this function to determine the highest non-zero coeff */
|
|
|
6264 |
var max_nonzero = 575;
|
|
|
6265 |
if (cod_info.block_type != Encoder.SHORT_TYPE) {
|
|
|
6266 |
// NORM, START or STOP type, but not SHORT
|
|
|
6267 |
var k = 576;
|
|
|
6268 |
while (k-- != 0 && BitStream.EQ(xr[k], 0)) {
|
|
|
6269 |
max_nonzero = k;
|
|
|
6270 |
}
|
|
|
6271 |
}
|
|
|
6272 |
cod_info.max_nonzero_coeff = max_nonzero;
|
|
|
6273 |
|
|
|
6274 |
for (var sfb = cod_info.sfb_smin; gsfb < cod_info.psymax; sfb++, gsfb += 3) {
|
|
|
6275 |
var width, b;
|
|
|
6276 |
var tmpATH;
|
|
|
6277 |
if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh)
|
|
|
6278 |
tmpATH = athAdjust(ATH.adjust, ATH.s[sfb], ATH.floor);
|
|
|
6279 |
else
|
|
|
6280 |
tmpATH = ATH.adjust * ATH.s[sfb];
|
|
|
6281 |
|
|
|
6282 |
width = cod_info.width[gsfb];
|
|
|
6283 |
for (b = 0; b < 3; b++) {
|
|
|
6284 |
var en0 = 0.0, xmin;
|
|
|
6285 |
var rh1, rh2;
|
|
|
6286 |
var l = width >> 1;
|
|
|
6287 |
|
|
|
6288 |
rh1 = tmpATH / width;
|
|
|
6289 |
rh2 = DBL_EPSILON;
|
|
|
6290 |
do {
|
|
|
6291 |
var xa, xb;
|
|
|
6292 |
xa = xr[j] * xr[j];
|
|
|
6293 |
en0 += xa;
|
|
|
6294 |
rh2 += (xa < rh1) ? xa : rh1;
|
|
|
6295 |
j++;
|
|
|
6296 |
xb = xr[j] * xr[j];
|
|
|
6297 |
en0 += xb;
|
|
|
6298 |
rh2 += (xb < rh1) ? xb : rh1;
|
|
|
6299 |
j++;
|
|
|
6300 |
} while (--l > 0);
|
|
|
6301 |
if (en0 > tmpATH)
|
|
|
6302 |
ath_over++;
|
|
|
6303 |
if (sfb == Encoder.SBPSY_s) {
|
|
|
6304 |
var x = tmpATH * gfc.nsPsy.shortfact[sfb];
|
|
|
6305 |
if (rh2 < x) {
|
|
|
6306 |
rh2 = x;
|
|
|
6307 |
}
|
|
|
6308 |
}
|
|
|
6309 |
if (enable_athaa_fix != 0)
|
|
|
6310 |
xmin = rh2;
|
|
|
6311 |
else
|
|
|
6312 |
xmin = tmpATH;
|
|
|
6313 |
|
|
|
6314 |
if (!gfp.ATHonly && !gfp.ATHshort) {
|
|
|
6315 |
var e = ratio.en.s[sfb][b];
|
|
|
6316 |
if (e > 0.0) {
|
|
|
6317 |
var x;
|
|
|
6318 |
x = en0 * ratio.thm.s[sfb][b] * masking_lower / e;
|
|
|
6319 |
if (enable_athaa_fix != 0)
|
|
|
6320 |
x *= gfc.nsPsy.shortfact[sfb];
|
|
|
6321 |
if (xmin < x)
|
|
|
6322 |
xmin = x;
|
|
|
6323 |
}
|
|
|
6324 |
}
|
|
|
6325 |
if (enable_athaa_fix != 0)
|
|
|
6326 |
pxmin[pxminPos++] = xmin;
|
|
|
6327 |
else
|
|
|
6328 |
pxmin[pxminPos++] = xmin * gfc.nsPsy.shortfact[sfb];
|
|
|
6329 |
}
|
|
|
6330 |
/* b */
|
|
|
6331 |
if (gfp.useTemporal) {
|
|
|
6332 |
if (pxmin[pxminPos - 3] > pxmin[pxminPos - 3 + 1])
|
|
|
6333 |
pxmin[pxminPos - 3 + 1] += (pxmin[pxminPos - 3] - pxmin[pxminPos - 3 + 1])
|
|
|
6334 |
* gfc.decay;
|
|
|
6335 |
if (pxmin[pxminPos - 3 + 1] > pxmin[pxminPos - 3 + 2])
|
|
|
6336 |
pxmin[pxminPos - 3 + 2] += (pxmin[pxminPos - 3 + 1] - pxmin[pxminPos - 3 + 2])
|
|
|
6337 |
* gfc.decay;
|
|
|
6338 |
}
|
|
|
6339 |
}
|
|
|
6340 |
/* end of short block sfb loop */
|
|
|
6341 |
|
|
|
6342 |
return ath_over;
|
|
|
6343 |
};
|
|
|
6344 |
|
|
|
6345 |
function StartLine(j) {
|
|
|
6346 |
this.s = j;
|
|
|
6347 |
}
|
|
|
6348 |
|
|
|
6349 |
this.calc_noise_core = function (cod_info, startline, l, step) {
|
|
|
6350 |
var noise = 0;
|
|
|
6351 |
var j = startline.s;
|
|
|
6352 |
var ix = cod_info.l3_enc;
|
|
|
6353 |
|
|
|
6354 |
if (j > cod_info.count1) {
|
|
|
6355 |
while ((l--) != 0) {
|
|
|
6356 |
var temp;
|
|
|
6357 |
temp = cod_info.xr[j];
|
|
|
6358 |
j++;
|
|
|
6359 |
noise += temp * temp;
|
|
|
6360 |
temp = cod_info.xr[j];
|
|
|
6361 |
j++;
|
|
|
6362 |
noise += temp * temp;
|
|
|
6363 |
}
|
|
|
6364 |
} else if (j > cod_info.big_values) {
|
|
|
6365 |
var ix01 = new_float(2);
|
|
|
6366 |
ix01[0] = 0;
|
|
|
6367 |
ix01[1] = step;
|
|
|
6368 |
while ((l--) != 0) {
|
|
|
6369 |
var temp;
|
|
|
6370 |
temp = Math.abs(cod_info.xr[j]) - ix01[ix[j]];
|
|
|
6371 |
j++;
|
|
|
6372 |
noise += temp * temp;
|
|
|
6373 |
temp = Math.abs(cod_info.xr[j]) - ix01[ix[j]];
|
|
|
6374 |
j++;
|
|
|
6375 |
noise += temp * temp;
|
|
|
6376 |
}
|
|
|
6377 |
} else {
|
|
|
6378 |
while ((l--) != 0) {
|
|
|
6379 |
var temp;
|
|
|
6380 |
temp = Math.abs(cod_info.xr[j]) - pow43[ix[j]] * step;
|
|
|
6381 |
j++;
|
|
|
6382 |
noise += temp * temp;
|
|
|
6383 |
temp = Math.abs(cod_info.xr[j]) - pow43[ix[j]] * step;
|
|
|
6384 |
j++;
|
|
|
6385 |
noise += temp * temp;
|
|
|
6386 |
}
|
|
|
6387 |
}
|
|
|
6388 |
|
|
|
6389 |
startline.s = j;
|
|
|
6390 |
return noise;
|
|
|
6391 |
}
|
|
|
6392 |
|
|
|
6393 |
/**
|
|
|
6394 |
* <PRE>
|
|
|
6395 |
* -oo dB => -1.00
|
|
|
6396 |
* - 6 dB => -0.97
|
|
|
6397 |
* - 3 dB => -0.80
|
|
|
6398 |
* - 2 dB => -0.64
|
|
|
6399 |
* - 1 dB => -0.38
|
|
|
6400 |
* 0 dB => 0.00
|
|
|
6401 |
* + 1 dB => +0.49
|
|
|
6402 |
* + 2 dB => +1.06
|
|
|
6403 |
* + 3 dB => +1.68
|
|
|
6404 |
* + 6 dB => +3.69
|
|
|
6405 |
* +10 dB => +6.45
|
|
|
6406 |
* </PRE>
|
|
|
6407 |
*/
|
|
|
6408 |
this.calc_noise = function (cod_info, l3_xmin, distort, res, prev_noise) {
|
|
|
6409 |
var distortPos = 0;
|
|
|
6410 |
var l3_xminPos = 0;
|
|
|
6411 |
var sfb, l, over = 0;
|
|
|
6412 |
var over_noise_db = 0;
|
|
|
6413 |
/* 0 dB relative to masking */
|
|
|
6414 |
var tot_noise_db = 0;
|
|
|
6415 |
/* -200 dB relative to masking */
|
|
|
6416 |
var max_noise = -20.0;
|
|
|
6417 |
var j = 0;
|
|
|
6418 |
var scalefac = cod_info.scalefac;
|
|
|
6419 |
var scalefacPos = 0;
|
|
|
6420 |
|
|
|
6421 |
res.over_SSD = 0;
|
|
|
6422 |
|
|
|
6423 |
for (sfb = 0; sfb < cod_info.psymax; sfb++) {
|
|
|
6424 |
var s = cod_info.global_gain
|
|
|
6425 |
- (((scalefac[scalefacPos++]) + (cod_info.preflag != 0 ? pretab[sfb]
|
|
|
6426 |
: 0)) << (cod_info.scalefac_scale + 1))
|
|
|
6427 |
- cod_info.subblock_gain[cod_info.window[sfb]] * 8;
|
|
|
6428 |
var noise = 0.0;
|
|
|
6429 |
|
|
|
6430 |
if (prev_noise != null && (prev_noise.step[sfb] == s)) {
|
|
|
6431 |
|
|
|
6432 |
/* use previously computed values */
|
|
|
6433 |
noise = prev_noise.noise[sfb];
|
|
|
6434 |
j += cod_info.width[sfb];
|
|
|
6435 |
distort[distortPos++] = noise / l3_xmin[l3_xminPos++];
|
|
|
6436 |
|
|
|
6437 |
noise = prev_noise.noise_log[sfb];
|
|
|
6438 |
|
|
|
6439 |
} else {
|
|
|
6440 |
var step = POW20(s);
|
|
|
6441 |
l = cod_info.width[sfb] >> 1;
|
|
|
6442 |
|
|
|
6443 |
if ((j + cod_info.width[sfb]) > cod_info.max_nonzero_coeff) {
|
|
|
6444 |
var usefullsize;
|
|
|
6445 |
usefullsize = cod_info.max_nonzero_coeff - j + 1;
|
|
|
6446 |
|
|
|
6447 |
if (usefullsize > 0)
|
|
|
6448 |
l = usefullsize >> 1;
|
|
|
6449 |
else
|
|
|
6450 |
l = 0;
|
|
|
6451 |
}
|
|
|
6452 |
|
|
|
6453 |
var sl = new StartLine(j);
|
|
|
6454 |
noise = this.calc_noise_core(cod_info, sl, l, step);
|
|
|
6455 |
j = sl.s;
|
|
|
6456 |
|
|
|
6457 |
if (prev_noise != null) {
|
|
|
6458 |
/* save noise values */
|
|
|
6459 |
prev_noise.step[sfb] = s;
|
|
|
6460 |
prev_noise.noise[sfb] = noise;
|
|
|
6461 |
}
|
|
|
6462 |
|
|
|
6463 |
noise = distort[distortPos++] = noise / l3_xmin[l3_xminPos++];
|
|
|
6464 |
|
|
|
6465 |
/* multiplying here is adding in dB, but can overflow */
|
|
|
6466 |
noise = Util.FAST_LOG10(Math.max(noise, 1E-20));
|
|
|
6467 |
|
|
|
6468 |
if (prev_noise != null) {
|
|
|
6469 |
/* save noise values */
|
|
|
6470 |
prev_noise.noise_log[sfb] = noise;
|
|
|
6471 |
}
|
|
|
6472 |
}
|
|
|
6473 |
|
|
|
6474 |
if (prev_noise != null) {
|
|
|
6475 |
/* save noise values */
|
|
|
6476 |
prev_noise.global_gain = cod_info.global_gain;
|
|
|
6477 |
}
|
|
|
6478 |
|
|
|
6479 |
tot_noise_db += noise;
|
|
|
6480 |
|
|
|
6481 |
if (noise > 0.0) {
|
|
|
6482 |
var tmp;
|
|
|
6483 |
|
|
|
6484 |
tmp = Math.max(0 | (noise * 10 + .5), 1);
|
|
|
6485 |
res.over_SSD += tmp * tmp;
|
|
|
6486 |
|
|
|
6487 |
over++;
|
|
|
6488 |
/* multiplying here is adding in dB -but can overflow */
|
|
|
6489 |
/* over_noise *= noise; */
|
|
|
6490 |
over_noise_db += noise;
|
|
|
6491 |
}
|
|
|
6492 |
max_noise = Math.max(max_noise, noise);
|
|
|
6493 |
|
|
|
6494 |
}
|
|
|
6495 |
|
|
|
6496 |
res.over_count = over;
|
|
|
6497 |
res.tot_noise = tot_noise_db;
|
|
|
6498 |
res.over_noise = over_noise_db;
|
|
|
6499 |
res.max_noise = max_noise;
|
|
|
6500 |
|
|
|
6501 |
return over;
|
|
|
6502 |
}
|
|
|
6503 |
|
|
|
6504 |
/**
|
|
|
6505 |
* updates plotting data
|
|
|
6506 |
*
|
|
|
6507 |
* Mark Taylor 2000-??-??
|
|
|
6508 |
*
|
|
|
6509 |
* Robert Hegemann: moved noise/distortion calc into it
|
|
|
6510 |
*/
|
|
|
6511 |
this.set_pinfo = function (gfp, cod_info, ratio, gr, ch) {
|
|
|
6512 |
var gfc = gfp.internal_flags;
|
|
|
6513 |
var sfb, sfb2;
|
|
|
6514 |
var l;
|
|
|
6515 |
var en0, en1;
|
|
|
6516 |
var ifqstep = (cod_info.scalefac_scale == 0) ? .5 : 1.0;
|
|
|
6517 |
var scalefac = cod_info.scalefac;
|
|
|
6518 |
|
|
|
6519 |
var l3_xmin = new_float(L3Side.SFBMAX);
|
|
|
6520 |
var xfsf = new_float(L3Side.SFBMAX);
|
|
|
6521 |
var noise = new CalcNoiseResult();
|
|
|
6522 |
|
|
|
6523 |
calc_xmin(gfp, ratio, cod_info, l3_xmin);
|
|
|
6524 |
calc_noise(cod_info, l3_xmin, xfsf, noise, null);
|
|
|
6525 |
|
|
|
6526 |
var j = 0;
|
|
|
6527 |
sfb2 = cod_info.sfb_lmax;
|
|
|
6528 |
if (cod_info.block_type != Encoder.SHORT_TYPE
|
|
|
6529 |
&& 0 == cod_info.mixed_block_flag)
|
|
|
6530 |
sfb2 = 22;
|
|
|
6531 |
for (sfb = 0; sfb < sfb2; sfb++) {
|
|
|
6532 |
var start = gfc.scalefac_band.l[sfb];
|
|
|
6533 |
var end = gfc.scalefac_band.l[sfb + 1];
|
|
|
6534 |
var bw = end - start;
|
|
|
6535 |
for (en0 = 0.0; j < end; j++)
|
|
|
6536 |
en0 += cod_info.xr[j] * cod_info.xr[j];
|
|
|
6537 |
en0 /= bw;
|
|
|
6538 |
/* convert to MDCT units */
|
|
|
6539 |
/* scaling so it shows up on FFT plot */
|
|
|
6540 |
en1 = 1e15;
|
|
|
6541 |
gfc.pinfo.en[gr][ch][sfb] = en1 * en0;
|
|
|
6542 |
gfc.pinfo.xfsf[gr][ch][sfb] = en1 * l3_xmin[sfb] * xfsf[sfb] / bw;
|
|
|
6543 |
|
|
|
6544 |
if (ratio.en.l[sfb] > 0 && !gfp.ATHonly)
|
|
|
6545 |
en0 = en0 / ratio.en.l[sfb];
|
|
|
6546 |
else
|
|
|
6547 |
en0 = 0.0;
|
|
|
6548 |
|
|
|
6549 |
gfc.pinfo.thr[gr][ch][sfb] = en1
|
|
|
6550 |
* Math.max(en0 * ratio.thm.l[sfb], gfc.ATH.l[sfb]);
|
|
|
6551 |
|
|
|
6552 |
/* there is no scalefactor bands >= SBPSY_l */
|
|
|
6553 |
gfc.pinfo.LAMEsfb[gr][ch][sfb] = 0;
|
|
|
6554 |
if (cod_info.preflag != 0 && sfb >= 11)
|
|
|
6555 |
gfc.pinfo.LAMEsfb[gr][ch][sfb] = -ifqstep * pretab[sfb];
|
|
|
6556 |
|
|
|
6557 |
if (sfb < Encoder.SBPSY_l) {
|
|
|
6558 |
/* scfsi should be decoded by caller side */
|
|
|
6559 |
gfc.pinfo.LAMEsfb[gr][ch][sfb] -= ifqstep * scalefac[sfb];
|
|
|
6560 |
}
|
|
|
6561 |
}
|
|
|
6562 |
/* for sfb */
|
|
|
6563 |
|
|
|
6564 |
if (cod_info.block_type == Encoder.SHORT_TYPE) {
|
|
|
6565 |
sfb2 = sfb;
|
|
|
6566 |
for (sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) {
|
|
|
6567 |
var start = gfc.scalefac_band.s[sfb];
|
|
|
6568 |
var end = gfc.scalefac_band.s[sfb + 1];
|
|
|
6569 |
var bw = end - start;
|
|
|
6570 |
for (var i = 0; i < 3; i++) {
|
|
|
6571 |
for (en0 = 0.0, l = start; l < end; l++) {
|
|
|
6572 |
en0 += cod_info.xr[j] * cod_info.xr[j];
|
|
|
6573 |
j++;
|
|
|
6574 |
}
|
|
|
6575 |
en0 = Math.max(en0 / bw, 1e-20);
|
|
|
6576 |
/* convert to MDCT units */
|
|
|
6577 |
/* scaling so it shows up on FFT plot */
|
|
|
6578 |
en1 = 1e15;
|
|
|
6579 |
|
|
|
6580 |
gfc.pinfo.en_s[gr][ch][3 * sfb + i] = en1 * en0;
|
|
|
6581 |
gfc.pinfo.xfsf_s[gr][ch][3 * sfb + i] = en1 * l3_xmin[sfb2]
|
|
|
6582 |
* xfsf[sfb2] / bw;
|
|
|
6583 |
if (ratio.en.s[sfb][i] > 0)
|
|
|
6584 |
en0 = en0 / ratio.en.s[sfb][i];
|
|
|
6585 |
else
|
|
|
6586 |
en0 = 0.0;
|
|
|
6587 |
if (gfp.ATHonly || gfp.ATHshort)
|
|
|
6588 |
en0 = 0;
|
|
|
6589 |
|
|
|
6590 |
gfc.pinfo.thr_s[gr][ch][3 * sfb + i] = en1
|
|
|
6591 |
* Math.max(en0 * ratio.thm.s[sfb][i],
|
|
|
6592 |
gfc.ATH.s[sfb]);
|
|
|
6593 |
|
|
|
6594 |
/* there is no scalefactor bands >= SBPSY_s */
|
|
|
6595 |
gfc.pinfo.LAMEsfb_s[gr][ch][3 * sfb + i] = -2.0
|
|
|
6596 |
* cod_info.subblock_gain[i];
|
|
|
6597 |
if (sfb < Encoder.SBPSY_s) {
|
|
|
6598 |
gfc.pinfo.LAMEsfb_s[gr][ch][3 * sfb + i] -= ifqstep
|
|
|
6599 |
* scalefac[sfb2];
|
|
|
6600 |
}
|
|
|
6601 |
sfb2++;
|
|
|
6602 |
}
|
|
|
6603 |
}
|
|
|
6604 |
}
|
|
|
6605 |
/* block type short */
|
|
|
6606 |
gfc.pinfo.LAMEqss[gr][ch] = cod_info.global_gain;
|
|
|
6607 |
gfc.pinfo.LAMEmainbits[gr][ch] = cod_info.part2_3_length
|
|
|
6608 |
+ cod_info.part2_length;
|
|
|
6609 |
gfc.pinfo.LAMEsfbits[gr][ch] = cod_info.part2_length;
|
|
|
6610 |
|
|
|
6611 |
gfc.pinfo.over[gr][ch] = noise.over_count;
|
|
|
6612 |
gfc.pinfo.max_noise[gr][ch] = noise.max_noise * 10.0;
|
|
|
6613 |
gfc.pinfo.over_noise[gr][ch] = noise.over_noise * 10.0;
|
|
|
6614 |
gfc.pinfo.tot_noise[gr][ch] = noise.tot_noise * 10.0;
|
|
|
6615 |
gfc.pinfo.over_SSD[gr][ch] = noise.over_SSD;
|
|
|
6616 |
}
|
|
|
6617 |
|
|
|
6618 |
/**
|
|
|
6619 |
* updates plotting data for a whole frame
|
|
|
6620 |
*
|
|
|
6621 |
* Robert Hegemann 2000-10-21
|
|
|
6622 |
*/
|
|
|
6623 |
function set_frame_pinfo(gfp, ratio) {
|
|
|
6624 |
var gfc = gfp.internal_flags;
|
|
|
6625 |
|
|
|
6626 |
gfc.masking_lower = 1.0;
|
|
|
6627 |
|
|
|
6628 |
/*
|
|
|
6629 |
* for every granule and channel patch l3_enc and set info
|
|
|
6630 |
*/
|
|
|
6631 |
for (var gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
6632 |
for (var ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
6633 |
var cod_info = gfc.l3_side.tt[gr][ch];
|
|
|
6634 |
var scalefac_sav = new_int(L3Side.SFBMAX);
|
|
|
6635 |
System.arraycopy(cod_info.scalefac, 0, scalefac_sav, 0,
|
|
|
6636 |
scalefac_sav.length);
|
|
|
6637 |
|
|
|
6638 |
/*
|
|
|
6639 |
* reconstruct the scalefactors in case SCFSI was used
|
|
|
6640 |
*/
|
|
|
6641 |
if (gr == 1) {
|
|
|
6642 |
var sfb;
|
|
|
6643 |
for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) {
|
|
|
6644 |
if (cod_info.scalefac[sfb] < 0) /* scfsi */
|
|
|
6645 |
cod_info.scalefac[sfb] = gfc.l3_side.tt[0][ch].scalefac[sfb];
|
|
|
6646 |
}
|
|
|
6647 |
}
|
|
|
6648 |
|
|
|
6649 |
set_pinfo(gfp, cod_info, ratio[gr][ch], gr, ch);
|
|
|
6650 |
System.arraycopy(scalefac_sav, 0, cod_info.scalefac, 0,
|
|
|
6651 |
scalefac_sav.length);
|
|
|
6652 |
}
|
|
|
6653 |
/* for ch */
|
|
|
6654 |
}
|
|
|
6655 |
/* for gr */
|
|
|
6656 |
}
|
|
|
6657 |
|
|
|
6658 |
}
|
|
|
6659 |
|
|
|
6660 |
|
|
|
6661 |
function CalcNoiseData() {
|
|
|
6662 |
this.global_gain = 0;
|
|
|
6663 |
this.sfb_count1 = 0;
|
|
|
6664 |
this.step = new_int(39);
|
|
|
6665 |
this.noise = new_float(39);
|
|
|
6666 |
this.noise_log = new_float(39);
|
|
|
6667 |
}
|
|
|
6668 |
|
|
|
6669 |
//package mp3;
|
|
|
6670 |
|
|
|
6671 |
|
|
|
6672 |
function GrInfo() {
|
|
|
6673 |
//float xr[] = new float[576];
|
|
|
6674 |
this.xr = new_float(576);
|
|
|
6675 |
//int l3_enc[] = new int[576];
|
|
|
6676 |
this.l3_enc = new_int(576);
|
|
|
6677 |
//int scalefac[] = new int[L3Side.SFBMAX];
|
|
|
6678 |
this.scalefac = new_int(L3Side.SFBMAX);
|
|
|
6679 |
this.xrpow_max = 0.;
|
|
|
6680 |
|
|
|
6681 |
this.part2_3_length = 0;
|
|
|
6682 |
this.big_values = 0;
|
|
|
6683 |
this.count1 = 0;
|
|
|
6684 |
this.global_gain = 0;
|
|
|
6685 |
this.scalefac_compress = 0;
|
|
|
6686 |
this.block_type = 0;
|
|
|
6687 |
this.mixed_block_flag = 0;
|
|
|
6688 |
this.table_select = new_int(3);
|
|
|
6689 |
this.subblock_gain = new_int(3 + 1);
|
|
|
6690 |
this.region0_count = 0;
|
|
|
6691 |
this.region1_count = 0;
|
|
|
6692 |
this.preflag = 0;
|
|
|
6693 |
this.scalefac_scale = 0;
|
|
|
6694 |
this.count1table_select = 0;
|
|
|
6695 |
|
|
|
6696 |
this.part2_length = 0;
|
|
|
6697 |
this.sfb_lmax = 0;
|
|
|
6698 |
this.sfb_smin = 0;
|
|
|
6699 |
this.psy_lmax = 0;
|
|
|
6700 |
this.sfbmax = 0;
|
|
|
6701 |
this.psymax = 0;
|
|
|
6702 |
this.sfbdivide = 0;
|
|
|
6703 |
this.width = new_int(L3Side.SFBMAX);
|
|
|
6704 |
this.window = new_int(L3Side.SFBMAX);
|
|
|
6705 |
this.count1bits = 0;
|
|
|
6706 |
/**
|
|
|
6707 |
* added for LSF
|
|
|
6708 |
*/
|
|
|
6709 |
this.sfb_partition_table = null;
|
|
|
6710 |
this.slen = new_int(4);
|
|
|
6711 |
|
|
|
6712 |
this.max_nonzero_coeff = 0;
|
|
|
6713 |
|
|
|
6714 |
var self = this;
|
|
|
6715 |
function clone_int(array) {
|
|
|
6716 |
return new Int32Array(array);
|
|
|
6717 |
}
|
|
|
6718 |
function clone_float(array) {
|
|
|
6719 |
return new Float32Array(array);
|
|
|
6720 |
}
|
|
|
6721 |
this.assign = function (other) {
|
|
|
6722 |
self.xr = clone_float(other.xr); //.slice(0); //clone();
|
|
|
6723 |
self.l3_enc = clone_int(other.l3_enc); //.slice(0); //clone();
|
|
|
6724 |
self.scalefac = clone_int(other.scalefac);//.slice(0); //clone();
|
|
|
6725 |
self.xrpow_max = other.xrpow_max;
|
|
|
6726 |
|
|
|
6727 |
self.part2_3_length = other.part2_3_length;
|
|
|
6728 |
self.big_values = other.big_values;
|
|
|
6729 |
self.count1 = other.count1;
|
|
|
6730 |
self.global_gain = other.global_gain;
|
|
|
6731 |
self.scalefac_compress = other.scalefac_compress;
|
|
|
6732 |
self.block_type = other.block_type;
|
|
|
6733 |
self.mixed_block_flag = other.mixed_block_flag;
|
|
|
6734 |
self.table_select = clone_int(other.table_select);//.slice(0); //clone();
|
|
|
6735 |
self.subblock_gain = clone_int(other.subblock_gain); //.slice(0); //.clone();
|
|
|
6736 |
self.region0_count = other.region0_count;
|
|
|
6737 |
self.region1_count = other.region1_count;
|
|
|
6738 |
self.preflag = other.preflag;
|
|
|
6739 |
self.scalefac_scale = other.scalefac_scale;
|
|
|
6740 |
self.count1table_select = other.count1table_select;
|
|
|
6741 |
|
|
|
6742 |
self.part2_length = other.part2_length;
|
|
|
6743 |
self.sfb_lmax = other.sfb_lmax;
|
|
|
6744 |
self.sfb_smin = other.sfb_smin;
|
|
|
6745 |
self.psy_lmax = other.psy_lmax;
|
|
|
6746 |
self.sfbmax = other.sfbmax;
|
|
|
6747 |
self.psymax = other.psymax;
|
|
|
6748 |
self.sfbdivide = other.sfbdivide;
|
|
|
6749 |
self.width = clone_int(other.width); //.slice(0); //.clone();
|
|
|
6750 |
self.window = clone_int(other.window); //.slice(0); //.clone();
|
|
|
6751 |
self.count1bits = other.count1bits;
|
|
|
6752 |
|
|
|
6753 |
self.sfb_partition_table = other.sfb_partition_table.slice(0); //.clone();
|
|
|
6754 |
self.slen = clone_int(other.slen); //.slice(0); //.clone();
|
|
|
6755 |
self.max_nonzero_coeff = other.max_nonzero_coeff;
|
|
|
6756 |
}
|
|
|
6757 |
}
|
|
|
6758 |
|
|
|
6759 |
|
|
|
6760 |
var L3Side = {};
|
|
|
6761 |
|
|
|
6762 |
|
|
|
6763 |
/**
|
|
|
6764 |
* max scalefactor band, max(SBMAX_l, SBMAX_s*3, (SBMAX_s-3)*3+8)
|
|
|
6765 |
*/
|
|
|
6766 |
L3Side.SFBMAX = (Encoder.SBMAX_s * 3);
|
|
|
6767 |
|
|
|
6768 |
/*
|
|
|
6769 |
* MP3 quantization
|
|
|
6770 |
*
|
|
|
6771 |
* Copyright (c) 1999-2000 Mark Taylor
|
|
|
6772 |
* Copyright (c) 1999-2003 Takehiro Tominaga
|
|
|
6773 |
* Copyright (c) 2000-2007 Robert Hegemann
|
|
|
6774 |
* Copyright (c) 2001-2005 Gabriel Bouvigne
|
|
|
6775 |
*
|
|
|
6776 |
* This library is free software; you can redistribute it and/or
|
|
|
6777 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
6778 |
* License as published by the Free Software Foundation; either
|
|
|
6779 |
* version 2 of the License, or (at your option) any later version.
|
|
|
6780 |
*
|
|
|
6781 |
* This library is distributed in the hope that it will be useful,
|
|
|
6782 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
6783 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
6784 |
* Library General Public License for more details.
|
|
|
6785 |
*
|
|
|
6786 |
* You should have received a copy of the GNU Lesser General Public
|
|
|
6787 |
* License along with this library; if not, write to the
|
|
|
6788 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
6789 |
* Boston, MA 02111-1307, USA.
|
|
|
6790 |
*/
|
|
|
6791 |
|
|
|
6792 |
/* $Id: Quantize.java,v 1.24 2011/05/24 20:48:06 kenchis Exp $ */
|
|
|
6793 |
|
|
|
6794 |
//package mp3;
|
|
|
6795 |
|
|
|
6796 |
//import java.util.Arrays;
|
|
|
6797 |
|
|
|
6798 |
|
|
|
6799 |
function Quantize() {
|
|
|
6800 |
var bs;
|
|
|
6801 |
this.rv = null;
|
|
|
6802 |
var rv;
|
|
|
6803 |
this.qupvt = null;
|
|
|
6804 |
var qupvt;
|
|
|
6805 |
|
|
|
6806 |
var vbr = new VBRQuantize();
|
|
|
6807 |
var tk;
|
|
|
6808 |
|
|
|
6809 |
this.setModules = function (_bs, _rv, _qupvt, _tk) {
|
|
|
6810 |
bs = _bs;
|
|
|
6811 |
rv = _rv;
|
|
|
6812 |
this.rv = _rv;
|
|
|
6813 |
qupvt = _qupvt;
|
|
|
6814 |
this.qupvt = _qupvt;
|
|
|
6815 |
tk = _tk;
|
|
|
6816 |
vbr.setModules(qupvt, tk);
|
|
|
6817 |
}
|
|
|
6818 |
|
|
|
6819 |
/**
|
|
|
6820 |
* convert from L/R <. Mid/Side
|
|
|
6821 |
*/
|
|
|
6822 |
this.ms_convert = function (l3_side, gr) {
|
|
|
6823 |
for (var i = 0; i < 576; ++i) {
|
|
|
6824 |
var l = l3_side.tt[gr][0].xr[i];
|
|
|
6825 |
var r = l3_side.tt[gr][1].xr[i];
|
|
|
6826 |
l3_side.tt[gr][0].xr[i] = (l + r) * (Util.SQRT2 * 0.5);
|
|
|
6827 |
l3_side.tt[gr][1].xr[i] = (l - r) * (Util.SQRT2 * 0.5);
|
|
|
6828 |
}
|
|
|
6829 |
};
|
|
|
6830 |
|
|
|
6831 |
/**
|
|
|
6832 |
* mt 6/99
|
|
|
6833 |
*
|
|
|
6834 |
* initializes cod_info, scalefac and xrpow
|
|
|
6835 |
*
|
|
|
6836 |
* returns 0 if all energies in xr are zero, else 1
|
|
|
6837 |
*/
|
|
|
6838 |
function init_xrpow_core(cod_info, xrpow, upper, sum) {
|
|
|
6839 |
sum = 0;
|
|
|
6840 |
for (var i = 0; i <= upper; ++i) {
|
|
|
6841 |
var tmp = Math.abs(cod_info.xr[i]);
|
|
|
6842 |
sum += tmp;
|
|
|
6843 |
xrpow[i] = Math.sqrt(tmp * Math.sqrt(tmp));
|
|
|
6844 |
|
|
|
6845 |
if (xrpow[i] > cod_info.xrpow_max)
|
|
|
6846 |
cod_info.xrpow_max = xrpow[i];
|
|
|
6847 |
}
|
|
|
6848 |
return sum;
|
|
|
6849 |
}
|
|
|
6850 |
|
|
|
6851 |
this.init_xrpow = function (gfc, cod_info, xrpow) {
|
|
|
6852 |
var sum = 0;
|
|
|
6853 |
var upper = 0 | cod_info.max_nonzero_coeff;
|
|
|
6854 |
|
|
|
6855 |
cod_info.xrpow_max = 0;
|
|
|
6856 |
|
|
|
6857 |
/*
|
|
|
6858 |
* check if there is some energy we have to quantize and calculate xrpow
|
|
|
6859 |
* matching our fresh scalefactors
|
|
|
6860 |
*/
|
|
|
6861 |
|
|
|
6862 |
Arrays.fill(xrpow, upper, 576, 0);
|
|
|
6863 |
|
|
|
6864 |
sum = init_xrpow_core(cod_info, xrpow, upper, sum);
|
|
|
6865 |
|
|
|
6866 |
/*
|
|
|
6867 |
* return 1 if we have something to quantize, else 0
|
|
|
6868 |
*/
|
|
|
6869 |
if (sum > 1E-20) {
|
|
|
6870 |
var j = 0;
|
|
|
6871 |
if ((gfc.substep_shaping & 2) != 0)
|
|
|
6872 |
j = 1;
|
|
|
6873 |
|
|
|
6874 |
for (var i = 0; i < cod_info.psymax; i++)
|
|
|
6875 |
gfc.pseudohalf[i] = j;
|
|
|
6876 |
|
|
|
6877 |
return true;
|
|
|
6878 |
}
|
|
|
6879 |
|
|
|
6880 |
Arrays.fill(cod_info.l3_enc, 0, 576, 0);
|
|
|
6881 |
return false;
|
|
|
6882 |
}
|
|
|
6883 |
|
|
|
6884 |
/**
|
|
|
6885 |
* Gabriel Bouvigne feb/apr 2003<BR>
|
|
|
6886 |
* Analog silence detection in partitionned sfb21 or sfb12 for short blocks
|
|
|
6887 |
*
|
|
|
6888 |
* From top to bottom of sfb, changes to 0 coeffs which are below ath. It
|
|
|
6889 |
* stops on the first coeff higher than ath.
|
|
|
6890 |
*/
|
|
|
6891 |
function psfb21_analogsilence(gfc, cod_info) {
|
|
|
6892 |
var ath = gfc.ATH;
|
|
|
6893 |
var xr = cod_info.xr;
|
|
|
6894 |
|
|
|
6895 |
if (cod_info.block_type != Encoder.SHORT_TYPE) {
|
|
|
6896 |
/* NORM, START or STOP type, but not SHORT blocks */
|
|
|
6897 |
var stop = false;
|
|
|
6898 |
for (var gsfb = Encoder.PSFB21 - 1; gsfb >= 0 && !stop; gsfb--) {
|
|
|
6899 |
var start = gfc.scalefac_band.psfb21[gsfb];
|
|
|
6900 |
var end = gfc.scalefac_band.psfb21[gsfb + 1];
|
|
|
6901 |
var ath21 = qupvt.athAdjust(ath.adjust, ath.psfb21[gsfb],
|
|
|
6902 |
ath.floor);
|
|
|
6903 |
|
|
|
6904 |
if (gfc.nsPsy.longfact[21] > 1e-12)
|
|
|
6905 |
ath21 *= gfc.nsPsy.longfact[21];
|
|
|
6906 |
|
|
|
6907 |
for (var j = end - 1; j >= start; j--) {
|
|
|
6908 |
if (Math.abs(xr[j]) < ath21)
|
|
|
6909 |
xr[j] = 0;
|
|
|
6910 |
else {
|
|
|
6911 |
stop = true;
|
|
|
6912 |
break;
|
|
|
6913 |
}
|
|
|
6914 |
}
|
|
|
6915 |
}
|
|
|
6916 |
} else {
|
|
|
6917 |
/* note: short blocks coeffs are reordered */
|
|
|
6918 |
for (var block = 0; block < 3; block++) {
|
|
|
6919 |
var stop = false;
|
|
|
6920 |
for (var gsfb = Encoder.PSFB12 - 1; gsfb >= 0 && !stop; gsfb--) {
|
|
|
6921 |
var start = gfc.scalefac_band.s[12]
|
|
|
6922 |
* 3
|
|
|
6923 |
+ (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12])
|
|
|
6924 |
* block
|
|
|
6925 |
+ (gfc.scalefac_band.psfb12[gsfb] - gfc.scalefac_band.psfb12[0]);
|
|
|
6926 |
var end = start
|
|
|
6927 |
+ (gfc.scalefac_band.psfb12[gsfb + 1] - gfc.scalefac_band.psfb12[gsfb]);
|
|
|
6928 |
var ath12 = qupvt.athAdjust(ath.adjust, ath.psfb12[gsfb],
|
|
|
6929 |
ath.floor);
|
|
|
6930 |
|
|
|
6931 |
if (gfc.nsPsy.shortfact[12] > 1e-12)
|
|
|
6932 |
ath12 *= gfc.nsPsy.shortfact[12];
|
|
|
6933 |
|
|
|
6934 |
for (var j = end - 1; j >= start; j--) {
|
|
|
6935 |
if (Math.abs(xr[j]) < ath12)
|
|
|
6936 |
xr[j] = 0;
|
|
|
6937 |
else {
|
|
|
6938 |
stop = true;
|
|
|
6939 |
break;
|
|
|
6940 |
}
|
|
|
6941 |
}
|
|
|
6942 |
}
|
|
|
6943 |
}
|
|
|
6944 |
}
|
|
|
6945 |
|
|
|
6946 |
}
|
|
|
6947 |
|
|
|
6948 |
this.init_outer_loop = function (gfc, cod_info) {
|
|
|
6949 |
/*
|
|
|
6950 |
* initialize fresh cod_info
|
|
|
6951 |
*/
|
|
|
6952 |
cod_info.part2_3_length = 0;
|
|
|
6953 |
cod_info.big_values = 0;
|
|
|
6954 |
cod_info.count1 = 0;
|
|
|
6955 |
cod_info.global_gain = 210;
|
|
|
6956 |
cod_info.scalefac_compress = 0;
|
|
|
6957 |
/* mixed_block_flag, block_type was set in psymodel.c */
|
|
|
6958 |
cod_info.table_select[0] = 0;
|
|
|
6959 |
cod_info.table_select[1] = 0;
|
|
|
6960 |
cod_info.table_select[2] = 0;
|
|
|
6961 |
cod_info.subblock_gain[0] = 0;
|
|
|
6962 |
cod_info.subblock_gain[1] = 0;
|
|
|
6963 |
cod_info.subblock_gain[2] = 0;
|
|
|
6964 |
cod_info.subblock_gain[3] = 0;
|
|
|
6965 |
/* this one is always 0 */
|
|
|
6966 |
cod_info.region0_count = 0;
|
|
|
6967 |
cod_info.region1_count = 0;
|
|
|
6968 |
cod_info.preflag = 0;
|
|
|
6969 |
cod_info.scalefac_scale = 0;
|
|
|
6970 |
cod_info.count1table_select = 0;
|
|
|
6971 |
cod_info.part2_length = 0;
|
|
|
6972 |
cod_info.sfb_lmax = Encoder.SBPSY_l;
|
|
|
6973 |
cod_info.sfb_smin = Encoder.SBPSY_s;
|
|
|
6974 |
cod_info.psy_lmax = gfc.sfb21_extra ? Encoder.SBMAX_l : Encoder.SBPSY_l;
|
|
|
6975 |
cod_info.psymax = cod_info.psy_lmax;
|
|
|
6976 |
cod_info.sfbmax = cod_info.sfb_lmax;
|
|
|
6977 |
cod_info.sfbdivide = 11;
|
|
|
6978 |
for (var sfb = 0; sfb < Encoder.SBMAX_l; sfb++) {
|
|
|
6979 |
cod_info.width[sfb] = gfc.scalefac_band.l[sfb + 1]
|
|
|
6980 |
- gfc.scalefac_band.l[sfb];
|
|
|
6981 |
/* which is always 0. */
|
|
|
6982 |
cod_info.window[sfb] = 3;
|
|
|
6983 |
}
|
|
|
6984 |
if (cod_info.block_type == Encoder.SHORT_TYPE) {
|
|
|
6985 |
var ixwork = new_float(576);
|
|
|
6986 |
|
|
|
6987 |
cod_info.sfb_smin = 0;
|
|
|
6988 |
cod_info.sfb_lmax = 0;
|
|
|
6989 |
if (cod_info.mixed_block_flag != 0) {
|
|
|
6990 |
/*
|
|
|
6991 |
* MPEG-1: sfbs 0-7 long block, 3-12 short blocks MPEG-2(.5):
|
|
|
6992 |
* sfbs 0-5 long block, 3-12 short blocks
|
|
|
6993 |
*/
|
|
|
6994 |
cod_info.sfb_smin = 3;
|
|
|
6995 |
cod_info.sfb_lmax = gfc.mode_gr * 2 + 4;
|
|
|
6996 |
}
|
|
|
6997 |
cod_info.psymax = cod_info.sfb_lmax
|
|
|
6998 |
+ 3
|
|
|
6999 |
* ((gfc.sfb21_extra ? Encoder.SBMAX_s : Encoder.SBPSY_s) - cod_info.sfb_smin);
|
|
|
7000 |
cod_info.sfbmax = cod_info.sfb_lmax + 3
|
|
|
7001 |
* (Encoder.SBPSY_s - cod_info.sfb_smin);
|
|
|
7002 |
cod_info.sfbdivide = cod_info.sfbmax - 18;
|
|
|
7003 |
cod_info.psy_lmax = cod_info.sfb_lmax;
|
|
|
7004 |
/* re-order the short blocks, for more efficient encoding below */
|
|
|
7005 |
/* By Takehiro TOMINAGA */
|
|
|
7006 |
/*
|
|
|
7007 |
* Within each scalefactor band, data is given for successive time
|
|
|
7008 |
* windows, beginning with window 0 and ending with window 2. Within
|
|
|
7009 |
* each window, the quantized values are then arranged in order of
|
|
|
7010 |
* increasing frequency...
|
|
|
7011 |
*/
|
|
|
7012 |
var ix = gfc.scalefac_band.l[cod_info.sfb_lmax];
|
|
|
7013 |
System.arraycopy(cod_info.xr, 0, ixwork, 0, 576);
|
|
|
7014 |
for (var sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) {
|
|
|
7015 |
var start = gfc.scalefac_band.s[sfb];
|
|
|
7016 |
var end = gfc.scalefac_band.s[sfb + 1];
|
|
|
7017 |
for (var window = 0; window < 3; window++) {
|
|
|
7018 |
for (var l = start; l < end; l++) {
|
|
|
7019 |
cod_info.xr[ix++] = ixwork[3 * l + window];
|
|
|
7020 |
}
|
|
|
7021 |
}
|
|
|
7022 |
}
|
|
|
7023 |
|
|
|
7024 |
var j = cod_info.sfb_lmax;
|
|
|
7025 |
for (var sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) {
|
|
|
7026 |
cod_info.width[j] = cod_info.width[j + 1] = cod_info.width[j + 2] = gfc.scalefac_band.s[sfb + 1]
|
|
|
7027 |
- gfc.scalefac_band.s[sfb];
|
|
|
7028 |
cod_info.window[j] = 0;
|
|
|
7029 |
cod_info.window[j + 1] = 1;
|
|
|
7030 |
cod_info.window[j + 2] = 2;
|
|
|
7031 |
j += 3;
|
|
|
7032 |
}
|
|
|
7033 |
}
|
|
|
7034 |
|
|
|
7035 |
cod_info.count1bits = 0;
|
|
|
7036 |
cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[0][0];
|
|
|
7037 |
cod_info.slen[0] = 0;
|
|
|
7038 |
cod_info.slen[1] = 0;
|
|
|
7039 |
cod_info.slen[2] = 0;
|
|
|
7040 |
cod_info.slen[3] = 0;
|
|
|
7041 |
|
|
|
7042 |
cod_info.max_nonzero_coeff = 575;
|
|
|
7043 |
|
|
|
7044 |
/*
|
|
|
7045 |
* fresh scalefactors are all zero
|
|
|
7046 |
*/
|
|
|
7047 |
Arrays.fill(cod_info.scalefac, 0);
|
|
|
7048 |
|
|
|
7049 |
psfb21_analogsilence(gfc, cod_info);
|
|
|
7050 |
};
|
|
|
7051 |
|
|
|
7052 |
function BinSearchDirection(ordinal) {
|
|
|
7053 |
this.ordinal = ordinal;
|
|
|
7054 |
}
|
|
|
7055 |
|
|
|
7056 |
BinSearchDirection.BINSEARCH_NONE = new BinSearchDirection(0);
|
|
|
7057 |
BinSearchDirection.BINSEARCH_UP = new BinSearchDirection(1);
|
|
|
7058 |
BinSearchDirection.BINSEARCH_DOWN = new BinSearchDirection(2);
|
|
|
7059 |
|
|
|
7060 |
/**
|
|
|
7061 |
* author/date??
|
|
|
7062 |
*
|
|
|
7063 |
* binary step size search used by outer_loop to get a quantizer step size
|
|
|
7064 |
* to start with
|
|
|
7065 |
*/
|
|
|
7066 |
function bin_search_StepSize(gfc, cod_info, desired_rate, ch, xrpow) {
|
|
|
7067 |
var nBits;
|
|
|
7068 |
var CurrentStep = gfc.CurrentStep[ch];
|
|
|
7069 |
var flagGoneOver = false;
|
|
|
7070 |
var start = gfc.OldValue[ch];
|
|
|
7071 |
var Direction = BinSearchDirection.BINSEARCH_NONE;
|
|
|
7072 |
cod_info.global_gain = start;
|
|
|
7073 |
desired_rate -= cod_info.part2_length;
|
|
|
7074 |
|
|
|
7075 |
for (; ;) {
|
|
|
7076 |
var step;
|
|
|
7077 |
nBits = tk.count_bits(gfc, xrpow, cod_info, null);
|
|
|
7078 |
|
|
|
7079 |
if (CurrentStep == 1 || nBits == desired_rate)
|
|
|
7080 |
break;
|
|
|
7081 |
/* nothing to adjust anymore */
|
|
|
7082 |
|
|
|
7083 |
if (nBits > desired_rate) {
|
|
|
7084 |
/* increase Quantize_StepSize */
|
|
|
7085 |
if (Direction == BinSearchDirection.BINSEARCH_DOWN)
|
|
|
7086 |
flagGoneOver = true;
|
|
|
7087 |
|
|
|
7088 |
if (flagGoneOver)
|
|
|
7089 |
CurrentStep /= 2;
|
|
|
7090 |
Direction = BinSearchDirection.BINSEARCH_UP;
|
|
|
7091 |
step = CurrentStep;
|
|
|
7092 |
} else {
|
|
|
7093 |
/* decrease Quantize_StepSize */
|
|
|
7094 |
if (Direction == BinSearchDirection.BINSEARCH_UP)
|
|
|
7095 |
flagGoneOver = true;
|
|
|
7096 |
|
|
|
7097 |
if (flagGoneOver)
|
|
|
7098 |
CurrentStep /= 2;
|
|
|
7099 |
Direction = BinSearchDirection.BINSEARCH_DOWN;
|
|
|
7100 |
step = -CurrentStep;
|
|
|
7101 |
}
|
|
|
7102 |
cod_info.global_gain += step;
|
|
|
7103 |
if (cod_info.global_gain < 0) {
|
|
|
7104 |
cod_info.global_gain = 0;
|
|
|
7105 |
flagGoneOver = true;
|
|
|
7106 |
}
|
|
|
7107 |
if (cod_info.global_gain > 255) {
|
|
|
7108 |
cod_info.global_gain = 255;
|
|
|
7109 |
flagGoneOver = true;
|
|
|
7110 |
}
|
|
|
7111 |
}
|
|
|
7112 |
|
|
|
7113 |
|
|
|
7114 |
while (nBits > desired_rate && cod_info.global_gain < 255) {
|
|
|
7115 |
cod_info.global_gain++;
|
|
|
7116 |
nBits = tk.count_bits(gfc, xrpow, cod_info, null);
|
|
|
7117 |
}
|
|
|
7118 |
gfc.CurrentStep[ch] = (start - cod_info.global_gain >= 4) ? 4 : 2;
|
|
|
7119 |
gfc.OldValue[ch] = cod_info.global_gain;
|
|
|
7120 |
cod_info.part2_3_length = nBits;
|
|
|
7121 |
return nBits;
|
|
|
7122 |
}
|
|
|
7123 |
|
|
|
7124 |
this.trancate_smallspectrums = function (gfc, gi, l3_xmin, work) {
|
|
|
7125 |
var distort = new_float(L3Side.SFBMAX);
|
|
|
7126 |
|
|
|
7127 |
if ((0 == (gfc.substep_shaping & 4) && gi.block_type == Encoder.SHORT_TYPE)
|
|
|
7128 |
|| (gfc.substep_shaping & 0x80) != 0)
|
|
|
7129 |
return;
|
|
|
7130 |
qupvt.calc_noise(gi, l3_xmin, distort, new CalcNoiseResult(), null);
|
|
|
7131 |
for (var j = 0; j < 576; j++) {
|
|
|
7132 |
var xr = 0.0;
|
|
|
7133 |
if (gi.l3_enc[j] != 0)
|
|
|
7134 |
xr = Math.abs(gi.xr[j]);
|
|
|
7135 |
work[j] = xr;
|
|
|
7136 |
}
|
|
|
7137 |
|
|
|
7138 |
var j = 0;
|
|
|
7139 |
var sfb = 8;
|
|
|
7140 |
if (gi.block_type == Encoder.SHORT_TYPE)
|
|
|
7141 |
sfb = 6;
|
|
|
7142 |
do {
|
|
|
7143 |
var allowedNoise, trancateThreshold;
|
|
|
7144 |
var nsame, start;
|
|
|
7145 |
|
|
|
7146 |
var width = gi.width[sfb];
|
|
|
7147 |
j += width;
|
|
|
7148 |
if (distort[sfb] >= 1.0)
|
|
|
7149 |
continue;
|
|
|
7150 |
|
|
|
7151 |
Arrays.sort(work, j - width, width);
|
|
|
7152 |
if (BitStream.EQ(work[j - 1], 0.0))
|
|
|
7153 |
continue;
|
|
|
7154 |
/* all zero sfb */
|
|
|
7155 |
|
|
|
7156 |
allowedNoise = (1.0 - distort[sfb]) * l3_xmin[sfb];
|
|
|
7157 |
trancateThreshold = 0.0;
|
|
|
7158 |
start = 0;
|
|
|
7159 |
do {
|
|
|
7160 |
var noise;
|
|
|
7161 |
for (nsame = 1; start + nsame < width; nsame++)
|
|
|
7162 |
if (BitStream.NEQ(work[start + j - width], work[start + j
|
|
|
7163 |
+ nsame - width]))
|
|
|
7164 |
break;
|
|
|
7165 |
|
|
|
7166 |
noise = work[start + j - width] * work[start + j - width]
|
|
|
7167 |
* nsame;
|
|
|
7168 |
if (allowedNoise < noise) {
|
|
|
7169 |
if (start != 0)
|
|
|
7170 |
trancateThreshold = work[start + j - width - 1];
|
|
|
7171 |
break;
|
|
|
7172 |
}
|
|
|
7173 |
allowedNoise -= noise;
|
|
|
7174 |
start += nsame;
|
|
|
7175 |
} while (start < width);
|
|
|
7176 |
if (BitStream.EQ(trancateThreshold, 0.0))
|
|
|
7177 |
continue;
|
|
|
7178 |
|
|
|
7179 |
do {
|
|
|
7180 |
if (Math.abs(gi.xr[j - width]) <= trancateThreshold)
|
|
|
7181 |
gi.l3_enc[j - width] = 0;
|
|
|
7182 |
} while (--width > 0);
|
|
|
7183 |
} while (++sfb < gi.psymax);
|
|
|
7184 |
|
|
|
7185 |
gi.part2_3_length = tk.noquant_count_bits(gfc, gi, null);
|
|
|
7186 |
};
|
|
|
7187 |
|
|
|
7188 |
/**
|
|
|
7189 |
* author/date??
|
|
|
7190 |
*
|
|
|
7191 |
* Function: Returns zero if there is a scalefac which has not been
|
|
|
7192 |
* amplified. Otherwise it returns one.
|
|
|
7193 |
*/
|
|
|
7194 |
function loop_break(cod_info) {
|
|
|
7195 |
for (var sfb = 0; sfb < cod_info.sfbmax; sfb++)
|
|
|
7196 |
if (cod_info.scalefac[sfb]
|
|
|
7197 |
+ cod_info.subblock_gain[cod_info.window[sfb]] == 0)
|
|
|
7198 |
return false;
|
|
|
7199 |
|
|
|
7200 |
return true;
|
|
|
7201 |
}
|
|
|
7202 |
|
|
|
7203 |
/* mt 5/99: Function: Improved calc_noise for a single channel */
|
|
|
7204 |
|
|
|
7205 |
function penalties(noise) {
|
|
|
7206 |
return Util.FAST_LOG10((0.368 + 0.632 * noise * noise * noise));
|
|
|
7207 |
}
|
|
|
7208 |
|
|
|
7209 |
/**
|
|
|
7210 |
* author/date??
|
|
|
7211 |
*
|
|
|
7212 |
* several different codes to decide which quantization is better
|
|
|
7213 |
*/
|
|
|
7214 |
function get_klemm_noise(distort, gi) {
|
|
|
7215 |
var klemm_noise = 1E-37;
|
|
|
7216 |
for (var sfb = 0; sfb < gi.psymax; sfb++)
|
|
|
7217 |
klemm_noise += penalties(distort[sfb]);
|
|
|
7218 |
|
|
|
7219 |
return Math.max(1e-20, klemm_noise);
|
|
|
7220 |
}
|
|
|
7221 |
|
|
|
7222 |
function quant_compare(quant_comp, best, calc, gi, distort) {
|
|
|
7223 |
/**
|
|
|
7224 |
* noise is given in decibels (dB) relative to masking thesholds.<BR>
|
|
|
7225 |
*
|
|
|
7226 |
* over_noise: ??? (the previous comment is fully wrong)<BR>
|
|
|
7227 |
* tot_noise: ??? (the previous comment is fully wrong)<BR>
|
|
|
7228 |
* max_noise: max quantization noise
|
|
|
7229 |
*/
|
|
|
7230 |
var better;
|
|
|
7231 |
|
|
|
7232 |
switch (quant_comp) {
|
|
|
7233 |
default:
|
|
|
7234 |
case 9:
|
|
|
7235 |
{
|
|
|
7236 |
if (best.over_count > 0) {
|
|
|
7237 |
/* there are distorted sfb */
|
|
|
7238 |
better = calc.over_SSD <= best.over_SSD;
|
|
|
7239 |
if (calc.over_SSD == best.over_SSD)
|
|
|
7240 |
better = calc.bits < best.bits;
|
|
|
7241 |
} else {
|
|
|
7242 |
/* no distorted sfb */
|
|
|
7243 |
better = ((calc.max_noise < 0) && ((calc.max_noise * 10 + calc.bits) <= (best.max_noise * 10 + best.bits)));
|
|
|
7244 |
}
|
|
|
7245 |
break;
|
|
|
7246 |
}
|
|
|
7247 |
|
|
|
7248 |
case 0:
|
|
|
7249 |
better = calc.over_count < best.over_count
|
|
|
7250 |
|| (calc.over_count == best.over_count && calc.over_noise < best.over_noise)
|
|
|
7251 |
|| (calc.over_count == best.over_count
|
|
|
7252 |
&& BitStream.EQ(calc.over_noise, best.over_noise) && calc.tot_noise < best.tot_noise);
|
|
|
7253 |
break;
|
|
|
7254 |
|
|
|
7255 |
case 8:
|
|
|
7256 |
calc.max_noise = get_klemm_noise(distort, gi);
|
|
|
7257 |
//$FALL-THROUGH$
|
|
|
7258 |
case 1:
|
|
|
7259 |
better = calc.max_noise < best.max_noise;
|
|
|
7260 |
break;
|
|
|
7261 |
case 2:
|
|
|
7262 |
better = calc.tot_noise < best.tot_noise;
|
|
|
7263 |
break;
|
|
|
7264 |
case 3:
|
|
|
7265 |
better = (calc.tot_noise < best.tot_noise)
|
|
|
7266 |
&& (calc.max_noise < best.max_noise);
|
|
|
7267 |
break;
|
|
|
7268 |
case 4:
|
|
|
7269 |
better = (calc.max_noise <= 0.0 && best.max_noise > 0.2)
|
|
|
7270 |
|| (calc.max_noise <= 0.0 && best.max_noise < 0.0
|
|
|
7271 |
&& best.max_noise > calc.max_noise - 0.2 && calc.tot_noise < best.tot_noise)
|
|
|
7272 |
|| (calc.max_noise <= 0.0 && best.max_noise > 0.0
|
|
|
7273 |
&& best.max_noise > calc.max_noise - 0.2 && calc.tot_noise < best.tot_noise
|
|
|
7274 |
+ best.over_noise)
|
|
|
7275 |
|| (calc.max_noise > 0.0 && best.max_noise > -0.05
|
|
|
7276 |
&& best.max_noise > calc.max_noise - 0.1 && calc.tot_noise
|
|
|
7277 |
+ calc.over_noise < best.tot_noise
|
|
|
7278 |
+ best.over_noise)
|
|
|
7279 |
|| (calc.max_noise > 0.0 && best.max_noise > -0.1
|
|
|
7280 |
&& best.max_noise > calc.max_noise - 0.15 && calc.tot_noise
|
|
|
7281 |
+ calc.over_noise + calc.over_noise < best.tot_noise
|
|
|
7282 |
+ best.over_noise + best.over_noise);
|
|
|
7283 |
break;
|
|
|
7284 |
case 5:
|
|
|
7285 |
better = calc.over_noise < best.over_noise
|
|
|
7286 |
|| (BitStream.EQ(calc.over_noise, best.over_noise) && calc.tot_noise < best.tot_noise);
|
|
|
7287 |
break;
|
|
|
7288 |
case 6:
|
|
|
7289 |
better = calc.over_noise < best.over_noise
|
|
|
7290 |
|| (BitStream.EQ(calc.over_noise, best.over_noise) && (calc.max_noise < best.max_noise || (BitStream
|
|
|
7291 |
.EQ(calc.max_noise, best.max_noise) && calc.tot_noise <= best.tot_noise)));
|
|
|
7292 |
break;
|
|
|
7293 |
case 7:
|
|
|
7294 |
better = calc.over_count < best.over_count
|
|
|
7295 |
|| calc.over_noise < best.over_noise;
|
|
|
7296 |
break;
|
|
|
7297 |
}
|
|
|
7298 |
|
|
|
7299 |
if (best.over_count == 0) {
|
|
|
7300 |
/*
|
|
|
7301 |
* If no distorted bands, only use this quantization if it is
|
|
|
7302 |
* better, and if it uses less bits. Unfortunately, part2_3_length
|
|
|
7303 |
* is sometimes a poor estimator of the final size at low bitrates.
|
|
|
7304 |
*/
|
|
|
7305 |
better = better && calc.bits < best.bits;
|
|
|
7306 |
}
|
|
|
7307 |
|
|
|
7308 |
return better;
|
|
|
7309 |
}
|
|
|
7310 |
|
|
|
7311 |
/**
|
|
|
7312 |
* author/date??
|
|
|
7313 |
*
|
|
|
7314 |
* <PRE>
|
|
|
7315 |
* Amplify the scalefactor bands that violate the masking threshold.
|
|
|
7316 |
* See ISO 11172-3 Section C.1.5.4.3.5
|
|
|
7317 |
*
|
|
|
7318 |
* distort[] = noise/masking
|
|
|
7319 |
* distort[] > 1 ==> noise is not masked
|
|
|
7320 |
* distort[] < 1 ==> noise is masked
|
|
|
7321 |
* max_dist = maximum value of distort[]
|
|
|
7322 |
*
|
|
|
7323 |
* Three algorithms:
|
|
|
7324 |
* noise_shaping_amp
|
|
|
7325 |
* 0 Amplify all bands with distort[]>1.
|
|
|
7326 |
*
|
|
|
7327 |
* 1 Amplify all bands with distort[] >= max_dist^(.5);
|
|
|
7328 |
* ( 50% in the db scale)
|
|
|
7329 |
*
|
|
|
7330 |
* 2 Amplify first band with distort[] >= max_dist;
|
|
|
7331 |
*
|
|
|
7332 |
*
|
|
|
7333 |
* For algorithms 0 and 1, if max_dist < 1, then amplify all bands
|
|
|
7334 |
* with distort[] >= .95*max_dist. This is to make sure we always
|
|
|
7335 |
* amplify at least one band.
|
|
|
7336 |
* </PRE>
|
|
|
7337 |
*/
|
|
|
7338 |
function amp_scalefac_bands(gfp, cod_info, distort, xrpow, bRefine) {
|
|
|
7339 |
var gfc = gfp.internal_flags;
|
|
|
7340 |
var ifqstep34;
|
|
|
7341 |
|
|
|
7342 |
if (cod_info.scalefac_scale == 0) {
|
|
|
7343 |
ifqstep34 = 1.29683955465100964055;
|
|
|
7344 |
/* 2**(.75*.5) */
|
|
|
7345 |
} else {
|
|
|
7346 |
ifqstep34 = 1.68179283050742922612;
|
|
|
7347 |
/* 2**(.75*1) */
|
|
|
7348 |
}
|
|
|
7349 |
|
|
|
7350 |
/* compute maximum value of distort[] */
|
|
|
7351 |
var trigger = 0;
|
|
|
7352 |
for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) {
|
|
|
7353 |
if (trigger < distort[sfb])
|
|
|
7354 |
trigger = distort[sfb];
|
|
|
7355 |
}
|
|
|
7356 |
|
|
|
7357 |
var noise_shaping_amp = gfc.noise_shaping_amp;
|
|
|
7358 |
if (noise_shaping_amp == 3) {
|
|
|
7359 |
if (bRefine)
|
|
|
7360 |
noise_shaping_amp = 2;
|
|
|
7361 |
else
|
|
|
7362 |
noise_shaping_amp = 1;
|
|
|
7363 |
}
|
|
|
7364 |
switch (noise_shaping_amp) {
|
|
|
7365 |
case 2:
|
|
|
7366 |
/* amplify exactly 1 band */
|
|
|
7367 |
break;
|
|
|
7368 |
|
|
|
7369 |
case 1:
|
|
|
7370 |
/* amplify bands within 50% of max (on db scale) */
|
|
|
7371 |
if (trigger > 1.0)
|
|
|
7372 |
trigger = Math.pow(trigger, .5);
|
|
|
7373 |
else
|
|
|
7374 |
trigger *= .95;
|
|
|
7375 |
break;
|
|
|
7376 |
|
|
|
7377 |
case 0:
|
|
|
7378 |
default:
|
|
|
7379 |
/* ISO algorithm. amplify all bands with distort>1 */
|
|
|
7380 |
if (trigger > 1.0)
|
|
|
7381 |
trigger = 1.0;
|
|
|
7382 |
else
|
|
|
7383 |
trigger *= .95;
|
|
|
7384 |
break;
|
|
|
7385 |
}
|
|
|
7386 |
|
|
|
7387 |
var j = 0;
|
|
|
7388 |
for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) {
|
|
|
7389 |
var width = cod_info.width[sfb];
|
|
|
7390 |
var l;
|
|
|
7391 |
j += width;
|
|
|
7392 |
if (distort[sfb] < trigger)
|
|
|
7393 |
continue;
|
|
|
7394 |
|
|
|
7395 |
if ((gfc.substep_shaping & 2) != 0) {
|
|
|
7396 |
gfc.pseudohalf[sfb] = (0 == gfc.pseudohalf[sfb]) ? 1 : 0;
|
|
|
7397 |
if (0 == gfc.pseudohalf[sfb] && gfc.noise_shaping_amp == 2)
|
|
|
7398 |
return;
|
|
|
7399 |
}
|
|
|
7400 |
cod_info.scalefac[sfb]++;
|
|
|
7401 |
for (l = -width; l < 0; l++) {
|
|
|
7402 |
xrpow[j + l] *= ifqstep34;
|
|
|
7403 |
if (xrpow[j + l] > cod_info.xrpow_max)
|
|
|
7404 |
cod_info.xrpow_max = xrpow[j + l];
|
|
|
7405 |
}
|
|
|
7406 |
|
|
|
7407 |
if (gfc.noise_shaping_amp == 2)
|
|
|
7408 |
return;
|
|
|
7409 |
}
|
|
|
7410 |
}
|
|
|
7411 |
|
|
|
7412 |
/**
|
|
|
7413 |
* Takehiro Tominaga 2000-xx-xx
|
|
|
7414 |
*
|
|
|
7415 |
* turns on scalefac scale and adjusts scalefactors
|
|
|
7416 |
*/
|
|
|
7417 |
function inc_scalefac_scale(cod_info, xrpow) {
|
|
|
7418 |
var ifqstep34 = 1.29683955465100964055;
|
|
|
7419 |
|
|
|
7420 |
var j = 0;
|
|
|
7421 |
for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) {
|
|
|
7422 |
var width = cod_info.width[sfb];
|
|
|
7423 |
var s = cod_info.scalefac[sfb];
|
|
|
7424 |
if (cod_info.preflag != 0)
|
|
|
7425 |
s += qupvt.pretab[sfb];
|
|
|
7426 |
j += width;
|
|
|
7427 |
if ((s & 1) != 0) {
|
|
|
7428 |
s++;
|
|
|
7429 |
for (var l = -width; l < 0; l++) {
|
|
|
7430 |
xrpow[j + l] *= ifqstep34;
|
|
|
7431 |
if (xrpow[j + l] > cod_info.xrpow_max)
|
|
|
7432 |
cod_info.xrpow_max = xrpow[j + l];
|
|
|
7433 |
}
|
|
|
7434 |
}
|
|
|
7435 |
cod_info.scalefac[sfb] = s >> 1;
|
|
|
7436 |
}
|
|
|
7437 |
cod_info.preflag = 0;
|
|
|
7438 |
cod_info.scalefac_scale = 1;
|
|
|
7439 |
}
|
|
|
7440 |
|
|
|
7441 |
/**
|
|
|
7442 |
* Takehiro Tominaga 2000-xx-xx
|
|
|
7443 |
*
|
|
|
7444 |
* increases the subblock gain and adjusts scalefactors
|
|
|
7445 |
*/
|
|
|
7446 |
function inc_subblock_gain(gfc, cod_info, xrpow) {
|
|
|
7447 |
var sfb;
|
|
|
7448 |
var scalefac = cod_info.scalefac;
|
|
|
7449 |
|
|
|
7450 |
/* subbloc_gain can't do anything in the long block region */
|
|
|
7451 |
for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) {
|
|
|
7452 |
if (scalefac[sfb] >= 16)
|
|
|
7453 |
return true;
|
|
|
7454 |
}
|
|
|
7455 |
|
|
|
7456 |
for (var window = 0; window < 3; window++) {
|
|
|
7457 |
var s1 = 0;
|
|
|
7458 |
var s2 = 0;
|
|
|
7459 |
|
|
|
7460 |
for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbdivide; sfb += 3) {
|
|
|
7461 |
if (s1 < scalefac[sfb])
|
|
|
7462 |
s1 = scalefac[sfb];
|
|
|
7463 |
}
|
|
|
7464 |
for (; sfb < cod_info.sfbmax; sfb += 3) {
|
|
|
7465 |
if (s2 < scalefac[sfb])
|
|
|
7466 |
s2 = scalefac[sfb];
|
|
|
7467 |
}
|
|
|
7468 |
|
|
|
7469 |
if (s1 < 16 && s2 < 8)
|
|
|
7470 |
continue;
|
|
|
7471 |
|
|
|
7472 |
if (cod_info.subblock_gain[window] >= 7)
|
|
|
7473 |
return true;
|
|
|
7474 |
|
|
|
7475 |
/*
|
|
|
7476 |
* even though there is no scalefactor for sfb12 subblock gain
|
|
|
7477 |
* affects upper frequencies too, that's why we have to go up to
|
|
|
7478 |
* SBMAX_s
|
|
|
7479 |
*/
|
|
|
7480 |
cod_info.subblock_gain[window]++;
|
|
|
7481 |
var j = gfc.scalefac_band.l[cod_info.sfb_lmax];
|
|
|
7482 |
for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbmax; sfb += 3) {
|
|
|
7483 |
var amp;
|
|
|
7484 |
var width = cod_info.width[sfb];
|
|
|
7485 |
var s = scalefac[sfb];
|
|
|
7486 |
s = s - (4 >> cod_info.scalefac_scale);
|
|
|
7487 |
if (s >= 0) {
|
|
|
7488 |
scalefac[sfb] = s;
|
|
|
7489 |
j += width * 3;
|
|
|
7490 |
continue;
|
|
|
7491 |
}
|
|
|
7492 |
|
|
|
7493 |
scalefac[sfb] = 0;
|
|
|
7494 |
{
|
|
|
7495 |
var gain = 210 + (s << (cod_info.scalefac_scale + 1));
|
|
|
7496 |
amp = qupvt.IPOW20(gain);
|
|
|
7497 |
}
|
|
|
7498 |
j += width * (window + 1);
|
|
|
7499 |
for (var l = -width; l < 0; l++) {
|
|
|
7500 |
xrpow[j + l] *= amp;
|
|
|
7501 |
if (xrpow[j + l] > cod_info.xrpow_max)
|
|
|
7502 |
cod_info.xrpow_max = xrpow[j + l];
|
|
|
7503 |
}
|
|
|
7504 |
j += width * (3 - window - 1);
|
|
|
7505 |
}
|
|
|
7506 |
|
|
|
7507 |
{
|
|
|
7508 |
var amp = qupvt.IPOW20(202);
|
|
|
7509 |
j += cod_info.width[sfb] * (window + 1);
|
|
|
7510 |
for (var l = -cod_info.width[sfb]; l < 0; l++) {
|
|
|
7511 |
xrpow[j + l] *= amp;
|
|
|
7512 |
if (xrpow[j + l] > cod_info.xrpow_max)
|
|
|
7513 |
cod_info.xrpow_max = xrpow[j + l];
|
|
|
7514 |
}
|
|
|
7515 |
}
|
|
|
7516 |
}
|
|
|
7517 |
return false;
|
|
|
7518 |
}
|
|
|
7519 |
|
|
|
7520 |
/**
|
|
|
7521 |
* <PRE>
|
|
|
7522 |
* Takehiro Tominaga /date??
|
|
|
7523 |
* Robert Hegemann 2000-09-06: made a function of it
|
|
|
7524 |
*
|
|
|
7525 |
* amplifies scalefactor bands,
|
|
|
7526 |
* - if all are already amplified returns 0
|
|
|
7527 |
* - if some bands are amplified too much:
|
|
|
7528 |
* * try to increase scalefac_scale
|
|
|
7529 |
* * if already scalefac_scale was set
|
|
|
7530 |
* try on short blocks to increase subblock gain
|
|
|
7531 |
* </PRE>
|
|
|
7532 |
*/
|
|
|
7533 |
function balance_noise(gfp, cod_info, distort, xrpow, bRefine) {
|
|
|
7534 |
var gfc = gfp.internal_flags;
|
|
|
7535 |
|
|
|
7536 |
amp_scalefac_bands(gfp, cod_info, distort, xrpow, bRefine);
|
|
|
7537 |
|
|
|
7538 |
/*
|
|
|
7539 |
* check to make sure we have not amplified too much loop_break returns
|
|
|
7540 |
* 0 if there is an unamplified scalefac scale_bitcount returns 0 if no
|
|
|
7541 |
* scalefactors are too large
|
|
|
7542 |
*/
|
|
|
7543 |
|
|
|
7544 |
var status = loop_break(cod_info);
|
|
|
7545 |
|
|
|
7546 |
if (status)
|
|
|
7547 |
return false;
|
|
|
7548 |
/* all bands amplified */
|
|
|
7549 |
|
|
|
7550 |
/*
|
|
|
7551 |
* not all scalefactors have been amplified. so these scalefacs are
|
|
|
7552 |
* possibly valid. encode them:
|
|
|
7553 |
*/
|
|
|
7554 |
if (gfc.mode_gr == 2)
|
|
|
7555 |
status = tk.scale_bitcount(cod_info);
|
|
|
7556 |
else
|
|
|
7557 |
status = tk.scale_bitcount_lsf(gfc, cod_info);
|
|
|
7558 |
|
|
|
7559 |
if (!status)
|
|
|
7560 |
return true;
|
|
|
7561 |
/* amplified some bands not exceeding limits */
|
|
|
7562 |
|
|
|
7563 |
/*
|
|
|
7564 |
* some scalefactors are too large. lets try setting scalefac_scale=1
|
|
|
7565 |
*/
|
|
|
7566 |
if (gfc.noise_shaping > 1) {
|
|
|
7567 |
Arrays.fill(gfc.pseudohalf, 0);
|
|
|
7568 |
if (0 == cod_info.scalefac_scale) {
|
|
|
7569 |
inc_scalefac_scale(cod_info, xrpow);
|
|
|
7570 |
status = false;
|
|
|
7571 |
} else {
|
|
|
7572 |
if (cod_info.block_type == Encoder.SHORT_TYPE
|
|
|
7573 |
&& gfc.subblock_gain > 0) {
|
|
|
7574 |
status = (inc_subblock_gain(gfc, cod_info, xrpow) || loop_break(cod_info));
|
|
|
7575 |
}
|
|
|
7576 |
}
|
|
|
7577 |
}
|
|
|
7578 |
|
|
|
7579 |
if (!status) {
|
|
|
7580 |
if (gfc.mode_gr == 2)
|
|
|
7581 |
status = tk.scale_bitcount(cod_info);
|
|
|
7582 |
else
|
|
|
7583 |
status = tk.scale_bitcount_lsf(gfc, cod_info);
|
|
|
7584 |
}
|
|
|
7585 |
return !status;
|
|
|
7586 |
}
|
|
|
7587 |
|
|
|
7588 |
/**
|
|
|
7589 |
* <PRE>
|
|
|
7590 |
* Function: The outer iteration loop controls the masking conditions
|
|
|
7591 |
* of all scalefactorbands. It computes the best scalefac and
|
|
|
7592 |
* global gain. This module calls the inner iteration loop
|
|
|
7593 |
*
|
|
|
7594 |
* mt 5/99 completely rewritten to allow for bit reservoir control,
|
|
|
7595 |
* mid/side channels with L/R or mid/side masking thresholds,
|
|
|
7596 |
* and chooses best quantization instead of last quantization when
|
|
|
7597 |
* no distortion free quantization can be found.
|
|
|
7598 |
*
|
|
|
7599 |
* added VBR support mt 5/99
|
|
|
7600 |
*
|
|
|
7601 |
* some code shuffle rh 9/00
|
|
|
7602 |
* </PRE>
|
|
|
7603 |
*
|
|
|
7604 |
* @param l3_xmin
|
|
|
7605 |
* allowed distortion
|
|
|
7606 |
* @param xrpow
|
|
|
7607 |
* coloured magnitudes of spectral
|
|
|
7608 |
* @param targ_bits
|
|
|
7609 |
* maximum allowed bits
|
|
|
7610 |
*/
|
|
|
7611 |
this.outer_loop = function (gfp, cod_info, l3_xmin, xrpow, ch, targ_bits) {
|
|
|
7612 |
var gfc = gfp.internal_flags;
|
|
|
7613 |
var cod_info_w = new GrInfo();
|
|
|
7614 |
var save_xrpow = new_float(576);
|
|
|
7615 |
var distort = new_float(L3Side.SFBMAX);
|
|
|
7616 |
var best_noise_info = new CalcNoiseResult();
|
|
|
7617 |
var better;
|
|
|
7618 |
var prev_noise = new CalcNoiseData();
|
|
|
7619 |
var best_part2_3_length = 9999999;
|
|
|
7620 |
var bEndOfSearch = false;
|
|
|
7621 |
var bRefine = false;
|
|
|
7622 |
var best_ggain_pass1 = 0;
|
|
|
7623 |
|
|
|
7624 |
bin_search_StepSize(gfc, cod_info, targ_bits, ch, xrpow);
|
|
|
7625 |
|
|
|
7626 |
if (0 == gfc.noise_shaping)
|
|
|
7627 |
/* fast mode, no noise shaping, we are ready */
|
|
|
7628 |
return 100;
|
|
|
7629 |
/* default noise_info.over_count */
|
|
|
7630 |
|
|
|
7631 |
/* compute the distortion in this quantization */
|
|
|
7632 |
/* coefficients and thresholds both l/r (or both mid/side) */
|
|
|
7633 |
qupvt.calc_noise(cod_info, l3_xmin, distort, best_noise_info,
|
|
|
7634 |
prev_noise);
|
|
|
7635 |
best_noise_info.bits = cod_info.part2_3_length;
|
|
|
7636 |
|
|
|
7637 |
cod_info_w.assign(cod_info);
|
|
|
7638 |
var age = 0;
|
|
|
7639 |
System.arraycopy(xrpow, 0, save_xrpow, 0, 576);
|
|
|
7640 |
|
|
|
7641 |
while (!bEndOfSearch) {
|
|
|
7642 |
/* BEGIN MAIN LOOP */
|
|
|
7643 |
do {
|
|
|
7644 |
var noise_info = new CalcNoiseResult();
|
|
|
7645 |
var search_limit;
|
|
|
7646 |
var maxggain = 255;
|
|
|
7647 |
|
|
|
7648 |
/*
|
|
|
7649 |
* When quantization with no distorted bands is found, allow up
|
|
|
7650 |
* to X new unsuccesful tries in serial. This gives us more
|
|
|
7651 |
* possibilities for different quant_compare modes. Much more
|
|
|
7652 |
* than 3 makes not a big difference, it is only slower.
|
|
|
7653 |
*/
|
|
|
7654 |
|
|
|
7655 |
if ((gfc.substep_shaping & 2) != 0) {
|
|
|
7656 |
search_limit = 20;
|
|
|
7657 |
} else {
|
|
|
7658 |
search_limit = 3;
|
|
|
7659 |
}
|
|
|
7660 |
|
|
|
7661 |
/*
|
|
|
7662 |
* Check if the last scalefactor band is distorted. in VBR mode
|
|
|
7663 |
* we can't get rid of the distortion, so quit now and VBR mode
|
|
|
7664 |
* will try again with more bits. (makes a 10% speed increase,
|
|
|
7665 |
* the files I tested were binary identical, 2000/05/20 Robert
|
|
|
7666 |
* Hegemann) distort[] > 1 means noise > allowed noise
|
|
|
7667 |
*/
|
|
|
7668 |
if (gfc.sfb21_extra) {
|
|
|
7669 |
if (distort[cod_info_w.sfbmax] > 1.0)
|
|
|
7670 |
break;
|
|
|
7671 |
if (cod_info_w.block_type == Encoder.SHORT_TYPE
|
|
|
7672 |
&& (distort[cod_info_w.sfbmax + 1] > 1.0 || distort[cod_info_w.sfbmax + 2] > 1.0))
|
|
|
7673 |
break;
|
|
|
7674 |
}
|
|
|
7675 |
|
|
|
7676 |
/* try a new scalefactor conbination on cod_info_w */
|
|
|
7677 |
if (!balance_noise(gfp, cod_info_w, distort, xrpow, bRefine))
|
|
|
7678 |
break;
|
|
|
7679 |
if (cod_info_w.scalefac_scale != 0)
|
|
|
7680 |
maxggain = 254;
|
|
|
7681 |
|
|
|
7682 |
/*
|
|
|
7683 |
* inner_loop starts with the initial quantization step computed
|
|
|
7684 |
* above and slowly increases until the bits < huff_bits. Thus
|
|
|
7685 |
* it is important not to start with too large of an inital
|
|
|
7686 |
* quantization step. Too small is ok, but inner_loop will take
|
|
|
7687 |
* longer
|
|
|
7688 |
*/
|
|
|
7689 |
var huff_bits = targ_bits - cod_info_w.part2_length;
|
|
|
7690 |
if (huff_bits <= 0)
|
|
|
7691 |
break;
|
|
|
7692 |
|
|
|
7693 |
/*
|
|
|
7694 |
* increase quantizer stepsize until needed bits are below
|
|
|
7695 |
* maximum
|
|
|
7696 |
*/
|
|
|
7697 |
while ((cod_info_w.part2_3_length = tk.count_bits(gfc, xrpow,
|
|
|
7698 |
cod_info_w, prev_noise)) > huff_bits
|
|
|
7699 |
&& cod_info_w.global_gain <= maxggain)
|
|
|
7700 |
cod_info_w.global_gain++;
|
|
|
7701 |
|
|
|
7702 |
if (cod_info_w.global_gain > maxggain)
|
|
|
7703 |
break;
|
|
|
7704 |
|
|
|
7705 |
if (best_noise_info.over_count == 0) {
|
|
|
7706 |
|
|
|
7707 |
while ((cod_info_w.part2_3_length = tk.count_bits(gfc,
|
|
|
7708 |
xrpow, cod_info_w, prev_noise)) > best_part2_3_length
|
|
|
7709 |
&& cod_info_w.global_gain <= maxggain)
|
|
|
7710 |
cod_info_w.global_gain++;
|
|
|
7711 |
|
|
|
7712 |
if (cod_info_w.global_gain > maxggain)
|
|
|
7713 |
break;
|
|
|
7714 |
}
|
|
|
7715 |
|
|
|
7716 |
/* compute the distortion in this quantization */
|
|
|
7717 |
qupvt.calc_noise(cod_info_w, l3_xmin, distort, noise_info,
|
|
|
7718 |
prev_noise);
|
|
|
7719 |
noise_info.bits = cod_info_w.part2_3_length;
|
|
|
7720 |
|
|
|
7721 |
/*
|
|
|
7722 |
* check if this quantization is better than our saved
|
|
|
7723 |
* quantization
|
|
|
7724 |
*/
|
|
|
7725 |
if (cod_info.block_type != Encoder.SHORT_TYPE) {
|
|
|
7726 |
// NORM, START or STOP type
|
|
|
7727 |
better = gfp.quant_comp;
|
|
|
7728 |
} else
|
|
|
7729 |
better = gfp.quant_comp_short;
|
|
|
7730 |
|
|
|
7731 |
better = quant_compare(better, best_noise_info, noise_info,
|
|
|
7732 |
cod_info_w, distort) ? 1 : 0;
|
|
|
7733 |
|
|
|
7734 |
/* save data so we can restore this quantization later */
|
|
|
7735 |
if (better != 0) {
|
|
|
7736 |
best_part2_3_length = cod_info.part2_3_length;
|
|
|
7737 |
best_noise_info = noise_info;
|
|
|
7738 |
cod_info.assign(cod_info_w);
|
|
|
7739 |
age = 0;
|
|
|
7740 |
/* save data so we can restore this quantization later */
|
|
|
7741 |
/* store for later reuse */
|
|
|
7742 |
System.arraycopy(xrpow, 0, save_xrpow, 0, 576);
|
|
|
7743 |
} else {
|
|
|
7744 |
/* early stop? */
|
|
|
7745 |
if (gfc.full_outer_loop == 0) {
|
|
|
7746 |
if (++age > search_limit
|
|
|
7747 |
&& best_noise_info.over_count == 0)
|
|
|
7748 |
break;
|
|
|
7749 |
if ((gfc.noise_shaping_amp == 3) && bRefine && age > 30)
|
|
|
7750 |
break;
|
|
|
7751 |
if ((gfc.noise_shaping_amp == 3)
|
|
|
7752 |
&& bRefine
|
|
|
7753 |
&& (cod_info_w.global_gain - best_ggain_pass1) > 15)
|
|
|
7754 |
break;
|
|
|
7755 |
}
|
|
|
7756 |
}
|
|
|
7757 |
} while ((cod_info_w.global_gain + cod_info_w.scalefac_scale) < 255);
|
|
|
7758 |
|
|
|
7759 |
if (gfc.noise_shaping_amp == 3) {
|
|
|
7760 |
if (!bRefine) {
|
|
|
7761 |
/* refine search */
|
|
|
7762 |
cod_info_w.assign(cod_info);
|
|
|
7763 |
System.arraycopy(save_xrpow, 0, xrpow, 0, 576);
|
|
|
7764 |
age = 0;
|
|
|
7765 |
best_ggain_pass1 = cod_info_w.global_gain;
|
|
|
7766 |
|
|
|
7767 |
bRefine = true;
|
|
|
7768 |
} else {
|
|
|
7769 |
/* search already refined, stop */
|
|
|
7770 |
bEndOfSearch = true;
|
|
|
7771 |
}
|
|
|
7772 |
|
|
|
7773 |
} else {
|
|
|
7774 |
bEndOfSearch = true;
|
|
|
7775 |
}
|
|
|
7776 |
}
|
|
|
7777 |
|
|
|
7778 |
/*
|
|
|
7779 |
* finish up
|
|
|
7780 |
*/
|
|
|
7781 |
if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh)
|
|
|
7782 |
/* restore for reuse on next try */
|
|
|
7783 |
System.arraycopy(save_xrpow, 0, xrpow, 0, 576);
|
|
|
7784 |
/*
|
|
|
7785 |
* do the 'substep shaping'
|
|
|
7786 |
*/
|
|
|
7787 |
else if ((gfc.substep_shaping & 1) != 0)
|
|
|
7788 |
trancate_smallspectrums(gfc, cod_info, l3_xmin, xrpow);
|
|
|
7789 |
|
|
|
7790 |
return best_noise_info.over_count;
|
|
|
7791 |
}
|
|
|
7792 |
|
|
|
7793 |
/**
|
|
|
7794 |
* Robert Hegemann 2000-09-06
|
|
|
7795 |
*
|
|
|
7796 |
* update reservoir status after FINAL quantization/bitrate
|
|
|
7797 |
*/
|
|
|
7798 |
this.iteration_finish_one = function (gfc, gr, ch) {
|
|
|
7799 |
var l3_side = gfc.l3_side;
|
|
|
7800 |
var cod_info = l3_side.tt[gr][ch];
|
|
|
7801 |
|
|
|
7802 |
/*
|
|
|
7803 |
* try some better scalefac storage
|
|
|
7804 |
*/
|
|
|
7805 |
tk.best_scalefac_store(gfc, gr, ch, l3_side);
|
|
|
7806 |
|
|
|
7807 |
/*
|
|
|
7808 |
* best huffman_divide may save some bits too
|
|
|
7809 |
*/
|
|
|
7810 |
if (gfc.use_best_huffman == 1)
|
|
|
7811 |
tk.best_huffman_divide(gfc, cod_info);
|
|
|
7812 |
|
|
|
7813 |
/*
|
|
|
7814 |
* update reservoir status after FINAL quantization/bitrate
|
|
|
7815 |
*/
|
|
|
7816 |
rv.ResvAdjust(gfc, cod_info);
|
|
|
7817 |
};
|
|
|
7818 |
|
|
|
7819 |
/**
|
|
|
7820 |
*
|
|
|
7821 |
* 2000-09-04 Robert Hegemann
|
|
|
7822 |
*
|
|
|
7823 |
* @param l3_xmin
|
|
|
7824 |
* allowed distortion of the scalefactor
|
|
|
7825 |
* @param xrpow
|
|
|
7826 |
* coloured magnitudes of spectral values
|
|
|
7827 |
*/
|
|
|
7828 |
this.VBR_encode_granule = function (gfp, cod_info, l3_xmin, xrpow, ch, min_bits, max_bits) {
|
|
|
7829 |
var gfc = gfp.internal_flags;
|
|
|
7830 |
var bst_cod_info = new GrInfo();
|
|
|
7831 |
var bst_xrpow = new_float(576);
|
|
|
7832 |
var Max_bits = max_bits;
|
|
|
7833 |
var real_bits = max_bits + 1;
|
|
|
7834 |
var this_bits = (max_bits + min_bits) / 2;
|
|
|
7835 |
var dbits, over, found = 0;
|
|
|
7836 |
var sfb21_extra = gfc.sfb21_extra;
|
|
|
7837 |
|
|
|
7838 |
Arrays.fill(bst_cod_info.l3_enc, 0);
|
|
|
7839 |
|
|
|
7840 |
/*
|
|
|
7841 |
* search within round about 40 bits of optimal
|
|
|
7842 |
*/
|
|
|
7843 |
do {
|
|
|
7844 |
|
|
|
7845 |
if (this_bits > Max_bits - 42)
|
|
|
7846 |
gfc.sfb21_extra = false;
|
|
|
7847 |
else
|
|
|
7848 |
gfc.sfb21_extra = sfb21_extra;
|
|
|
7849 |
|
|
|
7850 |
over = outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, this_bits);
|
|
|
7851 |
|
|
|
7852 |
/*
|
|
|
7853 |
* is quantization as good as we are looking for ? in this case: is
|
|
|
7854 |
* no scalefactor band distorted?
|
|
|
7855 |
*/
|
|
|
7856 |
if (over <= 0) {
|
|
|
7857 |
found = 1;
|
|
|
7858 |
/*
|
|
|
7859 |
* now we know it can be done with "real_bits" and maybe we can
|
|
|
7860 |
* skip some iterations
|
|
|
7861 |
*/
|
|
|
7862 |
real_bits = cod_info.part2_3_length;
|
|
|
7863 |
|
|
|
7864 |
/*
|
|
|
7865 |
* store best quantization so far
|
|
|
7866 |
*/
|
|
|
7867 |
bst_cod_info.assign(cod_info);
|
|
|
7868 |
System.arraycopy(xrpow, 0, bst_xrpow, 0, 576);
|
|
|
7869 |
|
|
|
7870 |
/*
|
|
|
7871 |
* try with fewer bits
|
|
|
7872 |
*/
|
|
|
7873 |
max_bits = real_bits - 32;
|
|
|
7874 |
dbits = max_bits - min_bits;
|
|
|
7875 |
this_bits = (max_bits + min_bits) / 2;
|
|
|
7876 |
} else {
|
|
|
7877 |
/*
|
|
|
7878 |
* try with more bits
|
|
|
7879 |
*/
|
|
|
7880 |
min_bits = this_bits + 32;
|
|
|
7881 |
dbits = max_bits - min_bits;
|
|
|
7882 |
this_bits = (max_bits + min_bits) / 2;
|
|
|
7883 |
|
|
|
7884 |
if (found != 0) {
|
|
|
7885 |
found = 2;
|
|
|
7886 |
/*
|
|
|
7887 |
* start again with best quantization so far
|
|
|
7888 |
*/
|
|
|
7889 |
cod_info.assign(bst_cod_info);
|
|
|
7890 |
System.arraycopy(bst_xrpow, 0, xrpow, 0, 576);
|
|
|
7891 |
}
|
|
|
7892 |
}
|
|
|
7893 |
} while (dbits > 12);
|
|
|
7894 |
|
|
|
7895 |
gfc.sfb21_extra = sfb21_extra;
|
|
|
7896 |
|
|
|
7897 |
/*
|
|
|
7898 |
* found=0 => nothing found, use last one found=1 => we just found the
|
|
|
7899 |
* best and left the loop found=2 => we restored a good one and have now
|
|
|
7900 |
* l3_enc to restore too
|
|
|
7901 |
*/
|
|
|
7902 |
if (found == 2) {
|
|
|
7903 |
System.arraycopy(bst_cod_info.l3_enc, 0, cod_info.l3_enc, 0, 576);
|
|
|
7904 |
}
|
|
|
7905 |
}
|
|
|
7906 |
|
|
|
7907 |
/**
|
|
|
7908 |
* Robert Hegemann 2000-09-05
|
|
|
7909 |
*
|
|
|
7910 |
* calculates * how many bits are available for analog silent granules * how
|
|
|
7911 |
* many bits to use for the lowest allowed bitrate * how many bits each
|
|
|
7912 |
* bitrate would provide
|
|
|
7913 |
*/
|
|
|
7914 |
this.get_framebits = function (gfp, frameBits) {
|
|
|
7915 |
var gfc = gfp.internal_flags;
|
|
|
7916 |
|
|
|
7917 |
/*
|
|
|
7918 |
* always use at least this many bits per granule per channel unless we
|
|
|
7919 |
* detect analog silence, see below
|
|
|
7920 |
*/
|
|
|
7921 |
gfc.bitrate_index = gfc.VBR_min_bitrate;
|
|
|
7922 |
var bitsPerFrame = bs.getframebits(gfp);
|
|
|
7923 |
|
|
|
7924 |
/*
|
|
|
7925 |
* bits for analog silence
|
|
|
7926 |
*/
|
|
|
7927 |
gfc.bitrate_index = 1;
|
|
|
7928 |
bitsPerFrame = bs.getframebits(gfp);
|
|
|
7929 |
|
|
|
7930 |
for (var i = 1; i <= gfc.VBR_max_bitrate; i++) {
|
|
|
7931 |
gfc.bitrate_index = i;
|
|
|
7932 |
var mb = new MeanBits(bitsPerFrame);
|
|
|
7933 |
frameBits[i] = rv.ResvFrameBegin(gfp, mb);
|
|
|
7934 |
bitsPerFrame = mb.bits;
|
|
|
7935 |
}
|
|
|
7936 |
};
|
|
|
7937 |
|
|
|
7938 |
/* RH: this one needs to be overhauled sometime */
|
|
|
7939 |
|
|
|
7940 |
/**
|
|
|
7941 |
* <PRE>
|
|
|
7942 |
* 2000-09-04 Robert Hegemann
|
|
|
7943 |
*
|
|
|
7944 |
* * converts LR to MS coding when necessary
|
|
|
7945 |
* * calculates allowed/adjusted quantization noise amounts
|
|
|
7946 |
* * detects analog silent frames
|
|
|
7947 |
*
|
|
|
7948 |
* some remarks:
|
|
|
7949 |
* - lower masking depending on Quality setting
|
|
|
7950 |
* - quality control together with adjusted ATH MDCT scaling
|
|
|
7951 |
* on lower quality setting allocate more noise from
|
|
|
7952 |
* ATH masking, and on higher quality setting allocate
|
|
|
7953 |
* less noise from ATH masking.
|
|
|
7954 |
* - experiments show that going more than 2dB over GPSYCHO's
|
|
|
7955 |
* limits ends up in very annoying artefacts
|
|
|
7956 |
* </PRE>
|
|
|
7957 |
*/
|
|
|
7958 |
this.VBR_old_prepare = function (gfp, pe, ms_ener_ratio, ratio, l3_xmin, frameBits, min_bits,
|
|
|
7959 |
max_bits, bands) {
|
|
|
7960 |
var gfc = gfp.internal_flags;
|
|
|
7961 |
|
|
|
7962 |
var masking_lower_db, adjust = 0.0;
|
|
|
7963 |
var analog_silence = 1;
|
|
|
7964 |
var bits = 0;
|
|
|
7965 |
|
|
|
7966 |
gfc.bitrate_index = gfc.VBR_max_bitrate;
|
|
|
7967 |
var avg = rv.ResvFrameBegin(gfp, new MeanBits(0)) / gfc.mode_gr;
|
|
|
7968 |
|
|
|
7969 |
get_framebits(gfp, frameBits);
|
|
|
7970 |
|
|
|
7971 |
for (var gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
7972 |
var mxb = qupvt.on_pe(gfp, pe, max_bits[gr], avg, gr, 0);
|
|
|
7973 |
if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) {
|
|
|
7974 |
ms_convert(gfc.l3_side, gr);
|
|
|
7975 |
qupvt.reduce_side(max_bits[gr], ms_ener_ratio[gr], avg, mxb);
|
|
|
7976 |
}
|
|
|
7977 |
for (var ch = 0; ch < gfc.channels_out; ++ch) {
|
|
|
7978 |
var cod_info = gfc.l3_side.tt[gr][ch];
|
|
|
7979 |
|
|
|
7980 |
if (cod_info.block_type != Encoder.SHORT_TYPE) {
|
|
|
7981 |
// NORM, START or STOP type
|
|
|
7982 |
adjust = 1.28 / (1 + Math
|
|
|
7983 |
.exp(3.5 - pe[gr][ch] / 300.)) - 0.05;
|
|
|
7984 |
masking_lower_db = gfc.PSY.mask_adjust - adjust;
|
|
|
7985 |
} else {
|
|
|
7986 |
adjust = 2.56 / (1 + Math
|
|
|
7987 |
.exp(3.5 - pe[gr][ch] / 300.)) - 0.14;
|
|
|
7988 |
masking_lower_db = gfc.PSY.mask_adjust_short - adjust;
|
|
|
7989 |
}
|
|
|
7990 |
gfc.masking_lower = Math.pow(10.0,
|
|
|
7991 |
masking_lower_db * 0.1);
|
|
|
7992 |
|
|
|
7993 |
init_outer_loop(gfc, cod_info);
|
|
|
7994 |
bands[gr][ch] = qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info,
|
|
|
7995 |
l3_xmin[gr][ch]);
|
|
|
7996 |
if (bands[gr][ch] != 0)
|
|
|
7997 |
analog_silence = 0;
|
|
|
7998 |
|
|
|
7999 |
min_bits[gr][ch] = 126;
|
|
|
8000 |
|
|
|
8001 |
bits += max_bits[gr][ch];
|
|
|
8002 |
}
|
|
|
8003 |
}
|
|
|
8004 |
for (var gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
8005 |
for (var ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
8006 |
if (bits > frameBits[gfc.VBR_max_bitrate]) {
|
|
|
8007 |
max_bits[gr][ch] *= frameBits[gfc.VBR_max_bitrate];
|
|
|
8008 |
max_bits[gr][ch] /= bits;
|
|
|
8009 |
}
|
|
|
8010 |
if (min_bits[gr][ch] > max_bits[gr][ch])
|
|
|
8011 |
min_bits[gr][ch] = max_bits[gr][ch];
|
|
|
8012 |
|
|
|
8013 |
}
|
|
|
8014 |
/* for ch */
|
|
|
8015 |
}
|
|
|
8016 |
/* for gr */
|
|
|
8017 |
|
|
|
8018 |
return analog_silence;
|
|
|
8019 |
};
|
|
|
8020 |
|
|
|
8021 |
this.bitpressure_strategy = function (gfc, l3_xmin, min_bits, max_bits) {
|
|
|
8022 |
for (var gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
8023 |
for (var ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
8024 |
var gi = gfc.l3_side.tt[gr][ch];
|
|
|
8025 |
var pxmin = l3_xmin[gr][ch];
|
|
|
8026 |
var pxminPos = 0;
|
|
|
8027 |
for (var sfb = 0; sfb < gi.psy_lmax; sfb++)
|
|
|
8028 |
pxmin[pxminPos++] *= 1. + .029 * sfb * sfb
|
|
|
8029 |
/ Encoder.SBMAX_l / Encoder.SBMAX_l;
|
|
|
8030 |
|
|
|
8031 |
if (gi.block_type == Encoder.SHORT_TYPE) {
|
|
|
8032 |
for (var sfb = gi.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) {
|
|
|
8033 |
pxmin[pxminPos++] *= 1. + .029 * sfb * sfb
|
|
|
8034 |
/ Encoder.SBMAX_s / Encoder.SBMAX_s;
|
|
|
8035 |
pxmin[pxminPos++] *= 1. + .029 * sfb * sfb
|
|
|
8036 |
/ Encoder.SBMAX_s / Encoder.SBMAX_s;
|
|
|
8037 |
pxmin[pxminPos++] *= 1. + .029 * sfb * sfb
|
|
|
8038 |
/ Encoder.SBMAX_s / Encoder.SBMAX_s;
|
|
|
8039 |
}
|
|
|
8040 |
}
|
|
|
8041 |
max_bits[gr][ch] = 0 | Math.max(min_bits[gr][ch],
|
|
|
8042 |
0.9 * max_bits[gr][ch]);
|
|
|
8043 |
}
|
|
|
8044 |
}
|
|
|
8045 |
};
|
|
|
8046 |
|
|
|
8047 |
this.VBR_new_prepare = function (gfp, pe, ratio, l3_xmin, frameBits, max_bits) {
|
|
|
8048 |
var gfc = gfp.internal_flags;
|
|
|
8049 |
|
|
|
8050 |
var analog_silence = 1;
|
|
|
8051 |
var avg = 0, bits = 0;
|
|
|
8052 |
var maximum_framebits;
|
|
|
8053 |
|
|
|
8054 |
if (!gfp.free_format) {
|
|
|
8055 |
gfc.bitrate_index = gfc.VBR_max_bitrate;
|
|
|
8056 |
|
|
|
8057 |
var mb = new MeanBits(avg);
|
|
|
8058 |
rv.ResvFrameBegin(gfp, mb);
|
|
|
8059 |
avg = mb.bits;
|
|
|
8060 |
|
|
|
8061 |
get_framebits(gfp, frameBits);
|
|
|
8062 |
maximum_framebits = frameBits[gfc.VBR_max_bitrate];
|
|
|
8063 |
} else {
|
|
|
8064 |
gfc.bitrate_index = 0;
|
|
|
8065 |
var mb = new MeanBits(avg);
|
|
|
8066 |
maximum_framebits = rv.ResvFrameBegin(gfp, mb);
|
|
|
8067 |
avg = mb.bits;
|
|
|
8068 |
frameBits[0] = maximum_framebits;
|
|
|
8069 |
}
|
|
|
8070 |
|
|
|
8071 |
for (var gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
8072 |
qupvt.on_pe(gfp, pe, max_bits[gr], avg, gr, 0);
|
|
|
8073 |
if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) {
|
|
|
8074 |
ms_convert(gfc.l3_side, gr);
|
|
|
8075 |
}
|
|
|
8076 |
for (var ch = 0; ch < gfc.channels_out; ++ch) {
|
|
|
8077 |
var cod_info = gfc.l3_side.tt[gr][ch];
|
|
|
8078 |
|
|
|
8079 |
gfc.masking_lower = Math.pow(10.0,
|
|
|
8080 |
gfc.PSY.mask_adjust * 0.1);
|
|
|
8081 |
|
|
|
8082 |
init_outer_loop(gfc, cod_info);
|
|
|
8083 |
if (0 != qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info,
|
|
|
8084 |
l3_xmin[gr][ch]))
|
|
|
8085 |
analog_silence = 0;
|
|
|
8086 |
|
|
|
8087 |
bits += max_bits[gr][ch];
|
|
|
8088 |
}
|
|
|
8089 |
}
|
|
|
8090 |
for (var gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
8091 |
for (var ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
8092 |
if (bits > maximum_framebits) {
|
|
|
8093 |
max_bits[gr][ch] *= maximum_framebits;
|
|
|
8094 |
max_bits[gr][ch] /= bits;
|
|
|
8095 |
}
|
|
|
8096 |
|
|
|
8097 |
}
|
|
|
8098 |
/* for ch */
|
|
|
8099 |
}
|
|
|
8100 |
/* for gr */
|
|
|
8101 |
|
|
|
8102 |
return analog_silence;
|
|
|
8103 |
};
|
|
|
8104 |
|
|
|
8105 |
/**
|
|
|
8106 |
* calculates target bits for ABR encoding
|
|
|
8107 |
*
|
|
|
8108 |
* mt 2000/05/31
|
|
|
8109 |
*/
|
|
|
8110 |
this.calc_target_bits = function (gfp, pe, ms_ener_ratio, targ_bits, analog_silence_bits, max_frame_bits) {
|
|
|
8111 |
var gfc = gfp.internal_flags;
|
|
|
8112 |
var l3_side = gfc.l3_side;
|
|
|
8113 |
var res_factor;
|
|
|
8114 |
var gr, ch, totbits, mean_bits = 0;
|
|
|
8115 |
|
|
|
8116 |
gfc.bitrate_index = gfc.VBR_max_bitrate;
|
|
|
8117 |
var mb = new MeanBits(mean_bits);
|
|
|
8118 |
max_frame_bits[0] = rv.ResvFrameBegin(gfp, mb);
|
|
|
8119 |
mean_bits = mb.bits;
|
|
|
8120 |
|
|
|
8121 |
gfc.bitrate_index = 1;
|
|
|
8122 |
mean_bits = bs.getframebits(gfp) - gfc.sideinfo_len * 8;
|
|
|
8123 |
analog_silence_bits[0] = mean_bits / (gfc.mode_gr * gfc.channels_out);
|
|
|
8124 |
|
|
|
8125 |
mean_bits = gfp.VBR_mean_bitrate_kbps * gfp.framesize * 1000;
|
|
|
8126 |
if ((gfc.substep_shaping & 1) != 0)
|
|
|
8127 |
mean_bits *= 1.09;
|
|
|
8128 |
mean_bits /= gfp.out_samplerate;
|
|
|
8129 |
mean_bits -= gfc.sideinfo_len * 8;
|
|
|
8130 |
mean_bits /= (gfc.mode_gr * gfc.channels_out);
|
|
|
8131 |
|
|
|
8132 |
/**
|
|
|
8133 |
* <PRE>
|
|
|
8134 |
* res_factor is the percentage of the target bitrate that should
|
|
|
8135 |
* be used on average. the remaining bits are added to the
|
|
|
8136 |
* bitreservoir and used for difficult to encode frames.
|
|
|
8137 |
*
|
|
|
8138 |
* Since we are tracking the average bitrate, we should adjust
|
|
|
8139 |
* res_factor "on the fly", increasing it if the average bitrate
|
|
|
8140 |
* is greater than the requested bitrate, and decreasing it
|
|
|
8141 |
* otherwise. Reasonable ranges are from .9 to 1.0
|
|
|
8142 |
*
|
|
|
8143 |
* Until we get the above suggestion working, we use the following
|
|
|
8144 |
* tuning:
|
|
|
8145 |
* compression ratio res_factor
|
|
|
8146 |
* 5.5 (256kbps) 1.0 no need for bitreservoir
|
|
|
8147 |
* 11 (128kbps) .93 7% held for reservoir
|
|
|
8148 |
*
|
|
|
8149 |
* with linear interpolation for other values.
|
|
|
8150 |
* </PRE>
|
|
|
8151 |
*/
|
|
|
8152 |
res_factor = .93 + .07 * (11.0 - gfp.compression_ratio)
|
|
|
8153 |
/ (11.0 - 5.5);
|
|
|
8154 |
if (res_factor < .90)
|
|
|
8155 |
res_factor = .90;
|
|
|
8156 |
if (res_factor > 1.00)
|
|
|
8157 |
res_factor = 1.00;
|
|
|
8158 |
|
|
|
8159 |
for (gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
8160 |
var sum = 0;
|
|
|
8161 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
8162 |
targ_bits[gr][ch] = (int)(res_factor * mean_bits);
|
|
|
8163 |
|
|
|
8164 |
if (pe[gr][ch] > 700) {
|
|
|
8165 |
var add_bits = (int)((pe[gr][ch] - 700) / 1.4);
|
|
|
8166 |
|
|
|
8167 |
var cod_info = l3_side.tt[gr][ch];
|
|
|
8168 |
targ_bits[gr][ch] = (int)(res_factor * mean_bits);
|
|
|
8169 |
|
|
|
8170 |
/* short blocks use a little extra, no matter what the pe */
|
|
|
8171 |
if (cod_info.block_type == Encoder.SHORT_TYPE) {
|
|
|
8172 |
if (add_bits < mean_bits / 2)
|
|
|
8173 |
add_bits = mean_bits / 2;
|
|
|
8174 |
}
|
|
|
8175 |
/* at most increase bits by 1.5*average */
|
|
|
8176 |
if (add_bits > mean_bits * 3 / 2)
|
|
|
8177 |
add_bits = mean_bits * 3 / 2;
|
|
|
8178 |
else if (add_bits < 0)
|
|
|
8179 |
add_bits = 0;
|
|
|
8180 |
|
|
|
8181 |
targ_bits[gr][ch] += add_bits;
|
|
|
8182 |
}
|
|
|
8183 |
if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) {
|
|
|
8184 |
targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL;
|
|
|
8185 |
}
|
|
|
8186 |
sum += targ_bits[gr][ch];
|
|
|
8187 |
}
|
|
|
8188 |
/* for ch */
|
|
|
8189 |
if (sum > LameInternalFlags.MAX_BITS_PER_GRANULE) {
|
|
|
8190 |
for (ch = 0; ch < gfc.channels_out; ++ch) {
|
|
|
8191 |
targ_bits[gr][ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE;
|
|
|
8192 |
targ_bits[gr][ch] /= sum;
|
|
|
8193 |
}
|
|
|
8194 |
}
|
|
|
8195 |
}
|
|
|
8196 |
/* for gr */
|
|
|
8197 |
|
|
|
8198 |
if (gfc.mode_ext == Encoder.MPG_MD_MS_LR)
|
|
|
8199 |
for (gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
8200 |
qupvt.reduce_side(targ_bits[gr], ms_ener_ratio[gr], mean_bits
|
|
|
8201 |
* gfc.channels_out,
|
|
|
8202 |
LameInternalFlags.MAX_BITS_PER_GRANULE);
|
|
|
8203 |
}
|
|
|
8204 |
|
|
|
8205 |
/*
|
|
|
8206 |
* sum target bits
|
|
|
8207 |
*/
|
|
|
8208 |
totbits = 0;
|
|
|
8209 |
for (gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
8210 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
8211 |
if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL)
|
|
|
8212 |
targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL;
|
|
|
8213 |
totbits += targ_bits[gr][ch];
|
|
|
8214 |
}
|
|
|
8215 |
}
|
|
|
8216 |
|
|
|
8217 |
/*
|
|
|
8218 |
* repartion target bits if needed
|
|
|
8219 |
*/
|
|
|
8220 |
if (totbits > max_frame_bits[0]) {
|
|
|
8221 |
for (gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
8222 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
8223 |
targ_bits[gr][ch] *= max_frame_bits[0];
|
|
|
8224 |
targ_bits[gr][ch] /= totbits;
|
|
|
8225 |
}
|
|
|
8226 |
}
|
|
|
8227 |
}
|
|
|
8228 |
}
|
|
|
8229 |
|
|
|
8230 |
}
|
|
|
8231 |
|
|
|
8232 |
/*
|
|
|
8233 |
* MP3 window subband -> subband filtering -> mdct routine
|
|
|
8234 |
*
|
|
|
8235 |
* Copyright (c) 1999-2000 Takehiro Tominaga
|
|
|
8236 |
*
|
|
|
8237 |
*
|
|
|
8238 |
* This library is free software; you can redistribute it and/or
|
|
|
8239 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
8240 |
* License as published by the Free Software Foundation; either
|
|
|
8241 |
* version 2 of the License, or (at your option) any later version.
|
|
|
8242 |
*
|
|
|
8243 |
* This library is distributed in the hope that it will be useful,
|
|
|
8244 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
8245 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
8246 |
* Library General Public License for more details.
|
|
|
8247 |
*
|
|
|
8248 |
* You should have received a copy of the GNU Library General Public
|
|
|
8249 |
* License along with this library; if not, write to the
|
|
|
8250 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
8251 |
* Boston, MA 02111-1307, USA.
|
|
|
8252 |
*/
|
|
|
8253 |
/*
|
|
|
8254 |
* Special Thanks to Patrick De Smet for your advices.
|
|
|
8255 |
*/
|
|
|
8256 |
|
|
|
8257 |
/* $Id: NewMDCT.java,v 1.11 2011/05/24 20:48:06 kenchis Exp $ */
|
|
|
8258 |
|
|
|
8259 |
//package mp3;
|
|
|
8260 |
|
|
|
8261 |
//import java.util.Arrays;
|
|
|
8262 |
|
|
|
8263 |
|
|
|
8264 |
|
|
|
8265 |
function NewMDCT() {
|
|
|
8266 |
|
|
|
8267 |
var enwindow = [
|
|
|
8268 |
-4.77e-07 * 0.740951125354959 / 2.384e-06,
|
|
|
8269 |
1.03951e-04 * 0.740951125354959 / 2.384e-06,
|
|
|
8270 |
9.53674e-04 * 0.740951125354959 / 2.384e-06,
|
|
|
8271 |
2.841473e-03 * 0.740951125354959 / 2.384e-06,
|
|
|
8272 |
3.5758972e-02 * 0.740951125354959 / 2.384e-06,
|
|
|
8273 |
3.401756e-03 * 0.740951125354959 / 2.384e-06,
|
|
|
8274 |
9.83715e-04 * 0.740951125354959 / 2.384e-06,
|
|
|
8275 |
9.9182e-05 * 0.740951125354959 / 2.384e-06, /* 15 */
|
|
|
8276 |
1.2398e-05 * 0.740951125354959 / 2.384e-06,
|
|
|
8277 |
1.91212e-04 * 0.740951125354959 / 2.384e-06,
|
|
|
8278 |
2.283096e-03 * 0.740951125354959 / 2.384e-06,
|
|
|
8279 |
1.6994476e-02 * 0.740951125354959 / 2.384e-06,
|
|
|
8280 |
-1.8756866e-02 * 0.740951125354959 / 2.384e-06,
|
|
|
8281 |
-2.630711e-03 * 0.740951125354959 / 2.384e-06,
|
|
|
8282 |
-2.47478e-04 * 0.740951125354959 / 2.384e-06,
|
|
|
8283 |
-1.4782e-05 * 0.740951125354959 / 2.384e-06,
|
|
|
8284 |
9.063471690191471e-01, 1.960342806591213e-01,
|
|
|
8285 |
|
|
|
8286 |
-4.77e-07 * 0.773010453362737 / 2.384e-06,
|
|
|
8287 |
1.05858e-04 * 0.773010453362737 / 2.384e-06,
|
|
|
8288 |
9.30786e-04 * 0.773010453362737 / 2.384e-06,
|
|
|
8289 |
2.521515e-03 * 0.773010453362737 / 2.384e-06,
|
|
|
8290 |
3.5694122e-02 * 0.773010453362737 / 2.384e-06,
|
|
|
8291 |
3.643036e-03 * 0.773010453362737 / 2.384e-06,
|
|
|
8292 |
9.91821e-04 * 0.773010453362737 / 2.384e-06,
|
|
|
8293 |
9.6321e-05 * 0.773010453362737 / 2.384e-06, /* 14 */
|
|
|
8294 |
1.1444e-05 * 0.773010453362737 / 2.384e-06,
|
|
|
8295 |
1.65462e-04 * 0.773010453362737 / 2.384e-06,
|
|
|
8296 |
2.110004e-03 * 0.773010453362737 / 2.384e-06,
|
|
|
8297 |
1.6112804e-02 * 0.773010453362737 / 2.384e-06,
|
|
|
8298 |
-1.9634247e-02 * 0.773010453362737 / 2.384e-06,
|
|
|
8299 |
-2.803326e-03 * 0.773010453362737 / 2.384e-06,
|
|
|
8300 |
-2.77042e-04 * 0.773010453362737 / 2.384e-06,
|
|
|
8301 |
-1.6689e-05 * 0.773010453362737 / 2.384e-06,
|
|
|
8302 |
8.206787908286602e-01, 3.901806440322567e-01,
|
|
|
8303 |
|
|
|
8304 |
-4.77e-07 * 0.803207531480645 / 2.384e-06,
|
|
|
8305 |
1.07288e-04 * 0.803207531480645 / 2.384e-06,
|
|
|
8306 |
9.02653e-04 * 0.803207531480645 / 2.384e-06,
|
|
|
8307 |
2.174854e-03 * 0.803207531480645 / 2.384e-06,
|
|
|
8308 |
3.5586357e-02 * 0.803207531480645 / 2.384e-06,
|
|
|
8309 |
3.858566e-03 * 0.803207531480645 / 2.384e-06,
|
|
|
8310 |
9.95159e-04 * 0.803207531480645 / 2.384e-06,
|
|
|
8311 |
9.3460e-05 * 0.803207531480645 / 2.384e-06, /* 13 */
|
|
|
8312 |
1.0014e-05 * 0.803207531480645 / 2.384e-06,
|
|
|
8313 |
1.40190e-04 * 0.803207531480645 / 2.384e-06,
|
|
|
8314 |
1.937389e-03 * 0.803207531480645 / 2.384e-06,
|
|
|
8315 |
1.5233517e-02 * 0.803207531480645 / 2.384e-06,
|
|
|
8316 |
-2.0506859e-02 * 0.803207531480645 / 2.384e-06,
|
|
|
8317 |
-2.974033e-03 * 0.803207531480645 / 2.384e-06,
|
|
|
8318 |
-3.07560e-04 * 0.803207531480645 / 2.384e-06,
|
|
|
8319 |
-1.8120e-05 * 0.803207531480645 / 2.384e-06,
|
|
|
8320 |
7.416505462720353e-01, 5.805693545089249e-01,
|
|
|
8321 |
|
|
|
8322 |
-4.77e-07 * 0.831469612302545 / 2.384e-06,
|
|
|
8323 |
1.08242e-04 * 0.831469612302545 / 2.384e-06,
|
|
|
8324 |
8.68797e-04 * 0.831469612302545 / 2.384e-06,
|
|
|
8325 |
1.800537e-03 * 0.831469612302545 / 2.384e-06,
|
|
|
8326 |
3.5435200e-02 * 0.831469612302545 / 2.384e-06,
|
|
|
8327 |
4.049301e-03 * 0.831469612302545 / 2.384e-06,
|
|
|
8328 |
9.94205e-04 * 0.831469612302545 / 2.384e-06,
|
|
|
8329 |
9.0599e-05 * 0.831469612302545 / 2.384e-06, /* 12 */
|
|
|
8330 |
9.060e-06 * 0.831469612302545 / 2.384e-06,
|
|
|
8331 |
1.16348e-04 * 0.831469612302545 / 2.384e-06,
|
|
|
8332 |
1.766682e-03 * 0.831469612302545 / 2.384e-06,
|
|
|
8333 |
1.4358521e-02 * 0.831469612302545 / 2.384e-06,
|
|
|
8334 |
-2.1372318e-02 * 0.831469612302545 / 2.384e-06,
|
|
|
8335 |
-3.14188e-03 * 0.831469612302545 / 2.384e-06,
|
|
|
8336 |
-3.39031e-04 * 0.831469612302545 / 2.384e-06,
|
|
|
8337 |
-1.9550e-05 * 0.831469612302545 / 2.384e-06,
|
|
|
8338 |
6.681786379192989e-01, 7.653668647301797e-01,
|
|
|
8339 |
|
|
|
8340 |
-4.77e-07 * 0.857728610000272 / 2.384e-06,
|
|
|
8341 |
1.08719e-04 * 0.857728610000272 / 2.384e-06,
|
|
|
8342 |
8.29220e-04 * 0.857728610000272 / 2.384e-06,
|
|
|
8343 |
1.399517e-03 * 0.857728610000272 / 2.384e-06,
|
|
|
8344 |
3.5242081e-02 * 0.857728610000272 / 2.384e-06,
|
|
|
8345 |
4.215240e-03 * 0.857728610000272 / 2.384e-06,
|
|
|
8346 |
9.89437e-04 * 0.857728610000272 / 2.384e-06,
|
|
|
8347 |
8.7261e-05 * 0.857728610000272 / 2.384e-06, /* 11 */
|
|
|
8348 |
8.106e-06 * 0.857728610000272 / 2.384e-06,
|
|
|
8349 |
9.3937e-05 * 0.857728610000272 / 2.384e-06,
|
|
|
8350 |
1.597881e-03 * 0.857728610000272 / 2.384e-06,
|
|
|
8351 |
1.3489246e-02 * 0.857728610000272 / 2.384e-06,
|
|
|
8352 |
-2.2228718e-02 * 0.857728610000272 / 2.384e-06,
|
|
|
8353 |
-3.306866e-03 * 0.857728610000272 / 2.384e-06,
|
|
|
8354 |
-3.71456e-04 * 0.857728610000272 / 2.384e-06,
|
|
|
8355 |
-2.1458e-05 * 0.857728610000272 / 2.384e-06,
|
|
|
8356 |
5.993769336819237e-01, 9.427934736519954e-01,
|
|
|
8357 |
|
|
|
8358 |
-4.77e-07 * 0.881921264348355 / 2.384e-06,
|
|
|
8359 |
1.08719e-04 * 0.881921264348355 / 2.384e-06,
|
|
|
8360 |
7.8392e-04 * 0.881921264348355 / 2.384e-06,
|
|
|
8361 |
9.71317e-04 * 0.881921264348355 / 2.384e-06,
|
|
|
8362 |
3.5007000e-02 * 0.881921264348355 / 2.384e-06,
|
|
|
8363 |
4.357815e-03 * 0.881921264348355 / 2.384e-06,
|
|
|
8364 |
9.80854e-04 * 0.881921264348355 / 2.384e-06,
|
|
|
8365 |
8.3923e-05 * 0.881921264348355 / 2.384e-06, /* 10 */
|
|
|
8366 |
7.629e-06 * 0.881921264348355 / 2.384e-06,
|
|
|
8367 |
7.2956e-05 * 0.881921264348355 / 2.384e-06,
|
|
|
8368 |
1.432419e-03 * 0.881921264348355 / 2.384e-06,
|
|
|
8369 |
1.2627602e-02 * 0.881921264348355 / 2.384e-06,
|
|
|
8370 |
-2.3074150e-02 * 0.881921264348355 / 2.384e-06,
|
|
|
8371 |
-3.467083e-03 * 0.881921264348355 / 2.384e-06,
|
|
|
8372 |
-4.04358e-04 * 0.881921264348355 / 2.384e-06,
|
|
|
8373 |
-2.3365e-05 * 0.881921264348355 / 2.384e-06,
|
|
|
8374 |
5.345111359507916e-01, 1.111140466039205e+00,
|
|
|
8375 |
|
|
|
8376 |
-9.54e-07 * 0.903989293123443 / 2.384e-06,
|
|
|
8377 |
1.08242e-04 * 0.903989293123443 / 2.384e-06,
|
|
|
8378 |
7.31945e-04 * 0.903989293123443 / 2.384e-06,
|
|
|
8379 |
5.15938e-04 * 0.903989293123443 / 2.384e-06,
|
|
|
8380 |
3.4730434e-02 * 0.903989293123443 / 2.384e-06,
|
|
|
8381 |
4.477024e-03 * 0.903989293123443 / 2.384e-06,
|
|
|
8382 |
9.68933e-04 * 0.903989293123443 / 2.384e-06,
|
|
|
8383 |
8.0585e-05 * 0.903989293123443 / 2.384e-06, /* 9 */
|
|
|
8384 |
6.676e-06 * 0.903989293123443 / 2.384e-06,
|
|
|
8385 |
5.2929e-05 * 0.903989293123443 / 2.384e-06,
|
|
|
8386 |
1.269817e-03 * 0.903989293123443 / 2.384e-06,
|
|
|
8387 |
1.1775017e-02 * 0.903989293123443 / 2.384e-06,
|
|
|
8388 |
-2.3907185e-02 * 0.903989293123443 / 2.384e-06,
|
|
|
8389 |
-3.622532e-03 * 0.903989293123443 / 2.384e-06,
|
|
|
8390 |
-4.38213e-04 * 0.903989293123443 / 2.384e-06,
|
|
|
8391 |
-2.5272e-05 * 0.903989293123443 / 2.384e-06,
|
|
|
8392 |
4.729647758913199e-01, 1.268786568327291e+00,
|
|
|
8393 |
|
|
|
8394 |
-9.54e-07 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8395 |
1.06812e-04 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8396 |
6.74248e-04 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8397 |
3.3379e-05 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8398 |
3.4412861e-02 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8399 |
4.573822e-03 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8400 |
9.54151e-04 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8401 |
7.6771e-05 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8402 |
6.199e-06 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8403 |
3.4332e-05 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8404 |
1.111031e-03 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8405 |
1.0933399e-02 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8406 |
-2.4725437e-02 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8407 |
-3.771782e-03 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8408 |
-4.72546e-04 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8409 |
-2.7657e-05 * 0.92387953251128675613 / 2.384e-06,
|
|
|
8410 |
4.1421356237309504879e-01, /* tan(PI/8) */
|
|
|
8411 |
1.414213562373095e+00,
|
|
|
8412 |
|
|
|
8413 |
-9.54e-07 * 0.941544065183021 / 2.384e-06,
|
|
|
8414 |
1.05381e-04 * 0.941544065183021 / 2.384e-06,
|
|
|
8415 |
6.10352e-04 * 0.941544065183021 / 2.384e-06,
|
|
|
8416 |
-4.75883e-04 * 0.941544065183021 / 2.384e-06,
|
|
|
8417 |
3.4055710e-02 * 0.941544065183021 / 2.384e-06,
|
|
|
8418 |
4.649162e-03 * 0.941544065183021 / 2.384e-06,
|
|
|
8419 |
9.35555e-04 * 0.941544065183021 / 2.384e-06,
|
|
|
8420 |
7.3433e-05 * 0.941544065183021 / 2.384e-06, /* 7 */
|
|
|
8421 |
5.245e-06 * 0.941544065183021 / 2.384e-06,
|
|
|
8422 |
1.7166e-05 * 0.941544065183021 / 2.384e-06,
|
|
|
8423 |
9.56535e-04 * 0.941544065183021 / 2.384e-06,
|
|
|
8424 |
1.0103703e-02 * 0.941544065183021 / 2.384e-06,
|
|
|
8425 |
-2.5527000e-02 * 0.941544065183021 / 2.384e-06,
|
|
|
8426 |
-3.914356e-03 * 0.941544065183021 / 2.384e-06,
|
|
|
8427 |
-5.07355e-04 * 0.941544065183021 / 2.384e-06,
|
|
|
8428 |
-3.0041e-05 * 0.941544065183021 / 2.384e-06,
|
|
|
8429 |
3.578057213145241e-01, 1.546020906725474e+00,
|
|
|
8430 |
|
|
|
8431 |
-9.54e-07 * 0.956940335732209 / 2.384e-06,
|
|
|
8432 |
1.02520e-04 * 0.956940335732209 / 2.384e-06,
|
|
|
8433 |
5.39303e-04 * 0.956940335732209 / 2.384e-06,
|
|
|
8434 |
-1.011848e-03 * 0.956940335732209 / 2.384e-06,
|
|
|
8435 |
3.3659935e-02 * 0.956940335732209 / 2.384e-06,
|
|
|
8436 |
4.703045e-03 * 0.956940335732209 / 2.384e-06,
|
|
|
8437 |
9.15051e-04 * 0.956940335732209 / 2.384e-06,
|
|
|
8438 |
7.0095e-05 * 0.956940335732209 / 2.384e-06, /* 6 */
|
|
|
8439 |
4.768e-06 * 0.956940335732209 / 2.384e-06,
|
|
|
8440 |
9.54e-07 * 0.956940335732209 / 2.384e-06,
|
|
|
8441 |
8.06808e-04 * 0.956940335732209 / 2.384e-06,
|
|
|
8442 |
9.287834e-03 * 0.956940335732209 / 2.384e-06,
|
|
|
8443 |
-2.6310921e-02 * 0.956940335732209 / 2.384e-06,
|
|
|
8444 |
-4.048824e-03 * 0.956940335732209 / 2.384e-06,
|
|
|
8445 |
-5.42164e-04 * 0.956940335732209 / 2.384e-06,
|
|
|
8446 |
-3.2425e-05 * 0.956940335732209 / 2.384e-06,
|
|
|
8447 |
3.033466836073424e-01, 1.662939224605090e+00,
|
|
|
8448 |
|
|
|
8449 |
-1.431e-06 * 0.970031253194544 / 2.384e-06,
|
|
|
8450 |
9.9182e-05 * 0.970031253194544 / 2.384e-06,
|
|
|
8451 |
4.62532e-04 * 0.970031253194544 / 2.384e-06,
|
|
|
8452 |
-1.573563e-03 * 0.970031253194544 / 2.384e-06,
|
|
|
8453 |
3.3225536e-02 * 0.970031253194544 / 2.384e-06,
|
|
|
8454 |
4.737377e-03 * 0.970031253194544 / 2.384e-06,
|
|
|
8455 |
8.91685e-04 * 0.970031253194544 / 2.384e-06,
|
|
|
8456 |
6.6280e-05 * 0.970031253194544 / 2.384e-06, /* 5 */
|
|
|
8457 |
4.292e-06 * 0.970031253194544 / 2.384e-06,
|
|
|
8458 |
-1.3828e-05 * 0.970031253194544 / 2.384e-06,
|
|
|
8459 |
6.61850e-04 * 0.970031253194544 / 2.384e-06,
|
|
|
8460 |
8.487225e-03 * 0.970031253194544 / 2.384e-06,
|
|
|
8461 |
-2.7073860e-02 * 0.970031253194544 / 2.384e-06,
|
|
|
8462 |
-4.174709e-03 * 0.970031253194544 / 2.384e-06,
|
|
|
8463 |
-5.76973e-04 * 0.970031253194544 / 2.384e-06,
|
|
|
8464 |
-3.4809e-05 * 0.970031253194544 / 2.384e-06,
|
|
|
8465 |
2.504869601913055e-01, 1.763842528696710e+00,
|
|
|
8466 |
|
|
|
8467 |
-1.431e-06 * 0.98078528040323 / 2.384e-06,
|
|
|
8468 |
9.5367e-05 * 0.98078528040323 / 2.384e-06,
|
|
|
8469 |
3.78609e-04 * 0.98078528040323 / 2.384e-06,
|
|
|
8470 |
-2.161503e-03 * 0.98078528040323 / 2.384e-06,
|
|
|
8471 |
3.2754898e-02 * 0.98078528040323 / 2.384e-06,
|
|
|
8472 |
4.752159e-03 * 0.98078528040323 / 2.384e-06,
|
|
|
8473 |
8.66413e-04 * 0.98078528040323 / 2.384e-06,
|
|
|
8474 |
6.2943e-05 * 0.98078528040323 / 2.384e-06, /* 4 */
|
|
|
8475 |
3.815e-06 * 0.98078528040323 / 2.384e-06,
|
|
|
8476 |
-2.718e-05 * 0.98078528040323 / 2.384e-06,
|
|
|
8477 |
5.22137e-04 * 0.98078528040323 / 2.384e-06,
|
|
|
8478 |
7.703304e-03 * 0.98078528040323 / 2.384e-06,
|
|
|
8479 |
-2.7815342e-02 * 0.98078528040323 / 2.384e-06,
|
|
|
8480 |
-4.290581e-03 * 0.98078528040323 / 2.384e-06,
|
|
|
8481 |
-6.11782e-04 * 0.98078528040323 / 2.384e-06,
|
|
|
8482 |
-3.7670e-05 * 0.98078528040323 / 2.384e-06,
|
|
|
8483 |
1.989123673796580e-01, 1.847759065022573e+00,
|
|
|
8484 |
|
|
|
8485 |
-1.907e-06 * 0.989176509964781 / 2.384e-06,
|
|
|
8486 |
9.0122e-05 * 0.989176509964781 / 2.384e-06,
|
|
|
8487 |
2.88486e-04 * 0.989176509964781 / 2.384e-06,
|
|
|
8488 |
-2.774239e-03 * 0.989176509964781 / 2.384e-06,
|
|
|
8489 |
3.2248020e-02 * 0.989176509964781 / 2.384e-06,
|
|
|
8490 |
4.748821e-03 * 0.989176509964781 / 2.384e-06,
|
|
|
8491 |
8.38757e-04 * 0.989176509964781 / 2.384e-06,
|
|
|
8492 |
5.9605e-05 * 0.989176509964781 / 2.384e-06, /* 3 */
|
|
|
8493 |
3.338e-06 * 0.989176509964781 / 2.384e-06,
|
|
|
8494 |
-3.9577e-05 * 0.989176509964781 / 2.384e-06,
|
|
|
8495 |
3.88145e-04 * 0.989176509964781 / 2.384e-06,
|
|
|
8496 |
6.937027e-03 * 0.989176509964781 / 2.384e-06,
|
|
|
8497 |
-2.8532982e-02 * 0.989176509964781 / 2.384e-06,
|
|
|
8498 |
-4.395962e-03 * 0.989176509964781 / 2.384e-06,
|
|
|
8499 |
-6.46591e-04 * 0.989176509964781 / 2.384e-06,
|
|
|
8500 |
-4.0531e-05 * 0.989176509964781 / 2.384e-06,
|
|
|
8501 |
1.483359875383474e-01, 1.913880671464418e+00,
|
|
|
8502 |
|
|
|
8503 |
-1.907e-06 * 0.995184726672197 / 2.384e-06,
|
|
|
8504 |
8.4400e-05 * 0.995184726672197 / 2.384e-06,
|
|
|
8505 |
1.91689e-04 * 0.995184726672197 / 2.384e-06,
|
|
|
8506 |
-3.411293e-03 * 0.995184726672197 / 2.384e-06,
|
|
|
8507 |
3.1706810e-02 * 0.995184726672197 / 2.384e-06,
|
|
|
8508 |
4.728317e-03 * 0.995184726672197 / 2.384e-06,
|
|
|
8509 |
8.09669e-04 * 0.995184726672197 / 2.384e-06,
|
|
|
8510 |
5.579e-05 * 0.995184726672197 / 2.384e-06,
|
|
|
8511 |
3.338e-06 * 0.995184726672197 / 2.384e-06,
|
|
|
8512 |
-5.0545e-05 * 0.995184726672197 / 2.384e-06,
|
|
|
8513 |
2.59876e-04 * 0.995184726672197 / 2.384e-06,
|
|
|
8514 |
6.189346e-03 * 0.995184726672197 / 2.384e-06,
|
|
|
8515 |
-2.9224873e-02 * 0.995184726672197 / 2.384e-06,
|
|
|
8516 |
-4.489899e-03 * 0.995184726672197 / 2.384e-06,
|
|
|
8517 |
-6.80923e-04 * 0.995184726672197 / 2.384e-06,
|
|
|
8518 |
-4.3392e-05 * 0.995184726672197 / 2.384e-06,
|
|
|
8519 |
9.849140335716425e-02, 1.961570560806461e+00,
|
|
|
8520 |
|
|
|
8521 |
-2.384e-06 * 0.998795456205172 / 2.384e-06,
|
|
|
8522 |
7.7724e-05 * 0.998795456205172 / 2.384e-06,
|
|
|
8523 |
8.8215e-05 * 0.998795456205172 / 2.384e-06,
|
|
|
8524 |
-4.072189e-03 * 0.998795456205172 / 2.384e-06,
|
|
|
8525 |
3.1132698e-02 * 0.998795456205172 / 2.384e-06,
|
|
|
8526 |
4.691124e-03 * 0.998795456205172 / 2.384e-06,
|
|
|
8527 |
7.79152e-04 * 0.998795456205172 / 2.384e-06,
|
|
|
8528 |
5.2929e-05 * 0.998795456205172 / 2.384e-06,
|
|
|
8529 |
2.861e-06 * 0.998795456205172 / 2.384e-06,
|
|
|
8530 |
-6.0558e-05 * 0.998795456205172 / 2.384e-06,
|
|
|
8531 |
1.37329e-04 * 0.998795456205172 / 2.384e-06,
|
|
|
8532 |
5.462170e-03 * 0.998795456205172 / 2.384e-06,
|
|
|
8533 |
-2.9890060e-02 * 0.998795456205172 / 2.384e-06,
|
|
|
8534 |
-4.570484e-03 * 0.998795456205172 / 2.384e-06,
|
|
|
8535 |
-7.14302e-04 * 0.998795456205172 / 2.384e-06,
|
|
|
8536 |
-4.6253e-05 * 0.998795456205172 / 2.384e-06,
|
|
|
8537 |
4.912684976946725e-02, 1.990369453344394e+00,
|
|
|
8538 |
|
|
|
8539 |
3.5780907e-02 * Util.SQRT2 * 0.5 / 2.384e-06,
|
|
|
8540 |
1.7876148e-02 * Util.SQRT2 * 0.5 / 2.384e-06,
|
|
|
8541 |
3.134727e-03 * Util.SQRT2 * 0.5 / 2.384e-06,
|
|
|
8542 |
2.457142e-03 * Util.SQRT2 * 0.5 / 2.384e-06,
|
|
|
8543 |
9.71317e-04 * Util.SQRT2 * 0.5 / 2.384e-06,
|
|
|
8544 |
2.18868e-04 * Util.SQRT2 * 0.5 / 2.384e-06,
|
|
|
8545 |
1.01566e-04 * Util.SQRT2 * 0.5 / 2.384e-06,
|
|
|
8546 |
1.3828e-05 * Util.SQRT2 * 0.5 / 2.384e-06,
|
|
|
8547 |
|
|
|
8548 |
3.0526638e-02 / 2.384e-06, 4.638195e-03 / 2.384e-06,
|
|
|
8549 |
7.47204e-04 / 2.384e-06, 4.9591e-05 / 2.384e-06,
|
|
|
8550 |
4.756451e-03 / 2.384e-06, 2.1458e-05 / 2.384e-06,
|
|
|
8551 |
-6.9618e-05 / 2.384e-06, /* 2.384e-06/2.384e-06 */
|
|
|
8552 |
];
|
|
|
8553 |
|
|
|
8554 |
var NS = 12;
|
|
|
8555 |
var NL = 36;
|
|
|
8556 |
|
|
|
8557 |
var win = [
|
|
|
8558 |
[
|
|
|
8559 |
2.382191739347913e-13,
|
|
|
8560 |
6.423305872147834e-13,
|
|
|
8561 |
9.400849094049688e-13,
|
|
|
8562 |
1.122435026096556e-12,
|
|
|
8563 |
1.183840321267481e-12,
|
|
|
8564 |
1.122435026096556e-12,
|
|
|
8565 |
9.400849094049690e-13,
|
|
|
8566 |
6.423305872147839e-13,
|
|
|
8567 |
2.382191739347918e-13,
|
|
|
8568 |
|
|
|
8569 |
5.456116108943412e-12,
|
|
|
8570 |
4.878985199565852e-12,
|
|
|
8571 |
4.240448995017367e-12,
|
|
|
8572 |
3.559909094758252e-12,
|
|
|
8573 |
2.858043359288075e-12,
|
|
|
8574 |
2.156177623817898e-12,
|
|
|
8575 |
1.475637723558783e-12,
|
|
|
8576 |
8.371015190102974e-13,
|
|
|
8577 |
2.599706096327376e-13,
|
|
|
8578 |
|
|
|
8579 |
-5.456116108943412e-12,
|
|
|
8580 |
-4.878985199565852e-12,
|
|
|
8581 |
-4.240448995017367e-12,
|
|
|
8582 |
-3.559909094758252e-12,
|
|
|
8583 |
-2.858043359288076e-12,
|
|
|
8584 |
-2.156177623817898e-12,
|
|
|
8585 |
-1.475637723558783e-12,
|
|
|
8586 |
-8.371015190102975e-13,
|
|
|
8587 |
-2.599706096327376e-13,
|
|
|
8588 |
|
|
|
8589 |
-2.382191739347923e-13,
|
|
|
8590 |
-6.423305872147843e-13,
|
|
|
8591 |
-9.400849094049696e-13,
|
|
|
8592 |
-1.122435026096556e-12,
|
|
|
8593 |
-1.183840321267481e-12,
|
|
|
8594 |
-1.122435026096556e-12,
|
|
|
8595 |
-9.400849094049694e-13,
|
|
|
8596 |
-6.423305872147840e-13,
|
|
|
8597 |
-2.382191739347918e-13,
|
|
|
8598 |
],
|
|
|
8599 |
[
|
|
|
8600 |
2.382191739347913e-13,
|
|
|
8601 |
6.423305872147834e-13,
|
|
|
8602 |
9.400849094049688e-13,
|
|
|
8603 |
1.122435026096556e-12,
|
|
|
8604 |
1.183840321267481e-12,
|
|
|
8605 |
1.122435026096556e-12,
|
|
|
8606 |
9.400849094049688e-13,
|
|
|
8607 |
6.423305872147841e-13,
|
|
|
8608 |
2.382191739347918e-13,
|
|
|
8609 |
|
|
|
8610 |
5.456116108943413e-12,
|
|
|
8611 |
4.878985199565852e-12,
|
|
|
8612 |
4.240448995017367e-12,
|
|
|
8613 |
3.559909094758253e-12,
|
|
|
8614 |
2.858043359288075e-12,
|
|
|
8615 |
2.156177623817898e-12,
|
|
|
8616 |
1.475637723558782e-12,
|
|
|
8617 |
8.371015190102975e-13,
|
|
|
8618 |
2.599706096327376e-13,
|
|
|
8619 |
|
|
|
8620 |
-5.461314069809755e-12,
|
|
|
8621 |
-4.921085770524055e-12,
|
|
|
8622 |
-4.343405037091838e-12,
|
|
|
8623 |
-3.732668368707687e-12,
|
|
|
8624 |
-3.093523840190885e-12,
|
|
|
8625 |
-2.430835727329465e-12,
|
|
|
8626 |
-1.734679010007751e-12,
|
|
|
8627 |
-9.748253656609281e-13,
|
|
|
8628 |
-2.797435120168326e-13,
|
|
|
8629 |
|
|
|
8630 |
0.000000000000000e+00,
|
|
|
8631 |
0.000000000000000e+00,
|
|
|
8632 |
0.000000000000000e+00,
|
|
|
8633 |
0.000000000000000e+00,
|
|
|
8634 |
0.000000000000000e+00,
|
|
|
8635 |
0.000000000000000e+00,
|
|
|
8636 |
-2.283748241799531e-13,
|
|
|
8637 |
-4.037858874020686e-13,
|
|
|
8638 |
-2.146547464825323e-13,
|
|
|
8639 |
],
|
|
|
8640 |
[
|
|
|
8641 |
1.316524975873958e-01, /* win[SHORT_TYPE] */
|
|
|
8642 |
4.142135623730950e-01,
|
|
|
8643 |
7.673269879789602e-01,
|
|
|
8644 |
|
|
|
8645 |
1.091308501069271e+00, /* tantab_l */
|
|
|
8646 |
1.303225372841206e+00,
|
|
|
8647 |
1.569685577117490e+00,
|
|
|
8648 |
1.920982126971166e+00,
|
|
|
8649 |
2.414213562373094e+00,
|
|
|
8650 |
3.171594802363212e+00,
|
|
|
8651 |
4.510708503662055e+00,
|
|
|
8652 |
7.595754112725146e+00,
|
|
|
8653 |
2.290376554843115e+01,
|
|
|
8654 |
|
|
|
8655 |
0.98480775301220802032, /* cx */
|
|
|
8656 |
0.64278760968653936292,
|
|
|
8657 |
0.34202014332566882393,
|
|
|
8658 |
0.93969262078590842791,
|
|
|
8659 |
-0.17364817766693030343,
|
|
|
8660 |
-0.76604444311897790243,
|
|
|
8661 |
0.86602540378443870761,
|
|
|
8662 |
0.500000000000000e+00,
|
|
|
8663 |
|
|
|
8664 |
-5.144957554275265e-01, /* ca */
|
|
|
8665 |
-4.717319685649723e-01,
|
|
|
8666 |
-3.133774542039019e-01,
|
|
|
8667 |
-1.819131996109812e-01,
|
|
|
8668 |
-9.457419252642064e-02,
|
|
|
8669 |
-4.096558288530405e-02,
|
|
|
8670 |
-1.419856857247115e-02,
|
|
|
8671 |
-3.699974673760037e-03,
|
|
|
8672 |
|
|
|
8673 |
8.574929257125442e-01, /* cs */
|
|
|
8674 |
8.817419973177052e-01,
|
|
|
8675 |
9.496286491027329e-01,
|
|
|
8676 |
9.833145924917901e-01,
|
|
|
8677 |
9.955178160675857e-01,
|
|
|
8678 |
9.991605581781475e-01,
|
|
|
8679 |
9.998991952444470e-01,
|
|
|
8680 |
9.999931550702802e-01,
|
|
|
8681 |
],
|
|
|
8682 |
[
|
|
|
8683 |
0.000000000000000e+00,
|
|
|
8684 |
0.000000000000000e+00,
|
|
|
8685 |
0.000000000000000e+00,
|
|
|
8686 |
0.000000000000000e+00,
|
|
|
8687 |
0.000000000000000e+00,
|
|
|
8688 |
0.000000000000000e+00,
|
|
|
8689 |
2.283748241799531e-13,
|
|
|
8690 |
4.037858874020686e-13,
|
|
|
8691 |
2.146547464825323e-13,
|
|
|
8692 |
|
|
|
8693 |
5.461314069809755e-12,
|
|
|
8694 |
4.921085770524055e-12,
|
|
|
8695 |
4.343405037091838e-12,
|
|
|
8696 |
3.732668368707687e-12,
|
|
|
8697 |
3.093523840190885e-12,
|
|
|
8698 |
2.430835727329466e-12,
|
|
|
8699 |
1.734679010007751e-12,
|
|
|
8700 |
9.748253656609281e-13,
|
|
|
8701 |
2.797435120168326e-13,
|
|
|
8702 |
|
|
|
8703 |
-5.456116108943413e-12,
|
|
|
8704 |
-4.878985199565852e-12,
|
|
|
8705 |
-4.240448995017367e-12,
|
|
|
8706 |
-3.559909094758253e-12,
|
|
|
8707 |
-2.858043359288075e-12,
|
|
|
8708 |
-2.156177623817898e-12,
|
|
|
8709 |
-1.475637723558782e-12,
|
|
|
8710 |
-8.371015190102975e-13,
|
|
|
8711 |
-2.599706096327376e-13,
|
|
|
8712 |
|
|
|
8713 |
-2.382191739347913e-13,
|
|
|
8714 |
-6.423305872147834e-13,
|
|
|
8715 |
-9.400849094049688e-13,
|
|
|
8716 |
-1.122435026096556e-12,
|
|
|
8717 |
-1.183840321267481e-12,
|
|
|
8718 |
-1.122435026096556e-12,
|
|
|
8719 |
-9.400849094049688e-13,
|
|
|
8720 |
-6.423305872147841e-13,
|
|
|
8721 |
-2.382191739347918e-13,
|
|
|
8722 |
]
|
|
|
8723 |
];
|
|
|
8724 |
|
|
|
8725 |
var tantab_l = win[Encoder.SHORT_TYPE];
|
|
|
8726 |
var cx = win[Encoder.SHORT_TYPE];
|
|
|
8727 |
var ca = win[Encoder.SHORT_TYPE];
|
|
|
8728 |
var cs = win[Encoder.SHORT_TYPE];
|
|
|
8729 |
|
|
|
8730 |
/**
|
|
|
8731 |
* new IDCT routine written by Takehiro TOMINAGA
|
|
|
8732 |
*
|
|
|
8733 |
* PURPOSE: Overlapping window on PCM samples<BR>
|
|
|
8734 |
*
|
|
|
8735 |
* SEMANTICS:<BR>
|
|
|
8736 |
* 32 16-bit pcm samples are scaled to fractional 2's complement and
|
|
|
8737 |
* concatenated to the end of the window buffer #x#. The updated window
|
|
|
8738 |
* buffer #x# is then windowed by the analysis window #c# to produce the
|
|
|
8739 |
* windowed sample #z#
|
|
|
8740 |
*/
|
|
|
8741 |
var order = [
|
|
|
8742 |
0, 1, 16, 17, 8, 9, 24, 25, 4, 5, 20, 21, 12, 13, 28, 29,
|
|
|
8743 |
2, 3, 18, 19, 10, 11, 26, 27, 6, 7, 22, 23, 14, 15, 30, 31
|
|
|
8744 |
];
|
|
|
8745 |
|
|
|
8746 |
/**
|
|
|
8747 |
* returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32
|
|
|
8748 |
*/
|
|
|
8749 |
function window_subband(x1, x1Pos, a) {
|
|
|
8750 |
var wp = 10;
|
|
|
8751 |
|
|
|
8752 |
var x2 = x1Pos + 238 - 14 - 286;
|
|
|
8753 |
|
|
|
8754 |
for (var i = -15; i < 0; i++) {
|
|
|
8755 |
var w, s, t;
|
|
|
8756 |
|
|
|
8757 |
w = enwindow[wp + -10];
|
|
|
8758 |
s = x1[x2 + -224] * w;
|
|
|
8759 |
t = x1[x1Pos + 224] * w;
|
|
|
8760 |
w = enwindow[wp + -9];
|
|
|
8761 |
s += x1[x2 + -160] * w;
|
|
|
8762 |
t += x1[x1Pos + 160] * w;
|
|
|
8763 |
w = enwindow[wp + -8];
|
|
|
8764 |
s += x1[x2 + -96] * w;
|
|
|
8765 |
t += x1[x1Pos + 96] * w;
|
|
|
8766 |
w = enwindow[wp + -7];
|
|
|
8767 |
s += x1[x2 + -32] * w;
|
|
|
8768 |
t += x1[x1Pos + 32] * w;
|
|
|
8769 |
w = enwindow[wp + -6];
|
|
|
8770 |
s += x1[x2 + 32] * w;
|
|
|
8771 |
t += x1[x1Pos + -32] * w;
|
|
|
8772 |
w = enwindow[wp + -5];
|
|
|
8773 |
s += x1[x2 + 96] * w;
|
|
|
8774 |
t += x1[x1Pos + -96] * w;
|
|
|
8775 |
w = enwindow[wp + -4];
|
|
|
8776 |
s += x1[x2 + 160] * w;
|
|
|
8777 |
t += x1[x1Pos + -160] * w;
|
|
|
8778 |
w = enwindow[wp + -3];
|
|
|
8779 |
s += x1[x2 + 224] * w;
|
|
|
8780 |
t += x1[x1Pos + -224] * w;
|
|
|
8781 |
|
|
|
8782 |
w = enwindow[wp + -2];
|
|
|
8783 |
s += x1[x1Pos + -256] * w;
|
|
|
8784 |
t -= x1[x2 + 256] * w;
|
|
|
8785 |
w = enwindow[wp + -1];
|
|
|
8786 |
s += x1[x1Pos + -192] * w;
|
|
|
8787 |
t -= x1[x2 + 192] * w;
|
|
|
8788 |
w = enwindow[wp + 0];
|
|
|
8789 |
s += x1[x1Pos + -128] * w;
|
|
|
8790 |
t -= x1[x2 + 128] * w;
|
|
|
8791 |
w = enwindow[wp + 1];
|
|
|
8792 |
s += x1[x1Pos + -64] * w;
|
|
|
8793 |
t -= x1[x2 + 64] * w;
|
|
|
8794 |
w = enwindow[wp + 2];
|
|
|
8795 |
s += x1[x1Pos + 0] * w;
|
|
|
8796 |
t -= x1[x2 + 0] * w;
|
|
|
8797 |
w = enwindow[wp + 3];
|
|
|
8798 |
s += x1[x1Pos + 64] * w;
|
|
|
8799 |
t -= x1[x2 + -64] * w;
|
|
|
8800 |
w = enwindow[wp + 4];
|
|
|
8801 |
s += x1[x1Pos + 128] * w;
|
|
|
8802 |
t -= x1[x2 + -128] * w;
|
|
|
8803 |
w = enwindow[wp + 5];
|
|
|
8804 |
s += x1[x1Pos + 192] * w;
|
|
|
8805 |
t -= x1[x2 + -192] * w;
|
|
|
8806 |
|
|
|
8807 |
/*
|
|
|
8808 |
* this multiplyer could be removed, but it needs more 256 FLOAT
|
|
|
8809 |
* data. thinking about the data cache performance, I think we
|
|
|
8810 |
* should not use such a huge table. tt 2000/Oct/25
|
|
|
8811 |
*/
|
|
|
8812 |
s *= enwindow[wp + 6];
|
|
|
8813 |
w = t - s;
|
|
|
8814 |
a[30 + i * 2] = t + s;
|
|
|
8815 |
a[31 + i * 2] = enwindow[wp + 7] * w;
|
|
|
8816 |
wp += 18;
|
|
|
8817 |
x1Pos--;
|
|
|
8818 |
x2++;
|
|
|
8819 |
}
|
|
|
8820 |
{
|
|
|
8821 |
var s, t, u, v;
|
|
|
8822 |
t = x1[x1Pos + -16] * enwindow[wp + -10];
|
|
|
8823 |
s = x1[x1Pos + -32] * enwindow[wp + -2];
|
|
|
8824 |
t += (x1[x1Pos + -48] - x1[x1Pos + 16]) * enwindow[wp + -9];
|
|
|
8825 |
s += x1[x1Pos + -96] * enwindow[wp + -1];
|
|
|
8826 |
t += (x1[x1Pos + -80] + x1[x1Pos + 48]) * enwindow[wp + -8];
|
|
|
8827 |
s += x1[x1Pos + -160] * enwindow[wp + 0];
|
|
|
8828 |
t += (x1[x1Pos + -112] - x1[x1Pos + 80]) * enwindow[wp + -7];
|
|
|
8829 |
s += x1[x1Pos + -224] * enwindow[wp + 1];
|
|
|
8830 |
t += (x1[x1Pos + -144] + x1[x1Pos + 112]) * enwindow[wp + -6];
|
|
|
8831 |
s -= x1[x1Pos + 32] * enwindow[wp + 2];
|
|
|
8832 |
t += (x1[x1Pos + -176] - x1[x1Pos + 144]) * enwindow[wp + -5];
|
|
|
8833 |
s -= x1[x1Pos + 96] * enwindow[wp + 3];
|
|
|
8834 |
t += (x1[x1Pos + -208] + x1[x1Pos + 176]) * enwindow[wp + -4];
|
|
|
8835 |
s -= x1[x1Pos + 160] * enwindow[wp + 4];
|
|
|
8836 |
t += (x1[x1Pos + -240] - x1[x1Pos + 208]) * enwindow[wp + -3];
|
|
|
8837 |
s -= x1[x1Pos + 224];
|
|
|
8838 |
|
|
|
8839 |
u = s - t;
|
|
|
8840 |
v = s + t;
|
|
|
8841 |
|
|
|
8842 |
t = a[14];
|
|
|
8843 |
s = a[15] - t;
|
|
|
8844 |
|
|
|
8845 |
a[31] = v + t; /* A0 */
|
|
|
8846 |
a[30] = u + s; /* A1 */
|
|
|
8847 |
a[15] = u - s; /* A2 */
|
|
|
8848 |
a[14] = v - t; /* A3 */
|
|
|
8849 |
}
|
|
|
8850 |
{
|
|
|
8851 |
var xr;
|
|
|
8852 |
xr = a[28] - a[0];
|
|
|
8853 |
a[0] += a[28];
|
|
|
8854 |
a[28] = xr * enwindow[wp + -2 * 18 + 7];
|
|
|
8855 |
xr = a[29] - a[1];
|
|
|
8856 |
a[1] += a[29];
|
|
|
8857 |
a[29] = xr * enwindow[wp + -2 * 18 + 7];
|
|
|
8858 |
|
|
|
8859 |
xr = a[26] - a[2];
|
|
|
8860 |
a[2] += a[26];
|
|
|
8861 |
a[26] = xr * enwindow[wp + -4 * 18 + 7];
|
|
|
8862 |
xr = a[27] - a[3];
|
|
|
8863 |
a[3] += a[27];
|
|
|
8864 |
a[27] = xr * enwindow[wp + -4 * 18 + 7];
|
|
|
8865 |
|
|
|
8866 |
xr = a[24] - a[4];
|
|
|
8867 |
a[4] += a[24];
|
|
|
8868 |
a[24] = xr * enwindow[wp + -6 * 18 + 7];
|
|
|
8869 |
xr = a[25] - a[5];
|
|
|
8870 |
a[5] += a[25];
|
|
|
8871 |
a[25] = xr * enwindow[wp + -6 * 18 + 7];
|
|
|
8872 |
|
|
|
8873 |
xr = a[22] - a[6];
|
|
|
8874 |
a[6] += a[22];
|
|
|
8875 |
a[22] = xr * Util.SQRT2;
|
|
|
8876 |
xr = a[23] - a[7];
|
|
|
8877 |
a[7] += a[23];
|
|
|
8878 |
a[23] = xr * Util.SQRT2 - a[7];
|
|
|
8879 |
a[7] -= a[6];
|
|
|
8880 |
a[22] -= a[7];
|
|
|
8881 |
a[23] -= a[22];
|
|
|
8882 |
|
|
|
8883 |
xr = a[6];
|
|
|
8884 |
a[6] = a[31] - xr;
|
|
|
8885 |
a[31] = a[31] + xr;
|
|
|
8886 |
xr = a[7];
|
|
|
8887 |
a[7] = a[30] - xr;
|
|
|
8888 |
a[30] = a[30] + xr;
|
|
|
8889 |
xr = a[22];
|
|
|
8890 |
a[22] = a[15] - xr;
|
|
|
8891 |
a[15] = a[15] + xr;
|
|
|
8892 |
xr = a[23];
|
|
|
8893 |
a[23] = a[14] - xr;
|
|
|
8894 |
a[14] = a[14] + xr;
|
|
|
8895 |
|
|
|
8896 |
xr = a[20] - a[8];
|
|
|
8897 |
a[8] += a[20];
|
|
|
8898 |
a[20] = xr * enwindow[wp + -10 * 18 + 7];
|
|
|
8899 |
xr = a[21] - a[9];
|
|
|
8900 |
a[9] += a[21];
|
|
|
8901 |
a[21] = xr * enwindow[wp + -10 * 18 + 7];
|
|
|
8902 |
|
|
|
8903 |
xr = a[18] - a[10];
|
|
|
8904 |
a[10] += a[18];
|
|
|
8905 |
a[18] = xr * enwindow[wp + -12 * 18 + 7];
|
|
|
8906 |
xr = a[19] - a[11];
|
|
|
8907 |
a[11] += a[19];
|
|
|
8908 |
a[19] = xr * enwindow[wp + -12 * 18 + 7];
|
|
|
8909 |
|
|
|
8910 |
xr = a[16] - a[12];
|
|
|
8911 |
a[12] += a[16];
|
|
|
8912 |
a[16] = xr * enwindow[wp + -14 * 18 + 7];
|
|
|
8913 |
xr = a[17] - a[13];
|
|
|
8914 |
a[13] += a[17];
|
|
|
8915 |
a[17] = xr * enwindow[wp + -14 * 18 + 7];
|
|
|
8916 |
|
|
|
8917 |
xr = -a[20] + a[24];
|
|
|
8918 |
a[20] += a[24];
|
|
|
8919 |
a[24] = xr * enwindow[wp + -12 * 18 + 7];
|
|
|
8920 |
xr = -a[21] + a[25];
|
|
|
8921 |
a[21] += a[25];
|
|
|
8922 |
a[25] = xr * enwindow[wp + -12 * 18 + 7];
|
|
|
8923 |
|
|
|
8924 |
xr = a[4] - a[8];
|
|
|
8925 |
a[4] += a[8];
|
|
|
8926 |
a[8] = xr * enwindow[wp + -12 * 18 + 7];
|
|
|
8927 |
xr = a[5] - a[9];
|
|
|
8928 |
a[5] += a[9];
|
|
|
8929 |
a[9] = xr * enwindow[wp + -12 * 18 + 7];
|
|
|
8930 |
|
|
|
8931 |
xr = a[0] - a[12];
|
|
|
8932 |
a[0] += a[12];
|
|
|
8933 |
a[12] = xr * enwindow[wp + -4 * 18 + 7];
|
|
|
8934 |
xr = a[1] - a[13];
|
|
|
8935 |
a[1] += a[13];
|
|
|
8936 |
a[13] = xr * enwindow[wp + -4 * 18 + 7];
|
|
|
8937 |
xr = a[16] - a[28];
|
|
|
8938 |
a[16] += a[28];
|
|
|
8939 |
a[28] = xr * enwindow[wp + -4 * 18 + 7];
|
|
|
8940 |
xr = -a[17] + a[29];
|
|
|
8941 |
a[17] += a[29];
|
|
|
8942 |
a[29] = xr * enwindow[wp + -4 * 18 + 7];
|
|
|
8943 |
|
|
|
8944 |
xr = Util.SQRT2 * (a[2] - a[10]);
|
|
|
8945 |
a[2] += a[10];
|
|
|
8946 |
a[10] = xr;
|
|
|
8947 |
xr = Util.SQRT2 * (a[3] - a[11]);
|
|
|
8948 |
a[3] += a[11];
|
|
|
8949 |
a[11] = xr;
|
|
|
8950 |
xr = Util.SQRT2 * (-a[18] + a[26]);
|
|
|
8951 |
a[18] += a[26];
|
|
|
8952 |
a[26] = xr - a[18];
|
|
|
8953 |
xr = Util.SQRT2 * (-a[19] + a[27]);
|
|
|
8954 |
a[19] += a[27];
|
|
|
8955 |
a[27] = xr - a[19];
|
|
|
8956 |
|
|
|
8957 |
xr = a[2];
|
|
|
8958 |
a[19] -= a[3];
|
|
|
8959 |
a[3] -= xr;
|
|
|
8960 |
a[2] = a[31] - xr;
|
|
|
8961 |
a[31] += xr;
|
|
|
8962 |
xr = a[3];
|
|
|
8963 |
a[11] -= a[19];
|
|
|
8964 |
a[18] -= xr;
|
|
|
8965 |
a[3] = a[30] - xr;
|
|
|
8966 |
a[30] += xr;
|
|
|
8967 |
xr = a[18];
|
|
|
8968 |
a[27] -= a[11];
|
|
|
8969 |
a[19] -= xr;
|
|
|
8970 |
a[18] = a[15] - xr;
|
|
|
8971 |
a[15] += xr;
|
|
|
8972 |
|
|
|
8973 |
xr = a[19];
|
|
|
8974 |
a[10] -= xr;
|
|
|
8975 |
a[19] = a[14] - xr;
|
|
|
8976 |
a[14] += xr;
|
|
|
8977 |
xr = a[10];
|
|
|
8978 |
a[11] -= xr;
|
|
|
8979 |
a[10] = a[23] - xr;
|
|
|
8980 |
a[23] += xr;
|
|
|
8981 |
xr = a[11];
|
|
|
8982 |
a[26] -= xr;
|
|
|
8983 |
a[11] = a[22] - xr;
|
|
|
8984 |
a[22] += xr;
|
|
|
8985 |
xr = a[26];
|
|
|
8986 |
a[27] -= xr;
|
|
|
8987 |
a[26] = a[7] - xr;
|
|
|
8988 |
a[7] += xr;
|
|
|
8989 |
|
|
|
8990 |
xr = a[27];
|
|
|
8991 |
a[27] = a[6] - xr;
|
|
|
8992 |
a[6] += xr;
|
|
|
8993 |
|
|
|
8994 |
xr = Util.SQRT2 * (a[0] - a[4]);
|
|
|
8995 |
a[0] += a[4];
|
|
|
8996 |
a[4] = xr;
|
|
|
8997 |
xr = Util.SQRT2 * (a[1] - a[5]);
|
|
|
8998 |
a[1] += a[5];
|
|
|
8999 |
a[5] = xr;
|
|
|
9000 |
xr = Util.SQRT2 * (a[16] - a[20]);
|
|
|
9001 |
a[16] += a[20];
|
|
|
9002 |
a[20] = xr;
|
|
|
9003 |
xr = Util.SQRT2 * (a[17] - a[21]);
|
|
|
9004 |
a[17] += a[21];
|
|
|
9005 |
a[21] = xr;
|
|
|
9006 |
|
|
|
9007 |
xr = -Util.SQRT2 * (a[8] - a[12]);
|
|
|
9008 |
a[8] += a[12];
|
|
|
9009 |
a[12] = xr - a[8];
|
|
|
9010 |
xr = -Util.SQRT2 * (a[9] - a[13]);
|
|
|
9011 |
a[9] += a[13];
|
|
|
9012 |
a[13] = xr - a[9];
|
|
|
9013 |
xr = -Util.SQRT2 * (a[25] - a[29]);
|
|
|
9014 |
a[25] += a[29];
|
|
|
9015 |
a[29] = xr - a[25];
|
|
|
9016 |
xr = -Util.SQRT2 * (a[24] + a[28]);
|
|
|
9017 |
a[24] -= a[28];
|
|
|
9018 |
a[28] = xr - a[24];
|
|
|
9019 |
|
|
|
9020 |
xr = a[24] - a[16];
|
|
|
9021 |
a[24] = xr;
|
|
|
9022 |
xr = a[20] - xr;
|
|
|
9023 |
a[20] = xr;
|
|
|
9024 |
xr = a[28] - xr;
|
|
|
9025 |
a[28] = xr;
|
|
|
9026 |
|
|
|
9027 |
xr = a[25] - a[17];
|
|
|
9028 |
a[25] = xr;
|
|
|
9029 |
xr = a[21] - xr;
|
|
|
9030 |
a[21] = xr;
|
|
|
9031 |
xr = a[29] - xr;
|
|
|
9032 |
a[29] = xr;
|
|
|
9033 |
|
|
|
9034 |
xr = a[17] - a[1];
|
|
|
9035 |
a[17] = xr;
|
|
|
9036 |
xr = a[9] - xr;
|
|
|
9037 |
a[9] = xr;
|
|
|
9038 |
xr = a[25] - xr;
|
|
|
9039 |
a[25] = xr;
|
|
|
9040 |
xr = a[5] - xr;
|
|
|
9041 |
a[5] = xr;
|
|
|
9042 |
xr = a[21] - xr;
|
|
|
9043 |
a[21] = xr;
|
|
|
9044 |
xr = a[13] - xr;
|
|
|
9045 |
a[13] = xr;
|
|
|
9046 |
xr = a[29] - xr;
|
|
|
9047 |
a[29] = xr;
|
|
|
9048 |
|
|
|
9049 |
xr = a[1] - a[0];
|
|
|
9050 |
a[1] = xr;
|
|
|
9051 |
xr = a[16] - xr;
|
|
|
9052 |
a[16] = xr;
|
|
|
9053 |
xr = a[17] - xr;
|
|
|
9054 |
a[17] = xr;
|
|
|
9055 |
xr = a[8] - xr;
|
|
|
9056 |
a[8] = xr;
|
|
|
9057 |
xr = a[9] - xr;
|
|
|
9058 |
a[9] = xr;
|
|
|
9059 |
xr = a[24] - xr;
|
|
|
9060 |
a[24] = xr;
|
|
|
9061 |
xr = a[25] - xr;
|
|
|
9062 |
a[25] = xr;
|
|
|
9063 |
xr = a[4] - xr;
|
|
|
9064 |
a[4] = xr;
|
|
|
9065 |
xr = a[5] - xr;
|
|
|
9066 |
a[5] = xr;
|
|
|
9067 |
xr = a[20] - xr;
|
|
|
9068 |
a[20] = xr;
|
|
|
9069 |
xr = a[21] - xr;
|
|
|
9070 |
a[21] = xr;
|
|
|
9071 |
xr = a[12] - xr;
|
|
|
9072 |
a[12] = xr;
|
|
|
9073 |
xr = a[13] - xr;
|
|
|
9074 |
a[13] = xr;
|
|
|
9075 |
xr = a[28] - xr;
|
|
|
9076 |
a[28] = xr;
|
|
|
9077 |
xr = a[29] - xr;
|
|
|
9078 |
a[29] = xr;
|
|
|
9079 |
|
|
|
9080 |
xr = a[0];
|
|
|
9081 |
a[0] += a[31];
|
|
|
9082 |
a[31] -= xr;
|
|
|
9083 |
xr = a[1];
|
|
|
9084 |
a[1] += a[30];
|
|
|
9085 |
a[30] -= xr;
|
|
|
9086 |
xr = a[16];
|
|
|
9087 |
a[16] += a[15];
|
|
|
9088 |
a[15] -= xr;
|
|
|
9089 |
xr = a[17];
|
|
|
9090 |
a[17] += a[14];
|
|
|
9091 |
a[14] -= xr;
|
|
|
9092 |
xr = a[8];
|
|
|
9093 |
a[8] += a[23];
|
|
|
9094 |
a[23] -= xr;
|
|
|
9095 |
xr = a[9];
|
|
|
9096 |
a[9] += a[22];
|
|
|
9097 |
a[22] -= xr;
|
|
|
9098 |
xr = a[24];
|
|
|
9099 |
a[24] += a[7];
|
|
|
9100 |
a[7] -= xr;
|
|
|
9101 |
xr = a[25];
|
|
|
9102 |
a[25] += a[6];
|
|
|
9103 |
a[6] -= xr;
|
|
|
9104 |
xr = a[4];
|
|
|
9105 |
a[4] += a[27];
|
|
|
9106 |
a[27] -= xr;
|
|
|
9107 |
xr = a[5];
|
|
|
9108 |
a[5] += a[26];
|
|
|
9109 |
a[26] -= xr;
|
|
|
9110 |
xr = a[20];
|
|
|
9111 |
a[20] += a[11];
|
|
|
9112 |
a[11] -= xr;
|
|
|
9113 |
xr = a[21];
|
|
|
9114 |
a[21] += a[10];
|
|
|
9115 |
a[10] -= xr;
|
|
|
9116 |
xr = a[12];
|
|
|
9117 |
a[12] += a[19];
|
|
|
9118 |
a[19] -= xr;
|
|
|
9119 |
xr = a[13];
|
|
|
9120 |
a[13] += a[18];
|
|
|
9121 |
a[18] -= xr;
|
|
|
9122 |
xr = a[28];
|
|
|
9123 |
a[28] += a[3];
|
|
|
9124 |
a[3] -= xr;
|
|
|
9125 |
xr = a[29];
|
|
|
9126 |
a[29] += a[2];
|
|
|
9127 |
a[2] -= xr;
|
|
|
9128 |
}
|
|
|
9129 |
}
|
|
|
9130 |
|
|
|
9131 |
/**
|
|
|
9132 |
* Function: Calculation of the MDCT In the case of long blocks (type 0,1,3)
|
|
|
9133 |
* there are 36 coefficents in the time domain and 18 in the frequency
|
|
|
9134 |
* domain.<BR>
|
|
|
9135 |
* In the case of short blocks (type 2) there are 3 transformations with
|
|
|
9136 |
* short length. This leads to 12 coefficents in the time and 6 in the
|
|
|
9137 |
* frequency domain. In this case the results are stored side by side in the
|
|
|
9138 |
* vector out[].
|
|
|
9139 |
*
|
|
|
9140 |
* New layer3
|
|
|
9141 |
*/
|
|
|
9142 |
function mdct_short(inout, inoutPos) {
|
|
|
9143 |
for (var l = 0; l < 3; l++) {
|
|
|
9144 |
var tc0, tc1, tc2, ts0, ts1, ts2;
|
|
|
9145 |
|
|
|
9146 |
ts0 = inout[inoutPos + 2 * 3] * win[Encoder.SHORT_TYPE][0]
|
|
|
9147 |
- inout[inoutPos + 5 * 3];
|
|
|
9148 |
tc0 = inout[inoutPos + 0 * 3] * win[Encoder.SHORT_TYPE][2]
|
|
|
9149 |
- inout[inoutPos + 3 * 3];
|
|
|
9150 |
tc1 = ts0 + tc0;
|
|
|
9151 |
tc2 = ts0 - tc0;
|
|
|
9152 |
|
|
|
9153 |
ts0 = inout[inoutPos + 5 * 3] * win[Encoder.SHORT_TYPE][0]
|
|
|
9154 |
+ inout[inoutPos + 2 * 3];
|
|
|
9155 |
tc0 = inout[inoutPos + 3 * 3] * win[Encoder.SHORT_TYPE][2]
|
|
|
9156 |
+ inout[inoutPos + 0 * 3];
|
|
|
9157 |
ts1 = ts0 + tc0;
|
|
|
9158 |
ts2 = -ts0 + tc0;
|
|
|
9159 |
|
|
|
9160 |
tc0 = (inout[inoutPos + 1 * 3] * win[Encoder.SHORT_TYPE][1] - inout[inoutPos + 4 * 3]) * 2.069978111953089e-11;
|
|
|
9161 |
/*
|
|
|
9162 |
* tritab_s [ 1 ]
|
|
|
9163 |
*/
|
|
|
9164 |
ts0 = (inout[inoutPos + 4 * 3] * win[Encoder.SHORT_TYPE][1] + inout[inoutPos + 1 * 3]) * 2.069978111953089e-11;
|
|
|
9165 |
/*
|
|
|
9166 |
* tritab_s [ 1 ]
|
|
|
9167 |
*/
|
|
|
9168 |
inout[inoutPos + 3 * 0] = tc1 * 1.907525191737280e-11 + tc0;
|
|
|
9169 |
/*
|
|
|
9170 |
* tritab_s[ 2 ]
|
|
|
9171 |
*/
|
|
|
9172 |
inout[inoutPos + 3 * 5] = -ts1 * 1.907525191737280e-11 + ts0;
|
|
|
9173 |
/*
|
|
|
9174 |
* tritab_s[0 ]
|
|
|
9175 |
*/
|
|
|
9176 |
tc2 = tc2 * 0.86602540378443870761 * 1.907525191737281e-11;
|
|
|
9177 |
/*
|
|
|
9178 |
* tritab_s[ 2]
|
|
|
9179 |
*/
|
|
|
9180 |
ts1 = ts1 * 0.5 * 1.907525191737281e-11 + ts0;
|
|
|
9181 |
inout[inoutPos + 3 * 1] = tc2 - ts1;
|
|
|
9182 |
inout[inoutPos + 3 * 2] = tc2 + ts1;
|
|
|
9183 |
|
|
|
9184 |
tc1 = tc1 * 0.5 * 1.907525191737281e-11 - tc0;
|
|
|
9185 |
ts2 = ts2 * 0.86602540378443870761 * 1.907525191737281e-11;
|
|
|
9186 |
/*
|
|
|
9187 |
* tritab_s[ 0]
|
|
|
9188 |
*/
|
|
|
9189 |
inout[inoutPos + 3 * 3] = tc1 + ts2;
|
|
|
9190 |
inout[inoutPos + 3 * 4] = tc1 - ts2;
|
|
|
9191 |
|
|
|
9192 |
inoutPos++;
|
|
|
9193 |
}
|
|
|
9194 |
}
|
|
|
9195 |
|
|
|
9196 |
function mdct_long(out, outPos, _in) {
|
|
|
9197 |
var ct, st;
|
|
|
9198 |
{
|
|
|
9199 |
var tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8;
|
|
|
9200 |
/* 1,2, 5,6, 9,10, 13,14, 17 */
|
|
|
9201 |
tc1 = _in[17] - _in[9];
|
|
|
9202 |
tc3 = _in[15] - _in[11];
|
|
|
9203 |
tc4 = _in[14] - _in[12];
|
|
|
9204 |
ts5 = _in[0] + _in[8];
|
|
|
9205 |
ts6 = _in[1] + _in[7];
|
|
|
9206 |
ts7 = _in[2] + _in[6];
|
|
|
9207 |
ts8 = _in[3] + _in[5];
|
|
|
9208 |
|
|
|
9209 |
out[outPos + 17] = (ts5 + ts7 - ts8) - (ts6 - _in[4]);
|
|
|
9210 |
st = (ts5 + ts7 - ts8) * cx[12 + 7] + (ts6 - _in[4]);
|
|
|
9211 |
ct = (tc1 - tc3 - tc4) * cx[12 + 6];
|
|
|
9212 |
out[outPos + 5] = ct + st;
|
|
|
9213 |
out[outPos + 6] = ct - st;
|
|
|
9214 |
|
|
|
9215 |
tc2 = (_in[16] - _in[10]) * cx[12 + 6];
|
|
|
9216 |
ts6 = ts6 * cx[12 + 7] + _in[4];
|
|
|
9217 |
ct = tc1 * cx[12 + 0] + tc2 + tc3 * cx[12 + 1] + tc4 * cx[12 + 2];
|
|
|
9218 |
st = -ts5 * cx[12 + 4] + ts6 - ts7 * cx[12 + 5] + ts8 * cx[12 + 3];
|
|
|
9219 |
out[outPos + 1] = ct + st;
|
|
|
9220 |
out[outPos + 2] = ct - st;
|
|
|
9221 |
|
|
|
9222 |
ct = tc1 * cx[12 + 1] - tc2 - tc3 * cx[12 + 2] + tc4 * cx[12 + 0];
|
|
|
9223 |
st = -ts5 * cx[12 + 5] + ts6 - ts7 * cx[12 + 3] + ts8 * cx[12 + 4];
|
|
|
9224 |
out[outPos + 9] = ct + st;
|
|
|
9225 |
out[outPos + 10] = ct - st;
|
|
|
9226 |
|
|
|
9227 |
ct = tc1 * cx[12 + 2] - tc2 + tc3 * cx[12 + 0] - tc4 * cx[12 + 1];
|
|
|
9228 |
st = ts5 * cx[12 + 3] - ts6 + ts7 * cx[12 + 4] - ts8 * cx[12 + 5];
|
|
|
9229 |
out[outPos + 13] = ct + st;
|
|
|
9230 |
out[outPos + 14] = ct - st;
|
|
|
9231 |
}
|
|
|
9232 |
{
|
|
|
9233 |
var ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8;
|
|
|
9234 |
|
|
|
9235 |
ts1 = _in[8] - _in[0];
|
|
|
9236 |
ts3 = _in[6] - _in[2];
|
|
|
9237 |
ts4 = _in[5] - _in[3];
|
|
|
9238 |
tc5 = _in[17] + _in[9];
|
|
|
9239 |
tc6 = _in[16] + _in[10];
|
|
|
9240 |
tc7 = _in[15] + _in[11];
|
|
|
9241 |
tc8 = _in[14] + _in[12];
|
|
|
9242 |
|
|
|
9243 |
out[outPos + 0] = (tc5 + tc7 + tc8) + (tc6 + _in[13]);
|
|
|
9244 |
ct = (tc5 + tc7 + tc8) * cx[12 + 7] - (tc6 + _in[13]);
|
|
|
9245 |
st = (ts1 - ts3 + ts4) * cx[12 + 6];
|
|
|
9246 |
out[outPos + 11] = ct + st;
|
|
|
9247 |
out[outPos + 12] = ct - st;
|
|
|
9248 |
|
|
|
9249 |
ts2 = (_in[7] - _in[1]) * cx[12 + 6];
|
|
|
9250 |
tc6 = _in[13] - tc6 * cx[12 + 7];
|
|
|
9251 |
ct = tc5 * cx[12 + 3] - tc6 + tc7 * cx[12 + 4] + tc8 * cx[12 + 5];
|
|
|
9252 |
st = ts1 * cx[12 + 2] + ts2 + ts3 * cx[12 + 0] + ts4 * cx[12 + 1];
|
|
|
9253 |
out[outPos + 3] = ct + st;
|
|
|
9254 |
out[outPos + 4] = ct - st;
|
|
|
9255 |
|
|
|
9256 |
ct = -tc5 * cx[12 + 5] + tc6 - tc7 * cx[12 + 3] - tc8 * cx[12 + 4];
|
|
|
9257 |
st = ts1 * cx[12 + 1] + ts2 - ts3 * cx[12 + 2] - ts4 * cx[12 + 0];
|
|
|
9258 |
out[outPos + 7] = ct + st;
|
|
|
9259 |
out[outPos + 8] = ct - st;
|
|
|
9260 |
|
|
|
9261 |
ct = -tc5 * cx[12 + 4] + tc6 - tc7 * cx[12 + 5] - tc8 * cx[12 + 3];
|
|
|
9262 |
st = ts1 * cx[12 + 0] - ts2 + ts3 * cx[12 + 1] - ts4 * cx[12 + 2];
|
|
|
9263 |
out[outPos + 15] = ct + st;
|
|
|
9264 |
out[outPos + 16] = ct - st;
|
|
|
9265 |
}
|
|
|
9266 |
}
|
|
|
9267 |
|
|
|
9268 |
this.mdct_sub48 = function(gfc, w0, w1) {
|
|
|
9269 |
var wk = w0;
|
|
|
9270 |
var wkPos = 286;
|
|
|
9271 |
/* thinking cache performance, ch->gr loop is better than gr->ch loop */
|
|
|
9272 |
for (var ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
9273 |
for (var gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
9274 |
var band;
|
|
|
9275 |
var gi = (gfc.l3_side.tt[gr][ch]);
|
|
|
9276 |
var mdct_enc = gi.xr;
|
|
|
9277 |
var mdct_encPos = 0;
|
|
|
9278 |
var samp = gfc.sb_sample[ch][1 - gr];
|
|
|
9279 |
var sampPos = 0;
|
|
|
9280 |
|
|
|
9281 |
for (var k = 0; k < 18 / 2; k++) {
|
|
|
9282 |
window_subband(wk, wkPos, samp[sampPos]);
|
|
|
9283 |
window_subband(wk, wkPos + 32, samp[sampPos + 1]);
|
|
|
9284 |
sampPos += 2;
|
|
|
9285 |
wkPos += 64;
|
|
|
9286 |
/*
|
|
|
9287 |
* Compensate for inversion in the analysis filter
|
|
|
9288 |
*/
|
|
|
9289 |
for (band = 1; band < 32; band += 2) {
|
|
|
9290 |
samp[sampPos - 1][band] *= -1;
|
|
|
9291 |
}
|
|
|
9292 |
}
|
|
|
9293 |
|
|
|
9294 |
/*
|
|
|
9295 |
* Perform imdct of 18 previous subband samples + 18 current
|
|
|
9296 |
* subband samples
|
|
|
9297 |
*/
|
|
|
9298 |
for (band = 0; band < 32; band++, mdct_encPos += 18) {
|
|
|
9299 |
var type = gi.block_type;
|
|
|
9300 |
var band0 = gfc.sb_sample[ch][gr];
|
|
|
9301 |
var band1 = gfc.sb_sample[ch][1 - gr];
|
|
|
9302 |
if (gi.mixed_block_flag != 0 && band < 2)
|
|
|
9303 |
type = 0;
|
|
|
9304 |
if (gfc.amp_filter[band] < 1e-12) {
|
|
|
9305 |
Arrays.fill(mdct_enc, mdct_encPos + 0,
|
|
|
9306 |
mdct_encPos + 18, 0);
|
|
|
9307 |
} else {
|
|
|
9308 |
if (gfc.amp_filter[band] < 1.0) {
|
|
|
9309 |
for (var k = 0; k < 18; k++)
|
|
|
9310 |
band1[k][order[band]] *= gfc.amp_filter[band];
|
|
|
9311 |
}
|
|
|
9312 |
if (type == Encoder.SHORT_TYPE) {
|
|
|
9313 |
for (var k = -NS / 4; k < 0; k++) {
|
|
|
9314 |
var w = win[Encoder.SHORT_TYPE][k + 3];
|
|
|
9315 |
mdct_enc[mdct_encPos + k * 3 + 9] = band0[9 + k][order[band]]
|
|
|
9316 |
* w - band0[8 - k][order[band]];
|
|
|
9317 |
mdct_enc[mdct_encPos + k * 3 + 18] = band0[14 - k][order[band]]
|
|
|
9318 |
* w + band0[15 + k][order[band]];
|
|
|
9319 |
mdct_enc[mdct_encPos + k * 3 + 10] = band0[15 + k][order[band]]
|
|
|
9320 |
* w - band0[14 - k][order[band]];
|
|
|
9321 |
mdct_enc[mdct_encPos + k * 3 + 19] = band1[2 - k][order[band]]
|
|
|
9322 |
* w + band1[3 + k][order[band]];
|
|
|
9323 |
mdct_enc[mdct_encPos + k * 3 + 11] = band1[3 + k][order[band]]
|
|
|
9324 |
* w - band1[2 - k][order[band]];
|
|
|
9325 |
mdct_enc[mdct_encPos + k * 3 + 20] = band1[8 - k][order[band]]
|
|
|
9326 |
* w + band1[9 + k][order[band]];
|
|
|
9327 |
}
|
|
|
9328 |
mdct_short(mdct_enc, mdct_encPos);
|
|
|
9329 |
} else {
|
|
|
9330 |
var work = new_float(18);
|
|
|
9331 |
for (var k = -NL / 4; k < 0; k++) {
|
|
|
9332 |
var a, b;
|
|
|
9333 |
a = win[type][k + 27]
|
|
|
9334 |
* band1[k + 9][order[band]]
|
|
|
9335 |
+ win[type][k + 36]
|
|
|
9336 |
* band1[8 - k][order[band]];
|
|
|
9337 |
b = win[type][k + 9]
|
|
|
9338 |
* band0[k + 9][order[band]]
|
|
|
9339 |
- win[type][k + 18]
|
|
|
9340 |
* band0[8 - k][order[band]];
|
|
|
9341 |
work[k + 9] = a - b * tantab_l[3 + k + 9];
|
|
|
9342 |
work[k + 18] = a * tantab_l[3 + k + 9] + b;
|
|
|
9343 |
}
|
|
|
9344 |
|
|
|
9345 |
mdct_long(mdct_enc, mdct_encPos, work);
|
|
|
9346 |
}
|
|
|
9347 |
}
|
|
|
9348 |
/*
|
|
|
9349 |
* Perform aliasing reduction butterfly
|
|
|
9350 |
*/
|
|
|
9351 |
if (type != Encoder.SHORT_TYPE && band != 0) {
|
|
|
9352 |
for (var k = 7; k >= 0; --k) {
|
|
|
9353 |
var bu, bd;
|
|
|
9354 |
bu = mdct_enc[mdct_encPos + k] * ca[20 + k]
|
|
|
9355 |
+ mdct_enc[mdct_encPos + -1 - k]
|
|
|
9356 |
* cs[28 + k];
|
|
|
9357 |
bd = mdct_enc[mdct_encPos + k] * cs[28 + k]
|
|
|
9358 |
- mdct_enc[mdct_encPos + -1 - k]
|
|
|
9359 |
* ca[20 + k];
|
|
|
9360 |
|
|
|
9361 |
mdct_enc[mdct_encPos + -1 - k] = bu;
|
|
|
9362 |
mdct_enc[mdct_encPos + k] = bd;
|
|
|
9363 |
}
|
|
|
9364 |
}
|
|
|
9365 |
}
|
|
|
9366 |
}
|
|
|
9367 |
wk = w1;
|
|
|
9368 |
wkPos = 286;
|
|
|
9369 |
if (gfc.mode_gr == 1) {
|
|
|
9370 |
for (var i = 0; i < 18; i++) {
|
|
|
9371 |
System.arraycopy(gfc.sb_sample[ch][1][i], 0,
|
|
|
9372 |
gfc.sb_sample[ch][0][i], 0, 32);
|
|
|
9373 |
}
|
|
|
9374 |
}
|
|
|
9375 |
}
|
|
|
9376 |
}
|
|
|
9377 |
}
|
|
|
9378 |
|
|
|
9379 |
//package mp3;
|
|
|
9380 |
|
|
|
9381 |
|
|
|
9382 |
function III_psy_ratio() {
|
|
|
9383 |
this.thm = new III_psy_xmin();
|
|
|
9384 |
this.en = new III_psy_xmin();
|
|
|
9385 |
}
|
|
|
9386 |
|
|
|
9387 |
|
|
|
9388 |
/**
|
|
|
9389 |
* ENCDELAY The encoder delay.
|
|
|
9390 |
*
|
|
|
9391 |
* Minimum allowed is MDCTDELAY (see below)
|
|
|
9392 |
*
|
|
|
9393 |
* The first 96 samples will be attenuated, so using a value less than 96
|
|
|
9394 |
* will result in corrupt data for the first 96-ENCDELAY samples.
|
|
|
9395 |
*
|
|
|
9396 |
* suggested: 576 set to 1160 to sync with FhG.
|
|
|
9397 |
*/
|
|
|
9398 |
Encoder.ENCDELAY = 576;
|
|
|
9399 |
/**
|
|
|
9400 |
* make sure there is at least one complete frame after the last frame
|
|
|
9401 |
* containing real data
|
|
|
9402 |
*
|
|
|
9403 |
* Using a value of 288 would be sufficient for a a very sophisticated
|
|
|
9404 |
* decoder that can decode granule-by-granule instead of frame by frame. But
|
|
|
9405 |
* lets not assume this, and assume the decoder will not decode frame N
|
|
|
9406 |
* unless it also has data for frame N+1
|
|
|
9407 |
*/
|
|
|
9408 |
Encoder.POSTDELAY = 1152;
|
|
|
9409 |
|
|
|
9410 |
/**
|
|
|
9411 |
* delay of the MDCT used in mdct.c original ISO routines had a delay of
|
|
|
9412 |
* 528! Takehiro's routines:
|
|
|
9413 |
*/
|
|
|
9414 |
Encoder.MDCTDELAY = 48;
|
|
|
9415 |
Encoder.FFTOFFSET = (224 + Encoder.MDCTDELAY);
|
|
|
9416 |
|
|
|
9417 |
/**
|
|
|
9418 |
* Most decoders, including the one we use, have a delay of 528 samples.
|
|
|
9419 |
*/
|
|
|
9420 |
Encoder.DECDELAY = 528;
|
|
|
9421 |
|
|
|
9422 |
/**
|
|
|
9423 |
* number of subbands
|
|
|
9424 |
*/
|
|
|
9425 |
Encoder.SBLIMIT = 32;
|
|
|
9426 |
|
|
|
9427 |
/**
|
|
|
9428 |
* parition bands bands
|
|
|
9429 |
*/
|
|
|
9430 |
Encoder.CBANDS = 64;
|
|
|
9431 |
|
|
|
9432 |
/**
|
|
|
9433 |
* number of critical bands/scale factor bands where masking is computed
|
|
|
9434 |
*/
|
|
|
9435 |
Encoder.SBPSY_l = 21;
|
|
|
9436 |
Encoder.SBPSY_s = 12;
|
|
|
9437 |
|
|
|
9438 |
/**
|
|
|
9439 |
* total number of scalefactor bands encoded
|
|
|
9440 |
*/
|
|
|
9441 |
Encoder.SBMAX_l = 22;
|
|
|
9442 |
Encoder.SBMAX_s = 13;
|
|
|
9443 |
Encoder.PSFB21 = 6;
|
|
|
9444 |
Encoder.PSFB12 = 6;
|
|
|
9445 |
|
|
|
9446 |
/**
|
|
|
9447 |
* FFT sizes
|
|
|
9448 |
*/
|
|
|
9449 |
Encoder.BLKSIZE = 1024;
|
|
|
9450 |
Encoder.HBLKSIZE = (Encoder.BLKSIZE / 2 + 1);
|
|
|
9451 |
Encoder.BLKSIZE_s = 256;
|
|
|
9452 |
Encoder.HBLKSIZE_s = (Encoder.BLKSIZE_s / 2 + 1);
|
|
|
9453 |
|
|
|
9454 |
Encoder.NORM_TYPE = 0;
|
|
|
9455 |
Encoder.START_TYPE = 1;
|
|
|
9456 |
Encoder.SHORT_TYPE = 2;
|
|
|
9457 |
Encoder.STOP_TYPE = 3;
|
|
|
9458 |
|
|
|
9459 |
/**
|
|
|
9460 |
* <PRE>
|
|
|
9461 |
* Mode Extention:
|
|
|
9462 |
* When we are in stereo mode, there are 4 possible methods to store these
|
|
|
9463 |
* two channels. The stereo modes -m? are using a subset of them.
|
|
|
9464 |
*
|
|
|
9465 |
* -ms: MPG_MD_LR_LR
|
|
|
9466 |
* -mj: MPG_MD_LR_LR and MPG_MD_MS_LR
|
|
|
9467 |
* -mf: MPG_MD_MS_LR
|
|
|
9468 |
* -mi: all
|
|
|
9469 |
* </PRE>
|
|
|
9470 |
*/
|
|
|
9471 |
Encoder.MPG_MD_LR_LR = 0;
|
|
|
9472 |
Encoder.MPG_MD_LR_I = 1;
|
|
|
9473 |
Encoder.MPG_MD_MS_LR = 2;
|
|
|
9474 |
Encoder.MPG_MD_MS_I = 3;
|
|
|
9475 |
|
|
|
9476 |
Encoder.fircoef = [-0.0207887 * 5, -0.0378413 * 5,
|
|
|
9477 |
-0.0432472 * 5, -0.031183 * 5, 7.79609e-18 * 5, 0.0467745 * 5,
|
|
|
9478 |
0.10091 * 5, 0.151365 * 5, 0.187098 * 5];
|
|
|
9479 |
|
|
|
9480 |
function Encoder() {
|
|
|
9481 |
|
|
|
9482 |
var FFTOFFSET = Encoder.FFTOFFSET;
|
|
|
9483 |
var MPG_MD_MS_LR = Encoder.MPG_MD_MS_LR;
|
|
|
9484 |
//BitStream bs;
|
|
|
9485 |
//PsyModel psy;
|
|
|
9486 |
//VBRTag vbr;
|
|
|
9487 |
//QuantizePVT qupvt;
|
|
|
9488 |
var bs = null;
|
|
|
9489 |
this.psy = null;
|
|
|
9490 |
var psy = null;
|
|
|
9491 |
var vbr = null;
|
|
|
9492 |
var qupvt = null;
|
|
|
9493 |
|
|
|
9494 |
//public final void setModules(BitStream bs, PsyModel psy, QuantizePVT qupvt,
|
|
|
9495 |
// VBRTag vbr) {
|
|
|
9496 |
this.setModules = function (_bs, _psy, _qupvt, _vbr) {
|
|
|
9497 |
bs = _bs;
|
|
|
9498 |
this.psy = _psy;
|
|
|
9499 |
psy = _psy;
|
|
|
9500 |
vbr = _vbr;
|
|
|
9501 |
qupvt = _qupvt;
|
|
|
9502 |
};
|
|
|
9503 |
|
|
|
9504 |
var newMDCT = new NewMDCT();
|
|
|
9505 |
|
|
|
9506 |
/***********************************************************************
|
|
|
9507 |
*
|
|
|
9508 |
* encoder and decoder delays
|
|
|
9509 |
*
|
|
|
9510 |
***********************************************************************/
|
|
|
9511 |
|
|
|
9512 |
/**
|
|
|
9513 |
* <PRE>
|
|
|
9514 |
* layer III enc->dec delay: 1056 (1057?) (observed)
|
|
|
9515 |
* layer II enc->dec delay: 480 (481?) (observed)
|
|
|
9516 |
*
|
|
|
9517 |
* polyphase 256-16 (dec or enc) = 240
|
|
|
9518 |
* mdct 256+32 (9*32) (dec or enc) = 288
|
|
|
9519 |
* total: 512+16
|
|
|
9520 |
*
|
|
|
9521 |
* My guess is that delay of polyphase filterbank is actualy 240.5
|
|
|
9522 |
* (there are technical reasons for this, see postings in mp3encoder).
|
|
|
9523 |
* So total Encode+Decode delay = ENCDELAY + 528 + 1
|
|
|
9524 |
* </PRE>
|
|
|
9525 |
*/
|
|
|
9526 |
|
|
|
9527 |
|
|
|
9528 |
/**
|
|
|
9529 |
* auto-adjust of ATH, useful for low volume Gabriel Bouvigne 3 feb 2001
|
|
|
9530 |
*
|
|
|
9531 |
* modifies some values in gfp.internal_flags.ATH (gfc.ATH)
|
|
|
9532 |
*/
|
|
|
9533 |
//private void adjust_ATH(final LameInternalFlags gfc) {
|
|
|
9534 |
function adjust_ATH(gfc) {
|
|
|
9535 |
var gr2_max, max_pow;
|
|
|
9536 |
|
|
|
9537 |
if (gfc.ATH.useAdjust == 0) {
|
|
|
9538 |
gfc.ATH.adjust = 1.0;
|
|
|
9539 |
/* no adjustment */
|
|
|
9540 |
return;
|
|
|
9541 |
}
|
|
|
9542 |
|
|
|
9543 |
/* jd - 2001 mar 12, 27, jun 30 */
|
|
|
9544 |
/* loudness based on equal loudness curve; */
|
|
|
9545 |
/* use granule with maximum combined loudness */
|
|
|
9546 |
max_pow = gfc.loudness_sq[0][0];
|
|
|
9547 |
gr2_max = gfc.loudness_sq[1][0];
|
|
|
9548 |
if (gfc.channels_out == 2) {
|
|
|
9549 |
max_pow += gfc.loudness_sq[0][1];
|
|
|
9550 |
gr2_max += gfc.loudness_sq[1][1];
|
|
|
9551 |
} else {
|
|
|
9552 |
max_pow += max_pow;
|
|
|
9553 |
gr2_max += gr2_max;
|
|
|
9554 |
}
|
|
|
9555 |
if (gfc.mode_gr == 2) {
|
|
|
9556 |
max_pow = Math.max(max_pow, gr2_max);
|
|
|
9557 |
}
|
|
|
9558 |
max_pow *= 0.5;
|
|
|
9559 |
/* max_pow approaches 1.0 for full band noise */
|
|
|
9560 |
|
|
|
9561 |
/* jd - 2001 mar 31, jun 30 */
|
|
|
9562 |
/* user tuning of ATH adjustment region */
|
|
|
9563 |
max_pow *= gfc.ATH.aaSensitivityP;
|
|
|
9564 |
|
|
|
9565 |
/*
|
|
|
9566 |
* adjust ATH depending on range of maximum value
|
|
|
9567 |
*/
|
|
|
9568 |
|
|
|
9569 |
/* jd - 2001 feb27, mar12,20, jun30, jul22 */
|
|
|
9570 |
/* continuous curves based on approximation */
|
|
|
9571 |
/* to GB's original values. */
|
|
|
9572 |
/* For an increase in approximate loudness, */
|
|
|
9573 |
/* set ATH adjust to adjust_limit immediately */
|
|
|
9574 |
/* after a delay of one frame. */
|
|
|
9575 |
/* For a loudness decrease, reduce ATH adjust */
|
|
|
9576 |
/* towards adjust_limit gradually. */
|
|
|
9577 |
/* max_pow is a loudness squared or a power. */
|
|
|
9578 |
if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */
|
|
|
9579 |
if (gfc.ATH.adjust >= 1.0) {
|
|
|
9580 |
gfc.ATH.adjust = 1.0;
|
|
|
9581 |
} else {
|
|
|
9582 |
/* preceding frame has lower ATH adjust; */
|
|
|
9583 |
/* ascend only to the preceding adjust_limit */
|
|
|
9584 |
/* in case there is leading low volume */
|
|
|
9585 |
if (gfc.ATH.adjust < gfc.ATH.adjustLimit) {
|
|
|
9586 |
gfc.ATH.adjust = gfc.ATH.adjustLimit;
|
|
|
9587 |
}
|
|
|
9588 |
}
|
|
|
9589 |
gfc.ATH.adjustLimit = 1.0;
|
|
|
9590 |
} else { /* adjustment curve */
|
|
|
9591 |
/* about 32 dB maximum adjust (0.000625) */
|
|
|
9592 |
var adj_lim_new = 31.98 * max_pow + 0.000625;
|
|
|
9593 |
if (gfc.ATH.adjust >= adj_lim_new) { /* descend gradually */
|
|
|
9594 |
gfc.ATH.adjust *= adj_lim_new * 0.075 + 0.925;
|
|
|
9595 |
if (gfc.ATH.adjust < adj_lim_new) { /* stop descent */
|
|
|
9596 |
gfc.ATH.adjust = adj_lim_new;
|
|
|
9597 |
}
|
|
|
9598 |
} else { /* ascend */
|
|
|
9599 |
if (gfc.ATH.adjustLimit >= adj_lim_new) {
|
|
|
9600 |
gfc.ATH.adjust = adj_lim_new;
|
|
|
9601 |
} else {
|
|
|
9602 |
/* preceding frame has lower ATH adjust; */
|
|
|
9603 |
/* ascend only to the preceding adjust_limit */
|
|
|
9604 |
if (gfc.ATH.adjust < gfc.ATH.adjustLimit) {
|
|
|
9605 |
gfc.ATH.adjust = gfc.ATH.adjustLimit;
|
|
|
9606 |
}
|
|
|
9607 |
}
|
|
|
9608 |
}
|
|
|
9609 |
gfc.ATH.adjustLimit = adj_lim_new;
|
|
|
9610 |
}
|
|
|
9611 |
}
|
|
|
9612 |
|
|
|
9613 |
/**
|
|
|
9614 |
* <PRE>
|
|
|
9615 |
* some simple statistics
|
|
|
9616 |
*
|
|
|
9617 |
* bitrate index 0: free bitrate . not allowed in VBR mode
|
|
|
9618 |
* : bitrates, kbps depending on MPEG version
|
|
|
9619 |
* bitrate index 15: forbidden
|
|
|
9620 |
*
|
|
|
9621 |
* mode_ext:
|
|
|
9622 |
* 0: LR
|
|
|
9623 |
* 1: LR-i
|
|
|
9624 |
* 2: MS
|
|
|
9625 |
* 3: MS-i
|
|
|
9626 |
* </PRE>
|
|
|
9627 |
*/
|
|
|
9628 |
function updateStats(gfc) {
|
|
|
9629 |
var gr, ch;
|
|
|
9630 |
|
|
|
9631 |
/* count bitrate indices */
|
|
|
9632 |
gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][4]++;
|
|
|
9633 |
gfc.bitrate_stereoMode_Hist[15][4]++;
|
|
|
9634 |
|
|
|
9635 |
/* count 'em for every mode extension in case of 2 channel encoding */
|
|
|
9636 |
if (gfc.channels_out == 2) {
|
|
|
9637 |
gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][gfc.mode_ext]++;
|
|
|
9638 |
gfc.bitrate_stereoMode_Hist[15][gfc.mode_ext]++;
|
|
|
9639 |
}
|
|
|
9640 |
for (gr = 0; gr < gfc.mode_gr; ++gr) {
|
|
|
9641 |
for (ch = 0; ch < gfc.channels_out; ++ch) {
|
|
|
9642 |
var bt = gfc.l3_side.tt[gr][ch].block_type | 0;
|
|
|
9643 |
if (gfc.l3_side.tt[gr][ch].mixed_block_flag != 0)
|
|
|
9644 |
bt = 4;
|
|
|
9645 |
gfc.bitrate_blockType_Hist[gfc.bitrate_index][bt]++;
|
|
|
9646 |
gfc.bitrate_blockType_Hist[gfc.bitrate_index][5]++;
|
|
|
9647 |
gfc.bitrate_blockType_Hist[15][bt]++;
|
|
|
9648 |
gfc.bitrate_blockType_Hist[15][5]++;
|
|
|
9649 |
}
|
|
|
9650 |
}
|
|
|
9651 |
}
|
|
|
9652 |
|
|
|
9653 |
function lame_encode_frame_init(gfp, inbuf) {
|
|
|
9654 |
var gfc = gfp.internal_flags;
|
|
|
9655 |
|
|
|
9656 |
var ch, gr;
|
|
|
9657 |
|
|
|
9658 |
if (gfc.lame_encode_frame_init == 0) {
|
|
|
9659 |
/* prime the MDCT/polyphase filterbank with a short block */
|
|
|
9660 |
var i, j;
|
|
|
9661 |
var primebuff0 = new_float(286 + 1152 + 576);
|
|
|
9662 |
var primebuff1 = new_float(286 + 1152 + 576);
|
|
|
9663 |
gfc.lame_encode_frame_init = 1;
|
|
|
9664 |
for (i = 0, j = 0; i < 286 + 576 * (1 + gfc.mode_gr); ++i) {
|
|
|
9665 |
if (i < 576 * gfc.mode_gr) {
|
|
|
9666 |
primebuff0[i] = 0;
|
|
|
9667 |
if (gfc.channels_out == 2)
|
|
|
9668 |
primebuff1[i] = 0;
|
|
|
9669 |
} else {
|
|
|
9670 |
primebuff0[i] = inbuf[0][j];
|
|
|
9671 |
if (gfc.channels_out == 2)
|
|
|
9672 |
primebuff1[i] = inbuf[1][j];
|
|
|
9673 |
++j;
|
|
|
9674 |
}
|
|
|
9675 |
}
|
|
|
9676 |
/* polyphase filtering / mdct */
|
|
|
9677 |
for (gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
9678 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
9679 |
gfc.l3_side.tt[gr][ch].block_type = Encoder.SHORT_TYPE;
|
|
|
9680 |
}
|
|
|
9681 |
}
|
|
|
9682 |
newMDCT.mdct_sub48(gfc, primebuff0, primebuff1);
|
|
|
9683 |
|
|
|
9684 |
/* check FFT will not use a negative starting offset */
|
|
|
9685 |
/* check if we have enough data for FFT */
|
|
|
9686 |
/* check if we have enough data for polyphase filterbank */
|
|
|
9687 |
}
|
|
|
9688 |
|
|
|
9689 |
}
|
|
|
9690 |
|
|
|
9691 |
/**
|
|
|
9692 |
* <PRE>
|
|
|
9693 |
* encodeframe() Layer 3
|
|
|
9694 |
*
|
|
|
9695 |
* encode a single frame
|
|
|
9696 |
*
|
|
|
9697 |
*
|
|
|
9698 |
* lame_encode_frame()
|
|
|
9699 |
*
|
|
|
9700 |
*
|
|
|
9701 |
* gr 0 gr 1
|
|
|
9702 |
* inbuf: |--------------|--------------|--------------|
|
|
|
9703 |
*
|
|
|
9704 |
*
|
|
|
9705 |
* Polyphase (18 windows, each shifted 32)
|
|
|
9706 |
* gr 0:
|
|
|
9707 |
* window1 <----512---.
|
|
|
9708 |
* window18 <----512---.
|
|
|
9709 |
*
|
|
|
9710 |
* gr 1:
|
|
|
9711 |
* window1 <----512---.
|
|
|
9712 |
* window18 <----512---.
|
|
|
9713 |
*
|
|
|
9714 |
*
|
|
|
9715 |
*
|
|
|
9716 |
* MDCT output: |--------------|--------------|--------------|
|
|
|
9717 |
*
|
|
|
9718 |
* FFT's <---------1024---------.
|
|
|
9719 |
* <---------1024-------.
|
|
|
9720 |
*
|
|
|
9721 |
*
|
|
|
9722 |
*
|
|
|
9723 |
* inbuf = buffer of PCM data size=MP3 framesize
|
|
|
9724 |
* encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY
|
|
|
9725 |
* so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]
|
|
|
9726 |
*
|
|
|
9727 |
* psy-model FFT has a 1 granule delay, so we feed it data for the
|
|
|
9728 |
* next granule.
|
|
|
9729 |
* FFT is centered over granule: 224+576+224
|
|
|
9730 |
* So FFT starts at: 576-224-MDCTDELAY
|
|
|
9731 |
*
|
|
|
9732 |
* MPEG2: FFT ends at: BLKSIZE+576-224-MDCTDELAY (1328)
|
|
|
9733 |
* MPEG1: FFT ends at: BLKSIZE+2*576-224-MDCTDELAY (1904)
|
|
|
9734 |
*
|
|
|
9735 |
* MPEG2: polyphase first window: [0..511]
|
|
|
9736 |
* 18th window: [544..1055] (1056)
|
|
|
9737 |
* MPEG1: 36th window: [1120..1631] (1632)
|
|
|
9738 |
* data needed: 512+framesize-32
|
|
|
9739 |
*
|
|
|
9740 |
* A close look newmdct.c shows that the polyphase filterbank
|
|
|
9741 |
* only uses data from [0..510] for each window. Perhaps because the window
|
|
|
9742 |
* used by the filterbank is zero for the last point, so Takehiro's
|
|
|
9743 |
* code doesn't bother to compute with it.
|
|
|
9744 |
*
|
|
|
9745 |
* FFT starts at 576-224-MDCTDELAY (304) = 576-FFTOFFSET
|
|
|
9746 |
*
|
|
|
9747 |
* </PRE>
|
|
|
9748 |
*/
|
|
|
9749 |
|
|
|
9750 |
|
|
|
9751 |
this.lame_encode_mp3_frame = function (gfp, inbuf_l, inbuf_r, mp3buf, mp3bufPos, mp3buf_size) {
|
|
|
9752 |
var mp3count;
|
|
|
9753 |
var masking_LR = new_array_n([2, 2]);
|
|
|
9754 |
/*
|
|
|
9755 |
* LR masking &
|
|
|
9756 |
* energy
|
|
|
9757 |
*/
|
|
|
9758 |
masking_LR[0][0] = new III_psy_ratio();
|
|
|
9759 |
masking_LR[0][1] = new III_psy_ratio();
|
|
|
9760 |
masking_LR[1][0] = new III_psy_ratio();
|
|
|
9761 |
masking_LR[1][1] = new III_psy_ratio();
|
|
|
9762 |
var masking_MS = new_array_n([2, 2]);
|
|
|
9763 |
/* MS masking & energy */
|
|
|
9764 |
masking_MS[0][0] = new III_psy_ratio();
|
|
|
9765 |
masking_MS[0][1] = new III_psy_ratio();
|
|
|
9766 |
masking_MS[1][0] = new III_psy_ratio();
|
|
|
9767 |
masking_MS[1][1] = new III_psy_ratio();
|
|
|
9768 |
//III_psy_ratio masking[][];
|
|
|
9769 |
var masking;
|
|
|
9770 |
/* pointer to selected maskings */
|
|
|
9771 |
var inbuf = [null, null];
|
|
|
9772 |
var gfc = gfp.internal_flags;
|
|
|
9773 |
|
|
|
9774 |
var tot_ener = new_float_n([2, 4]);
|
|
|
9775 |
var ms_ener_ratio = [.5, .5];
|
|
|
9776 |
var pe = [[0., 0.], [0., 0.]];
|
|
|
9777 |
var pe_MS = [[0., 0.], [0., 0.]];
|
|
|
9778 |
|
|
|
9779 |
//float[][] pe_use;
|
|
|
9780 |
var pe_use;
|
|
|
9781 |
|
|
|
9782 |
var ch, gr;
|
|
|
9783 |
|
|
|
9784 |
inbuf[0] = inbuf_l;
|
|
|
9785 |
inbuf[1] = inbuf_r;
|
|
|
9786 |
|
|
|
9787 |
if (gfc.lame_encode_frame_init == 0) {
|
|
|
9788 |
/* first run? */
|
|
|
9789 |
lame_encode_frame_init(gfp, inbuf);
|
|
|
9790 |
|
|
|
9791 |
}
|
|
|
9792 |
|
|
|
9793 |
/********************** padding *****************************/
|
|
|
9794 |
/**
|
|
|
9795 |
* <PRE>
|
|
|
9796 |
* padding method as described in
|
|
|
9797 |
* "MPEG-Layer3 / Bitstream Syntax and Decoding"
|
|
|
9798 |
* by Martin Sieler, Ralph Sperschneider
|
|
|
9799 |
*
|
|
|
9800 |
* note: there is no padding for the very first frame
|
|
|
9801 |
*
|
|
|
9802 |
* Robert Hegemann 2000-06-22
|
|
|
9803 |
* </PRE>
|
|
|
9804 |
*/
|
|
|
9805 |
gfc.padding = 0;
|
|
|
9806 |
if ((gfc.slot_lag -= gfc.frac_SpF) < 0) {
|
|
|
9807 |
gfc.slot_lag += gfp.out_samplerate;
|
|
|
9808 |
gfc.padding = 1;
|
|
|
9809 |
}
|
|
|
9810 |
|
|
|
9811 |
/****************************************
|
|
|
9812 |
* Stage 1: psychoacoustic model *
|
|
|
9813 |
****************************************/
|
|
|
9814 |
|
|
|
9815 |
if (gfc.psymodel != 0) {
|
|
|
9816 |
/*
|
|
|
9817 |
* psychoacoustic model psy model has a 1 granule (576) delay that
|
|
|
9818 |
* we must compensate for (mt 6/99).
|
|
|
9819 |
*/
|
|
|
9820 |
var ret;
|
|
|
9821 |
var bufp = [null, null];
|
|
|
9822 |
/* address of beginning of left & right granule */
|
|
|
9823 |
var bufpPos = 0;
|
|
|
9824 |
/* address of beginning of left & right granule */
|
|
|
9825 |
var blocktype = new_int(2);
|
|
|
9826 |
|
|
|
9827 |
for (gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
9828 |
|
|
|
9829 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
9830 |
bufp[ch] = inbuf[ch];
|
|
|
9831 |
bufpPos = 576 + gr * 576 - Encoder.FFTOFFSET;
|
|
|
9832 |
}
|
|
|
9833 |
if (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) {
|
|
|
9834 |
ret = psy.L3psycho_anal_vbr(gfp, bufp, bufpPos, gr,
|
|
|
9835 |
masking_LR, masking_MS, pe[gr], pe_MS[gr],
|
|
|
9836 |
tot_ener[gr], blocktype);
|
|
|
9837 |
} else {
|
|
|
9838 |
ret = psy.L3psycho_anal_ns(gfp, bufp, bufpPos, gr,
|
|
|
9839 |
masking_LR, masking_MS, pe[gr], pe_MS[gr],
|
|
|
9840 |
tot_ener[gr], blocktype);
|
|
|
9841 |
}
|
|
|
9842 |
if (ret != 0)
|
|
|
9843 |
return -4;
|
|
|
9844 |
|
|
|
9845 |
if (gfp.mode == MPEGMode.JOINT_STEREO) {
|
|
|
9846 |
ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3];
|
|
|
9847 |
if (ms_ener_ratio[gr] > 0)
|
|
|
9848 |
ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr];
|
|
|
9849 |
}
|
|
|
9850 |
|
|
|
9851 |
/* block type flags */
|
|
|
9852 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
9853 |
var cod_info = gfc.l3_side.tt[gr][ch];
|
|
|
9854 |
cod_info.block_type = blocktype[ch];
|
|
|
9855 |
cod_info.mixed_block_flag = 0;
|
|
|
9856 |
}
|
|
|
9857 |
}
|
|
|
9858 |
} else {
|
|
|
9859 |
/* no psy model */
|
|
|
9860 |
for (gr = 0; gr < gfc.mode_gr; gr++)
|
|
|
9861 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
9862 |
gfc.l3_side.tt[gr][ch].block_type = Encoder.NORM_TYPE;
|
|
|
9863 |
gfc.l3_side.tt[gr][ch].mixed_block_flag = 0;
|
|
|
9864 |
pe_MS[gr][ch] = pe[gr][ch] = 700;
|
|
|
9865 |
}
|
|
|
9866 |
}
|
|
|
9867 |
|
|
|
9868 |
/* auto-adjust of ATH, useful for low volume */
|
|
|
9869 |
adjust_ATH(gfc);
|
|
|
9870 |
|
|
|
9871 |
/****************************************
|
|
|
9872 |
* Stage 2: MDCT *
|
|
|
9873 |
****************************************/
|
|
|
9874 |
|
|
|
9875 |
/* polyphase filtering / mdct */
|
|
|
9876 |
newMDCT.mdct_sub48(gfc, inbuf[0], inbuf[1]);
|
|
|
9877 |
|
|
|
9878 |
/****************************************
|
|
|
9879 |
* Stage 3: MS/LR decision *
|
|
|
9880 |
****************************************/
|
|
|
9881 |
|
|
|
9882 |
/* Here will be selected MS or LR coding of the 2 stereo channels */
|
|
|
9883 |
gfc.mode_ext = Encoder.MPG_MD_LR_LR;
|
|
|
9884 |
|
|
|
9885 |
if (gfp.force_ms) {
|
|
|
9886 |
gfc.mode_ext = Encoder.MPG_MD_MS_LR;
|
|
|
9887 |
} else if (gfp.mode == MPEGMode.JOINT_STEREO) {
|
|
|
9888 |
/*
|
|
|
9889 |
* ms_ratio = is scaled, for historical reasons, to look like a
|
|
|
9890 |
* ratio of side_channel / total. 0 = signal is 100% mono .5 = L & R
|
|
|
9891 |
* uncorrelated
|
|
|
9892 |
*/
|
|
|
9893 |
|
|
|
9894 |
/**
|
|
|
9895 |
* <PRE>
|
|
|
9896 |
* [0] and [1] are the results for the two granules in MPEG-1,
|
|
|
9897 |
* in MPEG-2 it's only a faked averaging of the same value
|
|
|
9898 |
* _prev is the value of the last granule of the previous frame
|
|
|
9899 |
* _next is the value of the first granule of the next frame
|
|
|
9900 |
* </PRE>
|
|
|
9901 |
*/
|
|
|
9902 |
|
|
|
9903 |
var sum_pe_MS = 0.;
|
|
|
9904 |
var sum_pe_LR = 0.;
|
|
|
9905 |
for (gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
9906 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
9907 |
sum_pe_MS += pe_MS[gr][ch];
|
|
|
9908 |
sum_pe_LR += pe[gr][ch];
|
|
|
9909 |
}
|
|
|
9910 |
}
|
|
|
9911 |
|
|
|
9912 |
/* based on PE: M/S coding would not use much more bits than L/R */
|
|
|
9913 |
if (sum_pe_MS <= 1.00 * sum_pe_LR) {
|
|
|
9914 |
|
|
|
9915 |
var gi0 = gfc.l3_side.tt[0];
|
|
|
9916 |
var gi1 = gfc.l3_side.tt[gfc.mode_gr - 1];
|
|
|
9917 |
|
|
|
9918 |
if (gi0[0].block_type == gi0[1].block_type
|
|
|
9919 |
&& gi1[0].block_type == gi1[1].block_type) {
|
|
|
9920 |
|
|
|
9921 |
gfc.mode_ext = Encoder.MPG_MD_MS_LR;
|
|
|
9922 |
}
|
|
|
9923 |
}
|
|
|
9924 |
}
|
|
|
9925 |
|
|
|
9926 |
/* bit and noise allocation */
|
|
|
9927 |
if (gfc.mode_ext == MPG_MD_MS_LR) {
|
|
|
9928 |
masking = masking_MS;
|
|
|
9929 |
/* use MS masking */
|
|
|
9930 |
pe_use = pe_MS;
|
|
|
9931 |
} else {
|
|
|
9932 |
masking = masking_LR;
|
|
|
9933 |
/* use LR masking */
|
|
|
9934 |
pe_use = pe;
|
|
|
9935 |
}
|
|
|
9936 |
|
|
|
9937 |
/* copy data for MP3 frame analyzer */
|
|
|
9938 |
if (gfp.analysis && gfc.pinfo != null) {
|
|
|
9939 |
for (gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
9940 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
9941 |
gfc.pinfo.ms_ratio[gr] = gfc.ms_ratio[gr];
|
|
|
9942 |
gfc.pinfo.ms_ener_ratio[gr] = ms_ener_ratio[gr];
|
|
|
9943 |
gfc.pinfo.blocktype[gr][ch] = gfc.l3_side.tt[gr][ch].block_type;
|
|
|
9944 |
gfc.pinfo.pe[gr][ch] = pe_use[gr][ch];
|
|
|
9945 |
System.arraycopy(gfc.l3_side.tt[gr][ch].xr, 0,
|
|
|
9946 |
gfc.pinfo.xr[gr][ch], 0, 576);
|
|
|
9947 |
/*
|
|
|
9948 |
* in psymodel, LR and MS data was stored in pinfo. switch
|
|
|
9949 |
* to MS data:
|
|
|
9950 |
*/
|
|
|
9951 |
if (gfc.mode_ext == MPG_MD_MS_LR) {
|
|
|
9952 |
gfc.pinfo.ers[gr][ch] = gfc.pinfo.ers[gr][ch + 2];
|
|
|
9953 |
System.arraycopy(gfc.pinfo.energy[gr][ch + 2], 0,
|
|
|
9954 |
gfc.pinfo.energy[gr][ch], 0,
|
|
|
9955 |
gfc.pinfo.energy[gr][ch].length);
|
|
|
9956 |
}
|
|
|
9957 |
}
|
|
|
9958 |
}
|
|
|
9959 |
}
|
|
|
9960 |
|
|
|
9961 |
/****************************************
|
|
|
9962 |
* Stage 4: quantization loop *
|
|
|
9963 |
****************************************/
|
|
|
9964 |
|
|
|
9965 |
if (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_abr) {
|
|
|
9966 |
|
|
|
9967 |
var i;
|
|
|
9968 |
var f;
|
|
|
9969 |
|
|
|
9970 |
for (i = 0; i < 18; i++)
|
|
|
9971 |
gfc.nsPsy.pefirbuf[i] = gfc.nsPsy.pefirbuf[i + 1];
|
|
|
9972 |
|
|
|
9973 |
f = 0.0;
|
|
|
9974 |
for (gr = 0; gr < gfc.mode_gr; gr++)
|
|
|
9975 |
for (ch = 0; ch < gfc.channels_out; ch++)
|
|
|
9976 |
f += pe_use[gr][ch];
|
|
|
9977 |
gfc.nsPsy.pefirbuf[18] = f;
|
|
|
9978 |
|
|
|
9979 |
f = gfc.nsPsy.pefirbuf[9];
|
|
|
9980 |
for (i = 0; i < 9; i++)
|
|
|
9981 |
f += (gfc.nsPsy.pefirbuf[i] + gfc.nsPsy.pefirbuf[18 - i])
|
|
|
9982 |
* Encoder.fircoef[i];
|
|
|
9983 |
|
|
|
9984 |
f = (670 * 5 * gfc.mode_gr * gfc.channels_out) / f;
|
|
|
9985 |
for (gr = 0; gr < gfc.mode_gr; gr++) {
|
|
|
9986 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
9987 |
pe_use[gr][ch] *= f;
|
|
|
9988 |
}
|
|
|
9989 |
}
|
|
|
9990 |
}
|
|
|
9991 |
gfc.iteration_loop.iteration_loop(gfp, pe_use, ms_ener_ratio, masking);
|
|
|
9992 |
|
|
|
9993 |
/****************************************
|
|
|
9994 |
* Stage 5: bitstream formatting *
|
|
|
9995 |
****************************************/
|
|
|
9996 |
|
|
|
9997 |
/* write the frame to the bitstream */
|
|
|
9998 |
bs.format_bitstream(gfp);
|
|
|
9999 |
|
|
|
10000 |
/* copy mp3 bit buffer into array */
|
|
|
10001 |
mp3count = bs.copy_buffer(gfc, mp3buf, mp3bufPos, mp3buf_size, 1);
|
|
|
10002 |
|
|
|
10003 |
if (gfp.bWriteVbrTag)
|
|
|
10004 |
vbr.addVbrFrame(gfp);
|
|
|
10005 |
|
|
|
10006 |
if (gfp.analysis && gfc.pinfo != null) {
|
|
|
10007 |
for (ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
10008 |
var j;
|
|
|
10009 |
for (j = 0; j < FFTOFFSET; j++)
|
|
|
10010 |
gfc.pinfo.pcmdata[ch][j] = gfc.pinfo.pcmdata[ch][j
|
|
|
10011 |
+ gfp.framesize];
|
|
|
10012 |
for (j = FFTOFFSET; j < 1600; j++) {
|
|
|
10013 |
gfc.pinfo.pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET];
|
|
|
10014 |
}
|
|
|
10015 |
}
|
|
|
10016 |
qupvt.set_frame_pinfo(gfp, masking);
|
|
|
10017 |
}
|
|
|
10018 |
|
|
|
10019 |
updateStats(gfc);
|
|
|
10020 |
|
|
|
10021 |
return mp3count;
|
|
|
10022 |
}
|
|
|
10023 |
}
|
|
|
10024 |
|
|
|
10025 |
|
|
|
10026 |
//package mp3;
|
|
|
10027 |
|
|
|
10028 |
function VBRSeekInfo() {
|
|
|
10029 |
/**
|
|
|
10030 |
* What we have seen so far.
|
|
|
10031 |
*/
|
|
|
10032 |
this.sum = 0;
|
|
|
10033 |
/**
|
|
|
10034 |
* How many frames we have seen in this chunk.
|
|
|
10035 |
*/
|
|
|
10036 |
this.seen = 0;
|
|
|
10037 |
/**
|
|
|
10038 |
* How many frames we want to collect into one chunk.
|
|
|
10039 |
*/
|
|
|
10040 |
this.want = 0;
|
|
|
10041 |
/**
|
|
|
10042 |
* Actual position in our bag.
|
|
|
10043 |
*/
|
|
|
10044 |
this.pos = 0;
|
|
|
10045 |
/**
|
|
|
10046 |
* Size of our bag.
|
|
|
10047 |
*/
|
|
|
10048 |
this.size = 0;
|
|
|
10049 |
/**
|
|
|
10050 |
* Pointer to our bag.
|
|
|
10051 |
*/
|
|
|
10052 |
this.bag = null;
|
|
|
10053 |
this.nVbrNumFrames = 0;
|
|
|
10054 |
this.nBytesWritten = 0;
|
|
|
10055 |
/* VBR tag data */
|
|
|
10056 |
this.TotalFrameSize = 0;
|
|
|
10057 |
}
|
|
|
10058 |
|
|
|
10059 |
|
|
|
10060 |
|
|
|
10061 |
function IIISideInfo() {
|
|
|
10062 |
this.tt = [[null, null], [null, null]];
|
|
|
10063 |
this.main_data_begin = 0;
|
|
|
10064 |
this.private_bits = 0;
|
|
|
10065 |
this.resvDrain_pre = 0;
|
|
|
10066 |
this.resvDrain_post = 0;
|
|
|
10067 |
this.scfsi = [new_int(4), new_int(4)];
|
|
|
10068 |
|
|
|
10069 |
for (var gr = 0; gr < 2; gr++) {
|
|
|
10070 |
for (var ch = 0; ch < 2; ch++) {
|
|
|
10071 |
this.tt[gr][ch] = new GrInfo();
|
|
|
10072 |
}
|
|
|
10073 |
}
|
|
|
10074 |
}
|
|
|
10075 |
|
|
|
10076 |
|
|
|
10077 |
|
|
|
10078 |
//package mp3;
|
|
|
10079 |
|
|
|
10080 |
/**
|
|
|
10081 |
* Variables used for --nspsytune
|
|
|
10082 |
*
|
|
|
10083 |
* @author Ken
|
|
|
10084 |
*
|
|
|
10085 |
*/
|
|
|
10086 |
function NsPsy() {
|
|
|
10087 |
this.last_en_subshort = new_float_n([4, 9]);
|
|
|
10088 |
this.lastAttacks = new_int(4);
|
|
|
10089 |
this.pefirbuf = new_float(19);
|
|
|
10090 |
this.longfact = new_float(Encoder.SBMAX_l);
|
|
|
10091 |
this.shortfact = new_float(Encoder.SBMAX_s);
|
|
|
10092 |
|
|
|
10093 |
/**
|
|
|
10094 |
* short block tuning
|
|
|
10095 |
*/
|
|
|
10096 |
this.attackthre = 0.;
|
|
|
10097 |
this.attackthre_s = 0.;
|
|
|
10098 |
}
|
|
|
10099 |
|
|
|
10100 |
|
|
|
10101 |
function III_psy_xmin() {
|
|
|
10102 |
this.l = new_float(Encoder.SBMAX_l);
|
|
|
10103 |
this.s = new_float_n([Encoder.SBMAX_s, 3]);
|
|
|
10104 |
|
|
|
10105 |
var self = this;
|
|
|
10106 |
this.assign = function (iii_psy_xmin) {
|
|
|
10107 |
System.arraycopy(iii_psy_xmin.l, 0, self.l, 0, Encoder.SBMAX_l);
|
|
|
10108 |
for (var i = 0; i < Encoder.SBMAX_s; i++) {
|
|
|
10109 |
for (var j = 0; j < 3; j++) {
|
|
|
10110 |
self.s[i][j] = iii_psy_xmin.s[i][j];
|
|
|
10111 |
}
|
|
|
10112 |
}
|
|
|
10113 |
}
|
|
|
10114 |
}
|
|
|
10115 |
|
|
|
10116 |
|
|
|
10117 |
|
|
|
10118 |
|
|
|
10119 |
LameInternalFlags.MFSIZE = (3 * 1152 + Encoder.ENCDELAY - Encoder.MDCTDELAY);
|
|
|
10120 |
LameInternalFlags.MAX_HEADER_BUF = 256;
|
|
|
10121 |
LameInternalFlags.MAX_BITS_PER_CHANNEL = 4095;
|
|
|
10122 |
LameInternalFlags.MAX_BITS_PER_GRANULE = 7680;
|
|
|
10123 |
LameInternalFlags.BPC = 320;
|
|
|
10124 |
|
|
|
10125 |
function LameInternalFlags() {
|
|
|
10126 |
var MAX_HEADER_LEN = 40;
|
|
|
10127 |
|
|
|
10128 |
|
|
|
10129 |
/********************************************************************
|
|
|
10130 |
* internal variables NOT set by calling program, and should not be *
|
|
|
10131 |
* modified by the calling program *
|
|
|
10132 |
********************************************************************/
|
|
|
10133 |
|
|
|
10134 |
/**
|
|
|
10135 |
* Some remarks to the Class_ID field: The Class ID is an Identifier for a
|
|
|
10136 |
* pointer to this struct. It is very unlikely that a pointer to
|
|
|
10137 |
* lame_global_flags has the same 32 bits in it's structure (large and other
|
|
|
10138 |
* special properties, for instance prime).
|
|
|
10139 |
*
|
|
|
10140 |
* To test that the structure is right and initialized, use: if ( gfc .
|
|
|
10141 |
* Class_ID == LAME_ID ) ... Other remark: If you set a flag to 0 for uninit
|
|
|
10142 |
* data and 1 for init data, the right test should be "if (flag == 1)" and
|
|
|
10143 |
* NOT "if (flag)". Unintended modification of this element will be
|
|
|
10144 |
* otherwise misinterpreted as an init.
|
|
|
10145 |
*/
|
|
|
10146 |
this.Class_ID = 0;
|
|
|
10147 |
|
|
|
10148 |
this.lame_encode_frame_init = 0;
|
|
|
10149 |
this.iteration_init_init = 0;
|
|
|
10150 |
this.fill_buffer_resample_init = 0;
|
|
|
10151 |
|
|
|
10152 |
//public float mfbuf[][] = new float[2][MFSIZE];
|
|
|
10153 |
this.mfbuf = new_float_n([2, LameInternalFlags.MFSIZE]);
|
|
|
10154 |
|
|
|
10155 |
/**
|
|
|
10156 |
* granules per frame
|
|
|
10157 |
*/
|
|
|
10158 |
this.mode_gr = 0;
|
|
|
10159 |
/**
|
|
|
10160 |
* number of channels in the input data stream (PCM or decoded PCM)
|
|
|
10161 |
*/
|
|
|
10162 |
this.channels_in = 0;
|
|
|
10163 |
/**
|
|
|
10164 |
* number of channels in the output data stream (not used for decoding)
|
|
|
10165 |
*/
|
|
|
10166 |
this.channels_out = 0;
|
|
|
10167 |
/**
|
|
|
10168 |
* input_samp_rate/output_samp_rate
|
|
|
10169 |
*/
|
|
|
10170 |
//public double resample_ratio;
|
|
|
10171 |
this.resample_ratio = 0.;
|
|
|
10172 |
|
|
|
10173 |
this.mf_samples_to_encode = 0;
|
|
|
10174 |
this.mf_size = 0;
|
|
|
10175 |
/**
|
|
|
10176 |
* min bitrate index
|
|
|
10177 |
*/
|
|
|
10178 |
this.VBR_min_bitrate = 0;
|
|
|
10179 |
/**
|
|
|
10180 |
* max bitrate index
|
|
|
10181 |
*/
|
|
|
10182 |
this.VBR_max_bitrate = 0;
|
|
|
10183 |
this.bitrate_index = 0;
|
|
|
10184 |
this.samplerate_index = 0;
|
|
|
10185 |
this.mode_ext = 0;
|
|
|
10186 |
|
|
|
10187 |
/* lowpass and highpass filter control */
|
|
|
10188 |
/**
|
|
|
10189 |
* normalized frequency bounds of passband
|
|
|
10190 |
*/
|
|
|
10191 |
this.lowpass1 = 0.;
|
|
|
10192 |
this.lowpass2 = 0.;
|
|
|
10193 |
/**
|
|
|
10194 |
* normalized frequency bounds of passband
|
|
|
10195 |
*/
|
|
|
10196 |
this.highpass1 = 0.;
|
|
|
10197 |
this.highpass2 = 0.;
|
|
|
10198 |
|
|
|
10199 |
/**
|
|
|
10200 |
* 0 = none 1 = ISO AAC model 2 = allow scalefac_select=1
|
|
|
10201 |
*/
|
|
|
10202 |
this.noise_shaping = 0;
|
|
|
10203 |
|
|
|
10204 |
/**
|
|
|
10205 |
* 0 = ISO model: amplify all distorted bands<BR>
|
|
|
10206 |
* 1 = amplify within 50% of max (on db scale)<BR>
|
|
|
10207 |
* 2 = amplify only most distorted band<BR>
|
|
|
10208 |
* 3 = method 1 and refine with method 2<BR>
|
|
|
10209 |
*/
|
|
|
10210 |
this.noise_shaping_amp = 0;
|
|
|
10211 |
/**
|
|
|
10212 |
* 0 = no substep<BR>
|
|
|
10213 |
* 1 = use substep shaping at last step(VBR only)<BR>
|
|
|
10214 |
* (not implemented yet)<BR>
|
|
|
10215 |
* 2 = use substep inside loop<BR>
|
|
|
10216 |
* 3 = use substep inside loop and last step<BR>
|
|
|
10217 |
*/
|
|
|
10218 |
this.substep_shaping = 0;
|
|
|
10219 |
|
|
|
10220 |
/**
|
|
|
10221 |
* 1 = gpsycho. 0 = none
|
|
|
10222 |
*/
|
|
|
10223 |
this.psymodel = 0;
|
|
|
10224 |
/**
|
|
|
10225 |
* 0 = stop at over=0, all scalefacs amplified or<BR>
|
|
|
10226 |
* a scalefac has reached max value<BR>
|
|
|
10227 |
* 1 = stop when all scalefacs amplified or a scalefac has reached max value<BR>
|
|
|
10228 |
* 2 = stop when all scalefacs amplified
|
|
|
10229 |
*/
|
|
|
10230 |
this.noise_shaping_stop = 0;
|
|
|
10231 |
|
|
|
10232 |
/**
|
|
|
10233 |
* 0 = no, 1 = yes
|
|
|
10234 |
*/
|
|
|
10235 |
this.subblock_gain = 0;
|
|
|
10236 |
/**
|
|
|
10237 |
* 0 = no. 1=outside loop 2=inside loop(slow)
|
|
|
10238 |
*/
|
|
|
10239 |
this.use_best_huffman = 0;
|
|
|
10240 |
|
|
|
10241 |
/**
|
|
|
10242 |
* 0 = stop early after 0 distortion found. 1 = full search
|
|
|
10243 |
*/
|
|
|
10244 |
this.full_outer_loop = 0;
|
|
|
10245 |
|
|
|
10246 |
//public IIISideInfo l3_side = new IIISideInfo();
|
|
|
10247 |
this.l3_side = new IIISideInfo();
|
|
|
10248 |
this.ms_ratio = new_float(2);
|
|
|
10249 |
|
|
|
10250 |
/* used for padding */
|
|
|
10251 |
/**
|
|
|
10252 |
* padding for the current frame?
|
|
|
10253 |
*/
|
|
|
10254 |
this.padding = 0;
|
|
|
10255 |
this.frac_SpF = 0;
|
|
|
10256 |
this.slot_lag = 0;
|
|
|
10257 |
|
|
|
10258 |
/**
|
|
|
10259 |
* optional ID3 tags
|
|
|
10260 |
*/
|
|
|
10261 |
//public ID3TagSpec tag_spec;
|
|
|
10262 |
this.tag_spec = null;
|
|
|
10263 |
this.nMusicCRC = 0;
|
|
|
10264 |
|
|
|
10265 |
/* variables used by Quantize */
|
|
|
10266 |
//public int OldValue[] = new int[2];
|
|
|
10267 |
this.OldValue = new_int(2);
|
|
|
10268 |
//public int CurrentStep[] = new int[2];
|
|
|
10269 |
this.CurrentStep = new_int(2);
|
|
|
10270 |
|
|
|
10271 |
this.masking_lower = 0.;
|
|
|
10272 |
//public int bv_scf[] = new int[576];
|
|
|
10273 |
this.bv_scf = new_int(576);
|
|
|
10274 |
//public int pseudohalf[] = new int[L3Side.SFBMAX];
|
|
|
10275 |
this.pseudohalf = new_int(L3Side.SFBMAX);
|
|
|
10276 |
|
|
|
10277 |
/**
|
|
|
10278 |
* will be set in lame_init_params
|
|
|
10279 |
*/
|
|
|
10280 |
this.sfb21_extra = false;
|
|
|
10281 |
|
|
|
10282 |
/* BPC = maximum number of filter convolution windows to precompute */
|
|
|
10283 |
//public float[][] inbuf_old = new float[2][];
|
|
|
10284 |
this.inbuf_old = new Array(2);
|
|
|
10285 |
//public float[][] blackfilt = new float[2 * BPC + 1][];
|
|
|
10286 |
this.blackfilt = new Array(2 * LameInternalFlags.BPC + 1);
|
|
|
10287 |
//public double itime[] = new double[2];
|
|
|
10288 |
this.itime = new_double(2);
|
|
|
10289 |
this.sideinfo_len = 0;
|
|
|
10290 |
|
|
|
10291 |
/* variables for newmdct.c */
|
|
|
10292 |
//public float sb_sample[][][][] = new float[2][2][18][Encoder.SBLIMIT];
|
|
|
10293 |
this.sb_sample = new_float_n([2, 2, 18, Encoder.SBLIMIT]);
|
|
|
10294 |
this.amp_filter = new_float(32);
|
|
|
10295 |
|
|
|
10296 |
/* variables for BitStream */
|
|
|
10297 |
|
|
|
10298 |
/**
|
|
|
10299 |
* <PRE>
|
|
|
10300 |
* mpeg1: buffer=511 bytes smallest frame: 96-38(sideinfo)=58
|
|
|
10301 |
* max number of frames in reservoir: 8
|
|
|
10302 |
* mpeg2: buffer=255 bytes. smallest frame: 24-23bytes=1
|
|
|
10303 |
* with VBR, if you are encoding all silence, it is possible to
|
|
|
10304 |
* have 8kbs/24khz frames with 1byte of data each, which means we need
|
|
|
10305 |
* to buffer up to 255 headers!
|
|
|
10306 |
* </PRE>
|
|
|
10307 |
*/
|
|
|
10308 |
/**
|
|
|
10309 |
* also, max_header_buf has to be a power of two
|
|
|
10310 |
*/
|
|
|
10311 |
/**
|
|
|
10312 |
* max size of header is 38
|
|
|
10313 |
*/
|
|
|
10314 |
|
|
|
10315 |
function Header() {
|
|
|
10316 |
this.write_timing = 0;
|
|
|
10317 |
this.ptr = 0;
|
|
|
10318 |
//public byte buf[] = new byte[MAX_HEADER_LEN];
|
|
|
10319 |
this.buf = new_byte(MAX_HEADER_LEN);
|
|
|
10320 |
}
|
|
|
10321 |
|
|
|
10322 |
this.header = new Array(LameInternalFlags.MAX_HEADER_BUF);
|
|
|
10323 |
|
|
|
10324 |
this.h_ptr = 0;
|
|
|
10325 |
this.w_ptr = 0;
|
|
|
10326 |
this.ancillary_flag = 0;
|
|
|
10327 |
|
|
|
10328 |
/* variables for Reservoir */
|
|
|
10329 |
/**
|
|
|
10330 |
* in bits
|
|
|
10331 |
*/
|
|
|
10332 |
this.ResvSize = 0;
|
|
|
10333 |
/**
|
|
|
10334 |
* in bits
|
|
|
10335 |
*/
|
|
|
10336 |
this.ResvMax = 0;
|
|
|
10337 |
|
|
|
10338 |
//public ScaleFac scalefac_band = new ScaleFac();
|
|
|
10339 |
this.scalefac_band = new ScaleFac();
|
|
|
10340 |
|
|
|
10341 |
/* daa from PsyModel */
|
|
|
10342 |
/* The static variables "r", "phi_sav", "new", "old" and "oldest" have */
|
|
|
10343 |
/* to be remembered for the unpredictability measure. For "r" and */
|
|
|
10344 |
/* "phi_sav", the first index from the left is the channel select and */
|
|
|
10345 |
/* the second index is the "age" of the data. */
|
|
|
10346 |
this.minval_l = new_float(Encoder.CBANDS);
|
|
|
10347 |
this.minval_s = new_float(Encoder.CBANDS);
|
|
|
10348 |
this.nb_1 = new_float_n([4, Encoder.CBANDS]);
|
|
|
10349 |
this.nb_2 = new_float_n([4, Encoder.CBANDS]);
|
|
|
10350 |
this.nb_s1 = new_float_n([4, Encoder.CBANDS]);
|
|
|
10351 |
this.nb_s2 = new_float_n([4, Encoder.CBANDS]);
|
|
|
10352 |
this.s3_ss = null;
|
|
|
10353 |
this.s3_ll = null;
|
|
|
10354 |
this.decay = 0.;
|
|
|
10355 |
|
|
|
10356 |
//public III_psy_xmin[] thm = new III_psy_xmin[4];
|
|
|
10357 |
//public III_psy_xmin[] en = new III_psy_xmin[4];
|
|
|
10358 |
this.thm = new Array(4);
|
|
|
10359 |
this.en = new Array(4);
|
|
|
10360 |
|
|
|
10361 |
/**
|
|
|
10362 |
* fft and energy calculation
|
|
|
10363 |
*/
|
|
|
10364 |
this.tot_ener = new_float(4);
|
|
|
10365 |
|
|
|
10366 |
/* loudness calculation (for adaptive threshold of hearing) */
|
|
|
10367 |
/**
|
|
|
10368 |
* loudness^2 approx. per granule and channel
|
|
|
10369 |
*/
|
|
|
10370 |
this.loudness_sq = new_float_n([2, 2]);
|
|
|
10371 |
/**
|
|
|
10372 |
* account for granule delay of L3psycho_anal
|
|
|
10373 |
*/
|
|
|
10374 |
this.loudness_sq_save = new_float(2);
|
|
|
10375 |
|
|
|
10376 |
/**
|
|
|
10377 |
* Scale Factor Bands
|
|
|
10378 |
*/
|
|
|
10379 |
this.mld_l = new_float(Encoder.SBMAX_l);
|
|
|
10380 |
this.mld_s = new_float(Encoder.SBMAX_s);
|
|
|
10381 |
this.bm_l = new_int(Encoder.SBMAX_l);
|
|
|
10382 |
this.bo_l = new_int(Encoder.SBMAX_l);
|
|
|
10383 |
this.bm_s = new_int(Encoder.SBMAX_s);
|
|
|
10384 |
this.bo_s = new_int(Encoder.SBMAX_s);
|
|
|
10385 |
this.npart_l = 0;
|
|
|
10386 |
this.npart_s = 0;
|
|
|
10387 |
|
|
|
10388 |
this.s3ind = new_int_n([Encoder.CBANDS, 2]);
|
|
|
10389 |
this.s3ind_s = new_int_n([Encoder.CBANDS, 2]);
|
|
|
10390 |
|
|
|
10391 |
this.numlines_s = new_int(Encoder.CBANDS);
|
|
|
10392 |
this.numlines_l = new_int(Encoder.CBANDS);
|
|
|
10393 |
this.rnumlines_l = new_float(Encoder.CBANDS);
|
|
|
10394 |
this.mld_cb_l = new_float(Encoder.CBANDS);
|
|
|
10395 |
this.mld_cb_s = new_float(Encoder.CBANDS);
|
|
|
10396 |
this.numlines_s_num1 = 0;
|
|
|
10397 |
this.numlines_l_num1 = 0;
|
|
|
10398 |
|
|
|
10399 |
/* ratios */
|
|
|
10400 |
this.pe = new_float(4);
|
|
|
10401 |
this.ms_ratio_s_old = 0.;
|
|
|
10402 |
this.ms_ratio_l_old = 0.;
|
|
|
10403 |
this.ms_ener_ratio_old = 0.;
|
|
|
10404 |
|
|
|
10405 |
/**
|
|
|
10406 |
* block type
|
|
|
10407 |
*/
|
|
|
10408 |
this.blocktype_old = new_int(2);
|
|
|
10409 |
|
|
|
10410 |
/**
|
|
|
10411 |
* variables used for --nspsytune
|
|
|
10412 |
*/
|
|
|
10413 |
this.nsPsy = new NsPsy();
|
|
|
10414 |
|
|
|
10415 |
/**
|
|
|
10416 |
* used for Xing VBR header
|
|
|
10417 |
*/
|
|
|
10418 |
this.VBR_seek_table = new VBRSeekInfo();
|
|
|
10419 |
|
|
|
10420 |
/**
|
|
|
10421 |
* all ATH related stuff
|
|
|
10422 |
*/
|
|
|
10423 |
//public ATH ATH;
|
|
|
10424 |
this.ATH = null;
|
|
|
10425 |
|
|
|
10426 |
this.PSY = null;
|
|
|
10427 |
|
|
|
10428 |
this.nogap_total = 0;
|
|
|
10429 |
this.nogap_current = 0;
|
|
|
10430 |
|
|
|
10431 |
/* ReplayGain */
|
|
|
10432 |
this.decode_on_the_fly = true;
|
|
|
10433 |
this.findReplayGain = true;
|
|
|
10434 |
this.findPeakSample = true;
|
|
|
10435 |
this.PeakSample = 0.;
|
|
|
10436 |
this.RadioGain = 0;
|
|
|
10437 |
this.AudiophileGain = 0;
|
|
|
10438 |
//public ReplayGain rgdata;
|
|
|
10439 |
this.rgdata = null;
|
|
|
10440 |
|
|
|
10441 |
/**
|
|
|
10442 |
* gain change required for preventing clipping
|
|
|
10443 |
*/
|
|
|
10444 |
this.noclipGainChange = 0;
|
|
|
10445 |
/**
|
|
|
10446 |
* user-specified scale factor required for preventing clipping
|
|
|
10447 |
*/
|
|
|
10448 |
this.noclipScale = 0.;
|
|
|
10449 |
|
|
|
10450 |
/* simple statistics */
|
|
|
10451 |
this.bitrate_stereoMode_Hist = new_int_n([16, 4 + 1]);
|
|
|
10452 |
/**
|
|
|
10453 |
* norm/start/short/stop/mixed(short)/sum
|
|
|
10454 |
*/
|
|
|
10455 |
this.bitrate_blockType_Hist = new_int_n([16, 4 + 1 + 1]);
|
|
|
10456 |
|
|
|
10457 |
//public PlottingData pinfo;
|
|
|
10458 |
//public MPGLib.mpstr_tag hip;
|
|
|
10459 |
this.pinfo = null;
|
|
|
10460 |
this.hip = null;
|
|
|
10461 |
|
|
|
10462 |
this.in_buffer_nsamples = 0;
|
|
|
10463 |
//public float[] in_buffer_0;
|
|
|
10464 |
//public float[] in_buffer_1;
|
|
|
10465 |
this.in_buffer_0 = null;
|
|
|
10466 |
this.in_buffer_1 = null;
|
|
|
10467 |
|
|
|
10468 |
//public IIterationLoop iteration_loop;
|
|
|
10469 |
this.iteration_loop = null;
|
|
|
10470 |
|
|
|
10471 |
for (var i = 0; i < this.en.length; i++) {
|
|
|
10472 |
this.en[i] = new III_psy_xmin();
|
|
|
10473 |
}
|
|
|
10474 |
for (var i = 0; i < this.thm.length; i++) {
|
|
|
10475 |
this.thm[i] = new III_psy_xmin();
|
|
|
10476 |
}
|
|
|
10477 |
for (var i = 0; i < this.header.length; i++) {
|
|
|
10478 |
this.header[i] = new Header();
|
|
|
10479 |
}
|
|
|
10480 |
|
|
|
10481 |
}
|
|
|
10482 |
|
|
|
10483 |
|
|
|
10484 |
|
|
|
10485 |
function FFT() {
|
|
|
10486 |
|
|
|
10487 |
var window = new_float(Encoder.BLKSIZE);
|
|
|
10488 |
var window_s = new_float(Encoder.BLKSIZE_s / 2);
|
|
|
10489 |
|
|
|
10490 |
var costab = [
|
|
|
10491 |
9.238795325112867e-01, 3.826834323650898e-01,
|
|
|
10492 |
9.951847266721969e-01, 9.801714032956060e-02,
|
|
|
10493 |
9.996988186962042e-01, 2.454122852291229e-02,
|
|
|
10494 |
9.999811752826011e-01, 6.135884649154475e-03
|
|
|
10495 |
];
|
|
|
10496 |
|
|
|
10497 |
function fht(fz, fzPos, n) {
|
|
|
10498 |
var tri = 0;
|
|
|
10499 |
var k4;
|
|
|
10500 |
var fi;
|
|
|
10501 |
var gi;
|
|
|
10502 |
|
|
|
10503 |
n <<= 1;
|
|
|
10504 |
/* to get BLKSIZE, because of 3DNow! ASM routine */
|
|
|
10505 |
var fn = fzPos + n;
|
|
|
10506 |
k4 = 4;
|
|
|
10507 |
do {
|
|
|
10508 |
var s1, c1;
|
|
|
10509 |
var i, k1, k2, k3, kx;
|
|
|
10510 |
kx = k4 >> 1;
|
|
|
10511 |
k1 = k4;
|
|
|
10512 |
k2 = k4 << 1;
|
|
|
10513 |
k3 = k2 + k1;
|
|
|
10514 |
k4 = k2 << 1;
|
|
|
10515 |
fi = fzPos;
|
|
|
10516 |
gi = fi + kx;
|
|
|
10517 |
do {
|
|
|
10518 |
var f0, f1, f2, f3;
|
|
|
10519 |
f1 = fz[fi + 0] - fz[fi + k1];
|
|
|
10520 |
f0 = fz[fi + 0] + fz[fi + k1];
|
|
|
10521 |
f3 = fz[fi + k2] - fz[fi + k3];
|
|
|
10522 |
f2 = fz[fi + k2] + fz[fi + k3];
|
|
|
10523 |
fz[fi + k2] = f0 - f2;
|
|
|
10524 |
fz[fi + 0] = f0 + f2;
|
|
|
10525 |
fz[fi + k3] = f1 - f3;
|
|
|
10526 |
fz[fi + k1] = f1 + f3;
|
|
|
10527 |
f1 = fz[gi + 0] - fz[gi + k1];
|
|
|
10528 |
f0 = fz[gi + 0] + fz[gi + k1];
|
|
|
10529 |
f3 = (Util.SQRT2 * fz[gi + k3]);
|
|
|
10530 |
f2 = (Util.SQRT2 * fz[gi + k2]);
|
|
|
10531 |
fz[gi + k2] = f0 - f2;
|
|
|
10532 |
fz[gi + 0] = f0 + f2;
|
|
|
10533 |
fz[gi + k3] = f1 - f3;
|
|
|
10534 |
fz[gi + k1] = f1 + f3;
|
|
|
10535 |
gi += k4;
|
|
|
10536 |
fi += k4;
|
|
|
10537 |
} while (fi < fn);
|
|
|
10538 |
c1 = costab[tri + 0];
|
|
|
10539 |
s1 = costab[tri + 1];
|
|
|
10540 |
for (i = 1; i < kx; i++) {
|
|
|
10541 |
var c2, s2;
|
|
|
10542 |
c2 = 1 - (2 * s1) * s1;
|
|
|
10543 |
s2 = (2 * s1) * c1;
|
|
|
10544 |
fi = fzPos + i;
|
|
|
10545 |
gi = fzPos + k1 - i;
|
|
|
10546 |
do {
|
|
|
10547 |
var a, b, g0, f0, f1, g1, f2, g2, f3, g3;
|
|
|
10548 |
b = s2 * fz[fi + k1] - c2 * fz[gi + k1];
|
|
|
10549 |
a = c2 * fz[fi + k1] + s2 * fz[gi + k1];
|
|
|
10550 |
f1 = fz[fi + 0] - a;
|
|
|
10551 |
f0 = fz[fi + 0] + a;
|
|
|
10552 |
g1 = fz[gi + 0] - b;
|
|
|
10553 |
g0 = fz[gi + 0] + b;
|
|
|
10554 |
b = s2 * fz[fi + k3] - c2 * fz[gi + k3];
|
|
|
10555 |
a = c2 * fz[fi + k3] + s2 * fz[gi + k3];
|
|
|
10556 |
f3 = fz[fi + k2] - a;
|
|
|
10557 |
f2 = fz[fi + k2] + a;
|
|
|
10558 |
g3 = fz[gi + k2] - b;
|
|
|
10559 |
g2 = fz[gi + k2] + b;
|
|
|
10560 |
b = s1 * f2 - c1 * g3;
|
|
|
10561 |
a = c1 * f2 + s1 * g3;
|
|
|
10562 |
fz[fi + k2] = f0 - a;
|
|
|
10563 |
fz[fi + 0] = f0 + a;
|
|
|
10564 |
fz[gi + k3] = g1 - b;
|
|
|
10565 |
fz[gi + k1] = g1 + b;
|
|
|
10566 |
b = c1 * g2 - s1 * f3;
|
|
|
10567 |
a = s1 * g2 + c1 * f3;
|
|
|
10568 |
fz[gi + k2] = g0 - a;
|
|
|
10569 |
fz[gi + 0] = g0 + a;
|
|
|
10570 |
fz[fi + k3] = f1 - b;
|
|
|
10571 |
fz[fi + k1] = f1 + b;
|
|
|
10572 |
gi += k4;
|
|
|
10573 |
fi += k4;
|
|
|
10574 |
} while (fi < fn);
|
|
|
10575 |
c2 = c1;
|
|
|
10576 |
c1 = c2 * costab[tri + 0] - s1 * costab[tri + 1];
|
|
|
10577 |
s1 = c2 * costab[tri + 1] + s1 * costab[tri + 0];
|
|
|
10578 |
}
|
|
|
10579 |
tri += 2;
|
|
|
10580 |
} while (k4 < n);
|
|
|
10581 |
}
|
|
|
10582 |
|
|
|
10583 |
var rv_tbl = [0x00, 0x80, 0x40,
|
|
|
10584 |
0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10,
|
|
|
10585 |
0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70,
|
|
|
10586 |
0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28,
|
|
|
10587 |
0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58,
|
|
|
10588 |
0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04,
|
|
|
10589 |
0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64,
|
|
|
10590 |
0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34,
|
|
|
10591 |
0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c,
|
|
|
10592 |
0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c,
|
|
|
10593 |
0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c,
|
|
|
10594 |
0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22,
|
|
|
10595 |
0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52,
|
|
|
10596 |
0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a,
|
|
|
10597 |
0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a,
|
|
|
10598 |
0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a,
|
|
|
10599 |
0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46,
|
|
|
10600 |
0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16,
|
|
|
10601 |
0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76,
|
|
|
10602 |
0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e,
|
|
|
10603 |
0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e,
|
|
|
10604 |
0xde, 0x3e, 0xbe, 0x7e, 0xfe];
|
|
|
10605 |
|
|
|
10606 |
this.fft_short = function (gfc, x_real, chn, buffer, bufPos) {
|
|
|
10607 |
for (var b = 0; b < 3; b++) {
|
|
|
10608 |
var x = Encoder.BLKSIZE_s / 2;
|
|
|
10609 |
var k = 0xffff & ((576 / 3) * (b + 1));
|
|
|
10610 |
var j = Encoder.BLKSIZE_s / 8 - 1;
|
|
|
10611 |
do {
|
|
|
10612 |
var f0, f1, f2, f3, w;
|
|
|
10613 |
var i = rv_tbl[j << 2] & 0xff;
|
|
|
10614 |
|
|
|
10615 |
f0 = window_s[i] * buffer[chn][bufPos + i + k];
|
|
|
10616 |
w = window_s[0x7f - i] * buffer[chn][bufPos + i + k + 0x80];
|
|
|
10617 |
f1 = f0 - w;
|
|
|
10618 |
f0 = f0 + w;
|
|
|
10619 |
f2 = window_s[i + 0x40] * buffer[chn][bufPos + i + k + 0x40];
|
|
|
10620 |
w = window_s[0x3f - i] * buffer[chn][bufPos + i + k + 0xc0];
|
|
|
10621 |
f3 = f2 - w;
|
|
|
10622 |
f2 = f2 + w;
|
|
|
10623 |
|
|
|
10624 |
x -= 4;
|
|
|
10625 |
x_real[b][x + 0] = f0 + f2;
|
|
|
10626 |
x_real[b][x + 2] = f0 - f2;
|
|
|
10627 |
x_real[b][x + 1] = f1 + f3;
|
|
|
10628 |
x_real[b][x + 3] = f1 - f3;
|
|
|
10629 |
|
|
|
10630 |
f0 = window_s[i + 0x01] * buffer[chn][bufPos + i + k + 0x01];
|
|
|
10631 |
w = window_s[0x7e - i] * buffer[chn][bufPos + i + k + 0x81];
|
|
|
10632 |
f1 = f0 - w;
|
|
|
10633 |
f0 = f0 + w;
|
|
|
10634 |
f2 = window_s[i + 0x41] * buffer[chn][bufPos + i + k + 0x41];
|
|
|
10635 |
w = window_s[0x3e - i] * buffer[chn][bufPos + i + k + 0xc1];
|
|
|
10636 |
f3 = f2 - w;
|
|
|
10637 |
f2 = f2 + w;
|
|
|
10638 |
|
|
|
10639 |
x_real[b][x + Encoder.BLKSIZE_s / 2 + 0] = f0 + f2;
|
|
|
10640 |
x_real[b][x + Encoder.BLKSIZE_s / 2 + 2] = f0 - f2;
|
|
|
10641 |
x_real[b][x + Encoder.BLKSIZE_s / 2 + 1] = f1 + f3;
|
|
|
10642 |
x_real[b][x + Encoder.BLKSIZE_s / 2 + 3] = f1 - f3;
|
|
|
10643 |
} while (--j >= 0);
|
|
|
10644 |
|
|
|
10645 |
fht(x_real[b], x, Encoder.BLKSIZE_s / 2);
|
|
|
10646 |
/* BLKSIZE_s/2 because of 3DNow! ASM routine */
|
|
|
10647 |
/* BLKSIZE/2 because of 3DNow! ASM routine */
|
|
|
10648 |
}
|
|
|
10649 |
}
|
|
|
10650 |
|
|
|
10651 |
this.fft_long = function (gfc, y, chn, buffer, bufPos) {
|
|
|
10652 |
var jj = Encoder.BLKSIZE / 8 - 1;
|
|
|
10653 |
var x = Encoder.BLKSIZE / 2;
|
|
|
10654 |
|
|
|
10655 |
do {
|
|
|
10656 |
var f0, f1, f2, f3, w;
|
|
|
10657 |
var i = rv_tbl[jj] & 0xff;
|
|
|
10658 |
f0 = window[i] * buffer[chn][bufPos + i];
|
|
|
10659 |
w = window[i + 0x200] * buffer[chn][bufPos + i + 0x200];
|
|
|
10660 |
f1 = f0 - w;
|
|
|
10661 |
f0 = f0 + w;
|
|
|
10662 |
f2 = window[i + 0x100] * buffer[chn][bufPos + i + 0x100];
|
|
|
10663 |
w = window[i + 0x300] * buffer[chn][bufPos + i + 0x300];
|
|
|
10664 |
f3 = f2 - w;
|
|
|
10665 |
f2 = f2 + w;
|
|
|
10666 |
|
|
|
10667 |
x -= 4;
|
|
|
10668 |
y[x + 0] = f0 + f2;
|
|
|
10669 |
y[x + 2] = f0 - f2;
|
|
|
10670 |
y[x + 1] = f1 + f3;
|
|
|
10671 |
y[x + 3] = f1 - f3;
|
|
|
10672 |
|
|
|
10673 |
f0 = window[i + 0x001] * buffer[chn][bufPos + i + 0x001];
|
|
|
10674 |
w = window[i + 0x201] * buffer[chn][bufPos + i + 0x201];
|
|
|
10675 |
f1 = f0 - w;
|
|
|
10676 |
f0 = f0 + w;
|
|
|
10677 |
f2 = window[i + 0x101] * buffer[chn][bufPos + i + 0x101];
|
|
|
10678 |
w = window[i + 0x301] * buffer[chn][bufPos + i + 0x301];
|
|
|
10679 |
f3 = f2 - w;
|
|
|
10680 |
f2 = f2 + w;
|
|
|
10681 |
|
|
|
10682 |
y[x + Encoder.BLKSIZE / 2 + 0] = f0 + f2;
|
|
|
10683 |
y[x + Encoder.BLKSIZE / 2 + 2] = f0 - f2;
|
|
|
10684 |
y[x + Encoder.BLKSIZE / 2 + 1] = f1 + f3;
|
|
|
10685 |
y[x + Encoder.BLKSIZE / 2 + 3] = f1 - f3;
|
|
|
10686 |
} while (--jj >= 0);
|
|
|
10687 |
|
|
|
10688 |
fht(y, x, Encoder.BLKSIZE / 2);
|
|
|
10689 |
/* BLKSIZE/2 because of 3DNow! ASM routine */
|
|
|
10690 |
}
|
|
|
10691 |
|
|
|
10692 |
this.init_fft = function (gfc) {
|
|
|
10693 |
/* The type of window used here will make no real difference, but */
|
|
|
10694 |
/*
|
|
|
10695 |
* in the interest of merging nspsytune stuff - switch to blackman
|
|
|
10696 |
* window
|
|
|
10697 |
*/
|
|
|
10698 |
for (var i = 0; i < Encoder.BLKSIZE; i++)
|
|
|
10699 |
/* blackman window */
|
|
|
10700 |
window[i] = (0.42 - 0.5 * Math.cos(2 * Math.PI * (i + .5)
|
|
|
10701 |
/ Encoder.BLKSIZE) + 0.08 * Math.cos(4 * Math.PI * (i + .5)
|
|
|
10702 |
/ Encoder.BLKSIZE));
|
|
|
10703 |
|
|
|
10704 |
for (var i = 0; i < Encoder.BLKSIZE_s / 2; i++)
|
|
|
10705 |
window_s[i] = (0.5 * (1.0 - Math.cos(2.0 * Math.PI
|
|
|
10706 |
* (i + 0.5) / Encoder.BLKSIZE_s)));
|
|
|
10707 |
|
|
|
10708 |
}
|
|
|
10709 |
|
|
|
10710 |
}
|
|
|
10711 |
|
|
|
10712 |
/*
|
|
|
10713 |
* psymodel.c
|
|
|
10714 |
*
|
|
|
10715 |
* Copyright (c) 1999-2000 Mark Taylor
|
|
|
10716 |
* Copyright (c) 2001-2002 Naoki Shibata
|
|
|
10717 |
* Copyright (c) 2000-2003 Takehiro Tominaga
|
|
|
10718 |
* Copyright (c) 2000-2008 Robert Hegemann
|
|
|
10719 |
* Copyright (c) 2000-2005 Gabriel Bouvigne
|
|
|
10720 |
* Copyright (c) 2000-2005 Alexander Leidinger
|
|
|
10721 |
*
|
|
|
10722 |
* This library is free software; you can redistribute it and/or
|
|
|
10723 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
10724 |
* License as published by the Free Software Foundation; either
|
|
|
10725 |
* version 2 of the License, or (at your option) any later version.
|
|
|
10726 |
*
|
|
|
10727 |
* This library is distributed in the hope that it will be useful,
|
|
|
10728 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
10729 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
10730 |
* Library General Public License for more details.
|
|
|
10731 |
*
|
|
|
10732 |
* You should have received a copy of the GNU Lesser General Public
|
|
|
10733 |
* License along with this library; if not, write to the
|
|
|
10734 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
10735 |
* Boston, MA 02111-1307, USA.
|
|
|
10736 |
*/
|
|
|
10737 |
|
|
|
10738 |
/* $Id: PsyModel.java,v 1.27 2011/05/24 20:48:06 kenchis Exp $ */
|
|
|
10739 |
|
|
|
10740 |
|
|
|
10741 |
/*
|
|
|
10742 |
PSYCHO ACOUSTICS
|
|
|
10743 |
|
|
|
10744 |
|
|
|
10745 |
This routine computes the psycho acoustics, delayed by one granule.
|
|
|
10746 |
|
|
|
10747 |
Input: buffer of PCM data (1024 samples).
|
|
|
10748 |
|
|
|
10749 |
This window should be centered over the 576 sample granule window.
|
|
|
10750 |
The routine will compute the psycho acoustics for
|
|
|
10751 |
this granule, but return the psycho acoustics computed
|
|
|
10752 |
for the *previous* granule. This is because the block
|
|
|
10753 |
type of the previous granule can only be determined
|
|
|
10754 |
after we have computed the psycho acoustics for the following
|
|
|
10755 |
granule.
|
|
|
10756 |
|
|
|
10757 |
Output: maskings and energies for each scalefactor band.
|
|
|
10758 |
block type, PE, and some correlation measures.
|
|
|
10759 |
The PE is used by CBR modes to determine if extra bits
|
|
|
10760 |
from the bit reservoir should be used. The correlation
|
|
|
10761 |
measures are used to determine mid/side or regular stereo.
|
|
|
10762 |
*/
|
|
|
10763 |
/*
|
|
|
10764 |
Notation:
|
|
|
10765 |
|
|
|
10766 |
barks: a non-linear frequency scale. Mapping from frequency to
|
|
|
10767 |
barks is given by freq2bark()
|
|
|
10768 |
|
|
|
10769 |
scalefactor bands: The spectrum (frequencies) are broken into
|
|
|
10770 |
SBMAX "scalefactor bands". Thes bands
|
|
|
10771 |
are determined by the MPEG ISO spec. In
|
|
|
10772 |
the noise shaping/quantization code, we allocate
|
|
|
10773 |
bits among the partition bands to achieve the
|
|
|
10774 |
best possible quality
|
|
|
10775 |
|
|
|
10776 |
partition bands: The spectrum is also broken into about
|
|
|
10777 |
64 "partition bands". Each partition
|
|
|
10778 |
band is about .34 barks wide. There are about 2-5
|
|
|
10779 |
partition bands for each scalefactor band.
|
|
|
10780 |
|
|
|
10781 |
LAME computes all psycho acoustic information for each partition
|
|
|
10782 |
band. Then at the end of the computations, this information
|
|
|
10783 |
is mapped to scalefactor bands. The energy in each scalefactor
|
|
|
10784 |
band is taken as the sum of the energy in all partition bands
|
|
|
10785 |
which overlap the scalefactor band. The maskings can be computed
|
|
|
10786 |
in the same way (and thus represent the average masking in that band)
|
|
|
10787 |
or by taking the minmum value multiplied by the number of
|
|
|
10788 |
partition bands used (which represents a minimum masking in that band).
|
|
|
10789 |
*/
|
|
|
10790 |
/*
|
|
|
10791 |
The general outline is as follows:
|
|
|
10792 |
|
|
|
10793 |
1. compute the energy in each partition band
|
|
|
10794 |
2. compute the tonality in each partition band
|
|
|
10795 |
3. compute the strength of each partion band "masker"
|
|
|
10796 |
4. compute the masking (via the spreading function applied to each masker)
|
|
|
10797 |
5. Modifications for mid/side masking.
|
|
|
10798 |
|
|
|
10799 |
Each partition band is considiered a "masker". The strength
|
|
|
10800 |
of the i'th masker in band j is given by:
|
|
|
10801 |
|
|
|
10802 |
s3(bark(i)-bark(j))*strength(i)
|
|
|
10803 |
|
|
|
10804 |
The strength of the masker is a function of the energy and tonality.
|
|
|
10805 |
The more tonal, the less masking. LAME uses a simple linear formula
|
|
|
10806 |
(controlled by NMT and TMN) which says the strength is given by the
|
|
|
10807 |
energy divided by a linear function of the tonality.
|
|
|
10808 |
*/
|
|
|
10809 |
/*
|
|
|
10810 |
s3() is the "spreading function". It is given by a formula
|
|
|
10811 |
determined via listening tests.
|
|
|
10812 |
|
|
|
10813 |
The total masking in the j'th partition band is the sum over
|
|
|
10814 |
all maskings i. It is thus given by the convolution of
|
|
|
10815 |
the strength with s3(), the "spreading function."
|
|
|
10816 |
|
|
|
10817 |
masking(j) = sum_over_i s3(i-j)*strength(i) = s3 o strength
|
|
|
10818 |
|
|
|
10819 |
where "o" = convolution operator. s3 is given by a formula determined
|
|
|
10820 |
via listening tests. It is normalized so that s3 o 1 = 1.
|
|
|
10821 |
|
|
|
10822 |
Note: instead of a simple convolution, LAME also has the
|
|
|
10823 |
option of using "additive masking"
|
|
|
10824 |
|
|
|
10825 |
The most critical part is step 2, computing the tonality of each
|
|
|
10826 |
partition band. LAME has two tonality estimators. The first
|
|
|
10827 |
is based on the ISO spec, and measures how predictiable the
|
|
|
10828 |
signal is over time. The more predictable, the more tonal.
|
|
|
10829 |
The second measure is based on looking at the spectrum of
|
|
|
10830 |
a single granule. The more peaky the spectrum, the more
|
|
|
10831 |
tonal. By most indications, the latter approach is better.
|
|
|
10832 |
|
|
|
10833 |
Finally, in step 5, the maskings for the mid and side
|
|
|
10834 |
channel are possibly increased. Under certain circumstances,
|
|
|
10835 |
noise in the mid & side channels is assumed to also
|
|
|
10836 |
be masked by strong maskers in the L or R channels.
|
|
|
10837 |
|
|
|
10838 |
|
|
|
10839 |
Other data computed by the psy-model:
|
|
|
10840 |
|
|
|
10841 |
ms_ratio side-channel / mid-channel masking ratio (for previous granule)
|
|
|
10842 |
ms_ratio_next side-channel / mid-channel masking ratio for this granule
|
|
|
10843 |
|
|
|
10844 |
percep_entropy[2] L and R values (prev granule) of PE - A measure of how
|
|
|
10845 |
much pre-echo is in the previous granule
|
|
|
10846 |
percep_entropy_MS[2] mid and side channel values (prev granule) of percep_entropy
|
|
|
10847 |
energy[4] L,R,M,S energy in each channel, prev granule
|
|
|
10848 |
blocktype_d[2] block type to use for previous granule
|
|
|
10849 |
*/
|
|
|
10850 |
//package mp3;
|
|
|
10851 |
|
|
|
10852 |
//import java.util.Arrays;
|
|
|
10853 |
|
|
|
10854 |
|
|
|
10855 |
function PsyModel() {
|
|
|
10856 |
|
|
|
10857 |
var fft = new FFT();
|
|
|
10858 |
|
|
|
10859 |
var LOG10 = 2.30258509299404568402;
|
|
|
10860 |
|
|
|
10861 |
var rpelev = 2;
|
|
|
10862 |
var rpelev2 = 16;
|
|
|
10863 |
var rpelev_s = 2;
|
|
|
10864 |
var rpelev2_s = 16;
|
|
|
10865 |
|
|
|
10866 |
/* size of each partition band, in barks: */
|
|
|
10867 |
var DELBARK = .34;
|
|
|
10868 |
|
|
|
10869 |
/* tuned for output level (sensitive to energy scale) */
|
|
|
10870 |
var VO_SCALE = (1. / (14752 * 14752) / (Encoder.BLKSIZE / 2));
|
|
|
10871 |
|
|
|
10872 |
var temporalmask_sustain_sec = 0.01;
|
|
|
10873 |
|
|
|
10874 |
var NS_PREECHO_ATT0 = 0.8;
|
|
|
10875 |
var NS_PREECHO_ATT1 = 0.6;
|
|
|
10876 |
var NS_PREECHO_ATT2 = 0.3;
|
|
|
10877 |
|
|
|
10878 |
var NS_MSFIX = 3.5;
|
|
|
10879 |
|
|
|
10880 |
var NSATTACKTHRE = 4.4;
|
|
|
10881 |
var NSATTACKTHRE_S = 25;
|
|
|
10882 |
|
|
|
10883 |
var NSFIRLEN = 21;
|
|
|
10884 |
|
|
|
10885 |
/* size of each partition band, in barks: */
|
|
|
10886 |
var LN_TO_LOG10 = 0.2302585093;
|
|
|
10887 |
|
|
|
10888 |
function NON_LINEAR_SCALE_ENERGY(x) {
|
|
|
10889 |
return x;
|
|
|
10890 |
}
|
|
|
10891 |
|
|
|
10892 |
/**
|
|
|
10893 |
* <PRE>
|
|
|
10894 |
* L3psycho_anal. Compute psycho acoustics.
|
|
|
10895 |
*
|
|
|
10896 |
* Data returned to the calling program must be delayed by one
|
|
|
10897 |
* granule.
|
|
|
10898 |
*
|
|
|
10899 |
* This is done in two places.
|
|
|
10900 |
* If we do not need to know the blocktype, the copying
|
|
|
10901 |
* can be done here at the top of the program: we copy the data for
|
|
|
10902 |
* the last granule (computed during the last call) before it is
|
|
|
10903 |
* overwritten with the new data. It looks like this:
|
|
|
10904 |
*
|
|
|
10905 |
* 0. static psymodel_data
|
|
|
10906 |
* 1. calling_program_data = psymodel_data
|
|
|
10907 |
* 2. compute psymodel_data
|
|
|
10908 |
*
|
|
|
10909 |
* For data which needs to know the blocktype, the copying must be
|
|
|
10910 |
* done at the end of this loop, and the old values must be saved:
|
|
|
10911 |
*
|
|
|
10912 |
* 0. static psymodel_data_old
|
|
|
10913 |
* 1. compute psymodel_data
|
|
|
10914 |
* 2. compute possible block type of this granule
|
|
|
10915 |
* 3. compute final block type of previous granule based on #2.
|
|
|
10916 |
* 4. calling_program_data = psymodel_data_old
|
|
|
10917 |
* 5. psymodel_data_old = psymodel_data
|
|
|
10918 |
* psycho_loudness_approx
|
|
|
10919 |
* jd - 2001 mar 12
|
|
|
10920 |
* in: energy - BLKSIZE/2 elements of frequency magnitudes ^ 2
|
|
|
10921 |
* gfp - uses out_samplerate, ATHtype (also needed for ATHformula)
|
|
|
10922 |
* returns: loudness^2 approximation, a positive value roughly tuned for a value
|
|
|
10923 |
* of 1.0 for signals near clipping.
|
|
|
10924 |
* notes: When calibrated, feeding this function binary white noise at sample
|
|
|
10925 |
* values +32767 or -32768 should return values that approach 3.
|
|
|
10926 |
* ATHformula is used to approximate an equal loudness curve.
|
|
|
10927 |
* future: Data indicates that the shape of the equal loudness curve varies
|
|
|
10928 |
* with intensity. This function might be improved by using an equal
|
|
|
10929 |
* loudness curve shaped for typical playback levels (instead of the
|
|
|
10930 |
* ATH, that is shaped for the threshold). A flexible realization might
|
|
|
10931 |
* simply bend the existing ATH curve to achieve the desired shape.
|
|
|
10932 |
* However, the potential gain may not be enough to justify an effort.
|
|
|
10933 |
* </PRE>
|
|
|
10934 |
*/
|
|
|
10935 |
function psycho_loudness_approx(energy, gfc) {
|
|
|
10936 |
var loudness_power = 0.0;
|
|
|
10937 |
/* apply weights to power in freq. bands */
|
|
|
10938 |
for (var i = 0; i < Encoder.BLKSIZE / 2; ++i)
|
|
|
10939 |
loudness_power += energy[i] * gfc.ATH.eql_w[i];
|
|
|
10940 |
loudness_power *= VO_SCALE;
|
|
|
10941 |
|
|
|
10942 |
return loudness_power;
|
|
|
10943 |
}
|
|
|
10944 |
|
|
|
10945 |
function compute_ffts(gfp, fftenergy, fftenergy_s, wsamp_l, wsamp_lPos, wsamp_s, wsamp_sPos, gr_out, chn, buffer, bufPos) {
|
|
|
10946 |
var gfc = gfp.internal_flags;
|
|
|
10947 |
if (chn < 2) {
|
|
|
10948 |
fft.fft_long(gfc, wsamp_l[wsamp_lPos], chn, buffer, bufPos);
|
|
|
10949 |
fft.fft_short(gfc, wsamp_s[wsamp_sPos], chn, buffer, bufPos);
|
|
|
10950 |
}
|
|
|
10951 |
/* FFT data for mid and side channel is derived from L & R */
|
|
|
10952 |
else if (chn == 2) {
|
|
|
10953 |
for (var j = Encoder.BLKSIZE - 1; j >= 0; --j) {
|
|
|
10954 |
var l = wsamp_l[wsamp_lPos + 0][j];
|
|
|
10955 |
var r = wsamp_l[wsamp_lPos + 1][j];
|
|
|
10956 |
wsamp_l[wsamp_lPos + 0][j] = (l + r) * Util.SQRT2 * 0.5;
|
|
|
10957 |
wsamp_l[wsamp_lPos + 1][j] = (l - r) * Util.SQRT2 * 0.5;
|
|
|
10958 |
}
|
|
|
10959 |
for (var b = 2; b >= 0; --b) {
|
|
|
10960 |
for (var j = Encoder.BLKSIZE_s - 1; j >= 0; --j) {
|
|
|
10961 |
var l = wsamp_s[wsamp_sPos + 0][b][j];
|
|
|
10962 |
var r = wsamp_s[wsamp_sPos + 1][b][j];
|
|
|
10963 |
wsamp_s[wsamp_sPos + 0][b][j] = (l + r) * Util.SQRT2 * 0.5;
|
|
|
10964 |
wsamp_s[wsamp_sPos + 1][b][j] = (l - r) * Util.SQRT2 * 0.5;
|
|
|
10965 |
}
|
|
|
10966 |
}
|
|
|
10967 |
}
|
|
|
10968 |
|
|
|
10969 |
/*********************************************************************
|
|
|
10970 |
* compute energies
|
|
|
10971 |
*********************************************************************/
|
|
|
10972 |
fftenergy[0] = NON_LINEAR_SCALE_ENERGY(wsamp_l[wsamp_lPos + 0][0]);
|
|
|
10973 |
fftenergy[0] *= fftenergy[0];
|
|
|
10974 |
|
|
|
10975 |
for (var j = Encoder.BLKSIZE / 2 - 1; j >= 0; --j) {
|
|
|
10976 |
var re = (wsamp_l[wsamp_lPos + 0])[Encoder.BLKSIZE / 2 - j];
|
|
|
10977 |
var im = (wsamp_l[wsamp_lPos + 0])[Encoder.BLKSIZE / 2 + j];
|
|
|
10978 |
fftenergy[Encoder.BLKSIZE / 2 - j] = NON_LINEAR_SCALE_ENERGY((re
|
|
|
10979 |
* re + im * im) * 0.5);
|
|
|
10980 |
}
|
|
|
10981 |
for (var b = 2; b >= 0; --b) {
|
|
|
10982 |
fftenergy_s[b][0] = (wsamp_s[wsamp_sPos + 0])[b][0];
|
|
|
10983 |
fftenergy_s[b][0] *= fftenergy_s[b][0];
|
|
|
10984 |
for (var j = Encoder.BLKSIZE_s / 2 - 1; j >= 0; --j) {
|
|
|
10985 |
var re = (wsamp_s[wsamp_sPos + 0])[b][Encoder.BLKSIZE_s
|
|
|
10986 |
/ 2 - j];
|
|
|
10987 |
var im = (wsamp_s[wsamp_sPos + 0])[b][Encoder.BLKSIZE_s
|
|
|
10988 |
/ 2 + j];
|
|
|
10989 |
fftenergy_s[b][Encoder.BLKSIZE_s / 2 - j] = NON_LINEAR_SCALE_ENERGY((re
|
|
|
10990 |
* re + im * im) * 0.5);
|
|
|
10991 |
}
|
|
|
10992 |
}
|
|
|
10993 |
/* total energy */
|
|
|
10994 |
{
|
|
|
10995 |
var totalenergy = 0.0;
|
|
|
10996 |
for (var j = 11; j < Encoder.HBLKSIZE; j++)
|
|
|
10997 |
totalenergy += fftenergy[j];
|
|
|
10998 |
|
|
|
10999 |
gfc.tot_ener[chn] = totalenergy;
|
|
|
11000 |
}
|
|
|
11001 |
|
|
|
11002 |
if (gfp.analysis) {
|
|
|
11003 |
for (var j = 0; j < Encoder.HBLKSIZE; j++) {
|
|
|
11004 |
gfc.pinfo.energy[gr_out][chn][j] = gfc.pinfo.energy_save[chn][j];
|
|
|
11005 |
gfc.pinfo.energy_save[chn][j] = fftenergy[j];
|
|
|
11006 |
}
|
|
|
11007 |
gfc.pinfo.pe[gr_out][chn] = gfc.pe[chn];
|
|
|
11008 |
}
|
|
|
11009 |
|
|
|
11010 |
/*********************************************************************
|
|
|
11011 |
* compute loudness approximation (used for ATH auto-level adjustment)
|
|
|
11012 |
*********************************************************************/
|
|
|
11013 |
if (gfp.athaa_loudapprox == 2 && chn < 2) {
|
|
|
11014 |
// no loudness for mid/side ch
|
|
|
11015 |
gfc.loudness_sq[gr_out][chn] = gfc.loudness_sq_save[chn];
|
|
|
11016 |
gfc.loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc);
|
|
|
11017 |
}
|
|
|
11018 |
}
|
|
|
11019 |
|
|
|
11020 |
/* mask_add optimization */
|
|
|
11021 |
/* init the limit values used to avoid computing log in mask_add when it is not necessary */
|
|
|
11022 |
|
|
|
11023 |
/**
|
|
|
11024 |
* <PRE>
|
|
|
11025 |
* For example, with i = 10*log10(m2/m1)/10*16 (= log10(m2/m1)*16)
|
|
|
11026 |
*
|
|
|
11027 |
* abs(i)>8 is equivalent (as i is an integer) to
|
|
|
11028 |
* abs(i)>=9
|
|
|
11029 |
* i>=9 || i<=-9
|
|
|
11030 |
* equivalent to (as i is the biggest integer smaller than log10(m2/m1)*16
|
|
|
11031 |
* or the smallest integer bigger than log10(m2/m1)*16 depending on the sign of log10(m2/m1)*16)
|
|
|
11032 |
* log10(m2/m1)>=9/16 || log10(m2/m1)<=-9/16
|
|
|
11033 |
* exp10 is strictly increasing thus this is equivalent to
|
|
|
11034 |
* m2/m1 >= 10^(9/16) || m2/m1<=10^(-9/16) which are comparisons to constants
|
|
|
11035 |
* </PRE>
|
|
|
11036 |
*/
|
|
|
11037 |
|
|
|
11038 |
/**
|
|
|
11039 |
* as in if(i>8)
|
|
|
11040 |
*/
|
|
|
11041 |
var I1LIMIT = 8;
|
|
|
11042 |
/**
|
|
|
11043 |
* as in if(i>24) . changed 23
|
|
|
11044 |
*/
|
|
|
11045 |
var I2LIMIT = 23;
|
|
|
11046 |
/**
|
|
|
11047 |
* as in if(m<15)
|
|
|
11048 |
*/
|
|
|
11049 |
var MLIMIT = 15;
|
|
|
11050 |
|
|
|
11051 |
var ma_max_i1;
|
|
|
11052 |
var ma_max_i2;
|
|
|
11053 |
var ma_max_m;
|
|
|
11054 |
|
|
|
11055 |
/**
|
|
|
11056 |
* This is the masking table:<BR>
|
|
|
11057 |
* According to tonality, values are going from 0dB (TMN) to 9.3dB (NMT).<BR>
|
|
|
11058 |
* After additive masking computation, 8dB are added, so final values are
|
|
|
11059 |
* going from 8dB to 17.3dB
|
|
|
11060 |
*
|
|
|
11061 |
* pow(10, -0.0..-0.6)
|
|
|
11062 |
*/
|
|
|
11063 |
var tab = [1.0, 0.79433, 0.63096, 0.63096,
|
|
|
11064 |
0.63096, 0.63096, 0.63096, 0.25119, 0.11749];
|
|
|
11065 |
|
|
|
11066 |
function init_mask_add_max_values() {
|
|
|
11067 |
ma_max_i1 = Math.pow(10, (I1LIMIT + 1) / 16.0);
|
|
|
11068 |
ma_max_i2 = Math.pow(10, (I2LIMIT + 1) / 16.0);
|
|
|
11069 |
ma_max_m = Math.pow(10, (MLIMIT) / 10.0);
|
|
|
11070 |
}
|
|
|
11071 |
|
|
|
11072 |
var table1 = [3.3246 * 3.3246,
|
|
|
11073 |
3.23837 * 3.23837, 3.15437 * 3.15437, 3.00412 * 3.00412,
|
|
|
11074 |
2.86103 * 2.86103, 2.65407 * 2.65407, 2.46209 * 2.46209,
|
|
|
11075 |
2.284 * 2.284, 2.11879 * 2.11879, 1.96552 * 1.96552,
|
|
|
11076 |
1.82335 * 1.82335, 1.69146 * 1.69146, 1.56911 * 1.56911,
|
|
|
11077 |
1.46658 * 1.46658, 1.37074 * 1.37074, 1.31036 * 1.31036,
|
|
|
11078 |
1.25264 * 1.25264, 1.20648 * 1.20648, 1.16203 * 1.16203,
|
|
|
11079 |
1.12765 * 1.12765, 1.09428 * 1.09428, 1.0659 * 1.0659,
|
|
|
11080 |
1.03826 * 1.03826, 1.01895 * 1.01895, 1];
|
|
|
11081 |
|
|
|
11082 |
var table2 = [1.33352 * 1.33352,
|
|
|
11083 |
1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497,
|
|
|
11084 |
1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382,
|
|
|
11085 |
1.22321 * 1.22321, 1.14758 * 1.14758, 1];
|
|
|
11086 |
|
|
|
11087 |
var table3 = [2.35364 * 2.35364,
|
|
|
11088 |
2.29259 * 2.29259, 2.23313 * 2.23313, 2.12675 * 2.12675,
|
|
|
11089 |
2.02545 * 2.02545, 1.87894 * 1.87894, 1.74303 * 1.74303,
|
|
|
11090 |
1.61695 * 1.61695, 1.49999 * 1.49999, 1.39148 * 1.39148,
|
|
|
11091 |
1.29083 * 1.29083, 1.19746 * 1.19746, 1.11084 * 1.11084,
|
|
|
11092 |
1.03826 * 1.03826];
|
|
|
11093 |
|
|
|
11094 |
/**
|
|
|
11095 |
* addition of simultaneous masking Naoki Shibata 2000/7
|
|
|
11096 |
*/
|
|
|
11097 |
function mask_add(m1, m2, kk, b, gfc, shortblock) {
|
|
|
11098 |
var ratio;
|
|
|
11099 |
|
|
|
11100 |
if (m2 > m1) {
|
|
|
11101 |
if (m2 < (m1 * ma_max_i2))
|
|
|
11102 |
ratio = m2 / m1;
|
|
|
11103 |
else
|
|
|
11104 |
return (m1 + m2);
|
|
|
11105 |
} else {
|
|
|
11106 |
if (m1 >= (m2 * ma_max_i2))
|
|
|
11107 |
return (m1 + m2);
|
|
|
11108 |
ratio = m1 / m2;
|
|
|
11109 |
}
|
|
|
11110 |
|
|
|
11111 |
/* Should always be true, just checking */
|
|
|
11112 |
|
|
|
11113 |
m1 += m2;
|
|
|
11114 |
//if (((long)(b + 3) & 0xffffffff) <= 3 + 3) {
|
|
|
11115 |
if ((b + 3) <= 3 + 3) {
|
|
|
11116 |
/* approximately, 1 bark = 3 partitions */
|
|
|
11117 |
/* 65% of the cases */
|
|
|
11118 |
/* originally 'if(i > 8)' */
|
|
|
11119 |
if (ratio >= ma_max_i1) {
|
|
|
11120 |
/* 43% of the total */
|
|
|
11121 |
return m1;
|
|
|
11122 |
}
|
|
|
11123 |
|
|
|
11124 |
/* 22% of the total */
|
|
|
11125 |
var i = 0 | (Util.FAST_LOG10_X(ratio, 16.0));
|
|
|
11126 |
return m1 * table2[i];
|
|
|
11127 |
}
|
|
|
11128 |
|
|
|
11129 |
/**
|
|
|
11130 |
* <PRE>
|
|
|
11131 |
* m<15 equ log10((m1+m2)/gfc.ATH.cb[k])<1.5
|
|
|
11132 |
* equ (m1+m2)/gfc.ATH.cb[k]<10^1.5
|
|
|
11133 |
* equ (m1+m2)<10^1.5 * gfc.ATH.cb[k]
|
|
|
11134 |
* </PRE>
|
|
|
11135 |
*/
|
|
|
11136 |
var i = 0 | Util.FAST_LOG10_X(ratio, 16.0);
|
|
|
11137 |
if (shortblock != 0) {
|
|
|
11138 |
m2 = gfc.ATH.cb_s[kk] * gfc.ATH.adjust;
|
|
|
11139 |
} else {
|
|
|
11140 |
m2 = gfc.ATH.cb_l[kk] * gfc.ATH.adjust;
|
|
|
11141 |
}
|
|
|
11142 |
if (m1 < ma_max_m * m2) {
|
|
|
11143 |
/* 3% of the total */
|
|
|
11144 |
/* Originally if (m > 0) { */
|
|
|
11145 |
if (m1 > m2) {
|
|
|
11146 |
var f, r;
|
|
|
11147 |
|
|
|
11148 |
f = 1.0;
|
|
|
11149 |
if (i <= 13)
|
|
|
11150 |
f = table3[i];
|
|
|
11151 |
|
|
|
11152 |
r = Util.FAST_LOG10_X(m1 / m2, 10.0 / 15.0);
|
|
|
11153 |
return m1 * ((table1[i] - f) * r + f);
|
|
|
11154 |
}
|
|
|
11155 |
|
|
|
11156 |
if (i > 13)
|
|
|
11157 |
return m1;
|
|
|
11158 |
|
|
|
11159 |
return m1 * table3[i];
|
|
|
11160 |
}
|
|
|
11161 |
|
|
|
11162 |
/* 10% of total */
|
|
|
11163 |
return m1 * table1[i];
|
|
|
11164 |
}
|
|
|
11165 |
|
|
|
11166 |
var table2_ = [1.33352 * 1.33352,
|
|
|
11167 |
1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497,
|
|
|
11168 |
1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382,
|
|
|
11169 |
1.22321 * 1.22321, 1.14758 * 1.14758, 1];
|
|
|
11170 |
|
|
|
11171 |
/**
|
|
|
11172 |
* addition of simultaneous masking Naoki Shibata 2000/7
|
|
|
11173 |
*/
|
|
|
11174 |
function vbrpsy_mask_add(m1, m2, b) {
|
|
|
11175 |
var ratio;
|
|
|
11176 |
|
|
|
11177 |
if (m1 < 0) {
|
|
|
11178 |
m1 = 0;
|
|
|
11179 |
}
|
|
|
11180 |
if (m2 < 0) {
|
|
|
11181 |
m2 = 0;
|
|
|
11182 |
}
|
|
|
11183 |
if (m1 <= 0) {
|
|
|
11184 |
return m2;
|
|
|
11185 |
}
|
|
|
11186 |
if (m2 <= 0) {
|
|
|
11187 |
return m1;
|
|
|
11188 |
}
|
|
|
11189 |
if (m2 > m1) {
|
|
|
11190 |
ratio = m2 / m1;
|
|
|
11191 |
} else {
|
|
|
11192 |
ratio = m1 / m2;
|
|
|
11193 |
}
|
|
|
11194 |
if (-2 <= b && b <= 2) {
|
|
|
11195 |
/* approximately, 1 bark = 3 partitions */
|
|
|
11196 |
/* originally 'if(i > 8)' */
|
|
|
11197 |
if (ratio >= ma_max_i1) {
|
|
|
11198 |
return m1 + m2;
|
|
|
11199 |
} else {
|
|
|
11200 |
var i = 0 | (Util.FAST_LOG10_X(ratio, 16.0));
|
|
|
11201 |
return (m1 + m2) * table2_[i];
|
|
|
11202 |
}
|
|
|
11203 |
}
|
|
|
11204 |
if (ratio < ma_max_i2) {
|
|
|
11205 |
return m1 + m2;
|
|
|
11206 |
}
|
|
|
11207 |
if (m1 < m2) {
|
|
|
11208 |
m1 = m2;
|
|
|
11209 |
}
|
|
|
11210 |
return m1;
|
|
|
11211 |
}
|
|
|
11212 |
|
|
|
11213 |
/**
|
|
|
11214 |
* compute interchannel masking effects
|
|
|
11215 |
*/
|
|
|
11216 |
function calc_interchannel_masking(gfp, ratio) {
|
|
|
11217 |
var gfc = gfp.internal_flags;
|
|
|
11218 |
if (gfc.channels_out > 1) {
|
|
|
11219 |
for (var sb = 0; sb < Encoder.SBMAX_l; sb++) {
|
|
|
11220 |
var l = gfc.thm[0].l[sb];
|
|
|
11221 |
var r = gfc.thm[1].l[sb];
|
|
|
11222 |
gfc.thm[0].l[sb] += r * ratio;
|
|
|
11223 |
gfc.thm[1].l[sb] += l * ratio;
|
|
|
11224 |
}
|
|
|
11225 |
for (var sb = 0; sb < Encoder.SBMAX_s; sb++) {
|
|
|
11226 |
for (var sblock = 0; sblock < 3; sblock++) {
|
|
|
11227 |
var l = gfc.thm[0].s[sb][sblock];
|
|
|
11228 |
var r = gfc.thm[1].s[sb][sblock];
|
|
|
11229 |
gfc.thm[0].s[sb][sblock] += r * ratio;
|
|
|
11230 |
gfc.thm[1].s[sb][sblock] += l * ratio;
|
|
|
11231 |
}
|
|
|
11232 |
}
|
|
|
11233 |
}
|
|
|
11234 |
}
|
|
|
11235 |
|
|
|
11236 |
/**
|
|
|
11237 |
* compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper
|
|
|
11238 |
*/
|
|
|
11239 |
function msfix1(gfc) {
|
|
|
11240 |
for (var sb = 0; sb < Encoder.SBMAX_l; sb++) {
|
|
|
11241 |
/* use this fix if L & R masking differs by 2db or less */
|
|
|
11242 |
/* if db = 10*log10(x2/x1) < 2 */
|
|
|
11243 |
/* if (x2 < 1.58*x1) { */
|
|
|
11244 |
if (gfc.thm[0].l[sb] > 1.58 * gfc.thm[1].l[sb]
|
|
|
11245 |
|| gfc.thm[1].l[sb] > 1.58 * gfc.thm[0].l[sb])
|
|
|
11246 |
continue;
|
|
|
11247 |
var mld = gfc.mld_l[sb] * gfc.en[3].l[sb];
|
|
|
11248 |
var rmid = Math.max(gfc.thm[2].l[sb],
|
|
|
11249 |
Math.min(gfc.thm[3].l[sb], mld));
|
|
|
11250 |
|
|
|
11251 |
mld = gfc.mld_l[sb] * gfc.en[2].l[sb];
|
|
|
11252 |
var rside = Math.max(gfc.thm[3].l[sb],
|
|
|
11253 |
Math.min(gfc.thm[2].l[sb], mld));
|
|
|
11254 |
gfc.thm[2].l[sb] = rmid;
|
|
|
11255 |
gfc.thm[3].l[sb] = rside;
|
|
|
11256 |
}
|
|
|
11257 |
|
|
|
11258 |
for (var sb = 0; sb < Encoder.SBMAX_s; sb++) {
|
|
|
11259 |
for (var sblock = 0; sblock < 3; sblock++) {
|
|
|
11260 |
if (gfc.thm[0].s[sb][sblock] > 1.58 * gfc.thm[1].s[sb][sblock]
|
|
|
11261 |
|| gfc.thm[1].s[sb][sblock] > 1.58 * gfc.thm[0].s[sb][sblock])
|
|
|
11262 |
continue;
|
|
|
11263 |
var mld = gfc.mld_s[sb] * gfc.en[3].s[sb][sblock];
|
|
|
11264 |
var rmid = Math.max(gfc.thm[2].s[sb][sblock],
|
|
|
11265 |
Math.min(gfc.thm[3].s[sb][sblock], mld));
|
|
|
11266 |
|
|
|
11267 |
mld = gfc.mld_s[sb] * gfc.en[2].s[sb][sblock];
|
|
|
11268 |
var rside = Math.max(gfc.thm[3].s[sb][sblock],
|
|
|
11269 |
Math.min(gfc.thm[2].s[sb][sblock], mld));
|
|
|
11270 |
|
|
|
11271 |
gfc.thm[2].s[sb][sblock] = rmid;
|
|
|
11272 |
gfc.thm[3].s[sb][sblock] = rside;
|
|
|
11273 |
}
|
|
|
11274 |
}
|
|
|
11275 |
}
|
|
|
11276 |
|
|
|
11277 |
/**
|
|
|
11278 |
* Adjust M/S maskings if user set "msfix"
|
|
|
11279 |
*
|
|
|
11280 |
* Naoki Shibata 2000
|
|
|
11281 |
*/
|
|
|
11282 |
function ns_msfix(gfc, msfix, athadjust) {
|
|
|
11283 |
var msfix2 = msfix;
|
|
|
11284 |
var athlower = Math.pow(10, athadjust);
|
|
|
11285 |
|
|
|
11286 |
msfix *= 2.0;
|
|
|
11287 |
msfix2 *= 2.0;
|
|
|
11288 |
for (var sb = 0; sb < Encoder.SBMAX_l; sb++) {
|
|
|
11289 |
var thmLR, thmM, thmS, ath;
|
|
|
11290 |
ath = (gfc.ATH.cb_l[gfc.bm_l[sb]]) * athlower;
|
|
|
11291 |
thmLR = Math.min(Math.max(gfc.thm[0].l[sb], ath),
|
|
|
11292 |
Math.max(gfc.thm[1].l[sb], ath));
|
|
|
11293 |
thmM = Math.max(gfc.thm[2].l[sb], ath);
|
|
|
11294 |
thmS = Math.max(gfc.thm[3].l[sb], ath);
|
|
|
11295 |
if (thmLR * msfix < thmM + thmS) {
|
|
|
11296 |
var f = thmLR * msfix2 / (thmM + thmS);
|
|
|
11297 |
thmM *= f;
|
|
|
11298 |
thmS *= f;
|
|
|
11299 |
}
|
|
|
11300 |
gfc.thm[2].l[sb] = Math.min(thmM, gfc.thm[2].l[sb]);
|
|
|
11301 |
gfc.thm[3].l[sb] = Math.min(thmS, gfc.thm[3].l[sb]);
|
|
|
11302 |
}
|
|
|
11303 |
|
|
|
11304 |
athlower *= ( Encoder.BLKSIZE_s / Encoder.BLKSIZE);
|
|
|
11305 |
for (var sb = 0; sb < Encoder.SBMAX_s; sb++) {
|
|
|
11306 |
for (var sblock = 0; sblock < 3; sblock++) {
|
|
|
11307 |
var thmLR, thmM, thmS, ath;
|
|
|
11308 |
ath = (gfc.ATH.cb_s[gfc.bm_s[sb]]) * athlower;
|
|
|
11309 |
thmLR = Math.min(Math.max(gfc.thm[0].s[sb][sblock], ath),
|
|
|
11310 |
Math.max(gfc.thm[1].s[sb][sblock], ath));
|
|
|
11311 |
thmM = Math.max(gfc.thm[2].s[sb][sblock], ath);
|
|
|
11312 |
thmS = Math.max(gfc.thm[3].s[sb][sblock], ath);
|
|
|
11313 |
|
|
|
11314 |
if (thmLR * msfix < thmM + thmS) {
|
|
|
11315 |
var f = thmLR * msfix / (thmM + thmS);
|
|
|
11316 |
thmM *= f;
|
|
|
11317 |
thmS *= f;
|
|
|
11318 |
}
|
|
|
11319 |
gfc.thm[2].s[sb][sblock] = Math.min(gfc.thm[2].s[sb][sblock],
|
|
|
11320 |
thmM);
|
|
|
11321 |
gfc.thm[3].s[sb][sblock] = Math.min(gfc.thm[3].s[sb][sblock],
|
|
|
11322 |
thmS);
|
|
|
11323 |
}
|
|
|
11324 |
}
|
|
|
11325 |
}
|
|
|
11326 |
|
|
|
11327 |
/**
|
|
|
11328 |
* short block threshold calculation (part 2)
|
|
|
11329 |
*
|
|
|
11330 |
* partition band bo_s[sfb] is at the transition from scalefactor band sfb
|
|
|
11331 |
* to the next one sfb+1; enn and thmm have to be split between them
|
|
|
11332 |
*/
|
|
|
11333 |
function convert_partition2scalefac_s(gfc, eb, thr, chn, sblock) {
|
|
|
11334 |
var sb, b;
|
|
|
11335 |
var enn = 0.0;
|
|
|
11336 |
var thmm = 0.0;
|
|
|
11337 |
for (sb = b = 0; sb < Encoder.SBMAX_s; ++b, ++sb) {
|
|
|
11338 |
var bo_s_sb = gfc.bo_s[sb];
|
|
|
11339 |
var npart_s = gfc.npart_s;
|
|
|
11340 |
var b_lim = bo_s_sb < npart_s ? bo_s_sb : npart_s;
|
|
|
11341 |
while (b < b_lim) {
|
|
|
11342 |
// iff failed, it may indicate some index error elsewhere
|
|
|
11343 |
enn += eb[b];
|
|
|
11344 |
thmm += thr[b];
|
|
|
11345 |
b++;
|
|
|
11346 |
}
|
|
|
11347 |
gfc.en[chn].s[sb][sblock] = enn;
|
|
|
11348 |
gfc.thm[chn].s[sb][sblock] = thmm;
|
|
|
11349 |
|
|
|
11350 |
if (b >= npart_s) {
|
|
|
11351 |
++sb;
|
|
|
11352 |
break;
|
|
|
11353 |
}
|
|
|
11354 |
// iff failed, it may indicate some index error elsewhere
|
|
|
11355 |
{
|
|
|
11356 |
/* at transition sfb . sfb+1 */
|
|
|
11357 |
var w_curr = gfc.PSY.bo_s_weight[sb];
|
|
|
11358 |
var w_next = 1.0 - w_curr;
|
|
|
11359 |
enn = w_curr * eb[b];
|
|
|
11360 |
thmm = w_curr * thr[b];
|
|
|
11361 |
gfc.en[chn].s[sb][sblock] += enn;
|
|
|
11362 |
gfc.thm[chn].s[sb][sblock] += thmm;
|
|
|
11363 |
enn = w_next * eb[b];
|
|
|
11364 |
thmm = w_next * thr[b];
|
|
|
11365 |
}
|
|
|
11366 |
}
|
|
|
11367 |
/* zero initialize the rest */
|
|
|
11368 |
for (; sb < Encoder.SBMAX_s; ++sb) {
|
|
|
11369 |
gfc.en[chn].s[sb][sblock] = 0;
|
|
|
11370 |
gfc.thm[chn].s[sb][sblock] = 0;
|
|
|
11371 |
}
|
|
|
11372 |
}
|
|
|
11373 |
|
|
|
11374 |
/**
|
|
|
11375 |
* longblock threshold calculation (part 2)
|
|
|
11376 |
*/
|
|
|
11377 |
function convert_partition2scalefac_l(gfc, eb, thr, chn) {
|
|
|
11378 |
var sb, b;
|
|
|
11379 |
var enn = 0.0;
|
|
|
11380 |
var thmm = 0.0;
|
|
|
11381 |
for (sb = b = 0; sb < Encoder.SBMAX_l; ++b, ++sb) {
|
|
|
11382 |
var bo_l_sb = gfc.bo_l[sb];
|
|
|
11383 |
var npart_l = gfc.npart_l;
|
|
|
11384 |
var b_lim = bo_l_sb < npart_l ? bo_l_sb : npart_l;
|
|
|
11385 |
while (b < b_lim) {
|
|
|
11386 |
// iff failed, it may indicate some index error elsewhere
|
|
|
11387 |
enn += eb[b];
|
|
|
11388 |
thmm += thr[b];
|
|
|
11389 |
b++;
|
|
|
11390 |
}
|
|
|
11391 |
gfc.en[chn].l[sb] = enn;
|
|
|
11392 |
gfc.thm[chn].l[sb] = thmm;
|
|
|
11393 |
|
|
|
11394 |
if (b >= npart_l) {
|
|
|
11395 |
++sb;
|
|
|
11396 |
break;
|
|
|
11397 |
}
|
|
|
11398 |
{
|
|
|
11399 |
/* at transition sfb . sfb+1 */
|
|
|
11400 |
var w_curr = gfc.PSY.bo_l_weight[sb];
|
|
|
11401 |
var w_next = 1.0 - w_curr;
|
|
|
11402 |
enn = w_curr * eb[b];
|
|
|
11403 |
thmm = w_curr * thr[b];
|
|
|
11404 |
gfc.en[chn].l[sb] += enn;
|
|
|
11405 |
gfc.thm[chn].l[sb] += thmm;
|
|
|
11406 |
enn = w_next * eb[b];
|
|
|
11407 |
thmm = w_next * thr[b];
|
|
|
11408 |
}
|
|
|
11409 |
}
|
|
|
11410 |
/* zero initialize the rest */
|
|
|
11411 |
for (; sb < Encoder.SBMAX_l; ++sb) {
|
|
|
11412 |
gfc.en[chn].l[sb] = 0;
|
|
|
11413 |
gfc.thm[chn].l[sb] = 0;
|
|
|
11414 |
}
|
|
|
11415 |
}
|
|
|
11416 |
|
|
|
11417 |
function compute_masking_s(gfp, fftenergy_s, eb, thr, chn, sblock) {
|
|
|
11418 |
var gfc = gfp.internal_flags;
|
|
|
11419 |
var j, b;
|
|
|
11420 |
|
|
|
11421 |
for (b = j = 0; b < gfc.npart_s; ++b) {
|
|
|
11422 |
var ebb = 0, m = 0;
|
|
|
11423 |
var n = gfc.numlines_s[b];
|
|
|
11424 |
for (var i = 0; i < n; ++i, ++j) {
|
|
|
11425 |
var el = fftenergy_s[sblock][j];
|
|
|
11426 |
ebb += el;
|
|
|
11427 |
if (m < el)
|
|
|
11428 |
m = el;
|
|
|
11429 |
}
|
|
|
11430 |
eb[b] = ebb;
|
|
|
11431 |
}
|
|
|
11432 |
for (j = b = 0; b < gfc.npart_s; b++) {
|
|
|
11433 |
var kk = gfc.s3ind_s[b][0];
|
|
|
11434 |
var ecb = gfc.s3_ss[j++] * eb[kk];
|
|
|
11435 |
++kk;
|
|
|
11436 |
while (kk <= gfc.s3ind_s[b][1]) {
|
|
|
11437 |
ecb += gfc.s3_ss[j] * eb[kk];
|
|
|
11438 |
++j;
|
|
|
11439 |
++kk;
|
|
|
11440 |
}
|
|
|
11441 |
|
|
|
11442 |
{ /* limit calculated threshold by previous granule */
|
|
|
11443 |
var x = rpelev_s * gfc.nb_s1[chn][b];
|
|
|
11444 |
thr[b] = Math.min(ecb, x);
|
|
|
11445 |
}
|
|
|
11446 |
if (gfc.blocktype_old[chn & 1] == Encoder.SHORT_TYPE) {
|
|
|
11447 |
/* limit calculated threshold by even older granule */
|
|
|
11448 |
var x = rpelev2_s * gfc.nb_s2[chn][b];
|
|
|
11449 |
var y = thr[b];
|
|
|
11450 |
thr[b] = Math.min(x, y);
|
|
|
11451 |
}
|
|
|
11452 |
|
|
|
11453 |
gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b];
|
|
|
11454 |
gfc.nb_s1[chn][b] = ecb;
|
|
|
11455 |
}
|
|
|
11456 |
for (; b <= Encoder.CBANDS; ++b) {
|
|
|
11457 |
eb[b] = 0;
|
|
|
11458 |
thr[b] = 0;
|
|
|
11459 |
}
|
|
|
11460 |
}
|
|
|
11461 |
|
|
|
11462 |
function block_type_set(gfp, uselongblock, blocktype_d, blocktype) {
|
|
|
11463 |
var gfc = gfp.internal_flags;
|
|
|
11464 |
|
|
|
11465 |
if (gfp.short_blocks == ShortBlock.short_block_coupled
|
|
|
11466 |
/* force both channels to use the same block type */
|
|
|
11467 |
/* this is necessary if the frame is to be encoded in ms_stereo. */
|
|
|
11468 |
/* But even without ms_stereo, FhG does this */
|
|
|
11469 |
&& !(uselongblock[0] != 0 && uselongblock[1] != 0))
|
|
|
11470 |
uselongblock[0] = uselongblock[1] = 0;
|
|
|
11471 |
|
|
|
11472 |
/*
|
|
|
11473 |
* update the blocktype of the previous granule, since it depends on
|
|
|
11474 |
* what happend in this granule
|
|
|
11475 |
*/
|
|
|
11476 |
for (var chn = 0; chn < gfc.channels_out; chn++) {
|
|
|
11477 |
blocktype[chn] = Encoder.NORM_TYPE;
|
|
|
11478 |
/* disable short blocks */
|
|
|
11479 |
if (gfp.short_blocks == ShortBlock.short_block_dispensed)
|
|
|
11480 |
uselongblock[chn] = 1;
|
|
|
11481 |
if (gfp.short_blocks == ShortBlock.short_block_forced)
|
|
|
11482 |
uselongblock[chn] = 0;
|
|
|
11483 |
|
|
|
11484 |
if (uselongblock[chn] != 0) {
|
|
|
11485 |
/* no attack : use long blocks */
|
|
|
11486 |
if (gfc.blocktype_old[chn] == Encoder.SHORT_TYPE)
|
|
|
11487 |
blocktype[chn] = Encoder.STOP_TYPE;
|
|
|
11488 |
} else {
|
|
|
11489 |
/* attack : use short blocks */
|
|
|
11490 |
blocktype[chn] = Encoder.SHORT_TYPE;
|
|
|
11491 |
if (gfc.blocktype_old[chn] == Encoder.NORM_TYPE) {
|
|
|
11492 |
gfc.blocktype_old[chn] = Encoder.START_TYPE;
|
|
|
11493 |
}
|
|
|
11494 |
if (gfc.blocktype_old[chn] == Encoder.STOP_TYPE)
|
|
|
11495 |
gfc.blocktype_old[chn] = Encoder.SHORT_TYPE;
|
|
|
11496 |
}
|
|
|
11497 |
|
|
|
11498 |
blocktype_d[chn] = gfc.blocktype_old[chn];
|
|
|
11499 |
// value returned to calling program
|
|
|
11500 |
gfc.blocktype_old[chn] = blocktype[chn];
|
|
|
11501 |
// save for next call to l3psy_anal
|
|
|
11502 |
}
|
|
|
11503 |
}
|
|
|
11504 |
|
|
|
11505 |
function NS_INTERP(x, y, r) {
|
|
|
11506 |
/* was pow((x),(r))*pow((y),1-(r)) */
|
|
|
11507 |
if (r >= 1.0) {
|
|
|
11508 |
/* 99.7% of the time */
|
|
|
11509 |
return x;
|
|
|
11510 |
}
|
|
|
11511 |
if (r <= 0.0)
|
|
|
11512 |
return y;
|
|
|
11513 |
if (y > 0.0) {
|
|
|
11514 |
/* rest of the time */
|
|
|
11515 |
return (Math.pow(x / y, r) * y);
|
|
|
11516 |
}
|
|
|
11517 |
/* never happens */
|
|
|
11518 |
return 0.0;
|
|
|
11519 |
}
|
|
|
11520 |
|
|
|
11521 |
/**
|
|
|
11522 |
* these values are tuned only for 44.1kHz...
|
|
|
11523 |
*/
|
|
|
11524 |
var regcoef_s = [11.8, 13.6, 17.2, 32, 46.5,
|
|
|
11525 |
51.3, 57.5, 67.1, 71.5, 84.6, 97.6, 130,
|
|
|
11526 |
/* 255.8 */
|
|
|
11527 |
];
|
|
|
11528 |
|
|
|
11529 |
function pecalc_s(mr, masking_lower) {
|
|
|
11530 |
var pe_s = 1236.28 / 4;
|
|
|
11531 |
for (var sb = 0; sb < Encoder.SBMAX_s - 1; sb++) {
|
|
|
11532 |
for (var sblock = 0; sblock < 3; sblock++) {
|
|
|
11533 |
var thm = mr.thm.s[sb][sblock];
|
|
|
11534 |
if (thm > 0.0) {
|
|
|
11535 |
var x = thm * masking_lower;
|
|
|
11536 |
var en = mr.en.s[sb][sblock];
|
|
|
11537 |
if (en > x) {
|
|
|
11538 |
if (en > x * 1e10) {
|
|
|
11539 |
pe_s += regcoef_s[sb] * (10.0 * LOG10);
|
|
|
11540 |
} else {
|
|
|
11541 |
pe_s += regcoef_s[sb] * Util.FAST_LOG10(en / x);
|
|
|
11542 |
}
|
|
|
11543 |
}
|
|
|
11544 |
}
|
|
|
11545 |
}
|
|
|
11546 |
}
|
|
|
11547 |
|
|
|
11548 |
return pe_s;
|
|
|
11549 |
}
|
|
|
11550 |
|
|
|
11551 |
/**
|
|
|
11552 |
* these values are tuned only for 44.1kHz...
|
|
|
11553 |
*/
|
|
|
11554 |
var regcoef_l = [6.8, 5.8, 5.8, 6.4, 6.5, 9.9,
|
|
|
11555 |
12.1, 14.4, 15, 18.9, 21.6, 26.9, 34.2, 40.2, 46.8, 56.5,
|
|
|
11556 |
60.7, 73.9, 85.7, 93.4, 126.1,
|
|
|
11557 |
/* 241.3 */
|
|
|
11558 |
];
|
|
|
11559 |
|
|
|
11560 |
function pecalc_l(mr, masking_lower) {
|
|
|
11561 |
var pe_l = 1124.23 / 4;
|
|
|
11562 |
for (var sb = 0; sb < Encoder.SBMAX_l - 1; sb++) {
|
|
|
11563 |
var thm = mr.thm.l[sb];
|
|
|
11564 |
if (thm > 0.0) {
|
|
|
11565 |
var x = thm * masking_lower;
|
|
|
11566 |
var en = mr.en.l[sb];
|
|
|
11567 |
if (en > x) {
|
|
|
11568 |
if (en > x * 1e10) {
|
|
|
11569 |
pe_l += regcoef_l[sb] * (10.0 * LOG10);
|
|
|
11570 |
} else {
|
|
|
11571 |
pe_l += regcoef_l[sb] * Util.FAST_LOG10(en / x);
|
|
|
11572 |
}
|
|
|
11573 |
}
|
|
|
11574 |
}
|
|
|
11575 |
}
|
|
|
11576 |
return pe_l;
|
|
|
11577 |
}
|
|
|
11578 |
|
|
|
11579 |
function calc_energy(gfc, fftenergy, eb, max, avg) {
|
|
|
11580 |
var b, j;
|
|
|
11581 |
|
|
|
11582 |
for (b = j = 0; b < gfc.npart_l; ++b) {
|
|
|
11583 |
var ebb = 0, m = 0;
|
|
|
11584 |
var i;
|
|
|
11585 |
for (i = 0; i < gfc.numlines_l[b]; ++i, ++j) {
|
|
|
11586 |
var el = fftenergy[j];
|
|
|
11587 |
ebb += el;
|
|
|
11588 |
if (m < el)
|
|
|
11589 |
m = el;
|
|
|
11590 |
}
|
|
|
11591 |
eb[b] = ebb;
|
|
|
11592 |
max[b] = m;
|
|
|
11593 |
avg[b] = ebb * gfc.rnumlines_l[b];
|
|
|
11594 |
}
|
|
|
11595 |
}
|
|
|
11596 |
|
|
|
11597 |
function calc_mask_index_l(gfc, max, avg, mask_idx) {
|
|
|
11598 |
var last_tab_entry = tab.length - 1;
|
|
|
11599 |
var b = 0;
|
|
|
11600 |
var a = avg[b] + avg[b + 1];
|
|
|
11601 |
if (a > 0.0) {
|
|
|
11602 |
var m = max[b];
|
|
|
11603 |
if (m < max[b + 1])
|
|
|
11604 |
m = max[b + 1];
|
|
|
11605 |
a = 20.0 * (m * 2.0 - a)
|
|
|
11606 |
/ (a * (gfc.numlines_l[b] + gfc.numlines_l[b + 1] - 1));
|
|
|
11607 |
var k = 0 | a;
|
|
|
11608 |
if (k > last_tab_entry)
|
|
|
11609 |
k = last_tab_entry;
|
|
|
11610 |
mask_idx[b] = k;
|
|
|
11611 |
} else {
|
|
|
11612 |
mask_idx[b] = 0;
|
|
|
11613 |
}
|
|
|
11614 |
|
|
|
11615 |
for (b = 1; b < gfc.npart_l - 1; b++) {
|
|
|
11616 |
a = avg[b - 1] + avg[b] + avg[b + 1];
|
|
|
11617 |
if (a > 0.0) {
|
|
|
11618 |
var m = max[b - 1];
|
|
|
11619 |
if (m < max[b])
|
|
|
11620 |
m = max[b];
|
|
|
11621 |
if (m < max[b + 1])
|
|
|
11622 |
m = max[b + 1];
|
|
|
11623 |
a = 20.0
|
|
|
11624 |
* (m * 3.0 - a)
|
|
|
11625 |
/ (a * (gfc.numlines_l[b - 1] + gfc.numlines_l[b]
|
|
|
11626 |
+ gfc.numlines_l[b + 1] - 1));
|
|
|
11627 |
var k = 0 | a;
|
|
|
11628 |
if (k > last_tab_entry)
|
|
|
11629 |
k = last_tab_entry;
|
|
|
11630 |
mask_idx[b] = k;
|
|
|
11631 |
} else {
|
|
|
11632 |
mask_idx[b] = 0;
|
|
|
11633 |
}
|
|
|
11634 |
}
|
|
|
11635 |
|
|
|
11636 |
a = avg[b - 1] + avg[b];
|
|
|
11637 |
if (a > 0.0) {
|
|
|
11638 |
var m = max[b - 1];
|
|
|
11639 |
if (m < max[b])
|
|
|
11640 |
m = max[b];
|
|
|
11641 |
a = 20.0 * (m * 2.0 - a)
|
|
|
11642 |
/ (a * (gfc.numlines_l[b - 1] + gfc.numlines_l[b] - 1));
|
|
|
11643 |
var k = 0 | a;
|
|
|
11644 |
if (k > last_tab_entry)
|
|
|
11645 |
k = last_tab_entry;
|
|
|
11646 |
mask_idx[b] = k;
|
|
|
11647 |
} else {
|
|
|
11648 |
mask_idx[b] = 0;
|
|
|
11649 |
}
|
|
|
11650 |
}
|
|
|
11651 |
|
|
|
11652 |
var fircoef = [
|
|
|
11653 |
-8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2,
|
|
|
11654 |
-3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2,
|
|
|
11655 |
-5.52212e-17 * 2, -0.313819 * 2
|
|
|
11656 |
];
|
|
|
11657 |
|
|
|
11658 |
this.L3psycho_anal_ns = function (gfp, buffer, bufPos, gr_out, masking_ratio, masking_MS_ratio, percep_entropy, percep_MS_entropy, energy, blocktype_d) {
|
|
|
11659 |
/*
|
|
|
11660 |
* to get a good cache performance, one has to think about the sequence,
|
|
|
11661 |
* in which the variables are used.
|
|
|
11662 |
*/
|
|
|
11663 |
var gfc = gfp.internal_flags;
|
|
|
11664 |
|
|
|
11665 |
/* fft and energy calculation */
|
|
|
11666 |
var wsamp_L = new_float_n([2, Encoder.BLKSIZE]);
|
|
|
11667 |
var wsamp_S = new_float_n([2, 3, Encoder.BLKSIZE_s]);
|
|
|
11668 |
|
|
|
11669 |
/* convolution */
|
|
|
11670 |
var eb_l = new_float(Encoder.CBANDS + 1);
|
|
|
11671 |
var eb_s = new_float(Encoder.CBANDS + 1);
|
|
|
11672 |
var thr = new_float(Encoder.CBANDS + 2);
|
|
|
11673 |
|
|
|
11674 |
/* block type */
|
|
|
11675 |
var blocktype = new_int(2), uselongblock = new_int(2);
|
|
|
11676 |
|
|
|
11677 |
/* usual variables like loop indices, etc.. */
|
|
|
11678 |
var numchn, chn;
|
|
|
11679 |
var b, i, j, k;
|
|
|
11680 |
var sb, sblock;
|
|
|
11681 |
|
|
|
11682 |
/* variables used for --nspsytune */
|
|
|
11683 |
var ns_hpfsmpl = new_float_n([2, 576]);
|
|
|
11684 |
var pcfact;
|
|
|
11685 |
var mask_idx_l = new_int(Encoder.CBANDS + 2), mask_idx_s = new_int(Encoder.CBANDS + 2);
|
|
|
11686 |
|
|
|
11687 |
Arrays.fill(mask_idx_s, 0);
|
|
|
11688 |
|
|
|
11689 |
numchn = gfc.channels_out;
|
|
|
11690 |
/* chn=2 and 3 = Mid and Side channels */
|
|
|
11691 |
if (gfp.mode == MPEGMode.JOINT_STEREO)
|
|
|
11692 |
numchn = 4;
|
|
|
11693 |
|
|
|
11694 |
if (gfp.VBR == VbrMode.vbr_off)
|
|
|
11695 |
pcfact = gfc.ResvMax == 0 ? 0 : ( gfc.ResvSize)
|
|
|
11696 |
/ gfc.ResvMax * 0.5;
|
|
|
11697 |
else if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh
|
|
|
11698 |
|| gfp.VBR == VbrMode.vbr_mt) {
|
|
|
11699 |
pcfact = 0.6;
|
|
|
11700 |
} else
|
|
|
11701 |
pcfact = 1.0;
|
|
|
11702 |
|
|
|
11703 |
/**********************************************************************
|
|
|
11704 |
* Apply HPF of fs/4 to the input signal. This is used for attack
|
|
|
11705 |
* detection / handling.
|
|
|
11706 |
**********************************************************************/
|
|
|
11707 |
/* Don't copy the input buffer into a temporary buffer */
|
|
|
11708 |
/* unroll the loop 2 times */
|
|
|
11709 |
for (chn = 0; chn < gfc.channels_out; chn++) {
|
|
|
11710 |
/* apply high pass filter of fs/4 */
|
|
|
11711 |
var firbuf = buffer[chn];
|
|
|
11712 |
var firbufPos = bufPos + 576 - 350 - NSFIRLEN + 192;
|
|
|
11713 |
for (i = 0; i < 576; i++) {
|
|
|
11714 |
var sum1, sum2;
|
|
|
11715 |
sum1 = firbuf[firbufPos + i + 10];
|
|
|
11716 |
sum2 = 0.0;
|
|
|
11717 |
for (j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) {
|
|
|
11718 |
sum1 += fircoef[j]
|
|
|
11719 |
* (firbuf[firbufPos + i + j] + firbuf[firbufPos + i
|
|
|
11720 |
+ NSFIRLEN - j]);
|
|
|
11721 |
sum2 += fircoef[j + 1]
|
|
|
11722 |
* (firbuf[firbufPos + i + j + 1] + firbuf[firbufPos
|
|
|
11723 |
+ i + NSFIRLEN - j - 1]);
|
|
|
11724 |
}
|
|
|
11725 |
ns_hpfsmpl[chn][i] = sum1 + sum2;
|
|
|
11726 |
}
|
|
|
11727 |
masking_ratio[gr_out][chn].en.assign(gfc.en[chn]);
|
|
|
11728 |
masking_ratio[gr_out][chn].thm.assign(gfc.thm[chn]);
|
|
|
11729 |
if (numchn > 2) {
|
|
|
11730 |
/* MS maskings */
|
|
|
11731 |
/* percep_MS_entropy [chn-2] = gfc . pe [chn]; */
|
|
|
11732 |
masking_MS_ratio[gr_out][chn].en.assign(gfc.en[chn + 2]);
|
|
|
11733 |
masking_MS_ratio[gr_out][chn].thm.assign(gfc.thm[chn + 2]);
|
|
|
11734 |
}
|
|
|
11735 |
}
|
|
|
11736 |
|
|
|
11737 |
for (chn = 0; chn < numchn; chn++) {
|
|
|
11738 |
var wsamp_l;
|
|
|
11739 |
var wsamp_s;
|
|
|
11740 |
var en_subshort = new_float(12);
|
|
|
11741 |
var en_short = [0, 0, 0, 0];
|
|
|
11742 |
var attack_intensity = new_float(12);
|
|
|
11743 |
var ns_uselongblock = 1;
|
|
|
11744 |
var attackThreshold;
|
|
|
11745 |
var max = new_float(Encoder.CBANDS), avg = new_float(Encoder.CBANDS);
|
|
|
11746 |
var ns_attacks = [0, 0, 0, 0];
|
|
|
11747 |
var fftenergy = new_float(Encoder.HBLKSIZE);
|
|
|
11748 |
var fftenergy_s = new_float_n([3, Encoder.HBLKSIZE_s]);
|
|
|
11749 |
|
|
|
11750 |
/*
|
|
|
11751 |
* rh 20040301: the following loops do access one off the limits so
|
|
|
11752 |
* I increase the array dimensions by one and initialize the
|
|
|
11753 |
* accessed values to zero
|
|
|
11754 |
*/
|
|
|
11755 |
|
|
|
11756 |
/***************************************************************
|
|
|
11757 |
* determine the block type (window type)
|
|
|
11758 |
***************************************************************/
|
|
|
11759 |
/* calculate energies of each sub-shortblocks */
|
|
|
11760 |
for (i = 0; i < 3; i++) {
|
|
|
11761 |
en_subshort[i] = gfc.nsPsy.last_en_subshort[chn][i + 6];
|
|
|
11762 |
attack_intensity[i] = en_subshort[i]
|
|
|
11763 |
/ gfc.nsPsy.last_en_subshort[chn][i + 4];
|
|
|
11764 |
en_short[0] += en_subshort[i];
|
|
|
11765 |
}
|
|
|
11766 |
|
|
|
11767 |
if (chn == 2) {
|
|
|
11768 |
for (i = 0; i < 576; i++) {
|
|
|
11769 |
var l, r;
|
|
|
11770 |
l = ns_hpfsmpl[0][i];
|
|
|
11771 |
r = ns_hpfsmpl[1][i];
|
|
|
11772 |
ns_hpfsmpl[0][i] = l + r;
|
|
|
11773 |
ns_hpfsmpl[1][i] = l - r;
|
|
|
11774 |
}
|
|
|
11775 |
}
|
|
|
11776 |
{
|
|
|
11777 |
var pf = ns_hpfsmpl[chn & 1];
|
|
|
11778 |
var pfPos = 0;
|
|
|
11779 |
for (i = 0; i < 9; i++) {
|
|
|
11780 |
var pfe = pfPos + 576 / 9;
|
|
|
11781 |
var p = 1.;
|
|
|
11782 |
for (; pfPos < pfe; pfPos++)
|
|
|
11783 |
if (p < Math.abs(pf[pfPos]))
|
|
|
11784 |
p = Math.abs(pf[pfPos]);
|
|
|
11785 |
|
|
|
11786 |
gfc.nsPsy.last_en_subshort[chn][i] = en_subshort[i + 3] = p;
|
|
|
11787 |
en_short[1 + i / 3] += p;
|
|
|
11788 |
if (p > en_subshort[i + 3 - 2]) {
|
|
|
11789 |
p = p / en_subshort[i + 3 - 2];
|
|
|
11790 |
} else if (en_subshort[i + 3 - 2] > p * 10.0) {
|
|
|
11791 |
p = en_subshort[i + 3 - 2] / (p * 10.0);
|
|
|
11792 |
} else
|
|
|
11793 |
p = 0.0;
|
|
|
11794 |
attack_intensity[i + 3] = p;
|
|
|
11795 |
}
|
|
|
11796 |
}
|
|
|
11797 |
|
|
|
11798 |
if (gfp.analysis) {
|
|
|
11799 |
var x = attack_intensity[0];
|
|
|
11800 |
for (i = 1; i < 12; i++)
|
|
|
11801 |
if (x < attack_intensity[i])
|
|
|
11802 |
x = attack_intensity[i];
|
|
|
11803 |
gfc.pinfo.ers[gr_out][chn] = gfc.pinfo.ers_save[chn];
|
|
|
11804 |
gfc.pinfo.ers_save[chn] = x;
|
|
|
11805 |
}
|
|
|
11806 |
|
|
|
11807 |
/* compare energies between sub-shortblocks */
|
|
|
11808 |
attackThreshold = (chn == 3) ? gfc.nsPsy.attackthre_s
|
|
|
11809 |
: gfc.nsPsy.attackthre;
|
|
|
11810 |
for (i = 0; i < 12; i++)
|
|
|
11811 |
if (0 == ns_attacks[i / 3]
|
|
|
11812 |
&& attack_intensity[i] > attackThreshold)
|
|
|
11813 |
ns_attacks[i / 3] = (i % 3) + 1;
|
|
|
11814 |
|
|
|
11815 |
/*
|
|
|
11816 |
* should have energy change between short blocks, in order to avoid
|
|
|
11817 |
* periodic signals
|
|
|
11818 |
*/
|
|
|
11819 |
for (i = 1; i < 4; i++) {
|
|
|
11820 |
var ratio;
|
|
|
11821 |
if (en_short[i - 1] > en_short[i]) {
|
|
|
11822 |
ratio = en_short[i - 1] / en_short[i];
|
|
|
11823 |
} else {
|
|
|
11824 |
ratio = en_short[i] / en_short[i - 1];
|
|
|
11825 |
}
|
|
|
11826 |
if (ratio < 1.7) {
|
|
|
11827 |
ns_attacks[i] = 0;
|
|
|
11828 |
if (i == 1)
|
|
|
11829 |
ns_attacks[0] = 0;
|
|
|
11830 |
}
|
|
|
11831 |
}
|
|
|
11832 |
|
|
|
11833 |
if (ns_attacks[0] != 0 && gfc.nsPsy.lastAttacks[chn] != 0)
|
|
|
11834 |
ns_attacks[0] = 0;
|
|
|
11835 |
|
|
|
11836 |
if (gfc.nsPsy.lastAttacks[chn] == 3
|
|
|
11837 |
|| (ns_attacks[0] + ns_attacks[1] + ns_attacks[2] + ns_attacks[3]) != 0) {
|
|
|
11838 |
ns_uselongblock = 0;
|
|
|
11839 |
|
|
|
11840 |
if (ns_attacks[1] != 0 && ns_attacks[0] != 0)
|
|
|
11841 |
ns_attacks[1] = 0;
|
|
|
11842 |
if (ns_attacks[2] != 0 && ns_attacks[1] != 0)
|
|
|
11843 |
ns_attacks[2] = 0;
|
|
|
11844 |
if (ns_attacks[3] != 0 && ns_attacks[2] != 0)
|
|
|
11845 |
ns_attacks[3] = 0;
|
|
|
11846 |
}
|
|
|
11847 |
|
|
|
11848 |
if (chn < 2) {
|
|
|
11849 |
uselongblock[chn] = ns_uselongblock;
|
|
|
11850 |
} else {
|
|
|
11851 |
if (ns_uselongblock == 0) {
|
|
|
11852 |
uselongblock[0] = uselongblock[1] = 0;
|
|
|
11853 |
}
|
|
|
11854 |
}
|
|
|
11855 |
|
|
|
11856 |
/*
|
|
|
11857 |
* there is a one granule delay. Copy maskings computed last call
|
|
|
11858 |
* into masking_ratio to return to calling program.
|
|
|
11859 |
*/
|
|
|
11860 |
energy[chn] = gfc.tot_ener[chn];
|
|
|
11861 |
|
|
|
11862 |
/*********************************************************************
|
|
|
11863 |
* compute FFTs
|
|
|
11864 |
*********************************************************************/
|
|
|
11865 |
wsamp_s = wsamp_S;
|
|
|
11866 |
wsamp_l = wsamp_L;
|
|
|
11867 |
compute_ffts(gfp, fftenergy, fftenergy_s, wsamp_l, (chn & 1),
|
|
|
11868 |
wsamp_s, (chn & 1), gr_out, chn, buffer, bufPos);
|
|
|
11869 |
|
|
|
11870 |
/*********************************************************************
|
|
|
11871 |
* Calculate the energy and the tonality of each partition.
|
|
|
11872 |
*********************************************************************/
|
|
|
11873 |
calc_energy(gfc, fftenergy, eb_l, max, avg);
|
|
|
11874 |
calc_mask_index_l(gfc, max, avg, mask_idx_l);
|
|
|
11875 |
/* compute masking thresholds for short blocks */
|
|
|
11876 |
for (sblock = 0; sblock < 3; sblock++) {
|
|
|
11877 |
var enn, thmm;
|
|
|
11878 |
compute_masking_s(gfp, fftenergy_s, eb_s, thr, chn, sblock);
|
|
|
11879 |
convert_partition2scalefac_s(gfc, eb_s, thr, chn, sblock);
|
|
|
11880 |
/**** short block pre-echo control ****/
|
|
|
11881 |
for (sb = 0; sb < Encoder.SBMAX_s; sb++) {
|
|
|
11882 |
thmm = gfc.thm[chn].s[sb][sblock];
|
|
|
11883 |
|
|
|
11884 |
thmm *= NS_PREECHO_ATT0;
|
|
|
11885 |
if (ns_attacks[sblock] >= 2 || ns_attacks[sblock + 1] == 1) {
|
|
|
11886 |
var idx = (sblock != 0) ? sblock - 1 : 2;
|
|
|
11887 |
var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm,
|
|
|
11888 |
NS_PREECHO_ATT1 * pcfact);
|
|
|
11889 |
thmm = Math.min(thmm, p);
|
|
|
11890 |
}
|
|
|
11891 |
|
|
|
11892 |
if (ns_attacks[sblock] == 1) {
|
|
|
11893 |
var idx = (sblock != 0) ? sblock - 1 : 2;
|
|
|
11894 |
var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm,
|
|
|
11895 |
NS_PREECHO_ATT2 * pcfact);
|
|
|
11896 |
thmm = Math.min(thmm, p);
|
|
|
11897 |
} else if ((sblock != 0 && ns_attacks[sblock - 1] == 3)
|
|
|
11898 |
|| (sblock == 0 && gfc.nsPsy.lastAttacks[chn] == 3)) {
|
|
|
11899 |
var idx = (sblock != 2) ? sblock + 1 : 0;
|
|
|
11900 |
var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm,
|
|
|
11901 |
NS_PREECHO_ATT2 * pcfact);
|
|
|
11902 |
thmm = Math.min(thmm, p);
|
|
|
11903 |
}
|
|
|
11904 |
|
|
|
11905 |
/* pulse like signal detection for fatboy.wav and so on */
|
|
|
11906 |
enn = en_subshort[sblock * 3 + 3]
|
|
|
11907 |
+ en_subshort[sblock * 3 + 4]
|
|
|
11908 |
+ en_subshort[sblock * 3 + 5];
|
|
|
11909 |
if (en_subshort[sblock * 3 + 5] * 6 < enn) {
|
|
|
11910 |
thmm *= 0.5;
|
|
|
11911 |
if (en_subshort[sblock * 3 + 4] * 6 < enn)
|
|
|
11912 |
thmm *= 0.5;
|
|
|
11913 |
}
|
|
|
11914 |
|
|
|
11915 |
gfc.thm[chn].s[sb][sblock] = thmm;
|
|
|
11916 |
}
|
|
|
11917 |
}
|
|
|
11918 |
gfc.nsPsy.lastAttacks[chn] = ns_attacks[2];
|
|
|
11919 |
|
|
|
11920 |
/*********************************************************************
|
|
|
11921 |
* convolve the partitioned energy and unpredictability with the
|
|
|
11922 |
* spreading function, s3_l[b][k]
|
|
|
11923 |
********************************************************************/
|
|
|
11924 |
k = 0;
|
|
|
11925 |
{
|
|
|
11926 |
for (b = 0; b < gfc.npart_l; b++) {
|
|
|
11927 |
/*
|
|
|
11928 |
* convolve the partitioned energy with the spreading
|
|
|
11929 |
* function
|
|
|
11930 |
*/
|
|
|
11931 |
var kk = gfc.s3ind[b][0];
|
|
|
11932 |
var eb2 = eb_l[kk] * tab[mask_idx_l[kk]];
|
|
|
11933 |
var ecb = gfc.s3_ll[k++] * eb2;
|
|
|
11934 |
while (++kk <= gfc.s3ind[b][1]) {
|
|
|
11935 |
eb2 = eb_l[kk] * tab[mask_idx_l[kk]];
|
|
|
11936 |
ecb = mask_add(ecb, gfc.s3_ll[k++] * eb2, kk, kk - b,
|
|
|
11937 |
gfc, 0);
|
|
|
11938 |
}
|
|
|
11939 |
ecb *= 0.158489319246111;
|
|
|
11940 |
/* pow(10,-0.8) */
|
|
|
11941 |
|
|
|
11942 |
/**** long block pre-echo control ****/
|
|
|
11943 |
/**
|
|
|
11944 |
* <PRE>
|
|
|
11945 |
* dont use long block pre-echo control if previous granule was
|
|
|
11946 |
* a short block. This is to avoid the situation:
|
|
|
11947 |
* frame0: quiet (very low masking)
|
|
|
11948 |
* frame1: surge (triggers short blocks)
|
|
|
11949 |
* frame2: regular frame. looks like pre-echo when compared to
|
|
|
11950 |
* frame0, but all pre-echo was in frame1.
|
|
|
11951 |
* </PRE>
|
|
|
11952 |
*/
|
|
|
11953 |
/*
|
|
|
11954 |
* chn=0,1 L and R channels
|
|
|
11955 |
*
|
|
|
11956 |
* chn=2,3 S and M channels.
|
|
|
11957 |
*/
|
|
|
11958 |
|
|
|
11959 |
if (gfc.blocktype_old[chn & 1] == Encoder.SHORT_TYPE)
|
|
|
11960 |
thr[b] = ecb;
|
|
|
11961 |
else
|
|
|
11962 |
thr[b] = NS_INTERP(
|
|
|
11963 |
Math.min(ecb, Math.min(rpelev
|
|
|
11964 |
* gfc.nb_1[chn][b], rpelev2
|
|
|
11965 |
* gfc.nb_2[chn][b])), ecb, pcfact);
|
|
|
11966 |
|
|
|
11967 |
gfc.nb_2[chn][b] = gfc.nb_1[chn][b];
|
|
|
11968 |
gfc.nb_1[chn][b] = ecb;
|
|
|
11969 |
}
|
|
|
11970 |
}
|
|
|
11971 |
for (; b <= Encoder.CBANDS; ++b) {
|
|
|
11972 |
eb_l[b] = 0;
|
|
|
11973 |
thr[b] = 0;
|
|
|
11974 |
}
|
|
|
11975 |
/* compute masking thresholds for long blocks */
|
|
|
11976 |
convert_partition2scalefac_l(gfc, eb_l, thr, chn);
|
|
|
11977 |
}
|
|
|
11978 |
/* end loop over chn */
|
|
|
11979 |
|
|
|
11980 |
if (gfp.mode == MPEGMode.STEREO || gfp.mode == MPEGMode.JOINT_STEREO) {
|
|
|
11981 |
if (gfp.interChRatio > 0.0) {
|
|
|
11982 |
calc_interchannel_masking(gfp, gfp.interChRatio);
|
|
|
11983 |
}
|
|
|
11984 |
}
|
|
|
11985 |
|
|
|
11986 |
if (gfp.mode == MPEGMode.JOINT_STEREO) {
|
|
|
11987 |
var msfix;
|
|
|
11988 |
msfix1(gfc);
|
|
|
11989 |
msfix = gfp.msfix;
|
|
|
11990 |
if (Math.abs(msfix) > 0.0)
|
|
|
11991 |
ns_msfix(gfc, msfix, gfp.ATHlower * gfc.ATH.adjust);
|
|
|
11992 |
}
|
|
|
11993 |
|
|
|
11994 |
/***************************************************************
|
|
|
11995 |
* determine final block type
|
|
|
11996 |
***************************************************************/
|
|
|
11997 |
block_type_set(gfp, uselongblock, blocktype_d, blocktype);
|
|
|
11998 |
|
|
|
11999 |
/*********************************************************************
|
|
|
12000 |
* compute the value of PE to return ... no delay and advance
|
|
|
12001 |
*********************************************************************/
|
|
|
12002 |
for (chn = 0; chn < numchn; chn++) {
|
|
|
12003 |
var ppe;
|
|
|
12004 |
var ppePos = 0;
|
|
|
12005 |
var type;
|
|
|
12006 |
var mr;
|
|
|
12007 |
|
|
|
12008 |
if (chn > 1) {
|
|
|
12009 |
ppe = percep_MS_entropy;
|
|
|
12010 |
ppePos = -2;
|
|
|
12011 |
type = Encoder.NORM_TYPE;
|
|
|
12012 |
if (blocktype_d[0] == Encoder.SHORT_TYPE
|
|
|
12013 |
|| blocktype_d[1] == Encoder.SHORT_TYPE)
|
|
|
12014 |
type = Encoder.SHORT_TYPE;
|
|
|
12015 |
mr = masking_MS_ratio[gr_out][chn - 2];
|
|
|
12016 |
} else {
|
|
|
12017 |
ppe = percep_entropy;
|
|
|
12018 |
ppePos = 0;
|
|
|
12019 |
type = blocktype_d[chn];
|
|
|
12020 |
mr = masking_ratio[gr_out][chn];
|
|
|
12021 |
}
|
|
|
12022 |
|
|
|
12023 |
if (type == Encoder.SHORT_TYPE)
|
|
|
12024 |
ppe[ppePos + chn] = pecalc_s(mr, gfc.masking_lower);
|
|
|
12025 |
else
|
|
|
12026 |
ppe[ppePos + chn] = pecalc_l(mr, gfc.masking_lower);
|
|
|
12027 |
|
|
|
12028 |
if (gfp.analysis)
|
|
|
12029 |
gfc.pinfo.pe[gr_out][chn] = ppe[ppePos + chn];
|
|
|
12030 |
|
|
|
12031 |
}
|
|
|
12032 |
return 0;
|
|
|
12033 |
}
|
|
|
12034 |
|
|
|
12035 |
function vbrpsy_compute_fft_l(gfp, buffer, bufPos, chn, gr_out, fftenergy, wsamp_l, wsamp_lPos) {
|
|
|
12036 |
var gfc = gfp.internal_flags;
|
|
|
12037 |
if (chn < 2) {
|
|
|
12038 |
fft.fft_long(gfc, wsamp_l[wsamp_lPos], chn, buffer, bufPos);
|
|
|
12039 |
} else if (chn == 2) {
|
|
|
12040 |
/* FFT data for mid and side channel is derived from L & R */
|
|
|
12041 |
for (var j = Encoder.BLKSIZE - 1; j >= 0; --j) {
|
|
|
12042 |
var l = wsamp_l[wsamp_lPos + 0][j];
|
|
|
12043 |
var r = wsamp_l[wsamp_lPos + 1][j];
|
|
|
12044 |
wsamp_l[wsamp_lPos + 0][j] = (l + r) * Util.SQRT2 * 0.5;
|
|
|
12045 |
wsamp_l[wsamp_lPos + 1][j] = (l - r) * Util.SQRT2 * 0.5;
|
|
|
12046 |
}
|
|
|
12047 |
}
|
|
|
12048 |
|
|
|
12049 |
/*********************************************************************
|
|
|
12050 |
* compute energies
|
|
|
12051 |
*********************************************************************/
|
|
|
12052 |
fftenergy[0] = NON_LINEAR_SCALE_ENERGY(wsamp_l[wsamp_lPos + 0][0]);
|
|
|
12053 |
fftenergy[0] *= fftenergy[0];
|
|
|
12054 |
|
|
|
12055 |
for (var j = Encoder.BLKSIZE / 2 - 1; j >= 0; --j) {
|
|
|
12056 |
var re = wsamp_l[wsamp_lPos + 0][Encoder.BLKSIZE / 2 - j];
|
|
|
12057 |
var im = wsamp_l[wsamp_lPos + 0][Encoder.BLKSIZE / 2 + j];
|
|
|
12058 |
fftenergy[Encoder.BLKSIZE / 2 - j] = NON_LINEAR_SCALE_ENERGY((re
|
|
|
12059 |
* re + im * im) * 0.5);
|
|
|
12060 |
}
|
|
|
12061 |
/* total energy */
|
|
|
12062 |
{
|
|
|
12063 |
var totalenergy = 0.0;
|
|
|
12064 |
for (var j = 11; j < Encoder.HBLKSIZE; j++)
|
|
|
12065 |
totalenergy += fftenergy[j];
|
|
|
12066 |
|
|
|
12067 |
gfc.tot_ener[chn] = totalenergy;
|
|
|
12068 |
}
|
|
|
12069 |
|
|
|
12070 |
if (gfp.analysis) {
|
|
|
12071 |
for (var j = 0; j < Encoder.HBLKSIZE; j++) {
|
|
|
12072 |
gfc.pinfo.energy[gr_out][chn][j] = gfc.pinfo.energy_save[chn][j];
|
|
|
12073 |
gfc.pinfo.energy_save[chn][j] = fftenergy[j];
|
|
|
12074 |
}
|
|
|
12075 |
gfc.pinfo.pe[gr_out][chn] = gfc.pe[chn];
|
|
|
12076 |
}
|
|
|
12077 |
}
|
|
|
12078 |
|
|
|
12079 |
function vbrpsy_compute_fft_s(gfp, buffer, bufPos, chn, sblock, fftenergy_s, wsamp_s, wsamp_sPos) {
|
|
|
12080 |
var gfc = gfp.internal_flags;
|
|
|
12081 |
|
|
|
12082 |
if (sblock == 0 && chn < 2) {
|
|
|
12083 |
fft.fft_short(gfc, wsamp_s[wsamp_sPos], chn, buffer, bufPos);
|
|
|
12084 |
}
|
|
|
12085 |
if (chn == 2) {
|
|
|
12086 |
/* FFT data for mid and side channel is derived from L & R */
|
|
|
12087 |
for (var j = Encoder.BLKSIZE_s - 1; j >= 0; --j) {
|
|
|
12088 |
var l = wsamp_s[wsamp_sPos + 0][sblock][j];
|
|
|
12089 |
var r = wsamp_s[wsamp_sPos + 1][sblock][j];
|
|
|
12090 |
wsamp_s[wsamp_sPos + 0][sblock][j] = (l + r) * Util.SQRT2 * 0.5;
|
|
|
12091 |
wsamp_s[wsamp_sPos + 1][sblock][j] = (l - r) * Util.SQRT2 * 0.5;
|
|
|
12092 |
}
|
|
|
12093 |
}
|
|
|
12094 |
|
|
|
12095 |
/*********************************************************************
|
|
|
12096 |
* compute energies
|
|
|
12097 |
*********************************************************************/
|
|
|
12098 |
fftenergy_s[sblock][0] = wsamp_s[wsamp_sPos + 0][sblock][0];
|
|
|
12099 |
fftenergy_s[sblock][0] *= fftenergy_s[sblock][0];
|
|
|
12100 |
for (var j = Encoder.BLKSIZE_s / 2 - 1; j >= 0; --j) {
|
|
|
12101 |
var re = wsamp_s[wsamp_sPos + 0][sblock][Encoder.BLKSIZE_s / 2 - j];
|
|
|
12102 |
var im = wsamp_s[wsamp_sPos + 0][sblock][Encoder.BLKSIZE_s / 2 + j];
|
|
|
12103 |
fftenergy_s[sblock][Encoder.BLKSIZE_s / 2 - j] = NON_LINEAR_SCALE_ENERGY((re
|
|
|
12104 |
* re + im * im) * 0.5);
|
|
|
12105 |
}
|
|
|
12106 |
}
|
|
|
12107 |
|
|
|
12108 |
/**
|
|
|
12109 |
* compute loudness approximation (used for ATH auto-level adjustment)
|
|
|
12110 |
*/
|
|
|
12111 |
function vbrpsy_compute_loudness_approximation_l(gfp, gr_out, chn, fftenergy) {
|
|
|
12112 |
var gfc = gfp.internal_flags;
|
|
|
12113 |
if (gfp.athaa_loudapprox == 2 && chn < 2) {
|
|
|
12114 |
// no loudness for mid/side ch
|
|
|
12115 |
gfc.loudness_sq[gr_out][chn] = gfc.loudness_sq_save[chn];
|
|
|
12116 |
gfc.loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc);
|
|
|
12117 |
}
|
|
|
12118 |
}
|
|
|
12119 |
|
|
|
12120 |
var fircoef_ = [-8.65163e-18 * 2,
|
|
|
12121 |
-0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2,
|
|
|
12122 |
-3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2,
|
|
|
12123 |
0.0931738 * 2, -5.52212e-17 * 2, -0.313819 * 2];
|
|
|
12124 |
|
|
|
12125 |
/**
|
|
|
12126 |
* Apply HPF of fs/4 to the input signal. This is used for attack detection
|
|
|
12127 |
* / handling.
|
|
|
12128 |
*/
|
|
|
12129 |
function vbrpsy_attack_detection(gfp, buffer, bufPos, gr_out, masking_ratio, masking_MS_ratio, energy, sub_short_factor, ns_attacks, uselongblock) {
|
|
|
12130 |
var ns_hpfsmpl = new_float_n([2, 576]);
|
|
|
12131 |
var gfc = gfp.internal_flags;
|
|
|
12132 |
var n_chn_out = gfc.channels_out;
|
|
|
12133 |
/* chn=2 and 3 = Mid and Side channels */
|
|
|
12134 |
var n_chn_psy = (gfp.mode == MPEGMode.JOINT_STEREO) ? 4 : n_chn_out;
|
|
|
12135 |
/* Don't copy the input buffer into a temporary buffer */
|
|
|
12136 |
/* unroll the loop 2 times */
|
|
|
12137 |
for (var chn = 0; chn < n_chn_out; chn++) {
|
|
|
12138 |
/* apply high pass filter of fs/4 */
|
|
|
12139 |
firbuf = buffer[chn];
|
|
|
12140 |
var firbufPos = bufPos + 576 - 350 - NSFIRLEN + 192;
|
|
|
12141 |
for (var i = 0; i < 576; i++) {
|
|
|
12142 |
var sum1, sum2;
|
|
|
12143 |
sum1 = firbuf[firbufPos + i + 10];
|
|
|
12144 |
sum2 = 0.0;
|
|
|
12145 |
for (var j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) {
|
|
|
12146 |
sum1 += fircoef_[j]
|
|
|
12147 |
* (firbuf[firbufPos + i + j] + firbuf[firbufPos + i
|
|
|
12148 |
+ NSFIRLEN - j]);
|
|
|
12149 |
sum2 += fircoef_[j + 1]
|
|
|
12150 |
* (firbuf[firbufPos + i + j + 1] + firbuf[firbufPos
|
|
|
12151 |
+ i + NSFIRLEN - j - 1]);
|
|
|
12152 |
}
|
|
|
12153 |
ns_hpfsmpl[chn][i] = sum1 + sum2;
|
|
|
12154 |
}
|
|
|
12155 |
masking_ratio[gr_out][chn].en.assign(gfc.en[chn]);
|
|
|
12156 |
masking_ratio[gr_out][chn].thm.assign(gfc.thm[chn]);
|
|
|
12157 |
if (n_chn_psy > 2) {
|
|
|
12158 |
/* MS maskings */
|
|
|
12159 |
/* percep_MS_entropy [chn-2] = gfc . pe [chn]; */
|
|
|
12160 |
masking_MS_ratio[gr_out][chn].en.assign(gfc.en[chn + 2]);
|
|
|
12161 |
masking_MS_ratio[gr_out][chn].thm.assign(gfc.thm[chn + 2]);
|
|
|
12162 |
}
|
|
|
12163 |
}
|
|
|
12164 |
for (var chn = 0; chn < n_chn_psy; chn++) {
|
|
|
12165 |
var attack_intensity = new_float(12);
|
|
|
12166 |
var en_subshort = new_float(12);
|
|
|
12167 |
var en_short = [0, 0, 0, 0];
|
|
|
12168 |
var pf = ns_hpfsmpl[chn & 1];
|
|
|
12169 |
var pfPos = 0;
|
|
|
12170 |
var attackThreshold = (chn == 3) ? gfc.nsPsy.attackthre_s
|
|
|
12171 |
: gfc.nsPsy.attackthre;
|
|
|
12172 |
var ns_uselongblock = 1;
|
|
|
12173 |
|
|
|
12174 |
if (chn == 2) {
|
|
|
12175 |
for (var i = 0, j = 576; j > 0; ++i, --j) {
|
|
|
12176 |
var l = ns_hpfsmpl[0][i];
|
|
|
12177 |
var r = ns_hpfsmpl[1][i];
|
|
|
12178 |
ns_hpfsmpl[0][i] = l + r;
|
|
|
12179 |
ns_hpfsmpl[1][i] = l - r;
|
|
|
12180 |
}
|
|
|
12181 |
}
|
|
|
12182 |
/***************************************************************
|
|
|
12183 |
* determine the block type (window type)
|
|
|
12184 |
***************************************************************/
|
|
|
12185 |
/* calculate energies of each sub-shortblocks */
|
|
|
12186 |
for (var i = 0; i < 3; i++) {
|
|
|
12187 |
en_subshort[i] = gfc.nsPsy.last_en_subshort[chn][i + 6];
|
|
|
12188 |
attack_intensity[i] = en_subshort[i]
|
|
|
12189 |
/ gfc.nsPsy.last_en_subshort[chn][i + 4];
|
|
|
12190 |
en_short[0] += en_subshort[i];
|
|
|
12191 |
}
|
|
|
12192 |
|
|
|
12193 |
for (var i = 0; i < 9; i++) {
|
|
|
12194 |
var pfe = pfPos + 576 / 9;
|
|
|
12195 |
var p = 1.;
|
|
|
12196 |
for (; pfPos < pfe; pfPos++)
|
|
|
12197 |
if (p < Math.abs(pf[pfPos]))
|
|
|
12198 |
p = Math.abs(pf[pfPos]);
|
|
|
12199 |
|
|
|
12200 |
gfc.nsPsy.last_en_subshort[chn][i] = en_subshort[i + 3] = p;
|
|
|
12201 |
en_short[1 + i / 3] += p;
|
|
|
12202 |
if (p > en_subshort[i + 3 - 2]) {
|
|
|
12203 |
p = p / en_subshort[i + 3 - 2];
|
|
|
12204 |
} else if (en_subshort[i + 3 - 2] > p * 10.0) {
|
|
|
12205 |
p = en_subshort[i + 3 - 2] / (p * 10.0);
|
|
|
12206 |
} else {
|
|
|
12207 |
p = 0.0;
|
|
|
12208 |
}
|
|
|
12209 |
attack_intensity[i + 3] = p;
|
|
|
12210 |
}
|
|
|
12211 |
/* pulse like signal detection for fatboy.wav and so on */
|
|
|
12212 |
for (var i = 0; i < 3; ++i) {
|
|
|
12213 |
var enn = en_subshort[i * 3 + 3]
|
|
|
12214 |
+ en_subshort[i * 3 + 4] + en_subshort[i * 3 + 5];
|
|
|
12215 |
var factor = 1.;
|
|
|
12216 |
if (en_subshort[i * 3 + 5] * 6 < enn) {
|
|
|
12217 |
factor *= 0.5;
|
|
|
12218 |
if (en_subshort[i * 3 + 4] * 6 < enn) {
|
|
|
12219 |
factor *= 0.5;
|
|
|
12220 |
}
|
|
|
12221 |
}
|
|
|
12222 |
sub_short_factor[chn][i] = factor;
|
|
|
12223 |
}
|
|
|
12224 |
|
|
|
12225 |
if (gfp.analysis) {
|
|
|
12226 |
var x = attack_intensity[0];
|
|
|
12227 |
for (var i = 1; i < 12; i++) {
|
|
|
12228 |
if (x < attack_intensity[i]) {
|
|
|
12229 |
x = attack_intensity[i];
|
|
|
12230 |
}
|
|
|
12231 |
}
|
|
|
12232 |
gfc.pinfo.ers[gr_out][chn] = gfc.pinfo.ers_save[chn];
|
|
|
12233 |
gfc.pinfo.ers_save[chn] = x;
|
|
|
12234 |
}
|
|
|
12235 |
|
|
|
12236 |
/* compare energies between sub-shortblocks */
|
|
|
12237 |
for (var i = 0; i < 12; i++) {
|
|
|
12238 |
if (0 == ns_attacks[chn][i / 3]
|
|
|
12239 |
&& attack_intensity[i] > attackThreshold) {
|
|
|
12240 |
ns_attacks[chn][i / 3] = (i % 3) + 1;
|
|
|
12241 |
}
|
|
|
12242 |
}
|
|
|
12243 |
|
|
|
12244 |
/*
|
|
|
12245 |
* should have energy change between short blocks, in order to avoid
|
|
|
12246 |
* periodic signals
|
|
|
12247 |
*/
|
|
|
12248 |
/* Good samples to show the effect are Trumpet test songs */
|
|
|
12249 |
/*
|
|
|
12250 |
* GB: tuned (1) to avoid too many short blocks for test sample
|
|
|
12251 |
* TRUMPET
|
|
|
12252 |
*/
|
|
|
12253 |
/*
|
|
|
12254 |
* RH: tuned (2) to let enough short blocks through for test sample
|
|
|
12255 |
* FSOL and SNAPS
|
|
|
12256 |
*/
|
|
|
12257 |
for (var i = 1; i < 4; i++) {
|
|
|
12258 |
var u = en_short[i - 1];
|
|
|
12259 |
var v = en_short[i];
|
|
|
12260 |
var m = Math.max(u, v);
|
|
|
12261 |
if (m < 40000) { /* (2) */
|
|
|
12262 |
if (u < 1.7 * v && v < 1.7 * u) { /* (1) */
|
|
|
12263 |
if (i == 1 && ns_attacks[chn][0] <= ns_attacks[chn][i]) {
|
|
|
12264 |
ns_attacks[chn][0] = 0;
|
|
|
12265 |
}
|
|
|
12266 |
ns_attacks[chn][i] = 0;
|
|
|
12267 |
}
|
|
|
12268 |
}
|
|
|
12269 |
}
|
|
|
12270 |
|
|
|
12271 |
if (ns_attacks[chn][0] <= gfc.nsPsy.lastAttacks[chn]) {
|
|
|
12272 |
ns_attacks[chn][0] = 0;
|
|
|
12273 |
}
|
|
|
12274 |
|
|
|
12275 |
if (gfc.nsPsy.lastAttacks[chn] == 3
|
|
|
12276 |
|| (ns_attacks[chn][0] + ns_attacks[chn][1]
|
|
|
12277 |
+ ns_attacks[chn][2] + ns_attacks[chn][3]) != 0) {
|
|
|
12278 |
ns_uselongblock = 0;
|
|
|
12279 |
|
|
|
12280 |
if (ns_attacks[chn][1] != 0 && ns_attacks[chn][0] != 0) {
|
|
|
12281 |
ns_attacks[chn][1] = 0;
|
|
|
12282 |
}
|
|
|
12283 |
if (ns_attacks[chn][2] != 0 && ns_attacks[chn][1] != 0) {
|
|
|
12284 |
ns_attacks[chn][2] = 0;
|
|
|
12285 |
}
|
|
|
12286 |
if (ns_attacks[chn][3] != 0 && ns_attacks[chn][2] != 0) {
|
|
|
12287 |
ns_attacks[chn][3] = 0;
|
|
|
12288 |
}
|
|
|
12289 |
}
|
|
|
12290 |
if (chn < 2) {
|
|
|
12291 |
uselongblock[chn] = ns_uselongblock;
|
|
|
12292 |
} else {
|
|
|
12293 |
if (ns_uselongblock == 0) {
|
|
|
12294 |
uselongblock[0] = uselongblock[1] = 0;
|
|
|
12295 |
}
|
|
|
12296 |
}
|
|
|
12297 |
|
|
|
12298 |
/*
|
|
|
12299 |
* there is a one granule delay. Copy maskings computed last call
|
|
|
12300 |
* into masking_ratio to return to calling program.
|
|
|
12301 |
*/
|
|
|
12302 |
energy[chn] = gfc.tot_ener[chn];
|
|
|
12303 |
}
|
|
|
12304 |
}
|
|
|
12305 |
|
|
|
12306 |
function vbrpsy_skip_masking_s(gfc, chn, sblock) {
|
|
|
12307 |
if (sblock == 0) {
|
|
|
12308 |
for (var b = 0; b < gfc.npart_s; b++) {
|
|
|
12309 |
gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b];
|
|
|
12310 |
gfc.nb_s1[chn][b] = 0;
|
|
|
12311 |
}
|
|
|
12312 |
}
|
|
|
12313 |
}
|
|
|
12314 |
|
|
|
12315 |
function vbrpsy_skip_masking_l(gfc, chn) {
|
|
|
12316 |
for (var b = 0; b < gfc.npart_l; b++) {
|
|
|
12317 |
gfc.nb_2[chn][b] = gfc.nb_1[chn][b];
|
|
|
12318 |
gfc.nb_1[chn][b] = 0;
|
|
|
12319 |
}
|
|
|
12320 |
}
|
|
|
12321 |
|
|
|
12322 |
function psyvbr_calc_mask_index_s(gfc, max, avg, mask_idx) {
|
|
|
12323 |
var last_tab_entry = tab.length - 1;
|
|
|
12324 |
var b = 0;
|
|
|
12325 |
var a = avg[b] + avg[b + 1];
|
|
|
12326 |
if (a > 0.0) {
|
|
|
12327 |
var m = max[b];
|
|
|
12328 |
if (m < max[b + 1])
|
|
|
12329 |
m = max[b + 1];
|
|
|
12330 |
a = 20.0 * (m * 2.0 - a)
|
|
|
12331 |
/ (a * (gfc.numlines_s[b] + gfc.numlines_s[b + 1] - 1));
|
|
|
12332 |
var k = 0 | a;
|
|
|
12333 |
if (k > last_tab_entry)
|
|
|
12334 |
k = last_tab_entry;
|
|
|
12335 |
mask_idx[b] = k;
|
|
|
12336 |
} else {
|
|
|
12337 |
mask_idx[b] = 0;
|
|
|
12338 |
}
|
|
|
12339 |
|
|
|
12340 |
for (b = 1; b < gfc.npart_s - 1; b++) {
|
|
|
12341 |
a = avg[b - 1] + avg[b] + avg[b + 1];
|
|
|
12342 |
if (a > 0.0) {
|
|
|
12343 |
var m = max[b - 1];
|
|
|
12344 |
if (m < max[b])
|
|
|
12345 |
m = max[b];
|
|
|
12346 |
if (m < max[b + 1])
|
|
|
12347 |
m = max[b + 1];
|
|
|
12348 |
a = 20.0
|
|
|
12349 |
* (m * 3.0 - a)
|
|
|
12350 |
/ (a * (gfc.numlines_s[b - 1] + gfc.numlines_s[b]
|
|
|
12351 |
+ gfc.numlines_s[b + 1] - 1));
|
|
|
12352 |
var k = 0 | a;
|
|
|
12353 |
if (k > last_tab_entry)
|
|
|
12354 |
k = last_tab_entry;
|
|
|
12355 |
mask_idx[b] = k;
|
|
|
12356 |
} else {
|
|
|
12357 |
mask_idx[b] = 0;
|
|
|
12358 |
}
|
|
|
12359 |
}
|
|
|
12360 |
|
|
|
12361 |
a = avg[b - 1] + avg[b];
|
|
|
12362 |
if (a > 0.0) {
|
|
|
12363 |
var m = max[b - 1];
|
|
|
12364 |
if (m < max[b])
|
|
|
12365 |
m = max[b];
|
|
|
12366 |
a = 20.0 * (m * 2.0 - a)
|
|
|
12367 |
/ (a * (gfc.numlines_s[b - 1] + gfc.numlines_s[b] - 1));
|
|
|
12368 |
var k = 0 | a;
|
|
|
12369 |
if (k > last_tab_entry)
|
|
|
12370 |
k = last_tab_entry;
|
|
|
12371 |
mask_idx[b] = k;
|
|
|
12372 |
} else {
|
|
|
12373 |
mask_idx[b] = 0;
|
|
|
12374 |
}
|
|
|
12375 |
}
|
|
|
12376 |
|
|
|
12377 |
function vbrpsy_compute_masking_s(gfp, fftenergy_s, eb, thr, chn, sblock) {
|
|
|
12378 |
var gfc = gfp.internal_flags;
|
|
|
12379 |
var max = new float[Encoder.CBANDS], avg = new_float(Encoder.CBANDS);
|
|
|
12380 |
var i, j, b;
|
|
|
12381 |
var mask_idx_s = new int[Encoder.CBANDS];
|
|
|
12382 |
|
|
|
12383 |
for (b = j = 0; b < gfc.npart_s; ++b) {
|
|
|
12384 |
var ebb = 0, m = 0;
|
|
|
12385 |
var n = gfc.numlines_s[b];
|
|
|
12386 |
for (i = 0; i < n; ++i, ++j) {
|
|
|
12387 |
var el = fftenergy_s[sblock][j];
|
|
|
12388 |
ebb += el;
|
|
|
12389 |
if (m < el)
|
|
|
12390 |
m = el;
|
|
|
12391 |
}
|
|
|
12392 |
eb[b] = ebb;
|
|
|
12393 |
max[b] = m;
|
|
|
12394 |
avg[b] = ebb / n;
|
|
|
12395 |
}
|
|
|
12396 |
for (; b < Encoder.CBANDS; ++b) {
|
|
|
12397 |
max[b] = 0;
|
|
|
12398 |
avg[b] = 0;
|
|
|
12399 |
}
|
|
|
12400 |
psyvbr_calc_mask_index_s(gfc, max, avg, mask_idx_s);
|
|
|
12401 |
for (j = b = 0; b < gfc.npart_s; b++) {
|
|
|
12402 |
var kk = gfc.s3ind_s[b][0];
|
|
|
12403 |
var last = gfc.s3ind_s[b][1];
|
|
|
12404 |
var dd, dd_n;
|
|
|
12405 |
var x, ecb, avg_mask;
|
|
|
12406 |
dd = mask_idx_s[kk];
|
|
|
12407 |
dd_n = 1;
|
|
|
12408 |
ecb = gfc.s3_ss[j] * eb[kk] * tab[mask_idx_s[kk]];
|
|
|
12409 |
++j;
|
|
|
12410 |
++kk;
|
|
|
12411 |
while (kk <= last) {
|
|
|
12412 |
dd += mask_idx_s[kk];
|
|
|
12413 |
dd_n += 1;
|
|
|
12414 |
x = gfc.s3_ss[j] * eb[kk] * tab[mask_idx_s[kk]];
|
|
|
12415 |
ecb = vbrpsy_mask_add(ecb, x, kk - b);
|
|
|
12416 |
++j;
|
|
|
12417 |
++kk;
|
|
|
12418 |
}
|
|
|
12419 |
dd = (1 + 2 * dd) / (2 * dd_n);
|
|
|
12420 |
avg_mask = tab[dd] * 0.5;
|
|
|
12421 |
ecb *= avg_mask;
|
|
|
12422 |
thr[b] = ecb;
|
|
|
12423 |
gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b];
|
|
|
12424 |
gfc.nb_s1[chn][b] = ecb;
|
|
|
12425 |
{
|
|
|
12426 |
/*
|
|
|
12427 |
* if THR exceeds EB, the quantization routines will take the
|
|
|
12428 |
* difference from other bands. in case of strong tonal samples
|
|
|
12429 |
* (tonaltest.wav) this leads to heavy distortions. that's why
|
|
|
12430 |
* we limit THR here.
|
|
|
12431 |
*/
|
|
|
12432 |
x = max[b];
|
|
|
12433 |
x *= gfc.minval_s[b];
|
|
|
12434 |
x *= avg_mask;
|
|
|
12435 |
if (thr[b] > x) {
|
|
|
12436 |
thr[b] = x;
|
|
|
12437 |
}
|
|
|
12438 |
}
|
|
|
12439 |
if (gfc.masking_lower > 1) {
|
|
|
12440 |
thr[b] *= gfc.masking_lower;
|
|
|
12441 |
}
|
|
|
12442 |
if (thr[b] > eb[b]) {
|
|
|
12443 |
thr[b] = eb[b];
|
|
|
12444 |
}
|
|
|
12445 |
if (gfc.masking_lower < 1) {
|
|
|
12446 |
thr[b] *= gfc.masking_lower;
|
|
|
12447 |
}
|
|
|
12448 |
|
|
|
12449 |
}
|
|
|
12450 |
for (; b < Encoder.CBANDS; ++b) {
|
|
|
12451 |
eb[b] = 0;
|
|
|
12452 |
thr[b] = 0;
|
|
|
12453 |
}
|
|
|
12454 |
}
|
|
|
12455 |
|
|
|
12456 |
function vbrpsy_compute_masking_l(gfc, fftenergy, eb_l, thr, chn) {
|
|
|
12457 |
var max = new_float(Encoder.CBANDS), avg = new_float(Encoder.CBANDS);
|
|
|
12458 |
var mask_idx_l = new_int(Encoder.CBANDS + 2);
|
|
|
12459 |
var b;
|
|
|
12460 |
|
|
|
12461 |
/*********************************************************************
|
|
|
12462 |
* Calculate the energy and the tonality of each partition.
|
|
|
12463 |
*********************************************************************/
|
|
|
12464 |
calc_energy(gfc, fftenergy, eb_l, max, avg);
|
|
|
12465 |
calc_mask_index_l(gfc, max, avg, mask_idx_l);
|
|
|
12466 |
|
|
|
12467 |
/*********************************************************************
|
|
|
12468 |
* convolve the partitioned energy and unpredictability with the
|
|
|
12469 |
* spreading function, s3_l[b][k]
|
|
|
12470 |
********************************************************************/
|
|
|
12471 |
var k = 0;
|
|
|
12472 |
for (b = 0; b < gfc.npart_l; b++) {
|
|
|
12473 |
var x, ecb, avg_mask, t;
|
|
|
12474 |
/* convolve the partitioned energy with the spreading function */
|
|
|
12475 |
var kk = gfc.s3ind[b][0];
|
|
|
12476 |
var last = gfc.s3ind[b][1];
|
|
|
12477 |
var dd = 0, dd_n = 0;
|
|
|
12478 |
dd = mask_idx_l[kk];
|
|
|
12479 |
dd_n += 1;
|
|
|
12480 |
ecb = gfc.s3_ll[k] * eb_l[kk] * tab[mask_idx_l[kk]];
|
|
|
12481 |
++k;
|
|
|
12482 |
++kk;
|
|
|
12483 |
while (kk <= last) {
|
|
|
12484 |
dd += mask_idx_l[kk];
|
|
|
12485 |
dd_n += 1;
|
|
|
12486 |
x = gfc.s3_ll[k] * eb_l[kk] * tab[mask_idx_l[kk]];
|
|
|
12487 |
t = vbrpsy_mask_add(ecb, x, kk - b);
|
|
|
12488 |
ecb = t;
|
|
|
12489 |
++k;
|
|
|
12490 |
++kk;
|
|
|
12491 |
}
|
|
|
12492 |
dd = (1 + 2 * dd) / (2 * dd_n);
|
|
|
12493 |
avg_mask = tab[dd] * 0.5;
|
|
|
12494 |
ecb *= avg_mask;
|
|
|
12495 |
|
|
|
12496 |
/**** long block pre-echo control ****/
|
|
|
12497 |
/**
|
|
|
12498 |
* <PRE>
|
|
|
12499 |
* dont use long block pre-echo control if previous granule was
|
|
|
12500 |
* a short block. This is to avoid the situation:
|
|
|
12501 |
* frame0: quiet (very low masking)
|
|
|
12502 |
* frame1: surge (triggers short blocks)
|
|
|
12503 |
* frame2: regular frame. looks like pre-echo when compared to
|
|
|
12504 |
* frame0, but all pre-echo was in frame1.
|
|
|
12505 |
* </PRE>
|
|
|
12506 |
*/
|
|
|
12507 |
/*
|
|
|
12508 |
* chn=0,1 L and R channels chn=2,3 S and M channels.
|
|
|
12509 |
*/
|
|
|
12510 |
if (gfc.blocktype_old[chn & 0x01] == Encoder.SHORT_TYPE) {
|
|
|
12511 |
var ecb_limit = rpelev * gfc.nb_1[chn][b];
|
|
|
12512 |
if (ecb_limit > 0) {
|
|
|
12513 |
thr[b] = Math.min(ecb, ecb_limit);
|
|
|
12514 |
} else {
|
|
|
12515 |
/**
|
|
|
12516 |
* <PRE>
|
|
|
12517 |
* Robert 071209:
|
|
|
12518 |
* Because we don't calculate long block psy when we know a granule
|
|
|
12519 |
* should be of short blocks, we don't have any clue how the granule
|
|
|
12520 |
* before would have looked like as a long block. So we have to guess
|
|
|
12521 |
* a little bit for this END_TYPE block.
|
|
|
12522 |
* Most of the time we get away with this sloppyness. (fingers crossed :)
|
|
|
12523 |
* The speed increase is worth it.
|
|
|
12524 |
* </PRE>
|
|
|
12525 |
*/
|
|
|
12526 |
thr[b] = Math.min(ecb, eb_l[b] * NS_PREECHO_ATT2);
|
|
|
12527 |
}
|
|
|
12528 |
} else {
|
|
|
12529 |
var ecb_limit_2 = rpelev2 * gfc.nb_2[chn][b];
|
|
|
12530 |
var ecb_limit_1 = rpelev * gfc.nb_1[chn][b];
|
|
|
12531 |
var ecb_limit;
|
|
|
12532 |
if (ecb_limit_2 <= 0) {
|
|
|
12533 |
ecb_limit_2 = ecb;
|
|
|
12534 |
}
|
|
|
12535 |
if (ecb_limit_1 <= 0) {
|
|
|
12536 |
ecb_limit_1 = ecb;
|
|
|
12537 |
}
|
|
|
12538 |
if (gfc.blocktype_old[chn & 0x01] == Encoder.NORM_TYPE) {
|
|
|
12539 |
ecb_limit = Math.min(ecb_limit_1, ecb_limit_2);
|
|
|
12540 |
} else {
|
|
|
12541 |
ecb_limit = ecb_limit_1;
|
|
|
12542 |
}
|
|
|
12543 |
thr[b] = Math.min(ecb, ecb_limit);
|
|
|
12544 |
}
|
|
|
12545 |
gfc.nb_2[chn][b] = gfc.nb_1[chn][b];
|
|
|
12546 |
gfc.nb_1[chn][b] = ecb;
|
|
|
12547 |
{
|
|
|
12548 |
/*
|
|
|
12549 |
* if THR exceeds EB, the quantization routines will take the
|
|
|
12550 |
* difference from other bands. in case of strong tonal samples
|
|
|
12551 |
* (tonaltest.wav) this leads to heavy distortions. that's why
|
|
|
12552 |
* we limit THR here.
|
|
|
12553 |
*/
|
|
|
12554 |
x = max[b];
|
|
|
12555 |
x *= gfc.minval_l[b];
|
|
|
12556 |
x *= avg_mask;
|
|
|
12557 |
if (thr[b] > x) {
|
|
|
12558 |
thr[b] = x;
|
|
|
12559 |
}
|
|
|
12560 |
}
|
|
|
12561 |
if (gfc.masking_lower > 1) {
|
|
|
12562 |
thr[b] *= gfc.masking_lower;
|
|
|
12563 |
}
|
|
|
12564 |
if (thr[b] > eb_l[b]) {
|
|
|
12565 |
thr[b] = eb_l[b];
|
|
|
12566 |
}
|
|
|
12567 |
if (gfc.masking_lower < 1) {
|
|
|
12568 |
thr[b] *= gfc.masking_lower;
|
|
|
12569 |
}
|
|
|
12570 |
}
|
|
|
12571 |
for (; b < Encoder.CBANDS; ++b) {
|
|
|
12572 |
eb_l[b] = 0;
|
|
|
12573 |
thr[b] = 0;
|
|
|
12574 |
}
|
|
|
12575 |
}
|
|
|
12576 |
|
|
|
12577 |
function vbrpsy_compute_block_type(gfp, uselongblock) {
|
|
|
12578 |
var gfc = gfp.internal_flags;
|
|
|
12579 |
|
|
|
12580 |
if (gfp.short_blocks == ShortBlock.short_block_coupled
|
|
|
12581 |
/* force both channels to use the same block type */
|
|
|
12582 |
/* this is necessary if the frame is to be encoded in ms_stereo. */
|
|
|
12583 |
/* But even without ms_stereo, FhG does this */
|
|
|
12584 |
&& !(uselongblock[0] != 0 && uselongblock[1] != 0))
|
|
|
12585 |
uselongblock[0] = uselongblock[1] = 0;
|
|
|
12586 |
|
|
|
12587 |
for (var chn = 0; chn < gfc.channels_out; chn++) {
|
|
|
12588 |
/* disable short blocks */
|
|
|
12589 |
if (gfp.short_blocks == ShortBlock.short_block_dispensed) {
|
|
|
12590 |
uselongblock[chn] = 1;
|
|
|
12591 |
}
|
|
|
12592 |
if (gfp.short_blocks == ShortBlock.short_block_forced) {
|
|
|
12593 |
uselongblock[chn] = 0;
|
|
|
12594 |
}
|
|
|
12595 |
}
|
|
|
12596 |
}
|
|
|
12597 |
|
|
|
12598 |
function vbrpsy_apply_block_type(gfp, uselongblock, blocktype_d) {
|
|
|
12599 |
var gfc = gfp.internal_flags;
|
|
|
12600 |
|
|
|
12601 |
/*
|
|
|
12602 |
* update the blocktype of the previous granule, since it depends on
|
|
|
12603 |
* what happend in this granule
|
|
|
12604 |
*/
|
|
|
12605 |
for (var chn = 0; chn < gfc.channels_out; chn++) {
|
|
|
12606 |
var blocktype = Encoder.NORM_TYPE;
|
|
|
12607 |
/* disable short blocks */
|
|
|
12608 |
|
|
|
12609 |
if (uselongblock[chn] != 0) {
|
|
|
12610 |
/* no attack : use long blocks */
|
|
|
12611 |
if (gfc.blocktype_old[chn] == Encoder.SHORT_TYPE)
|
|
|
12612 |
blocktype = Encoder.STOP_TYPE;
|
|
|
12613 |
} else {
|
|
|
12614 |
/* attack : use short blocks */
|
|
|
12615 |
blocktype = Encoder.SHORT_TYPE;
|
|
|
12616 |
if (gfc.blocktype_old[chn] == Encoder.NORM_TYPE) {
|
|
|
12617 |
gfc.blocktype_old[chn] = Encoder.START_TYPE;
|
|
|
12618 |
}
|
|
|
12619 |
if (gfc.blocktype_old[chn] == Encoder.STOP_TYPE)
|
|
|
12620 |
gfc.blocktype_old[chn] = Encoder.SHORT_TYPE;
|
|
|
12621 |
}
|
|
|
12622 |
|
|
|
12623 |
blocktype_d[chn] = gfc.blocktype_old[chn];
|
|
|
12624 |
// value returned to calling program
|
|
|
12625 |
gfc.blocktype_old[chn] = blocktype;
|
|
|
12626 |
// save for next call to l3psy_anal
|
|
|
12627 |
}
|
|
|
12628 |
}
|
|
|
12629 |
|
|
|
12630 |
/**
|
|
|
12631 |
* compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper
|
|
|
12632 |
*/
|
|
|
12633 |
function vbrpsy_compute_MS_thresholds(eb, thr, cb_mld, ath_cb, athadjust, msfix, n) {
|
|
|
12634 |
var msfix2 = msfix * 2;
|
|
|
12635 |
var athlower = msfix > 0 ? Math.pow(10, athadjust) : 1;
|
|
|
12636 |
var rside, rmid;
|
|
|
12637 |
for (var b = 0; b < n; ++b) {
|
|
|
12638 |
var ebM = eb[2][b];
|
|
|
12639 |
var ebS = eb[3][b];
|
|
|
12640 |
var thmL = thr[0][b];
|
|
|
12641 |
var thmR = thr[1][b];
|
|
|
12642 |
var thmM = thr[2][b];
|
|
|
12643 |
var thmS = thr[3][b];
|
|
|
12644 |
|
|
|
12645 |
/* use this fix if L & R masking differs by 2db or less */
|
|
|
12646 |
if (thmL <= 1.58 * thmR && thmR <= 1.58 * thmL) {
|
|
|
12647 |
var mld_m = cb_mld[b] * ebS;
|
|
|
12648 |
var mld_s = cb_mld[b] * ebM;
|
|
|
12649 |
rmid = Math.max(thmM, Math.min(thmS, mld_m));
|
|
|
12650 |
rside = Math.max(thmS, Math.min(thmM, mld_s));
|
|
|
12651 |
} else {
|
|
|
12652 |
rmid = thmM;
|
|
|
12653 |
rside = thmS;
|
|
|
12654 |
}
|
|
|
12655 |
if (msfix > 0) {
|
|
|
12656 |
/***************************************************************/
|
|
|
12657 |
/* Adjust M/S maskings if user set "msfix" */
|
|
|
12658 |
/***************************************************************/
|
|
|
12659 |
/* Naoki Shibata 2000 */
|
|
|
12660 |
var thmLR, thmMS;
|
|
|
12661 |
var ath = ath_cb[b] * athlower;
|
|
|
12662 |
thmLR = Math.min(Math.max(thmL, ath), Math.max(thmR, ath));
|
|
|
12663 |
thmM = Math.max(rmid, ath);
|
|
|
12664 |
thmS = Math.max(rside, ath);
|
|
|
12665 |
thmMS = thmM + thmS;
|
|
|
12666 |
if (thmMS > 0 && (thmLR * msfix2) < thmMS) {
|
|
|
12667 |
var f = thmLR * msfix2 / thmMS;
|
|
|
12668 |
thmM *= f;
|
|
|
12669 |
thmS *= f;
|
|
|
12670 |
}
|
|
|
12671 |
rmid = Math.min(thmM, rmid);
|
|
|
12672 |
rside = Math.min(thmS, rside);
|
|
|
12673 |
}
|
|
|
12674 |
if (rmid > ebM) {
|
|
|
12675 |
rmid = ebM;
|
|
|
12676 |
}
|
|
|
12677 |
if (rside > ebS) {
|
|
|
12678 |
rside = ebS;
|
|
|
12679 |
}
|
|
|
12680 |
thr[2][b] = rmid;
|
|
|
12681 |
thr[3][b] = rside;
|
|
|
12682 |
}
|
|
|
12683 |
}
|
|
|
12684 |
|
|
|
12685 |
this.L3psycho_anal_vbr = function (gfp, buffer, bufPos, gr_out, masking_ratio, masking_MS_ratio, percep_entropy, percep_MS_entropy, energy, blocktype_d) {
|
|
|
12686 |
var gfc = gfp.internal_flags;
|
|
|
12687 |
|
|
|
12688 |
/* fft and energy calculation */
|
|
|
12689 |
var wsamp_l;
|
|
|
12690 |
var wsamp_s;
|
|
|
12691 |
var fftenergy = new_float(Encoder.HBLKSIZE);
|
|
|
12692 |
var fftenergy_s = new_float_n([3, Encoder.HBLKSIZE_s]);
|
|
|
12693 |
var wsamp_L = new_float_n([2, Encoder.BLKSIZE]);
|
|
|
12694 |
var wsamp_S = new_float_n([2, 3, Encoder.BLKSIZE_s]);
|
|
|
12695 |
var eb = new_float_n([4, Encoder.CBANDS]), thr = new_float_n([4, Encoder.CBANDS]);
|
|
|
12696 |
var sub_short_factor = new_float_n([4, 3]);
|
|
|
12697 |
var pcfact = 0.6;
|
|
|
12698 |
|
|
|
12699 |
/* block type */
|
|
|
12700 |
var ns_attacks = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0],
|
|
|
12701 |
[0, 0, 0, 0]];
|
|
|
12702 |
var uselongblock = new_int(2);
|
|
|
12703 |
|
|
|
12704 |
/* usual variables like loop indices, etc.. */
|
|
|
12705 |
|
|
|
12706 |
/* chn=2 and 3 = Mid and Side channels */
|
|
|
12707 |
var n_chn_psy = (gfp.mode == MPEGMode.JOINT_STEREO) ? 4
|
|
|
12708 |
: gfc.channels_out;
|
|
|
12709 |
|
|
|
12710 |
vbrpsy_attack_detection(gfp, buffer, bufPos, gr_out, masking_ratio,
|
|
|
12711 |
masking_MS_ratio, energy, sub_short_factor, ns_attacks,
|
|
|
12712 |
uselongblock);
|
|
|
12713 |
|
|
|
12714 |
vbrpsy_compute_block_type(gfp, uselongblock);
|
|
|
12715 |
|
|
|
12716 |
/* LONG BLOCK CASE */
|
|
|
12717 |
{
|
|
|
12718 |
for (var chn = 0; chn < n_chn_psy; chn++) {
|
|
|
12719 |
var ch01 = chn & 0x01;
|
|
|
12720 |
wsamp_l = wsamp_L;
|
|
|
12721 |
vbrpsy_compute_fft_l(gfp, buffer, bufPos, chn, gr_out,
|
|
|
12722 |
fftenergy, wsamp_l, ch01);
|
|
|
12723 |
|
|
|
12724 |
vbrpsy_compute_loudness_approximation_l(gfp, gr_out, chn,
|
|
|
12725 |
fftenergy);
|
|
|
12726 |
|
|
|
12727 |
if (uselongblock[ch01] != 0) {
|
|
|
12728 |
vbrpsy_compute_masking_l(gfc, fftenergy, eb[chn], thr[chn],
|
|
|
12729 |
chn);
|
|
|
12730 |
} else {
|
|
|
12731 |
vbrpsy_skip_masking_l(gfc, chn);
|
|
|
12732 |
}
|
|
|
12733 |
}
|
|
|
12734 |
if ((uselongblock[0] + uselongblock[1]) == 2) {
|
|
|
12735 |
/* M/S channel */
|
|
|
12736 |
if (gfp.mode == MPEGMode.JOINT_STEREO) {
|
|
|
12737 |
vbrpsy_compute_MS_thresholds(eb, thr, gfc.mld_cb_l,
|
|
|
12738 |
gfc.ATH.cb_l, gfp.ATHlower * gfc.ATH.adjust,
|
|
|
12739 |
gfp.msfix, gfc.npart_l);
|
|
|
12740 |
}
|
|
|
12741 |
}
|
|
|
12742 |
/* TODO: apply adaptive ATH masking here ?? */
|
|
|
12743 |
for (var chn = 0; chn < n_chn_psy; chn++) {
|
|
|
12744 |
var ch01 = chn & 0x01;
|
|
|
12745 |
if (uselongblock[ch01] != 0) {
|
|
|
12746 |
convert_partition2scalefac_l(gfc, eb[chn], thr[chn], chn);
|
|
|
12747 |
}
|
|
|
12748 |
}
|
|
|
12749 |
}
|
|
|
12750 |
|
|
|
12751 |
/* SHORT BLOCKS CASE */
|
|
|
12752 |
{
|
|
|
12753 |
for (var sblock = 0; sblock < 3; sblock++) {
|
|
|
12754 |
for (var chn = 0; chn < n_chn_psy; ++chn) {
|
|
|
12755 |
var ch01 = chn & 0x01;
|
|
|
12756 |
|
|
|
12757 |
if (uselongblock[ch01] != 0) {
|
|
|
12758 |
vbrpsy_skip_masking_s(gfc, chn, sblock);
|
|
|
12759 |
} else {
|
|
|
12760 |
/* compute masking thresholds for short blocks */
|
|
|
12761 |
wsamp_s = wsamp_S;
|
|
|
12762 |
vbrpsy_compute_fft_s(gfp, buffer, bufPos, chn, sblock,
|
|
|
12763 |
fftenergy_s, wsamp_s, ch01);
|
|
|
12764 |
vbrpsy_compute_masking_s(gfp, fftenergy_s, eb[chn],
|
|
|
12765 |
thr[chn], chn, sblock);
|
|
|
12766 |
}
|
|
|
12767 |
}
|
|
|
12768 |
if ((uselongblock[0] + uselongblock[1]) == 0) {
|
|
|
12769 |
/* M/S channel */
|
|
|
12770 |
if (gfp.mode == MPEGMode.JOINT_STEREO) {
|
|
|
12771 |
vbrpsy_compute_MS_thresholds(eb, thr, gfc.mld_cb_s,
|
|
|
12772 |
gfc.ATH.cb_s, gfp.ATHlower * gfc.ATH.adjust,
|
|
|
12773 |
gfp.msfix, gfc.npart_s);
|
|
|
12774 |
}
|
|
|
12775 |
/* L/R channel */
|
|
|
12776 |
}
|
|
|
12777 |
/* TODO: apply adaptive ATH masking here ?? */
|
|
|
12778 |
for (var chn = 0; chn < n_chn_psy; ++chn) {
|
|
|
12779 |
var ch01 = chn & 0x01;
|
|
|
12780 |
if (0 == uselongblock[ch01]) {
|
|
|
12781 |
convert_partition2scalefac_s(gfc, eb[chn], thr[chn],
|
|
|
12782 |
chn, sblock);
|
|
|
12783 |
}
|
|
|
12784 |
}
|
|
|
12785 |
}
|
|
|
12786 |
|
|
|
12787 |
/**** short block pre-echo control ****/
|
|
|
12788 |
for (var chn = 0; chn < n_chn_psy; chn++) {
|
|
|
12789 |
var ch01 = chn & 0x01;
|
|
|
12790 |
|
|
|
12791 |
if (uselongblock[ch01] != 0) {
|
|
|
12792 |
continue;
|
|
|
12793 |
}
|
|
|
12794 |
for (var sb = 0; sb < Encoder.SBMAX_s; sb++) {
|
|
|
12795 |
var new_thmm = new_float(3);
|
|
|
12796 |
for (var sblock = 0; sblock < 3; sblock++) {
|
|
|
12797 |
var thmm = gfc.thm[chn].s[sb][sblock];
|
|
|
12798 |
thmm *= NS_PREECHO_ATT0;
|
|
|
12799 |
|
|
|
12800 |
if (ns_attacks[chn][sblock] >= 2
|
|
|
12801 |
|| ns_attacks[chn][sblock + 1] == 1) {
|
|
|
12802 |
var idx = (sblock != 0) ? sblock - 1 : 2;
|
|
|
12803 |
var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm,
|
|
|
12804 |
NS_PREECHO_ATT1 * pcfact);
|
|
|
12805 |
thmm = Math.min(thmm, p);
|
|
|
12806 |
} else if (ns_attacks[chn][sblock] == 1) {
|
|
|
12807 |
var idx = (sblock != 0) ? sblock - 1 : 2;
|
|
|
12808 |
var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm,
|
|
|
12809 |
NS_PREECHO_ATT2 * pcfact);
|
|
|
12810 |
thmm = Math.min(thmm, p);
|
|
|
12811 |
} else if ((sblock != 0 && ns_attacks[chn][sblock - 1] == 3)
|
|
|
12812 |
|| (sblock == 0 && gfc.nsPsy.lastAttacks[chn] == 3)) {
|
|
|
12813 |
var idx = (sblock != 2) ? sblock + 1 : 0;
|
|
|
12814 |
var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm,
|
|
|
12815 |
NS_PREECHO_ATT2 * pcfact);
|
|
|
12816 |
thmm = Math.min(thmm, p);
|
|
|
12817 |
}
|
|
|
12818 |
|
|
|
12819 |
/* pulse like signal detection for fatboy.wav and so on */
|
|
|
12820 |
thmm *= sub_short_factor[chn][sblock];
|
|
|
12821 |
|
|
|
12822 |
new_thmm[sblock] = thmm;
|
|
|
12823 |
}
|
|
|
12824 |
for (var sblock = 0; sblock < 3; sblock++) {
|
|
|
12825 |
gfc.thm[chn].s[sb][sblock] = new_thmm[sblock];
|
|
|
12826 |
}
|
|
|
12827 |
}
|
|
|
12828 |
}
|
|
|
12829 |
}
|
|
|
12830 |
for (var chn = 0; chn < n_chn_psy; chn++) {
|
|
|
12831 |
gfc.nsPsy.lastAttacks[chn] = ns_attacks[chn][2];
|
|
|
12832 |
}
|
|
|
12833 |
|
|
|
12834 |
/***************************************************************
|
|
|
12835 |
* determine final block type
|
|
|
12836 |
***************************************************************/
|
|
|
12837 |
vbrpsy_apply_block_type(gfp, uselongblock, blocktype_d);
|
|
|
12838 |
|
|
|
12839 |
/*********************************************************************
|
|
|
12840 |
* compute the value of PE to return ... no delay and advance
|
|
|
12841 |
*********************************************************************/
|
|
|
12842 |
for (var chn = 0; chn < n_chn_psy; chn++) {
|
|
|
12843 |
var ppe;
|
|
|
12844 |
var ppePos;
|
|
|
12845 |
var type;
|
|
|
12846 |
var mr;
|
|
|
12847 |
|
|
|
12848 |
if (chn > 1) {
|
|
|
12849 |
ppe = percep_MS_entropy;
|
|
|
12850 |
ppePos = -2;
|
|
|
12851 |
type = Encoder.NORM_TYPE;
|
|
|
12852 |
if (blocktype_d[0] == Encoder.SHORT_TYPE
|
|
|
12853 |
|| blocktype_d[1] == Encoder.SHORT_TYPE)
|
|
|
12854 |
type = Encoder.SHORT_TYPE;
|
|
|
12855 |
mr = masking_MS_ratio[gr_out][chn - 2];
|
|
|
12856 |
} else {
|
|
|
12857 |
ppe = percep_entropy;
|
|
|
12858 |
ppePos = 0;
|
|
|
12859 |
type = blocktype_d[chn];
|
|
|
12860 |
mr = masking_ratio[gr_out][chn];
|
|
|
12861 |
}
|
|
|
12862 |
|
|
|
12863 |
if (type == Encoder.SHORT_TYPE) {
|
|
|
12864 |
ppe[ppePos + chn] = pecalc_s(mr, gfc.masking_lower);
|
|
|
12865 |
} else {
|
|
|
12866 |
ppe[ppePos + chn] = pecalc_l(mr, gfc.masking_lower);
|
|
|
12867 |
}
|
|
|
12868 |
|
|
|
12869 |
if (gfp.analysis) {
|
|
|
12870 |
gfc.pinfo.pe[gr_out][chn] = ppe[ppePos + chn];
|
|
|
12871 |
}
|
|
|
12872 |
}
|
|
|
12873 |
return 0;
|
|
|
12874 |
}
|
|
|
12875 |
|
|
|
12876 |
function s3_func_x(bark, hf_slope) {
|
|
|
12877 |
var tempx = bark, tempy;
|
|
|
12878 |
|
|
|
12879 |
if (tempx >= 0) {
|
|
|
12880 |
tempy = -tempx * 27;
|
|
|
12881 |
} else {
|
|
|
12882 |
tempy = tempx * hf_slope;
|
|
|
12883 |
}
|
|
|
12884 |
if (tempy <= -72.0) {
|
|
|
12885 |
return 0;
|
|
|
12886 |
}
|
|
|
12887 |
return Math.exp(tempy * LN_TO_LOG10);
|
|
|
12888 |
}
|
|
|
12889 |
|
|
|
12890 |
function norm_s3_func_x(hf_slope) {
|
|
|
12891 |
var lim_a = 0, lim_b = 0;
|
|
|
12892 |
{
|
|
|
12893 |
var x = 0, l, h;
|
|
|
12894 |
for (x = 0; s3_func_x(x, hf_slope) > 1e-20; x -= 1)
|
|
|
12895 |
;
|
|
|
12896 |
l = x;
|
|
|
12897 |
h = 0;
|
|
|
12898 |
while (Math.abs(h - l) > 1e-12) {
|
|
|
12899 |
x = (h + l) / 2;
|
|
|
12900 |
if (s3_func_x(x, hf_slope) > 0) {
|
|
|
12901 |
h = x;
|
|
|
12902 |
} else {
|
|
|
12903 |
l = x;
|
|
|
12904 |
}
|
|
|
12905 |
}
|
|
|
12906 |
lim_a = l;
|
|
|
12907 |
}
|
|
|
12908 |
{
|
|
|
12909 |
var x = 0, l, h;
|
|
|
12910 |
for (x = 0; s3_func_x(x, hf_slope) > 1e-20; x += 1)
|
|
|
12911 |
;
|
|
|
12912 |
l = 0;
|
|
|
12913 |
h = x;
|
|
|
12914 |
while (Math.abs(h - l) > 1e-12) {
|
|
|
12915 |
x = (h + l) / 2;
|
|
|
12916 |
if (s3_func_x(x, hf_slope) > 0) {
|
|
|
12917 |
l = x;
|
|
|
12918 |
} else {
|
|
|
12919 |
h = x;
|
|
|
12920 |
}
|
|
|
12921 |
}
|
|
|
12922 |
lim_b = h;
|
|
|
12923 |
}
|
|
|
12924 |
{
|
|
|
12925 |
var sum = 0;
|
|
|
12926 |
var m = 1000;
|
|
|
12927 |
var i;
|
|
|
12928 |
for (i = 0; i <= m; ++i) {
|
|
|
12929 |
var x = lim_a + i * (lim_b - lim_a) / m;
|
|
|
12930 |
var y = s3_func_x(x, hf_slope);
|
|
|
12931 |
sum += y;
|
|
|
12932 |
}
|
|
|
12933 |
{
|
|
|
12934 |
var norm = (m + 1) / (sum * (lim_b - lim_a));
|
|
|
12935 |
/* printf( "norm = %lf\n",norm); */
|
|
|
12936 |
return norm;
|
|
|
12937 |
}
|
|
|
12938 |
}
|
|
|
12939 |
}
|
|
|
12940 |
|
|
|
12941 |
/**
|
|
|
12942 |
* The spreading function. Values returned in units of energy
|
|
|
12943 |
*/
|
|
|
12944 |
function s3_func(bark) {
|
|
|
12945 |
var tempx, x, tempy, temp;
|
|
|
12946 |
tempx = bark;
|
|
|
12947 |
if (tempx >= 0)
|
|
|
12948 |
tempx *= 3;
|
|
|
12949 |
else
|
|
|
12950 |
tempx *= 1.5;
|
|
|
12951 |
|
|
|
12952 |
if (tempx >= 0.5 && tempx <= 2.5) {
|
|
|
12953 |
temp = tempx - 0.5;
|
|
|
12954 |
x = 8.0 * (temp * temp - 2.0 * temp);
|
|
|
12955 |
} else
|
|
|
12956 |
x = 0.0;
|
|
|
12957 |
tempx += 0.474;
|
|
|
12958 |
tempy = 15.811389 + 7.5 * tempx - 17.5
|
|
|
12959 |
* Math.sqrt(1.0 + tempx * tempx);
|
|
|
12960 |
|
|
|
12961 |
if (tempy <= -60.0)
|
|
|
12962 |
return 0.0;
|
|
|
12963 |
|
|
|
12964 |
tempx = Math.exp((x + tempy) * LN_TO_LOG10);
|
|
|
12965 |
|
|
|
12966 |
/**
|
|
|
12967 |
* <PRE>
|
|
|
12968 |
* Normalization. The spreading function should be normalized so that:
|
|
|
12969 |
* +inf
|
|
|
12970 |
* /
|
|
|
12971 |
* | s3 [ bark ] d(bark) = 1
|
|
|
12972 |
* /
|
|
|
12973 |
* -inf
|
|
|
12974 |
* </PRE>
|
|
|
12975 |
*/
|
|
|
12976 |
tempx /= .6609193;
|
|
|
12977 |
return tempx;
|
|
|
12978 |
}
|
|
|
12979 |
|
|
|
12980 |
/**
|
|
|
12981 |
* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7
|
|
|
12982 |
*/
|
|
|
12983 |
function freq2bark(freq) {
|
|
|
12984 |
/* input: freq in hz output: barks */
|
|
|
12985 |
if (freq < 0)
|
|
|
12986 |
freq = 0;
|
|
|
12987 |
freq = freq * 0.001;
|
|
|
12988 |
return 13.0 * Math.atan(.76 * freq) + 3.5
|
|
|
12989 |
* Math.atan(freq * freq / (7.5 * 7.5));
|
|
|
12990 |
}
|
|
|
12991 |
|
|
|
12992 |
function init_numline(numlines, bo, bm, bval, bval_width, mld, bo_w, sfreq, blksize, scalepos, deltafreq, sbmax) {
|
|
|
12993 |
var b_frq = new_float(Encoder.CBANDS + 1);
|
|
|
12994 |
var sample_freq_frac = sfreq / (sbmax > 15 ? 2 * 576 : 2 * 192);
|
|
|
12995 |
var partition = new_int(Encoder.HBLKSIZE);
|
|
|
12996 |
var i;
|
|
|
12997 |
sfreq /= blksize;
|
|
|
12998 |
var j = 0;
|
|
|
12999 |
var ni = 0;
|
|
|
13000 |
/* compute numlines, the number of spectral lines in each partition band */
|
|
|
13001 |
/* each partition band should be about DELBARK wide. */
|
|
|
13002 |
for (i = 0; i < Encoder.CBANDS; i++) {
|
|
|
13003 |
var bark1;
|
|
|
13004 |
var j2;
|
|
|
13005 |
bark1 = freq2bark(sfreq * j);
|
|
|
13006 |
|
|
|
13007 |
b_frq[i] = sfreq * j;
|
|
|
13008 |
|
|
|
13009 |
for (j2 = j; freq2bark(sfreq * j2) - bark1 < DELBARK
|
|
|
13010 |
&& j2 <= blksize / 2; j2++)
|
|
|
13011 |
;
|
|
|
13012 |
|
|
|
13013 |
numlines[i] = j2 - j;
|
|
|
13014 |
ni = i + 1;
|
|
|
13015 |
|
|
|
13016 |
while (j < j2) {
|
|
|
13017 |
partition[j++] = i;
|
|
|
13018 |
}
|
|
|
13019 |
if (j > blksize / 2) {
|
|
|
13020 |
j = blksize / 2;
|
|
|
13021 |
++i;
|
|
|
13022 |
break;
|
|
|
13023 |
}
|
|
|
13024 |
}
|
|
|
13025 |
b_frq[i] = sfreq * j;
|
|
|
13026 |
|
|
|
13027 |
for (var sfb = 0; sfb < sbmax; sfb++) {
|
|
|
13028 |
var i1, i2, start, end;
|
|
|
13029 |
var arg;
|
|
|
13030 |
start = scalepos[sfb];
|
|
|
13031 |
end = scalepos[sfb + 1];
|
|
|
13032 |
|
|
|
13033 |
i1 = 0 | Math.floor(.5 + deltafreq * (start - .5));
|
|
|
13034 |
if (i1 < 0)
|
|
|
13035 |
i1 = 0;
|
|
|
13036 |
i2 = 0 | Math.floor(.5 + deltafreq * (end - .5));
|
|
|
13037 |
|
|
|
13038 |
if (i2 > blksize / 2)
|
|
|
13039 |
i2 = blksize / 2;
|
|
|
13040 |
|
|
|
13041 |
bm[sfb] = (partition[i1] + partition[i2]) / 2;
|
|
|
13042 |
bo[sfb] = partition[i2];
|
|
|
13043 |
var f_tmp = sample_freq_frac * end;
|
|
|
13044 |
/*
|
|
|
13045 |
* calculate how much of this band belongs to current scalefactor
|
|
|
13046 |
* band
|
|
|
13047 |
*/
|
|
|
13048 |
bo_w[sfb] = (f_tmp - b_frq[bo[sfb]])
|
|
|
13049 |
/ (b_frq[bo[sfb] + 1] - b_frq[bo[sfb]]);
|
|
|
13050 |
if (bo_w[sfb] < 0) {
|
|
|
13051 |
bo_w[sfb] = 0;
|
|
|
13052 |
} else {
|
|
|
13053 |
if (bo_w[sfb] > 1) {
|
|
|
13054 |
bo_w[sfb] = 1;
|
|
|
13055 |
}
|
|
|
13056 |
}
|
|
|
13057 |
/* setup stereo demasking thresholds */
|
|
|
13058 |
/* formula reverse enginerred from plot in paper */
|
|
|
13059 |
arg = freq2bark(sfreq * scalepos[sfb] * deltafreq);
|
|
|
13060 |
arg = ( Math.min(arg, 15.5) / 15.5);
|
|
|
13061 |
|
|
|
13062 |
mld[sfb] = Math.pow(10.0,
|
|
|
13063 |
1.25 * (1 - Math.cos(Math.PI * arg)) - 2.5);
|
|
|
13064 |
}
|
|
|
13065 |
|
|
|
13066 |
/* compute bark values of each critical band */
|
|
|
13067 |
j = 0;
|
|
|
13068 |
for (var k = 0; k < ni; k++) {
|
|
|
13069 |
var w = numlines[k];
|
|
|
13070 |
var bark1, bark2;
|
|
|
13071 |
|
|
|
13072 |
bark1 = freq2bark(sfreq * (j));
|
|
|
13073 |
bark2 = freq2bark(sfreq * (j + w - 1));
|
|
|
13074 |
bval[k] = .5 * (bark1 + bark2);
|
|
|
13075 |
|
|
|
13076 |
bark1 = freq2bark(sfreq * (j - .5));
|
|
|
13077 |
bark2 = freq2bark(sfreq * (j + w - .5));
|
|
|
13078 |
bval_width[k] = bark2 - bark1;
|
|
|
13079 |
j += w;
|
|
|
13080 |
}
|
|
|
13081 |
|
|
|
13082 |
return ni;
|
|
|
13083 |
}
|
|
|
13084 |
|
|
|
13085 |
function init_s3_values(s3ind, npart, bval, bval_width, norm, use_old_s3) {
|
|
|
13086 |
var s3 = new_float_n([Encoder.CBANDS, Encoder.CBANDS]);
|
|
|
13087 |
/*
|
|
|
13088 |
* The s3 array is not linear in the bark scale.
|
|
|
13089 |
*
|
|
|
13090 |
* bval[x] should be used to get the bark value.
|
|
|
13091 |
*/
|
|
|
13092 |
var j;
|
|
|
13093 |
var numberOfNoneZero = 0;
|
|
|
13094 |
|
|
|
13095 |
/**
|
|
|
13096 |
* <PRE>
|
|
|
13097 |
* s[i][j], the value of the spreading function,
|
|
|
13098 |
* centered at band j (masker), for band i (maskee)
|
|
|
13099 |
*
|
|
|
13100 |
* i.e.: sum over j to spread into signal barkval=i
|
|
|
13101 |
* NOTE: i and j are used opposite as in the ISO docs
|
|
|
13102 |
* </PRE>
|
|
|
13103 |
*/
|
|
|
13104 |
if (use_old_s3) {
|
|
|
13105 |
for (var i = 0; i < npart; i++) {
|
|
|
13106 |
for (j = 0; j < npart; j++) {
|
|
|
13107 |
var v = s3_func(bval[i] - bval[j]) * bval_width[j];
|
|
|
13108 |
s3[i][j] = v * norm[i];
|
|
|
13109 |
}
|
|
|
13110 |
}
|
|
|
13111 |
} else {
|
|
|
13112 |
for (j = 0; j < npart; j++) {
|
|
|
13113 |
var hf_slope = 15 + Math.min(21 / bval[j], 12);
|
|
|
13114 |
var s3_x_norm = norm_s3_func_x(hf_slope);
|
|
|
13115 |
for (var i = 0; i < npart; i++) {
|
|
|
13116 |
var v = s3_x_norm
|
|
|
13117 |
* s3_func_x(bval[i] - bval[j], hf_slope)
|
|
|
13118 |
* bval_width[j];
|
|
|
13119 |
s3[i][j] = v * norm[i];
|
|
|
13120 |
}
|
|
|
13121 |
}
|
|
|
13122 |
}
|
|
|
13123 |
for (var i = 0; i < npart; i++) {
|
|
|
13124 |
for (j = 0; j < npart; j++) {
|
|
|
13125 |
if (s3[i][j] > 0.0)
|
|
|
13126 |
break;
|
|
|
13127 |
}
|
|
|
13128 |
s3ind[i][0] = j;
|
|
|
13129 |
|
|
|
13130 |
for (j = npart - 1; j > 0; j--) {
|
|
|
13131 |
if (s3[i][j] > 0.0)
|
|
|
13132 |
break;
|
|
|
13133 |
}
|
|
|
13134 |
s3ind[i][1] = j;
|
|
|
13135 |
numberOfNoneZero += (s3ind[i][1] - s3ind[i][0] + 1);
|
|
|
13136 |
}
|
|
|
13137 |
|
|
|
13138 |
var p = new_float(numberOfNoneZero);
|
|
|
13139 |
var k = 0;
|
|
|
13140 |
for (var i = 0; i < npart; i++)
|
|
|
13141 |
for (j = s3ind[i][0]; j <= s3ind[i][1]; j++)
|
|
|
13142 |
p[k++] = s3[i][j];
|
|
|
13143 |
|
|
|
13144 |
return p;
|
|
|
13145 |
}
|
|
|
13146 |
|
|
|
13147 |
function stereo_demask(f) {
|
|
|
13148 |
/* setup stereo demasking thresholds */
|
|
|
13149 |
/* formula reverse enginerred from plot in paper */
|
|
|
13150 |
var arg = freq2bark(f);
|
|
|
13151 |
arg = (Math.min(arg, 15.5) / 15.5);
|
|
|
13152 |
|
|
|
13153 |
return Math.pow(10.0,
|
|
|
13154 |
1.25 * (1 - Math.cos(Math.PI * arg)) - 2.5);
|
|
|
13155 |
}
|
|
|
13156 |
|
|
|
13157 |
/**
|
|
|
13158 |
* NOTE: the bitrate reduction from the inter-channel masking effect is low
|
|
|
13159 |
* compared to the chance of getting annyoing artefacts. L3psycho_anal_vbr
|
|
|
13160 |
* does not use this feature. (Robert 071216)
|
|
|
13161 |
*/
|
|
|
13162 |
this.psymodel_init = function (gfp) {
|
|
|
13163 |
var gfc = gfp.internal_flags;
|
|
|
13164 |
var i;
|
|
|
13165 |
var useOldS3 = true;
|
|
|
13166 |
var bvl_a = 13, bvl_b = 24;
|
|
|
13167 |
var snr_l_a = 0, snr_l_b = 0;
|
|
|
13168 |
var snr_s_a = -8.25, snr_s_b = -4.5;
|
|
|
13169 |
var bval = new_float(Encoder.CBANDS);
|
|
|
13170 |
var bval_width = new_float(Encoder.CBANDS);
|
|
|
13171 |
var norm = new_float(Encoder.CBANDS);
|
|
|
13172 |
var sfreq = gfp.out_samplerate;
|
|
|
13173 |
|
|
|
13174 |
switch (gfp.experimentalZ) {
|
|
|
13175 |
default:
|
|
|
13176 |
case 0:
|
|
|
13177 |
useOldS3 = true;
|
|
|
13178 |
break;
|
|
|
13179 |
case 1:
|
|
|
13180 |
useOldS3 = (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) ? false
|
|
|
13181 |
: true;
|
|
|
13182 |
break;
|
|
|
13183 |
case 2:
|
|
|
13184 |
useOldS3 = false;
|
|
|
13185 |
break;
|
|
|
13186 |
case 3:
|
|
|
13187 |
bvl_a = 8;
|
|
|
13188 |
snr_l_a = -1.75;
|
|
|
13189 |
snr_l_b = -0.0125;
|
|
|
13190 |
snr_s_a = -8.25;
|
|
|
13191 |
snr_s_b = -2.25;
|
|
|
13192 |
break;
|
|
|
13193 |
}
|
|
|
13194 |
gfc.ms_ener_ratio_old = .25;
|
|
|
13195 |
gfc.blocktype_old[0] = gfc.blocktype_old[1] = Encoder.NORM_TYPE;
|
|
|
13196 |
// the vbr header is long blocks
|
|
|
13197 |
|
|
|
13198 |
for (i = 0; i < 4; ++i) {
|
|
|
13199 |
for (var j = 0; j < Encoder.CBANDS; ++j) {
|
|
|
13200 |
gfc.nb_1[i][j] = 1e20;
|
|
|
13201 |
gfc.nb_2[i][j] = 1e20;
|
|
|
13202 |
gfc.nb_s1[i][j] = gfc.nb_s2[i][j] = 1.0;
|
|
|
13203 |
}
|
|
|
13204 |
for (var sb = 0; sb < Encoder.SBMAX_l; sb++) {
|
|
|
13205 |
gfc.en[i].l[sb] = 1e20;
|
|
|
13206 |
gfc.thm[i].l[sb] = 1e20;
|
|
|
13207 |
}
|
|
|
13208 |
for (var j = 0; j < 3; ++j) {
|
|
|
13209 |
for (var sb = 0; sb < Encoder.SBMAX_s; sb++) {
|
|
|
13210 |
gfc.en[i].s[sb][j] = 1e20;
|
|
|
13211 |
gfc.thm[i].s[sb][j] = 1e20;
|
|
|
13212 |
}
|
|
|
13213 |
gfc.nsPsy.lastAttacks[i] = 0;
|
|
|
13214 |
}
|
|
|
13215 |
for (var j = 0; j < 9; j++)
|
|
|
13216 |
gfc.nsPsy.last_en_subshort[i][j] = 10.;
|
|
|
13217 |
}
|
|
|
13218 |
|
|
|
13219 |
/* init. for loudness approx. -jd 2001 mar 27 */
|
|
|
13220 |
gfc.loudness_sq_save[0] = gfc.loudness_sq_save[1] = 0.0;
|
|
|
13221 |
|
|
|
13222 |
/*************************************************************************
|
|
|
13223 |
* now compute the psychoacoustic model specific constants
|
|
|
13224 |
************************************************************************/
|
|
|
13225 |
/* compute numlines, bo, bm, bval, bval_width, mld */
|
|
|
13226 |
|
|
|
13227 |
gfc.npart_l = init_numline(gfc.numlines_l, gfc.bo_l, gfc.bm_l, bval,
|
|
|
13228 |
bval_width, gfc.mld_l, gfc.PSY.bo_l_weight, sfreq,
|
|
|
13229 |
Encoder.BLKSIZE, gfc.scalefac_band.l, Encoder.BLKSIZE
|
|
|
13230 |
/ (2.0 * 576), Encoder.SBMAX_l);
|
|
|
13231 |
/* compute the spreading function */
|
|
|
13232 |
for (i = 0; i < gfc.npart_l; i++) {
|
|
|
13233 |
var snr = snr_l_a;
|
|
|
13234 |
if (bval[i] >= bvl_a) {
|
|
|
13235 |
snr = snr_l_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_l_a
|
|
|
13236 |
* (bvl_b - bval[i]) / (bvl_b - bvl_a);
|
|
|
13237 |
}
|
|
|
13238 |
norm[i] = Math.pow(10.0, snr / 10.0);
|
|
|
13239 |
if (gfc.numlines_l[i] > 0) {
|
|
|
13240 |
gfc.rnumlines_l[i] = 1.0 / gfc.numlines_l[i];
|
|
|
13241 |
} else {
|
|
|
13242 |
gfc.rnumlines_l[i] = 0;
|
|
|
13243 |
}
|
|
|
13244 |
}
|
|
|
13245 |
gfc.s3_ll = init_s3_values(gfc.s3ind, gfc.npart_l, bval, bval_width,
|
|
|
13246 |
norm, useOldS3);
|
|
|
13247 |
|
|
|
13248 |
/* compute long block specific values, ATH and MINVAL */
|
|
|
13249 |
var j = 0;
|
|
|
13250 |
for (i = 0; i < gfc.npart_l; i++) {
|
|
|
13251 |
var x;
|
|
|
13252 |
|
|
|
13253 |
/* ATH */
|
|
|
13254 |
x = Float.MAX_VALUE;
|
|
|
13255 |
for (var k = 0; k < gfc.numlines_l[i]; k++, j++) {
|
|
|
13256 |
var freq = sfreq * j / (1000.0 * Encoder.BLKSIZE);
|
|
|
13257 |
var level;
|
|
|
13258 |
/*
|
|
|
13259 |
* ATH below 100 Hz constant, not further climbing
|
|
|
13260 |
*/
|
|
|
13261 |
level = this.ATHformula(freq * 1000, gfp) - 20;
|
|
|
13262 |
// scale to FFT units; returned value is in dB
|
|
|
13263 |
level = Math.pow(10., 0.1 * level);
|
|
|
13264 |
// convert from dB . energy
|
|
|
13265 |
level *= gfc.numlines_l[i];
|
|
|
13266 |
if (x > level)
|
|
|
13267 |
x = level;
|
|
|
13268 |
}
|
|
|
13269 |
gfc.ATH.cb_l[i] = x;
|
|
|
13270 |
|
|
|
13271 |
/*
|
|
|
13272 |
* MINVAL. For low freq, the strength of the masking is limited by
|
|
|
13273 |
* minval this is an ISO MPEG1 thing, dont know if it is really
|
|
|
13274 |
* needed
|
|
|
13275 |
*/
|
|
|
13276 |
/*
|
|
|
13277 |
* FIXME: it does work to reduce low-freq problems in S53-Wind-Sax
|
|
|
13278 |
* and lead-voice samples, but introduces some 3 kbps bit bloat too.
|
|
|
13279 |
* TODO: Further refinement of the shape of this hack.
|
|
|
13280 |
*/
|
|
|
13281 |
x = -20 + bval[i] * 20 / 10;
|
|
|
13282 |
if (x > 6) {
|
|
|
13283 |
x = 100;
|
|
|
13284 |
}
|
|
|
13285 |
if (x < -15) {
|
|
|
13286 |
x = -15;
|
|
|
13287 |
}
|
|
|
13288 |
x -= 8.;
|
|
|
13289 |
gfc.minval_l[i] = (Math.pow(10.0, x / 10.) * gfc.numlines_l[i]);
|
|
|
13290 |
}
|
|
|
13291 |
|
|
|
13292 |
/************************************************************************
|
|
|
13293 |
* do the same things for short blocks
|
|
|
13294 |
************************************************************************/
|
|
|
13295 |
gfc.npart_s = init_numline(gfc.numlines_s, gfc.bo_s, gfc.bm_s, bval,
|
|
|
13296 |
bval_width, gfc.mld_s, gfc.PSY.bo_s_weight, sfreq,
|
|
|
13297 |
Encoder.BLKSIZE_s, gfc.scalefac_band.s, Encoder.BLKSIZE_s
|
|
|
13298 |
/ (2.0 * 192), Encoder.SBMAX_s);
|
|
|
13299 |
|
|
|
13300 |
/* SNR formula. short block is normalized by SNR. is it still right ? */
|
|
|
13301 |
j = 0;
|
|
|
13302 |
for (i = 0; i < gfc.npart_s; i++) {
|
|
|
13303 |
var x;
|
|
|
13304 |
var snr = snr_s_a;
|
|
|
13305 |
if (bval[i] >= bvl_a) {
|
|
|
13306 |
snr = snr_s_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_s_a
|
|
|
13307 |
* (bvl_b - bval[i]) / (bvl_b - bvl_a);
|
|
|
13308 |
}
|
|
|
13309 |
norm[i] = Math.pow(10.0, snr / 10.0);
|
|
|
13310 |
|
|
|
13311 |
/* ATH */
|
|
|
13312 |
x = Float.MAX_VALUE;
|
|
|
13313 |
for (var k = 0; k < gfc.numlines_s[i]; k++, j++) {
|
|
|
13314 |
var freq = sfreq * j / (1000.0 * Encoder.BLKSIZE_s);
|
|
|
13315 |
var level;
|
|
|
13316 |
/* freq = Min(.1,freq); */
|
|
|
13317 |
/*
|
|
|
13318 |
* ATH below 100 Hz constant, not
|
|
|
13319 |
* further climbing
|
|
|
13320 |
*/
|
|
|
13321 |
level = this.ATHformula(freq * 1000, gfp) - 20;
|
|
|
13322 |
// scale to FFT units; returned value is in dB
|
|
|
13323 |
level = Math.pow(10., 0.1 * level);
|
|
|
13324 |
// convert from dB . energy
|
|
|
13325 |
level *= gfc.numlines_s[i];
|
|
|
13326 |
if (x > level)
|
|
|
13327 |
x = level;
|
|
|
13328 |
}
|
|
|
13329 |
gfc.ATH.cb_s[i] = x;
|
|
|
13330 |
|
|
|
13331 |
/*
|
|
|
13332 |
* MINVAL. For low freq, the strength of the masking is limited by
|
|
|
13333 |
* minval this is an ISO MPEG1 thing, dont know if it is really
|
|
|
13334 |
* needed
|
|
|
13335 |
*/
|
|
|
13336 |
x = (-7.0 + bval[i] * 7.0 / 12.0);
|
|
|
13337 |
if (bval[i] > 12) {
|
|
|
13338 |
x *= 1 + Math.log(1 + x) * 3.1;
|
|
|
13339 |
}
|
|
|
13340 |
if (bval[i] < 12) {
|
|
|
13341 |
x *= 1 + Math.log(1 - x) * 2.3;
|
|
|
13342 |
}
|
|
|
13343 |
if (x < -15) {
|
|
|
13344 |
x = -15;
|
|
|
13345 |
}
|
|
|
13346 |
x -= 8;
|
|
|
13347 |
gfc.minval_s[i] = Math.pow(10.0, x / 10)
|
|
|
13348 |
* gfc.numlines_s[i];
|
|
|
13349 |
}
|
|
|
13350 |
|
|
|
13351 |
gfc.s3_ss = init_s3_values(gfc.s3ind_s, gfc.npart_s, bval, bval_width,
|
|
|
13352 |
norm, useOldS3);
|
|
|
13353 |
|
|
|
13354 |
init_mask_add_max_values();
|
|
|
13355 |
fft.init_fft(gfc);
|
|
|
13356 |
|
|
|
13357 |
/* setup temporal masking */
|
|
|
13358 |
gfc.decay = Math.exp(-1.0 * LOG10
|
|
|
13359 |
/ (temporalmask_sustain_sec * sfreq / 192.0));
|
|
|
13360 |
|
|
|
13361 |
{
|
|
|
13362 |
var msfix;
|
|
|
13363 |
msfix = NS_MSFIX;
|
|
|
13364 |
if ((gfp.exp_nspsytune & 2) != 0)
|
|
|
13365 |
msfix = 1.0;
|
|
|
13366 |
if (Math.abs(gfp.msfix) > 0.0)
|
|
|
13367 |
msfix = gfp.msfix;
|
|
|
13368 |
gfp.msfix = msfix;
|
|
|
13369 |
|
|
|
13370 |
/*
|
|
|
13371 |
* spread only from npart_l bands. Normally, we use the spreading
|
|
|
13372 |
* function to convolve from npart_l down to npart_l bands
|
|
|
13373 |
*/
|
|
|
13374 |
for (var b = 0; b < gfc.npart_l; b++)
|
|
|
13375 |
if (gfc.s3ind[b][1] > gfc.npart_l - 1)
|
|
|
13376 |
gfc.s3ind[b][1] = gfc.npart_l - 1;
|
|
|
13377 |
}
|
|
|
13378 |
|
|
|
13379 |
/*
|
|
|
13380 |
* prepare for ATH auto adjustment: we want to decrease the ATH by 12 dB
|
|
|
13381 |
* per second
|
|
|
13382 |
*/
|
|
|
13383 |
var frame_duration = (576. * gfc.mode_gr / sfreq);
|
|
|
13384 |
gfc.ATH.decay = Math.pow(10., -12. / 10. * frame_duration);
|
|
|
13385 |
gfc.ATH.adjust = 0.01;
|
|
|
13386 |
/* minimum, for leading low loudness */
|
|
|
13387 |
gfc.ATH.adjustLimit = 1.0;
|
|
|
13388 |
/* on lead, allow adjust up to maximum */
|
|
|
13389 |
|
|
|
13390 |
|
|
|
13391 |
if (gfp.ATHtype != -1) {
|
|
|
13392 |
/* compute equal loudness weights (eql_w) */
|
|
|
13393 |
var freq;
|
|
|
13394 |
var freq_inc = gfp.out_samplerate
|
|
|
13395 |
/ (Encoder.BLKSIZE);
|
|
|
13396 |
var eql_balance = 0.0;
|
|
|
13397 |
freq = 0.0;
|
|
|
13398 |
for (i = 0; i < Encoder.BLKSIZE / 2; ++i) {
|
|
|
13399 |
/* convert ATH dB to relative power (not dB) */
|
|
|
13400 |
/* to determine eql_w */
|
|
|
13401 |
freq += freq_inc;
|
|
|
13402 |
gfc.ATH.eql_w[i] = 1. / Math.pow(10, this.ATHformula(freq, gfp) / 10);
|
|
|
13403 |
eql_balance += gfc.ATH.eql_w[i];
|
|
|
13404 |
}
|
|
|
13405 |
eql_balance = 1.0 / eql_balance;
|
|
|
13406 |
for (i = Encoder.BLKSIZE / 2; --i >= 0;) { /* scale weights */
|
|
|
13407 |
gfc.ATH.eql_w[i] *= eql_balance;
|
|
|
13408 |
}
|
|
|
13409 |
}
|
|
|
13410 |
{
|
|
|
13411 |
for (var b = j = 0; b < gfc.npart_s; ++b) {
|
|
|
13412 |
for (i = 0; i < gfc.numlines_s[b]; ++i) {
|
|
|
13413 |
++j;
|
|
|
13414 |
}
|
|
|
13415 |
}
|
|
|
13416 |
for (var b = j = 0; b < gfc.npart_l; ++b) {
|
|
|
13417 |
for (i = 0; i < gfc.numlines_l[b]; ++i) {
|
|
|
13418 |
++j;
|
|
|
13419 |
}
|
|
|
13420 |
}
|
|
|
13421 |
}
|
|
|
13422 |
j = 0;
|
|
|
13423 |
for (i = 0; i < gfc.npart_l; i++) {
|
|
|
13424 |
var freq = sfreq * (j + gfc.numlines_l[i] / 2) / (1.0 * Encoder.BLKSIZE);
|
|
|
13425 |
gfc.mld_cb_l[i] = stereo_demask(freq);
|
|
|
13426 |
j += gfc.numlines_l[i];
|
|
|
13427 |
}
|
|
|
13428 |
for (; i < Encoder.CBANDS; ++i) {
|
|
|
13429 |
gfc.mld_cb_l[i] = 1;
|
|
|
13430 |
}
|
|
|
13431 |
j = 0;
|
|
|
13432 |
for (i = 0; i < gfc.npart_s; i++) {
|
|
|
13433 |
var freq = sfreq * (j + gfc.numlines_s[i] / 2) / (1.0 * Encoder.BLKSIZE_s);
|
|
|
13434 |
gfc.mld_cb_s[i] = stereo_demask(freq);
|
|
|
13435 |
j += gfc.numlines_s[i];
|
|
|
13436 |
}
|
|
|
13437 |
for (; i < Encoder.CBANDS; ++i) {
|
|
|
13438 |
gfc.mld_cb_s[i] = 1;
|
|
|
13439 |
}
|
|
|
13440 |
return 0;
|
|
|
13441 |
}
|
|
|
13442 |
|
|
|
13443 |
/**
|
|
|
13444 |
* Those ATH formulas are returning their minimum value for input = -1
|
|
|
13445 |
*/
|
|
|
13446 |
function ATHformula_GB(f, value) {
|
|
|
13447 |
/**
|
|
|
13448 |
* <PRE>
|
|
|
13449 |
* from Painter & Spanias
|
|
|
13450 |
* modified by Gabriel Bouvigne to better fit the reality
|
|
|
13451 |
* ath = 3.640 * pow(f,-0.8)
|
|
|
13452 |
* - 6.800 * exp(-0.6*pow(f-3.4,2.0))
|
|
|
13453 |
* + 6.000 * exp(-0.15*pow(f-8.7,2.0))
|
|
|
13454 |
* + 0.6* 0.001 * pow(f,4.0);
|
|
|
13455 |
*
|
|
|
13456 |
*
|
|
|
13457 |
* In the past LAME was using the Painter &Spanias formula.
|
|
|
13458 |
* But we had some recurrent problems with HF content.
|
|
|
13459 |
* We measured real ATH values, and found the older formula
|
|
|
13460 |
* to be inaccurate in the higher part. So we made this new
|
|
|
13461 |
* formula and this solved most of HF problematic test cases.
|
|
|
13462 |
* The tradeoff is that in VBR mode it increases a lot the
|
|
|
13463 |
* bitrate.
|
|
|
13464 |
* </PRE>
|
|
|
13465 |
*/
|
|
|
13466 |
|
|
|
13467 |
/*
|
|
|
13468 |
* This curve can be adjusted according to the VBR scale: it adjusts
|
|
|
13469 |
* from something close to Painter & Spanias on V9 up to Bouvigne's
|
|
|
13470 |
* formula for V0. This way the VBR bitrate is more balanced according
|
|
|
13471 |
* to the -V value.
|
|
|
13472 |
*/
|
|
|
13473 |
|
|
|
13474 |
// the following Hack allows to ask for the lowest value
|
|
|
13475 |
if (f < -.3)
|
|
|
13476 |
f = 3410;
|
|
|
13477 |
|
|
|
13478 |
// convert to khz
|
|
|
13479 |
f /= 1000;
|
|
|
13480 |
f = Math.max(0.1, f);
|
|
|
13481 |
var ath = 3.640 * Math.pow(f, -0.8) - 6.800
|
|
|
13482 |
* Math.exp(-0.6 * Math.pow(f - 3.4, 2.0)) + 6.000
|
|
|
13483 |
* Math.exp(-0.15 * Math.pow(f - 8.7, 2.0))
|
|
|
13484 |
+ (0.6 + 0.04 * value) * 0.001 * Math.pow(f, 4.0);
|
|
|
13485 |
return ath;
|
|
|
13486 |
}
|
|
|
13487 |
|
|
|
13488 |
this.ATHformula = function (f, gfp) {
|
|
|
13489 |
var ath;
|
|
|
13490 |
switch (gfp.ATHtype) {
|
|
|
13491 |
case 0:
|
|
|
13492 |
ath = ATHformula_GB(f, 9);
|
|
|
13493 |
break;
|
|
|
13494 |
case 1:
|
|
|
13495 |
// over sensitive, should probably be removed
|
|
|
13496 |
ath = ATHformula_GB(f, -1);
|
|
|
13497 |
break;
|
|
|
13498 |
case 2:
|
|
|
13499 |
ath = ATHformula_GB(f, 0);
|
|
|
13500 |
break;
|
|
|
13501 |
case 3:
|
|
|
13502 |
// modification of GB formula by Roel
|
|
|
13503 |
ath = ATHformula_GB(f, 1) + 6;
|
|
|
13504 |
break;
|
|
|
13505 |
case 4:
|
|
|
13506 |
ath = ATHformula_GB(f, gfp.ATHcurve);
|
|
|
13507 |
break;
|
|
|
13508 |
default:
|
|
|
13509 |
ath = ATHformula_GB(f, 0);
|
|
|
13510 |
break;
|
|
|
13511 |
}
|
|
|
13512 |
return ath;
|
|
|
13513 |
}
|
|
|
13514 |
|
|
|
13515 |
}
|
|
|
13516 |
|
|
|
13517 |
|
|
|
13518 |
|
|
|
13519 |
function Lame() {
|
|
|
13520 |
var self = this;
|
|
|
13521 |
var LAME_MAXALBUMART = (128 * 1024);
|
|
|
13522 |
|
|
|
13523 |
Lame.V9 = 410;
|
|
|
13524 |
Lame.V8 = 420;
|
|
|
13525 |
Lame.V7 = 430;
|
|
|
13526 |
Lame.V6 = 440;
|
|
|
13527 |
Lame.V5 = 450;
|
|
|
13528 |
Lame.V4 = 460;
|
|
|
13529 |
Lame.V3 = 470;
|
|
|
13530 |
Lame.V2 = 480;
|
|
|
13531 |
Lame.V1 = 490;
|
|
|
13532 |
Lame.V0 = 500;
|
|
|
13533 |
|
|
|
13534 |
/* still there for compatibility */
|
|
|
13535 |
|
|
|
13536 |
Lame.R3MIX = 1000;
|
|
|
13537 |
Lame.STANDARD = 1001;
|
|
|
13538 |
Lame.EXTREME = 1002;
|
|
|
13539 |
Lame.INSANE = 1003;
|
|
|
13540 |
Lame.STANDARD_FAST = 1004;
|
|
|
13541 |
Lame.EXTREME_FAST = 1005;
|
|
|
13542 |
Lame.MEDIUM = 1006;
|
|
|
13543 |
Lame.MEDIUM_FAST = 1007;
|
|
|
13544 |
|
|
|
13545 |
/**
|
|
|
13546 |
* maximum size of mp3buffer needed if you encode at most 1152 samples for
|
|
|
13547 |
* each call to lame_encode_buffer. see lame_encode_buffer() below
|
|
|
13548 |
* (LAME_MAXMP3BUFFER is now obsolete)
|
|
|
13549 |
*/
|
|
|
13550 |
var LAME_MAXMP3BUFFER = (16384 + LAME_MAXALBUMART);
|
|
|
13551 |
Lame.LAME_MAXMP3BUFFER = LAME_MAXMP3BUFFER;
|
|
|
13552 |
|
|
|
13553 |
var ga;
|
|
|
13554 |
var bs;
|
|
|
13555 |
var p;
|
|
|
13556 |
var qupvt;
|
|
|
13557 |
var qu;
|
|
|
13558 |
var psy = new PsyModel();
|
|
|
13559 |
var vbr;
|
|
|
13560 |
var ver;
|
|
|
13561 |
var id3;
|
|
|
13562 |
var mpglib;
|
|
|
13563 |
this.enc = new Encoder();
|
|
|
13564 |
|
|
|
13565 |
this.setModules = function (_ga, _bs, _p, _qupvt, _qu, _vbr, _ver, _id3, _mpglib) {
|
|
|
13566 |
ga = _ga;
|
|
|
13567 |
bs = _bs;
|
|
|
13568 |
p = _p;
|
|
|
13569 |
qupvt = _qupvt;
|
|
|
13570 |
qu = _qu;
|
|
|
13571 |
vbr = _vbr;
|
|
|
13572 |
ver = _ver;
|
|
|
13573 |
id3 = _id3;
|
|
|
13574 |
mpglib = _mpglib;
|
|
|
13575 |
this.enc.setModules(bs, psy, qupvt, vbr);
|
|
|
13576 |
}
|
|
|
13577 |
|
|
|
13578 |
/**
|
|
|
13579 |
* PSY Model related stuff
|
|
|
13580 |
*/
|
|
|
13581 |
function PSY() {
|
|
|
13582 |
/**
|
|
|
13583 |
* The dbQ stuff.
|
|
|
13584 |
*/
|
|
|
13585 |
this.mask_adjust = 0.;
|
|
|
13586 |
/**
|
|
|
13587 |
* The dbQ stuff.
|
|
|
13588 |
*/
|
|
|
13589 |
this.mask_adjust_short = 0.;
|
|
|
13590 |
/* at transition from one scalefactor band to next */
|
|
|
13591 |
/**
|
|
|
13592 |
* Band weight long scalefactor bands.
|
|
|
13593 |
*/
|
|
|
13594 |
this.bo_l_weight = new_float(Encoder.SBMAX_l);
|
|
|
13595 |
/**
|
|
|
13596 |
* Band weight short scalefactor bands.
|
|
|
13597 |
*/
|
|
|
13598 |
this.bo_s_weight = new_float(Encoder.SBMAX_s);
|
|
|
13599 |
}
|
|
|
13600 |
|
|
|
13601 |
function LowPassHighPass() {
|
|
|
13602 |
this.lowerlimit = 0.;
|
|
|
13603 |
}
|
|
|
13604 |
|
|
|
13605 |
function BandPass(bitrate, lPass) {
|
|
|
13606 |
this.lowpass = lPass;
|
|
|
13607 |
}
|
|
|
13608 |
|
|
|
13609 |
var LAME_ID = 0xFFF88E3B;
|
|
|
13610 |
|
|
|
13611 |
function lame_init_old(gfp) {
|
|
|
13612 |
var gfc;
|
|
|
13613 |
|
|
|
13614 |
gfp.class_id = LAME_ID;
|
|
|
13615 |
|
|
|
13616 |
gfc = gfp.internal_flags = new LameInternalFlags();
|
|
|
13617 |
|
|
|
13618 |
/* Global flags. set defaults here for non-zero values */
|
|
|
13619 |
/* see lame.h for description */
|
|
|
13620 |
/*
|
|
|
13621 |
* set integer values to -1 to mean that LAME will compute the best
|
|
|
13622 |
* value, UNLESS the calling program as set it (and the value is no
|
|
|
13623 |
* longer -1)
|
|
|
13624 |
*/
|
|
|
13625 |
|
|
|
13626 |
gfp.mode = MPEGMode.NOT_SET;
|
|
|
13627 |
gfp.original = 1;
|
|
|
13628 |
gfp.in_samplerate = 44100;
|
|
|
13629 |
gfp.num_channels = 2;
|
|
|
13630 |
gfp.num_samples = -1;
|
|
|
13631 |
|
|
|
13632 |
gfp.bWriteVbrTag = true;
|
|
|
13633 |
gfp.quality = -1;
|
|
|
13634 |
gfp.short_blocks = null;
|
|
|
13635 |
gfc.subblock_gain = -1;
|
|
|
13636 |
|
|
|
13637 |
gfp.lowpassfreq = 0;
|
|
|
13638 |
gfp.highpassfreq = 0;
|
|
|
13639 |
gfp.lowpasswidth = -1;
|
|
|
13640 |
gfp.highpasswidth = -1;
|
|
|
13641 |
|
|
|
13642 |
gfp.VBR = VbrMode.vbr_off;
|
|
|
13643 |
gfp.VBR_q = 4;
|
|
|
13644 |
gfp.ATHcurve = -1;
|
|
|
13645 |
gfp.VBR_mean_bitrate_kbps = 128;
|
|
|
13646 |
gfp.VBR_min_bitrate_kbps = 0;
|
|
|
13647 |
gfp.VBR_max_bitrate_kbps = 0;
|
|
|
13648 |
gfp.VBR_hard_min = 0;
|
|
|
13649 |
gfc.VBR_min_bitrate = 1;
|
|
|
13650 |
/* not 0 ????? */
|
|
|
13651 |
gfc.VBR_max_bitrate = 13;
|
|
|
13652 |
/* not 14 ????? */
|
|
|
13653 |
|
|
|
13654 |
gfp.quant_comp = -1;
|
|
|
13655 |
gfp.quant_comp_short = -1;
|
|
|
13656 |
|
|
|
13657 |
gfp.msfix = -1;
|
|
|
13658 |
|
|
|
13659 |
gfc.resample_ratio = 1;
|
|
|
13660 |
|
|
|
13661 |
gfc.OldValue[0] = 180;
|
|
|
13662 |
gfc.OldValue[1] = 180;
|
|
|
13663 |
gfc.CurrentStep[0] = 4;
|
|
|
13664 |
gfc.CurrentStep[1] = 4;
|
|
|
13665 |
gfc.masking_lower = 1;
|
|
|
13666 |
gfc.nsPsy.attackthre = -1;
|
|
|
13667 |
gfc.nsPsy.attackthre_s = -1;
|
|
|
13668 |
|
|
|
13669 |
gfp.scale = -1;
|
|
|
13670 |
|
|
|
13671 |
gfp.athaa_type = -1;
|
|
|
13672 |
gfp.ATHtype = -1;
|
|
|
13673 |
/* default = -1 = set in lame_init_params */
|
|
|
13674 |
gfp.athaa_loudapprox = -1;
|
|
|
13675 |
/* 1 = flat loudness approx. (total energy) */
|
|
|
13676 |
/* 2 = equal loudness curve */
|
|
|
13677 |
gfp.athaa_sensitivity = 0.0;
|
|
|
13678 |
/* no offset */
|
|
|
13679 |
gfp.useTemporal = null;
|
|
|
13680 |
gfp.interChRatio = -1;
|
|
|
13681 |
|
|
|
13682 |
/*
|
|
|
13683 |
* The reason for int mf_samples_to_encode = ENCDELAY + POSTDELAY;
|
|
|
13684 |
* ENCDELAY = internal encoder delay. And then we have to add
|
|
|
13685 |
* POSTDELAY=288 because of the 50% MDCT overlap. A 576 MDCT granule
|
|
|
13686 |
* decodes to 1152 samples. To synthesize the 576 samples centered under
|
|
|
13687 |
* this granule we need the previous granule for the first 288 samples
|
|
|
13688 |
* (no problem), and the next granule for the next 288 samples (not
|
|
|
13689 |
* possible if this is last granule). So we need to pad with 288 samples
|
|
|
13690 |
* to make sure we can encode the 576 samples we are interested in.
|
|
|
13691 |
*/
|
|
|
13692 |
gfc.mf_samples_to_encode = Encoder.ENCDELAY + Encoder.POSTDELAY;
|
|
|
13693 |
gfp.encoder_padding = 0;
|
|
|
13694 |
gfc.mf_size = Encoder.ENCDELAY - Encoder.MDCTDELAY;
|
|
|
13695 |
/*
|
|
|
13696 |
* we pad input with this many 0's
|
|
|
13697 |
*/
|
|
|
13698 |
|
|
|
13699 |
gfp.findReplayGain = false;
|
|
|
13700 |
gfp.decode_on_the_fly = false;
|
|
|
13701 |
|
|
|
13702 |
gfc.decode_on_the_fly = false;
|
|
|
13703 |
gfc.findReplayGain = false;
|
|
|
13704 |
gfc.findPeakSample = false;
|
|
|
13705 |
|
|
|
13706 |
gfc.RadioGain = 0;
|
|
|
13707 |
gfc.AudiophileGain = 0;
|
|
|
13708 |
gfc.noclipGainChange = 0;
|
|
|
13709 |
gfc.noclipScale = -1.0;
|
|
|
13710 |
|
|
|
13711 |
gfp.preset = 0;
|
|
|
13712 |
|
|
|
13713 |
gfp.write_id3tag_automatic = true;
|
|
|
13714 |
return 0;
|
|
|
13715 |
}
|
|
|
13716 |
|
|
|
13717 |
this.lame_init = function () {
|
|
|
13718 |
var gfp = new LameGlobalFlags();
|
|
|
13719 |
|
|
|
13720 |
var ret = lame_init_old(gfp);
|
|
|
13721 |
if (ret != 0) {
|
|
|
13722 |
return null;
|
|
|
13723 |
}
|
|
|
13724 |
|
|
|
13725 |
gfp.lame_allocated_gfp = 1;
|
|
|
13726 |
return gfp;
|
|
|
13727 |
}
|
|
|
13728 |
|
|
|
13729 |
function filter_coef(x) {
|
|
|
13730 |
if (x > 1.0)
|
|
|
13731 |
return 0.0;
|
|
|
13732 |
if (x <= 0.0)
|
|
|
13733 |
return 1.0;
|
|
|
13734 |
|
|
|
13735 |
return Math.cos(Math.PI / 2 * x);
|
|
|
13736 |
}
|
|
|
13737 |
|
|
|
13738 |
this.nearestBitrateFullIndex = function (bitrate) {
|
|
|
13739 |
/* borrowed from DM abr presets */
|
|
|
13740 |
|
|
|
13741 |
var full_bitrate_table = [8, 16, 24, 32, 40, 48, 56, 64, 80,
|
|
|
13742 |
96, 112, 128, 160, 192, 224, 256, 320];
|
|
|
13743 |
|
|
|
13744 |
var lower_range = 0, lower_range_kbps = 0, upper_range = 0, upper_range_kbps = 0;
|
|
|
13745 |
|
|
|
13746 |
/* We assume specified bitrate will be 320kbps */
|
|
|
13747 |
upper_range_kbps = full_bitrate_table[16];
|
|
|
13748 |
upper_range = 16;
|
|
|
13749 |
lower_range_kbps = full_bitrate_table[16];
|
|
|
13750 |
lower_range = 16;
|
|
|
13751 |
|
|
|
13752 |
/*
|
|
|
13753 |
* Determine which significant bitrates the value specified falls
|
|
|
13754 |
* between, if loop ends without breaking then we were correct above
|
|
|
13755 |
* that the value was 320
|
|
|
13756 |
*/
|
|
|
13757 |
for (var b = 0; b < 16; b++) {
|
|
|
13758 |
if ((Math.max(bitrate, full_bitrate_table[b + 1])) != bitrate) {
|
|
|
13759 |
upper_range_kbps = full_bitrate_table[b + 1];
|
|
|
13760 |
upper_range = b + 1;
|
|
|
13761 |
lower_range_kbps = full_bitrate_table[b];
|
|
|
13762 |
lower_range = (b);
|
|
|
13763 |
break;
|
|
|
13764 |
/* We found upper range */
|
|
|
13765 |
}
|
|
|
13766 |
}
|
|
|
13767 |
|
|
|
13768 |
/* Determine which range the value specified is closer to */
|
|
|
13769 |
if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) {
|
|
|
13770 |
return lower_range;
|
|
|
13771 |
}
|
|
|
13772 |
return upper_range;
|
|
|
13773 |
}
|
|
|
13774 |
|
|
|
13775 |
function optimum_samplefreq(lowpassfreq, input_samplefreq) {
|
|
|
13776 |
/*
|
|
|
13777 |
* Rules:
|
|
|
13778 |
*
|
|
|
13779 |
* - if possible, sfb21 should NOT be used
|
|
|
13780 |
*/
|
|
|
13781 |
var suggested_samplefreq = 44100;
|
|
|
13782 |
|
|
|
13783 |
if (input_samplefreq >= 48000)
|
|
|
13784 |
suggested_samplefreq = 48000;
|
|
|
13785 |
else if (input_samplefreq >= 44100)
|
|
|
13786 |
suggested_samplefreq = 44100;
|
|
|
13787 |
else if (input_samplefreq >= 32000)
|
|
|
13788 |
suggested_samplefreq = 32000;
|
|
|
13789 |
else if (input_samplefreq >= 24000)
|
|
|
13790 |
suggested_samplefreq = 24000;
|
|
|
13791 |
else if (input_samplefreq >= 22050)
|
|
|
13792 |
suggested_samplefreq = 22050;
|
|
|
13793 |
else if (input_samplefreq >= 16000)
|
|
|
13794 |
suggested_samplefreq = 16000;
|
|
|
13795 |
else if (input_samplefreq >= 12000)
|
|
|
13796 |
suggested_samplefreq = 12000;
|
|
|
13797 |
else if (input_samplefreq >= 11025)
|
|
|
13798 |
suggested_samplefreq = 11025;
|
|
|
13799 |
else if (input_samplefreq >= 8000)
|
|
|
13800 |
suggested_samplefreq = 8000;
|
|
|
13801 |
|
|
|
13802 |
if (lowpassfreq == -1)
|
|
|
13803 |
return suggested_samplefreq;
|
|
|
13804 |
|
|
|
13805 |
if (lowpassfreq <= 15960)
|
|
|
13806 |
suggested_samplefreq = 44100;
|
|
|
13807 |
if (lowpassfreq <= 15250)
|
|
|
13808 |
suggested_samplefreq = 32000;
|
|
|
13809 |
if (lowpassfreq <= 11220)
|
|
|
13810 |
suggested_samplefreq = 24000;
|
|
|
13811 |
if (lowpassfreq <= 9970)
|
|
|
13812 |
suggested_samplefreq = 22050;
|
|
|
13813 |
if (lowpassfreq <= 7230)
|
|
|
13814 |
suggested_samplefreq = 16000;
|
|
|
13815 |
if (lowpassfreq <= 5420)
|
|
|
13816 |
suggested_samplefreq = 12000;
|
|
|
13817 |
if (lowpassfreq <= 4510)
|
|
|
13818 |
suggested_samplefreq = 11025;
|
|
|
13819 |
if (lowpassfreq <= 3970)
|
|
|
13820 |
suggested_samplefreq = 8000;
|
|
|
13821 |
|
|
|
13822 |
if (input_samplefreq < suggested_samplefreq) {
|
|
|
13823 |
/*
|
|
|
13824 |
* choose a valid MPEG sample frequency above the input sample
|
|
|
13825 |
* frequency to avoid SFB21/12 bitrate bloat rh 061115
|
|
|
13826 |
*/
|
|
|
13827 |
if (input_samplefreq > 44100) {
|
|
|
13828 |
return 48000;
|
|
|
13829 |
}
|
|
|
13830 |
if (input_samplefreq > 32000) {
|
|
|
13831 |
return 44100;
|
|
|
13832 |
}
|
|
|
13833 |
if (input_samplefreq > 24000) {
|
|
|
13834 |
return 32000;
|
|
|
13835 |
}
|
|
|
13836 |
if (input_samplefreq > 22050) {
|
|
|
13837 |
return 24000;
|
|
|
13838 |
}
|
|
|
13839 |
if (input_samplefreq > 16000) {
|
|
|
13840 |
return 22050;
|
|
|
13841 |
}
|
|
|
13842 |
if (input_samplefreq > 12000) {
|
|
|
13843 |
return 16000;
|
|
|
13844 |
}
|
|
|
13845 |
if (input_samplefreq > 11025) {
|
|
|
13846 |
return 12000;
|
|
|
13847 |
}
|
|
|
13848 |
if (input_samplefreq > 8000) {
|
|
|
13849 |
return 11025;
|
|
|
13850 |
}
|
|
|
13851 |
return 8000;
|
|
|
13852 |
}
|
|
|
13853 |
return suggested_samplefreq;
|
|
|
13854 |
}
|
|
|
13855 |
|
|
|
13856 |
/**
|
|
|
13857 |
* convert samp freq in Hz to index
|
|
|
13858 |
*/
|
|
|
13859 |
function SmpFrqIndex(sample_freq, gpf) {
|
|
|
13860 |
switch (sample_freq) {
|
|
|
13861 |
case 44100:
|
|
|
13862 |
gpf.version = 1;
|
|
|
13863 |
return 0;
|
|
|
13864 |
case 48000:
|
|
|
13865 |
gpf.version = 1;
|
|
|
13866 |
return 1;
|
|
|
13867 |
case 32000:
|
|
|
13868 |
gpf.version = 1;
|
|
|
13869 |
return 2;
|
|
|
13870 |
case 22050:
|
|
|
13871 |
gpf.version = 0;
|
|
|
13872 |
return 0;
|
|
|
13873 |
case 24000:
|
|
|
13874 |
gpf.version = 0;
|
|
|
13875 |
return 1;
|
|
|
13876 |
case 16000:
|
|
|
13877 |
gpf.version = 0;
|
|
|
13878 |
return 2;
|
|
|
13879 |
case 11025:
|
|
|
13880 |
gpf.version = 0;
|
|
|
13881 |
return 0;
|
|
|
13882 |
case 12000:
|
|
|
13883 |
gpf.version = 0;
|
|
|
13884 |
return 1;
|
|
|
13885 |
case 8000:
|
|
|
13886 |
gpf.version = 0;
|
|
|
13887 |
return 2;
|
|
|
13888 |
default:
|
|
|
13889 |
gpf.version = 0;
|
|
|
13890 |
return -1;
|
|
|
13891 |
}
|
|
|
13892 |
}
|
|
|
13893 |
|
|
|
13894 |
/**
|
|
|
13895 |
* @param bRate
|
|
|
13896 |
* legal rates from 8 to 320
|
|
|
13897 |
*/
|
|
|
13898 |
function FindNearestBitrate(bRate, version, samplerate) {
|
|
|
13899 |
/* MPEG-1 or MPEG-2 LSF */
|
|
|
13900 |
if (samplerate < 16000)
|
|
|
13901 |
version = 2;
|
|
|
13902 |
|
|
|
13903 |
var bitrate = Tables.bitrate_table[version][1];
|
|
|
13904 |
|
|
|
13905 |
for (var i = 2; i <= 14; i++) {
|
|
|
13906 |
if (Tables.bitrate_table[version][i] > 0) {
|
|
|
13907 |
if (Math.abs(Tables.bitrate_table[version][i] - bRate) < Math
|
|
|
13908 |
.abs(bitrate - bRate))
|
|
|
13909 |
bitrate = Tables.bitrate_table[version][i];
|
|
|
13910 |
}
|
|
|
13911 |
}
|
|
|
13912 |
return bitrate;
|
|
|
13913 |
}
|
|
|
13914 |
|
|
|
13915 |
/**
|
|
|
13916 |
* @param bRate
|
|
|
13917 |
* legal rates from 32 to 448 kbps
|
|
|
13918 |
* @param version
|
|
|
13919 |
* MPEG-1 or MPEG-2/2.5 LSF
|
|
|
13920 |
*/
|
|
|
13921 |
function BitrateIndex(bRate, version, samplerate) {
|
|
|
13922 |
/* convert bitrate in kbps to index */
|
|
|
13923 |
if (samplerate < 16000)
|
|
|
13924 |
version = 2;
|
|
|
13925 |
for (var i = 0; i <= 14; i++) {
|
|
|
13926 |
if (Tables.bitrate_table[version][i] > 0) {
|
|
|
13927 |
if (Tables.bitrate_table[version][i] == bRate) {
|
|
|
13928 |
return i;
|
|
|
13929 |
}
|
|
|
13930 |
}
|
|
|
13931 |
}
|
|
|
13932 |
return -1;
|
|
|
13933 |
}
|
|
|
13934 |
|
|
|
13935 |
function optimum_bandwidth(lh, bitrate) {
|
|
|
13936 |
/**
|
|
|
13937 |
* <PRE>
|
|
|
13938 |
* Input:
|
|
|
13939 |
* bitrate total bitrate in kbps
|
|
|
13940 |
*
|
|
|
13941 |
* Output:
|
|
|
13942 |
* lowerlimit: best lowpass frequency limit for input filter in Hz
|
|
|
13943 |
* upperlimit: best highpass frequency limit for input filter in Hz
|
|
|
13944 |
* </PRE>
|
|
|
13945 |
*/
|
|
|
13946 |
var freq_map = [new BandPass(8, 2000),
|
|
|
13947 |
new BandPass(16, 3700), new BandPass(24, 3900),
|
|
|
13948 |
new BandPass(32, 5500), new BandPass(40, 7000),
|
|
|
13949 |
new BandPass(48, 7500), new BandPass(56, 10000),
|
|
|
13950 |
new BandPass(64, 11000), new BandPass(80, 13500),
|
|
|
13951 |
new BandPass(96, 15100), new BandPass(112, 15600),
|
|
|
13952 |
new BandPass(128, 17000), new BandPass(160, 17500),
|
|
|
13953 |
new BandPass(192, 18600), new BandPass(224, 19400),
|
|
|
13954 |
new BandPass(256, 19700), new BandPass(320, 20500)];
|
|
|
13955 |
|
|
|
13956 |
var table_index = self.nearestBitrateFullIndex(bitrate);
|
|
|
13957 |
lh.lowerlimit = freq_map[table_index].lowpass;
|
|
|
13958 |
}
|
|
|
13959 |
|
|
|
13960 |
function lame_init_params_ppflt(gfp) {
|
|
|
13961 |
var gfc = gfp.internal_flags;
|
|
|
13962 |
/***************************************************************/
|
|
|
13963 |
/* compute info needed for polyphase filter (filter type==0, default) */
|
|
|
13964 |
/***************************************************************/
|
|
|
13965 |
|
|
|
13966 |
var lowpass_band = 32;
|
|
|
13967 |
var highpass_band = -1;
|
|
|
13968 |
|
|
|
13969 |
if (gfc.lowpass1 > 0) {
|
|
|
13970 |
var minband = 999;
|
|
|
13971 |
for (var band = 0; band <= 31; band++) {
|
|
|
13972 |
var freq = (band / 31.0);
|
|
|
13973 |
/* this band and above will be zeroed: */
|
|
|
13974 |
if (freq >= gfc.lowpass2) {
|
|
|
13975 |
lowpass_band = Math.min(lowpass_band, band);
|
|
|
13976 |
}
|
|
|
13977 |
if (gfc.lowpass1 < freq && freq < gfc.lowpass2) {
|
|
|
13978 |
minband = Math.min(minband, band);
|
|
|
13979 |
}
|
|
|
13980 |
}
|
|
|
13981 |
|
|
|
13982 |
/*
|
|
|
13983 |
* compute the *actual* transition band implemented by the polyphase
|
|
|
13984 |
* filter
|
|
|
13985 |
*/
|
|
|
13986 |
if (minband == 999) {
|
|
|
13987 |
gfc.lowpass1 = (lowpass_band - .75) / 31.0;
|
|
|
13988 |
} else {
|
|
|
13989 |
gfc.lowpass1 = (minband - .75) / 31.0;
|
|
|
13990 |
}
|
|
|
13991 |
gfc.lowpass2 = lowpass_band / 31.0;
|
|
|
13992 |
}
|
|
|
13993 |
|
|
|
13994 |
/*
|
|
|
13995 |
* make sure highpass filter is within 90% of what the effective
|
|
|
13996 |
* highpass frequency will be
|
|
|
13997 |
*/
|
|
|
13998 |
if (gfc.highpass2 > 0) {
|
|
|
13999 |
if (gfc.highpass2 < .9 * (.75 / 31.0)) {
|
|
|
14000 |
gfc.highpass1 = 0;
|
|
|
14001 |
gfc.highpass2 = 0;
|
|
|
14002 |
System.err.println("Warning: highpass filter disabled. "
|
|
|
14003 |
+ "highpass frequency too small\n");
|
|
|
14004 |
}
|
|
|
14005 |
}
|
|
|
14006 |
|
|
|
14007 |
if (gfc.highpass2 > 0) {
|
|
|
14008 |
var maxband = -1;
|
|
|
14009 |
for (var band = 0; band <= 31; band++) {
|
|
|
14010 |
var freq = band / 31.0;
|
|
|
14011 |
/* this band and below will be zereod */
|
|
|
14012 |
if (freq <= gfc.highpass1) {
|
|
|
14013 |
highpass_band = Math.max(highpass_band, band);
|
|
|
14014 |
}
|
|
|
14015 |
if (gfc.highpass1 < freq && freq < gfc.highpass2) {
|
|
|
14016 |
maxband = Math.max(maxband, band);
|
|
|
14017 |
}
|
|
|
14018 |
}
|
|
|
14019 |
/*
|
|
|
14020 |
* compute the *actual* transition band implemented by the polyphase
|
|
|
14021 |
* filter
|
|
|
14022 |
*/
|
|
|
14023 |
gfc.highpass1 = highpass_band / 31.0;
|
|
|
14024 |
if (maxband == -1) {
|
|
|
14025 |
gfc.highpass2 = (highpass_band + .75) / 31.0;
|
|
|
14026 |
} else {
|
|
|
14027 |
gfc.highpass2 = (maxband + .75) / 31.0;
|
|
|
14028 |
}
|
|
|
14029 |
}
|
|
|
14030 |
|
|
|
14031 |
for (var band = 0; band < 32; band++) {
|
|
|
14032 |
var fc1, fc2;
|
|
|
14033 |
var freq = band / 31.0;
|
|
|
14034 |
if (gfc.highpass2 > gfc.highpass1) {
|
|
|
14035 |
fc1 = filter_coef((gfc.highpass2 - freq)
|
|
|
14036 |
/ (gfc.highpass2 - gfc.highpass1 + 1e-20));
|
|
|
14037 |
} else {
|
|
|
14038 |
fc1 = 1.0;
|
|
|
14039 |
}
|
|
|
14040 |
if (gfc.lowpass2 > gfc.lowpass1) {
|
|
|
14041 |
fc2 = filter_coef((freq - gfc.lowpass1)
|
|
|
14042 |
/ (gfc.lowpass2 - gfc.lowpass1 + 1e-20));
|
|
|
14043 |
} else {
|
|
|
14044 |
fc2 = 1.0;
|
|
|
14045 |
}
|
|
|
14046 |
gfc.amp_filter[band] = (fc1 * fc2);
|
|
|
14047 |
}
|
|
|
14048 |
}
|
|
|
14049 |
|
|
|
14050 |
function lame_init_qval(gfp) {
|
|
|
14051 |
var gfc = gfp.internal_flags;
|
|
|
14052 |
|
|
|
14053 |
switch (gfp.quality) {
|
|
|
14054 |
default:
|
|
|
14055 |
case 9: /* no psymodel, no noise shaping */
|
|
|
14056 |
gfc.psymodel = 0;
|
|
|
14057 |
gfc.noise_shaping = 0;
|
|
|
14058 |
gfc.noise_shaping_amp = 0;
|
|
|
14059 |
gfc.noise_shaping_stop = 0;
|
|
|
14060 |
gfc.use_best_huffman = 0;
|
|
|
14061 |
gfc.full_outer_loop = 0;
|
|
|
14062 |
break;
|
|
|
14063 |
|
|
|
14064 |
case 8:
|
|
|
14065 |
gfp.quality = 7;
|
|
|
14066 |
//$FALL-THROUGH$
|
|
|
14067 |
case 7:
|
|
|
14068 |
/*
|
|
|
14069 |
* use psymodel (for short block and m/s switching), but no noise
|
|
|
14070 |
* shapping
|
|
|
14071 |
*/
|
|
|
14072 |
gfc.psymodel = 1;
|
|
|
14073 |
gfc.noise_shaping = 0;
|
|
|
14074 |
gfc.noise_shaping_amp = 0;
|
|
|
14075 |
gfc.noise_shaping_stop = 0;
|
|
|
14076 |
gfc.use_best_huffman = 0;
|
|
|
14077 |
gfc.full_outer_loop = 0;
|
|
|
14078 |
break;
|
|
|
14079 |
|
|
|
14080 |
case 6:
|
|
|
14081 |
gfc.psymodel = 1;
|
|
|
14082 |
if (gfc.noise_shaping == 0)
|
|
|
14083 |
gfc.noise_shaping = 1;
|
|
|
14084 |
gfc.noise_shaping_amp = 0;
|
|
|
14085 |
gfc.noise_shaping_stop = 0;
|
|
|
14086 |
if (gfc.subblock_gain == -1)
|
|
|
14087 |
gfc.subblock_gain = 1;
|
|
|
14088 |
gfc.use_best_huffman = 0;
|
|
|
14089 |
gfc.full_outer_loop = 0;
|
|
|
14090 |
break;
|
|
|
14091 |
|
|
|
14092 |
case 5:
|
|
|
14093 |
gfc.psymodel = 1;
|
|
|
14094 |
if (gfc.noise_shaping == 0)
|
|
|
14095 |
gfc.noise_shaping = 1;
|
|
|
14096 |
gfc.noise_shaping_amp = 0;
|
|
|
14097 |
gfc.noise_shaping_stop = 0;
|
|
|
14098 |
if (gfc.subblock_gain == -1)
|
|
|
14099 |
gfc.subblock_gain = 1;
|
|
|
14100 |
gfc.use_best_huffman = 0;
|
|
|
14101 |
gfc.full_outer_loop = 0;
|
|
|
14102 |
break;
|
|
|
14103 |
|
|
|
14104 |
case 4:
|
|
|
14105 |
gfc.psymodel = 1;
|
|
|
14106 |
if (gfc.noise_shaping == 0)
|
|
|
14107 |
gfc.noise_shaping = 1;
|
|
|
14108 |
gfc.noise_shaping_amp = 0;
|
|
|
14109 |
gfc.noise_shaping_stop = 0;
|
|
|
14110 |
if (gfc.subblock_gain == -1)
|
|
|
14111 |
gfc.subblock_gain = 1;
|
|
|
14112 |
gfc.use_best_huffman = 1;
|
|
|
14113 |
gfc.full_outer_loop = 0;
|
|
|
14114 |
break;
|
|
|
14115 |
|
|
|
14116 |
case 3:
|
|
|
14117 |
gfc.psymodel = 1;
|
|
|
14118 |
if (gfc.noise_shaping == 0)
|
|
|
14119 |
gfc.noise_shaping = 1;
|
|
|
14120 |
gfc.noise_shaping_amp = 1;
|
|
|
14121 |
gfc.noise_shaping_stop = 1;
|
|
|
14122 |
if (gfc.subblock_gain == -1)
|
|
|
14123 |
gfc.subblock_gain = 1;
|
|
|
14124 |
gfc.use_best_huffman = 1;
|
|
|
14125 |
gfc.full_outer_loop = 0;
|
|
|
14126 |
break;
|
|
|
14127 |
|
|
|
14128 |
case 2:
|
|
|
14129 |
gfc.psymodel = 1;
|
|
|
14130 |
if (gfc.noise_shaping == 0)
|
|
|
14131 |
gfc.noise_shaping = 1;
|
|
|
14132 |
if (gfc.substep_shaping == 0)
|
|
|
14133 |
gfc.substep_shaping = 2;
|
|
|
14134 |
gfc.noise_shaping_amp = 1;
|
|
|
14135 |
gfc.noise_shaping_stop = 1;
|
|
|
14136 |
if (gfc.subblock_gain == -1)
|
|
|
14137 |
gfc.subblock_gain = 1;
|
|
|
14138 |
gfc.use_best_huffman = 1;
|
|
|
14139 |
/* inner loop */
|
|
|
14140 |
gfc.full_outer_loop = 0;
|
|
|
14141 |
break;
|
|
|
14142 |
|
|
|
14143 |
case 1:
|
|
|
14144 |
gfc.psymodel = 1;
|
|
|
14145 |
if (gfc.noise_shaping == 0)
|
|
|
14146 |
gfc.noise_shaping = 1;
|
|
|
14147 |
if (gfc.substep_shaping == 0)
|
|
|
14148 |
gfc.substep_shaping = 2;
|
|
|
14149 |
gfc.noise_shaping_amp = 2;
|
|
|
14150 |
gfc.noise_shaping_stop = 1;
|
|
|
14151 |
if (gfc.subblock_gain == -1)
|
|
|
14152 |
gfc.subblock_gain = 1;
|
|
|
14153 |
gfc.use_best_huffman = 1;
|
|
|
14154 |
gfc.full_outer_loop = 0;
|
|
|
14155 |
break;
|
|
|
14156 |
|
|
|
14157 |
case 0:
|
|
|
14158 |
gfc.psymodel = 1;
|
|
|
14159 |
if (gfc.noise_shaping == 0)
|
|
|
14160 |
gfc.noise_shaping = 1;
|
|
|
14161 |
if (gfc.substep_shaping == 0)
|
|
|
14162 |
gfc.substep_shaping = 2;
|
|
|
14163 |
gfc.noise_shaping_amp = 2;
|
|
|
14164 |
gfc.noise_shaping_stop = 1;
|
|
|
14165 |
if (gfc.subblock_gain == -1)
|
|
|
14166 |
gfc.subblock_gain = 1;
|
|
|
14167 |
gfc.use_best_huffman = 1;
|
|
|
14168 |
/*
|
|
|
14169 |
* type 2 disabled because of it slowness, in favor of full outer
|
|
|
14170 |
* loop search
|
|
|
14171 |
*/
|
|
|
14172 |
gfc.full_outer_loop = 0;
|
|
|
14173 |
/*
|
|
|
14174 |
* full outer loop search disabled because of audible distortions it
|
|
|
14175 |
* may generate rh 060629
|
|
|
14176 |
*/
|
|
|
14177 |
break;
|
|
|
14178 |
}
|
|
|
14179 |
|
|
|
14180 |
}
|
|
|
14181 |
|
|
|
14182 |
function lame_init_bitstream(gfp) {
|
|
|
14183 |
var gfc = gfp.internal_flags;
|
|
|
14184 |
gfp.frameNum = 0;
|
|
|
14185 |
|
|
|
14186 |
if (gfp.write_id3tag_automatic) {
|
|
|
14187 |
id3.id3tag_write_v2(gfp);
|
|
|
14188 |
}
|
|
|
14189 |
/* initialize histogram data optionally used by frontend */
|
|
|
14190 |
|
|
|
14191 |
gfc.bitrate_stereoMode_Hist = new_int_n([16, 4 + 1]);
|
|
|
14192 |
gfc.bitrate_blockType_Hist = new_int_n([16, 4 + 1 + 1]);
|
|
|
14193 |
|
|
|
14194 |
gfc.PeakSample = 0.0;
|
|
|
14195 |
|
|
|
14196 |
/* Write initial VBR Header to bitstream and init VBR data */
|
|
|
14197 |
if (gfp.bWriteVbrTag)
|
|
|
14198 |
vbr.InitVbrTag(gfp);
|
|
|
14199 |
}
|
|
|
14200 |
|
|
|
14201 |
/********************************************************************
|
|
|
14202 |
* initialize internal params based on data in gf (globalflags struct filled
|
|
|
14203 |
* in by calling program)
|
|
|
14204 |
*
|
|
|
14205 |
* OUTLINE:
|
|
|
14206 |
*
|
|
|
14207 |
* We first have some complex code to determine bitrate, output samplerate
|
|
|
14208 |
* and mode. It is complicated by the fact that we allow the user to set
|
|
|
14209 |
* some or all of these parameters, and need to determine best possible
|
|
|
14210 |
* values for the rest of them:
|
|
|
14211 |
*
|
|
|
14212 |
* 1. set some CPU related flags 2. check if we are mono.mono, stereo.mono
|
|
|
14213 |
* or stereo.stereo 3. compute bitrate and output samplerate: user may have
|
|
|
14214 |
* set compression ratio user may have set a bitrate user may have set a
|
|
|
14215 |
* output samplerate 4. set some options which depend on output samplerate
|
|
|
14216 |
* 5. compute the actual compression ratio 6. set mode based on compression
|
|
|
14217 |
* ratio
|
|
|
14218 |
*
|
|
|
14219 |
* The remaining code is much simpler - it just sets options based on the
|
|
|
14220 |
* mode & compression ratio:
|
|
|
14221 |
*
|
|
|
14222 |
* set allow_diff_short based on mode select lowpass filter based on
|
|
|
14223 |
* compression ratio & mode set the bitrate index, and min/max bitrates for
|
|
|
14224 |
* VBR modes disable VBR tag if it is not appropriate initialize the
|
|
|
14225 |
* bitstream initialize scalefac_band data set sideinfo_len (based on
|
|
|
14226 |
* channels, CRC, out_samplerate) write an id3v2 tag into the bitstream
|
|
|
14227 |
* write VBR tag into the bitstream set mpeg1/2 flag estimate the number of
|
|
|
14228 |
* frames (based on a lot of data)
|
|
|
14229 |
*
|
|
|
14230 |
* now we set more flags: nspsytune: see code VBR modes see code CBR/ABR see
|
|
|
14231 |
* code
|
|
|
14232 |
*
|
|
|
14233 |
* Finally, we set the algorithm flags based on the gfp.quality value
|
|
|
14234 |
* lame_init_qval(gfp);
|
|
|
14235 |
*
|
|
|
14236 |
********************************************************************/
|
|
|
14237 |
this.lame_init_params = function (gfp) {
|
|
|
14238 |
var gfc = gfp.internal_flags;
|
|
|
14239 |
|
|
|
14240 |
gfc.Class_ID = 0;
|
|
|
14241 |
if (gfc.ATH == null)
|
|
|
14242 |
gfc.ATH = new ATH();
|
|
|
14243 |
if (gfc.PSY == null)
|
|
|
14244 |
gfc.PSY = new PSY();
|
|
|
14245 |
if (gfc.rgdata == null)
|
|
|
14246 |
gfc.rgdata = new ReplayGain();
|
|
|
14247 |
|
|
|
14248 |
gfc.channels_in = gfp.num_channels;
|
|
|
14249 |
if (gfc.channels_in == 1)
|
|
|
14250 |
gfp.mode = MPEGMode.MONO;
|
|
|
14251 |
gfc.channels_out = (gfp.mode == MPEGMode.MONO) ? 1 : 2;
|
|
|
14252 |
gfc.mode_ext = Encoder.MPG_MD_MS_LR;
|
|
|
14253 |
if (gfp.mode == MPEGMode.MONO)
|
|
|
14254 |
gfp.force_ms = false;
|
|
|
14255 |
/*
|
|
|
14256 |
* don't allow forced mid/side stereo for mono output
|
|
|
14257 |
*/
|
|
|
14258 |
|
|
|
14259 |
if (gfp.VBR == VbrMode.vbr_off && gfp.VBR_mean_bitrate_kbps != 128
|
|
|
14260 |
&& gfp.brate == 0)
|
|
|
14261 |
gfp.brate = gfp.VBR_mean_bitrate_kbps;
|
|
|
14262 |
|
|
|
14263 |
if (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_mtrh
|
|
|
14264 |
|| gfp.VBR == VbrMode.vbr_mt) {
|
|
|
14265 |
/* these modes can handle free format condition */
|
|
|
14266 |
} else {
|
|
|
14267 |
gfp.free_format = false;
|
|
|
14268 |
/* mode can't be mixed with free format */
|
|
|
14269 |
}
|
|
|
14270 |
|
|
|
14271 |
if (gfp.VBR == VbrMode.vbr_off && gfp.brate == 0) {
|
|
|
14272 |
/* no bitrate or compression ratio specified, use 11.025 */
|
|
|
14273 |
if (BitStream.EQ(gfp.compression_ratio, 0))
|
|
|
14274 |
gfp.compression_ratio = 11.025;
|
|
|
14275 |
/*
|
|
|
14276 |
* rate to compress a CD down to exactly 128000 bps
|
|
|
14277 |
*/
|
|
|
14278 |
}
|
|
|
14279 |
|
|
|
14280 |
/* find bitrate if user specify a compression ratio */
|
|
|
14281 |
if (gfp.VBR == VbrMode.vbr_off && gfp.compression_ratio > 0) {
|
|
|
14282 |
|
|
|
14283 |
if (gfp.out_samplerate == 0)
|
|
|
14284 |
gfp.out_samplerate = map2MP3Frequency((int)(0.97 * gfp.in_samplerate));
|
|
|
14285 |
/*
|
|
|
14286 |
* round up with a margin of 3 %
|
|
|
14287 |
*/
|
|
|
14288 |
|
|
|
14289 |
/*
|
|
|
14290 |
* choose a bitrate for the output samplerate which achieves
|
|
|
14291 |
* specified compression ratio
|
|
|
14292 |
*/
|
|
|
14293 |
gfp.brate = 0 | (gfp.out_samplerate * 16 * gfc.channels_out / (1.e3 * gfp.compression_ratio));
|
|
|
14294 |
|
|
|
14295 |
/* we need the version for the bitrate table look up */
|
|
|
14296 |
gfc.samplerate_index = SmpFrqIndex(gfp.out_samplerate, gfp);
|
|
|
14297 |
|
|
|
14298 |
if (!gfp.free_format) /*
|
|
|
14299 |
* for non Free Format find the nearest allowed
|
|
|
14300 |
* bitrate
|
|
|
14301 |
*/
|
|
|
14302 |
gfp.brate = FindNearestBitrate(gfp.brate, gfp.version,
|
|
|
14303 |
gfp.out_samplerate);
|
|
|
14304 |
}
|
|
|
14305 |
|
|
|
14306 |
if (gfp.out_samplerate != 0) {
|
|
|
14307 |
if (gfp.out_samplerate < 16000) {
|
|
|
14308 |
gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps,
|
|
|
14309 |
8);
|
|
|
14310 |
gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps,
|
|
|
14311 |
64);
|
|
|
14312 |
} else if (gfp.out_samplerate < 32000) {
|
|
|
14313 |
gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps,
|
|
|
14314 |
8);
|
|
|
14315 |
gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps,
|
|
|
14316 |
160);
|
|
|
14317 |
} else {
|
|
|
14318 |
gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps,
|
|
|
14319 |
32);
|
|
|
14320 |
gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps,
|
|
|
14321 |
320);
|
|
|
14322 |
}
|
|
|
14323 |
}
|
|
|
14324 |
|
|
|
14325 |
/****************************************************************/
|
|
|
14326 |
/* if a filter has not been enabled, see if we should add one: */
|
|
|
14327 |
/****************************************************************/
|
|
|
14328 |
if (gfp.lowpassfreq == 0) {
|
|
|
14329 |
var lowpass = 16000.;
|
|
|
14330 |
|
|
|
14331 |
switch (gfp.VBR) {
|
|
|
14332 |
case VbrMode.vbr_off:
|
|
|
14333 |
{
|
|
|
14334 |
var lh = new LowPassHighPass();
|
|
|
14335 |
optimum_bandwidth(lh, gfp.brate);
|
|
|
14336 |
lowpass = lh.lowerlimit;
|
|
|
14337 |
break;
|
|
|
14338 |
}
|
|
|
14339 |
case VbrMode.vbr_abr:
|
|
|
14340 |
{
|
|
|
14341 |
var lh = new LowPassHighPass();
|
|
|
14342 |
optimum_bandwidth(lh, gfp.VBR_mean_bitrate_kbps);
|
|
|
14343 |
lowpass = lh.lowerlimit;
|
|
|
14344 |
break;
|
|
|
14345 |
}
|
|
|
14346 |
case VbrMode.vbr_rh:
|
|
|
14347 |
{
|
|
|
14348 |
var x = [19500, 19000, 18600, 18000, 17500, 16000,
|
|
|
14349 |
15600, 14900, 12500, 10000, 3950];
|
|
|
14350 |
if (0 <= gfp.VBR_q && gfp.VBR_q <= 9) {
|
|
|
14351 |
var a = x[gfp.VBR_q], b = x[gfp.VBR_q + 1], m = gfp.VBR_q_frac;
|
|
|
14352 |
lowpass = linear_int(a, b, m);
|
|
|
14353 |
} else {
|
|
|
14354 |
lowpass = 19500;
|
|
|
14355 |
}
|
|
|
14356 |
break;
|
|
|
14357 |
}
|
|
|
14358 |
default:
|
|
|
14359 |
{
|
|
|
14360 |
var x = [19500, 19000, 18500, 18000, 17500, 16500,
|
|
|
14361 |
15500, 14500, 12500, 9500, 3950];
|
|
|
14362 |
if (0 <= gfp.VBR_q && gfp.VBR_q <= 9) {
|
|
|
14363 |
var a = x[gfp.VBR_q], b = x[gfp.VBR_q + 1], m = gfp.VBR_q_frac;
|
|
|
14364 |
lowpass = linear_int(a, b, m);
|
|
|
14365 |
} else {
|
|
|
14366 |
lowpass = 19500;
|
|
|
14367 |
}
|
|
|
14368 |
}
|
|
|
14369 |
}
|
|
|
14370 |
if (gfp.mode == MPEGMode.MONO
|
|
|
14371 |
&& (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_abr))
|
|
|
14372 |
lowpass *= 1.5;
|
|
|
14373 |
|
|
|
14374 |
gfp.lowpassfreq = lowpass | 0;
|
|
|
14375 |
}
|
|
|
14376 |
|
|
|
14377 |
if (gfp.out_samplerate == 0) {
|
|
|
14378 |
if (2 * gfp.lowpassfreq > gfp.in_samplerate) {
|
|
|
14379 |
gfp.lowpassfreq = gfp.in_samplerate / 2;
|
|
|
14380 |
}
|
|
|
14381 |
gfp.out_samplerate = optimum_samplefreq(gfp.lowpassfreq | 0,
|
|
|
14382 |
gfp.in_samplerate);
|
|
|
14383 |
}
|
|
|
14384 |
|
|
|
14385 |
gfp.lowpassfreq = Math.min(20500, gfp.lowpassfreq);
|
|
|
14386 |
gfp.lowpassfreq = Math.min(gfp.out_samplerate / 2, gfp.lowpassfreq);
|
|
|
14387 |
|
|
|
14388 |
if (gfp.VBR == VbrMode.vbr_off) {
|
|
|
14389 |
gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out
|
|
|
14390 |
/ (1.e3 * gfp.brate);
|
|
|
14391 |
}
|
|
|
14392 |
if (gfp.VBR == VbrMode.vbr_abr) {
|
|
|
14393 |
gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out
|
|
|
14394 |
/ (1.e3 * gfp.VBR_mean_bitrate_kbps);
|
|
|
14395 |
}
|
|
|
14396 |
|
|
|
14397 |
/*
|
|
|
14398 |
* do not compute ReplayGain values and do not find the peak sample if
|
|
|
14399 |
* we can't store them
|
|
|
14400 |
*/
|
|
|
14401 |
if (!gfp.bWriteVbrTag) {
|
|
|
14402 |
gfp.findReplayGain = false;
|
|
|
14403 |
gfp.decode_on_the_fly = false;
|
|
|
14404 |
gfc.findPeakSample = false;
|
|
|
14405 |
}
|
|
|
14406 |
gfc.findReplayGain = gfp.findReplayGain;
|
|
|
14407 |
gfc.decode_on_the_fly = gfp.decode_on_the_fly;
|
|
|
14408 |
|
|
|
14409 |
if (gfc.decode_on_the_fly)
|
|
|
14410 |
gfc.findPeakSample = true;
|
|
|
14411 |
|
|
|
14412 |
if (gfc.findReplayGain) {
|
|
|
14413 |
if (ga.InitGainAnalysis(gfc.rgdata, gfp.out_samplerate) == GainAnalysis.INIT_GAIN_ANALYSIS_ERROR) {
|
|
|
14414 |
gfp.internal_flags = null;
|
|
|
14415 |
return -6;
|
|
|
14416 |
}
|
|
|
14417 |
}
|
|
|
14418 |
|
|
|
14419 |
if (gfc.decode_on_the_fly && !gfp.decode_only) {
|
|
|
14420 |
if (gfc.hip != null) {
|
|
|
14421 |
mpglib.hip_decode_exit(gfc.hip);
|
|
|
14422 |
}
|
|
|
14423 |
gfc.hip = mpglib.hip_decode_init();
|
|
|
14424 |
}
|
|
|
14425 |
|
|
|
14426 |
gfc.mode_gr = gfp.out_samplerate <= 24000 ? 1 : 2;
|
|
|
14427 |
/*
|
|
|
14428 |
* Number of granules per frame
|
|
|
14429 |
*/
|
|
|
14430 |
gfp.framesize = 576 * gfc.mode_gr;
|
|
|
14431 |
gfp.encoder_delay = Encoder.ENCDELAY;
|
|
|
14432 |
|
|
|
14433 |
gfc.resample_ratio = gfp.in_samplerate / gfp.out_samplerate;
|
|
|
14434 |
|
|
|
14435 |
/**
|
|
|
14436 |
* <PRE>
|
|
|
14437 |
* sample freq bitrate compression ratio
|
|
|
14438 |
* [kHz] [kbps/channel] for 16 bit input
|
|
|
14439 |
* 44.1 56 12.6
|
|
|
14440 |
* 44.1 64 11.025
|
|
|
14441 |
* 44.1 80 8.82
|
|
|
14442 |
* 22.05 24 14.7
|
|
|
14443 |
* 22.05 32 11.025
|
|
|
14444 |
* 22.05 40 8.82
|
|
|
14445 |
* 16 16 16.0
|
|
|
14446 |
* 16 24 10.667
|
|
|
14447 |
* </PRE>
|
|
|
14448 |
*/
|
|
|
14449 |
/**
|
|
|
14450 |
* <PRE>
|
|
|
14451 |
* For VBR, take a guess at the compression_ratio.
|
|
|
14452 |
* For example:
|
|
|
14453 |
*
|
|
|
14454 |
* VBR_q compression like
|
|
|
14455 |
* - 4.4 320 kbps/44 kHz
|
|
|
14456 |
* 0...1 5.5 256 kbps/44 kHz
|
|
|
14457 |
* 2 7.3 192 kbps/44 kHz
|
|
|
14458 |
* 4 8.8 160 kbps/44 kHz
|
|
|
14459 |
* 6 11 128 kbps/44 kHz
|
|
|
14460 |
* 9 14.7 96 kbps
|
|
|
14461 |
*
|
|
|
14462 |
* for lower bitrates, downsample with --resample
|
|
|
14463 |
* </PRE>
|
|
|
14464 |
*/
|
|
|
14465 |
switch (gfp.VBR) {
|
|
|
14466 |
case VbrMode.vbr_mt:
|
|
|
14467 |
case VbrMode.vbr_rh:
|
|
|
14468 |
case VbrMode.vbr_mtrh:
|
|
|
14469 |
{
|
|
|
14470 |
/* numbers are a bit strange, but they determine the lowpass value */
|
|
|
14471 |
var cmp = [5.7, 6.5, 7.3, 8.2, 10, 11.9, 13, 14,
|
|
|
14472 |
15, 16.5];
|
|
|
14473 |
gfp.compression_ratio = cmp[gfp.VBR_q];
|
|
|
14474 |
}
|
|
|
14475 |
break;
|
|
|
14476 |
case VbrMode.vbr_abr:
|
|
|
14477 |
gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out
|
|
|
14478 |
/ (1.e3 * gfp.VBR_mean_bitrate_kbps);
|
|
|
14479 |
break;
|
|
|
14480 |
default:
|
|
|
14481 |
gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out
|
|
|
14482 |
/ (1.e3 * gfp.brate);
|
|
|
14483 |
break;
|
|
|
14484 |
}
|
|
|
14485 |
|
|
|
14486 |
/*
|
|
|
14487 |
* mode = -1 (not set by user) or mode = MONO (because of only 1 input
|
|
|
14488 |
* channel). If mode has not been set, then select J-STEREO
|
|
|
14489 |
*/
|
|
|
14490 |
if (gfp.mode == MPEGMode.NOT_SET) {
|
|
|
14491 |
gfp.mode = MPEGMode.JOINT_STEREO;
|
|
|
14492 |
}
|
|
|
14493 |
|
|
|
14494 |
/* apply user driven high pass filter */
|
|
|
14495 |
if (gfp.highpassfreq > 0) {
|
|
|
14496 |
gfc.highpass1 = 2. * gfp.highpassfreq;
|
|
|
14497 |
|
|
|
14498 |
if (gfp.highpasswidth >= 0)
|
|
|
14499 |
gfc.highpass2 = 2. * (gfp.highpassfreq + gfp.highpasswidth);
|
|
|
14500 |
else
|
|
|
14501 |
/* 0% above on default */
|
|
|
14502 |
gfc.highpass2 = (1 + 0.00) * 2. * gfp.highpassfreq;
|
|
|
14503 |
|
|
|
14504 |
gfc.highpass1 /= gfp.out_samplerate;
|
|
|
14505 |
gfc.highpass2 /= gfp.out_samplerate;
|
|
|
14506 |
} else {
|
|
|
14507 |
gfc.highpass1 = 0;
|
|
|
14508 |
gfc.highpass2 = 0;
|
|
|
14509 |
}
|
|
|
14510 |
/* apply user driven low pass filter */
|
|
|
14511 |
if (gfp.lowpassfreq > 0) {
|
|
|
14512 |
gfc.lowpass2 = 2. * gfp.lowpassfreq;
|
|
|
14513 |
if (gfp.lowpasswidth >= 0) {
|
|
|
14514 |
gfc.lowpass1 = 2. * (gfp.lowpassfreq - gfp.lowpasswidth);
|
|
|
14515 |
if (gfc.lowpass1 < 0) /* has to be >= 0 */
|
|
|
14516 |
gfc.lowpass1 = 0;
|
|
|
14517 |
} else { /* 0% below on default */
|
|
|
14518 |
gfc.lowpass1 = (1 - 0.00) * 2. * gfp.lowpassfreq;
|
|
|
14519 |
}
|
|
|
14520 |
gfc.lowpass1 /= gfp.out_samplerate;
|
|
|
14521 |
gfc.lowpass2 /= gfp.out_samplerate;
|
|
|
14522 |
} else {
|
|
|
14523 |
gfc.lowpass1 = 0;
|
|
|
14524 |
gfc.lowpass2 = 0;
|
|
|
14525 |
}
|
|
|
14526 |
|
|
|
14527 |
/**********************************************************************/
|
|
|
14528 |
/* compute info needed for polyphase filter (filter type==0, default) */
|
|
|
14529 |
/**********************************************************************/
|
|
|
14530 |
lame_init_params_ppflt(gfp);
|
|
|
14531 |
/*******************************************************
|
|
|
14532 |
* samplerate and bitrate index
|
|
|
14533 |
*******************************************************/
|
|
|
14534 |
gfc.samplerate_index = SmpFrqIndex(gfp.out_samplerate, gfp);
|
|
|
14535 |
if (gfc.samplerate_index < 0) {
|
|
|
14536 |
gfp.internal_flags = null;
|
|
|
14537 |
return -1;
|
|
|
14538 |
}
|
|
|
14539 |
|
|
|
14540 |
if (gfp.VBR == VbrMode.vbr_off) {
|
|
|
14541 |
if (gfp.free_format) {
|
|
|
14542 |
gfc.bitrate_index = 0;
|
|
|
14543 |
} else {
|
|
|
14544 |
gfp.brate = FindNearestBitrate(gfp.brate, gfp.version,
|
|
|
14545 |
gfp.out_samplerate);
|
|
|
14546 |
gfc.bitrate_index = BitrateIndex(gfp.brate, gfp.version,
|
|
|
14547 |
gfp.out_samplerate);
|
|
|
14548 |
if (gfc.bitrate_index <= 0) {
|
|
|
14549 |
gfp.internal_flags = null;
|
|
|
14550 |
return -1;
|
|
|
14551 |
}
|
|
|
14552 |
}
|
|
|
14553 |
} else {
|
|
|
14554 |
gfc.bitrate_index = 1;
|
|
|
14555 |
}
|
|
|
14556 |
|
|
|
14557 |
/* for CBR, we will write an "info" tag. */
|
|
|
14558 |
|
|
|
14559 |
if (gfp.analysis)
|
|
|
14560 |
gfp.bWriteVbrTag = false;
|
|
|
14561 |
|
|
|
14562 |
/* some file options not allowed if output is: not specified or stdout */
|
|
|
14563 |
if (gfc.pinfo != null)
|
|
|
14564 |
gfp.bWriteVbrTag = false;
|
|
|
14565 |
/* disable Xing VBR tag */
|
|
|
14566 |
|
|
|
14567 |
bs.init_bit_stream_w(gfc);
|
|
|
14568 |
|
|
|
14569 |
var j = gfc.samplerate_index + (3 * gfp.version) + 6
|
|
|
14570 |
* (gfp.out_samplerate < 16000 ? 1 : 0);
|
|
|
14571 |
for (var i = 0; i < Encoder.SBMAX_l + 1; i++)
|
|
|
14572 |
gfc.scalefac_band.l[i] = qupvt.sfBandIndex[j].l[i];
|
|
|
14573 |
|
|
|
14574 |
for (var i = 0; i < Encoder.PSFB21 + 1; i++) {
|
|
|
14575 |
var size = (gfc.scalefac_band.l[22] - gfc.scalefac_band.l[21])
|
|
|
14576 |
/ Encoder.PSFB21;
|
|
|
14577 |
var start = gfc.scalefac_band.l[21] + i * size;
|
|
|
14578 |
gfc.scalefac_band.psfb21[i] = start;
|
|
|
14579 |
}
|
|
|
14580 |
gfc.scalefac_band.psfb21[Encoder.PSFB21] = 576;
|
|
|
14581 |
|
|
|
14582 |
for (var i = 0; i < Encoder.SBMAX_s + 1; i++)
|
|
|
14583 |
gfc.scalefac_band.s[i] = qupvt.sfBandIndex[j].s[i];
|
|
|
14584 |
|
|
|
14585 |
for (var i = 0; i < Encoder.PSFB12 + 1; i++) {
|
|
|
14586 |
var size = (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12])
|
|
|
14587 |
/ Encoder.PSFB12;
|
|
|
14588 |
var start = gfc.scalefac_band.s[12] + i * size;
|
|
|
14589 |
gfc.scalefac_band.psfb12[i] = start;
|
|
|
14590 |
}
|
|
|
14591 |
gfc.scalefac_band.psfb12[Encoder.PSFB12] = 192;
|
|
|
14592 |
/* determine the mean bitrate for main data */
|
|
|
14593 |
if (gfp.version == 1) /* MPEG 1 */
|
|
|
14594 |
gfc.sideinfo_len = (gfc.channels_out == 1) ? 4 + 17 : 4 + 32;
|
|
|
14595 |
else
|
|
|
14596 |
/* MPEG 2 */
|
|
|
14597 |
gfc.sideinfo_len = (gfc.channels_out == 1) ? 4 + 9 : 4 + 17;
|
|
|
14598 |
|
|
|
14599 |
if (gfp.error_protection)
|
|
|
14600 |
gfc.sideinfo_len += 2;
|
|
|
14601 |
|
|
|
14602 |
lame_init_bitstream(gfp);
|
|
|
14603 |
|
|
|
14604 |
gfc.Class_ID = LAME_ID;
|
|
|
14605 |
|
|
|
14606 |
{
|
|
|
14607 |
var k;
|
|
|
14608 |
|
|
|
14609 |
for (k = 0; k < 19; k++)
|
|
|
14610 |
gfc.nsPsy.pefirbuf[k] = 700 * gfc.mode_gr * gfc.channels_out;
|
|
|
14611 |
|
|
|
14612 |
if (gfp.ATHtype == -1)
|
|
|
14613 |
gfp.ATHtype = 4;
|
|
|
14614 |
}
|
|
|
14615 |
|
|
|
14616 |
switch (gfp.VBR) {
|
|
|
14617 |
|
|
|
14618 |
case VbrMode.vbr_mt:
|
|
|
14619 |
gfp.VBR = VbrMode.vbr_mtrh;
|
|
|
14620 |
//$FALL-THROUGH$
|
|
|
14621 |
case VbrMode.vbr_mtrh:
|
|
|
14622 |
{
|
|
|
14623 |
if (gfp.useTemporal == null) {
|
|
|
14624 |
gfp.useTemporal = false;
|
|
|
14625 |
/* off by default for this VBR mode */
|
|
|
14626 |
}
|
|
|
14627 |
|
|
|
14628 |
p.apply_preset(gfp, 500 - (gfp.VBR_q * 10), 0);
|
|
|
14629 |
/**
|
|
|
14630 |
* <PRE>
|
|
|
14631 |
* The newer VBR code supports only a limited
|
|
|
14632 |
* subset of quality levels:
|
|
|
14633 |
* 9-5=5 are the same, uses x^3/4 quantization
|
|
|
14634 |
* 4-0=0 are the same 5 plus best huffman divide code
|
|
|
14635 |
* </PRE>
|
|
|
14636 |
*/
|
|
|
14637 |
if (gfp.quality < 0)
|
|
|
14638 |
gfp.quality = LAME_DEFAULT_QUALITY;
|
|
|
14639 |
if (gfp.quality < 5)
|
|
|
14640 |
gfp.quality = 0;
|
|
|
14641 |
if (gfp.quality > 5)
|
|
|
14642 |
gfp.quality = 5;
|
|
|
14643 |
|
|
|
14644 |
gfc.PSY.mask_adjust = gfp.maskingadjust;
|
|
|
14645 |
gfc.PSY.mask_adjust_short = gfp.maskingadjust_short;
|
|
|
14646 |
|
|
|
14647 |
/*
|
|
|
14648 |
* sfb21 extra only with MPEG-1 at higher sampling rates
|
|
|
14649 |
*/
|
|
|
14650 |
if (gfp.experimentalY)
|
|
|
14651 |
gfc.sfb21_extra = false;
|
|
|
14652 |
else
|
|
|
14653 |
gfc.sfb21_extra = (gfp.out_samplerate > 44000);
|
|
|
14654 |
|
|
|
14655 |
gfc.iteration_loop = new VBRNewIterationLoop(qu);
|
|
|
14656 |
break;
|
|
|
14657 |
|
|
|
14658 |
}
|
|
|
14659 |
case VbrMode.vbr_rh:
|
|
|
14660 |
{
|
|
|
14661 |
|
|
|
14662 |
p.apply_preset(gfp, 500 - (gfp.VBR_q * 10), 0);
|
|
|
14663 |
|
|
|
14664 |
gfc.PSY.mask_adjust = gfp.maskingadjust;
|
|
|
14665 |
gfc.PSY.mask_adjust_short = gfp.maskingadjust_short;
|
|
|
14666 |
|
|
|
14667 |
/*
|
|
|
14668 |
* sfb21 extra only with MPEG-1 at higher sampling rates
|
|
|
14669 |
*/
|
|
|
14670 |
if (gfp.experimentalY)
|
|
|
14671 |
gfc.sfb21_extra = false;
|
|
|
14672 |
else
|
|
|
14673 |
gfc.sfb21_extra = (gfp.out_samplerate > 44000);
|
|
|
14674 |
|
|
|
14675 |
/*
|
|
|
14676 |
* VBR needs at least the output of GPSYCHO, so we have to garantee
|
|
|
14677 |
* that by setting a minimum quality level, actually level 6 does
|
|
|
14678 |
* it. down to level 6
|
|
|
14679 |
*/
|
|
|
14680 |
if (gfp.quality > 6)
|
|
|
14681 |
gfp.quality = 6;
|
|
|
14682 |
|
|
|
14683 |
if (gfp.quality < 0)
|
|
|
14684 |
gfp.quality = LAME_DEFAULT_QUALITY;
|
|
|
14685 |
|
|
|
14686 |
gfc.iteration_loop = new VBROldIterationLoop(qu);
|
|
|
14687 |
break;
|
|
|
14688 |
}
|
|
|
14689 |
|
|
|
14690 |
default: /* cbr/abr */
|
|
|
14691 |
{
|
|
|
14692 |
var vbrmode;
|
|
|
14693 |
|
|
|
14694 |
/*
|
|
|
14695 |
* no sfb21 extra with CBR code
|
|
|
14696 |
*/
|
|
|
14697 |
gfc.sfb21_extra = false;
|
|
|
14698 |
|
|
|
14699 |
if (gfp.quality < 0)
|
|
|
14700 |
gfp.quality = LAME_DEFAULT_QUALITY;
|
|
|
14701 |
|
|
|
14702 |
vbrmode = gfp.VBR;
|
|
|
14703 |
if (vbrmode == VbrMode.vbr_off)
|
|
|
14704 |
gfp.VBR_mean_bitrate_kbps = gfp.brate;
|
|
|
14705 |
/* second, set parameters depending on bitrate */
|
|
|
14706 |
p.apply_preset(gfp, gfp.VBR_mean_bitrate_kbps, 0);
|
|
|
14707 |
gfp.VBR = vbrmode;
|
|
|
14708 |
|
|
|
14709 |
gfc.PSY.mask_adjust = gfp.maskingadjust;
|
|
|
14710 |
gfc.PSY.mask_adjust_short = gfp.maskingadjust_short;
|
|
|
14711 |
|
|
|
14712 |
if (vbrmode == VbrMode.vbr_off) {
|
|
|
14713 |
gfc.iteration_loop = new CBRNewIterationLoop(qu);
|
|
|
14714 |
} else {
|
|
|
14715 |
gfc.iteration_loop = new ABRIterationLoop(qu);
|
|
|
14716 |
}
|
|
|
14717 |
break;
|
|
|
14718 |
}
|
|
|
14719 |
}
|
|
|
14720 |
/* initialize default values common for all modes */
|
|
|
14721 |
|
|
|
14722 |
if (gfp.VBR != VbrMode.vbr_off) { /* choose a min/max bitrate for VBR */
|
|
|
14723 |
/* if the user didn't specify VBR_max_bitrate: */
|
|
|
14724 |
gfc.VBR_min_bitrate = 1;
|
|
|
14725 |
/*
|
|
|
14726 |
* default: allow 8 kbps (MPEG-2) or 32 kbps (MPEG-1)
|
|
|
14727 |
*/
|
|
|
14728 |
gfc.VBR_max_bitrate = 14;
|
|
|
14729 |
/*
|
|
|
14730 |
* default: allow 160 kbps (MPEG-2) or 320 kbps (MPEG-1)
|
|
|
14731 |
*/
|
|
|
14732 |
if (gfp.out_samplerate < 16000)
|
|
|
14733 |
gfc.VBR_max_bitrate = 8;
|
|
|
14734 |
/* default: allow 64 kbps (MPEG-2.5) */
|
|
|
14735 |
if (gfp.VBR_min_bitrate_kbps != 0) {
|
|
|
14736 |
gfp.VBR_min_bitrate_kbps = FindNearestBitrate(
|
|
|
14737 |
gfp.VBR_min_bitrate_kbps, gfp.version,
|
|
|
14738 |
gfp.out_samplerate);
|
|
|
14739 |
gfc.VBR_min_bitrate = BitrateIndex(gfp.VBR_min_bitrate_kbps,
|
|
|
14740 |
gfp.version, gfp.out_samplerate);
|
|
|
14741 |
if (gfc.VBR_min_bitrate < 0)
|
|
|
14742 |
return -1;
|
|
|
14743 |
}
|
|
|
14744 |
if (gfp.VBR_max_bitrate_kbps != 0) {
|
|
|
14745 |
gfp.VBR_max_bitrate_kbps = FindNearestBitrate(
|
|
|
14746 |
gfp.VBR_max_bitrate_kbps, gfp.version,
|
|
|
14747 |
gfp.out_samplerate);
|
|
|
14748 |
gfc.VBR_max_bitrate = BitrateIndex(gfp.VBR_max_bitrate_kbps,
|
|
|
14749 |
gfp.version, gfp.out_samplerate);
|
|
|
14750 |
if (gfc.VBR_max_bitrate < 0)
|
|
|
14751 |
return -1;
|
|
|
14752 |
}
|
|
|
14753 |
gfp.VBR_min_bitrate_kbps = Tables.bitrate_table[gfp.version][gfc.VBR_min_bitrate];
|
|
|
14754 |
gfp.VBR_max_bitrate_kbps = Tables.bitrate_table[gfp.version][gfc.VBR_max_bitrate];
|
|
|
14755 |
gfp.VBR_mean_bitrate_kbps = Math.min(
|
|
|
14756 |
Tables.bitrate_table[gfp.version][gfc.VBR_max_bitrate],
|
|
|
14757 |
gfp.VBR_mean_bitrate_kbps);
|
|
|
14758 |
gfp.VBR_mean_bitrate_kbps = Math.max(
|
|
|
14759 |
Tables.bitrate_table[gfp.version][gfc.VBR_min_bitrate],
|
|
|
14760 |
gfp.VBR_mean_bitrate_kbps);
|
|
|
14761 |
}
|
|
|
14762 |
|
|
|
14763 |
/* just another daily changing developer switch */
|
|
|
14764 |
if (gfp.tune) {
|
|
|
14765 |
gfc.PSY.mask_adjust += gfp.tune_value_a;
|
|
|
14766 |
gfc.PSY.mask_adjust_short += gfp.tune_value_a;
|
|
|
14767 |
}
|
|
|
14768 |
|
|
|
14769 |
/* initialize internal qval settings */
|
|
|
14770 |
lame_init_qval(gfp);
|
|
|
14771 |
/*
|
|
|
14772 |
* automatic ATH adjustment on
|
|
|
14773 |
*/
|
|
|
14774 |
if (gfp.athaa_type < 0)
|
|
|
14775 |
gfc.ATH.useAdjust = 3;
|
|
|
14776 |
else
|
|
|
14777 |
gfc.ATH.useAdjust = gfp.athaa_type;
|
|
|
14778 |
|
|
|
14779 |
/* initialize internal adaptive ATH settings -jd */
|
|
|
14780 |
gfc.ATH.aaSensitivityP = Math.pow(10.0, gfp.athaa_sensitivity
|
|
|
14781 |
/ -10.0);
|
|
|
14782 |
|
|
|
14783 |
if (gfp.short_blocks == null) {
|
|
|
14784 |
gfp.short_blocks = ShortBlock.short_block_allowed;
|
|
|
14785 |
}
|
|
|
14786 |
|
|
|
14787 |
/*
|
|
|
14788 |
* Note Jan/2003: Many hardware decoders cannot handle short blocks in
|
|
|
14789 |
* regular stereo mode unless they are coupled (same type in both
|
|
|
14790 |
* channels) it is a rare event (1 frame per min. or so) that LAME would
|
|
|
14791 |
* use uncoupled short blocks, so lets turn them off until we decide how
|
|
|
14792 |
* to handle this. No other encoders allow uncoupled short blocks, even
|
|
|
14793 |
* though it is in the standard.
|
|
|
14794 |
*/
|
|
|
14795 |
/*
|
|
|
14796 |
* rh 20040217: coupling makes no sense for mono and dual-mono streams
|
|
|
14797 |
*/
|
|
|
14798 |
if (gfp.short_blocks == ShortBlock.short_block_allowed
|
|
|
14799 |
&& (gfp.mode == MPEGMode.JOINT_STEREO || gfp.mode == MPEGMode.STEREO)) {
|
|
|
14800 |
gfp.short_blocks = ShortBlock.short_block_coupled;
|
|
|
14801 |
}
|
|
|
14802 |
|
|
|
14803 |
if (gfp.quant_comp < 0)
|
|
|
14804 |
gfp.quant_comp = 1;
|
|
|
14805 |
if (gfp.quant_comp_short < 0)
|
|
|
14806 |
gfp.quant_comp_short = 0;
|
|
|
14807 |
|
|
|
14808 |
if (gfp.msfix < 0)
|
|
|
14809 |
gfp.msfix = 0;
|
|
|
14810 |
|
|
|
14811 |
/* select psychoacoustic model */
|
|
|
14812 |
gfp.exp_nspsytune = gfp.exp_nspsytune | 1;
|
|
|
14813 |
|
|
|
14814 |
if (gfp.internal_flags.nsPsy.attackthre < 0)
|
|
|
14815 |
gfp.internal_flags.nsPsy.attackthre = PsyModel.NSATTACKTHRE;
|
|
|
14816 |
if (gfp.internal_flags.nsPsy.attackthre_s < 0)
|
|
|
14817 |
gfp.internal_flags.nsPsy.attackthre_s = PsyModel.NSATTACKTHRE_S;
|
|
|
14818 |
|
|
|
14819 |
|
|
|
14820 |
if (gfp.scale < 0)
|
|
|
14821 |
gfp.scale = 1;
|
|
|
14822 |
|
|
|
14823 |
if (gfp.ATHtype < 0)
|
|
|
14824 |
gfp.ATHtype = 4;
|
|
|
14825 |
|
|
|
14826 |
if (gfp.ATHcurve < 0)
|
|
|
14827 |
gfp.ATHcurve = 4;
|
|
|
14828 |
|
|
|
14829 |
if (gfp.athaa_loudapprox < 0)
|
|
|
14830 |
gfp.athaa_loudapprox = 2;
|
|
|
14831 |
|
|
|
14832 |
if (gfp.interChRatio < 0)
|
|
|
14833 |
gfp.interChRatio = 0;
|
|
|
14834 |
|
|
|
14835 |
if (gfp.useTemporal == null)
|
|
|
14836 |
gfp.useTemporal = true;
|
|
|
14837 |
/* on by default */
|
|
|
14838 |
|
|
|
14839 |
/*
|
|
|
14840 |
* padding method as described in
|
|
|
14841 |
* "MPEG-Layer3 / Bitstream Syntax and Decoding" by Martin Sieler, Ralph
|
|
|
14842 |
* Sperschneider
|
|
|
14843 |
*
|
|
|
14844 |
* note: there is no padding for the very first frame
|
|
|
14845 |
*
|
|
|
14846 |
* Robert Hegemann 2000-06-22
|
|
|
14847 |
*/
|
|
|
14848 |
gfc.slot_lag = gfc.frac_SpF = 0;
|
|
|
14849 |
if (gfp.VBR == VbrMode.vbr_off)
|
|
|
14850 |
gfc.slot_lag = gfc.frac_SpF = (((gfp.version + 1) * 72000 * gfp.brate) % gfp.out_samplerate) | 0;
|
|
|
14851 |
|
|
|
14852 |
qupvt.iteration_init(gfp);
|
|
|
14853 |
psy.psymodel_init(gfp);
|
|
|
14854 |
return 0;
|
|
|
14855 |
}
|
|
|
14856 |
|
|
|
14857 |
function update_inbuffer_size(gfc, nsamples) {
|
|
|
14858 |
if (gfc.in_buffer_0 == null || gfc.in_buffer_nsamples < nsamples) {
|
|
|
14859 |
gfc.in_buffer_0 = new_float(nsamples);
|
|
|
14860 |
gfc.in_buffer_1 = new_float(nsamples);
|
|
|
14861 |
gfc.in_buffer_nsamples = nsamples;
|
|
|
14862 |
}
|
|
|
14863 |
}
|
|
|
14864 |
|
|
|
14865 |
this.lame_encode_flush = function (gfp, mp3buffer, mp3bufferPos, mp3buffer_size) {
|
|
|
14866 |
var gfc = gfp.internal_flags;
|
|
|
14867 |
var buffer = new_short_n([2, 1152]);
|
|
|
14868 |
var imp3 = 0, mp3count, mp3buffer_size_remaining;
|
|
|
14869 |
|
|
|
14870 |
/*
|
|
|
14871 |
* we always add POSTDELAY=288 padding to make sure granule with real
|
|
|
14872 |
* data can be complety decoded (because of 50% overlap with next
|
|
|
14873 |
* granule
|
|
|
14874 |
*/
|
|
|
14875 |
var end_padding;
|
|
|
14876 |
var frames_left;
|
|
|
14877 |
var samples_to_encode = gfc.mf_samples_to_encode - Encoder.POSTDELAY;
|
|
|
14878 |
var mf_needed = calcNeeded(gfp);
|
|
|
14879 |
|
|
|
14880 |
/* Was flush already called? */
|
|
|
14881 |
if (gfc.mf_samples_to_encode < 1) {
|
|
|
14882 |
return 0;
|
|
|
14883 |
}
|
|
|
14884 |
mp3count = 0;
|
|
|
14885 |
|
|
|
14886 |
if (gfp.in_samplerate != gfp.out_samplerate) {
|
|
|
14887 |
/*
|
|
|
14888 |
* delay due to resampling; needs to be fixed, if resampling code
|
|
|
14889 |
* gets changed
|
|
|
14890 |
*/
|
|
|
14891 |
samples_to_encode += 16. * gfp.out_samplerate / gfp.in_samplerate;
|
|
|
14892 |
}
|
|
|
14893 |
end_padding = gfp.framesize - (samples_to_encode % gfp.framesize);
|
|
|
14894 |
if (end_padding < 576)
|
|
|
14895 |
end_padding += gfp.framesize;
|
|
|
14896 |
gfp.encoder_padding = end_padding;
|
|
|
14897 |
|
|
|
14898 |
frames_left = (samples_to_encode + end_padding) / gfp.framesize;
|
|
|
14899 |
|
|
|
14900 |
/*
|
|
|
14901 |
* send in a frame of 0 padding until all internal sample buffers are
|
|
|
14902 |
* flushed
|
|
|
14903 |
*/
|
|
|
14904 |
while (frames_left > 0 && imp3 >= 0) {
|
|
|
14905 |
var bunch = mf_needed - gfc.mf_size;
|
|
|
14906 |
var frame_num = gfp.frameNum;
|
|
|
14907 |
|
|
|
14908 |
bunch *= gfp.in_samplerate;
|
|
|
14909 |
bunch /= gfp.out_samplerate;
|
|
|
14910 |
if (bunch > 1152)
|
|
|
14911 |
bunch = 1152;
|
|
|
14912 |
if (bunch < 1)
|
|
|
14913 |
bunch = 1;
|
|
|
14914 |
|
|
|
14915 |
mp3buffer_size_remaining = mp3buffer_size - mp3count;
|
|
|
14916 |
|
|
|
14917 |
/* if user specifed buffer size = 0, dont check size */
|
|
|
14918 |
if (mp3buffer_size == 0)
|
|
|
14919 |
mp3buffer_size_remaining = 0;
|
|
|
14920 |
|
|
|
14921 |
imp3 = this.lame_encode_buffer(gfp, buffer[0], buffer[1], bunch,
|
|
|
14922 |
mp3buffer, mp3bufferPos, mp3buffer_size_remaining);
|
|
|
14923 |
|
|
|
14924 |
mp3bufferPos += imp3;
|
|
|
14925 |
mp3count += imp3;
|
|
|
14926 |
frames_left -= (frame_num != gfp.frameNum) ? 1 : 0;
|
|
|
14927 |
}
|
|
|
14928 |
/*
|
|
|
14929 |
* Set gfc.mf_samples_to_encode to 0, so we may detect and break loops
|
|
|
14930 |
* calling it more than once in a row.
|
|
|
14931 |
*/
|
|
|
14932 |
gfc.mf_samples_to_encode = 0;
|
|
|
14933 |
|
|
|
14934 |
if (imp3 < 0) {
|
|
|
14935 |
/* some type of fatal error */
|
|
|
14936 |
return imp3;
|
|
|
14937 |
}
|
|
|
14938 |
|
|
|
14939 |
mp3buffer_size_remaining = mp3buffer_size - mp3count;
|
|
|
14940 |
/* if user specifed buffer size = 0, dont check size */
|
|
|
14941 |
if (mp3buffer_size == 0)
|
|
|
14942 |
mp3buffer_size_remaining = 0;
|
|
|
14943 |
|
|
|
14944 |
/* mp3 related stuff. bit buffer might still contain some mp3 data */
|
|
|
14945 |
bs.flush_bitstream(gfp);
|
|
|
14946 |
imp3 = bs.copy_buffer(gfc, mp3buffer, mp3bufferPos,
|
|
|
14947 |
mp3buffer_size_remaining, 1);
|
|
|
14948 |
if (imp3 < 0) {
|
|
|
14949 |
/* some type of fatal error */
|
|
|
14950 |
return imp3;
|
|
|
14951 |
}
|
|
|
14952 |
mp3bufferPos += imp3;
|
|
|
14953 |
mp3count += imp3;
|
|
|
14954 |
mp3buffer_size_remaining = mp3buffer_size - mp3count;
|
|
|
14955 |
/* if user specifed buffer size = 0, dont check size */
|
|
|
14956 |
if (mp3buffer_size == 0)
|
|
|
14957 |
mp3buffer_size_remaining = 0;
|
|
|
14958 |
|
|
|
14959 |
if (gfp.write_id3tag_automatic) {
|
|
|
14960 |
/* write a id3 tag to the bitstream */
|
|
|
14961 |
id3.id3tag_write_v1(gfp);
|
|
|
14962 |
|
|
|
14963 |
imp3 = bs.copy_buffer(gfc, mp3buffer, mp3bufferPos,
|
|
|
14964 |
mp3buffer_size_remaining, 0);
|
|
|
14965 |
|
|
|
14966 |
if (imp3 < 0) {
|
|
|
14967 |
return imp3;
|
|
|
14968 |
}
|
|
|
14969 |
mp3count += imp3;
|
|
|
14970 |
}
|
|
|
14971 |
return mp3count;
|
|
|
14972 |
};
|
|
|
14973 |
|
|
|
14974 |
this.lame_encode_buffer = function (gfp, buffer_l, buffer_r, nsamples, mp3buf, mp3bufPos, mp3buf_size) {
|
|
|
14975 |
var gfc = gfp.internal_flags;
|
|
|
14976 |
var in_buffer = [null, null];
|
|
|
14977 |
|
|
|
14978 |
if (gfc.Class_ID != LAME_ID)
|
|
|
14979 |
return -3;
|
|
|
14980 |
|
|
|
14981 |
if (nsamples == 0)
|
|
|
14982 |
return 0;
|
|
|
14983 |
|
|
|
14984 |
update_inbuffer_size(gfc, nsamples);
|
|
|
14985 |
|
|
|
14986 |
in_buffer[0] = gfc.in_buffer_0;
|
|
|
14987 |
in_buffer[1] = gfc.in_buffer_1;
|
|
|
14988 |
|
|
|
14989 |
/* make a copy of input buffer, changing type to sample_t */
|
|
|
14990 |
for (var i = 0; i < nsamples; i++) {
|
|
|
14991 |
in_buffer[0][i] = buffer_l[i];
|
|
|
14992 |
if (gfc.channels_in > 1)
|
|
|
14993 |
in_buffer[1][i] = buffer_r[i];
|
|
|
14994 |
}
|
|
|
14995 |
|
|
|
14996 |
return lame_encode_buffer_sample(gfp, in_buffer[0], in_buffer[1],
|
|
|
14997 |
nsamples, mp3buf, mp3bufPos, mp3buf_size);
|
|
|
14998 |
}
|
|
|
14999 |
|
|
|
15000 |
function calcNeeded(gfp) {
|
|
|
15001 |
var mf_needed = Encoder.BLKSIZE + gfp.framesize - Encoder.FFTOFFSET;
|
|
|
15002 |
/*
|
|
|
15003 |
* amount needed for FFT
|
|
|
15004 |
*/
|
|
|
15005 |
mf_needed = Math.max(mf_needed, 512 + gfp.framesize - 32);
|
|
|
15006 |
|
|
|
15007 |
return mf_needed;
|
|
|
15008 |
}
|
|
|
15009 |
|
|
|
15010 |
function lame_encode_buffer_sample(gfp, buffer_l, buffer_r, nsamples, mp3buf, mp3bufPos, mp3buf_size) {
|
|
|
15011 |
var gfc = gfp.internal_flags;
|
|
|
15012 |
var mp3size = 0, ret, i, ch, mf_needed;
|
|
|
15013 |
var mp3out;
|
|
|
15014 |
var mfbuf = [null, null];
|
|
|
15015 |
var in_buffer = [null, null];
|
|
|
15016 |
|
|
|
15017 |
if (gfc.Class_ID != LAME_ID)
|
|
|
15018 |
return -3;
|
|
|
15019 |
|
|
|
15020 |
if (nsamples == 0)
|
|
|
15021 |
return 0;
|
|
|
15022 |
|
|
|
15023 |
/* copy out any tags that may have been written into bitstream */
|
|
|
15024 |
mp3out = bs.copy_buffer(gfc, mp3buf, mp3bufPos, mp3buf_size, 0);
|
|
|
15025 |
if (mp3out < 0)
|
|
|
15026 |
return mp3out;
|
|
|
15027 |
/* not enough buffer space */
|
|
|
15028 |
mp3bufPos += mp3out;
|
|
|
15029 |
mp3size += mp3out;
|
|
|
15030 |
|
|
|
15031 |
in_buffer[0] = buffer_l;
|
|
|
15032 |
in_buffer[1] = buffer_r;
|
|
|
15033 |
|
|
|
15034 |
/* Apply user defined re-scaling */
|
|
|
15035 |
|
|
|
15036 |
/* user selected scaling of the samples */
|
|
|
15037 |
if (BitStream.NEQ(gfp.scale, 0) && BitStream.NEQ(gfp.scale, 1.0)) {
|
|
|
15038 |
for (i = 0; i < nsamples; ++i) {
|
|
|
15039 |
in_buffer[0][i] *= gfp.scale;
|
|
|
15040 |
if (gfc.channels_out == 2)
|
|
|
15041 |
in_buffer[1][i] *= gfp.scale;
|
|
|
15042 |
}
|
|
|
15043 |
}
|
|
|
15044 |
|
|
|
15045 |
/* user selected scaling of the channel 0 (left) samples */
|
|
|
15046 |
if (BitStream.NEQ(gfp.scale_left, 0)
|
|
|
15047 |
&& BitStream.NEQ(gfp.scale_left, 1.0)) {
|
|
|
15048 |
for (i = 0; i < nsamples; ++i) {
|
|
|
15049 |
in_buffer[0][i] *= gfp.scale_left;
|
|
|
15050 |
}
|
|
|
15051 |
}
|
|
|
15052 |
|
|
|
15053 |
/* user selected scaling of the channel 1 (right) samples */
|
|
|
15054 |
if (BitStream.NEQ(gfp.scale_right, 0)
|
|
|
15055 |
&& BitStream.NEQ(gfp.scale_right, 1.0)) {
|
|
|
15056 |
for (i = 0; i < nsamples; ++i) {
|
|
|
15057 |
in_buffer[1][i] *= gfp.scale_right;
|
|
|
15058 |
}
|
|
|
15059 |
}
|
|
|
15060 |
|
|
|
15061 |
/* Downsample to Mono if 2 channels in and 1 channel out */
|
|
|
15062 |
if (gfp.num_channels == 2 && gfc.channels_out == 1) {
|
|
|
15063 |
for (i = 0; i < nsamples; ++i) {
|
|
|
15064 |
in_buffer[0][i] = 0.5 * ( in_buffer[0][i] + in_buffer[1][i]);
|
|
|
15065 |
in_buffer[1][i] = 0.0;
|
|
|
15066 |
}
|
|
|
15067 |
}
|
|
|
15068 |
|
|
|
15069 |
mf_needed = calcNeeded(gfp);
|
|
|
15070 |
|
|
|
15071 |
mfbuf[0] = gfc.mfbuf[0];
|
|
|
15072 |
mfbuf[1] = gfc.mfbuf[1];
|
|
|
15073 |
|
|
|
15074 |
var in_bufferPos = 0;
|
|
|
15075 |
while (nsamples > 0) {
|
|
|
15076 |
var in_buffer_ptr = [null, null];
|
|
|
15077 |
var n_in = 0;
|
|
|
15078 |
/* number of input samples processed with fill_buffer */
|
|
|
15079 |
var n_out = 0;
|
|
|
15080 |
/* number of samples output with fill_buffer */
|
|
|
15081 |
/* n_in <> n_out if we are resampling */
|
|
|
15082 |
|
|
|
15083 |
in_buffer_ptr[0] = in_buffer[0];
|
|
|
15084 |
in_buffer_ptr[1] = in_buffer[1];
|
|
|
15085 |
/* copy in new samples into mfbuf, with resampling */
|
|
|
15086 |
var inOut = new InOut();
|
|
|
15087 |
fill_buffer(gfp, mfbuf, in_buffer_ptr, in_bufferPos, nsamples,
|
|
|
15088 |
inOut);
|
|
|
15089 |
n_in = inOut.n_in;
|
|
|
15090 |
n_out = inOut.n_out;
|
|
|
15091 |
|
|
|
15092 |
/* compute ReplayGain of resampled input if requested */
|
|
|
15093 |
if (gfc.findReplayGain && !gfc.decode_on_the_fly)
|
|
|
15094 |
if (ga.AnalyzeSamples(gfc.rgdata, mfbuf[0], gfc.mf_size,
|
|
|
15095 |
mfbuf[1], gfc.mf_size, n_out, gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR)
|
|
|
15096 |
return -6;
|
|
|
15097 |
|
|
|
15098 |
/* update in_buffer counters */
|
|
|
15099 |
nsamples -= n_in;
|
|
|
15100 |
in_bufferPos += n_in;
|
|
|
15101 |
if (gfc.channels_out == 2)
|
|
|
15102 |
;// in_bufferPos += n_in;
|
|
|
15103 |
|
|
|
15104 |
/* update mfbuf[] counters */
|
|
|
15105 |
gfc.mf_size += n_out;
|
|
|
15106 |
|
|
|
15107 |
/*
|
|
|
15108 |
* lame_encode_flush may have set gfc.mf_sample_to_encode to 0 so we
|
|
|
15109 |
* have to reinitialize it here when that happened.
|
|
|
15110 |
*/
|
|
|
15111 |
if (gfc.mf_samples_to_encode < 1) {
|
|
|
15112 |
gfc.mf_samples_to_encode = Encoder.ENCDELAY + Encoder.POSTDELAY;
|
|
|
15113 |
}
|
|
|
15114 |
gfc.mf_samples_to_encode += n_out;
|
|
|
15115 |
|
|
|
15116 |
if (gfc.mf_size >= mf_needed) {
|
|
|
15117 |
/* encode the frame. */
|
|
|
15118 |
/* mp3buf = pointer to current location in buffer */
|
|
|
15119 |
/* mp3buf_size = size of original mp3 output buffer */
|
|
|
15120 |
/* = 0 if we should not worry about the */
|
|
|
15121 |
/* buffer size because calling program is */
|
|
|
15122 |
/* to lazy to compute it */
|
|
|
15123 |
/* mp3size = size of data written to buffer so far */
|
|
|
15124 |
/* mp3buf_size-mp3size = amount of space avalable */
|
|
|
15125 |
|
|
|
15126 |
var buf_size = mp3buf_size - mp3size;
|
|
|
15127 |
if (mp3buf_size == 0)
|
|
|
15128 |
buf_size = 0;
|
|
|
15129 |
|
|
|
15130 |
ret = lame_encode_frame(gfp, mfbuf[0], mfbuf[1], mp3buf,
|
|
|
15131 |
mp3bufPos, buf_size);
|
|
|
15132 |
|
|
|
15133 |
if (ret < 0)
|
|
|
15134 |
return ret;
|
|
|
15135 |
mp3bufPos += ret;
|
|
|
15136 |
mp3size += ret;
|
|
|
15137 |
|
|
|
15138 |
/* shift out old samples */
|
|
|
15139 |
gfc.mf_size -= gfp.framesize;
|
|
|
15140 |
gfc.mf_samples_to_encode -= gfp.framesize;
|
|
|
15141 |
for (ch = 0; ch < gfc.channels_out; ch++)
|
|
|
15142 |
for (i = 0; i < gfc.mf_size; i++)
|
|
|
15143 |
mfbuf[ch][i] = mfbuf[ch][i + gfp.framesize];
|
|
|
15144 |
}
|
|
|
15145 |
}
|
|
|
15146 |
|
|
|
15147 |
return mp3size;
|
|
|
15148 |
}
|
|
|
15149 |
|
|
|
15150 |
function lame_encode_frame(gfp, inbuf_l, inbuf_r, mp3buf, mp3bufPos, mp3buf_size) {
|
|
|
15151 |
var ret = self.enc.lame_encode_mp3_frame(gfp, inbuf_l, inbuf_r, mp3buf,
|
|
|
15152 |
mp3bufPos, mp3buf_size);
|
|
|
15153 |
gfp.frameNum++;
|
|
|
15154 |
return ret;
|
|
|
15155 |
}
|
|
|
15156 |
|
|
|
15157 |
function InOut() {
|
|
|
15158 |
this.n_in = 0;
|
|
|
15159 |
this.n_out = 0;
|
|
|
15160 |
}
|
|
|
15161 |
|
|
|
15162 |
|
|
|
15163 |
function NumUsed() {
|
|
|
15164 |
this.num_used = 0;
|
|
|
15165 |
}
|
|
|
15166 |
|
|
|
15167 |
/**
|
|
|
15168 |
* Greatest common divisor.
|
|
|
15169 |
* <p>
|
|
|
15170 |
* Joint work of Euclid and M. Hendry
|
|
|
15171 |
*/
|
|
|
15172 |
function gcd(i, j) {
|
|
|
15173 |
return j != 0 ? gcd(j, i % j) : i;
|
|
|
15174 |
}
|
|
|
15175 |
|
|
|
15176 |
/**
|
|
|
15177 |
* Resampling via FIR filter, blackman window.
|
|
|
15178 |
*/
|
|
|
15179 |
function blackman(x, fcn, l) {
|
|
|
15180 |
/*
|
|
|
15181 |
* This algorithm from: SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C
|
|
|
15182 |
* S.D. Stearns and R.A. David, Prentice-Hall, 1992
|
|
|
15183 |
*/
|
|
|
15184 |
var wcn = (Math.PI * fcn);
|
|
|
15185 |
|
|
|
15186 |
x /= l;
|
|
|
15187 |
if (x < 0)
|
|
|
15188 |
x = 0;
|
|
|
15189 |
if (x > 1)
|
|
|
15190 |
x = 1;
|
|
|
15191 |
var x2 = x - .5;
|
|
|
15192 |
|
|
|
15193 |
var bkwn = 0.42 - 0.5 * Math.cos(2 * x * Math.PI) + 0.08 * Math.cos(4 * x * Math.PI);
|
|
|
15194 |
if (Math.abs(x2) < 1e-9)
|
|
|
15195 |
return (wcn / Math.PI);
|
|
|
15196 |
else
|
|
|
15197 |
return (bkwn * Math.sin(l * wcn * x2) / (Math.PI * l * x2));
|
|
|
15198 |
}
|
|
|
15199 |
|
|
|
15200 |
function fill_buffer_resample(gfp, outbuf, outbufPos, desired_len, inbuf, in_bufferPos, len, num_used, ch) {
|
|
|
15201 |
var gfc = gfp.internal_flags;
|
|
|
15202 |
var i, j = 0, k;
|
|
|
15203 |
/* number of convolution functions to pre-compute */
|
|
|
15204 |
var bpc = gfp.out_samplerate
|
|
|
15205 |
/ gcd(gfp.out_samplerate, gfp.in_samplerate);
|
|
|
15206 |
if (bpc > LameInternalFlags.BPC)
|
|
|
15207 |
bpc = LameInternalFlags.BPC;
|
|
|
15208 |
|
|
|
15209 |
var intratio = (Math.abs(gfc.resample_ratio
|
|
|
15210 |
- Math.floor(.5 + gfc.resample_ratio)) < .0001) ? 1 : 0;
|
|
|
15211 |
var fcn = 1.00 / gfc.resample_ratio;
|
|
|
15212 |
if (fcn > 1.00)
|
|
|
15213 |
fcn = 1.00;
|
|
|
15214 |
var filter_l = 31;
|
|
|
15215 |
if (0 == filter_l % 2)
|
|
|
15216 |
--filter_l;
|
|
|
15217 |
/* must be odd */
|
|
|
15218 |
filter_l += intratio;
|
|
|
15219 |
/* unless resample_ratio=int, it must be even */
|
|
|
15220 |
|
|
|
15221 |
var BLACKSIZE = filter_l + 1;
|
|
|
15222 |
/* size of data needed for FIR */
|
|
|
15223 |
|
|
|
15224 |
if (gfc.fill_buffer_resample_init == 0) {
|
|
|
15225 |
gfc.inbuf_old[0] = new_float(BLACKSIZE);
|
|
|
15226 |
gfc.inbuf_old[1] = new_float(BLACKSIZE);
|
|
|
15227 |
for (i = 0; i <= 2 * bpc; ++i)
|
|
|
15228 |
gfc.blackfilt[i] = new_float(BLACKSIZE);
|
|
|
15229 |
|
|
|
15230 |
gfc.itime[0] = 0;
|
|
|
15231 |
gfc.itime[1] = 0;
|
|
|
15232 |
|
|
|
15233 |
/* precompute blackman filter coefficients */
|
|
|
15234 |
for (j = 0; j <= 2 * bpc; j++) {
|
|
|
15235 |
var sum = 0.;
|
|
|
15236 |
var offset = (j - bpc) / (2. * bpc);
|
|
|
15237 |
for (i = 0; i <= filter_l; i++)
|
|
|
15238 |
sum += gfc.blackfilt[j][i] = blackman(i - offset, fcn,
|
|
|
15239 |
filter_l);
|
|
|
15240 |
for (i = 0; i <= filter_l; i++)
|
|
|
15241 |
gfc.blackfilt[j][i] /= sum;
|
|
|
15242 |
}
|
|
|
15243 |
gfc.fill_buffer_resample_init = 1;
|
|
|
15244 |
}
|
|
|
15245 |
|
|
|
15246 |
var inbuf_old = gfc.inbuf_old[ch];
|
|
|
15247 |
|
|
|
15248 |
/* time of j'th element in inbuf = itime + j/ifreq; */
|
|
|
15249 |
/* time of k'th element in outbuf = j/ofreq */
|
|
|
15250 |
for (k = 0; k < desired_len; k++) {
|
|
|
15251 |
var time0;
|
|
|
15252 |
var joff;
|
|
|
15253 |
|
|
|
15254 |
time0 = k * gfc.resample_ratio;
|
|
|
15255 |
/* time of k'th output sample */
|
|
|
15256 |
j = 0 | Math.floor(time0 - gfc.itime[ch]);
|
|
|
15257 |
|
|
|
15258 |
/* check if we need more input data */
|
|
|
15259 |
if ((filter_l + j - filter_l / 2) >= len)
|
|
|
15260 |
break;
|
|
|
15261 |
|
|
|
15262 |
/* blackman filter. by default, window centered at j+.5(filter_l%2) */
|
|
|
15263 |
/* but we want a window centered at time0. */
|
|
|
15264 |
var offset = (time0 - gfc.itime[ch] - (j + .5 * (filter_l % 2)));
|
|
|
15265 |
|
|
|
15266 |
/* find the closest precomputed window for this offset: */
|
|
|
15267 |
joff = 0 | Math.floor((offset * 2 * bpc) + bpc + .5);
|
|
|
15268 |
var xvalue = 0.;
|
|
|
15269 |
for (i = 0; i <= filter_l; ++i) {
|
|
|
15270 |
/* force integer index */
|
|
|
15271 |
var j2 = 0 | (i + j - filter_l / 2);
|
|
|
15272 |
var y;
|
|
|
15273 |
y = (j2 < 0) ? inbuf_old[BLACKSIZE + j2] : inbuf[in_bufferPos
|
|
|
15274 |
+ j2];
|
|
|
15275 |
xvalue += y * gfc.blackfilt[joff][i];
|
|
|
15276 |
}
|
|
|
15277 |
outbuf[outbufPos + k] = xvalue;
|
|
|
15278 |
}
|
|
|
15279 |
|
|
|
15280 |
/* k = number of samples added to outbuf */
|
|
|
15281 |
/* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2] */
|
|
|
15282 |
|
|
|
15283 |
/* how many samples of input data were used: */
|
|
|
15284 |
num_used.num_used = Math.min(len, filter_l + j - filter_l / 2);
|
|
|
15285 |
|
|
|
15286 |
/*
|
|
|
15287 |
* adjust our input time counter. Incriment by the number of samples
|
|
|
15288 |
* used, then normalize so that next output sample is at time 0, next
|
|
|
15289 |
* input buffer is at time itime[ch]
|
|
|
15290 |
*/
|
|
|
15291 |
gfc.itime[ch] += num_used.num_used - k * gfc.resample_ratio;
|
|
|
15292 |
|
|
|
15293 |
/* save the last BLACKSIZE samples into the inbuf_old buffer */
|
|
|
15294 |
if (num_used.num_used >= BLACKSIZE) {
|
|
|
15295 |
for (i = 0; i < BLACKSIZE; i++)
|
|
|
15296 |
inbuf_old[i] = inbuf[in_bufferPos + num_used.num_used + i
|
|
|
15297 |
- BLACKSIZE];
|
|
|
15298 |
} else {
|
|
|
15299 |
/* shift in num_used.num_used samples into inbuf_old */
|
|
|
15300 |
var n_shift = BLACKSIZE - num_used.num_used;
|
|
|
15301 |
/*
|
|
|
15302 |
* number of samples to
|
|
|
15303 |
* shift
|
|
|
15304 |
*/
|
|
|
15305 |
|
|
|
15306 |
/*
|
|
|
15307 |
* shift n_shift samples by num_used.num_used, to make room for the
|
|
|
15308 |
* num_used new samples
|
|
|
15309 |
*/
|
|
|
15310 |
for (i = 0; i < n_shift; ++i)
|
|
|
15311 |
inbuf_old[i] = inbuf_old[i + num_used.num_used];
|
|
|
15312 |
|
|
|
15313 |
/* shift in the num_used.num_used samples */
|
|
|
15314 |
for (j = 0; i < BLACKSIZE; ++i, ++j)
|
|
|
15315 |
inbuf_old[i] = inbuf[in_bufferPos + j];
|
|
|
15316 |
|
|
|
15317 |
}
|
|
|
15318 |
return k;
|
|
|
15319 |
/* return the number samples created at the new samplerate */
|
|
|
15320 |
}
|
|
|
15321 |
|
|
|
15322 |
function fill_buffer(gfp, mfbuf, in_buffer, in_bufferPos, nsamples, io) {
|
|
|
15323 |
var gfc = gfp.internal_flags;
|
|
|
15324 |
|
|
|
15325 |
/* copy in new samples into mfbuf, with resampling if necessary */
|
|
|
15326 |
if ((gfc.resample_ratio < .9999) || (gfc.resample_ratio > 1.0001)) {
|
|
|
15327 |
for (var ch = 0; ch < gfc.channels_out; ch++) {
|
|
|
15328 |
var numUsed = new NumUsed();
|
|
|
15329 |
io.n_out = fill_buffer_resample(gfp, mfbuf[ch], gfc.mf_size,
|
|
|
15330 |
gfp.framesize, in_buffer[ch], in_bufferPos, nsamples,
|
|
|
15331 |
numUsed, ch);
|
|
|
15332 |
io.n_in = numUsed.num_used;
|
|
|
15333 |
}
|
|
|
15334 |
} else {
|
|
|
15335 |
io.n_out = Math.min(gfp.framesize, nsamples);
|
|
|
15336 |
io.n_in = io.n_out;
|
|
|
15337 |
for (var i = 0; i < io.n_out; ++i) {
|
|
|
15338 |
mfbuf[0][gfc.mf_size + i] = in_buffer[0][in_bufferPos + i];
|
|
|
15339 |
if (gfc.channels_out == 2)
|
|
|
15340 |
mfbuf[1][gfc.mf_size + i] = in_buffer[1][in_bufferPos + i];
|
|
|
15341 |
}
|
|
|
15342 |
}
|
|
|
15343 |
}
|
|
|
15344 |
|
|
|
15345 |
}
|
|
|
15346 |
|
|
|
15347 |
|
|
|
15348 |
|
|
|
15349 |
function GetAudio() {
|
|
|
15350 |
var parse;
|
|
|
15351 |
var mpg;
|
|
|
15352 |
|
|
|
15353 |
this.setModules = function (parse2, mpg2) {
|
|
|
15354 |
parse = parse2;
|
|
|
15355 |
mpg = mpg2;
|
|
|
15356 |
}
|
|
|
15357 |
}
|
|
|
15358 |
|
|
|
15359 |
|
|
|
15360 |
function Parse() {
|
|
|
15361 |
var ver;
|
|
|
15362 |
var id3;
|
|
|
15363 |
var pre;
|
|
|
15364 |
|
|
|
15365 |
this.setModules = function (ver2, id32, pre2) {
|
|
|
15366 |
ver = ver2;
|
|
|
15367 |
id3 = id32;
|
|
|
15368 |
pre = pre2;
|
|
|
15369 |
}
|
|
|
15370 |
}
|
|
|
15371 |
|
|
|
15372 |
function MPGLib() {
|
|
|
15373 |
}
|
|
|
15374 |
|
|
|
15375 |
function ID3Tag() {
|
|
|
15376 |
var bits;
|
|
|
15377 |
var ver;
|
|
|
15378 |
|
|
|
15379 |
this.setModules = function (_bits, _ver) {
|
|
|
15380 |
bits = _bits;
|
|
|
15381 |
ver = _ver;
|
|
|
15382 |
}
|
|
|
15383 |
}
|
|
|
15384 |
|
|
|
15385 |
function Mp3Encoder(channels, samplerate, kbps) {
|
|
|
15386 |
if (arguments.length != 3) {
|
|
|
15387 |
console.error('WARN: Mp3Encoder(channels, samplerate, kbps) not specified');
|
|
|
15388 |
channels = 1;
|
|
|
15389 |
samplerate = 44100;
|
|
|
15390 |
kbps = 128;
|
|
|
15391 |
}
|
|
|
15392 |
var lame = new Lame();
|
|
|
15393 |
var gaud = new GetAudio();
|
|
|
15394 |
var ga = new GainAnalysis();
|
|
|
15395 |
var bs = new BitStream();
|
|
|
15396 |
var p = new Presets();
|
|
|
15397 |
var qupvt = new QuantizePVT();
|
|
|
15398 |
var qu = new Quantize();
|
|
|
15399 |
var vbr = new VBRTag();
|
|
|
15400 |
var ver = new Version();
|
|
|
15401 |
var id3 = new ID3Tag();
|
|
|
15402 |
var rv = new Reservoir();
|
|
|
15403 |
var tak = new Takehiro();
|
|
|
15404 |
var parse = new Parse();
|
|
|
15405 |
var mpg = new MPGLib();
|
|
|
15406 |
|
|
|
15407 |
lame.setModules(ga, bs, p, qupvt, qu, vbr, ver, id3, mpg);
|
|
|
15408 |
bs.setModules(ga, mpg, ver, vbr);
|
|
|
15409 |
id3.setModules(bs, ver);
|
|
|
15410 |
p.setModules(lame);
|
|
|
15411 |
qu.setModules(bs, rv, qupvt, tak);
|
|
|
15412 |
qupvt.setModules(tak, rv, lame.enc.psy);
|
|
|
15413 |
rv.setModules(bs);
|
|
|
15414 |
tak.setModules(qupvt);
|
|
|
15415 |
vbr.setModules(lame, bs, ver);
|
|
|
15416 |
gaud.setModules(parse, mpg);
|
|
|
15417 |
parse.setModules(ver, id3, p);
|
|
|
15418 |
|
|
|
15419 |
var gfp = lame.lame_init();
|
|
|
15420 |
|
|
|
15421 |
gfp.num_channels = channels;
|
|
|
15422 |
gfp.in_samplerate = samplerate;
|
|
|
15423 |
gfp.brate = kbps;
|
|
|
15424 |
gfp.mode = MPEGMode.STEREO;
|
|
|
15425 |
gfp.quality = 3;
|
|
|
15426 |
gfp.bWriteVbrTag = false;
|
|
|
15427 |
gfp.disable_reservoir = true;
|
|
|
15428 |
gfp.write_id3tag_automatic = false;
|
|
|
15429 |
|
|
|
15430 |
var retcode = lame.lame_init_params(gfp);
|
|
|
15431 |
var maxSamples = 1152;
|
|
|
15432 |
var mp3buf_size = 0 | (1.25 * maxSamples + 7200);
|
|
|
15433 |
var mp3buf = new_byte(mp3buf_size);
|
|
|
15434 |
|
|
|
15435 |
this.encodeBuffer = function (left, right) {
|
|
|
15436 |
if (channels == 1) {
|
|
|
15437 |
right = left;
|
|
|
15438 |
}
|
|
|
15439 |
if (left.length > maxSamples) {
|
|
|
15440 |
maxSamples = left.length;
|
|
|
15441 |
mp3buf_size = 0 | (1.25 * maxSamples + 7200);
|
|
|
15442 |
mp3buf = new_byte(mp3buf_size);
|
|
|
15443 |
}
|
|
|
15444 |
|
|
|
15445 |
var _sz = lame.lame_encode_buffer(gfp, left, right, left.length, mp3buf, 0, mp3buf_size);
|
|
|
15446 |
return new Int8Array(mp3buf.subarray(0, _sz));
|
|
|
15447 |
};
|
|
|
15448 |
|
|
|
15449 |
this.flush = function () {
|
|
|
15450 |
var _sz = lame.lame_encode_flush(gfp, mp3buf, 0, mp3buf_size);
|
|
|
15451 |
return new Int8Array(mp3buf.subarray(0, _sz));
|
|
|
15452 |
};
|
|
|
15453 |
}
|
|
|
15454 |
|
|
|
15455 |
function WavHeader() {
|
|
|
15456 |
this.dataOffset = 0;
|
|
|
15457 |
this.dataLen = 0;
|
|
|
15458 |
this.channels = 0;
|
|
|
15459 |
this.sampleRate = 0;
|
|
|
15460 |
}
|
|
|
15461 |
|
|
|
15462 |
function fourccToInt(fourcc) {
|
|
|
15463 |
return fourcc.charCodeAt(0) << 24 | fourcc.charCodeAt(1) << 16 | fourcc.charCodeAt(2) << 8 | fourcc.charCodeAt(3);
|
|
|
15464 |
}
|
|
|
15465 |
|
|
|
15466 |
WavHeader.RIFF = fourccToInt("RIFF");
|
|
|
15467 |
WavHeader.WAVE = fourccToInt("WAVE");
|
|
|
15468 |
WavHeader.fmt_ = fourccToInt("fmt ");
|
|
|
15469 |
WavHeader.data = fourccToInt("data");
|
|
|
15470 |
|
|
|
15471 |
WavHeader.readHeader = function (dataView) {
|
|
|
15472 |
var w = new WavHeader();
|
|
|
15473 |
|
|
|
15474 |
var header = dataView.getUint32(0, false);
|
|
|
15475 |
if (WavHeader.RIFF != header) {
|
|
|
15476 |
return;
|
|
|
15477 |
}
|
|
|
15478 |
var fileLen = dataView.getUint32(4, true);
|
|
|
15479 |
if (WavHeader.WAVE != dataView.getUint32(8, false)) {
|
|
|
15480 |
return;
|
|
|
15481 |
}
|
|
|
15482 |
if (WavHeader.fmt_ != dataView.getUint32(12, false)) {
|
|
|
15483 |
return;
|
|
|
15484 |
}
|
|
|
15485 |
var fmtLen = dataView.getUint32(16, true);
|
|
|
15486 |
var pos = 16 + 4;
|
|
|
15487 |
switch (fmtLen) {
|
|
|
15488 |
case 16:
|
|
|
15489 |
case 18:
|
|
|
15490 |
w.channels = dataView.getUint16(pos + 2, true);
|
|
|
15491 |
w.sampleRate = dataView.getUint32(pos + 4, true);
|
|
|
15492 |
break;
|
|
|
15493 |
default:
|
|
|
15494 |
throw 'extended fmt chunk not implemented';
|
|
|
15495 |
}
|
|
|
15496 |
pos += fmtLen;
|
|
|
15497 |
var data = WavHeader.data;
|
|
|
15498 |
var len = 0;
|
|
|
15499 |
while (data != header) {
|
|
|
15500 |
header = dataView.getUint32(pos, false);
|
|
|
15501 |
len = dataView.getUint32(pos + 4, true);
|
|
|
15502 |
if (data == header) {
|
|
|
15503 |
break;
|
|
|
15504 |
}
|
|
|
15505 |
pos += (len + 8);
|
|
|
15506 |
}
|
|
|
15507 |
w.dataLen = len;
|
|
|
15508 |
w.dataOffset = pos + 8;
|
|
|
15509 |
return w;
|
|
|
15510 |
};
|
|
|
15511 |
|
|
|
15512 |
L3Side.SFBMAX = (Encoder.SBMAX_s * 3);
|
|
|
15513 |
//testFullLength();
|
|
|
15514 |
lamejs.Mp3Encoder = Mp3Encoder;
|
|
|
15515 |
lamejs.WavHeader = WavHeader;
|
|
|
15516 |
}
|
|
|
15517 |
//fs=require('fs');
|
|
|
15518 |
lamejs();
|
|
|
15519 |
export default lamejs;
|