This commit is contained in:
minjaesong
2023-01-13 22:56:59 +09:00
parent ac684fed71
commit 1c9e99bb66
12 changed files with 2627 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
const Mp3 = require('mp3dec')
const pcm = require("pcm")
Object.keys(Mp3).forEach(e=>{
print(`${e}\t`)
})
println()
println("reading...")
let arr = files.open("A:/gateless.mp3").bread()
let ab = new ArrayBuffer(arr.length)
let abba = new Uint8Array(ab)
arr.forEach((v,i)=>{ abba[i] = v })
let mp3ArrayBuffer = new Uint8Array(ab, 0, arr.length)
println("decoding...")
let decoder = Mp3.newDecoder(ab)
if (decoder === null) throw Error("decoder is null")
audio.resetParams(0)
audio.purgeQueue(0)
audio.setPcmMode(0)
audio.setMasterVolume(0, 255)
audio.play(0)
let decodedLength = 0
let readPtr = sys.malloc(8000)
let decodePtr = sys.malloc(12000)
function decodeAndResample(readArr, decodePtr, readLength) {
for (let i = 0; i < readLength; i+= 2) {
let sample = pcm.u16Tos16(readArr[i] | (readArr[i+1] << 8))
let u8 = pcm.s16Tou8(sample)
sys.poke(decodePtr + (i >> 1), u8)
}
return readLength / 2
}
function printPlayBar() {
}
const QUEUE_MAX = 4
decoder.decode(obj=>{
let buf = obj.buf
let err = obj.err
decodedLength += buf.byteLength
let declen = decodeAndResample(buf, decodePtr, buf.byteLength)
audio.putPcmDataByPtr(decodePtr, declen, 0)
audio.setSampleUploadLength(0, declen)
audio.startSampleUpload(0)
audio.play(0)
serial.println(`Send sample (${audio.getPosition(0)})`)
// sys.sleep(0) // decoding time is slower than realtime :(
}) // now you got decoded PCM data
sys.free(readPtr)
sys.free(decodePtr)

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 SoundBus Technologies CO., LTD.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,84 @@
var Bits = {
createNew: function (vec) {
var bits = {
vec: vec, // ArrayBuffer
bitPos: 0,
bytePos: 0
};
/**
* @return {number}
*/
bits.Bit = function () {
if (bits.vec.byteLength <= bits.bytePos) {
// TODO: Should this return error?
return 0;
}
var dv = new DataView(bits.vec, bits.bytePos);
var tmp = (dv.getUint8(0) >>> (7 - bits.bitPos)) >>> 0;
tmp &= 0x01;
bits.bytePos += ((bits.bitPos + 1) >>> 3) >>> 0;
bits.bitPos = (bits.bitPos + 1) & 0x07;
return tmp;
};
/**
* @return {number}
*/
bits.Bits = function (num) {
if (num === 0) {
return 0;
}
if (bits.vec.byteLength <= bits.bytePos) {
// TODO: Should this return error?
return 0;
}
var bb = new DataView(bits.vec, bits.bytePos);
// always end bit wise ops with >>> 0 so the result gets interpreted as unsigned.
// don't use >>. If the left-most bit is 1 it will try to preseve the sign and thus will introduce 1's to the left. Always use >>>.
// see https://stackoverflow.com/a/6798829
var tmp = (((getValue(bb, 0) << 24) >>> 0) | ((getValue(bb, 1) << 16) >>> 0) | ((getValue(bb, 2) << 8) >>> 0) | (getValue(bb, 3) >>> 0)) >>> 0;
tmp = (tmp << bits.bitPos) >>> 0;
tmp = (tmp >>> (32 - num)) >>> 0;
bits.bytePos += ((bits.bitPos + num) >>> 3) >>> 0;
bits.bitPos = (bits.bitPos + num) & 0x07;
return tmp;
};
bits.Tail = function (offset) {
var a = new Uint8Array(bits.vec);
return a.slice(bits.vec.byteLength - offset).buffer;
// return new Uint8Array(bits.vec, bits.vec.byteLength - offset).buffer;
};
bits.LenInBytes = function () {
return bits.vec.byteLength;
};
/**
* @return {number}
*/
bits.BitPos = function () {
return ((bits.bytePos << 3) >>> 0) + bits.bitPos;
};
bits.SetPos = function (pos) {
bits.bytePos = (pos >>> 3) >>> 0;
bits.bitPos = (pos & 0x7) >>> 0;
};
return bits;
},
append: function (bits, buf) {
return Bits.createNew(bits.vec.concat(buf));
},
};
var getValue = function (dv, index) {
if (index >= dv.byteLength) {
return 0;
}
return dv.getUint8(index);
};
exports = Bits;

View File

@@ -0,0 +1,60 @@
var consts = {
Version2_5: 0,
VersionReserved: 1,
Version2: 2,
Version1: 3,
LayerReserved: 0,
Layer3: 1,
Layer2: 2,
Layer1: 3,
ModeStereo: 0,
ModeJointStereo: 1,
ModeDualChannel: 2,
ModeSingleChannel: 3,
SamplesPerGr: 576,
SamplingFrequency44100: 0,
SamplingFrequency48000: 1,
SamplingFrequency32000: 2,
SamplingFrequencyReserved: 3,
newSamplingFrequencyInstance: function (value) {
var instance = {
value: value
};
instance.Int = function () {
switch(instance.value) {
case consts.SamplingFrequency44100:
return 44100;
case consts.SamplingFrequency48000:
return 48000;
case consts.SamplingFrequency32000:
return 32000;
}
throw new Error('not reached');
};
return instance;
},
SfBandIndicesSet: {
0: { // SamplingFrequency44100
L: [0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576],
S: [0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192]
},
1: { // SamplingFrequency48000
L: [0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 576],
S: [0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192]
},
2: { // SamplingFrequency32000
L: [0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576],
S: [0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192]
}
}
};
consts.BytesPerFrame = consts.SamplesPerGr * 2 * 4;
exports = consts;

View File

