@wasm-audio-decoders/common
Advanced tools
Comparing version 4.0.1 to 5.0.0
{ | ||
"name": "@wasm-audio-decoders/common", | ||
"version": "4.0.1", | ||
"version": "5.0.0", | ||
"description": "Web Assembly Audio Decoders Common", | ||
@@ -5,0 +5,0 @@ "module": "index.js", |
export default function WASMAudioDecoderCommon(caller) { | ||
// setup static methods | ||
const uint8Array = Uint8Array; | ||
const uint16Array = Uint16Array; | ||
const float32Array = Float32Array; | ||
if (!WASMAudioDecoderCommon.concatFloat32) { | ||
if (!WASMAudioDecoderCommon.modules) { | ||
Object.defineProperties(WASMAudioDecoderCommon, { | ||
modules: { | ||
value: new WeakMap(), | ||
}, | ||
setModule: { | ||
value(Ref, module) { | ||
WASMAudioDecoderCommon.modules.set(Ref, Promise.resolve(module)); | ||
}, | ||
}, | ||
getModule: { | ||
value(Ref, wasmString) { | ||
let module = WASMAudioDecoderCommon.modules.get(Ref); | ||
if (!module) { | ||
if (!wasmString) { | ||
wasmString = Ref.wasm; | ||
module = WASMAudioDecoderCommon.inflateDynEncodeString( | ||
wasmString | ||
).then((data) => WebAssembly.compile(data)); | ||
} else { | ||
module = WebAssembly.compile( | ||
WASMAudioDecoderCommon.decodeDynString(wasmString) | ||
); | ||
} | ||
WASMAudioDecoderCommon.modules.set(Ref, module); | ||
} | ||
return module; | ||
}, | ||
}, | ||
concatFloat32: { | ||
@@ -60,4 +92,4 @@ value(buffers, length) { | ||
inflateDynEncodeString: { | ||
value(source, dest) { | ||
decodeDynString: { | ||
value(source) { | ||
const output = new uint8Array(source.length); | ||
@@ -89,391 +121,58 @@ const offset = parseInt(source.substring(11, 13), 16); | ||
return WASMAudioDecoderCommon.inflate( | ||
output.subarray(0, byteIndex), | ||
dest | ||
); | ||
return output.subarray(0, byteIndex); | ||
}, | ||
}, | ||
inflate: { | ||
value(source, dest) { | ||
const TINF_OK = 0; | ||
const TINF_DATA_ERROR = -3; | ||
const _16 = 16, | ||
_24 = 24, | ||
_30 = 30, | ||
_144 = 144, | ||
_256 = 256; | ||
inflateDynEncodeString: { | ||
value(source) { | ||
source = WASMAudioDecoderCommon.decodeDynString(source); | ||
function Tree() { | ||
this.t = new uint16Array(_16); /* table of code length counts */ | ||
this.trans = new uint16Array( | ||
288 | ||
); /* code -> symbol translation table */ | ||
} | ||
return new Promise((resolve) => { | ||
// prettier-ignore | ||
const puffString = String.raw`dynEncode0014u*ttt$#U¤¤U¤¤3yzzss|yusvuyÚ&4<054<,5T44^T44<(6U~J(44< ~A544U~6J0444545 444J0444J,4U4U Ò7U454U4Z4U4U^/6545T4T44BU~64CU~O4U54U~5 U5T4B4Z!4U~5U5U5T4U~6U4ZTU5U5T44~4O4U2ZTU5T44Z!4B6T44U~64B6U~O44U~4O4U~54U~5 44~C4~54U~5 44~5454U4B6Ub!444~UO4U~5 U54U4ZTU#44U$464<4~B6^4<444~U~B4U~54U544~544~U5 µUä#UJUè#5TT4U0ZTTUX5U5T4T4Uà#~4OU4U $~C4~54U~5 T44$6U\!TTT4UaT4<6T4<64<Z!44~4N4<U~5 4UZ!4U±_TU#44UU6UÔ~B$544$6U\!4U6U¤#~B44Uä#~B$~64<6_TU#444U~B~6~54<Y!44<_!T4Y!4<64~444~AN44<U~6J4U5 44J4U[!U#44UO4U~54U~5 U54 7U6844J44J 4UJ4UJ04VK(44<J44<J$4U´~54U~5 4U¤~5!TTT4U$5"U5TTTTTTT4U$"4VK,U54<(6U~64<$6_!4< 64~6A54A544U~6#J(U54A4U[!44J(44#~A4U6UUU [!4464~64_!4<64~54<6T4<4]TU5 T4Y!44~44~AN4U~54U~54U5 44J(44J UÄA!U5U#UôJU"UÔJU#UÔ"JU#U´"JT4U´ZTU5T4UôZTU5T4UDZTU5T4U$[T44~UO4U~5 UÔUô4U~U´$.U5T4UP[T4U~4~UO4U~5 U#<U#<4U~U2$.UÄUN 44 ~UO4U~5 44!~UO4U~5 4U~4~UO4U~5 44J44J(U5 44U¤~J@44Uä~J<44UD~J844U~J44U$54U$5U54U$54U1^4U1^!4U~54U~5U54U~6U4U^/65T4T4U$54U~4BU~4O4U54U~5 UU'464U'_/54UU~5T4T4U~4BU~UO4U54U~5 U54Uä~4U¤~4U~U'$!44~5U5T44\T44U<~$6U\!4U#aT4U~4U~4O4U~5 U5U5U5TTT4U$"4YTU5 4U4~C5U5 U5U5444$4~64~\TU5 4U~4U~5T4Y!44O4U~54U~54U5 4CYTU5 4Uä~4U¤~4U~4$6TU54U\!44Bæ4Bä~[!4U~4UD~4U~4U~4$6TU54U\!44B4B~[!44U<~4U4~$5 4U"U#$544"Y!454U^!44<J44<(J454U~84UN!#%'+/37?GOWgw·×÷Uä;U9$%& !"#`; | ||
function Data(source, dest) { | ||
this.s = source; | ||
this.i = 0; | ||
this.t = 0; | ||
this.bitcount = 0; | ||
WASMAudioDecoderCommon.getModule(WASMAudioDecoderCommon, puffString) | ||
.then((wasm) => WebAssembly.instantiate(wasm, {})) | ||
.then(({ exports }) => { | ||
// required for minifiers that mangle the __heap_base property | ||
const instanceExports = new Map(Object.entries(exports)); | ||
this.dest = dest; | ||
this.destLen = 0; | ||
const puff = instanceExports.get("puff"); | ||
const memory = instanceExports.get("memory")["buffer"]; | ||
const dataArray = new uint8Array(memory); | ||
const heapView = new DataView(memory); | ||
this.ltree = new Tree(); /* dynamic length/symbol tree */ | ||
this.dtree = new Tree(); /* dynamic distance tree */ | ||
} | ||
let heapPos = instanceExports.get("__heap_base"); | ||
/* --------------------------------------------------- * | ||
* -- uninitialized global data (static structures) -- * | ||
* --------------------------------------------------- */ | ||
// source length | ||
const sourceLength = source.length; | ||
const sourceLengthPtr = heapPos; | ||
heapPos += 4; | ||
heapView.setInt32(sourceLengthPtr, sourceLength, true); | ||
const sltree = new Tree(); | ||
const sdtree = new Tree(); | ||
// source data | ||
const sourcePtr = heapPos; | ||
heapPos += sourceLength; | ||
dataArray.set(source, sourcePtr); | ||
/* extra bits and base tables for length codes */ | ||
const length_bits = new uint8Array(_30); | ||
const length_base = new uint16Array(_30); | ||
// destination length | ||
const destLengthPtr = heapPos; | ||
heapPos += 4; | ||
heapView.setInt32( | ||
destLengthPtr, | ||
dataArray.byteLength - heapPos, | ||
true | ||
); | ||
/* extra bits and base tables for distance codes */ | ||
const dist_bits = new uint8Array(_30); | ||
const dist_base = new uint16Array(_30); | ||
// destination data fills in the rest of the heap | ||
puff(heapPos, destLengthPtr, sourcePtr, sourceLengthPtr); | ||
/* special ordering of code length codes */ | ||
const clcidx = new uint8Array([ | ||
_16, | ||
17, | ||
18, | ||
0, | ||
8, | ||
7, | ||
9, | ||
6, | ||
10, | ||
5, | ||
11, | ||
4, | ||
12, | ||
3, | ||
13, | ||
2, | ||
14, | ||
1, | ||
15, | ||
]); | ||
/* used by tinf_decode_trees, avoids allocations every call */ | ||
const code_tree = new Tree(); | ||
const lengths = new uint8Array(288 + 32); | ||
/* ----------------------- * | ||
* -- utility functions -- * | ||
* ----------------------- */ | ||
/* build extra bits and base tables */ | ||
const tinf_build_bits_base = (bits, base, delta, first) => { | ||
let i, sum; | ||
/* build bits table */ | ||
for (i = 0; i < delta; ) bits[i++] = 0; | ||
for (i = 0; i < _30 - delta; ) bits[i + delta] = (i++ / delta) | 0; | ||
/* build base table */ | ||
for (sum = first, i = 0; i < _30; ) { | ||
base[i] = sum; | ||
sum += 1 << bits[i++]; | ||
} | ||
}; | ||
/* build the fixed huffman trees */ | ||
const tinf_build_fixed_trees = (lt, dt) => { | ||
let i; | ||
/* build fixed length tree */ | ||
for (i = 0; i < 7; ) lt.t[i++] = 0; | ||
lt.t[7] = _24; | ||
lt.t[8] = 152; | ||
lt.t[9] = 112; | ||
for (i = 0; i < _24; ) lt.trans[i] = _256 + i++; | ||
for (i = 0; i < _144; ) lt.trans[_24 + i] = i++; | ||
for (i = 0; i < 8; ) lt.trans[_24 + _144 + i] = 280 + i++; | ||
for (i = 0; i < 112; ) lt.trans[_24 + _144 + 8 + i] = _144 + i++; | ||
/* build fixed distance tree */ | ||
for (i = 0; i < 5; ) dt.t[i++] = 0; | ||
dt.t[5] = 32; | ||
for (i = 0; i < 32; ) dt.trans[i] = i++; | ||
}; | ||
/* given an array of code lengths, build a tree */ | ||
const offs = new uint16Array(_16); | ||
const tinf_build_tree = (t, lengths, off, num) => { | ||
let i, sum; | ||
/* clear code length count table */ | ||
for (i = 0; i < _16; ) t.t[i++] = 0; | ||
/* scan symbol lengths, and sum code length counts */ | ||
for (i = 0; i < num; ) t.t[lengths[off + i++]]++; | ||
t.t[0] = 0; | ||
/* compute offset table for distribution sort */ | ||
for (sum = 0, i = 0; i < _16; ) { | ||
offs[i] = sum; | ||
sum += t.t[i++]; | ||
} | ||
/* create code->symbol translation table (symbols sorted by code) */ | ||
for (i = 0; i < num; ++i) | ||
if (lengths[off + i]) t.trans[offs[lengths[off + i]]++] = i; | ||
}; | ||
/* ---------------------- * | ||
* -- decode functions -- * | ||
* ---------------------- */ | ||
/* get one bit from source stream */ | ||
const tinf_getbit = (d) => { | ||
/* check if tag is empty */ | ||
if (!d.bitcount--) { | ||
/* load next tag */ | ||
d.t = d.s[d.i++]; | ||
d.bitcount = 7; | ||
} | ||
/* shift bit out of tag */ | ||
const bit = d.t & 1; | ||
d.t >>>= 1; | ||
return bit; | ||
}; | ||
/* read a num bit value from a stream and add base */ | ||
const tinf_read_bits = (d, num, base) => { | ||
if (!num) return base; | ||
while (d.bitcount < _24) { | ||
d.t |= d.s[d.i++] << d.bitcount; | ||
d.bitcount += 8; | ||
} | ||
const val = d.t & (65535 >>> (_16 - num)); | ||
d.t >>>= num; | ||
d.bitcount -= num; | ||
return val + base; | ||
}; | ||
/* given a data stream and a tree, decode a symbol */ | ||
const tinf_decode_symbol = (d, t) => { | ||
while (d.bitcount < _24) { | ||
d.t |= d.s[d.i++] << d.bitcount; | ||
d.bitcount += 8; | ||
} | ||
let sum = 0, | ||
cur = 0, | ||
len = 0, | ||
tag = d.t; | ||
/* get more bits while code value is above sum */ | ||
do { | ||
cur = 2 * cur + (tag & 1); | ||
tag >>>= 1; | ||
++len; | ||
sum += t.t[len]; | ||
cur -= t.t[len]; | ||
} while (cur >= 0); | ||
d.t = tag; | ||
d.bitcount -= len; | ||
return t.trans[sum + cur]; | ||
}; | ||
/* given a data stream, decode dynamic trees from it */ | ||
const tinf_decode_trees = (d, lt, dt) => { | ||
let i, | ||
length, | ||
num = 0; | ||
/* get 5 bits HLIT (257-286) */ | ||
const hlit = tinf_read_bits(d, 5, 257); | ||
/* get 5 bits HDIST (1-32) */ | ||
const hdist = tinf_read_bits(d, 5, 1); | ||
/* get 4 bits HCLEN (4-19) */ | ||
const hclen = tinf_read_bits(d, 4, 4); | ||
for (i = 0; i < 19; ) lengths[i++] = 0; | ||
/* read code lengths for code length alphabet */ | ||
for (i = 0; i < hclen; ) { | ||
/* get 3 bits code length (0-7) */ | ||
const clen = tinf_read_bits(d, 3, 0); | ||
lengths[clcidx[i++]] = clen; | ||
} | ||
/* build code length tree */ | ||
tinf_build_tree(code_tree, lengths, 0, 19); | ||
/* decode code lengths for the dynamic trees */ | ||
while (num < hlit + hdist) { | ||
const sym = tinf_decode_symbol(d, code_tree); | ||
switch (sym) { | ||
case _16: | ||
/* copy previous code length 3-6 times (read 2 bits) */ | ||
const prev = lengths[num - 1]; | ||
length = tinf_read_bits(d, 2, 3); | ||
while (length--) lengths[num++] = prev; | ||
break; | ||
case 17: | ||
/* repeat code length 0 for 3-10 times (read 3 bits) */ | ||
length = tinf_read_bits(d, 3, 3); | ||
while (length--) lengths[num++] = 0; | ||
break; | ||
case 18: | ||
/* repeat code length 0 for 11-138 times (read 7 bits) */ | ||
length = tinf_read_bits(d, 7, 11); | ||
while (length--) lengths[num++] = 0; | ||
break; | ||
default: | ||
/* values 0-15 represent the actual code lengths */ | ||
lengths[num++] = sym; | ||
break; | ||
} | ||
} | ||
/* build dynamic trees */ | ||
tinf_build_tree(lt, lengths, 0, hlit); | ||
tinf_build_tree(dt, lengths, hlit, hdist); | ||
}; | ||
/* ----------------------------- * | ||
* -- block inflate functions -- * | ||
* ----------------------------- */ | ||
/* given a stream and two trees, inflate a block of data */ | ||
const tinf_inflate_block_data = (d, lt, dt) => { | ||
while (1) { | ||
let sym = tinf_decode_symbol(d, lt); | ||
/* check for end of block */ | ||
if (sym === _256) return TINF_OK; | ||
if (sym < _256) { | ||
d.dest[d.destLen++] = sym; | ||
} else { | ||
let length, dist, offs; | ||
sym -= 257; | ||
/* possibly get more bits from length code */ | ||
length = tinf_read_bits(d, length_bits[sym], length_base[sym]); | ||
dist = tinf_decode_symbol(d, dt); | ||
/* possibly get more bits from distance code */ | ||
offs = | ||
d.destLen - | ||
tinf_read_bits(d, dist_bits[dist], dist_base[dist]); | ||
/* copy match */ | ||
for (let i = offs; i < offs + length; ) { | ||
d.dest[d.destLen++] = d.dest[i++]; | ||
} | ||
} | ||
} | ||
}; | ||
/* inflate an uncompressed block of data */ | ||
const tinf_inflate_uncompressed_block = (d) => { | ||
let length, invlength; | ||
/* unread from bitbuffer */ | ||
while (d.bitcount > 8) { | ||
d.i--; | ||
d.bitcount -= 8; | ||
} | ||
/* get length */ | ||
length = d.s[d.i + 1]; | ||
length = _256 * length + d.s[d.i]; | ||
/* get one's complement of length */ | ||
invlength = d.s[d.i + 3]; | ||
invlength = _256 * invlength + d.s[d.i + 2]; | ||
/* check length */ | ||
if (length !== (~invlength & 65535)) return TINF_DATA_ERROR; | ||
d.i += 4; | ||
/* copy block */ | ||
while (length--) d.dest[d.destLen++] = d.s[d.i++]; | ||
/* make sure we start next block on a byte boundary */ | ||
d.bitcount = 0; | ||
return TINF_OK; | ||
}; | ||
/* -------------------- * | ||
* -- initialization -- * | ||
* -------------------- */ | ||
/* build fixed huffman trees */ | ||
tinf_build_fixed_trees(sltree, sdtree); | ||
/* build extra bits and base tables */ | ||
tinf_build_bits_base(length_bits, length_base, 4, 3); | ||
tinf_build_bits_base(dist_bits, dist_base, 2, 1); | ||
/* fix a special case */ | ||
length_bits[28] = 0; | ||
length_base[28] = 258; | ||
const d = new Data(source, dest); | ||
let bfinal, btype, res; | ||
do { | ||
/* read final block flag */ | ||
bfinal = tinf_getbit(d); | ||
/* read block type (2 bits) */ | ||
btype = tinf_read_bits(d, 2, 0); | ||
/* decompress block */ | ||
switch (btype) { | ||
case 0: | ||
/* decompress uncompressed block */ | ||
res = tinf_inflate_uncompressed_block(d); | ||
break; | ||
case 1: | ||
/* decompress block with fixed huffman trees */ | ||
res = tinf_inflate_block_data(d, sltree, sdtree); | ||
break; | ||
case 2: | ||
/* decompress block with dynamic huffman trees */ | ||
tinf_decode_trees(d, d.ltree, d.dtree); | ||
res = tinf_inflate_block_data(d, d.ltree, d.dtree); | ||
break; | ||
default: | ||
res = TINF_DATA_ERROR; | ||
} | ||
if (res !== TINF_OK) throw new Error("Data error"); | ||
} while (!bfinal); | ||
return d.destLen < d.dest.length | ||
? d.dest.subarray(0, d.destLen) | ||
: d.dest; | ||
resolve( | ||
dataArray.slice( | ||
heapPos, | ||
heapPos + heapView.getInt32(destLengthPtr, true) | ||
) | ||
); | ||
}); | ||
}); | ||
}, | ||
@@ -522,16 +221,26 @@ }, | ||
this._wasm = new caller._EmscriptenWASM(WASMAudioDecoderCommon); | ||
this._pointers = new Set(); | ||
this.instantiate = () => { | ||
const _module = caller._module; | ||
const _EmscriptenWASM = caller._EmscriptenWASM; | ||
const _inputSize = caller._inputSize; | ||
const _outputChannels = caller._outputChannels; | ||
const _outputChannelSize = caller._outputChannelSize; | ||
return this._wasm.ready.then(() => { | ||
caller._input = this.allocateTypedArray(caller._inputSize, uint8Array); | ||
if (_module) WASMAudioDecoderCommon.setModule(_EmscriptenWASM, _module); | ||
// output buffer | ||
caller._output = this.allocateTypedArray( | ||
caller._outputChannels * caller._outputChannelSize, | ||
float32Array | ||
); | ||
this._wasm = new _EmscriptenWASM(WASMAudioDecoderCommon).instantiate(); | ||
this._pointers = new Set(); | ||
return this; | ||
}); | ||
return this._wasm.ready.then(() => { | ||
caller._input = this.allocateTypedArray(_inputSize, uint8Array); | ||
// output buffer | ||
caller._output = this.allocateTypedArray( | ||
_outputChannels * _outputChannelSize, | ||
float32Array | ||
); | ||
return this; | ||
}); | ||
}; | ||
} |
@@ -5,84 +5,85 @@ import Worker from "web-worker"; | ||
export default class WASMAudioDecoderWorker extends Worker { | ||
constructor(options, Decoder, EmscriptenWASM) { | ||
const webworkerSourceCode = | ||
"'use strict';" + | ||
// dependencies need to be manually resolved when stringifying this function | ||
`(${((_options, _Decoder, _WASMAudioDecoderCommon, _EmscriptenWASM) => { | ||
// We're in a Web Worker | ||
Object.defineProperties(_Decoder, { | ||
WASMAudioDecoderCommon: { value: _WASMAudioDecoderCommon }, | ||
EmscriptenWASM: { value: _EmscriptenWASM }, | ||
isWebWorker: { value: true }, | ||
}); | ||
constructor(options, name, Decoder, EmscriptenWASM) { | ||
if (!WASMAudioDecoderCommon.modules) new WASMAudioDecoderCommon(); | ||
const decoder = new _Decoder(_options); | ||
let source = WASMAudioDecoderCommon.modules.get(Decoder); | ||
self.onmessage = ({ data: { id, command, data } }) => { | ||
switch (command) { | ||
case "ready": | ||
decoder.ready.then(() => { | ||
self.postMessage({ | ||
id, | ||
}); | ||
if (!source) { | ||
const webworkerSourceCode = | ||
"'use strict';" + | ||
// dependencies need to be manually resolved when stringifying this function | ||
`(${((_options, _Decoder, _WASMAudioDecoderCommon, _EmscriptenWASM) => { | ||
// We're in a Web Worker | ||
// setup Promise that will be resolved once the WebAssembly Module is received | ||
let decoder, | ||
moduleResolve, | ||
modulePromise = new Promise((resolve) => { | ||
moduleResolve = resolve; | ||
}); | ||
self.onmessage = ({ data: { id, command, data } }) => { | ||
let messagePromise = modulePromise, | ||
messagePayload = { id }, | ||
transferList; | ||
if (command === "module") { | ||
Object.defineProperties(_Decoder, { | ||
WASMAudioDecoderCommon: { value: _WASMAudioDecoderCommon }, | ||
EmscriptenWASM: { value: _EmscriptenWASM }, | ||
module: { value: data }, | ||
isWebWorker: { value: true }, | ||
}); | ||
break; | ||
case "free": | ||
decoder = new _Decoder(_options); | ||
moduleResolve(); | ||
} else if (command === "free") { | ||
decoder.free(); | ||
self.postMessage({ | ||
id, | ||
}); | ||
break; | ||
case "reset": | ||
decoder.reset().then(() => { | ||
self.postMessage({ | ||
id, | ||
}); | ||
}); | ||
break; | ||
case "decode": | ||
case "decodeFrame": | ||
case "decodeFrames": | ||
const { channelData, samplesDecoded, sampleRate } = decoder[ | ||
command | ||
]( | ||
// detach buffers | ||
Array.isArray(data) | ||
? data.map((data) => new Uint8Array(data)) | ||
: new Uint8Array(data) | ||
} else if (command === "ready") { | ||
messagePromise = messagePromise.then(() => decoder.ready); | ||
} else if (command === "reset") { | ||
messagePromise = messagePromise.then(() => decoder.reset()); | ||
} else { | ||
// "decode": | ||
// "decodeFrame": | ||
// "decodeFrames": | ||
Object.assign( | ||
messagePayload, | ||
decoder[command]( | ||
// detach buffers | ||
Array.isArray(data) | ||
? data.map((data) => new Uint8Array(data)) | ||
: new Uint8Array(data) | ||
) | ||
); | ||
self.postMessage( | ||
{ | ||
id, | ||
channelData, | ||
samplesDecoded, | ||
sampleRate, | ||
}, | ||
// The "transferList" parameter transfers ownership of channel data to main thread, | ||
// which avoids copying memory. | ||
channelData.map((channel) => channel.buffer) | ||
// The "transferList" parameter transfers ownership of channel data to main thread, | ||
// which avoids copying memory. | ||
transferList = messagePayload.channelData.map( | ||
(channel) => channel.buffer | ||
); | ||
break; | ||
default: | ||
this.console.error("Unknown command sent to worker: " + command); | ||
} | ||
}; | ||
}).toString()})(${JSON.stringify( | ||
options | ||
)}, ${Decoder}, ${WASMAudioDecoderCommon}, ${EmscriptenWASM})`; | ||
} | ||
const type = "text/javascript"; | ||
let source; | ||
messagePromise.then(() => | ||
self.postMessage(messagePayload, transferList) | ||
); | ||
}; | ||
}).toString()})(${JSON.stringify( | ||
options | ||
)}, ${Decoder}, ${WASMAudioDecoderCommon}, ${EmscriptenWASM})`; | ||
try { | ||
// browser | ||
source = URL.createObjectURL(new Blob([webworkerSourceCode], { type })); | ||
} catch { | ||
// nodejs | ||
source = `data:${type};base64,${Buffer.from(webworkerSourceCode).toString( | ||
"base64" | ||
)}`; | ||
const type = "text/javascript"; | ||
try { | ||
// browser | ||
source = URL.createObjectURL(new Blob([webworkerSourceCode], { type })); | ||
WASMAudioDecoderCommon.modules.set(Decoder, source); | ||
} catch { | ||
// nodejs | ||
source = `data:${type};base64,${Buffer.from( | ||
webworkerSourceCode | ||
).toString("base64")}`; | ||
} | ||
} | ||
super(source); | ||
super(source, { name }); | ||
@@ -97,2 +98,6 @@ this._id = Number.MIN_SAFE_INTEGER; | ||
}; | ||
new EmscriptenWASM(WASMAudioDecoderCommon).getModule().then((compiled) => { | ||
this._postToDecoder("module", compiled); | ||
}); | ||
} | ||
@@ -99,0 +104,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
58411
8
0
68
343
1
1