@audio/decode-caf 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/decode-caf.js +12 -5
- package/package.json +1 -1
package/decode-caf.js
CHANGED
|
@@ -23,7 +23,7 @@ export default async function decode(src) {
|
|
|
23
23
|
* @returns {Promise<{decode(chunk: Uint8Array): {channelData, sampleRate}, flush(), free()}>}
|
|
24
24
|
*/
|
|
25
25
|
export async function decoder() {
|
|
26
|
-
let hdr = null, left = null, freed = false
|
|
26
|
+
let hdr = null, left = null, freed = false, dataLeft = Infinity
|
|
27
27
|
return {
|
|
28
28
|
decode(data) {
|
|
29
29
|
if (freed) throw Error('Decoder already freed')
|
|
@@ -33,12 +33,17 @@ export async function decoder() {
|
|
|
33
33
|
if (!hdr) {
|
|
34
34
|
hdr = scanCafHdr(chunk)
|
|
35
35
|
if (!hdr) { left = chunk.slice(); return EMPTY }
|
|
36
|
+
dataLeft = hdr.dataSize
|
|
36
37
|
chunk = chunk.subarray(hdr.dataStart)
|
|
37
38
|
}
|
|
39
|
+
if (dataLeft <= 0) return EMPTY // past the data chunk — ignore trailing chunks
|
|
38
40
|
let fb = hdr.frameBytes
|
|
39
|
-
let
|
|
40
|
-
|
|
41
|
-
if (chunk.length >
|
|
41
|
+
let avail = Math.min(chunk.length, dataLeft) // don't read past the declared data size
|
|
42
|
+
let complete = Math.floor(avail / fb) * fb
|
|
43
|
+
if (!complete) { if (chunk.length && dataLeft > chunk.length) left = chunk.slice(); return EMPTY }
|
|
44
|
+
dataLeft -= complete
|
|
45
|
+
let rest = chunk.subarray(complete)
|
|
46
|
+
if (rest.length && dataLeft > 0) left = rest.subarray(0, Math.min(rest.length, dataLeft)).slice()
|
|
42
47
|
return decodeCafRaw(chunk.subarray(0, complete), hdr)
|
|
43
48
|
},
|
|
44
49
|
flush() { left = null; return EMPTY },
|
|
@@ -78,13 +83,15 @@ function scanCafHdr(buf) {
|
|
|
78
83
|
if (!desc) return null
|
|
79
84
|
let dataStart = off + 4 // skip editCount
|
|
80
85
|
if (dataStart > buf.length) return null
|
|
86
|
+
// -1 (0xFFFF…) size means "until EOF" — read to end; else payload minus 4-byte editCount
|
|
87
|
+
let dataSize = (sizeHi === 0xFFFFFFFF && sizeLo === 0xFFFFFFFF) ? Infinity : Math.max(0, size - 4)
|
|
81
88
|
let { formatID, formatFlags, channelsPerFrame: ch, bitsPerChannel: bits } = desc
|
|
82
89
|
let bytesPerSample = bits >> 3
|
|
83
90
|
let frameBytes
|
|
84
91
|
if (formatID === 'alaw' || formatID === 'ulaw') frameBytes = ch
|
|
85
92
|
else frameBytes = ch * bytesPerSample
|
|
86
93
|
if (!frameBytes) return null
|
|
87
|
-
return { ...desc, dataStart, frameBytes }
|
|
94
|
+
return { ...desc, dataStart, frameBytes, dataSize }
|
|
88
95
|
}
|
|
89
96
|
if (size < 0) break
|
|
90
97
|
if (sizeHi === 0xFFFFFFFF && sizeLo === 0xFFFFFFFF) break
|