@@ -0,0 +1,741 @@
var consts = require('A:/tvdos/include/js-mp3/consts.js');
var util = require('A:/tvdos/include/js-mp3/util.js');
var Frameheader = require('A:/tvdos/include/js-mp3/frameheader.js');
var Imdct = require('A:/tvdos/include/js-mp3/imdct.js');
var Maindata = require('A:/tvdos/include/js-mp3/maindata.js');
var Sideinfo = require('A:/tvdos/include/js-mp3/sideinfo.js');
var powtab34 = new Float64Array(8207);
var pretab_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0];
var pretab = new Float64Array(pretab_data.length);
pretab.set(pretab_data);
for (var i = 0; i < powtab34.length; i++) {
powtab34[i] = Math.pow(i, 4.0 / 3.0);
}
var synthNWin = [];
for (var i = 0; i < 64; i++) {
synthNWin.push(new Float32Array(32));
}
for (var i = 0; i < 64; i++) {
for (var j = 0; j < 32; j++) {
synthNWin[i][j] = Math.cos(((16 + i) * (2 * j + 1)) * (Math.PI / 64.0));
}
}
var synthDtbl = new Float32Array([
0.000000000, -0.000015259, -0.000015259, -0.000015259,
-0.000015259, -0.000015259, -0.000015259, -0.000030518,
-0.000030518, -0.000030518, -0.000030518, -0.000045776,
-0.000045776, -0.000061035, -0.000061035, -0.000076294,
-0.000076294, -0.000091553, -0.000106812, -0.000106812,
-0.000122070, -0.000137329, -0.000152588, -0.000167847,
-0.000198364, -0.000213623, -0.000244141, -0.000259399,
-0.000289917, -0.000320435, -0.000366211, -0.000396729,
-0.000442505, -0.000473022, -0.000534058, -0.000579834,
-0.000625610, -0.000686646, -0.000747681, -0.000808716,
-0.000885010, -0.000961304, -0.001037598, -0.001113892,
-0.001205444, -0.001296997, -0.001388550, -0.001480103,
-0.001586914, -0.001693726, -0.001785278, -0.001907349,
-0.002014160, -0.002120972, -0.002243042, -0.002349854,
-0.002456665, -0.002578735, -0.002685547, -0.002792358,
-0.002899170, -0.002990723, -0.003082275, -0.003173828,
0.003250122, 0.003326416, 0.003387451, 0.003433228,
0.003463745, 0.003479004, 0.003479004, 0.003463745,
0.003417969, 0.003372192, 0.003280640, 0.003173828,
0.003051758, 0.002883911, 0.002700806, 0.002487183,
0.002227783, 0.001937866, 0.001617432, 0.001266479,
0.000869751, 0.000442505, -0.000030518, -0.000549316,
-0.001098633, -0.001693726, -0.002334595, -0.003005981,
-0.003723145, -0.004486084, -0.005294800, -0.006118774,
-0.007003784, -0.007919312, -0.008865356, -0.009841919,
-0.010848999, -0.011886597, -0.012939453, -0.014022827,
-0.015121460, -0.016235352, -0.017349243, -0.018463135,
-0.019577026, -0.020690918, -0.021789551, -0.022857666,
-0.023910522, -0.024932861, -0.025909424, -0.026840210,
-0.027725220, -0.028533936, -0.029281616, -0.029937744,
-0.030532837, -0.031005859, -0.031387329, -0.031661987,
-0.031814575, -0.031845093, -0.031738281, -0.031478882,
0.031082153, 0.030517578, 0.029785156, 0.028884888,
0.027801514, 0.026535034, 0.025085449, 0.023422241,
0.021575928, 0.019531250, 0.017257690, 0.014801025,
0.012115479, 0.009231567, 0.006134033, 0.002822876,
-0.000686646, -0.004394531, -0.008316040, -0.012420654,
-0.016708374, -0.021179199, -0.025817871, -0.030609131,
-0.035552979, -0.040634155, -0.045837402, -0.051132202,
-0.056533813, -0.061996460, -0.067520142, -0.073059082,
-0.078628540, -0.084182739, -0.089706421, -0.095169067,
-0.100540161, -0.105819702, -0.110946655, -0.115921021,
-0.120697021, -0.125259399, -0.129562378, -0.133590698,
-0.137298584, -0.140670776, -0.143676758, -0.146255493,
-0.148422241, -0.150115967, -0.151306152, -0.151962280,
-0.152069092, -0.151596069, -0.150497437, -0.148773193,
-0.146362305, -0.143264771, -0.139450073, -0.134887695,
-0.129577637, -0.123474121, -0.116577148, -0.108856201,
0.100311279, 0.090927124, 0.080688477, 0.069595337,
0.057617188, 0.044784546, 0.031082153, 0.016510010,
0.001068115, -0.015228271, -0.032379150, -0.050354004,
-0.069168091, -0.088775635, -0.109161377, -0.130310059,
-0.152206421, -0.174789429, -0.198059082, -0.221984863,
-0.246505737, -0.271591187, -0.297210693, -0.323318481,
-0.349868774, -0.376800537, -0.404083252, -0.431655884,
-0.459472656, -0.487472534, -0.515609741, -0.543823242,
-0.572036743, -0.600219727, -0.628295898, -0.656219482,
-0.683914185, -0.711318970, -0.738372803, -0.765029907,
-0.791213989, -0.816864014, -0.841949463, -0.866363525,
-0.890090942, -0.913055420, -0.935195923, -0.956481934,
-0.976852417, -0.996246338, -1.014617920, -1.031936646,
-1.048156738, -1.063217163, -1.077117920, -1.089782715,
-1.101211548, -1.111373901, -1.120223999, -1.127746582,
-1.133926392, -1.138763428, -1.142211914, -1.144287109,
1.144989014, 1.144287109, 1.142211914, 1.138763428,
1.133926392, 1.127746582, 1.120223999, 1.111373901,
1.101211548, 1.089782715, 1.077117920, 1.063217163,
1.048156738, 1.031936646, 1.014617920, 0.996246338,
0.976852417, 0.956481934, 0.935195923, 0.913055420,
0.890090942, 0.866363525, 0.841949463, 0.816864014,
0.791213989, 0.765029907, 0.738372803, 0.711318970,
0.683914185, 0.656219482, 0.628295898, 0.600219727,
0.572036743, 0.543823242, 0.515609741, 0.487472534,
0.459472656, 0.431655884, 0.404083252, 0.376800537,
0.349868774, 0.323318481, 0.297210693, 0.271591187,
0.246505737, 0.221984863, 0.198059082, 0.174789429,
0.152206421, 0.130310059, 0.109161377, 0.088775635,
0.069168091, 0.050354004, 0.032379150, 0.015228271,
-0.001068115, -0.016510010, -0.031082153, -0.044784546,
-0.057617188, -0.069595337, -0.080688477, -0.090927124,
0.100311279, 0.108856201, 0.116577148, 0.123474121,
0.129577637, 0.134887695, 0.139450073, 0.143264771,
0.146362305, 0.148773193, 0.150497437, 0.151596069,
0.152069092, 0.151962280, 0.151306152, 0.150115967,
0.148422241, 0.146255493, 0.143676758, 0.140670776,
0.137298584, 0.133590698, 0.129562378, 0.125259399,
0.120697021, 0.115921021, 0.110946655, 0.105819702,
0.100540161, 0.095169067, 0.089706421, 0.084182739,
0.078628540, 0.073059082, 0.067520142, 0.061996460,
0.056533813, 0.051132202, 0.045837402, 0.040634155,
0.035552979, 0.030609131, 0.025817871, 0.021179199,
0.016708374, 0.012420654, 0.008316040, 0.004394531,
0.000686646, -0.002822876, -0.006134033, -0.009231567,
-0.012115479, -0.014801025, -0.017257690, -0.019531250,
-0.021575928, -0.023422241, -0.025085449, -0.026535034,
-0.027801514, -0.028884888, -0.029785156, -0.030517578,
0.031082153, 0.031478882, 0.031738281, 0.031845093,
0.031814575, 0.031661987, 0.031387329, 0.031005859,
0.030532837, 0.029937744, 0.029281616, 0.028533936,
0.027725220, 0.026840210, 0.025909424, 0.024932861,
0.023910522, 0.022857666, 0.021789551, 0.020690918,
0.019577026, 0.018463135, 0.017349243, 0.016235352,
0.015121460, 0.014022827, 0.012939453, 0.011886597,
0.010848999, 0.009841919, 0.008865356, 0.007919312,
0.007003784, 0.006118774, 0.005294800, 0.004486084,
0.003723145, 0.003005981, 0.002334595, 0.001693726,
0.001098633, 0.000549316, 0.000030518, -0.000442505,
-0.000869751, -0.001266479, -0.001617432, -0.001937866,
-0.002227783, -0.002487183, -0.002700806, -0.002883911,
-0.003051758, -0.003173828, -0.003280640, -0.003372192,
-0.003417969, -0.003463745, -0.003479004, -0.003479004,
-0.003463745, -0.003433228, -0.003387451, -0.003326416,
0.003250122, 0.003173828, 0.003082275, 0.002990723,
0.002899170, 0.002792358, 0.002685547, 0.002578735,
0.002456665, 0.002349854, 0.002243042, 0.002120972,
0.002014160, 0.001907349, 0.001785278, 0.001693726,
0.001586914, 0.001480103, 0.001388550, 0.001296997,
0.001205444, 0.001113892, 0.001037598, 0.000961304,
0.000885010, 0.000808716, 0.000747681, 0.000686646,
0.000625610, 0.000579834, 0.000534058, 0.000473022,
0.000442505, 0.000396729, 0.000366211, 0.000320435,
0.000289917, 0.000259399, 0.000244141, 0.000213623,
0.000198364, 0.000167847, 0.000152588, 0.000137329,
0.000122070, 0.000106812, 0.000106812, 0.000091553,
0.000076294, 0.000076294, 0.000061035, 0.000061035,
0.000045776, 0.000045776, 0.000030518, 0.000030518,
0.000030518, 0.000030518, 0.000015259, 0.000015259,
0.000015259, 0.000015259, 0.000015259, 0.000015259,
], 0, 512);
var cs = new Float32Array([
0.857493, 0.881742, 0.949629, 0.983315, 0.995518, 0.999161, 0.999899,
0.999993
]);
var ca = new Float32Array([
-0.514496, -0.471732, -0.313377, -0.181913, -0.094574, -0.040966,
-0.014199, -0.003700
]);
var isRatios = [0.000000, 0.267949, 0.577350, 1.000000, 1.732051, 3.732051];
var Frame = {
createNew: function (header, sideInfo, mainData, mainDataBits) {
var frame = {
header: header,
sideInfo: sideInfo,
mainData: mainData,
mainDataBits: mainDataBits
};
frame.store = new Array(2);
for (var i = 0; i < frame.store.length; i++) {
var a = new Array(32);
for (var j = 0; j < a.length; j++) {
a[j] = new Float32Array(18);
}
frame.store[i] = a;
}
frame.v_vec = new Array(2);
for (var i = 0; i < frame.v_vec.length; i++) {
frame.v_vec[i] = new Float32Array(1024);
}
/**
* Return decoded pcm ArrayBuffer
*
* @constructor
*/
frame.decode = function () {
var nch = frame.header.numberOfChannels();
var out;
if (nch === 1) {
out = new Uint8Array(consts.BytesPerFrame / 2);
} else {
out = new Uint8Array(consts.BytesPerFrame);
}
for (var gr = 0; gr < 2; gr++) {
for (var ch = 0; ch < nch; ch++) {
frame.requantize(gr, ch);
frame.reorder(gr, ch);
}
frame.stereo(gr);
for (var ch = 0; ch < nch; ch++) {
frame.antialias(gr, ch);
frame.hybridSynthesis(gr, ch);
frame.frequencyInversion(gr, ch);
if (nch === 1) {
frame.subbandSynthesis(gr, ch, out.subarray(consts.SamplesPerGr * 4 * gr / 2));
} else {
frame.subbandSynthesis(gr, ch, out.subarray(consts.SamplesPerGr * 4 * gr));
}
}
}
return out;
};
frame.antialias = function (gr, ch) {
// No antialiasing is done for short blocks
if ((frame.sideInfo.WinSwitchFlag[gr][ch] === 1) &&
(frame.sideInfo.BlockType[gr][ch] === 2) &&
(frame.sideInfo.MixedBlockFlag[gr][ch]) === 0) {
return;
}
// Setup the limit for how many subbands to transform
var sblim = 32;
if ((frame.sideInfo.WinSwitchFlag[gr][ch] === 1) &&
(frame.sideInfo.BlockType[gr][ch] === 2) &&
(frame.sideInfo.MixedBlockFlag[gr][ch] === 1)) {
sblim = 2
}
// Do the actual antialiasing
for (var sb = 1; sb < sblim; sb++) {
for (var i = 0; i < 8; i++) {
var li = 18 * sb - 1 - i;
var ui = 18 * sb + i;
var lb = frame.mainData.Is[gr][ch][li] * cs[i] - frame.mainData.Is[gr][ch][ui]
* ca[i];
var ub = frame.mainData.Is[gr][ch][ui] * cs[i] + frame.mainData.Is[gr][ch][li]
* ca[i];
frame.mainData.Is[gr][ch][li] = lb;
frame.mainData.Is[gr][ch][ui] = ub;
}
}
};
frame.hybridSynthesis = function (gr, ch) {
// Loop through all 32 subbands
for (var sb = 0; sb < 32; sb++) {
// Determine blocktype for this subband
var bt = frame.sideInfo.BlockType[gr][ch];
if ((frame.sideInfo.WinSwitchFlag[gr][ch] === 1) &&
(frame.sideInfo.MixedBlockFlag[gr][ch] === 1) && (sb < 2)) {
bt = 0;
}
// Do the inverse modified DCT and windowing
var inData = new Float32Array(18);
for (var i = 0; i < 18; i++) {
inData[i] = frame.mainData.Is[gr][ch][sb * 18 + i];
}
var rawout = Imdct.Win(inData, bt);
// Overlapp add with stored vector into main_data vector
for (var i = 0; i < 18; i++) {
frame.mainData.Is[gr][ch][sb * 18 + i] = rawout[i] + frame.store[ch][sb][i];
frame.store[ch][sb][i] = rawout[i + 18];
}
}
};
frame.frequencyInversion = function (gr, ch) {
for (var sb = 1; sb < 32; sb += 2) {
for (var i = 1; i < 18; i += 2) {
frame.mainData.Is[gr][ch][sb * 18 + i] =
-frame.mainData.Is[gr][ch][sb * 18 + i];
}
}
};
frame.stereo = function (gr) {
if (frame.header.useMSStereo()) {
// Determine how many frequency lines to transform
var i = 1;
if (frame.sideInfo.Count1[gr][0] > frame.sideInfo.Count1[gr][1]) {
i = 0;
}
var max_pos = frame.sideInfo.Count1[gr][i];
// Do the actual processing
const invSqrt2 = Math.SQRT2 / 2;
for (var i = 0; i < max_pos; i++) {
var left = (frame.mainData.Is[gr][0][i] + frame.mainData.Is[gr][1][i])
* invSqrt2;
var right = (frame.mainData.Is[gr][0][i] - frame.mainData.Is[gr][1][i])
* invSqrt2;
frame.mainData.Is[gr][0][i] = left;
frame.mainData.Is[gr][1][i] = right;
}
}
if (frame.header.useIntensityStereo()) {
// Setup sampling frequency index
var sfreq = frame.header.samplingFrequency();
// First band that is intensity stereo encoded is first band scale factor
// band on or above count1 frequency line. N.B.: Intensity stereo coding is
// only done for higher subbands, but logic is here for lower subbands.
// Determine type of block to process
if ((frame.sideInfo.WinSwitchFlag[gr][0] === 1) && (frame.sideInfo.BlockType[gr][0]
=== 2)) { // Short blocks
// Check if the first two subbands
// (=2*18 samples = 8 long or 3 short sfb's) uses long blocks
if (frame.sideInfo.MixedBlockFlag[gr][0] !== 0) { // 2 longbl. sb first
for (var sfb = 0; sfb < 8; sfb++) { // First process 8 sfb's at start
// Is this scale factor band above count1 for the right channel?
if (consts.SfBandIndicesSet[sfreq].L[sfb]
>= frame.sideInfo.Count1[gr][1]) {
frame.stereoProcessIntensityLong(gr, sfb);
}
}
// And next the remaining bands which uses short blocks
for (var sfb = 3; sfb < 12; sfb++) {
// Is this scale factor band above count1 for the right channel?
if (consts.SfBandIndicesSet[sfreq].S[sfb] * 3
>= frame.sideInfo.Count1[gr][1]) {
frame.stereoProcessIntensityShort(gr, sfb);
}
}
} else { // Only short blocks
for (var sfb = 0; sfb < 12; sfb++) {
// Is this scale factor band above count1 for the right channel?
if (consts.SfBandIndicesSet[sfreq].S[sfb] * 3
>= frame.sideInfo.Count1[gr][1]) {
frame.stereoProcessIntensityShort(gr, sfb);
}
}
}
} else { // Only long blocks
for (var sfb = 0; sfb < 21; sfb++) {
// Is this scale factor band above count1 for the right channel?
if (consts.SfBandIndicesSet[sfreq].L[sfb] >= frame.sideInfo.Count1[gr][1]) {
frame.stereoProcessIntensityLong(gr, sfb);
}
}
}
}
};
frame.stereoProcessIntensityLong = function (gr, sfb) {
var is_ratio_l = 0.0;
var is_ratio_r = 0.0;
// Check that((is_pos[sfb]=scalefac) < 7) => no intensity stereo
var is_pos = frame.mainData.ScalefacL[gr][0][sfb];
if (is_pos < 7) {
var sfreq = frame.header.samplingFrequency().value; // Setup sampling freq index
var sfb_start = consts.SfBandIndicesSet[sfreq].L[sfb];
var sfb_stop = consts.SfBandIndicesSet[sfreq].L[sfb + 1];
if (is_pos === 6) { // tan((6*PI)/12 = PI/2) needs special treatment!
is_ratio_l = 1.0;
is_ratio_r = 0.0;
} else {
is_ratio_l = isRatios[is_pos] / (1.0 + isRatios[is_pos]);
is_ratio_r = 1.0 / (1.0 + isRatios[is_pos]);
}
// Now decode all samples in this scale factor band
for (var i = sfb_start; i < sfb_stop; i++) {
frame.mainData.Is[gr][0][i] *= is_ratio_l;
frame.mainData.Is[gr][1][i] *= is_ratio_r;
}
}
};
frame.stereoProcessIntensityShort = function (gr, sfb) {
var is_ratio_l = 0.0;
var is_ratio_r = 0.0;
var sfreq = frame.header.samplingFrequency().value; // Setup sampling freq index
// The window length
var win_len = consts.SfBandIndicesSet[sfreq].S[sfb + 1]
- consts.SfBandIndicesSet[sfreq].S[sfb];
// The three windows within the band has different scalefactors
for (var win = 0; win < 3; win++) {
// Check that((is_pos[sfb]=scalefac) < 7) => no intensity stereo
var is_pos = frame.mainData.ScalefacS[gr][0][sfb][win];
if (is_pos < 7) {
var sfb_start = consts.SfBandIndicesSet[sfreq].S[sfb] * 3 + win_len * win;
var sfb_stop = sfb_start + win_len;
if (is_pos === 6) { // tan((6*PI)/12 = PI/2) needs special treatment!
is_ratio_l = 1.0;
is_ratio_r = 0.0;
} else {
is_ratio_l = isRatios[is_pos] / (1.0 + isRatios[is_pos]);
is_ratio_r = 1.0 / (1.0 + isRatios[is_pos]);
}
// Now decode all samples in this scale factor band
for (var i = sfb_start; i < sfb_stop; i++) {
// https://github.com/technosaurus/PDMP3/issues/3
frame.mainData.Is[gr][0][i] *= is_ratio_l;
frame.mainData.Is[gr][1][i] *= is_ratio_r;
}
}
}
};
frame.requantize = function (gr, ch) {
// Setup sampling frequency index
var sfreq = frame.header.samplingFrequency().value;
// Determine type of block to process
if (frame.sideInfo.WinSwitchFlag[gr][ch] === 1 && frame.sideInfo.BlockType[gr][ch]
=== 2) { // Short blocks
// Check if the first two subbands
// (=2*18 samples = 8 long or 3 short sfb's) uses long blocks
if (frame.sideInfo.MixedBlockFlag[gr][ch] !== 0) { // 2 longbl. sb first
// First process the 2 long block subbands at the start
var sfb = 0;
var next_sfb = consts.SfBandIndicesSet[sfreq].L[sfb + 1];
for (var i = 0; i < 36; i++) {
if (i === next_sfb) {
sfb++;
next_sfb = consts.SfBandIndicesSet[sfreq].L[sfb + 1];
}
frame.requantizeProcessLong(gr, ch, i, sfb);
}
// And next the remaining,non-zero,bands which uses short blocks
sfb = 3;
next_sfb = consts.SfBandIndicesSet[sfreq].S[sfb + 1] * 3;
var win_len = consts.SfBandIndicesSet[sfreq].S[sfb + 1] -
consts.SfBandIndicesSet[sfreq].S[sfb];
for (var i = 36; i < int(f.sideInfo.Count1[gr][ch]);) /* i++ done below! */ {
// Check if we're into the next scalefac band
if (i === next_sfb) {
sfb++;
next_sfb = consts.SfBandIndicesSet[sfreq].S[sfb + 1] * 3;
win_len = consts.SfBandIndicesSet[sfreq].S[sfb + 1] -
consts.SfBandIndicesSet[sfreq].S[sfb];
}
for (var win = 0; win < 3; win++) {
for (var j = 0; j < win_len; j++) {
frame.requantizeProcessShort(gr, ch, i, sfb, win);
i++;
}
}
}
} else { // Only short blocks
var sfb = 0;
var next_sfb = consts.SfBandIndicesSet[sfreq].S[sfb + 1] * 3;
var win_len = consts.SfBandIndicesSet[sfreq].S[sfb + 1] -
consts.SfBandIndicesSet[sfreq].S[sfb];
for (var i = 0; i < frame.sideInfo.Count1[gr][ch];) /* i++ done below! */ {
// Check if we're into the next scalefac band
if (i === next_sfb) {
sfb++;
next_sfb = consts.SfBandIndicesSet[sfreq].S[sfb + 1] * 3;
win_len = consts.SfBandIndicesSet[sfreq].S[sfb + 1] -
consts.SfBandIndicesSet[sfreq].S[sfb];
}
for (var win = 0; win < 3; win++) {
for (var j = 0; j < win_len; j++) {
frame.requantizeProcessShort(gr, ch, i, sfb, win);
i++;
}
}
}
}
} else { // Only long blocks
var sfb = 0;
var next_sfb = consts.SfBandIndicesSet[sfreq].L[sfb + 1];
for (var i = 0; i < frame.sideInfo.Count1[gr][ch]; i++) {
if (i === next_sfb) {
sfb++;
next_sfb = consts.SfBandIndicesSet[sfreq].L[sfb + 1];
}
frame.requantizeProcessLong(gr, ch, i, sfb);
}
}
};
frame.requantizeProcessLong = function (gr, ch, is_pos, sfb) {
var sf_mult = 0.5;
if (frame.sideInfo.ScalefacScale[gr][ch] !== 0) {
sf_mult = 1.0;
}
var pf_x_pt = frame.sideInfo.Preflag[gr][ch] * pretab[sfb];
var idx = -(sf_mult * (frame.mainData.ScalefacL[gr][ch][sfb] + pf_x_pt)) +
0.25 * (frame.sideInfo.GlobalGain[gr][ch] - 210);
var tmp1 = Math.pow(2.0, idx);
var tmp2 = 0.0;
if (frame.mainData.Is[gr][ch][is_pos] < 0.0) {
tmp2 = -powtab34[-frame.mainData.Is[gr][ch][is_pos]];
} else {
tmp2 = powtab34[frame.mainData.Is[gr][ch][is_pos]];
}
frame.mainData.Is[gr][ch][is_pos] = tmp1 * tmp2;
};
frame.requantizeProcessShort = function (gr, ch, is_pos, sfb, win) {
var sf_mult = 0.5;
if (frame.sideInfo.ScalefacScale[gr][ch] !== 0) {
sf_mult = 1.0;
}
var idx = -(sf_mult * frame.mainData.ScalefacS[gr][ch][sfb][win]) +
0.25 * (frame.sideInfo.GlobalGain[gr][ch] - 210.0 -
8.0 * frame.sideInfo.SubblockGain[gr][ch][win]);
var tmp1 = Math.pow(2.0, idx);
var tmp2 = 0.0;
if (frame.mainData.Is[gr][ch][is_pos] < 0) {
tmp2 = -powtab34[-frame.mainData.Is[gr][ch][is_pos]];
} else {
tmp2 = powtab34[frame.mainData.Is[gr][ch][is_pos]];
}
frame.mainData.Is[gr][ch][is_pos] = tmp1 * tmp2;
};
frame.reorder = function (gr, ch) {
var re = new Float32Array(consts.SamplesPerGr);
var sfreq = frame.header.samplingFrequency().value; // Setup sampling freq index
// Only reorder short blocks
if ((frame.sideInfo.WinSwitchFlag[gr][ch] === 1) && (frame.sideInfo.BlockType[gr][ch]
== 2)) { // Short blocks
// Check if the first two subbands
// (=2*18 samples = 8 long or 3 short sfb's) uses long blocks
var sfb = 0;
// 2 longbl. sb first
if (frame.sideInfo.MixedBlockFlag[gr][ch] !== 0) {
sfb = 3;
}
var next_sfb = consts.SfBandIndicesSet[sfreq].S[sfb + 1] * 3;
var win_len = consts.SfBandIndicesSet[sfreq].S[sfb + 1]
- consts.SfBandIndicesSet[sfreq].S[sfb];
var i = 36;
if (sfb === 0) {
i = 0;
}
for (; i < consts.SamplesPerGr;) {
// Check if we're into the next scalefac band
if (i === next_sfb) {
// Copy reordered data back to the original vector
var j = 3 * consts.SfBandIndicesSet[sfreq].S[sfb];
for (var s = 0; s < 3 * win_len; s++) {
frame.mainData.Is[gr][ch][j + s] = re[s]; // copy(frame.mainData.Is[gr][ch][j:j+3*win_len],
// re[0:3*win_len])
}
// Check if this band is above the rzero region,if so we're done
if (i >= frame.sideInfo.Count1[gr][ch]) {
return;
}
sfb++;
next_sfb = consts.SfBandIndicesSet[sfreq].S[sfb + 1] * 3;
win_len =
consts.SfBandIndicesSet[sfreq].S[sfb + 1]
- consts.SfBandIndicesSet[sfreq].S[sfb];
}
for (var win = 0; win < 3; win++) { // Do the actual reordering
for (j = 0; j < win_len; j++) {
re[j * 3 + win] = frame.mainData.Is[gr][ch][i];
i++;
}
}
}
// Copy reordered data of last band back to original vector
var j = 3 * consts.SfBandIndicesSet[sfreq].S[12];
for (var s = 0; s < 3 * win_len; s++) {
frame.mainData.Is[gr][ch][j + s] = re[s]; // copy(frame.mainData.Is[gr][ch][j:j+3*win_len],
// re[0:3*win_len])
}
}
};
frame.subbandSynthesis = function (gr, ch, out) {
var u_vec = new Float32Array(512);
var s_vec = new Float32Array(32);
var nch = frame.header.numberOfChannels();
// Setup the n_win windowing vector and the v_vec intermediate vector
for (var ss = 0; ss < 18; ss++) { // Loop through 18 samples in 32 subbands
frame.v_vec[ch].set(frame.v_vec[ch].slice(0, 1024 - 64), 64); // copy(f.v_vec[ch][64:1024],
// f.v_vec[ch][0:1024-64])
var d = frame.mainData.Is[gr][ch];
for (var i = 0; i < 32; i++) { // Copy next 32 time samples to a temp vector
s_vec[i] = d[i * 18 + ss];
}
for (var i = 0; i < 64; i++) { // Matrix multiply input with n_win[][] matrix
var sum = 0;
for (var j = 0; j < 32; j++) {
sum += synthNWin[i][j] * s_vec[j];
}
frame.v_vec[ch][i] = sum;
}
var v = frame.v_vec[ch];
for (var i = 0; i < 512; i += 64) { // Build the U vector
u_vec.set(v.slice((i << 1) >>> 0, ((i << 1) >>> 0) + 32), i); // copy(u_vec[i:i+32],
// v[(i<<1):(i<<1)+32])
u_vec.set(v.slice(((i << 1) >>> 0) + 96, ((i << 1) >>> 0) + 128), i + 32); // copy(u_vec[i+32:i+64],
// v[(i<<1)+96:(i<<1)+128])
}
for (var i = 0; i < 512; i++) { // Window by u_vec[i] with synthDtbl[i]
u_vec[i] *= synthDtbl[i];
}
for (var i = 0; i < 32; i++) { // Calc 32 samples,store in outdata vector
var sum = 0;
for (var j = 0; j < 512; j += 32) {
sum += u_vec[j + i];
}
// sum now contains time sample 32*ss+i. Convert to 16-bit signed int
var samp = sum * 32767;
if (samp > 32767) {
samp = 32767;
} else if (samp < -32767) {
samp = -32767;
}
var s = samp;
var idx;
if (nch === 1) {
idx = 2 * (32*ss + i);
} else {
idx = 4 * (32*ss + i);
}
if (ch === 0) {
out[idx] = s;
out[idx + 1] = (s >>> 8) >>> 0;
} else {
out[idx + 2] = s;
out[idx + 3] = (s >>> 8) >>> 0;
}
}
}
return out;
};
frame.samplingFrequency = function () {
return frame.header.samplingFrequency().Int();
};
return frame;
},
readCRC: function (source) {
var result = source.readFull(2);
if (result.err) {
return {
err: result.err
}
}
var buf = result.buf;
if (buf.byteLength < 2) {
return "mp3: error at readCRC";
}
},
read: function (source, position, prev) {
var rr = Frameheader.read(source, position)
if (rr.err) {
return {
f: null,
position: 0,
err: rr.err
}
}
var pos = rr.position;
var fh = rr.h;
// pos = rr.stopPosition;
if (fh.protectionBit() === 0) {
// pos += 2;
var err = Frame.readCRC(source);
if (typeof(err) !== 'undefined') {
return {
f: null,
position: 0,
err: err
}
}
}
if (fh.id() !== consts.Version1) {
return {
f: null,
position: 0,
err: "mp3: only MPEG version 1 (want " + consts.Version1 + "; got " + fh.id()
+ ") is supported"
}
}
if (fh.layer() !== consts.Layer3) {
return {
f: null,
position: 0,
err: "mp3: only layer3 (want " + consts.Version1 + "; got " + fh.layer()
+ ") is supported"
}
}
var result = Sideinfo.read(source, fh, pos);
if (result.err) {
return {
f: null,
position: 0,
err: result.err
}
}
var si = result.v;
// If there's not enough main data in the bit reservoir,
// signal to calling function so that decoding isn't done!
// Get main data (scalefactors and Huffman coded frequency data)
var prevM = null;
if (prev) {
prevM = prev.mainDataBits;
}
result = Maindata.read(source, prevM, fh, si);
if (result.err) {
return {
f: null,
position: 0,
err: result.err
}
}
var f = Frame.createNew(fh, si, result.v, result.bits);
if (prev) {
f.store = prev.store;
f.v_vec = prev.v_vec;
}
return {
f: f,
position: pos,
err: null
};
}
};
exports = Frame;

