1 |
|
---|
2 | var bitrate_table /* [5][15] */ = [
|
---|
3 | /* MPEG-1 */
|
---|
4 | [ 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */
|
---|
5 | 256000, 288000, 320000, 352000, 384000, 416000, 448000 ],
|
---|
6 | [ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */
|
---|
7 | 128000, 160000, 192000, 224000, 256000, 320000, 384000 ],
|
---|
8 | [ 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */
|
---|
9 | 112000, 128000, 160000, 192000, 224000, 256000, 320000 ],
|
---|
10 |
|
---|
11 | /* MPEG-2 LSF */
|
---|
12 | [ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */
|
---|
13 | 128000, 144000, 160000, 176000, 192000, 224000, 256000 ],
|
---|
14 | [ 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */
|
---|
15 | 64000, 80000, 96000, 112000, 128000, 144000, 160000 ] /* II & III */
|
---|
16 | ];
|
---|
17 |
|
---|
18 | var samplerate_table /* [3] */ = [ 44100, 48000, 32000 ];
|
---|
19 |
|
---|
20 | var decoder_table = [
|
---|
21 | function() { console.log("Layer I decoding is not implemented!"); },
|
---|
22 | function() { console.log("Layer II decoding is not implemented!"); },
|
---|
23 | Mad.layer_III
|
---|
24 | ];
|
---|
25 |
|
---|
26 | Mad.Layer = {
|
---|
27 | I: 1,
|
---|
28 | II: 2,
|
---|
29 | III: 3
|
---|
30 | };
|
---|
31 |
|
---|
32 | Mad.Mode = {
|
---|
33 | SINGLE_CHANNEL : 0,
|
---|
34 | DUAL_CHANNEL : 1, /* dual channel */
|
---|
35 | JOINT_STEREO : 2, /* joint (MS/intensity) stereo */
|
---|
36 | STEREO : 3 /* normal LR stereo */
|
---|
37 | };
|
---|
38 |
|
---|
39 | Mad.Emphasis = {
|
---|
40 | NONE : 0, /* no emphasis */
|
---|
41 | _50_15_US : 1, /* 50/15 microseconds emphasis */
|
---|
42 | CCITT_J_17 : 3, /* CCITT J.17 emphasis */
|
---|
43 | RESERVED : 2 /* unknown emphasis */
|
---|
44 | };
|
---|
45 |
|
---|
46 | Mad.Header = function () {
|
---|
47 | this.layer = 0; /* audio layer (1, 2, or 3) */
|
---|
48 | this.mode = 0; /* channel mode (see above) */
|
---|
49 | this.mode_extension = 0; /* additional mode info */
|
---|
50 | this.emphasis = 0; /* de-emphasis to use (see above) */
|
---|
51 |
|
---|
52 | this.bitrate = 0; /* stream bitrate (bps) */
|
---|
53 | this.samplerate = 0; /* sampling frequency (Hz) */
|
---|
54 |
|
---|
55 | this.crc_check = 0; /* frame CRC accumulator */
|
---|
56 | this.crc_target = 0; /* final target CRC checksum */
|
---|
57 |
|
---|
58 | this.flags = 0; /* flags (see below) */
|
---|
59 | this.private_bits = 0; /* private bits (see below) */
|
---|
60 |
|
---|
61 | //this.duration = mad_timer_zero; /* audio playing time of frame */
|
---|
62 | };
|
---|
63 |
|
---|
64 | Mad.Header.prototype.nchannels = function () {
|
---|
65 | return this.mode === 0 ? 1 : 2;
|
---|
66 | }
|
---|
67 |
|
---|
68 | Mad.Header.prototype.nbsamples = function() {
|
---|
69 | return (this.layer === Mad.Layer.I ? 12 :
|
---|
70 | ((this.layer === Mad.Layer.III && (this.flags & Mad.Flag.LSF_EXT)) ? 18 : 36));
|
---|
71 | }
|
---|
72 |
|
---|
73 | /* libmad's decode_header */
|
---|
74 | Mad.Header.actually_decode = function(stream) {
|
---|
75 | var header = new Mad.Header();
|
---|
76 |
|
---|
77 | header.flags = 0;
|
---|
78 | header.private_bits = 0;
|
---|
79 |
|
---|
80 | /* header() */
|
---|
81 |
|
---|
82 | /* syncword */
|
---|
83 | stream.ptr.skip(11);
|
---|
84 |
|
---|
85 | /* MPEG 2.5 indicator (really part of syncword) */
|
---|
86 | if (stream.ptr.read(1) === 0) {
|
---|
87 | header.flags |= Mad.Flag.MPEG_2_5_EXT;
|
---|
88 | }
|
---|
89 |
|
---|
90 | /* ID */
|
---|
91 | if (stream.ptr.read(1) === 0) {
|
---|
92 | header.flags |= Mad.Flag.LSF_EXT;
|
---|
93 | } else if (header.flags & Mad.Flag.MPEG_2_5_EXT) {
|
---|
94 | stream.error = Mad.Error.LOSTSYNC;
|
---|
95 | return null;
|
---|
96 | }
|
---|
97 |
|
---|
98 | /* layer */
|
---|
99 | header.layer = 4 - stream.ptr.read(2);
|
---|
100 |
|
---|
101 | if (header.layer === 4) {
|
---|
102 | stream.error = Mad.Error.BADLAYER;
|
---|
103 | return header;
|
---|
104 | }
|
---|
105 |
|
---|
106 | /* protection_bit */
|
---|
107 | if (stream.ptr.read(1) === 0) {
|
---|
108 | header.flags |= Mad.Flag.PROTECTION;
|
---|
109 | // TODO: crc
|
---|
110 | //header.crc_check = mad_bit_crc(stream.ptr, 16, 0xffff);
|
---|
111 | stream.ptr.skip(16);
|
---|
112 | }
|
---|
113 |
|
---|
114 | /* bitrate_index */
|
---|
115 | var index = stream.ptr.read(4);
|
---|
116 | if (index === 15) {
|
---|
117 | stream.error = Mad.Error.BADBITRATE;
|
---|
118 | return header;
|
---|
119 | }
|
---|
120 |
|
---|
121 | if (header.flags & Mad.Flag.LSF_EXT) {
|
---|
122 | header.bitrate = bitrate_table[3 + (header.layer >> 1)][index];
|
---|
123 | } else {
|
---|
124 | header.bitrate = bitrate_table[header.layer - 1][index];
|
---|
125 | }
|
---|
126 |
|
---|
127 | /* sampling_frequency */
|
---|
128 | index = stream.ptr.read(2);
|
---|
129 |
|
---|
130 | if (index === 3) {
|
---|
131 | stream.error = Mad.Error.BADSAMPLERATE;
|
---|
132 | return header;
|
---|
133 | }
|
---|
134 |
|
---|
135 | header.samplerate = samplerate_table[index];
|
---|
136 |
|
---|
137 | if (header.flags & Mad.Flag.LSF_EXT) {
|
---|
138 | header.samplerate /= 2;
|
---|
139 |
|
---|
140 | if (header.flags & Mad.Flag.MPEG_2_5_EXT)
|
---|
141 | header.samplerate /= 2;
|
---|
142 | }
|
---|
143 |
|
---|
144 | /* padding_bit */
|
---|
145 | if (stream.ptr.read(1))
|
---|
146 | header.flags |= Mad.Flag.PADDING;
|
---|
147 |
|
---|
148 | /* private_bit */
|
---|
149 | if (stream.ptr.read(1))
|
---|
150 | header.private_bits |= Mad.Private.HEADER;
|
---|
151 |
|
---|
152 | /* mode */
|
---|
153 | header.mode = 3 - stream.ptr.read(2);
|
---|
154 |
|
---|
155 | /* mode_extension */
|
---|
156 | header.mode_extension = stream.ptr.read(2);
|
---|
157 |
|
---|
158 | /* copyright */
|
---|
159 | if (stream.ptr.read(1))
|
---|
160 | header.flags |= Mad.Flag.COPYRIGHT;
|
---|
161 |
|
---|
162 | /* original/copy */
|
---|
163 | if (stream.ptr.read(1))
|
---|
164 | header.flags |= Mad.Flag.ORIGINAL;
|
---|
165 |
|
---|
166 | /* emphasis */
|
---|
167 | header.emphasis = stream.ptr.read(2);
|
---|
168 |
|
---|
169 | /* error_check() */
|
---|
170 |
|
---|
171 | /* crc_check */
|
---|
172 | if (header.flags & Mad.Flag.PROTECTION)
|
---|
173 | header.crc_target = stream.ptr.read(16);
|
---|
174 |
|
---|
175 | return header;
|
---|
176 | }
|
---|
177 |
|
---|
178 | /* libmad's mad_header_decode */
|
---|
179 | Mad.Header.decode = function(stream) {
|
---|
180 | var header = null;
|
---|
181 |
|
---|
182 | // those are actually pointers. javascript powa.
|
---|
183 | var ptr = stream.next_frame;
|
---|
184 | var end = stream.bufend;
|
---|
185 | var pad_slot = 0;
|
---|
186 | var N = 0;
|
---|
187 |
|
---|
188 | /* stream skip */
|
---|
189 | if (stream.skiplen) {
|
---|
190 | if (!stream.sync)
|
---|
191 | ptr = stream.this_frame;
|
---|
192 |
|
---|
193 | if (end - ptr < stream.skiplen) {
|
---|
194 | stream.skiplen -= end - ptr;
|
---|
195 | stream.next_frame = end;
|
---|
196 |
|
---|
197 | stream.error = Mad.Error.BUFLEN;
|
---|
198 | return null;
|
---|
199 | }
|
---|
200 |
|
---|
201 | ptr += stream.skiplen;
|
---|
202 | stream.skiplen = 0;
|
---|
203 |
|
---|
204 | stream.sync = 1;
|
---|
205 | }
|
---|
206 |
|
---|
207 | // emulating goto in JS, yay! this was a 'sync:' label
|
---|
208 | var syncing = true;
|
---|
209 |
|
---|
210 | while(syncing) {
|
---|
211 | syncing = false;
|
---|
212 |
|
---|
213 | /* synchronize */
|
---|
214 | try {
|
---|
215 | if (stream.sync) {
|
---|
216 | if (end - ptr < Mad.BUFFER_GUARD) {
|
---|
217 | stream.next_frame = ptr;
|
---|
218 |
|
---|
219 | stream.error = Mad.Error.BUFLEN;
|
---|
220 | return null;
|
---|
221 | } else if (!(stream.getU8(ptr) === 0xff && (stream.getU8(ptr + 1) & 0xe0) === 0xe0)) {
|
---|
222 | /* mark point where frame sync word was expected */
|
---|
223 | stream.this_frame = ptr;
|
---|
224 | stream.next_frame = ptr + 1;
|
---|
225 |
|
---|
226 | stream.error = Mad.Error.LOSTSYNC;
|
---|
227 | return null;
|
---|
228 | }
|
---|
229 | } else {
|
---|
230 | stream.ptr = new Mad.Bit(stream.stream, ptr);
|
---|
231 |
|
---|
232 | if (stream.doSync() === -1) {
|
---|
233 | if (end - stream.next_frame >= Mad.BUFFER_GUARD)
|
---|
234 | stream.next_frame = end - Mad.BUFFER_GUARD;
|
---|
235 | stream.error = Mad.Error.BUFLEN;
|
---|
236 | return null;
|
---|
237 | }
|
---|
238 |
|
---|
239 | ptr = stream.ptr.nextbyte();
|
---|
240 | }
|
---|
241 | } catch (e) {
|
---|
242 | console.log("Synchronization error: " + e);
|
---|
243 |
|
---|
244 | stream.error = Mad.Error.BUFLEN;
|
---|
245 |
|
---|
246 | return null;
|
---|
247 | }
|
---|
248 |
|
---|
249 | /* begin processing */
|
---|
250 | stream.this_frame = ptr;
|
---|
251 | stream.next_frame = ptr + 1; /* possibly bogus sync word */
|
---|
252 |
|
---|
253 | stream.ptr = new Mad.Bit(stream.stream, stream.this_frame);
|
---|
254 |
|
---|
255 | header = Mad.Header.actually_decode(stream);
|
---|
256 | if(header === null) return null; // well Duh^2
|
---|
257 |
|
---|
258 | //console.log("=============== Decoding layer " + header.layer + " audio mode " +
|
---|
259 | // header.mode + " with " + header.bitrate +
|
---|
260 | // " bps and a samplerate of " + header.samplerate);
|
---|
261 |
|
---|
262 | /* calculate frame duration */
|
---|
263 | //mad_timer_set(&header.duration, 0, 32 * MAD_NSBSAMPLES(header), header.samplerate);
|
---|
264 |
|
---|
265 | /* calculate free bit rate */
|
---|
266 | if (header.bitrate === 0) {
|
---|
267 | console.log("Uh oh, a free bitrate stream. We're fucked.");
|
---|
268 | stream.error = Mad.Error.BADDATAPTR; // best guess
|
---|
269 | return null;
|
---|
270 |
|
---|
271 | // if ((stream.freerate === 0 || !stream.sync ||
|
---|
272 | // (header.layer === Mad.Layer.III && stream.freerate > 640000)) &&
|
---|
273 | // free_bitrate(stream, header) === -1)
|
---|
274 | // return null;
|
---|
275 | //
|
---|
276 | // header.bitrate = stream.freerate;
|
---|
277 | // header.flags |= Mad.Flag.FREEFORMAT;
|
---|
278 | }
|
---|
279 |
|
---|
280 | /* calculate beginning of next frame */
|
---|
281 | pad_slot = (header.flags & Mad.Flag.PADDING) ? 1 : 0;
|
---|
282 |
|
---|
283 | if (header.layer === Mad.Layer.I) {
|
---|
284 | N = (((12 * header.bitrate / header.samplerate) << 0) + pad_slot) * 4;
|
---|
285 | } else {
|
---|
286 | var slots_per_frame = (header.layer === Mad.Layer.III &&
|
---|
287 | (header.flags & Mad.Flag.LSF_EXT)) ? 72 : 144;
|
---|
288 | //console.log("slots_per_frame = " + slots_per_frame + ", bitrate = " + header.bitrate + ", samplerate = " + header.samplerate);
|
---|
289 |
|
---|
290 | N = ((slots_per_frame * header.bitrate / header.samplerate) << 0) + pad_slot;
|
---|
291 | }
|
---|
292 |
|
---|
293 |
|
---|
294 | /* verify there is enough data left in buffer to decode this frame */
|
---|
295 | if (N + Mad.BUFFER_GUARD > end - stream.this_frame) {
|
---|
296 | stream.next_frame = stream.this_frame;
|
---|
297 |
|
---|
298 | stream.error = Mad.Error.BUFLEN;
|
---|
299 | return null;
|
---|
300 | }
|
---|
301 |
|
---|
302 | stream.next_frame = stream.this_frame + N;
|
---|
303 |
|
---|
304 | // console.log("N = " + N + ", pad_slot = " + pad_slot + ", next_frame = " + stream.next_frame);
|
---|
305 |
|
---|
306 | if (!stream.sync) {
|
---|
307 | /* check that a valid frame header follows this frame */
|
---|
308 | ptr = stream.next_frame;
|
---|
309 | if (!(stream.getU8(ptr) === 0xff && (stream.getU8(ptr + 1) & 0xe0) === 0xe0)) {
|
---|
310 | ptr = stream.next_frame = stream.this_frame + 1;
|
---|
311 |
|
---|
312 | // emulating 'goto sync'
|
---|
313 | syncing = true;
|
---|
314 | continue;
|
---|
315 | }
|
---|
316 | stream.sync = 1;
|
---|
317 | }
|
---|
318 | } // end of goto emulation (label 'sync')
|
---|
319 |
|
---|
320 | header.flags |= Mad.Flag.INCOMPLETE;
|
---|
321 | return header;
|
---|
322 | }
|
---|
323 |
|
---|
324 | Mad.Frame = function () {
|
---|
325 | this.header = new Mad.Header(); /* MPEG audio header */
|
---|
326 |
|
---|
327 | this.options = 0; /* decoding options (from stream) */
|
---|
328 |
|
---|
329 | // sbsample[2][36][32]
|
---|
330 | this.sbsample = []; /* synthesis subband filter samples */
|
---|
331 | for(var ch = 0; ch < 2; ch++) {
|
---|
332 | this.sbsample[ch] = [];
|
---|
333 | for(var grp = 0; grp < 36; grp++) {
|
---|
334 | // this.sbsample[ch][grp] = new Float64Array(new ArrayBuffer(8 * 32));
|
---|
335 | this.sbsample[ch][grp] = [];
|
---|
336 | for(var i = 0; i < 32; i++) {
|
---|
337 | this.sbsample[ch][grp][i] = 0;
|
---|
338 | }
|
---|
339 | }
|
---|
340 | }
|
---|
341 |
|
---|
342 | // overlap[2][32][18]
|
---|
343 | this.overlap = []; /* Layer III block overlap data */
|
---|
344 | for(var ch = 0; ch < 2; ch++) {
|
---|
345 | this.overlap[ch] = [];
|
---|
346 | for(var sb = 0; sb < 32; sb++) {
|
---|
347 | // this.overlap[ch][sb] = new Float64Array(new ArrayBuffer(8 * 18));
|
---|
348 | this.overlap[ch][sb] = [];
|
---|
349 | for(var i = 0; i < 18; i++) {
|
---|
350 | this.overlap[ch][sb][i] = 0;
|
---|
351 | }
|
---|
352 | }
|
---|
353 | }
|
---|
354 | };
|
---|
355 |
|
---|
356 | Mad.Frame.decode = function(frame, stream) {
|
---|
357 | frame.options = stream.options;
|
---|
358 |
|
---|
359 | /* header() */
|
---|
360 | /* error_check() */
|
---|
361 |
|
---|
362 | if (!(frame.header.flags & Mad.Flag.INCOMPLETE)) {
|
---|
363 | frame.header = Mad.Header.decode(stream);
|
---|
364 | if(frame.header === null) {
|
---|
365 | // something went wrong
|
---|
366 | throw 'Header decoding failed';
|
---|
367 | }
|
---|
368 | }
|
---|
369 |
|
---|
370 | frame.header.flags &= ~Mad.Flag.INCOMPLETE;
|
---|
371 |
|
---|
372 | if (decoder_table[frame.header.layer - 1](stream, frame) === -1) {
|
---|
373 | if (!Mad.recoverable(stream.error)) {
|
---|
374 | stream.next_frame = stream.this_frame;
|
---|
375 | }
|
---|
376 | throw 'Decoder table error';
|
---|
377 | }
|
---|
378 |
|
---|
379 | return frame;
|
---|
380 | };
|
---|
381 |
|
---|
382 | Mad.sbsampleIndex = function (i, j, k) {
|
---|
383 | return i * 36 * 32 + j * 32 + k;
|
---|
384 | };
|
---|
385 |
|
---|
386 | Mad.overlapIndex = function (i, j, k) {
|
---|
387 | return i * 32 * 18 + j * 18 + k;
|
---|
388 | };
|
---|
389 |
|
---|
390 | Mad.Flag = {
|
---|
391 | NPRIVATE_III : 0x0007, /* number of Layer III private bits */
|
---|
392 | INCOMPLETE : 0x0008, /* header but not data is decoded */
|
---|
393 |
|
---|
394 | PROTECTION : 0x0010, /* frame has CRC protection */
|
---|
395 | COPYRIGHT : 0x0020, /* frame is copyright */
|
---|
396 | ORIGINAL : 0x0040, /* frame is original (else copy) */
|
---|
397 | PADDING : 0x0080, /* frame has additional slot */
|
---|
398 |
|
---|
399 | I_STEREO : 0x0100, /* uses intensity joint stereo */
|
---|
400 | MS_STEREO : 0x0200, /* uses middle/side joint stereo */
|
---|
401 | FREEFORMAT : 0x0400, /* uses free format bitrate */
|
---|
402 |
|
---|
403 | LSF_EXT : 0x1000, /* lower sampling freq. extension */
|
---|
404 | MC_EXT : 0x2000, /* multichannel audio extension */
|
---|
405 | MPEG_2_5_EXT : 0x4000 /* MPEG 2.5 (unofficial) extension */
|
---|
406 | };
|
---|
407 |
|
---|
408 | Mad.Private = {
|
---|
409 | HEADER : 0x0100, /* header private bit */
|
---|
410 | III : 0x001f /* Layer III private bits (up to 5) */
|
---|
411 | };
|
---|