diff --git a/src/html5/js/lib/aurora/aurora.js b/src/html5/js/lib/aurora/aurora.js
index bc47bafe21..18b3f1eb38 100644
--- a/src/html5/js/lib/aurora/aurora.js
+++ b/src/html5/js/lib/aurora/aurora.js
@@ -3106,7 +3106,7 @@ Resampler.prototype.initialize = function () {
this.tailExists = false;
this.lastWeight = 0;
}
-
+
var outputBufferSize = (Math.ceil(this.inputBufferLength * this.toSampleRate / this.fromSampleRate / this.channels * 1.01) * this.channels) + this.channels;
this.outputBuffer = new Float32Array(outputBufferSize);
this.lastOutput = new Float32Array(this.channels);
@@ -3149,7 +3149,7 @@ Resampler.prototype.compileLinearInterpolationFunction = function () {
toCompile += "this.lastWeight = weight % 1;\
}\
return this.outputBuffer;";
-
+
this.resampler = Function("buffer", toCompile);
};
@@ -3215,7 +3215,7 @@ Resampler.prototype.compileMultiTapFunction = function () {
} while (actualPosition < bufferLength);\
}\
return this.outputBuffer;";
-
+
this.resampler = Function("buffer", toCompile);
};
diff --git a/src/html5/js/lib/aurora/flac.js b/src/html5/js/lib/aurora/flac.js
index 6a35ecf820..882a926a4d 100644
--- a/src/html5/js/lib/aurora/flac.js
+++ b/src/html5/js/lib/aurora/flac.js
@@ -9,7 +9,7 @@ require('./src/ogg');
* FLAC.js - Free Lossless Audio Codec decoder in JavaScript
* Original C version from FFmpeg (c) 2003 Alex Beregszaszi
* JavaScript port by Devon Govett and Jens Nockert of Official.fm Labs
- *
+ *
* Licensed under the same terms as the original. The original
* license follows.
*
@@ -29,62 +29,62 @@ var AV = (typeof window !== "undefined" ? window['AV'] : typeof global !== "unde
var FLACDecoder = AV.Decoder.extend(function() {
AV.Decoder.register('flac', this);
-
+
this.prototype.setCookie = function(cookie) {
this.cookie = cookie;
-
+
// initialize arrays
this.decoded = [];
for (var i = 0; i < this.format.channelsPerFrame; i++) {
this.decoded[i] = new Int32Array(cookie.maxBlockSize);
}
-
+
// for 24 bit lpc frames, this is used to simulate a 64 bit int
this.lpc_total = new Int32Array(2);
};
-
+
const BLOCK_SIZES = new Int16Array([
0, 192, 576 << 0, 576 << 1, 576 << 2, 576 << 3, 0, 0,
256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6, 256 << 7
]);
-
+
const SAMPLE_RATES = new Int32Array([
0, 88200, 176400, 192000,
8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
0, 0, 0, 0
]);
-
+
const SAMPLE_SIZES = new Int8Array([
0, 8, 12, 0, 16, 20, 24, 0
]);
-
+
const MAX_CHANNELS = 8,
CHMODE_INDEPENDENT = 0,
CHMODE_LEFT_SIDE = 8,
CHMODE_RIGHT_SIDE = 9,
CHMODE_MID_SIDE = 10;
-
+
this.prototype.readChunk = function() {
var stream = this.bitstream;
if (!stream.available(32))
return;
-
+
// frame sync code
if ((stream.read(15) & 0x7FFF) !== 0x7FFC)
throw new Error('Invalid sync code');
-
+
var isVarSize = stream.read(1), // variable block size stream code
bsCode = stream.read(4), // block size
srCode = stream.read(4), // sample rate code
chMode = stream.read(4), // channel mode
bpsCode = stream.read(3); // bits per sample
-
+
stream.advance(1); // reserved bit
-
+
// channels
this.chMode = chMode;
var channels;
-
+
if (chMode < MAX_CHANNELS) {
channels = chMode + 1;
this.chMode = CHMODE_INDEPENDENT;
@@ -93,30 +93,30 @@ var FLACDecoder = AV.Decoder.extend(function() {
} else {
throw new Error('Invalid channel mode');
}
-
+
if (channels !== this.format.channelsPerFrame)
throw new Error('Switching channel layout mid-stream not supported.');
-
- // bits per sample
+
+ // bits per sample
if (bpsCode === 3 || bpsCode === 7)
throw new Error('Invalid sample size code');
-
+
this.bps = SAMPLE_SIZES[bpsCode];
if (this.bps !== this.format.bitsPerChannel)
throw new Error('Switching bits per sample mid-stream not supported.');
-
+
// sample number or frame number
// see http://www.hydrogenaudio.org/forums/index.php?s=ea7085ffe6d57132c36e6105c0d434c9&showtopic=88390&pid=754269&st=0entry754269
var ones = 0;
while (stream.read(1) === 1)
ones++;
-
+
var frame_or_sample_num = stream.read(7 - ones);
for (; ones > 1; ones--) {
stream.advance(2); // == 2
frame_or_sample_num = (frame_or_sample_num << 6) | stream.read(6);
}
-
+
// block size
if (bsCode === 0)
throw new Error('Reserved blocksize code');
@@ -126,7 +126,7 @@ var FLACDecoder = AV.Decoder.extend(function() {
this.blockSize = stream.read(16) + 1;
else
this.blockSize = BLOCK_SIZES[bsCode];
-
+
// sample rate
var sampleRate;
if (srCode < 12)
@@ -139,23 +139,23 @@ var FLACDecoder = AV.Decoder.extend(function() {
sampleRate = stream.read(16) * 10;
else
throw new Error('Invalid sample rate code');
-
+
stream.advance(8); // skip CRC check
-
+
// subframes
for (var i = 0; i < channels; i++)
this.decodeSubframe(i);
-
+
stream.align();
stream.advance(16); // skip CRC frame footer
-
+
var is32 = this.bps > 16,
output = new ArrayBuffer(this.blockSize * channels * (is32 ? 4 : 2)),
buf = is32 ? new Int32Array(output) : new Int16Array(output),
blockSize = this.blockSize,
decoded = this.decoded,
j = 0;
-
+
switch (this.chMode) {
case CHMODE_INDEPENDENT:
for (var k = 0; k < blockSize; k++) {
@@ -164,7 +164,7 @@ var FLACDecoder = AV.Decoder.extend(function() {
}
}
break;
-
+
case CHMODE_LEFT_SIDE:
for (var i = 0; i < blockSize; i++) {
var left = decoded[0][i],
@@ -174,7 +174,7 @@ var FLACDecoder = AV.Decoder.extend(function() {
buf[j++] = (left - right);
}
break;
-
+
case CHMODE_RIGHT_SIDE:
for (var i = 0; i < blockSize; i++) {
var left = decoded[0][i],
@@ -184,28 +184,28 @@ var FLACDecoder = AV.Decoder.extend(function() {
buf[j++] = right;
}
break;
-
+
case CHMODE_MID_SIDE:
for (var i = 0; i < blockSize; i++) {
var left = decoded[0][i],
right = decoded[1][i];
-
+
left -= right >> 1;
buf[j++] = (left + right);
buf[j++] = left;
}
break;
}
-
+
return buf;
};
-
+
this.prototype.decodeSubframe = function(channel) {
var wasted = 0,
stream = this.bitstream,
blockSize = this.blockSize,
decoded = this.decoded;
-
+
this.curr_bps = this.bps;
if (channel === 0) {
if (this.chMode === CHMODE_RIGHT_SIDE)
@@ -214,12 +214,12 @@ var FLACDecoder = AV.Decoder.extend(function() {
if (this.chMode === CHMODE_LEFT_SIDE || this.chMode === CHMODE_MID_SIDE)
this.curr_bps++;
}
-
+
if (stream.read(1))
throw new Error("Invalid subframe padding");
-
+
var type = stream.read(6);
-
+
if (stream.read(1)) {
wasted = 1;
while (!stream.read(1))
@@ -227,95 +227,95 @@ var FLACDecoder = AV.Decoder.extend(function() {
this.curr_bps -= wasted;
}
-
+
if (this.curr_bps > 32)
throw new Error("decorrelated bit depth > 32 (" + this.curr_bps + ")");
-
+
if (type === 0) {
var tmp = stream.read(this.curr_bps, true);
for (var i = 0; i < blockSize; i++)
decoded[channel][i] = tmp;
-
+
} else if (type === 1) {
var bps = this.curr_bps;
for (var i = 0; i < blockSize; i++)
decoded[channel][i] = stream.read(bps, true);
-
+
} else if ((type >= 8) && (type <= 12)) {
this.decode_subframe_fixed(channel, type & ~0x8);
-
+
} else if (type >= 32) {
this.decode_subframe_lpc(channel, (type & ~0x20) + 1);
} else {
throw new Error("Invalid coding type");
}
-
+
if (wasted) {
for (var i = 0; i < blockSize; i++)
decoded[channel][i] <<= wasted;
}
};
-
+
this.prototype.decode_subframe_fixed = function(channel, predictor_order) {
var decoded = this.decoded[channel],
stream = this.bitstream,
bps = this.curr_bps;
-
+
// warm up samples
for (var i = 0; i < predictor_order; i++)
decoded[i] = stream.read(bps, true);
-
+
this.decode_residuals(channel, predictor_order);
-
+
var a = 0, b = 0, c = 0, d = 0;
-
- if (predictor_order > 0)
+
+ if (predictor_order > 0)
a = decoded[predictor_order - 1];
-
+
if (predictor_order > 1)
b = a - decoded[predictor_order - 2];
-
- if (predictor_order > 2)
+
+ if (predictor_order > 2)
c = b - decoded[predictor_order - 2] + decoded[predictor_order - 3];
-
+
if (predictor_order > 3)
d = c - decoded[predictor_order - 2] + 2 * decoded[predictor_order - 3] - decoded[predictor_order - 4];
-
+
switch (predictor_order) {
case 0:
break;
-
+
case 1:
case 2:
case 3:
case 4:
var abcd = new Int32Array([a, b, c, d]),
blockSize = this.blockSize;
-
+
for (var i = predictor_order; i < blockSize; i++) {
abcd[predictor_order - 1] += decoded[i];
-
+
for (var j = predictor_order - 2; j >= 0; j--) {
abcd[j] += abcd[j + 1];
}
-
+
decoded[i] = abcd[0];
}
-
+
break;
-
+
default:
throw new Error("Invalid Predictor Order " + predictor_order);
}
};
-
+
this.prototype.decode_subframe_lpc = function(channel, predictor_order) {
var stream = this.bitstream,
decoded = this.decoded[channel],
bps = this.curr_bps,
blockSize = this.blockSize;
-
+
// warm up samples
for (var i = 0; i < predictor_order; i++) {
decoded[i] = stream.read(bps, true);
@@ -324,42 +324,42 @@ var FLACDecoder = AV.Decoder.extend(function() {
var coeff_prec = stream.read(4) + 1;
if (coeff_prec === 16)
throw new Error("Invalid coefficient precision");
-
+
var qlevel = stream.read(5, true);
if (qlevel < 0)
throw new Error("Negative qlevel, maybe buggy stream");
-
+
var coeffs = new Int32Array(32);
for (var i = 0; i < predictor_order; i++) {
coeffs[i] = stream.read(coeff_prec, true);
}
-
+
this.decode_residuals(channel, predictor_order);
-
+
if (this.bps <= 16) {
for (var i = predictor_order; i < blockSize - 1; i += 2) {
var d = decoded[i - predictor_order],
s0 = 0, s1 = 0, c = 0;
-
+
for (var j = predictor_order - 1; j > 0; j--) {
c = coeffs[j];
s0 += c * d;
d = decoded[i - j];
s1 += c * d;
}
-
+
c = coeffs[0];
s0 += c * d;
d = decoded[i] += (s0 >> qlevel);
s1 += c * d;
decoded[i + 1] += (s1 >> qlevel);
}
-
+
if (i < blockSize) {
var sum = 0;
for (var j = 0; j < predictor_order; j++)
sum += coeffs[j] * decoded[i - j - 1];
-
+
decoded[i] += (sum >> qlevel);
}
} else {
@@ -372,7 +372,7 @@ var FLACDecoder = AV.Decoder.extend(function() {
for (j = 0; j < predictor_order; j++) {
// simulate `total += coeffs[j] * decoded[i - j - 1]`
- multiply_add(total, coeffs[j], decoded[i - j - 1]);
+ multiply_add(total, coeffs[j], decoded[i - j - 1]);
}
// simulate `decoded[i] += total >> qlevel`
@@ -381,9 +381,9 @@ var FLACDecoder = AV.Decoder.extend(function() {
}
}
};
-
+
const TWO_PWR_32_DBL = Math.pow(2, 32);
-
+
// performs `total += a * b` on a simulated 64 bit int
// total is an Int32Array(2)
// a and b are JS numbers (32 bit ints)
@@ -393,14 +393,14 @@ var FLACDecoder = AV.Decoder.extend(function() {
var n = r < 0;
if (n)
r = -r;
-
+
var r_low = (r % TWO_PWR_32_DBL) | 0;
var r_high = (r / TWO_PWR_32_DBL) | 0;
if (n) {
r_low = ~r_low + 1;
r_high = ~r_high;
}
-
+
// add result to total
var a48 = total[1] >>> 16;
var a32 = total[1] & 0xFFFF;
@@ -424,31 +424,31 @@ var FLACDecoder = AV.Decoder.extend(function() {
c32 &= 0xFFFF;
c48 += a48 + b48;
c48 &= 0xFFFF;
-
+
// store result back in total
total[0] = (c16 << 16) | c00;
total[1] = (c48 << 16) | c32;
}
-
+
const INT_MAX = 32767;
-
+
this.prototype.decode_residuals = function(channel, predictor_order) {
var stream = this.bitstream,
method_type = stream.read(2);
-
+
if (method_type > 1)
throw new Error('Illegal residual coding method ' + method_type);
-
+
var rice_order = stream.read(4),
samples = (this.blockSize >>> rice_order);
-
+
if (predictor_order > samples)
throw new Error('Invalid predictor order ' + predictor_order + ' > ' + samples);
-
+
var decoded = this.decoded[channel],
- sample = predictor_order,
+ sample = predictor_order,
i = predictor_order;
-
+
for (var partition = 0; partition < (1 << rice_order); partition++) {
var tmp = stream.read(method_type === 0 ? 4 : 5);
@@ -456,24 +456,24 @@ var FLACDecoder = AV.Decoder.extend(function() {
tmp = stream.read(5);
for (; i < samples; i++)
decoded[sample++] = stream.read(tmp, true);
-
+
} else {
for (; i < samples; i++)
decoded[sample++] = this.golomb(tmp, INT_MAX, 0);
}
-
+
i = 0;
}
};
-
+
const MIN_CACHE_BITS = 25;
-
+
this.prototype.golomb = function(k, limit, esc_len) {
var data = this.bitstream,
offset = data.bitPosition,
buf = data.peek(32 - offset) << offset,
v = 0;
-
+
var log = 31 - clz(buf | 1); // log2(buf)
if (log - k >= 32 - MIN_CACHE_BITS && 32 - log < limit) {
@@ -482,7 +482,7 @@ var FLACDecoder = AV.Decoder.extend(function() {
data.advance(32 + k - log);
v = buf;
-
+
} else {
for (var i = 0; data.read(1) === 0; i++)
buf = data.peek(32 - offset) << offset;
@@ -494,19 +494,19 @@ var FLACDecoder = AV.Decoder.extend(function() {
buf = 0;
v = buf + (i << k);
-
+
} else if (i === limit - 1) {
buf = data.read(esc_len);
v = buf + 1;
-
+
} else {
v = -1;
}
}
-
+
return (v >> 1) ^ -(v & 1);
};
-
+
// Should be in the damned standard library...
function clz(input) {
var output = 0,
@@ -539,13 +539,13 @@ var FLACDecoder = AV.Decoder.extend(function() {
if (curbyte & 0x8)
return output;
-
+
if (curbyte & 0x4)
return output + 1;
-
+
if (curbyte & 0x2)
return output + 2;
-
+
if (curbyte & 0x1)
return output + 3;
@@ -579,11 +579,11 @@ var AV = (typeof window !== "undefined" ? window['AV'] : typeof global !== "unde
var FLACDemuxer = AV.Demuxer.extend(function() {
AV.Demuxer.register(this);
-
+
this.probe = function(buffer) {
return buffer.peekString(0, 4) === 'fLaC';
}
-
+
const STREAMINFO = 0,
PADDING = 1,
APPLICATION = 2,
@@ -593,62 +593,62 @@ var FLACDemuxer = AV.Demuxer.extend(function() {
PICTURE = 6,
INVALID = 127,
STREAMINFO_SIZE = 34;
-
+
this.prototype.readChunk = function() {
var stream = this.stream;
-
+
if (!this.readHeader && stream.available(4)) {
if (stream.readString(4) !== 'fLaC')
return this.emit('error', 'Invalid FLAC file.');
-
+
this.readHeader = true;
}
-
- while (stream.available(1) && !this.last) {
+
+ while (stream.available(1) && !this.last) {
if (!this.readBlockHeaders) {
var tmp = stream.readUInt8();
this.last = (tmp & 0x80) === 0x80,
this.type = tmp & 0x7F,
this.size = stream.readUInt24();
}
-
+
if (!this.foundStreamInfo && this.type !== STREAMINFO)
return this.emit('error', 'STREAMINFO must be the first block');
-
+
if (!stream.available(this.size))
return;
-
+
switch (this.type) {
case STREAMINFO:
if (this.foundStreamInfo)
return this.emit('error', 'STREAMINFO can only occur once.');
-
+
if (this.size !== STREAMINFO_SIZE)
return this.emit('error', 'STREAMINFO size is wrong.');
-
+
this.foundStreamInfo = true;
var bitstream = new AV.Bitstream(stream);
-
+
var cookie = {
minBlockSize: bitstream.read(16),
maxBlockSize: bitstream.read(16),
minFrameSize: bitstream.read(24),
maxFrameSize: bitstream.read(24)
};
-
+
this.format = {
formatID: 'flac',
sampleRate: bitstream.read(20),
channelsPerFrame: bitstream.read(3) + 1,
bitsPerChannel: bitstream.read(5) + 1
};
-
+
this.emit('format', this.format);
this.emit('cookie', cookie);
-
+
var sampleCount = bitstream.read(36);
this.emit('duration', sampleCount / this.format.sampleRate * 1000 | 0);
-
+
stream.advance(16); // skip MD5 hashes
this.readBlockHeaders = false;
break;
@@ -690,21 +690,21 @@ var FLACDemuxer = AV.Demuxer.extend(function() {
// see http://www.xiph.org/vorbis/doc/v-comment.html
this.metadata || (this.metadata = {});
var len = stream.readUInt32(true);
-
+
this.metadata.vendor = stream.readString(len);
var length = stream.readUInt32(true);
-
+
for (var i = 0; i < length; i++) {
len = stream.readUInt32(true);
var str = stream.readString(len, 'utf8'),
idx = str.indexOf('=');
-
+
this.metadata[str.slice(0, idx).toLowerCase()] = str.slice(idx + 1);
}
-
+
// TODO: standardize field names across formats
break;
-
+
case PICTURE:
var type = stream.readUInt32();
if (type !== 3) { // make sure this is album art (type 3)
@@ -720,29 +720,29 @@ var FLACDemuxer = AV.Demuxer.extend(function() {
colors = stream.readUInt32(),
length = stream.readUInt32(),
picture = stream.readBuffer(length);
-
+
this.metadata || (this.metadata = {});
this.metadata.coverArt = picture;
}
-
+
// does anyone want the rest of the info?
break;
-
+
default:
stream.advance(this.size);
this.readBlockHeaders = false;
}
-
+
if (this.last && this.metadata)
this.emit('metadata', this.metadata);
}
-
+
while (stream.available(1) && this.last) {
var buffer = stream.readSingleBuffer(stream.remainingBytes());
this.emit('data', buffer);
}
}
-
+
});
module.exports = FLACDemuxer;
@@ -760,32 +760,32 @@ if (!OggDemuxer) return;
OggDemuxer.plugins.push({
magic: "\177FLAC",
-
+
init: function() {
this.list = new AV.BufferList();
this.stream = new AV.Stream(this.list);
},
-
+
readHeaders: function(packet) {
var stream = this.stream;
this.list.append(new AV.Buffer(packet));
-
+
stream.advance(5); // magic
if (stream.readUInt8() != 1)
throw new Error('Unsupported FLAC version');
-
+
stream.advance(3);
if (stream.peekString(0, 4) != 'fLaC')
throw new Error('Not flac');
-
+
this.flac = AV.Demuxer.find(stream.peekSingleBuffer(0, stream.remainingBytes()));
if (!this.flac)
throw new Error('Flac demuxer not found');
-
+
this.flac.prototype.readChunk.call(this);
return true;
},
-
+
readPacket: function(packet) {
this.list.append(new AV.Buffer(packet));
this.flac.prototype.readChunk.call(this);
diff --git a/src/html5/js/lib/aurora/mp3.js b/src/html5/js/lib/aurora/mp3.js
index ee68985f94..85b3be5b73 100644
--- a/src/html5/js/lib/aurora/mp3.js
+++ b/src/html5/js/lib/aurora/mp3.js
@@ -15,14 +15,14 @@ var Layer3 = require('./layer3');
var MP3Decoder = AV.Decoder.extend(function() {
AV.Decoder.register('mp3', this);
-
+
this.prototype.init = function() {
this.mp3_stream = new MP3Stream(this.bitstream);
this.frame = new MP3Frame();
this.synth = new MP3Synth();
this.seeking = false;
};
-
+
this.prototype.readChunk = function() {
var stream = this.mp3_stream;
var frame = this.frame;
@@ -40,33 +40,33 @@ var MP3Decoder = AV.Decoder.extend(function() {
throw err;
}
}
-
+
this.seeking = false;
} else {
frame.decode(stream);
}
-
+
synth.frame(frame);
-
+
// interleave samples
var data = synth.pcm.samples,
channels = synth.pcm.channels,
len = synth.pcm.length,
output = new Float32Array(len * channels),
j = 0;
-
+
for (var k = 0; k < len; k++) {
for (var i = 0; i < channels; i++) {
output[j++] = data[i][k];
}
}
-
+
return output;
};
-
+
this.prototype.seek = function(timestamp) {
var offset;
-
+
// if there was a Xing or VBRI tag with a seek table, use that
// otherwise guesstimate based on CBR bitrate
if (this.demuxer.seekPoints.length > 0) {
@@ -75,44 +75,44 @@ var MP3Decoder = AV.Decoder.extend(function() {
} else {
offset = timestamp * this.format.bitrate / 8 / this.format.sampleRate;
}
-
+
this.mp3_stream.reset(offset);
-
+
// try to find 3 consecutive valid frame headers in a row
for (var i = 0; i < 4096; i++) {
var pos = offset + i;
for (var j = 0; j < 3; j++) {
this.mp3_stream.reset(pos);
-
+
try {
var header = MP3FrameHeader.decode(this.mp3_stream);
} catch (e) {
break;
}
-
+
// skip the rest of the frame
var size = header.framesize();
if (size == null)
break;
-
+
pos += size;
}
-
+
// check if we're done
if (j === 3)
break;
}
-
+
// if we didn't find 3 frames, just try the first one and hope for the best
if (j !== 3)
i = 0;
-
+
this.mp3_stream.reset(offset + i);
-
+
// if we guesstimated, update the timestamp to another estimate of where we actually seeked to
if (this.demuxer.seekPoints.length === 0)
timestamp = this.stream.offset / (this.format.bitrate / 8) * this.format.sampleRate;
-
+
this.seeking = true;
return timestamp;
};
@@ -181,7 +181,7 @@ var MP3Demuxer = AV.Demuxer.extend(function() {
this.prototype.parseDuration = function(header, off) {
var stream = this.stream;
var frames;
-
+
if (this.metadata) {
var mllt = this.metadata.MPEGLocationLookupTable;
if (mllt) {
@@ -189,20 +189,20 @@ var MP3Demuxer = AV.Demuxer.extend(function() {
var refSize = mllt.bitsForBytesDeviation + mllt.bitsForMillisecondsDev;
var samples = 0;
var bytes = 0;
-
+
while (bitstream.available(refSize)) {
this.addSeekPoint(bytes, samples);
-
+
var bytesDev = bitstream.read(mllt.bitsForBytesDeviation);
bitstream.advance(mllt.bitsForMillisecondsDev); // skip millisecond deviation
-
+
bytes += mllt.bytesBetweenReference + bytesDev;
samples += mllt.framesBetweenReference * header.nbsamples() * 32;
}
-
+
this.addSeekPoint(bytes, samples);
}
-
+
if (this.metadata.length) {
this.emit('duration', parseInt(this.metadata.length, 10));
return true;
@@ -351,17 +351,17 @@ MP3Frame.prototype.decode = function(stream) {
this.header = MP3FrameHeader.decode(stream);
this.header.flags &= ~MP3FrameHeader.FLAGS.INCOMPLETE;
-
+
// make an instance of the decoder for this layer if needed
var decoder = this.decoders[this.header.layer - 1];
if (!decoder) {
var Layer = MP3Frame.layers[this.header.layer];
if (!Layer)
throw new Error("Layer " + this.header.layer + " is not supported.");
-
+
decoder = this.decoders[this.header.layer - 1] = new Layer();
}
-
+
decoder.decode(stream, this);
};
@@ -403,8 +403,8 @@ const BITRATES = [
64000, 80000, 96000, 112000, 128000, 144000, 160000 ] // II & III
];
-const SAMPLERATES = [
- 44100, 48000, 32000
+const SAMPLERATES = [
+ 44100, 48000, 32000
];
MP3FrameHeader.FLAGS = {
@@ -450,11 +450,11 @@ MP3FrameHeader.BUFFER_MDLEN = (511 + 2048 + MP3FrameHeader.BUFFER_GUARD);
MP3FrameHeader.prototype.copy = function() {
var clone = new MP3FrameHeader();
var keys = Object.keys(this);
-
+
for (var key in keys) {
clone[key] = this[key];
}
-
+
return clone;
}
@@ -469,17 +469,17 @@ MP3FrameHeader.prototype.nbsamples = function() {
MP3FrameHeader.prototype.framesize = function() {
if (this.bitrate === 0)
return null;
-
+
var padding = (this.flags & MP3FrameHeader.FLAGS.PADDING ? 1 : 0);
switch (this.layer) {
case 1:
var size = (this.bitrate * 12) / this.samplerate | 0;
return (size + padding) * 4;
-
+
case 2:
var size = (this.bitrate * 144) / this.samplerate | 0;
return size + padding;
-
+
case 3:
default:
var lsf = this.flags & MP3FrameHeader.FLAGS.LSF_EXT ? 1 : 0;
@@ -491,32 +491,32 @@ MP3FrameHeader.prototype.framesize = function() {
MP3FrameHeader.prototype.decode = function(stream) {
this.flags = 0;
this.private_bits = 0;
-
- // syncword
+
+ // syncword
stream.advance(11);
- // MPEG 2.5 indicator (really part of syncword)
+ // MPEG 2.5 indicator (really part of syncword)
if (stream.read(1) === 0)
this.flags |= MP3FrameHeader.FLAGS.MPEG_2_5_EXT;
- // ID
+ // ID
if (stream.read(1) === 0) {
this.flags |= MP3FrameHeader.FLAGS.LSF_EXT;
} else if (this.flags & MP3FrameHeader.FLAGS.MPEG_2_5_EXT) {
throw new AV.UnderflowError(); // LOSTSYNC
}
- // layer
+ // layer
this.layer = 4 - stream.read(2);
if (this.layer === 4)
throw new Error('Invalid layer');
- // protection_bit
+ // protection_bit
if (stream.read(1) === 0)
this.flags |= MP3FrameHeader.FLAGS.PROTECTION;
- // bitrate_index
+ // bitrate_index
var index = stream.read(4);
if (index === 15)
throw new Error('Invalid bitrate');
@@ -527,7 +527,7 @@ MP3FrameHeader.prototype.decode = function(stream) {
this.bitrate = BITRATES[this.layer - 1][index];
}
- // sampling_frequency
+ // sampling_frequency
index = stream.read(2);
if (index === 3)
throw new Error('Invalid sampling frequency');
@@ -541,32 +541,32 @@ MP3FrameHeader.prototype.decode = function(stream) {
this.samplerate /= 2;
}
- // padding_bit
+ // padding_bit
if (stream.read(1))
this.flags |= MP3FrameHeader.FLAGS.PADDING;
- // private_bit
+ // private_bit
if (stream.read(1))
this.private_bits |= PRIVATE.HEADER;
- // mode
+ // mode
this.mode = 3 - stream.read(2);
- // mode_extension
+ // mode_extension
this.mode_extension = stream.read(2);
- // copyright
+ // copyright
if (stream.read(1))
this.flags |= MP3FrameHeader.FLAGS.COPYRIGHT;
- // original/copy
+ // original/copy
if (stream.read(1))
this.flags |= MP3FrameHeader.FLAGS.ORIGINAL;
- // emphasis
+ // emphasis
this.emphasis = stream.read(2);
- // crc_check
+ // crc_check
if (this.flags & MP3FrameHeader.FLAGS.PROTECTION)
this.crc_target = stream.read(16);
};
@@ -576,10 +576,10 @@ MP3FrameHeader.decode = function(stream) {
var ptr = stream.next_frame;
var syncing = true;
var header = null;
-
+
while (syncing) {
syncing = false;
-
+
if (stream.sync) {
if (!stream.available(MP3FrameHeader.BUFFER_GUARD)) {
stream.next_frame = ptr;
@@ -594,49 +594,49 @@ MP3FrameHeader.decode = function(stream) {
stream.seek(ptr * 8);
if (!stream.doSync())
throw new AV.UnderflowError();
-
+
ptr = stream.nextByte();
}
-
+
// begin processing
stream.this_frame = ptr;
stream.next_frame = ptr + 1; // possibly bogus sync word
-
+
stream.seek(stream.this_frame * 8);
-
+
header = new MP3FrameHeader();
header.decode(stream);
-
+
if (header.bitrate === 0) {
if (stream.freerate === 0 || !stream.sync || (header.layer === 3 && stream.freerate > 640000))
MP3FrameHeader.free_bitrate(stream, header);
-
+
header.bitrate = stream.freerate;
header.flags |= MP3FrameHeader.FLAGS.FREEFORMAT;
}
-
+
// calculate beginning of next frame
var pad_slot = (header.flags & MP3FrameHeader.FLAGS.PADDING) ? 1 : 0;
-
+
if (header.layer === 1) {
var N = (((12 * header.bitrate / header.samplerate) << 0) + pad_slot) * 4;
} else {
var slots_per_frame = (header.layer === 3 && (header.flags & MP3FrameHeader.FLAGS.LSF_EXT)) ? 72 : 144;
var N = ((slots_per_frame * header.bitrate / header.samplerate) << 0) + pad_slot;
}
-
+
// verify there is enough data left in buffer to decode this frame
if (!stream.available(N + MP3FrameHeader.BUFFER_GUARD)) {
stream.next_frame = stream.this_frame;
throw new AV.UnderflowError();
}
-
+
stream.next_frame = stream.this_frame + N;
-
+
if (!stream.sync) {
// check that a valid frame header follows this frame
ptr = stream.next_frame;
-
+
if (!(stream.getU8(ptr) === 0xff && (stream.getU8(ptr + 1) & 0xe0) === 0xe0)) {
ptr = stream.next_frame = stream.this_frame + 1;
@@ -644,11 +644,11 @@ MP3FrameHeader.decode = function(stream) {
syncing = true;
continue;
}
-
+
stream.sync = true;
}
}
-
+
header.flags |= MP3FrameHeader.FLAGS.INCOMPLETE;
return header;
};
@@ -656,35 +656,35 @@ MP3FrameHeader.decode = function(stream) {
MP3FrameHeader.free_bitrate = function(stream, header) {
var pad_slot = header.flags & MP3FrameHeader.FLAGS.PADDING ? 1 : 0,
slots_per_frame = header.layer === 3 && header.flags & MP3FrameHeader.FLAGS.LSF_EXT ? 72 : 144;
-
+
var start = stream.offset();
var rate = 0;
-
+
while (stream.doSync()) {
var peek_header = header.copy();
var peek_stream = stream.copy();
-
+
if (peek_header.decode(peek_stream) && peek_header.layer === header.layer && peek_header.samplerate === header.samplerate) {
var N = stream.nextByte() - stream.this_frame;
-
+
if (header.layer === 1) {
rate = header.samplerate * (N - 4 * pad_slot + 4) / 48 / 1000 | 0;
} else {
rate = header.samplerate * (N - pad_slot + 1) / slots_per_frame / 1000 | 0;
}
-
+
if (rate >= 8)
break;
}
-
+
stream.advance(8);
}
-
+
stream.seek(start);
-
+
if (rate < 8 || (header.layer === 3 && rate > 640))
throw new AV.UnderflowError(); // LOSTSYNC
-
+
stream.freerate = rate * 1000;
};
@@ -3690,11 +3690,11 @@ var ID3Stream = AV.Base.extend({
this.stream = stream;
this.offset = 0;
},
-
+
read: function() {
if (!this.data) {
this.data = {};
-
+
// read all frames
var frame;
while (frame = this.readFrame()) {
@@ -3702,7 +3702,7 @@ var ID3Stream = AV.Base.extend({
if (frame.key in this.data) {
if (!Array.isArray(this.data[frame.key]))
this.data[frame.key] = [this.data[frame.key]];
-
+
this.data[frame.key].push(frame.value);
} else {
this.data[frame.key] = frame.value;
@@ -3712,20 +3712,20 @@ var ID3Stream = AV.Base.extend({
return this.data;
},
-
+
readFrame: function() {
if (this.offset >= this.header.length)
return null;
-
- // get the header
+
+ // get the header
var header = this.readHeader();
var decoder = header.identifier;
-
+
if (header.identifier.charCodeAt(0) === 0) {
this.offset += this.header.length + 1;
return null;
}
-
+
// map common frame names to a single type
if (!this.frameTypes[decoder]) {
for (var key in this.map) {
@@ -3740,15 +3740,15 @@ var ID3Stream = AV.Base.extend({
// decode the frame
var frame = this.decodeFrame(header, this.frameTypes[decoder]),
keys = Object.keys(frame);
-
- // if it only returned one key, use that as the value
+
+ // if it only returned one key, use that as the value
if (keys.length === 1)
frame = frame[keys[0]];
-
+
var result = {
value: frame
};
-
+
} else {
// No frame type found, treat it as binary
var result = {
@@ -3757,7 +3757,7 @@ var ID3Stream = AV.Base.extend({
}
result.key = this.names[header.identifier] ? this.names[header.identifier] : header.identifier;
-
+
// special sauce for cover art, which should just be a buffer
if (result.key === 'coverArt')
result.value = result.value.data;
@@ -3769,82 +3769,82 @@ var ID3Stream = AV.Base.extend({
decodeFrame: function(header, fields) {
var stream = this.stream,
start = stream.offset;
-
+
var encoding = 0, ret = {};
var len = Object.keys(fields).length, i = 0;
-
+
for (var key in fields) {
var type = fields[key];
var rest = header.length - (stream.offset - start);
i++;
-
+
// check for special field names
switch (key) {
case 'encoding':
encoding = stream.readUInt8();
continue;
-
+
case 'language':
ret.language = stream.readString(3);
continue;
}
-
+
// check types
- switch (type) {
+ switch (type) {
case 'latin1':
ret[key] = stream.readString(i === len ? rest : null, 'latin1');
break;
-
+
case 'string':
ret[key] = stream.readString(i === len ? rest : null, ENCODINGS[encoding]);
break;
-
+
case 'binary':
ret[key] = stream.readBuffer(rest)
break;
-
+
case 'int16':
ret[key] = stream.readInt16();
break;
-
+
case 'int8':
ret[key] = stream.readInt8();
break;
-
+
case 'int24':
ret[key] = stream.readInt24();
break;
-
+
case 'int32':
ret[key] = stream.readInt32();
break;
-
+
case 'int32+':
ret[key] = stream.readInt32();
if (rest > 4)
throw new Error('Seriously dude? Stop playing this song and get a life!');
-
+
break;
-
+
case 'date':
var val = stream.readString(8);
ret[key] = new Date(val.slice(0, 4), val.slice(4, 6) - 1, val.slice(6, 8));
break;
-
+
case 'frame_id':
ret[key] = stream.readString(4);
break;
-
+
default:
throw new Error('Unknown key type ' + type);
}
}
-
+
// Just in case something went wrong...
var rest = header.length - (stream.offset - start);
if (rest > 0)
stream.advance(rest);
-
+
return ret;
}
});
@@ -3852,23 +3852,23 @@ var ID3Stream = AV.Base.extend({
// ID3 v2.3 and v2.4 support
exports.ID3v23Stream = ID3Stream.extend({
readHeader: function() {
- var identifier = this.stream.readString(4);
+ var identifier = this.stream.readString(4);
var length = 0;
-
+
if (this.header.major === 4) {
for (var i = 0; i < 4; i++)
length = (length << 7) + (this.stream.readUInt8() & 0x7f);
} else {
length = this.stream.readUInt32();
}
-
+
return {
identifier: identifier,
length: length,
flags: this.stream.readUInt16()
};
},
-
+
map: {
text: [
// Identification Frames
@@ -3885,55 +3885,55 @@ exports.ID3v23Stream = ID3Stream.extend({
// Other Text Frames
'TOFN', 'TDLY', 'TDEN', 'TDOR', 'TDRC', 'TDRL', 'TDTG', 'TSSE', 'TSOA', 'TSOP', 'TSOT',
-
+
// Deprecated Text Frames
'TDAT', 'TIME', 'TORY', 'TRDA', 'TSIZ', 'TYER',
-
+
// Non-standard iTunes Frames
'TCMP', 'TSO2', 'TSOC'
],
-
+
url: [
'WCOM', 'WCOP', 'WOAF', 'WOAR', 'WOAS', 'WORS', 'WPAY', 'WPUB'
]
},
-
- frameTypes: {
+
+ frameTypes: {
text: {
encoding: 1,
value: 'string'
},
-
+
url: {
value: 'latin1'
},
-
+
TXXX: {
encoding: 1,
description: 'string',
value: 'string'
},
-
+
WXXX: {
encoding: 1,
description: 'string',
value: 'latin1',
},
-
+
USLT: {
encoding: 1,
language: 1,
description: 'string',
value: 'string'
},
-
+
COMM: {
encoding: 1,
language: 1,
description: 'string',
value: 'string'
},
-
+
APIC: {
encoding: 1,
mime: 'latin1',
@@ -3941,7 +3941,7 @@ exports.ID3v23Stream = ID3Stream.extend({
description: 'string',
data: 'binary'
},
-
+
UFID: {
owner: 'latin1',
identifier: 'binary'
@@ -3950,12 +3950,12 @@ exports.ID3v23Stream = ID3Stream.extend({
MCDI: {
value: 'binary'
},
-
+
PRIV: {
owner: 'latin1',
value: 'binary'
},
-
+
GEOB: {
encoding: 1,
mime: 'latin1',
@@ -3963,29 +3963,29 @@ exports.ID3v23Stream = ID3Stream.extend({
description: 'string',
data: 'binary'
},
-
+
PCNT: {
value: 'int32+'
},
-
+
POPM: {
email: 'latin1',
rating: 'int8',
counter: 'int32+'
},
-
+
AENC: {
owner: 'latin1',
previewStart: 'int16',
previewLength: 'int16',
encryptionInfo: 'binary'
},
-
+
ETCO: {
format: 'int8',
data: 'binary' // TODO
},
-
+
MLLT: {
framesBetweenReference: 'int16',
bytesBetweenReference: 'int24',
@@ -3994,12 +3994,12 @@ exports.ID3v23Stream = ID3Stream.extend({
bitsForMillisecondsDev: 'int8',
data: 'binary' // TODO
},
-
+
SYTC: {
format: 'int8',
tempoData: 'binary' // TODO
},
-
+
SYLT: {
encoding: 1,
language: 1,
@@ -4008,18 +4008,18 @@ exports.ID3v23Stream = ID3Stream.extend({
description: 'string',
data: 'binary' // TODO
},
-
+
RVA2: {
identification: 'latin1',
data: 'binary' // TODO
},
-
+
EQU2: {
interpolationMethod: 'int8',
identification: 'latin1',
data: 'binary' // TODO
},
-
+
RVRB: {
left: 'int16',
right: 'int16',
@@ -4032,37 +4032,37 @@ exports.ID3v23Stream = ID3Stream.extend({
premixLR: 'int8',
premixRL: 'int8'
},
-
+
RBUF: {
size: 'int24',
flag: 'int8',
offset: 'int32'
},
-
+
LINK: {
identifier: 'frame_id',
url: 'latin1',
data: 'binary' // TODO stringlist?
},
-
+
POSS: {
format: 'int8',
position: 'binary' // TODO
},
-
+
USER: {
encoding: 1,
language: 1,
value: 'string'
},
-
+
OWNE: {
encoding: 1,
price: 'latin1',
purchaseDate: 'date',
seller: 'string'
},
-
+
COMR: {
encoding: 1,
price: 'latin1',
@@ -4074,28 +4074,28 @@ exports.ID3v23Stream = ID3Stream.extend({
logoMime: 'latin1',
logo: 'binary'
},
-
+
ENCR: {
owner: 'latin1',
methodSymbol: 'int8',
data: 'binary'
},
-
+
GRID: {
owner: 'latin1',
groupSymbol: 'int8',
data: 'binary'
},
-
+
SIGN: {
groupSymbol: 'int8',
signature: 'binary'
},
-
+
SEEK: {
value: 'int32'
},
-
+
ASPI: {
dataStart: 'int32',
dataLength: 'int32',
@@ -4103,25 +4103,25 @@ exports.ID3v23Stream = ID3Stream.extend({
bitsPerPoint: 'int8',
data: 'binary' // TODO
},
-
+
// Deprecated ID3 v2.3 frames
IPLS: {
encoding: 1,
value: 'string' // list?
},
-
+
RVAD: {
adjustment: 'int8',
bits: 'int8',
data: 'binary' // TODO
},
-
+
EQUA: {
adjustmentBits: 'int8',
data: 'binary' // TODO
}
},
-
+
names: {
// Identification Frames
'TIT1': 'grouping',
@@ -4177,10 +4177,10 @@ exports.ID3v23Stream = ID3Stream.extend({
'TSOA': 'albumSortOrder',
'TSOP': 'performerSortOrder',
'TSOT': 'titleSortOrder',
-
+
// User defined text information
'TXXX': 'userText',
-
+
// Unsynchronised lyrics/text transcription
'USLT': 'lyrics',
@@ -4195,7 +4195,7 @@ exports.ID3v23Stream = ID3Stream.extend({
// Comment Frame
'COMM': 'comments',
-
+
// URL link frames
'WCOM': 'commercialInformation',
'WCOP': 'copyrightInformation',
@@ -4243,7 +4243,7 @@ exports.ID3v23Stream = ID3Stream.extend({
'IPLS': 'involvedPeopleList',
'RVAD': 'volumeAdjustment',
'EQUA': 'equalization',
-
+
// Non-standard iTunes frames
'TCMP': 'compilation',
'TSO2': 'albumArtistSortOrder',
@@ -4252,19 +4252,19 @@ exports.ID3v23Stream = ID3Stream.extend({
});
// ID3 v2.2 support
-exports.ID3v22Stream = exports.ID3v23Stream.extend({
+exports.ID3v22Stream = exports.ID3v23Stream.extend({
readHeader: function() {
var id = this.stream.readString(3);
-
+
if (this.frameReplacements[id] && !this.frameTypes[id])
this.frameTypes[id] = this.frameReplacements[id];
-
+
return {
identifier: this.replacements[id] || id,
length: this.stream.readUInt24()
};
},
-
+
// map 3 char ID3 v2.2 names to 4 char ID3 v2.3/4 names
replacements: {
'UFI': 'UFID',
@@ -4304,7 +4304,7 @@ exports.ID3v22Stream = exports.ID3v23Stream.extend({
'TOL': 'TOLY',
'TOR': 'TORY',
'TXX': 'TXXX',
-
+
'WAF': 'WOAF',
'WAR': 'WOAR',
'WAS': 'WOAS',
@@ -4312,7 +4312,7 @@ exports.ID3v22Stream = exports.ID3v23Stream.extend({
'WCP': 'WCOP',
'WPB': 'WPUB',
'WXX': 'WXXX',
-
+
'IPL': 'IPLS',
'MCI': 'MCDI',
'ETC': 'ETCO',
@@ -4324,14 +4324,14 @@ exports.ID3v22Stream = exports.ID3v23Stream.extend({
'RVA': 'RVAD',
'EQU': 'EQUA',
'REV': 'RVRB',
-
+
'GEO': 'GEOB',
'CNT': 'PCNT',
'POP': 'POPM',
'BUF': 'RBUF',
'CRA': 'AENC',
'LNK': 'LINK',
-
+
// iTunes stuff
'TST': 'TSOT',
'TSP': 'TSOP',
@@ -4340,7 +4340,7 @@ exports.ID3v22Stream = exports.ID3v23Stream.extend({
'TS2': 'TSO2',
'TSC': 'TSOC'
},
-
+
// replacements for ID3 v2.3/4 frames
frameReplacements: {
PIC: {
@@ -4350,7 +4350,7 @@ exports.ID3v22Stream = exports.ID3v23Stream.extend({
description: 'string',
data: 'binary'
},
-
+
CRM: {
owner: 'latin1',
description: 'latin1',
@@ -4552,7 +4552,7 @@ var MP3FrameHeader = require('./header');
var MP3Frame = require('./frame');
var utils = require('./utils');
-function Layer1() {
+function Layer1() {
this.allocation = utils.makeArray([2, 32], Uint8Array);
this.scalefactor = utils.makeArray([2, 32], Uint8Array);
}
@@ -4571,17 +4571,17 @@ const LINEAR_TABLE = new Float32Array([
Layer1.prototype.decode = function(stream, frame) {
var header = frame.header;
var nch = header.nchannels();
-
+
var bound = 32;
if (header.mode === MP3FrameHeader.MODE.JOINT_STEREO) {
header.flags |= MP3FrameHeader.FLAGS.I_STEREO;
bound = 4 + header.mode_extension * 4;
}
-
+
if (header.flags & MP3FrameHeader.FLAGS.PROTECTION) {
// TODO: crc check
}
-
+
// decode bit allocations
var allocation = this.allocation;
for (var sb = 0; sb < bound; sb++) {
@@ -4589,36 +4589,36 @@ Layer1.prototype.decode = function(stream, frame) {
var nb = stream.read(4);
if (nb === 15)
throw new Error("forbidden bit allocation value");
-
+
allocation[ch][sb] = nb ? nb + 1 : 0;
}
}
-
+
for (var sb = bound; sb < 32; sb++) {
var nb = stream.read(4);
if (nb === 15)
throw new Error("forbidden bit allocation value");
-
+
allocation[0][sb] =
allocation[1][sb] = nb ? nb + 1 : 0;
}
-
+
// decode scalefactors
var scalefactor = this.scalefactor;
for (var sb = 0; sb < 32; sb++) {
for (var ch = 0; ch < nch; ch++) {
if (allocation[ch][sb]) {
scalefactor[ch][sb] = stream.read(6);
-
+
/*
* Scalefactor index 63 does not appear in Table B.1 of
* ISO/IEC 11172-3. Nonetheless, other implementations accept it,
- * so we do as well
+ * so we do as well
*/
}
}
}
-
+
// decode samples
for (var s = 0; s < 12; s++) {
for (var sb = 0; sb < bound; sb++) {
@@ -4627,12 +4627,12 @@ Layer1.prototype.decode = function(stream, frame) {
frame.sbsample[ch][s][sb] = nb ? this.sample(stream, nb) * tables.SF_TABLE[scalefactor[ch][sb]] : 0;
}
}
-
+
for (var sb = bound; sb < 32; sb++) {
var nb = allocation[0][sb];
if (nb) {
var sample = this.sample(stream, nb);
-
+
for (var ch = 0; ch < nch; ch++) {
frame.sbsample[ch][s][sb] = sample * tables.SF_TABLE[scalefactor[ch][sb]];
}
@@ -4647,12 +4647,12 @@ Layer1.prototype.decode = function(stream, frame) {
Layer1.prototype.sample = function(stream, nb) {
var sample = stream.read(nb);
-
+
// invert most significant bit, and form a 2's complement sample
sample ^= 1 << (nb - 1);
sample |= -(sample & (1 << (nb - 1)));
sample /= (1 << (nb - 1));
-
+
// requantize the sample
// s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1))
sample += 1 >> (nb - 1);
@@ -4667,7 +4667,7 @@ var MP3FrameHeader = require('./header');
var MP3Frame = require('./frame');
var utils = require('./utils');
-function Layer2() {
+function Layer2() {
this.samples = new Float64Array(3);
this.allocation = utils.makeArray([2, 32], Uint8Array);
this.scfsi = utils.makeArray([2, 32], Uint8Array);
@@ -4681,19 +4681,19 @@ const SBQUANT = [
// ISO/IEC 11172-3 Table B.2a
{ sblimit: 27, offsets:
[ 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 ] },
-
+
// ISO/IEC 11172-3 Table B.2b
{ sblimit: 30, offsets:
[ 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0 ] },
-
+
// ISO/IEC 11172-3 Table B.2c
{ sblimit: 8, offsets:
[ 5, 5, 2, 2, 2, 2, 2, 2 ] },
-
+
// ISO/IEC 11172-3 Table B.2d
{ sblimit: 12, offsets:
[ 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ] },
-
+
// ISO/IEC 13818-3 Table B.1
{ sblimit: 30, offsets:
[ 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] }
@@ -4751,17 +4751,17 @@ Layer2.prototype.decode = function(stream, frame) {
var header = frame.header;
var nch = header.nchannels();
var index;
-
+
if (header.flags & MP3FrameHeader.FLAGS.LSF_EXT) {
index = 4;
} else if (header.flags & MP3FrameHeader.FLAGS.FREEFORMAT) {
index = header.samplerate === 48000 ? 0 : 1;
} else {
var bitrate_per_channel = header.bitrate;
-
+
if (nch === 2) {
bitrate_per_channel /= 2;
-
+
/*
* ISO/IEC 11172-3 allows only single channel mode for 32, 48, 56, and
* 80 kbps bitrates in Layer II, but some encoders ignore this
@@ -4775,7 +4775,7 @@ Layer2.prototype.decode = function(stream, frame) {
if (bitrate_per_channel > 192000)
throw new Error('bad bitrate/mode combination');
}
-
+
if (bitrate_per_channel <= 48000)
index = header.samplerate === 32000 ? 3 : 2;
else if (bitrate_per_channel <= 80000)
@@ -4783,35 +4783,35 @@ Layer2.prototype.decode = function(stream, frame) {
else
index = header.samplerate === 48000 ? 0 : 1;
}
-
+
var sblimit = SBQUANT[index].sblimit;
var offsets = SBQUANT[index].offsets;
-
+
var bound = 32;
if (header.mode === MP3FrameHeader.MODE.JOINT_STEREO) {
header.flags |= MP3FrameHeader.FLAGS.I_STEREO;
bound = 4 + header.mode_extension * 4;
}
-
+
if (bound > sblimit)
bound = sblimit;
-
+
// decode bit allocations
var allocation = this.allocation;
for (var sb = 0; sb < bound; sb++) {
var nbal = BITALLOC[offsets[sb]].nbal;
-
+
for (var ch = 0; ch < nch; ch++)
allocation[ch][sb] = stream.read(nbal);
}
-
+
for (var sb = bound; sb < sblimit; sb++) {
var nbal = BITALLOC[offsets[sb]].nbal;
-
+
allocation[0][sb] =
allocation[1][sb] = stream.read(nbal);
}
-
+
// decode scalefactor selection info
var scfsi = this.scfsi;
for (var sb = 0; sb < sblimit; sb++) {
@@ -4820,36 +4820,36 @@ Layer2.prototype.decode = function(stream, frame) {
scfsi[ch][sb] = stream.read(2);
}
}
-
+
if (header.flags & MP3FrameHeader.FLAGS.PROTECTION) {
// TODO: crc check
}
-
+
// decode scalefactors
var scalefactor = this.scalefactor;
for (var sb = 0; sb < sblimit; sb++) {
for (var ch = 0; ch < nch; ch++) {
if (allocation[ch][sb]) {
scalefactor[ch][sb][0] = stream.read(6);
-
+
switch (scfsi[ch][sb]) {
case 2:
scalefactor[ch][sb][2] =
scalefactor[ch][sb][1] = scalefactor[ch][sb][0];
break;
-
+
case 0:
scalefactor[ch][sb][1] = stream.read(6);
// fall through
-
+
case 1:
case 3:
scalefactor[ch][sb][2] = stream.read(6);
}
-
+
if (scfsi[ch][sb] & 1)
scalefactor[ch][sb][1] = scalefactor[ch][sb][scfsi[ch][sb] - 1];
-
+
/*
* Scalefactor index 63 does not appear in Table B.1 of
* ISO/IEC 11172-3. Nonetheless, other implementations accept it,
@@ -4858,16 +4858,16 @@ Layer2.prototype.decode = function(stream, frame) {
}
}
}
-
+
// decode samples
for (var gr = 0; gr < 12; gr++) {
// normal
for (var sb = 0; sb < bound; sb++) {
- for (var ch = 0; ch < nch; ch++) {
+ for (var ch = 0; ch < nch; ch++) {
if (index = allocation[ch][sb]) {
index = OFFSETS[BITALLOC[offsets[sb]].offset][index - 1];
this.decodeSamples(stream, QC_TABLE[index]);
-
+
var scale = tables.SF_TABLE[scalefactor[ch][sb][gr >> 2]];
for (var s = 0; s < 3; s++) {
frame.sbsample[ch][3 * gr + s][sb] = this.samples[s] * scale;
@@ -4879,13 +4879,13 @@ Layer2.prototype.decode = function(stream, frame) {
}
}
}
-
+
// joint stereo
for (var sb = bound; sb < sblimit; sb++) {
if (index = allocation[0][sb]) {
index = OFFSETS[BITALLOC[offsets[sb]].offset][index - 1];
this.decodeSamples(stream, QC_TABLE[index]);
-
+
for (var ch = 0; ch < nch; ch++) {
var scale = tables.SF_TABLE[scalefactor[ch][sb][gr >> 2]];
for (var s = 0; s < 3; s++) {
@@ -4900,7 +4900,7 @@ Layer2.prototype.decode = function(stream, frame) {
}
}
}
-
+
// the rest
for (var ch = 0; ch < nch; ch++) {
for (var s = 0; s < 3; s++) {
@@ -4915,12 +4915,12 @@ Layer2.prototype.decode = function(stream, frame) {
Layer2.prototype.decodeSamples = function(stream, quantclass) {
var sample = this.samples;
var nb = quantclass.group;
-
+
if (nb) {
// degrouping
var c = stream.read(quantclass.bits);
var nlevels = quantclass.nlevels;
-
+
for (var s = 0; s < 3; s++) {
sample[s] = c % nlevels;
c = c / nlevels | 0;
@@ -4931,13 +4931,13 @@ Layer2.prototype.decodeSamples = function(stream, quantclass) {
sample[s] = stream.read(nb);
}
}
-
+
for (var s = 0; s < 3; s++) {
// invert most significant bit, and form a 2's complement sample
var requantized = sample[s] ^ (1 << (nb - 1));
requantized |= -(requantized & (1 << (nb - 1)));
requantized /= (1 << (nb - 1));
-
+
// requantize the sample
sample[s] = (requantized + quantclass.D) * quantclass.C;
}
@@ -4972,14 +4972,14 @@ function MP3Channel() {
this.big_values = null;
this.global_gain = null;
this.scalefac_compress = null;
-
+
this.flags = null;
this.block_type = null;
this.table_select = new Uint8Array(3);
this.subblock_gain = new Uint8Array(3);
this.region0_count = null;
this.region1_count = null;
-
+
// from main_data
this.scalefac = new Uint8Array(39);
}
@@ -4987,14 +4987,14 @@ function MP3Channel() {
function Layer3() {
this.imdct = new IMDCT();
this.si = new MP3SideInfo();
-
+
// preallocate reusable typed arrays for performance
this.xr = [new Float64Array(576), new Float64Array(576)];
this._exponents = new Int32Array(39);
this.reqcache = new Float64Array(16);
this.modes = new Int16Array(39);
this.output = new Float64Array(36);
-
+
this.tmp = utils.makeArray([32, 3, 6]);
this.tmp2 = new Float64Array(32 * 3 * 6);
}
@@ -5005,53 +5005,53 @@ Layer3.prototype.decode = function(stream, frame) {
var header = frame.header;
var next_md_begin = 0;
var md_len = 0;
-
+
var nch = header.nchannels();
var si_len = (header.flags & MP3FrameHeader.FLAGS.LSF_EXT) ? (nch === 1 ? 9 : 17) : (nch === 1 ? 17 : 32);
-
+
// check frame sanity
if (stream.next_frame - stream.nextByte() < si_len) {
stream.md_len = 0;
throw new Error('Bad frame length');
}
-
+
// check CRC word
if (header.flags & MP3FrameHeader.FLAGS.PROTECTION) {
// TODO: crc check
}
-
+
// decode frame side information
- var sideInfo = this.sideInfo(stream, nch, header.flags & MP3FrameHeader.FLAGS.LSF_EXT);
+ var sideInfo = this.sideInfo(stream, nch, header.flags & MP3FrameHeader.FLAGS.LSF_EXT);
var si = sideInfo.si;
var data_bitlen = sideInfo.data_bitlen;
var priv_bitlen = sideInfo.priv_bitlen;
-
+
header.flags |= priv_bitlen;
header.private_bits |= si.private_bits;
-
+
// find main_data of next frame
var peek = stream.copy();
peek.seek(stream.next_frame * 8);
-
- var nextHeader = peek.read(16);
+
+ var nextHeader = peek.read(16);
if ((nextHeader & 0xffe6) === 0xffe2) { // syncword | layer
if ((nextHeader & 1) === 0) // protection bit
peek.advance(16); // crc check
-
+
peek.advance(16); // skip the rest of the header
next_md_begin = peek.read((nextHeader & 8) ? 9 : 8);
}
-
+
// find main_data of this frame
var frame_space = stream.next_frame - stream.nextByte();
-
+
if (next_md_begin > si.main_data_begin + frame_space)
next_md_begin = 0;
-
+
var md_len = si.main_data_begin + frame_space - next_md_begin;
var frame_used = 0;
var ptr;
-
+
if (si.main_data_begin === 0) {
ptr = stream.stream;
stream.md_len = 0;
@@ -5061,27 +5061,27 @@ Layer3.prototype.decode = function(stream, frame) {
throw new Error('bad main_data_begin pointer');
} else {
var old_md_len = stream.md_len;
-
+
if (md_len > si.main_data_begin) {
if (stream.md_len + md_len - si.main_data_begin > MP3FrameHeader.BUFFER_MDLEN) {
throw new Error("Assertion failed: (stream.md_len + md_len - si.main_data_begin <= MAD_MP3FrameHeader.BUFFER_MDLEN)");
}
-
+
frame_used = md_len - si.main_data_begin;
this.memcpy(stream.main_data, stream.md_len, stream.stream.stream, stream.nextByte(), frame_used);
stream.md_len += frame_used;
}
-
+
ptr = new AV.Bitstream(AV.Stream.fromBuffer(new AV.Buffer(stream.main_data)));
ptr.advance((old_md_len - si.main_data_begin) * 8);
}
}
-
+
var frame_free = frame_space - frame_used;
-
+
// decode main_data
this.decodeMainData(ptr, frame, si, nch);
-
+
// preload main_data buffer with up to 511 bytes for next frame(s)
if (frame_free >= next_md_begin) {
this.memcpy(stream.main_data, 0, stream.stream.stream, stream.next_frame - next_md_begin, next_md_begin);
@@ -5099,7 +5099,7 @@ Layer3.prototype.decode = function(stream, frame) {
} else {
stream.md_len = 0;
}
-
+
this.memcpy(stream.main_data, stream.md_len, stream.stream.stream, stream.next_frame - frame_free, frame_free);
stream.md_len += frame_free;
}
@@ -5121,7 +5121,7 @@ Layer3.prototype.sideInfo = function(stream, nch, lsf) {
var si = this.si;
var data_bitlen = 0;
var priv_bitlen = lsf ? ((nch === 1) ? 1 : 2) : ((nch === 1) ? 5 : 3);
-
+
si.main_data_begin = stream.read(lsf ? 8 : 9);
si.private_bits = stream.read(priv_bitlen);
@@ -5131,13 +5131,13 @@ Layer3.prototype.sideInfo = function(stream, nch, lsf) {
for (var ch = 0; ch < nch; ++ch)
si.scfsi[ch] = stream.read(4);
}
-
+
for (var gr = 0; gr < ngr; gr++) {
var granule = si.gr[gr];
-
+
for (var ch = 0; ch < nch; ch++) {
var channel = granule.ch[ch];
-
+
channel.part2_3_length = stream.read(12);
channel.big_values = stream.read(9);
channel.global_gain = stream.read(8);
@@ -5187,7 +5187,7 @@ Layer3.prototype.sideInfo = function(stream, nch, lsf) {
channel.flags |= stream.read(lsf ? 2 : 3);
}
}
-
+
return {
si: si,
data_bitlen: data_bitlen,
@@ -5208,20 +5208,20 @@ Layer3.prototype.decodeMainData = function(stream, frame, si, nch) {
if (header.flags & MP3FrameHeader.FLAGS.MPEG_2_5_EXT)
sfreqi += 3;
-
+
// scalefactors, Huffman decoding, requantization
var ngr = (header.flags & MP3FrameHeader.FLAGS.LSF_EXT) ? 1 : 2;
var xr = this.xr;
-
+
for (var gr = 0; gr < ngr; ++gr) {
var granule = si.gr[gr];
var sfbwidth = [];
var l = 0;
-
+
for (var ch = 0; ch < nch; ++ch) {
var channel = granule.ch[ch];
var part2_length;
-
+
sfbwidth[ch] = tables.SFBWIDTH_TABLE[sfreqi].l;
if (channel.block_type === 2) {
sfbwidth[ch] = (channel.flags & tables.MIXED_BLOCK_FLAG) ? tables.SFBWIDTH_TABLE[sfreqi].m : tables.SFBWIDTH_TABLE[sfreqi].s;
@@ -5235,19 +5235,19 @@ Layer3.prototype.decodeMainData = function(stream, frame, si, nch) {
this.huffmanDecode(stream, xr[ch], channel, sfbwidth[ch], part2_length);
}
-
+
// joint stereo processing
if (header.mode === MP3FrameHeader.MODE.JOINT_STEREO && header.mode_extension !== 0)
this.stereo(xr, si.gr, gr, header, sfbwidth[0]);
-
+
// reordering, alias reduction, IMDCT, overlap-add, frequency inversion
for (var ch = 0; ch < nch; ch++) {
var channel = granule.ch[ch];
var sample = frame.sbsample[ch].slice(18 * gr);
-
+
var sb, l = 0, i, sblimit;
var output = this.output;
-
+
if (channel.block_type === 2) {
this.reorder(xr[ch], channel, sfbwidth[ch]);
@@ -5263,7 +5263,7 @@ Layer3.prototype.decodeMainData = function(stream, frame, si, nch) {
} else {
this.aliasreduce(xr[ch], 576);
}
-
+
// subbands 0-1
if (channel.block_type !== 2 || (channel.flags & tables.MIXED_BLOCK_FLAG)) {
var block_type = channel.block_type;
@@ -5282,7 +5282,7 @@ Layer3.prototype.decodeMainData = function(stream, frame, si, nch) {
this.overlap(output, frame.overlap[ch][sb], sample, sb);
}
}
-
+
this.freqinver(sample, 1);
// (nonzero) subbands 2-31
@@ -5290,7 +5290,7 @@ Layer3.prototype.decodeMainData = function(stream, frame, si, nch) {
while (i > 36 && xr[ch][i - 1] === 0) {
--i;
}
-
+
sblimit = 32 - (((576 - i) / 18) << 0);
if (channel.block_type !== 2) {
@@ -5312,7 +5312,7 @@ Layer3.prototype.decodeMainData = function(stream, frame, si, nch) {
this.freqinver(sample, sb);
}
}
-
+
// remaining (zero) subbands
for (var sb = sblimit; sb < 32; ++sb) {
this.overlap_z(frame.overlap[ch][sb], sample, sb);
@@ -5329,7 +5329,7 @@ Layer3.prototype.scalefactors = function(stream, channel, gr0ch, scfsi) {
var slen1 = tables.SFLEN_TABLE[channel.scalefac_compress].slen1;
var slen2 = tables.SFLEN_TABLE[channel.scalefac_compress].slen2;
var sfbi;
-
+
if (channel.block_type === 2) {
sfbi = 0;
@@ -5379,7 +5379,7 @@ Layer3.prototype.scalefactors = function(stream, channel, gr0ch, scfsi) {
channel.scalefac[21] = 0;
}
-
+
return stream.offset() - start;
};
@@ -5389,14 +5389,14 @@ Layer3.prototype.scalefactors_lsf = function(stream, channel, gr1ch, mode_extens
var index = channel.block_type === 2 ? (channel.flags & tables.MIXED_BLOCK_FLAG ? 2 : 1) : 0;
var slen = new Int32Array(4);
var nsfb;
-
+
if (!((mode_extension & tables.I_STEREO) && gr1ch)) {
if (scalefac_compress < 400) {
slen[0] = (scalefac_compress >>> 4) / 5;
slen[1] = (scalefac_compress >>> 4) % 5;
slen[2] = (scalefac_compress % 16) >>> 2;
slen[3] = scalefac_compress % 4;
-
+
nsfb = tables.NSFB_TABLE[0][index];
} else if (scalefac_compress < 500) {
scalefac_compress -= 400;
@@ -5418,20 +5418,20 @@ Layer3.prototype.scalefactors_lsf = function(stream, channel, gr1ch, mode_extens
channel.flags |= tables.PREFLAG;
nsfb = tables.NSFB_TABLE[2][index];
}
-
+
var n = 0;
for (var part = 0; part < 4; part++) {
for (var i = 0; i < nsfb[part]; i++) {
channel.scalefac[n++] = stream.read(slen[part]);
}
}
-
+
while (n < 39) {
channel.scalefac[n++] = 0;
}
} else { // (mode_extension & tables.I_STEREO) && gr1ch (i.e. ch == 1)
scalefac_compress >>>= 1;
-
+
if (scalefac_compress < 180) {
slen[0] = scalefac_compress / 36;
slen[1] = (scalefac_compress % 36) / 6;
@@ -5458,7 +5458,7 @@ Layer3.prototype.scalefactors_lsf = function(stream, channel, gr1ch, mode_extens
nsfb = tables.NSFB_TABLE[5][index];
}
-
+
var n = 0;
for (var part = 0; part < 4; ++part) {
var max = (1 << slen[part]) - 1;
@@ -5469,58 +5469,58 @@ Layer3.prototype.scalefactors_lsf = function(stream, channel, gr1ch, mode_extens
gr1ch.scalefac[n++] = is_pos === max ? 1 : 0;
}
}
-
+
while (n < 39) {
channel.scalefac[n] = 0;
gr1ch.scalefac[n++] = 0; // apparently not illegal
}
}
-
+
return stream.offset() - start;
};
Layer3.prototype.huffmanDecode = function(stream, xr, channel, sfbwidth, part2_length) {
var exponents = this._exponents;
var sfbwidthptr = 0;
-
- var bits_left = channel.part2_3_length - part2_length;
+
+ var bits_left = channel.part2_3_length - part2_length;
if (bits_left < 0)
throw new Error('bad audio data length');
-
+
this.exponents(channel, sfbwidth, exponents);
-
+
var peek = stream.copy();
stream.advance(bits_left);
-
+
/* align bit reads to byte boundaries */
var cachesz = 8 - peek.bitPosition;
cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7;
-
+
var bitcache = peek.read(cachesz);
bits_left -= cachesz;
var xrptr = 0;
-
+
// big_values
var region = 0;
var reqcache = this.reqcache;
-
+
var sfbound = xrptr + sfbwidth[sfbwidthptr++];
var rcount = channel.region0_count + 1;
-
+
var entry = huffman.huff_pair_table[channel.table_select[region]];
var table = entry.table;
var linbits = entry.linbits;
var startbits = entry.startbits;
-
+
if (typeof table === 'undefined')
throw new Error('bad Huffman table select');
-
+
var expptr = 0;
var exp = exponents[expptr++];
var reqhits = 0;
var big_values = channel.big_values;
-
+
while (big_values-- && cachesz + bits_left > 0) {
if (xrptr === sfbound) {
sfbound += sfbwidth[sfbwidthptr++];
@@ -5548,29 +5548,29 @@ Layer3.prototype.huffmanDecode = function(stream, xr, channel, sfbwidth, part2_l
++expptr;
}
-
+
if (cachesz < 21) {
var bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7;
bitcache = (bitcache << bits) | peek.read(bits);
cachesz += bits;
bits_left -= bits;
}
-
+
var clumpsz = startbits;
var pair = table[ (((bitcache) >> ((cachesz) - (clumpsz))) & ((1 << (clumpsz)) - 1))];
-
+
while (!pair.final) {
cachesz -= clumpsz;
clumpsz = pair.ptr.bits;
pair = table[pair.ptr.offset + (((bitcache) >> ((cachesz) - (clumpsz))) & ((1 << (clumpsz)) - 1))];
}
-
+
cachesz -= pair.value.hlen;
-
+
if (linbits) {
var value = pair.value.x;
var x_final = false;
-
+
switch (value) {
case 0:
xr[xrptr] = 0;
@@ -5597,17 +5597,17 @@ Layer3.prototype.huffmanDecode = function(stream, xr, channel, sfbwidth, part2_l
reqhits |= (1 << value);
requantized = reqcache[value] = this.requantize(value, exp);
}
-
+
x_final = true;
}
-
+
if(x_final) {
xr[xrptr] = ((bitcache) & (1 << ((cachesz--) - 1))) ? -requantized : requantized;
}
-
+
value = pair.value.y;
var y_final = false;
-
+
switch (value) {
case 0:
xr[xrptr + 1] = 0;
@@ -5635,14 +5635,14 @@ Layer3.prototype.huffmanDecode = function(stream, xr, channel, sfbwidth, part2_l
reqcache[value] = this.requantize(value, exp);
requantized = reqcache[value];
}
-
+
y_final = true;
}
-
+
if(y_final) {
xr[xrptr + 1] = ((bitcache) & (1 << ((cachesz--) - 1))) ? -requantized : requantized;
}
-
+
} else {
var value = pair.value.x;
@@ -5677,29 +5677,29 @@ Layer3.prototype.huffmanDecode = function(stream, xr, channel, sfbwidth, part2_l
xrptr += 2;
}
-
+
if (cachesz + bits_left < 0)
throw new Error('Huffman data overrun');
-
- // count1
+
+ // count1
var table = huffman.huff_quad_table[channel.flags & tables.COUNT1TABLE_SELECT];
var requantized = this.requantize(1, exp);
-
+
while (cachesz + bits_left > 0 && xrptr <= 572) {
if (cachesz < 10) {
bitcache = (bitcache << 16) | peek.read(16);
cachesz += 16;
bits_left -= 16;
}
-
+
var quad = table[(((bitcache) >> ((cachesz) - (4))) & ((1 << (4)) - 1))];
-
+
// quad tables guaranteed to have at most one extra lookup
if (!quad.final) {
cachesz -= 4;
quad = table[quad.ptr.offset + (((bitcache) >> ((cachesz) - (quad.ptr.bits))) & ((1 << (quad.ptr.bits)) - 1))];
}
-
+
cachesz -= quad.value.hlen;
if (xrptr === sfbound) {
@@ -5712,7 +5712,7 @@ Layer3.prototype.huffmanDecode = function(stream, xr, channel, sfbwidth, part2_l
++expptr;
}
-
+
// v (0..1)
xr[xrptr] = quad.value.v ? (((bitcache) & (1 << ((cachesz--) - 1))) ? -requantized : requantized) : 0;
@@ -5730,7 +5730,7 @@ Layer3.prototype.huffmanDecode = function(stream, xr, channel, sfbwidth, part2_l
++expptr;
}
-
+
// x (0..1)
xr[xrptr] = quad.value.x ? (((bitcache) & (1 << ((cachesz--) - 1))) ? -requantized : requantized) : 0;
@@ -5738,18 +5738,18 @@ Layer3.prototype.huffmanDecode = function(stream, xr, channel, sfbwidth, part2_l
xr[xrptr + 1] = quad.value.y ? (((bitcache) & (1 << ((cachesz--) - 1))) ? -requantized : requantized) : 0;
xrptr += 2;
-
+
if (cachesz + bits_left < 0) {
// technically the bitstream is misformatted, but apparently
// some encoders are just a bit sloppy with stuffing bits
xrptr -= 4;
}
}
-
+
if (-bits_left > MP3FrameHeader.BUFFER_GUARD * 8) {
throw new Error("assertion failed: (-bits_left <= MP3FrameHeader.BUFFER_GUARD * CHAR_BIT)");
}
-
+
// rzero
while (xrptr < 576) {
xr[xrptr] = 0;
@@ -5765,11 +5765,11 @@ Layer3.prototype.requantize = function(value, exp) {
var requantized = Math.pow(value, 4.0 / 3.0);
requantized *= Math.pow(2.0, (exp / 4.0));
-
+
if (frac) {
requantized *= Math.pow(2.0, (frac / 4.0));
}
-
+
if (exp < 0) {
requantized /= Math.pow(2.0, -exp * (3.0 / 4.0));
}
@@ -5780,30 +5780,30 @@ Layer3.prototype.requantize = function(value, exp) {
Layer3.prototype.exponents = function(channel, sfbwidth, exponents) {
var gain = channel.global_gain - 210;
var scalefac_multiplier = (channel.flags & tables.SCALEFAC_SCALE) ? 2 : 1;
-
+
if (channel.block_type === 2) {
var sfbi = 0, l = 0;
-
+
if (channel.flags & tables.MIXED_BLOCK_FLAG) {
var premask = (channel.flags & tables.PREFLAG) ? ~0 : 0;
-
+
// long block subbands 0-1
while (l < 36) {
exponents[sfbi] = gain - ((channel.scalefac[sfbi] + (tables.PRETAB[sfbi] & premask)) << scalefac_multiplier);
l += sfbwidth[sfbi++];
}
}
-
+
// this is probably wrong for 8000 Hz short/mixed blocks
var gain0 = gain - 8 * channel.subblock_gain[0];
var gain1 = gain - 8 * channel.subblock_gain[1];
var gain2 = gain - 8 * channel.subblock_gain[2];
-
+
while (l < 576) {
exponents[sfbi + 0] = gain0 - (channel.scalefac[sfbi + 0] << scalefac_multiplier);
exponents[sfbi + 1] = gain1 - (channel.scalefac[sfbi + 1] << scalefac_multiplier);
exponents[sfbi + 2] = gain2 - (channel.scalefac[sfbi + 2] << scalefac_multiplier);
-
+
l += 3 * sfbwidth[sfbi];
sfbi += 3;
}
@@ -5824,27 +5824,27 @@ Layer3.prototype.stereo = function(xr, granules, gr, header, sfbwidth) {
var granule = granules[gr];
var modes = this.modes;
var sfbi, l, n, i;
-
+
if (granule.ch[0].block_type !== granule.ch[1].block_type || (granule.ch[0].flags & tables.MIXED_BLOCK_FLAG) !== (granule.ch[1].flags & tables.MIXED_BLOCK_FLAG))
throw new Error('incompatible stereo block_type');
-
+
for (var i = 0; i < 39; i++)
modes[i] = header.mode_extension;
-
+
// intensity stereo
if (header.mode_extension & tables.I_STEREO) {
var right_ch = granule.ch[1];
var right_xr = xr[1];
-
+
header.flags |= MP3FrameHeader.FLAGS.I_STEREO;
-
+
// first determine which scalefactor bands are to be processed
if (right_ch.block_type === 2) {
var lower, start, max, bound = new Uint32Array(3), w;
lower = start = max = bound[0] = bound[1] = bound[2] = 0;
sfbi = l = 0;
-
+
if (right_ch.flags & tables.MIXED_BLOCK_FLAG) {
while (l < 36) {
n = sfbwidth[sfbi++];
@@ -5862,7 +5862,7 @@ Layer3.prototype.stereo = function(xr, granules, gr, header, sfbwidth) {
start = sfbi;
}
-
+
var w = 0;
while (l < 576) {
n = sfbwidth[sfbi++];
@@ -5878,7 +5878,7 @@ Layer3.prototype.stereo = function(xr, granules, gr, header, sfbwidth) {
l += n;
w = (w + 1) % 3;
}
-
+
if (max)
lower = start;
@@ -5912,14 +5912,14 @@ Layer3.prototype.stereo = function(xr, granules, gr, header, sfbwidth) {
for (i = 0; i < bound; ++i)
modes[i] = header.mode_extension & ~tables.I_STEREO;
}
-
+
// now do the actual processing
if (header.flags & MP3FrameHeader.FLAGS.LSF_EXT) {
var illegal_pos = granules[gr + 1].ch[1].scalefac;
// intensity_scale
var lsf_scale = IS_Ltables.SF_TABLE[right_ch.scalefac_compress & 0x1];
-
+
for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
n = sfbwidth[sfbi];
@@ -5932,7 +5932,7 @@ Layer3.prototype.stereo = function(xr, granules, gr, header, sfbwidth) {
}
is_pos = right_ch.scalefac[sfbi];
-
+
for (i = 0; i < n; ++i) {
var left = xr[0][l + i];
@@ -5973,7 +5973,7 @@ Layer3.prototype.stereo = function(xr, granules, gr, header, sfbwidth) {
}
}
}
-
+
// middle/side stereo
if (header.mode_extension & tables.MS_STEREO) {
header.flags |= tables.MS_STEREO;
@@ -6041,7 +6041,7 @@ Layer3.prototype.imdct_s = function (X, z) {
var yptr = 0;
var wptr;
var Xptr = 0;
-
+
var y = new Float64Array(36);
var hi, lo;
@@ -6129,7 +6129,7 @@ Layer3.prototype.reorder = function (xr, channel, sfbwidth) {
var tmp = this.tmp;
var sbw = new Uint32Array(3);
var sw = new Uint32Array(3);
-
+
// this is probably wrong for 8000 Hz mixed blocks
var sb = 0;
@@ -6154,7 +6154,7 @@ Layer3.prototype.reorder = function (xr, channel, sfbwidth) {
f = sfbwidth[sfbwidthPointer++] - 1;
w = (w + 1) % 3;
}
-
+
tmp[sbw[w]][w][sw[w]++] = xr[l];
if (sw[w] === 6) {
@@ -6165,7 +6165,7 @@ Layer3.prototype.reorder = function (xr, channel, sfbwidth) {
var tmp2 = this.tmp2;
var ptr = 0;
-
+
for (var i = 0; i < 32; i++) {
for (var j = 0; j < 3; j++) {
for (var k = 0; k < 6; k++) {
@@ -6173,8 +6173,8 @@ Layer3.prototype.reorder = function (xr, channel, sfbwidth) {
}
}
}
-
- var len = (576 - 18 * sb);
+
+ var len = (576 - 18 * sb);
for (var i = 0; i < len; i++) {
xr[18 * sb + i] = tmp2[sb + i];
}
@@ -6194,10 +6194,10 @@ function MP3Stream(stream) {
this.freerate = 0; // free bitrate (fixed)
this.this_frame = stream.stream.offset; // start of current frame
this.next_frame = stream.stream.offset; // start of next frame
-
+
this.main_data = new Uint8Array(MP3FrameHeader.BUFFER_MDLEN); // actual audio data
this.md_len = 0; // length of main data
-
+
// copy methods from actual stream
for (var key in stream) {
if (typeof stream[key] === 'function')
@@ -6218,14 +6218,14 @@ MP3Stream.prototype.nextByte = function() {
MP3Stream.prototype.doSync = function() {
var stream = this.stream.stream;
this.align();
-
+
while (this.available(16) && !(stream.peekUInt8(0) === 0xff && (stream.peekUInt8(1) & 0xe0) === 0xe0)) {
this.advance(8);
}
if (!this.available(MP3FrameHeader.BUFFER_GUARD))
return false;
-
+
return true;
};
@@ -6244,7 +6244,7 @@ var utils = require('./utils');
function MP3Synth() {
this.filter = utils.makeArray([2, 2, 2, 16, 8]); // polyphase filterbank outputs
this.phase = 0;
-
+
this.pcm = {
samplerate: 0,
channels: 0,
@@ -7194,7 +7194,7 @@ const D = [
*/
MP3Synth.prototype.full = function(frame, nch, ns) {
var Dptr, hi, lo, ptr;
-
+
for (var ch = 0; ch < nch; ++ch) {
var sbsample = frame.sbsample[ch];
var filter = this.filter[ch];
@@ -7217,7 +7217,7 @@ MP3Synth.prototype.full = function(frame, nch, ns) {
var fePtr = 0;
var fxPtr = 0;
var foPtr = 0;
-
+
Dptr = 0;
ptr = D[Dptr];
@@ -7232,8 +7232,8 @@ MP3Synth.prototype.full = function(frame, nch, ns) {
lo += _fx[5] * ptr[po + 6];
lo += _fx[6] * ptr[po + 4];
lo += _fx[7] * ptr[po + 2];
- lo = -lo;
-
+ lo = -lo;
+
lo += _fe[0] * ptr[pe + 0];
lo += _fe[1] * ptr[pe + 14];
lo += _fe[2] * ptr[pe + 12];
@@ -7360,7 +7360,7 @@ module.exports = MP3Synth;
* add a 64th entry.
*/
exports.SF_TABLE = new Float32Array([
- 2.000000000000, 1.587401051968, 1.259921049895, 1.000000000000,
+ 2.000000000000, 1.587401051968, 1.259921049895, 1.000000000000,
0.793700525984, 0.629960524947, 0.500000000000, 0.396850262992,
0.314980262474, 0.250000000000, 0.198425131496, 0.157490131237,
0.125000000000, 0.099212565748, 0.078745065618, 0.062500000000,
@@ -7663,7 +7663,7 @@ exports.IS_LSF_TABLE = [
0.105112052,
0.088388348,
0.074325445
- ]),
+ ]),
new Float32Array([
0.707106781,
0.500000000,
@@ -7691,7 +7691,7 @@ exports.SFLEN_TABLE = [
{ slen1: 0, slen2: 0 }, { slen1: 0, slen2: 1 }, { slen1: 0, slen2: 2 }, { slen1: 0, slen2: 3 },
{ slen1: 3, slen2: 0 }, { slen1: 1, slen2: 1 }, { slen1: 1, slen2: 2 }, { slen1: 1, slen2: 3 },
{ slen1: 2, slen2: 1 }, { slen1: 2, slen2: 2 }, { slen1: 2, slen2: 3 }, { slen1: 3, slen2: 1 },
- { slen1: 3, slen2: 2 }, { slen1: 3, slen2: 3 }, { slen1: 4, slen2: 2 }, { slen1: 4, slen2: 3 }
+ { slen1: 3, slen2: 2 }, { slen1: 3, slen2: 3 }, { slen1: 4, slen2: 2 }, { slen1: 4, slen2: 3 }
];
/*
@@ -7723,25 +7723,25 @@ exports.NSFB_TABLE = [
[ 15, 12, 9, 0 ],
[ 6, 18, 9, 0 ] ]
];
-
+
},{}],15:[function(require,module,exports){
/**
* Makes a multidimensional array
*/
exports.makeArray = function(lengths, Type) {
if (!Type) Type = Float64Array;
-
+
if (lengths.length === 1) {
return new Type(lengths[0]);
}
-
+
var ret = [],
len = lengths[0];
-
+
for (var j = 0; j < len; j++) {
ret[j] = exports.makeArray(lengths.slice(1), Type);
}
-
+
return ret;
};