View File

@@ -0,0 +1,283 @@
var consts = require('A:/tvdos/include/js-mp3/consts.js');
var Frameheader = {
createNew: function (value) {
// A mepg1FrameHeader is MPEG1 Layer 1-3 frame header
var fh = {
value: value
};
/**
* ID returns this header's ID stored in position 20,19
*
* @return {number}
*/
fh.id = function () {
return ((fh.value & 0x00180000) >>> 19) >>> 0;
};
/**
* Layer returns the mpeg layer of this frame stored in position 18,17
*
* @return {number}
*/
fh.layer = function () {
return ((fh.value & 0x00060000) >>> 17) >>> 0;
};
/**
* ProtectionBit returns the protection bit stored in position 16
*
* @return {number}
*/
fh.protectionBit = function () {
return ((fh.value & 0x00010000) >>> 16) >>> 0;
};
/**
* BirateIndex returns the bitrate index stored in position 15,12
*
* @return {number}
*/
fh.bitrateIndex = function () {
return ((fh.value & 0x0000f000) >>> 12) >>> 0;
};
/**
* SamplingFrequency returns the SamplingFrequency in Hz stored in position 11,10
*
* @returns {*}
* @constructor
*/
fh.samplingFrequency = function () {
return consts.newSamplingFrequencyInstance(((fh.value & 0x00000c00) >>> 10) >>> 0)
};
/**
* PaddingBit returns the padding bit stored in position 9
*
* @return {number}
*/
fh.paddingBit = function () {
return ((fh.value & 0x00000200) >>> 9) >>> 0;
};
/**
* PrivateBit returns the private bit stored in position 8 - this bit may be used to store
* arbitrary data to be used by an application
*
* @return {number}
*/
fh.privateBit = function () {
return ((fh.value & 0x00000100) >>> 8) >>> 0;
};
/**
* Mode returns the channel mode, stored in position 7,6
*
* @return {number}
*/
fh.mode = function () {
return ((fh.value & 0x000000c0) >>> 6) >>> 0;
};
/**
* modeExtension returns the mode_extension - for use with Joint Stereo - stored in
* position 4,5
*
* @returns {number}
*/
fh.modeExtension = function () {
return ((fh.value & 0x00000030) >>> 4) >>> 0;
};
/**
* UseMSStereo returns a boolean value indicating whether the frame uses middle/side stereo.
*
* @returns {*}
*/
fh.useMSStereo = function () {
if (fh.mode() !== consts.ModeJointStereo) {
return false;
}
return (fh.modeExtension() & 0x2) !== 0;
};
/**
* UseIntensityStereo returns a boolean value indicating whether the frame uses intensity
* stereo.
*
* @returns {*}
*/
fh.useIntensityStereo = function () {
if (fh.mode() !== consts.ModeJointStereo) {
return false;
}
return (fh.modeExtension() & 0x1) !== 0;
};
/**
* Copyright returns whether or not this recording is copywritten - stored in position 3
*
* @returns {number}
*/
fh.copyright = function () {
return ((fh.value & 0x00000008) >>> 3) >>> 0;
};
/**
* OriginalOrCopy returns whether or not this is an Original recording or a copy of one -
* stored in position 2
*
* @returns {number}
*/
fh.originalOrCopy = function () {
return ((fh.value & 0x00000004) >>> 2) >>> 0;
};
/**
* Emphasis returns emphasis - the emphasis indication is here to tell the decoder that the
* file must be de-emphasized - stored in position 0,1
*
* @returns {number}
*/
fh.emphasis = function () {
return (fh.value & 0x00000003) >>> 0;
};
/**
* IsValid returns a boolean value indicating whether the header is valid or not.
*
* @returns {boolean}
*/
fh.isValid = function () {
const sync = 0xffe00000;
if ((fh.value & sync) >>> 0 !== sync) {
return false;
}
if (fh.id() === consts.VersionReserved) {
return false;
}
if (fh.bitrateIndex() === 15) {
return false;
}
if (fh.samplingFrequency().value === consts.SamplingFrequencyReserved) {
return false;
}
if (fh.layer() === consts.LayerReserved) {
return false;
}
if (fh.emphasis() === 2) {
return false;
}
return true;
};
/**
* @returns {number}
*/
fh.frameSize = function () {
var value = (144 * Frameheader.bitrate(fh.layer(), fh.bitrateIndex()))
/ fh.samplingFrequency().Int()
+ fh.paddingBit();
return Math.floor(value);
};
/**
* @returns {number}
*/
fh.numberOfChannels = function () {
if (fh.mode() === consts.ModeSingleChannel) {
return 1;
}
return 2;
};
return fh;
},
bitrate: function (layer, index) {
switch (layer) {
case consts.Layer1:
return [0, 32000, 64000, 96000, 128000, 160000, 192000, 224000,
256000, 288000, 320000, 352000, 384000, 416000, 448000][index];
case consts.Layer2:
return [0, 32000, 48000, 56000, 64000, 80000, 96000, 112000,
128000, 160000, 192000, 224000, 256000, 320000, 384000][index];
case consts.Layer3:
return [0, 32000, 40000, 48000, 56000, 64000, 80000, 96000,
112000, 128000, 160000, 192000, 224000, 256000, 320000][index];
}
throw new Error('not reached');
},
read: function (source, position) {
var pos = position;
var result = source.readFull(4);
if (result.err) {
return {
err: result.err
}
}
var buf = result.buf;
if (buf.byteLength < 4) {
return {
h: 0,
position: 0,
err: "UnexpectedEOF readHeader (1)"
}
}
var b1 = buf[0] >>> 0;
var b2 = buf[1] >>> 0;
var b3 = buf[2] >>> 0;
var b4 = buf[3] >>> 0;
var fh = Frameheader.createNew((((b1 << 24) >>> 0) | ((b2 << 16) >>> 0) | ((b3 << 8) >>> 0) | ((b4 << 0) >>> 0)) >>> 0);
while (!fh.isValid()) {
// stopPosition++;
result = source.readFull(1);
if (result.err) {
return {
err: result.err
}
}
buf = result.buf;
if (buf.byteLength < 1) {
return {
h: 0,
position: 0,
err: "UnexpectedEOF readHeader (2)"
}
}
b1 = b2;
b2 = b3;
b3 = b4;
b4 = buf[0] >>> 0;
fh = Frameheader.createNew((((b1 << 24) >>> 0) | ((b2 << 16) >>> 0) | ((b3 << 8) >>> 0) | ((b4 << 0) >>> 0)) >>> 0);
pos++;
}
// If we get here we've found the sync word, and can decode the header
// which is in the low 20 bits of the 32-bit sync+header word.
if (fh.bitrateIndex() === 0) {
return {
h: 0,
position: 0,
err: "mp3: free bitrate format is not supported. Header word is " + fh.value + " at position " + position
}
}
return {
h: fh,
position: pos
}
}
};
exports = Frameheader;

View File

