mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
mp3 test
This commit is contained in:
@@ -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)
|
||||
21
assets/disk0/tvdos/include/js-mp3/LICENSE
Normal file
21
assets/disk0/tvdos/include/js-mp3/LICENSE
Normal 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.
|
||||
84
assets/disk0/tvdos/include/js-mp3/bits.js
Normal file
84
assets/disk0/tvdos/include/js-mp3/bits.js
Normal 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;
|
||||
60
assets/disk0/tvdos/include/js-mp3/consts.js
Normal file
60
assets/disk0/tvdos/include/js-mp3/consts.js
Normal 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;
|
||||
741
assets/disk0/tvdos/include/js-mp3/frame.js
Normal file
741
assets/disk0/tvdos/include/js-mp3/frame.js
Normal 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;
|
||||
283
assets/disk0/tvdos/include/js-mp3/frameheader.js
Normal file
283
assets/disk0/tvdos/include/js-mp3/frameheader.js
Normal 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;
|
||||
412
assets/disk0/tvdos/include/js-mp3/huffman.js
Normal file
412
assets/disk0/tvdos/include/js-mp3/huffman.js
Normal 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
|
||||
};
|
||||
95
assets/disk0/tvdos/include/js-mp3/imdct.js
Normal file
95
assets/disk0/tvdos/include/js-mp3/imdct.js
Normal 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;
|
||||
314
assets/disk0/tvdos/include/js-mp3/maindata.js
Normal file
314
assets/disk0/tvdos/include/js-mp3/maindata.js
Normal 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;
|
||||
157
assets/disk0/tvdos/include/js-mp3/sideinfo.js
Normal file
157
assets/disk0/tvdos/include/js-mp3/sideinfo.js
Normal 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;
|
||||
108
assets/disk0/tvdos/include/js-mp3/util.js
Normal file
108
assets/disk0/tvdos/include/js-mp3/util.js
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
282
assets/disk0/tvdos/include/mp3dec.js
Normal file
282
assets/disk0/tvdos/include/mp3dec.js
Normal 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;
|
||||
Reference in New Issue
Block a user