@@ -0,0 +1,412 @@
var huffmanTable = new Uint16Array([
// 1
0x0201, 0x0000, 0x0201, 0x0010, 0x0201, 0x0001, 0x0011,
// 2
0x0201, 0x0000, 0x0401, 0x0201, 0x0010, 0x0001, 0x0201, 0x0011, 0x0401, 0x0201, 0x0020,
0x0021, 0x0201, 0x0012, 0x0201, 0x0002, 0x0022,
// 3
0x0401, 0x0201, 0x0000, 0x0001, 0x0201, 0x0011, 0x0201, 0x0010, 0x0401, 0x0201, 0x0020,
0x0021, 0x0201, 0x0012, 0x0201, 0x0002, 0x0022,
// 5
0x0201, 0x0000, 0x0401, 0x0201, 0x0010, 0x0001, 0x0201, 0x0011, 0x0801, 0x0401, 0x0201,
0x0020, 0x0002, 0x0201, 0x0021, 0x0012, 0x0801, 0x0401, 0x0201, 0x0022, 0x0030, 0x0201,
0x0003, 0x0013, 0x0201, 0x0031, 0x0201, 0x0032, 0x0201, 0x0023, 0x0033,
// 6
0x0601, 0x0401, 0x0201, 0x0000, 0x0010, 0x0011, 0x0601, 0x0201, 0x0001, 0x0201, 0x0020,
0x0021, 0x0601, 0x0201, 0x0012, 0x0201, 0x0002, 0x0022, 0x0401, 0x0201, 0x0031, 0x0013,
0x0401, 0x0201, 0x0030, 0x0032, 0x0201, 0x0023, 0x0201, 0x0003, 0x0033,
// 7
0x0201, 0x0000, 0x0401, 0x0201, 0x0010, 0x0001, 0x0801, 0x0201, 0x0011, 0x0401, 0x0201,
0x0020, 0x0002, 0x0021, 0x1201, 0x0601, 0x0201, 0x0012, 0x0201, 0x0022, 0x0030, 0x0401,
0x0201, 0x0031, 0x0013, 0x0401, 0x0201, 0x0003, 0x0032, 0x0201, 0x0023, 0x0004, 0x0a01,
0x0401, 0x0201, 0x0040, 0x0041, 0x0201, 0x0014, 0x0201, 0x0042, 0x0024, 0x0c01, 0x0601,
0x0401, 0x0201, 0x0033, 0x0043, 0x0050, 0x0401, 0x0201, 0x0034, 0x0005, 0x0051, 0x0601,
0x0201, 0x0015, 0x0201, 0x0052, 0x0025, 0x0401, 0x0201, 0x0044, 0x0035, 0x0401, 0x0201,
0x0053, 0x0054, 0x0201, 0x0045, 0x0055,
// 8
0x0601, 0x0201, 0x0000, 0x0201, 0x0010, 0x0001, 0x0201, 0x0011, 0x0401, 0x0201, 0x0021,
0x0012, 0x0e01, 0x0401, 0x0201, 0x0020, 0x0002, 0x0201, 0x0022, 0x0401, 0x0201, 0x0030,
0x0003, 0x0201, 0x0031, 0x0013, 0x0e01, 0x0801, 0x0401, 0x0201, 0x0032, 0x0023, 0x0201,
0x0040, 0x0004, 0x0201, 0x0041, 0x0201, 0x0014, 0x0042, 0x0c01, 0x0601, 0x0201, 0x0024,
0x0201, 0x0033, 0x0050, 0x0401, 0x0201, 0x0043, 0x0034, 0x0051, 0x0601, 0x0201, 0x0015,
0x0201, 0x0005, 0x0052, 0x0601, 0x0201, 0x0025, 0x0201, 0x0044, 0x0035, 0x0201, 0x0053,
0x0201, 0x0045, 0x0201, 0x0054, 0x0055,
// 9
0x0801, 0x0401, 0x0201, 0x0000, 0x0010, 0x0201, 0x0001, 0x0011, 0x0a01, 0x0401, 0x0201,
0x0020, 0x0021, 0x0201, 0x0012, 0x0201, 0x0002, 0x0022, 0x0c01, 0x0601, 0x0401, 0x0201,
0x0030, 0x0003, 0x0031, 0x0201, 0x0013, 0x0201, 0x0032, 0x0023, 0x0c01, 0x0401, 0x0201,
0x0041, 0x0014, 0x0401, 0x0201, 0x0040, 0x0033, 0x0201, 0x0042, 0x0024, 0x0a01, 0x0601,
0x0401, 0x0201, 0x0004, 0x0050, 0x0043, 0x0201, 0x0034, 0x0051, 0x0801, 0x0401, 0x0201,
0x0015, 0x0052, 0x0201, 0x0025, 0x0044, 0x0601, 0x0401, 0x0201, 0x0005, 0x0054, 0x0053,
0x0201, 0x0035, 0x0201, 0x0045, 0x0055,
// 10
0x0201, 0x0000, 0x0401, 0x0201, 0x0010, 0x0001, 0x0a01, 0x0201, 0x0011, 0x0401, 0x0201,
0x0020, 0x0002, 0x0201, 0x0021, 0x0012, 0x1c01, 0x0801, 0x0401, 0x0201, 0x0022, 0x0030,
0x0201, 0x0031, 0x0013, 0x0801, 0x0401, 0x0201, 0x0003, 0x0032, 0x0201, 0x0023, 0x0040,
0x0401, 0x0201, 0x0041, 0x0014, 0x0401, 0x0201, 0x0004, 0x0033, 0x0201, 0x0042, 0x0024,
0x1c01, 0x0a01, 0x0601, 0x0401, 0x0201, 0x0050, 0x0005, 0x0060, 0x0201, 0x0061, 0x0016,
0x0c01, 0x0601, 0x0401, 0x0201, 0x0043, 0x0034, 0x0051, 0x0201, 0x0015, 0x0201, 0x0052,
0x0025, 0x0401, 0x0201, 0x0026, 0x0036, 0x0071, 0x1401, 0x0801, 0x0201, 0x0017, 0x0401,
0x0201, 0x0044, 0x0053, 0x0006, 0x0601, 0x0401, 0x0201, 0x0035, 0x0045, 0x0062, 0x0201,
0x0070, 0x0201, 0x0007, 0x0064, 0x0e01, 0x0401, 0x0201, 0x0072, 0x0027, 0x0601, 0x0201,
0x0063, 0x0201, 0x0054, 0x0055, 0x0201, 0x0046, 0x0073, 0x0801, 0x0401, 0x0201, 0x0037,
0x0065, 0x0201, 0x0056, 0x0074, 0x0601, 0x0201, 0x0047, 0x0201, 0x0066, 0x0075, 0x0401,
0x0201, 0x0057, 0x0076, 0x0201, 0x0067, 0x0077,
// 11
0x0601, 0x0201, 0x0000, 0x0201, 0x0010, 0x0001, 0x0801, 0x0201, 0x0011, 0x0401, 0x0201,
0x0020, 0x0002, 0x0012, 0x1801, 0x0801, 0x0201, 0x0021, 0x0201, 0x0022, 0x0201, 0x0030,
0x0003, 0x0401, 0x0201, 0x0031, 0x0013, 0x0401, 0x0201, 0x0032, 0x0023, 0x0401, 0x0201,
0x0040, 0x0004, 0x0201, 0x0041, 0x0014, 0x1e01, 0x1001, 0x0a01, 0x0401, 0x0201, 0x0042,
0x0024, 0x0401, 0x0201, 0x0033, 0x0043, 0x0050, 0x0401, 0x0201, 0x0034, 0x0051, 0x0061,
0x0601, 0x0201, 0x0016, 0x0201, 0x0006, 0x0026, 0x0201, 0x0062, 0x0201, 0x0015, 0x0201,
0x0005, 0x0052, 0x1001, 0x0a01, 0x0601, 0x0401, 0x0201, 0x0025, 0x0044, 0x0060, 0x0201,
0x0063, 0x0036, 0x0401, 0x0201, 0x0070, 0x0017, 0x0071, 0x1001, 0x0601, 0x0401, 0x0201,
0x0007, 0x0064, 0x0072, 0x0201, 0x0027, 0x0401, 0x0201, 0x0053, 0x0035, 0x0201, 0x0054,
0x0045, 0x0a01, 0x0401, 0x0201, 0x0046, 0x0073, 0x0201, 0x0037, 0x0201, 0x0065, 0x0056,
0x0a01, 0x0601, 0x0401, 0x0201, 0x0055, 0x0057, 0x0074, 0x0201, 0x0047, 0x0066, 0x0401,
0x0201, 0x0075, 0x0076, 0x0201, 0x0067, 0x0077,
// 12
0x0c01, 0x0401, 0x0201, 0x0010, 0x0001, 0x0201, 0x0011, 0x0201, 0x0000, 0x0201, 0x0020,
0x0002, 0x1001, 0x0401, 0x0201, 0x0021, 0x0012, 0x0401, 0x0201, 0x0022, 0x0031, 0x0201,
0x0013, 0x0201, 0x0030, 0x0201, 0x0003, 0x0040, 0x1a01, 0x0801, 0x0401, 0x0201, 0x0032,
0x0023, 0x0201, 0x0041, 0x0033, 0x0a01, 0x0401, 0x0201, 0x0014, 0x0042, 0x0201, 0x0024,
0x0201, 0x0004, 0x0050, 0x0401, 0x0201, 0x0043, 0x0034, 0x0201, 0x0051, 0x0015, 0x1c01,
0x0e01, 0x0801, 0x0401, 0x0201, 0x0052, 0x0025, 0x0201, 0x0053, 0x0035, 0x0401, 0x0201,
0x0060, 0x0016, 0x0061, 0x0401, 0x0201, 0x0062, 0x0026, 0x0601, 0x0401, 0x0201, 0x0005,
0x0006, 0x0044, 0x0201, 0x0054, 0x0045, 0x1201, 0x0a01, 0x0401, 0x0201, 0x0063, 0x0036,
0x0401, 0x0201, 0x0070, 0x0007, 0x0071, 0x0401, 0x0201, 0x0017, 0x0064, 0x0201, 0x0046,
0x0072, 0x0a01, 0x0601, 0x0201, 0x0027, 0x0201, 0x0055, 0x0073, 0x0201, 0x0037, 0x0056,
0x0801, 0x0401, 0x0201, 0x0065, 0x0074, 0x0201, 0x0047, 0x0066, 0x0401, 0x0201, 0x0075,
0x0057, 0x0201, 0x0076, 0x0201, 0x0067, 0x0077,
// 13
0x0201, 0x0000, 0x0601, 0x0201, 0x0010, 0x0201, 0x0001, 0x0011, 0x1c01, 0x0801, 0x0401,
0x0201, 0x0020, 0x0002, 0x0201, 0x0021, 0x0012, 0x0801, 0x0401, 0x0201, 0x0022, 0x0030,
0x0201, 0x0003, 0x0031, 0x0601, 0x0201, 0x0013, 0x0201, 0x0032, 0x0023, 0x0401, 0x0201,
0x0040, 0x0004, 0x0041, 0x4601, 0x1c01, 0x0e01, 0x0601, 0x0201, 0x0014, 0x0201, 0x0033,
0x0042, 0x0401, 0x0201, 0x0024, 0x0050, 0x0201, 0x0043, 0x0034, 0x0401, 0x0201, 0x0051,
0x0015, 0x0401, 0x0201, 0x0005, 0x0052, 0x0201, 0x0025, 0x0201, 0x0044, 0x0053, 0x0e01,
0x0801, 0x0401, 0x0201, 0x0060, 0x0006, 0x0201, 0x0061, 0x0016, 0x0401, 0x0201, 0x0080,
0x0008, 0x0081, 0x1001, 0x0801, 0x0401, 0x0201, 0x0035, 0x0062, 0x0201, 0x0026, 0x0054,
0x0401, 0x0201, 0x0045, 0x0063, 0x0201, 0x0036, 0x0070, 0x0601, 0x0401, 0x0201, 0x0007,
0x0055, 0x0071, 0x0201, 0x0017, 0x0201, 0x0027, 0x0037, 0x4801, 0x1801, 0x0c01, 0x0401,
0x0201, 0x0018, 0x0082, 0x0201, 0x0028, 0x0401, 0x0201, 0x0064, 0x0046, 0x0072, 0x0801,
0x0401, 0x0201, 0x0084, 0x0048, 0x0201, 0x0090, 0x0009, 0x0201, 0x0091, 0x0019, 0x1801,
0x0e01, 0x0801, 0x0401, 0x0201, 0x0073, 0x0065, 0x0201, 0x0056, 0x0074, 0x0401, 0x0201,
0x0047, 0x0066, 0x0083, 0x0601, 0x0201, 0x0038, 0x0201, 0x0075, 0x0057, 0x0201, 0x0092,
0x0029, 0x0e01, 0x0801, 0x0401, 0x0201, 0x0067, 0x0085, 0x0201, 0x0058, 0x0039, 0x0201,
0x0093, 0x0201, 0x0049, 0x0086, 0x0601, 0x0201, 0x00a0, 0x0201, 0x0068, 0x000a, 0x0201,
0x00a1, 0x001a, 0x4401, 0x1801, 0x0c01, 0x0401, 0x0201, 0x00a2, 0x002a, 0x0401, 0x0201,
0x0095, 0x0059, 0x0201, 0x00a3, 0x003a, 0x0801, 0x0401, 0x0201, 0x004a, 0x0096, 0x0201,
0x00b0, 0x000b, 0x0201, 0x00b1, 0x001b, 0x1401, 0x0801, 0x0201, 0x00b2, 0x0401, 0x0201,
0x0076, 0x0077, 0x0094, 0x0601, 0x0401, 0x0201, 0x0087, 0x0078, 0x00a4, 0x0401, 0x0201,
0x0069, 0x00a5, 0x002b, 0x0c01, 0x0601, 0x0401, 0x0201, 0x005a, 0x0088, 0x00b3, 0x0201,
0x003b, 0x0201, 0x0079, 0x00a6, 0x0601, 0x0401, 0x0201, 0x006a, 0x00b4, 0x00c0, 0x0401,
0x0201, 0x000c, 0x0098, 0x00c1, 0x3c01, 0x1601, 0x0a01, 0x0601, 0x0201, 0x001c, 0x0201,
0x0089, 0x00b5, 0x0201, 0x005b, 0x00c2, 0x0401, 0x0201, 0x002c, 0x003c, 0x0401, 0x0201,
0x00b6, 0x006b, 0x0201, 0x00c4, 0x004c, 0x1001, 0x0801, 0x0401, 0x0201, 0x00a8, 0x008a,
0x0201, 0x00d0, 0x000d, 0x0201, 0x00d1, 0x0201, 0x004b, 0x0201, 0x0097, 0x00a7, 0x0c01,
0x0601, 0x0201, 0x00c3, 0x0201, 0x007a, 0x0099, 0x0401, 0x0201, 0x00c5, 0x005c, 0x00b7,
0x0401, 0x0201, 0x001d, 0x00d2, 0x0201, 0x002d, 0x0201, 0x007b, 0x00d3, 0x3401, 0x1c01,
0x0c01, 0x0401, 0x0201, 0x003d, 0x00c6, 0x0401, 0x0201, 0x006c, 0x00a9, 0x0201, 0x009a,
0x00d4, 0x0801, 0x0401, 0x0201, 0x00b8, 0x008b, 0x0201, 0x004d, 0x00c7, 0x0401, 0x0201,
0x007c, 0x00d5, 0x0201, 0x005d, 0x00e0, 0x0a01, 0x0401, 0x0201, 0x00e1, 0x001e, 0x0401,
0x0201, 0x000e, 0x002e, 0x00e2, 0x0801, 0x0401, 0x0201, 0x00e3, 0x006d, 0x0201, 0x008c,
0x00e4, 0x0401, 0x0201, 0x00e5, 0x00ba, 0x00f0, 0x2601, 0x1001, 0x0401, 0x0201, 0x00f1,
0x001f, 0x0601, 0x0401, 0x0201, 0x00aa, 0x009b, 0x00b9, 0x0201, 0x003e, 0x0201, 0x00d6,
0x00c8, 0x0c01, 0x0601, 0x0201, 0x004e, 0x0201, 0x00d7, 0x007d, 0x0201, 0x00ab, 0x0201,
0x005e, 0x00c9, 0x0601, 0x0201, 0x000f, 0x0201, 0x009c, 0x006e, 0x0201, 0x00f2, 0x002f,
0x2001, 0x1001, 0x0601, 0x0401, 0x0201, 0x00d8, 0x008d, 0x003f, 0x0601, 0x0201, 0x00f3,
0x0201, 0x00e6, 0x00ca, 0x0201, 0x00f4, 0x004f, 0x0801, 0x0401, 0x0201, 0x00bb, 0x00ac,
0x0201, 0x00e7, 0x00f5, 0x0401, 0x0201, 0x00d9, 0x009d, 0x0201, 0x005f, 0x00e8, 0x1e01,
0x0c01, 0x0601, 0x0201, 0x006f, 0x0201, 0x00f6, 0x00cb, 0x0401, 0x0201, 0x00bc, 0x00ad,
0x00da, 0x0801, 0x0201, 0x00f7, 0x0401, 0x0201, 0x007e, 0x007f, 0x008e, 0x0601, 0x0401,
0x0201, 0x009e, 0x00ae, 0x00cc, 0x0201, 0x00f8, 0x008f, 0x1201, 0x0801, 0x0401, 0x0201,
0x00db, 0x00bd, 0x0201, 0x00ea, 0x00f9, 0x0401, 0x0201, 0x009f, 0x00eb, 0x0201, 0x00be,
0x0201, 0x00cd, 0x00fa, 0x0e01, 0x0401, 0x0201, 0x00dd, 0x00ec, 0x0601, 0x0401, 0x0201,
0x00e9, 0x00af, 0x00dc, 0x0201, 0x00ce, 0x00fb, 0x0801, 0x0401, 0x0201, 0x00bf, 0x00de,
0x0201, 0x00cf, 0x00ee, 0x0401, 0x0201, 0x00df, 0x00ef, 0x0201, 0x00ff, 0x0201, 0x00ed,
0x0201, 0x00fd, 0x0201, 0x00fc, 0x00fe,
// 15
0x1001, 0x0601, 0x0201, 0x0000, 0x0201, 0x0010, 0x0001, 0x0201, 0x0011, 0x0401, 0x0201,
0x0020, 0x0002, 0x0201, 0x0021, 0x0012, 0x3201, 0x1001, 0x0601, 0x0201, 0x0022, 0x0201,
0x0030, 0x0031, 0x0601, 0x0201, 0x0013, 0x0201, 0x0003, 0x0040, 0x0201, 0x0032, 0x0023,
0x0e01, 0x0601, 0x0401, 0x0201, 0x0004, 0x0014, 0x0041, 0x0401, 0x0201, 0x0033, 0x0042,
0x0201, 0x0024, 0x0043, 0x0a01, 0x0601, 0x0201, 0x0034, 0x0201, 0x0050, 0x0005, 0x0201,
0x0051, 0x0015, 0x0401, 0x0201, 0x0052, 0x0025, 0x0401, 0x0201, 0x0044, 0x0053, 0x0061,
0x5a01, 0x2401, 0x1201, 0x0a01, 0x0601, 0x0201, 0x0035, 0x0201, 0x0060, 0x0006, 0x0201,
0x0016, 0x0062, 0x0401, 0x0201, 0x0026, 0x0054, 0x0201, 0x0045, 0x0063, 0x0a01, 0x0601,
0x0201, 0x0036, 0x0201, 0x0070, 0x0007, 0x0201, 0x0071, 0x0055, 0x0401, 0x0201, 0x0017,
0x0064, 0x0201, 0x0072, 0x0027, 0x1801, 0x1001, 0x0801, 0x0401, 0x0201, 0x0046, 0x0073,
0x0201, 0x0037, 0x0065, 0x0401, 0x0201, 0x0056, 0x0080, 0x0201, 0x0008, 0x0074, 0x0401,
0x0201, 0x0081, 0x0018, 0x0201, 0x0082, 0x0028, 0x1001, 0x0801, 0x0401, 0x0201, 0x0047,
0x0066, 0x0201, 0x0083, 0x0038, 0x0401, 0x0201, 0x0075, 0x0057, 0x0201, 0x0084, 0x0048,
0x0601, 0x0401, 0x0201, 0x0090, 0x0019, 0x0091, 0x0401, 0x0201, 0x0092, 0x0076, 0x0201,
0x0067, 0x0029, 0x5c01, 0x2401, 0x1201, 0x0a01, 0x0401, 0x0201, 0x0085, 0x0058, 0x0401,
0x0201, 0x0009, 0x0077, 0x0093, 0x0401, 0x0201, 0x0039, 0x0094, 0x0201, 0x0049, 0x0086,
0x0a01, 0x0601, 0x0201, 0x0068, 0x0201, 0x00a0, 0x000a, 0x0201, 0x00a1, 0x001a, 0x0401,
0x0201, 0x00a2, 0x002a, 0x0201, 0x0095, 0x0059, 0x1a01, 0x0e01, 0x0601, 0x0201, 0x00a3,
0x0201, 0x003a, 0x0087, 0x0401, 0x0201, 0x0078, 0x00a4, 0x0201, 0x004a, 0x0096, 0x0601,
0x0401, 0x0201, 0x0069, 0x00b0, 0x00b1, 0x0401, 0x0201, 0x001b, 0x00a5, 0x00b2, 0x0e01,
0x0801, 0x0401, 0x0201, 0x005a, 0x002b, 0x0201, 0x0088, 0x0097, 0x0201, 0x00b3, 0x0201,
0x0079, 0x003b, 0x0801, 0x0401, 0x0201, 0x006a, 0x00b4, 0x0201, 0x004b, 0x00c1, 0x0401,
0x0201, 0x0098, 0x0089, 0x0201, 0x001c, 0x00b5, 0x5001, 0x2201, 0x1001, 0x0601, 0x0401,
0x0201, 0x005b, 0x002c, 0x00c2, 0x0601, 0x0401, 0x0201, 0x000b, 0x00c0, 0x00a6, 0x0201,
0x00a7, 0x007a, 0x0a01, 0x0401, 0x0201, 0x00c3, 0x003c, 0x0401, 0x0201, 0x000c, 0x0099,
0x00b6, 0x0401, 0x0201, 0x006b, 0x00c4, 0x0201, 0x004c, 0x00a8, 0x1401, 0x0a01, 0x0401,
0x0201, 0x008a, 0x00c5, 0x0401, 0x0201, 0x00d0, 0x005c, 0x00d1, 0x0401, 0x0201, 0x00b7,
0x007b, 0x0201, 0x001d, 0x0201, 0x000d, 0x002d, 0x0c01, 0x0401, 0x0201, 0x00d2, 0x00d3,
0x0401, 0x0201, 0x003d, 0x00c6, 0x0201, 0x006c, 0x00a9, 0x0601, 0x0401, 0x0201, 0x009a,
0x00b8, 0x00d4, 0x0401, 0x0201, 0x008b, 0x004d, 0x0201, 0x00c7, 0x007c, 0x4401, 0x2201,
0x1201, 0x0a01, 0x0401, 0x0201, 0x00d5, 0x005d, 0x0401, 0x0201, 0x00e0, 0x000e, 0x00e1,
0x0401, 0x0201, 0x001e, 0x00e2, 0x0201, 0x00aa, 0x002e, 0x0801, 0x0401, 0x0201, 0x00b9,
0x009b, 0x0201, 0x00e3, 0x00d6, 0x0401, 0x0201, 0x006d, 0x003e, 0x0201, 0x00c8, 0x008c,
0x1001, 0x0801, 0x0401, 0x0201, 0x00e4, 0x004e, 0x0201, 0x00d7, 0x007d, 0x0401, 0x0201,
0x00e5, 0x00ba, 0x0201, 0x00ab, 0x005e, 0x0801, 0x0401, 0x0201, 0x00c9, 0x009c, 0x0201,
0x00f1, 0x001f, 0x0601, 0x0401, 0x0201, 0x00f0, 0x006e, 0x00f2, 0x0201, 0x002f, 0x00e6,
0x2601, 0x1201, 0x0801, 0x0401, 0x0201, 0x00d8, 0x00f3, 0x0201, 0x003f, 0x00f4, 0x0601,
0x0201, 0x004f, 0x0201, 0x008d, 0x00d9, 0x0201, 0x00bb, 0x00ca, 0x0801, 0x0401, 0x0201,
0x00ac, 0x00e7, 0x0201, 0x007e, 0x00f5, 0x0801, 0x0401, 0x0201, 0x009d, 0x005f, 0x0201,
0x00e8, 0x008e, 0x0201, 0x00f6, 0x00cb, 0x2201, 0x1201, 0x0a01, 0x0601, 0x0401, 0x0201,
0x000f, 0x00ae, 0x006f, 0x0201, 0x00bc, 0x00da, 0x0401, 0x0201, 0x00ad, 0x00f7, 0x0201,
0x007f, 0x00e9, 0x0801, 0x0401, 0x0201, 0x009e, 0x00cc, 0x0201, 0x00f8, 0x008f, 0x0401,
0x0201, 0x00db, 0x00bd, 0x0201, 0x00ea, 0x00f9, 0x1001, 0x0801, 0x0401, 0x0201, 0x009f,
0x00dc, 0x0201, 0x00cd, 0x00eb, 0x0401, 0x0201, 0x00be, 0x00fa, 0x0201, 0x00af, 0x00dd,
0x0e01, 0x0601, 0x0401, 0x0201, 0x00ec, 0x00ce, 0x00fb, 0x0401, 0x0201, 0x00bf, 0x00ed,
0x0201, 0x00de, 0x00fc, 0x0601, 0x0401, 0x0201, 0x00cf, 0x00fd, 0x00ee, 0x0401, 0x0201,
0x00df, 0x00fe, 0x0201, 0x00ef, 0x00ff,
// 16
0x0201, 0x0000, 0x0601, 0x0201, 0x0010, 0x0201, 0x0001, 0x0011, 0x2a01, 0x0801, 0x0401,
0x0201, 0x0020, 0x0002, 0x0201, 0x0021, 0x0012, 0x0a01, 0x0601, 0x0201, 0x0022, 0x0201,
0x0030, 0x0003, 0x0201, 0x0031, 0x0013, 0x0a01, 0x0401, 0x0201, 0x0032, 0x0023, 0x0401,
0x0201, 0x0040, 0x0004, 0x0041, 0x0601, 0x0201, 0x0014, 0x0201, 0x0033, 0x0042, 0x0401,
0x0201, 0x0024, 0x0050, 0x0201, 0x0043, 0x0034, 0x8a01, 0x2801, 0x1001, 0x0601, 0x0401,
0x0201, 0x0005, 0x0015, 0x0051, 0x0401, 0x0201, 0x0052, 0x0025, 0x0401, 0x0201, 0x0044,
0x0035, 0x0053, 0x0a01, 0x0601, 0x0401, 0x0201, 0x0060, 0x0006, 0x0061, 0x0201, 0x0016,
0x0062, 0x0801, 0x0401, 0x0201, 0x0026, 0x0054, 0x0201, 0x0045, 0x0063, 0x0401, 0x0201,
0x0036, 0x0070, 0x0071, 0x2801, 0x1201, 0x0801, 0x0201, 0x0017, 0x0201, 0x0007, 0x0201,
0x0055, 0x0064, 0x0401, 0x0201, 0x0072, 0x0027, 0x0401, 0x0201, 0x0046, 0x0065, 0x0073,
0x0a01, 0x0601, 0x0201, 0x0037, 0x0201, 0x0056, 0x0008, 0x0201, 0x0080, 0x0081, 0x0601,
0x0201, 0x0018, 0x0201, 0x0074, 0x0047, 0x0201, 0x0082, 0x0201, 0x0028, 0x0066, 0x1801,
0x0e01, 0x0801, 0x0401, 0x0201, 0x0083, 0x0038, 0x0201, 0x0075, 0x0084, 0x0401, 0x0201,
0x0048, 0x0090, 0x0091, 0x0601, 0x0201, 0x0019, 0x0201, 0x0009, 0x0076, 0x0201, 0x0092,
0x0029, 0x0e01, 0x0801, 0x0401, 0x0201, 0x0085, 0x0058, 0x0201, 0x0093, 0x0039, 0x0401,
0x0201, 0x00a0, 0x000a, 0x001a, 0x0801, 0x0201, 0x00a2, 0x0201, 0x0067, 0x0201, 0x0057,
0x0049, 0x0601, 0x0201, 0x0094, 0x0201, 0x0077, 0x0086, 0x0201, 0x00a1, 0x0201, 0x0068,
0x0095, 0xdc01, 0x7e01, 0x3201, 0x1a01, 0x0c01, 0x0601, 0x0201, 0x002a, 0x0201, 0x0059,
0x003a, 0x0201, 0x00a3, 0x0201, 0x0087, 0x0078, 0x0801, 0x0401, 0x0201, 0x00a4, 0x004a,
0x0201, 0x0096, 0x0069, 0x0401, 0x0201, 0x00b0, 0x000b, 0x00b1, 0x0a01, 0x0401, 0x0201,
0x001b, 0x00b2, 0x0201, 0x002b, 0x0201, 0x00a5, 0x005a, 0x0601, 0x0201, 0x00b3, 0x0201,
0x00a6, 0x006a, 0x0401, 0x0201, 0x00b4, 0x004b, 0x0201, 0x000c, 0x00c1, 0x1e01, 0x0e01,
0x0601, 0x0401, 0x0201, 0x00b5, 0x00c2, 0x002c, 0x0401, 0x0201, 0x00a7, 0x00c3, 0x0201,
0x006b, 0x00c4, 0x0801, 0x0201, 0x001d, 0x0401, 0x0201, 0x0088, 0x0097, 0x003b, 0x0401,
0x0201, 0x00d1, 0x00d2, 0x0201, 0x002d, 0x00d3, 0x1201, 0x0601, 0x0401, 0x0201, 0x001e,
0x002e, 0x00e2, 0x0601, 0x0401, 0x0201, 0x0079, 0x0098, 0x00c0, 0x0201, 0x001c, 0x0201,
0x0089, 0x005b, 0x0e01, 0x0601, 0x0201, 0x003c, 0x0201, 0x007a, 0x00b6, 0x0401, 0x0201,
0x004c, 0x0099, 0x0201, 0x00a8, 0x008a, 0x0601, 0x0201, 0x000d, 0x0201, 0x00c5, 0x005c,
0x0401, 0x0201, 0x003d, 0x00c6, 0x0201, 0x006c, 0x009a, 0x5801, 0x5601, 0x2401, 0x1001,
0x0801, 0x0401, 0x0201, 0x008b, 0x004d, 0x0201, 0x00c7, 0x007c, 0x0401, 0x0201, 0x00d5,
0x005d, 0x0201, 0x00e0, 0x000e, 0x0801, 0x0201, 0x00e3, 0x0401, 0x0201, 0x00d0, 0x00b7,
0x007b, 0x0601, 0x0401, 0x0201, 0x00a9, 0x00b8, 0x00d4, 0x0201, 0x00e1, 0x0201, 0x00aa,
0x00b9, 0x1801, 0x0a01, 0x0601, 0x0401, 0x0201, 0x009b, 0x00d6, 0x006d, 0x0201, 0x003e,
0x00c8, 0x0601, 0x0401, 0x0201, 0x008c, 0x00e4, 0x004e, 0x0401, 0x0201, 0x00d7, 0x00e5,
0x0201, 0x00ba, 0x00ab, 0x0c01, 0x0401, 0x0201, 0x009c, 0x00e6, 0x0401, 0x0201, 0x006e,
0x00d8, 0x0201, 0x008d, 0x00bb, 0x0801, 0x0401, 0x0201, 0x00e7, 0x009d, 0x0201, 0x00e8,
0x008e, 0x0401, 0x0201, 0x00cb, 0x00bc, 0x009e, 0x00f1, 0x0201, 0x001f, 0x0201, 0x000f,
0x002f, 0x4201, 0x3801, 0x0201, 0x00f2, 0x3401, 0x3201, 0x1401, 0x0801, 0x0201, 0x00bd,
0x0201, 0x005e, 0x0201, 0x007d, 0x00c9, 0x0601, 0x0201, 0x00ca, 0x0201, 0x00ac, 0x007e,
0x0401, 0x0201, 0x00da, 0x00ad, 0x00cc, 0x0a01, 0x0601, 0x0201, 0x00ae, 0x0201, 0x00db,
0x00dc, 0x0201, 0x00cd, 0x00be, 0x0601, 0x0401, 0x0201, 0x00eb, 0x00ed, 0x00ee, 0x0601,
0x0401, 0x0201, 0x00d9, 0x00ea, 0x00e9, 0x0201, 0x00de, 0x0401, 0x0201, 0x00dd, 0x00ec,
0x00ce, 0x003f, 0x00f0, 0x0401, 0x0201, 0x00f3, 0x00f4, 0x0201, 0x004f, 0x0201, 0x00f5,
0x005f, 0x0a01, 0x0201, 0x00ff, 0x0401, 0x0201, 0x00f6, 0x006f, 0x0201, 0x00f7, 0x007f,
0x0c01, 0x0601, 0x0201, 0x008f, 0x0201, 0x00f8, 0x00f9, 0x0401, 0x0201, 0x009f, 0x00fa,
0x00af, 0x0801, 0x0401, 0x0201, 0x00fb, 0x00bf, 0x0201, 0x00fc, 0x00cf, 0x0401, 0x0201,
0x00fd, 0x00df, 0x0201, 0x00fe, 0x00ef,
// 24
0x3c01, 0x0801, 0x0401, 0x0201, 0x0000, 0x0010, 0x0201, 0x0001, 0x0011, 0x0e01, 0x0601,
0x0401, 0x0201, 0x0020, 0x0002, 0x0021, 0x0201, 0x0012, 0x0201, 0x0022, 0x0201, 0x0030,
0x0003, 0x0e01, 0x0401, 0x0201, 0x0031, 0x0013, 0x0401, 0x0201, 0x0032, 0x0023, 0x0401,
0x0201, 0x0040, 0x0004, 0x0041, 0x0801, 0x0401, 0x0201, 0x0014, 0x0033, 0x0201, 0x0042,
0x0024, 0x0601, 0x0401, 0x0201, 0x0043, 0x0034, 0x0051, 0x0601, 0x0401, 0x0201, 0x0050,
0x0005, 0x0015, 0x0201, 0x0052, 0x0025, 0xfa01, 0x6201, 0x2201, 0x1201, 0x0a01, 0x0401,
0x0201, 0x0044, 0x0053, 0x0201, 0x0035, 0x0201, 0x0060, 0x0006, 0x0401, 0x0201, 0x0061,
0x0016, 0x0201, 0x0062, 0x0026, 0x0801, 0x0401, 0x0201, 0x0054, 0x0045, 0x0201, 0x0063,
0x0036, 0x0401, 0x0201, 0x0071, 0x0055, 0x0201, 0x0064, 0x0046, 0x2001, 0x0e01, 0x0601,
0x0201, 0x0072, 0x0201, 0x0027, 0x0037, 0x0201, 0x0073, 0x0401, 0x0201, 0x0070, 0x0007,
0x0017, 0x0a01, 0x0401, 0x0201, 0x0065, 0x0056, 0x0401, 0x0201, 0x0080, 0x0008, 0x0081,
0x0401, 0x0201, 0x0074, 0x0047, 0x0201, 0x0018, 0x0082, 0x1001, 0x0801, 0x0401, 0x0201,
0x0028, 0x0066, 0x0201, 0x0083, 0x0038, 0x0401, 0x0201, 0x0075, 0x0057, 0x0201, 0x0084,
0x0048, 0x0801, 0x0401, 0x0201, 0x0091, 0x0019, 0x0201, 0x0092, 0x0076, 0x0401, 0x0201,
0x0067, 0x0029, 0x0201, 0x0085, 0x0058, 0x5c01, 0x2201, 0x1001, 0x0801, 0x0401, 0x0201,
0x0093, 0x0039, 0x0201, 0x0094, 0x0049, 0x0401, 0x0201, 0x0077, 0x0086, 0x0201, 0x0068,
0x00a1, 0x0801, 0x0401, 0x0201, 0x00a2, 0x002a, 0x0201, 0x0095, 0x0059, 0x0401, 0x0201,
0x00a3, 0x003a, 0x0201, 0x0087, 0x0201, 0x0078, 0x004a, 0x1601, 0x0c01, 0x0401, 0x0201,
0x00a4, 0x0096, 0x0401, 0x0201, 0x0069, 0x00b1, 0x0201, 0x001b, 0x00a5, 0x0601, 0x0201,
0x00b2, 0x0201, 0x005a, 0x002b, 0x0201, 0x0088, 0x00b3, 0x1001, 0x0a01, 0x0601, 0x0201,
0x0090, 0x0201, 0x0009, 0x00a0, 0x0201, 0x0097, 0x0079, 0x0401, 0x0201, 0x00a6, 0x006a,
0x00b4, 0x0c01, 0x0601, 0x0201, 0x001a, 0x0201, 0x000a, 0x00b0, 0x0201, 0x003b, 0x0201,
0x000b, 0x00c0, 0x0401, 0x0201, 0x004b, 0x00c1, 0x0201, 0x0098, 0x0089, 0x4301, 0x2201,
0x1001, 0x0801, 0x0401, 0x0201, 0x001c, 0x00b5, 0x0201, 0x005b, 0x00c2, 0x0401, 0x0201,
0x002c, 0x00a7, 0x0201, 0x007a, 0x00c3, 0x0a01, 0x0601, 0x0201, 0x003c, 0x0201, 0x000c,
0x00d0, 0x0201, 0x00b6, 0x006b, 0x0401, 0x0201, 0x00c4, 0x004c, 0x0201, 0x0099, 0x00a8,
0x1001, 0x0801, 0x0401, 0x0201, 0x008a, 0x00c5, 0x0201, 0x005c, 0x00d1, 0x0401, 0x0201,
0x00b7, 0x007b, 0x0201, 0x001d, 0x00d2, 0x0901, 0x0401, 0x0201, 0x002d, 0x00d3, 0x0201,
0x003d, 0x00c6, 0x55fa, 0x0401, 0x0201, 0x006c, 0x00a9, 0x0201, 0x009a, 0x00d4, 0x2001,
0x1001, 0x0801, 0x0401, 0x0201, 0x00b8, 0x008b, 0x0201, 0x004d, 0x00c7, 0x0401, 0x0201,
0x007c, 0x00d5, 0x0201, 0x005d, 0x00e1, 0x0801, 0x0401, 0x0201, 0x001e, 0x00e2, 0x0201,
0x00aa, 0x00b9, 0x0401, 0x0201, 0x009b, 0x00e3, 0x0201, 0x00d6, 0x006d, 0x1401, 0x0a01,
0x0601, 0x0201, 0x003e, 0x0201, 0x002e, 0x004e, 0x0201, 0x00c8, 0x008c, 0x0401, 0x0201,
0x00e4, 0x00d7, 0x0401, 0x0201, 0x007d, 0x00ab, 0x00e5, 0x0a01, 0x0401, 0x0201, 0x00ba,
0x005e, 0x0201, 0x00c9, 0x0201, 0x009c, 0x006e, 0x0801, 0x0201, 0x00e6, 0x0201, 0x000d,
0x0201, 0x00e0, 0x000e, 0x0401, 0x0201, 0x00d8, 0x008d, 0x0201, 0x00bb, 0x00ca, 0x4a01,
0x0201, 0x00ff, 0x4001, 0x3a01, 0x2001, 0x1001, 0x0801, 0x0401, 0x0201, 0x00ac, 0x00e7,
0x0201, 0x007e, 0x00d9, 0x0401, 0x0201, 0x009d, 0x00e8, 0x0201, 0x008e, 0x00cb, 0x0801,
0x0401, 0x0201, 0x00bc, 0x00da, 0x0201, 0x00ad, 0x00e9, 0x0401, 0x0201, 0x009e, 0x00cc,
0x0201, 0x00db, 0x00bd, 0x1001, 0x0801, 0x0401, 0x0201, 0x00ea, 0x00ae, 0x0201, 0x00dc,
0x00cd, 0x0401, 0x0201, 0x00eb, 0x00be, 0x0201, 0x00dd, 0x00ec, 0x0801, 0x0401, 0x0201,
0x00ce, 0x00ed, 0x0201, 0x00de, 0x00ee, 0x000f, 0x0401, 0x0201, 0x00f0, 0x001f, 0x00f1,
0x0401, 0x0201, 0x00f2, 0x002f, 0x0201, 0x00f3, 0x003f, 0x1201, 0x0801, 0x0401, 0x0201,
0x00f4, 0x004f, 0x0201, 0x00f5, 0x005f, 0x0401, 0x0201, 0x00f6, 0x006f, 0x0201, 0x00f7,
0x0201, 0x007f, 0x008f, 0x0a01, 0x0401, 0x0201, 0x00f8, 0x00f9, 0x0401, 0x0201, 0x009f,
0x00af, 0x00fa, 0x0801, 0x0401, 0x0201, 0x00fb, 0x00bf, 0x0201, 0x00fc, 0x00cf, 0x0401,
0x0201, 0x00fd, 0x00df, 0x0201, 0x00fe, 0x00ef,
// 32
0x0201, 0x0000, 0x0801, 0x0401, 0x0201, 0x0008, 0x0004, 0x0201, 0x0001, 0x0002, 0x0801,
0x0401, 0x0201, 0x000c, 0x000a, 0x0201, 0x0003, 0x0006, 0x0601, 0x0201, 0x0009, 0x0201,
0x0005, 0x0007, 0x0401, 0x0201, 0x000e, 0x000d, 0x0201, 0x000f, 0x000b,
// 33
0x1001, 0x0801, 0x0401, 0x0201, 0x0000, 0x0001, 0x0201, 0x0002, 0x0003, 0x0401, 0x0201,
0x0004, 0x0005, 0x0201, 0x0006, 0x0007, 0x0801, 0x0401, 0x0201, 0x0008, 0x0009, 0x0201,
0x000a, 0x000b, 0x0401, 0x0201, 0x000c, 0x000d, 0x0201, 0x000e, 0x000f,
]);
var huffmanMain = [
{ hufftable: null, linbits: 0}, // Table 0
{ hufftable: huffmanTable.subarray(0, 7), linbits: 0}, // Table 1
{ hufftable: huffmanTable.subarray(7, (7 + 17)), linbits: 0}, // Table 2
{ hufftable: huffmanTable.subarray(24, (24 + 17)), linbits: 0}, // Table 3
{ hufftable: null, linbits: 0}, // Table 4
{ hufftable: huffmanTable.subarray(41, (41 + 31)), linbits: 0}, // Table 5
{ hufftable: huffmanTable.subarray(72, (72 + 31)), linbits: 0}, // Table 6
{ hufftable: huffmanTable.subarray(103, (103 + 71)), linbits: 0}, // Table 7
{ hufftable: huffmanTable.subarray(174, (174 + 71)), linbits: 0}, // Table 8
{ hufftable: huffmanTable.subarray(245, (245 + 71)), linbits: 0}, // Table 9
{ hufftable: huffmanTable.subarray(316, (316 + 127)), linbits: 0}, // Table 10
{ hufftable: huffmanTable.subarray(443, (443 + 127)), linbits: 0}, // Table 11
{ hufftable: huffmanTable.subarray(570, (570 + 127)), linbits: 0}, // Table 12
{ hufftable: huffmanTable.subarray(697, (697 + 511)), linbits: 0}, // Table 13
{ hufftable: null, linbits: 0}, // Table 14
{ hufftable: huffmanTable.subarray(1208, (1208 + 511)), linbits: 0}, // Table 15
{ hufftable: huffmanTable.subarray(1719, (1719 + 511)), linbits: 1}, // Table 16
{ hufftable: huffmanTable.subarray(1719, (1719 + 511)), linbits: 2}, // Table 17
{ hufftable: huffmanTable.subarray(1719, (1719 + 511)), linbits: 3}, // Table 18
{ hufftable: huffmanTable.subarray(1719, (1719 + 511)), linbits: 4}, // Table 19
{ hufftable: huffmanTable.subarray(1719, (1719 + 511)), linbits: 6}, // Table 20
{ hufftable: huffmanTable.subarray(1719, (1719 + 511)), linbits: 8}, // Table 21
{ hufftable: huffmanTable.subarray(1719, (1719 + 511)), linbits: 10},// Table 22
{ hufftable: huffmanTable.subarray(1719, (1719 + 511)), linbits: 13},// Table 23
{ hufftable: huffmanTable.subarray(2230, (2230 + 512)), linbits: 4}, // Table 24
{ hufftable: huffmanTable.subarray(2230, (2230 + 512)), linbits: 5}, // Table 25
{ hufftable: huffmanTable.subarray(2230, (2230 + 512)), linbits: 6}, // Table 26
{ hufftable: huffmanTable.subarray(2230, (2230 + 512)), linbits: 7}, // Table 27
{ hufftable: huffmanTable.subarray(2230, (2230 + 512)), linbits: 8}, // Table 28
{ hufftable: huffmanTable.subarray(2230, (2230 + 512)), linbits: 9}, // Table 29
{ hufftable: huffmanTable.subarray(2230, (2230 + 512)), linbits: 11},// Table 30
{ hufftable: huffmanTable.subarray(2230, (2230 + 512)), linbits: 13},// Table 31
{ hufftable: huffmanTable.subarray(2742, (2742 + 31)), linbits: 0}, // Table 32
{ hufftable: huffmanTable.subarray(2773, (2773 + 31)), linbits: 0}, // Table 33
];
// m -> bits
function decode(m, tableNum) {
var x =0, y = 0 ,v = 0, w = 0;
var point = 0;
var error = 1;
var bitsleft = 32;
var hufftable = huffmanMain[tableNum].hufftable;
var linbits = huffmanMain[tableNum].linbits;
if (null === hufftable) {
return {
x: 0,
y: 0,
v: 0,
w: 0,
err: null
};
}
while(true) { // Start reading the Huffman code word,bit by bit
// Check if we've matched a code word
if ((hufftable[point] & 0xff00) >>> 0 === 0) {
error = 0;
x = (((hufftable[point] >>> 4) >>> 0) & 0xf) >>> 0;
y = (hufftable[point] & 0xf) >>> 0;
break;
}
if (m.Bit() !== 0) { // Go right in tree
while((hufftable[point] & 0xff) >>> 0 >= 250) {
point += ((hufftable[point] & 0xff) >>> 0);
}
point += ((hufftable[point] & 0xff) >>> 0);
} else { // Go left in tree
while(((hufftable[point] >>> 8) >>> 0) >= 250) {
point += (hufftable[point] >>> 8) >>> 0;
}
point += (hufftable[point] >>> 8) >>> 0;
}
bitsleft--;
if ((bitsleft <= 0) || (point >= hufftable.length)) {
break
}
}
if (error !== 0) { // Check for error.
return {
x: 0,
y: 0,
v: 0,
w: 0,
err: "mp3: illegal Huff code in data. bleft = " + bitsleft + ", point = " + point +". tab = " + tableNum + "."
};
}
if (tableNum > 31) { // Process sign encodings for quadruples tables.
v = (((y >>> 3) >>> 0) & 1) >>> 0;
w = (((y >>> 2) >>> 0) & 1) >>> 0;
x = (((y >>> 1) >>> 0) & 1) >>> 0;
y = (y & 1) >>> 0;
if ((v !== 0) && (m.Bit() === 1)) {
v = -v;
}
if ((w !== 0) && (m.Bit() === 1)) {
w = -w;
}
if ((x !== 0) && (m.Bit() === 1)) {
x = -x;
}
if ((y !== 0) && (m.Bit() === 1)) {
y = -y;
}
} else {
if ((linbits !== 0) && (x === 15)) {
x += m.Bits(linbits); // Get linbits
}
if ((x !== 0) && (m.Bit() === 1)) {
x = -x; // Get sign bit
}
if ((linbits !== 0) && (y === 15)) {
y += m.Bits(linbits); // Get linbits
}
if ((y !== 0) && (m.Bit() === 1)) {
y = -y; // Get sign bit
}
}
return {
x: x,
y: y,
v: v,
w: w,
err: null
}
}
exports = {
decode: decode
};

View File

@@ -0,0 +1,95 @@
var imdctWinData = [new Float32Array(36), new Float32Array(36), new Float32Array(36), new Float32Array(36)];
var cosN12 = [];
for (var i = 0; i < 6; i++) {
cosN12.push(new Float32Array(12));
}
var cosN36 = [];
for (var i = 0; i < 18; i++) {
cosN36.push(new Float32Array(36));
}
var init = function () {
for (var i = 0; i < 36; i++) {
imdctWinData[0][i] = Math.sin(Math.PI / 36 * (i + 0.5));
}
for (var i = 0; i < 18; i++) {
imdctWinData[1][i] = Math.sin(Math.PI / 36 * (i + 0.5));
}
for (var i = 18; i < 24; i++) {
imdctWinData[1][i] = 1.0;
}
for (var i = 24; i < 30; i++) {
imdctWinData[1][i] = Math.sin(Math.PI / 12 * (i + 0.5 - 18.0));
}
for (var i = 30; i < 36; i++) {
imdctWinData[1][i] = 0.0;
}
for (var i = 0; i < 12; i++) {
imdctWinData[2][i] = Math.sin(Math.PI / 12 * (i + 0.5));
}
for (var i = 12; i < 36; i++) {
imdctWinData[2][i] = 0.0;
}
for (var i = 0; i < 6; i++) {
imdctWinData[3][i] = 0.0;
}
for (var i = 6; i < 12; i++) {
imdctWinData[3][i] = Math.sin(Math.PI / 12 * (i + 0.5 - 6.0));
}
for (var i = 12; i < 18; i++) {
imdctWinData[3][i] = 1.0;
}
for (var i = 18; i < 36; i++) {
imdctWinData[3][i] = Math.sin(Math.PI / 36 * (i + 0.5));
}
const cosN12_N = 12
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 12; j++) {
cosN12[i][j] = Math.cos(Math.PI / (2 * cosN12_N) * (2*j + 1 + cosN12_N/2) * (2*i + 1));
}
}
const cosN36_N = 36;
for (var i = 0; i < 18; i++) {
for (var j = 0; j < 36; j++) {
cosN36[i][j] = Math.cos(Math.PI / (2 * cosN36_N) * (2*j + 1 + cosN36_N/2) * (2*i + 1));
}
}
};
init();
var Imdct = {
Win: function (inData, blockType) {
var out = new Float32Array(36);
if (blockType === 2) {
var iwd = imdctWinData[blockType];
const N = 12;
for (var i = 0; i < 3; i++) {
for (var p = 0; p < N; p++) {
var sum = 0.0;
for (var m = 0; m < N/2; m++) {
sum += inData[i+3*m] * cosN12[m][p];
}
out[6*i+p+6] += sum * iwd[p];
}
}
return out;
}
const N = 36;
var iwd = imdctWinData[blockType];
for (var p = 0; p < N; p++) {
var sum = 0.0;
for (var m = 0; m < N/2; m++) {
sum += inData[m] * cosN36[m][p];
}
out[p] = sum * iwd[p];
}
return out;
}
};
exports = Imdct;

View File

@@ -0,0 +1,314 @@
var util = require('A:/tvdos/include/js-mp3/util.js');
var consts = require('A:/tvdos/include/js-mp3/consts.js');
var huffman = require('A:/tvdos/include/js-mp3/huffman.js');
var bits = require('A:/tvdos/include/js-mp3/bits.js');
var scalefacSizes = [
[0, 0], [0, 1], [0, 2], [0, 3], [3, 0], [1, 1], [1, 2], [1, 3],
[2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3], [4, 2], [4, 3]
];
var MainData = {
createNew: function () {
// A MainData is MPEG1 Layer 3 Main Data.
var mainData = {
};
util.init3dArray(mainData, 'ScalefacL', 2, 2, 22); // 0-4 bits
util.init4dArray(mainData, 'ScalefacS', 2, 2, 13, 3); // 0-4 bits
util.init3dArray(mainData, 'Is', 2, 2, 576); // Huffman coded freq. lines
return mainData;
},
read: function (source, prev, fh, si) {
var nch = fh.numberOfChannels();
// Calculate header audio data size
var framesize = fh.frameSize();
if (framesize > 2000) {
return {
v: null,
bits: null,
err: "mp3: framesize = " + framesize
}
}
// Sideinfo is 17 bytes for one channel and 32 bytes for two
var sideinfo_size = 32;
if (nch === 1) {
sideinfo_size = 17;
}
// Main data size is the rest of the frame,including ancillary data
var main_data_size = framesize - sideinfo_size - 4; // sync+header
// CRC is 2 bytes
if (fh.protectionBit() === 0) {
main_data_size -= 2;
}
// Assemble main data buffer with data from this frame and the previous
// two frames. main_data_begin indicates how many bytes from previous
// frames that should be used. This buffer is later accessed by the
// Bits function in the same way as the side info is.
var result = read(source, prev, main_data_size, si.MainDataBegin); // read bits for maindata
if (result.err) {
return {
v: null,
bits: null,
err: result.err
}
}
var b = result.b;
var md = MainData.createNew();
for (var gr = 0; gr < 2; gr++) {
for (var ch = 0; ch < nch; ch++) {
var part_2_start = b.BitPos();
// Number of bits in the bitstream for the bands
var slen1 = scalefacSizes[si.ScalefacCompress[gr][ch]][0];
var slen2 = scalefacSizes[si.ScalefacCompress[gr][ch]][1];
if (si.WinSwitchFlag[gr][ch] === 1 && si.BlockType[gr][ch] === 2) {
if (si.MixedBlockFlag[gr][ch] !== 0) {
for (var sfb = 0; sfb < 8; sfb++) {
md.ScalefacL[gr][ch][sfb] = b.Bits(slen1)
}
for (var sfb = 3; sfb < 12; sfb++) {
//slen1 for band 3-5,slen2 for 6-11
var nbits = slen2;
if (sfb < 6) {
nbits = slen1;
}
for (var win = 0; win < 3; win++) {
md.ScalefacS[gr][ch][sfb][win] = b.Bits(nbits);
}
}
} else {
for (var sfb = 0; sfb < 12; sfb++) {
//slen1 for band 3-5,slen2 for 6-11
var nbits = slen2;
if (sfb < 6) {
nbits = slen1;
}
for (var win = 0; win < 3; win++) {
md.ScalefacS[gr][ch][sfb][win] = b.Bits(nbits);
}
}
}
} else {
// Scale factor bands 0-5
if (si.Scfsi[ch][0] === 0 || gr === 0) {
for (var sfb = 0; sfb < 6; sfb++) {
md.ScalefacL[gr][ch][sfb] = b.Bits(slen1);
}
} else if (si.Scfsi[ch][0] === 1 && gr === 1) {
// Copy scalefactors from granule 0 to granule 1
// TODO: This is not listed on the spec.
for (var sfb = 0; sfb < 6; sfb++) {
md.ScalefacL[1][ch][sfb] = md.ScalefacL[0][ch][sfb];
}
}
// Scale factor bands 6-10
if (si.Scfsi[ch][1] === 0 || gr === 0) {
for (var sfb = 6; sfb < 11; sfb++) {
md.ScalefacL[gr][ch][sfb] = b.Bits(slen1);
}
} else if (si.Scfsi[ch][1] === 1 && gr === 1) {
// Copy scalefactors from granule 0 to granule 1
for (var sfb = 6; sfb < 11; sfb++) {
md.ScalefacL[1][ch][sfb] = md.ScalefacL[0][ch][sfb];
}
}
// Scale factor bands 11-15
if (si.Scfsi[ch][2] === 0 || gr === 0) {
for (var sfb = 11; sfb < 16; sfb++) {
md.ScalefacL[gr][ch][sfb] = b.Bits(slen2);
}
} else if (si.Scfsi[ch][2] === 1 && gr === 1) {
// Copy scalefactors from granule 0 to granule 1
for (var sfb = 11; sfb < 16; sfb++) {
md.ScalefacL[1][ch][sfb] = md.ScalefacL[0][ch][sfb];
}
}
// Scale factor bands 16-20
if (si.Scfsi[ch][3] === 0 || gr === 0) {
for (var sfb = 16; sfb < 21; sfb++) {
md.ScalefacL[gr][ch][sfb] = b.Bits(slen2);
}
} else if (si.Scfsi[ch][3] === 1 && gr === 1) {
// Copy scalefactors from granule 0 to granule 1
for (var sfb = 16; sfb < 21; sfb++) {
md.ScalefacL[1][ch][sfb] = md.ScalefacL[0][ch][sfb];
}
}
}
var err = readHuffman(b, fh, si, md, part_2_start, gr, ch);
if (err) {
return {
v: null,
bits: null,
err: err
}
}
}
}
return {
v: md,
bits: b,
err: null
}
}
};
var read = function (source, prev, size, offset) {
if (size > 1500) {
return {
b: null,
err: "mp3: size = " + size
}
}
// Check that there's data available from previous frames if needed
if (prev !== null && offset > prev.LenInBytes()) {
// No, there is not, so we skip decoding this frame, but we have to
// read the main_data bits from the bitstream in case they are needed
// for decoding the next frame.
var buf = new Uint8Array(source, 0, size);
if (buf.byteLength < size) {
return {
b: null,
err: "maindata.Read (1)"
}
}
// TODO: Define a special error and enable to continue the next frame.
return {
m: bits.append(prev, buf),
err: null
};
}
// Copy data from previous frames
var vec;
if (prev !== null) {
vec = prev.Tail(offset);
}
// Read the main_data from file
var result = source.readFull(size);
if (result.err) {
return {
err: result.err
}
}
var buf = result.buf;
// var buf = new Uint8Array(source, 0, size);
if (buf.byteLength < size) {
return {
b: null,
err: "maindata.Read (2)"
}
}
return {
b: bits.createNew(util.concatBuffers(vec, new Uint8Array(buf.slice()).buffer)),
err: null
}
};
var readHuffman = function (m, header, sideInfo, mainData, part_2_start, gr, ch) {
// Check that there is any data to decode. If not, zero the array.
if (sideInfo.Part2_3Length[gr][ch] === 0) {
for (var i = 0; i < consts.SamplesPerGr; i++) {
mainData.Is[gr][ch][i] = 0.0;
}
return null;
}
// Calculate bit_pos_end which is the index of the last bit for this part.
var bit_pos_end = part_2_start + sideInfo.Part2_3Length[gr][ch] - 1;
// Determine region boundaries
var region_1_start = 0;
var region_2_start = 0;
if ((sideInfo.WinSwitchFlag[gr][ch] === 1) && (sideInfo.BlockType[gr][ch] === 2)) {
region_1_start = 36; // sfb[9/3]*3=36
region_2_start = consts.SamplesPerGr; // No Region2 for short block case.
} else {
var sfreq = header.samplingFrequency().value;
var l = consts.SfBandIndicesSet[sfreq].L;
var i = sideInfo.Region0Count[gr][ch] + 1;
if (i < 0 || util.len(l) <= i) {
// TODO: Better error messages (#3)
return "mp3: readHuffman failed: invalid index i: " + i;
}
region_1_start = l[i];
var j = sideInfo.Region0Count[gr][ch] + sideInfo.Region1Count[gr][ch] + 2;
if (j < 0 || util.len(l) <= j) {
// TODO: Better error messages (#3)
return "mp3: readHuffman failed: invalid index j: " + j;
}
region_2_start = l[j];
}
// Read big_values using tables according to region_x_start
for (var is_pos = 0; is_pos < sideInfo.BigValues[gr][ch]*2; is_pos++) {
// #22
if (is_pos >= util.len(mainData.Is[gr][ch])) {
return "mp3: is_pos was too big: " + is_pos;
}
var table_num = 0;
if (is_pos < region_1_start) {
table_num = sideInfo.TableSelect[gr][ch][0];
} else if (is_pos < region_2_start) {
table_num = sideInfo.TableSelect[gr][ch][1];
} else {
table_num = sideInfo.TableSelect[gr][ch][2];
}
// Get next Huffman coded words
var result = huffman.decode(m, table_num);
if (result.err) {
return err;
}
// In the big_values area there are two freq lines per Huffman word
mainData.Is[gr][ch][is_pos] = result.x;
is_pos++;
mainData.Is[gr][ch][is_pos] = result.y;
}
// Read small values until is_pos = 576 or we run out of huffman data
// TODO: Is this comment wrong?
var table_num = sideInfo.Count1TableSelect[gr][ch] + 32;
var is_pos = sideInfo.BigValues[gr][ch] * 2;
for (;is_pos <= 572 && m.BitPos() <= bit_pos_end;) {
// Get next Huffman coded words
var result = huffman.decode(m, table_num);
if (result.err) {
return err;
}
mainData.Is[gr][ch][is_pos] = result.v;
is_pos++;
if (is_pos >= consts.SamplesPerGr) {
break;
}
mainData.Is[gr][ch][is_pos] = result.w;
is_pos++;
if (is_pos >= consts.SamplesPerGr) {
break;
}
mainData.Is[gr][ch][is_pos] = result.x;
is_pos++;
if (is_pos >= consts.SamplesPerGr) {
break;
}
mainData.Is[gr][ch][is_pos] = result.y;
is_pos++;
}
// Check that we didn't read past the end of this section
if (m.BitPos() > (bit_pos_end + 1)) {
// Remove last words read
is_pos -= 4;
}
// Setup count1 which is the index of the first sample in the rzero reg.
sideInfo.Count1[gr][ch] = is_pos;
// Zero out the last part if necessary
for (;is_pos < consts.SamplesPerGr;) {
mainData.Is[gr][ch][is_pos] = 0.0;
is_pos++;
}
// Set the bitpos to point to the next part to read
m.SetPos(bit_pos_end + 1);
return null;
};
exports = MainData;

View File

@@ -0,0 +1,157 @@
var Bits = require('A:/tvdos/include/js-mp3/bits.js');
var consts = require('A:/tvdos/include/js-mp3/consts.js');
var util = require('A:/tvdos/include/js-mp3/util.js');
var Sideinfo = {
createNew: function () {
// A SideInfo is MPEG1 Layer 3 Side Information.
// [2][2] means [gr][ch].
// MainDataBegin int // 9 bits
// PrivateBits int // 3 bits in mono, 5 in stereo
// Scfsi [2][4]int // 1 bit
// Part2_3Length [2][2]int // 12 bits
// BigValues [2][2]int // 9 bits
// GlobalGain [2][2]int // 8 bits
// ScalefacCompress [2][2]int // 4 bits
// WinSwitchFlag [2][2]int // 1 bit
//
// BlockType [2][2]int // 2 bits
// MixedBlockFlag [2][2]int // 1 bit
// TableSelect [2][2][3]int // 5 bits
// SubblockGain [2][2][3]int // 3 bits
//
// Region0Count [2][2]int // 4 bits
// Region1Count [2][2]int // 3 bits
//
// Preflag [2][2]int // 1 bit
// ScalefacScale [2][2]int // 1 bit
// Count1TableSelect [2][2]int // 1 bit
// Count1 [2][2]int // Not in file, calc by huffman decoder
var sideinfo = {
};
util.init2dArray(sideinfo, 'Scfsi', 2, 4);
util.init2dArray(sideinfo, 'Part2_3Length', 2, 2);
util.init2dArray(sideinfo, 'BigValues', 2, 2);
util.init2dArray(sideinfo, 'GlobalGain', 2, 2);
util.init2dArray(sideinfo, 'ScalefacCompress', 2, 2);
util.init2dArray(sideinfo, 'WinSwitchFlag', 2, 2);
util.init2dArray(sideinfo, 'BlockType', 2, 2);
util.init2dArray(sideinfo, 'MixedBlockFlag', 2, 2);
util.init3dArray(sideinfo, 'TableSelect', 2, 2, 3);
util.init3dArray(sideinfo, 'SubblockGain', 2, 2, 3);
util.init2dArray(sideinfo, 'Region0Count', 2, 2);
util.init2dArray(sideinfo, 'Region1Count', 2, 2);
util.init2dArray(sideinfo, 'Preflag', 2, 2);
util.init2dArray(sideinfo, 'ScalefacScale', 2, 2);
util.init2dArray(sideinfo, 'Count1TableSelect', 2, 2);
util.init2dArray(sideinfo, 'Count1', 2, 2);
return sideinfo;
},
read: function (source, fheader, pos) {
var nch = fheader.numberOfChannels();
// Calculate header audio data size
var framesize = fheader.frameSize();
if (framesize > 2000) {
return {
v: null,
err: "mp3: framesize = " + framesize
}
}
// Sideinfo is 17 bytes for one channel and 32 bytes for two
var sideinfo_size = 32;
if (nch === 1) {
sideinfo_size = 17;
}
// Main data size is the rest of the frame,including ancillary data
var main_data_size = framesize - sideinfo_size - 4; // sync+header
// CRC is 2 bytes
if (fheader.protectionBit() === 0) {
main_data_size -= 2;
}
// Read sideinfo from bitstream into buffer used by Bits()
var result = source.readFull(sideinfo_size);
if (result.err) {
return {
err: result.err
}
}
var buf = result.buf;
// var buf = new Uint8Array(source.buf, pos, sideinfo_size);
if (buf.byteLength < sideinfo_size) {
return {
v: null,
pos: pos,
err: "mp3: couldn't read sideinfo " + sideinfo_size + " bytes"
}
}
var s = Bits.createNew(new Uint8Array(buf.slice()).buffer);
// Parse audio data
// Pointer to where we should start reading main data
var si = Sideinfo.createNew();
si.MainDataBegin = s.Bits(9);
// Get private bits. Not used for anything.
if (fheader.mode() === consts.ModeSingleChannel) {
si.PrivateBits = s.Bits(5);
} else {
si.PrivateBits = s.Bits(3);
}
// Get scale factor selection information
for (var ch = 0; ch < nch; ch++) {
for (var scfsi_band = 0; scfsi_band < 4; scfsi_band++) {
si.Scfsi[ch][scfsi_band] = s.Bits(1);
}
}
// Get the rest of the side information
for (var gr = 0; gr < 2; gr++) {
for (var ch = 0; ch < nch; ch++) {
si.Part2_3Length[gr][ch] = s.Bits(12);
si.BigValues[gr][ch] = s.Bits(9);
si.GlobalGain[gr][ch] = s.Bits(8);
si.ScalefacCompress[gr][ch] = s.Bits(4);
si.WinSwitchFlag[gr][ch] = s.Bits(1);
if (si.WinSwitchFlag[gr][ch] === 1) {
si.BlockType[gr][ch] = s.Bits(2);
si.MixedBlockFlag[gr][ch] = s.Bits(1);
for (var region = 0; region < 2; region++) {
si.TableSelect[gr][ch][region] = s.Bits(5);
}
for (var window = 0; window < 3; window++) {
si.SubblockGain[gr][ch][window] = s.Bits(3);
}
// TODO: This is not listed on the spec. Is this correct??
if (si.BlockType[gr][ch] === 2 && si.MixedBlockFlag[gr][ch] === 0) {
si.Region0Count[gr][ch] = 8; // Implicit
} else {
si.Region0Count[gr][ch] = 7; // Implicit
}
// The standard is wrong on this!!!
// Implicit
si.Region1Count[gr][ch] = 20 - si.Region0Count[gr][ch];
} else {
for (var region = 0; region < 3; region++) {
si.TableSelect[gr][ch][region] = s.Bits(5);
}
si.Region0Count[gr][ch] = s.Bits(4);
si.Region1Count[gr][ch] = s.Bits(3);
si.BlockType[gr][ch] = 0; // Implicit
}
si.Preflag[gr][ch] = s.Bits(1);
si.ScalefacScale[gr][ch] = s.Bits(1);
si.Count1TableSelect[gr][ch] = s.Bits(1);
}
}
return {
v: si,
err: null
}
}
};
exports = Sideinfo;

View File

@@ -0,0 +1,108 @@
function init2dArray(root, prop, first, second) {
root[prop] = [];
for (var i = 0; i < first; i++) {
root[prop].push([]);
}
for(var i = 0; i < root[prop].length; i++) {
for (var j = 0; j < second; j++) {
root[prop][i].push(0);
}
}
}
function init3dArray(root, prop, first, second, third) {
root[prop] = [];
for (var i = 0; i < first; i++) {
root[prop].push([]);
}
for(var i = 0; i < root[prop].length; i++) {
for (var j = 0; j < second; j++) {
root[prop][i].push([])
}
for (var x = 0; x < root[prop][i].length; x++) {
for (var y = 0; y < third; y++) {
root[prop][i][x].push(0);
}
}
}
}
function init4dArray(root, prop, first, second, third, fourth) {
root[prop] = [];
for (var i = 0; i < first; i++) {
root[prop].push([]);
}
for(var i = 0; i < root[prop].length; i++) {
for (var j = 0; j < second; j++) {
root[prop][i].push([])
}
for (var x = 0; x < root[prop][i].length; x++) {
for (var y = 0; y < third; y++) {
var a = [];
for (var z = 0; z < fourth; z++) {
a.push(0);
}
root[prop][i][x].push(a);
}
}
}
}
function concatTypedArrays(a, b) { // a, b TypedArray of same type
var c = new (a.constructor)(a.length + b.length);
c.set(a, 0);
c.set(b, a.length);
return c;
}
function concatBuffers(a, b) {
return concatTypedArrays(
new Uint8Array((!!a ? a.buffer : new ArrayBuffer(0)) || a),
new Uint8Array((!!b ? b.buffer : new ArrayBuffer(0)) || b)
).buffer;
}
function concatBytes(ui8a, byte) {
var b = new Uint8Array(1);
b[0] = byte;
return concatTypedArrays(ui8a, b);
}
function len(v) {
if (typeof(v) === 'object') {
return v.length;
}
return 0;
}
exports = {
init2dArray: init2dArray,
init3dArray: init3dArray,
init4dArray: init4dArray,
concatTypedArrays: concatTypedArrays,
concatBuffers: concatBuffers,
concatBytes: concatBytes,
len: len,
string: {
bin: function (v) {
return parseInt(v);
}
},
number: {
bin: function (v) {
var sign = (v < 0 ? "-" : "");
var result = Math.abs(v).toString(2);
while(result.length < 32) {
result = "0" + result;
}
return sign + result;
}
}
};

View File

@@ -0,0 +1,282 @@
/*
js-mp3
https://github.com/soundbus-technologies/js-mp3
Copyright (c) 2018 SoundBus Technologies CO., LTD.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
var Frame = require('A:/tvdos/include/js-mp3/frame.js');
var util = require('A:/tvdos/include/js-mp3/util.js');
var consts = require('A:/tvdos/include/js-mp3/consts.js');
var Frameheader = require('A:/tvdos/include/js-mp3/frameheader.js');
const invalidLength = -1;
var Mp3 = {
// Create new source object with specified ArrayBuffer
newSource: function(buf) {
var source = {
buf: buf,
pos: 0
};
/**
* Seek the buffer position
*
* @param position
* @param whence
*/
source.seek = function (position) {
if (position < 0 || position > source.buf.byteLength) {
return {
err: "position not correct"
}
}
source.pos = position;
return {
pos: source.pos
};
};
source.readFull = function (length) {
try {
if (length < 0) throw Error("Source.pos less than 0: "+source.pos)
var l = Math.min(source.buf.byteLength - source.pos, length);
if (l < 0) {
serial.println("l < 0: "+l)
throw Error("l < 0: "+l)
}
var bbuf = new Uint8Array(source.buf, source.pos, l);
source.pos += bbuf.byteLength;
if (source.pos < 0) {
throw Error("pos < 0: "+source.pos)
}
return {
buf: bbuf,
err: null
};
} catch (e) {
return {
buf: null,
err: e.toString()
}
}
};
source.getPos = function () {
if (source.pos > 3) {
return source.pos - 3; // skip tags
}
return source.pos;
};
source.skipTags = function () {
var result = source.readFull(3);
if (result.err) {
return {
err: result.err
}
}
var buf = result.buf;
// decode UTF-8
var t = String.fromCharCode.apply(null, buf);
switch (t) {
case "TAG":
result = source.readFull(125);
if (result.err) {
return {
err: result.err
}
}
buf = result.buf;
break;
case 'ID3':
// Skip version (2 bytes) and flag (1 byte)
result = source.readFull(3);
if (result.err) {
return {
err: result.err
}
}
result = source.readFull(4);
if (result.err) {
return {
err: result.err
}
}
buf = result.buf;
if (buf.byteLength !== 4) {
return {
err: "data not enough."
};
}
var size = (((buf[0] >>> 0) << 21) >>> 0) | (((buf[1] >>> 0) << 14) >>> 0) | (((buf[2] >>> 0) << 7) >>> 0) | (buf[3] >>> 0);
result = source.readFull(size);
if (result.err) {
return {
err: result.err
}
}
buf = result.buf;
break;
default:
source.unread(buf);
// source.pos -= 3;
break;
}
return {};
};
source.unread = function (buf) {
source.pos -= buf.byteLength
};
source.rewind = function() {
source.pos = 0;
};
return source;
},
newDecoder: function (buf) {
var s = Mp3.newSource(buf);
var decoder = {
source: s,
sampleRate: 0,
frame: null,
frameStarts: [],
// buf: null,
pos: 0,
length: invalidLength
};
// ======= Methods of decoder :: start =========
decoder.readFrame = function () {
var result = Frame.read(decoder.source, decoder.source.pos, decoder.frame);
if (result.err) {
return {
err: result.err
}
}
decoder.frame = result.f;
var pcm_buf = decoder.frame.decode();
// decoder.buf = util.concatBuffers(decoder.buf, pcm_buf);
return { buf: pcm_buf };
};
decoder.decode = function (callback) {
var result;
while(true) {
result = decoder.readFrame();
if (typeof callback == "function") callback(result)
if (result.err) {
break;
}
}
// return decoder.buf;
};
decoder.ensureFrameStartsAndLength = function () {
if (decoder.length !== invalidLength) {
return {}
}
var pos = decoder.source.pos;
decoder.source.rewind();
var r = decoder.source.skipTags();
if (r.err) {
return {
err: r.err
}
}
var l = 0;
while(true) {
var result = Frameheader.read(decoder.source, decoder.source.pos);
if (result.err) {
if (result.err.toString().indexOf("UnexpectedEOF") > -1) {
break;
}
return {
err: result.err
};
}
decoder.frameStarts.push(result.position);
l += consts.BytesPerFrame;
result = decoder.source.readFull(result.h.frameSize() - 4); // move to next frame position
if (result.err) {
break;
}
}
decoder.length = l;
var result = decoder.source.seek(pos); // reset to beginning position
if (result.err) {
return result;
}
return {};
};
// ======= Methods of decoder :: end =========
var r = s.skipTags();
if (r && r.err) {
throw Error(`Error creating new MP3 source: ${r.err}`)
return null;
}
var result = decoder.readFrame();
if (result.err) {
throw Error(`Error reading frame: ${result.err}`)
return null;
}
decoder.sampleRate = decoder.frame.samplingFrequency();
result = decoder.ensureFrameStartsAndLength();
if (result.err) {
throw Error(`Error ensuring Frame starts and length: ${result.err}`)
return null;
}
return decoder;
}
};
exports = Mp3;