@openclaw/whatsapp 2026.5.28 → 2026.5.31-beta.1
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/dist/{access-control-Z0fYaWrx.js → access-control-C53zKYSN.js} +1 -1
- package/dist/{accounts-BMGM1RtF.js → accounts-DgViSyJx.js} +1 -0
- package/dist/{action-runtime-BdhkGtaP.js → action-runtime-Cyp5GNIT.js} +2 -2
- package/dist/action-runtime-api.js +1 -1
- package/dist/action-runtime.runtime.js +1 -1
- package/dist/api.js +9 -9
- package/dist/{approval-handler.runtime-C25wPeBf.js → approval-handler.runtime-BVmOu6x1.js} +1 -2
- package/dist/{auth-store-BrKb0mwT.js → auth-store-CZ22aNcV.js} +4 -2
- package/dist/{channel-D3y4A5Dd.js → channel-DA2BAIo5.js} +17 -64
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-react-action-Cd2qkLqp.js → channel-react-action-zvbaCnGe.js} +3 -3
- package/dist/{channel.runtime-C228XUjs.js → channel.runtime-Q1LZDB5s.js} +4 -4
- package/dist/{channel.setup-BJQyTUUP.js → channel.setup-DHXOo4h5.js} +2 -3
- package/dist/{config-schema-CsNDlDpL.js → config-schema-CROZuhT-.js} +16 -0
- package/dist/{connection-controller-mpPGmqGq.js → connection-controller-Bnm4INld.js} +2 -2
- package/dist/contract-api.js +1 -1
- package/dist/light-runtime-api.js +1 -1
- package/dist/{login-CE4UYnyO.js → login-2fuBM7Je.js} +4 -4
- package/dist/{login-qr-LBvhEes5.js → login-qr-B1o7GFy8.js} +10 -6
- package/dist/login-qr-runtime.js +1 -1
- package/dist/{monitor-Ccph7Y8M.js → monitor-BVRq04Dt.js} +36 -18
- package/dist/runtime-api.js +7 -7
- package/dist/{send-C4LG-Cl6.js → send-DSlVXKL_.js} +53 -41
- package/dist/{send-api-C66vkRl9.js → send-api-Bjn-h80j.js} +3 -2
- package/dist/{session-D8UW2Vbn.js → session-DyGWNClj.js} +1 -1
- package/dist/{setup-core-DpfT4K-2.js → setup-core-OvPMaAsx.js} +4 -4
- package/dist/{setup-finalize-CFnxX7la.js → setup-finalize-Dk23pfKc.js} +3 -3
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-DRsmp0ZS.js → setup-surface-F-jVrH8u.js} +3 -3
- package/node_modules/@audio/decode-aac/LICENSE +9 -0
- package/node_modules/@audio/decode-aac/README.md +60 -0
- package/node_modules/@audio/decode-aac/decode-aac.d.ts +16 -0
- package/node_modules/@audio/decode-aac/decode-aac.js +391 -0
- package/node_modules/@audio/decode-aac/package.json +47 -0
- package/node_modules/@audio/decode-aac/src/aac.wasm.cjs +0 -0
- package/node_modules/@audio/decode-aiff/LICENSE +21 -0
- package/node_modules/@audio/decode-aiff/README.md +53 -0
- package/node_modules/@audio/decode-aiff/decode-aiff.d.ts +16 -0
- package/node_modules/@audio/decode-aiff/decode-aiff.js +583 -0
- package/node_modules/@audio/decode-aiff/package.json +42 -0
- package/node_modules/@audio/decode-amr/LICENSE +191 -0
- package/node_modules/@audio/decode-amr/README.md +65 -0
- package/node_modules/@audio/decode-amr/decode-amr.d.ts +16 -0
- package/node_modules/@audio/decode-amr/decode-amr.js +159 -0
- package/node_modules/@audio/decode-amr/package.json +48 -0
- package/node_modules/@audio/decode-amr/src/amr.wasm.cjs +0 -0
- package/node_modules/@audio/decode-caf/LICENSE +21 -0
- package/node_modules/@audio/decode-caf/README.md +55 -0
- package/node_modules/@audio/decode-caf/decode-caf.d.ts +16 -0
- package/node_modules/@audio/decode-caf/decode-caf.js +190 -0
- package/node_modules/@audio/decode-caf/package.json +43 -0
- package/node_modules/{audio-buffer → @audio/decode-flac}/LICENSE +5 -2
- package/node_modules/@audio/decode-flac/README.md +23 -0
- package/node_modules/@audio/decode-flac/decode-flac.d.ts +16 -0
- package/node_modules/@audio/decode-flac/decode-flac.js +2994 -0
- package/node_modules/@audio/decode-flac/meta.js +115 -0
- package/node_modules/@audio/decode-flac/package.json +49 -0
- package/node_modules/@audio/decode-mp3/LICENSE +25 -0
- package/node_modules/@audio/decode-mp3/README.md +23 -0
- package/node_modules/@audio/decode-mp3/decode-mp3.d.ts +16 -0
- package/node_modules/@audio/decode-mp3/decode-mp3.js +868 -0
- package/node_modules/@audio/decode-mp3/meta.js +143 -0
- package/node_modules/@audio/decode-mp3/package.json +50 -0
- package/node_modules/@audio/decode-opus/LICENSE +25 -0
- package/node_modules/@audio/decode-opus/README.md +23 -0
- package/node_modules/@audio/decode-opus/decode-opus.d.ts +16 -0
- package/node_modules/@audio/decode-opus/decode-opus.js +3179 -0
- package/node_modules/@audio/decode-opus/package.json +47 -0
- package/node_modules/@audio/decode-qoa/LICENSE +25 -0
- package/node_modules/@audio/decode-qoa/README.md +21 -0
- package/node_modules/@audio/decode-qoa/decode-qoa.d.ts +16 -0
- package/node_modules/@audio/decode-qoa/decode-qoa.js +278 -0
- package/node_modules/@audio/decode-qoa/package.json +46 -0
- package/node_modules/@audio/decode-vorbis/LICENSE +25 -0
- package/node_modules/@audio/decode-vorbis/README.md +23 -0
- package/node_modules/@audio/decode-vorbis/decode-vorbis.d.ts +16 -0
- package/node_modules/@audio/decode-vorbis/decode-vorbis.js +2984 -0
- package/node_modules/@audio/decode-vorbis/package.json +47 -0
- package/node_modules/@audio/decode-wav/decode-wav.js +104 -0
- package/node_modules/@audio/decode-wav/meta.js +114 -0
- package/node_modules/@audio/decode-wav/package.json +27 -0
- package/node_modules/@audio/decode-webm/LICENSE +21 -0
- package/node_modules/@audio/decode-webm/README.md +57 -0
- package/node_modules/@audio/decode-webm/decode-webm.d.ts +16 -0
- package/node_modules/@audio/decode-webm/decode-webm.js +3964 -0
- package/node_modules/@audio/decode-webm/package.json +51 -0
- package/node_modules/@audio/decode-wma/LICENSE +12 -0
- package/node_modules/@audio/decode-wma/README.md +76 -0
- package/node_modules/@audio/decode-wma/decode-wma.d.ts +33 -0
- package/node_modules/@audio/decode-wma/decode-wma.js +525 -0
- package/node_modules/@audio/decode-wma/package.json +47 -0
- package/node_modules/@audio/decode-wma/src/wma.wasm.cjs +0 -0
- package/node_modules/audio-decode/.claude/settings.json +204 -0
- package/node_modules/audio-decode/.github/workflows/test.js.yml +11 -20
- package/node_modules/audio-decode/.gitmodules +9 -0
- package/node_modules/audio-decode/audio-decode.d.ts +48 -10
- package/node_modules/audio-decode/audio-decode.js +193 -77
- package/node_modules/audio-decode/meta.js +11 -0
- package/node_modules/audio-decode/package.json +49 -21
- package/node_modules/audio-decode/readme.md +129 -29
- package/node_modules/audio-decode/stream.d.ts +15 -0
- package/node_modules/audio-decode/stream.js +1 -0
- package/node_modules/audio-decode/test.html +29 -10
- package/node_modules/lru-cache/dist/commonjs/browser/index.d.ts +2 -2
- package/node_modules/lru-cache/dist/commonjs/browser/index.d.ts.map +1 -1
- package/node_modules/lru-cache/dist/commonjs/browser/index.js.map +1 -1
- package/node_modules/lru-cache/dist/commonjs/browser/index.min.js.map +1 -1
- package/node_modules/lru-cache/dist/commonjs/index.d.ts +2 -2
- package/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/lru-cache/dist/commonjs/index.js.map +1 -1
- package/node_modules/lru-cache/dist/commonjs/index.min.js.map +1 -1
- package/node_modules/lru-cache/dist/commonjs/node/index.d.ts +2 -2
- package/node_modules/lru-cache/dist/commonjs/node/index.d.ts.map +1 -1
- package/node_modules/lru-cache/dist/commonjs/node/index.js.map +1 -1
- package/node_modules/lru-cache/dist/commonjs/node/index.min.js.map +1 -1
- package/node_modules/lru-cache/dist/esm/browser/index.d.ts +2 -2
- package/node_modules/lru-cache/dist/esm/browser/index.d.ts.map +1 -1
- package/node_modules/lru-cache/dist/esm/browser/index.js.map +1 -1
- package/node_modules/lru-cache/dist/esm/browser/index.min.js.map +1 -1
- package/node_modules/lru-cache/dist/esm/index.d.ts +2 -2
- package/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -1
- package/node_modules/lru-cache/dist/esm/index.js.map +1 -1
- package/node_modules/lru-cache/dist/esm/index.min.js.map +1 -1
- package/node_modules/lru-cache/dist/esm/node/index.d.ts +2 -2
- package/node_modules/lru-cache/dist/esm/node/index.d.ts.map +1 -1
- package/node_modules/lru-cache/dist/esm/node/index.js.map +1 -1
- package/node_modules/lru-cache/dist/esm/node/index.min.js.map +1 -1
- package/node_modules/lru-cache/package.json +1 -1
- package/node_modules/typebox/build/type/script/mapping.d.mts +5 -2
- package/node_modules/typebox/build/type/script/mapping.mjs +15 -8
- package/node_modules/typebox/build/type/script/parser.d.mts +3 -1
- package/node_modules/typebox/build/type/script/parser.mjs +2 -1
- package/node_modules/typebox/package.json +29 -29
- package/npm-shrinkwrap.json +156 -39
- package/openclaw.plugin.json +76 -0
- package/package.json +6 -6
- package/node_modules/audio-buffer/.eslintrc.json +0 -44
- package/node_modules/audio-buffer/.github/workflows/node.js.yml +0 -31
- package/node_modules/audio-buffer/.travis.yml +0 -7
- package/node_modules/audio-buffer/index.js +0 -76
- package/node_modules/audio-buffer/package.json +0 -37
- package/node_modules/audio-buffer/readme.md +0 -56
- package/node_modules/audio-decode/.eslintrc.json +0 -43
- package/node_modules/audio-decode/.travis.yml +0 -13
- package/node_modules/audio-decode/tea.yaml +0 -6
- package/node_modules/audio-decode/test-case.js +0 -11
- package/node_modules/audio-decode/test.js +0 -107
- package/node_modules/node-wav/README.md +0 -35
- package/node_modules/node-wav/file.wav +0 -0
- package/node_modules/node-wav/index.js +0 -291
- package/node_modules/node-wav/package.json +0 -29
- package/node_modules/node-wav/tests/file1.wav +0 -0
- package/node_modules/node-wav/tests/test.js +0 -66
- package/node_modules/node-wav/x.js +0 -12
- package/node_modules/node-wav/x.json +0 -86702
- package/node_modules/node-wav/x.js~ +0 -13
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIFF/AIFF-C decoder — pure JS
|
|
3
|
+
* Decodes AIFF and AIFF-C audio to Float32Array PCM samples
|
|
4
|
+
*
|
|
5
|
+
* let { channelData, sampleRate } = await decode(aiffbuf)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const EMPTY = Object.freeze({ channelData: [], sampleRate: 0 })
|
|
9
|
+
|
|
10
|
+
// A-law expansion table (ITU-T G.711)
|
|
11
|
+
const ALAW_TBL = new Int16Array(256)
|
|
12
|
+
// mu-law expansion table (ITU-T G.711)
|
|
13
|
+
const ULAW_TBL = new Int16Array(256)
|
|
14
|
+
|
|
15
|
+
;(function buildTables() {
|
|
16
|
+
for (let i = 0; i < 256; i++) {
|
|
17
|
+
// A-law
|
|
18
|
+
let ax = i ^ 0x55, seg = (ax >> 4) & 7, val = ((ax & 0x0F) << 4) + 8
|
|
19
|
+
if (seg) val = (val + 256) << (seg - 1)
|
|
20
|
+
ALAW_TBL[i] = (ax & 0x80) ? val : -val
|
|
21
|
+
|
|
22
|
+
// mu-law
|
|
23
|
+
let ux = ~i & 0xFF
|
|
24
|
+
seg = (ux >> 4) & 7
|
|
25
|
+
val = ((ux & 0x0F) << 3) + 132
|
|
26
|
+
val <<= seg
|
|
27
|
+
ULAW_TBL[i] = (ux & 0x80) ? (val - 132) : -(val - 132)
|
|
28
|
+
}
|
|
29
|
+
})()
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Read 80-bit IEEE 754 extended precision float
|
|
33
|
+
*/
|
|
34
|
+
function readF80(b, o) {
|
|
35
|
+
let sign = (b[o] >> 7) & 1
|
|
36
|
+
let exp = ((b[o] & 0x7F) << 8) | b[o + 1]
|
|
37
|
+
let hi = ((b[o + 2] << 24) | (b[o + 3] << 16) | (b[o + 4] << 8) | b[o + 5]) >>> 0
|
|
38
|
+
let lo = ((b[o + 6] << 24) | (b[o + 7] << 16) | (b[o + 8] << 8) | b[o + 9]) >>> 0
|
|
39
|
+
if (exp === 0 && hi === 0 && lo === 0) return 0
|
|
40
|
+
if (exp === 0x7FFF) return sign ? -Infinity : Infinity
|
|
41
|
+
let f = (hi * 4294967296 + lo) / 9223372036854775808 // / 2^63
|
|
42
|
+
return (sign ? -1 : 1) * f * Math.pow(2, exp - 16383)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function str4(b, o) {
|
|
46
|
+
return String.fromCharCode(b[o], b[o + 1], b[o + 2], b[o + 3])
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function r32(b, o) {
|
|
50
|
+
return ((b[o] << 24) | (b[o + 1] << 16) | (b[o + 2] << 8) | b[o + 3]) >>> 0
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function r16(b, o) {
|
|
54
|
+
return (b[o] << 8) | b[o + 1]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Parse AIFF/AIFF-C and decode to Float32Array channels
|
|
59
|
+
*/
|
|
60
|
+
function parseAiff(buf) {
|
|
61
|
+
if (!buf || buf.length < 12) return EMPTY
|
|
62
|
+
|
|
63
|
+
let b = buf instanceof Uint8Array ? buf : new Uint8Array(buf)
|
|
64
|
+
if (b.length < 12) return EMPTY
|
|
65
|
+
|
|
66
|
+
// Validate FORM header
|
|
67
|
+
if (str4(b, 0) !== 'FORM') throw Error('Not an AIFF file')
|
|
68
|
+
let form = str4(b, 8)
|
|
69
|
+
if (form !== 'AIFF' && form !== 'AIFC') throw Error('Not an AIFF file')
|
|
70
|
+
let isAIFC = form === 'AIFC'
|
|
71
|
+
|
|
72
|
+
let nCh = 0, nFrames = 0, bps = 0, sr = 0, comp = 'NONE'
|
|
73
|
+
let ssndOff = -1, ssndSize = 0
|
|
74
|
+
|
|
75
|
+
// Parse chunks
|
|
76
|
+
let pos = 12, end = Math.min(8 + r32(b, 4), b.length)
|
|
77
|
+
while (pos + 8 <= end) {
|
|
78
|
+
let ckId = str4(b, pos)
|
|
79
|
+
let ckSize = r32(b, pos + 4)
|
|
80
|
+
let ckData = pos + 8
|
|
81
|
+
|
|
82
|
+
if (ckId === 'COMM') {
|
|
83
|
+
if (ckData + 18 > b.length) throw Error('Truncated COMM chunk')
|
|
84
|
+
nCh = r16(b, ckData)
|
|
85
|
+
nFrames = r32(b, ckData + 2)
|
|
86
|
+
bps = r16(b, ckData + 6)
|
|
87
|
+
sr = readF80(b, ckData + 8)
|
|
88
|
+
if (isAIFC && ckSize >= 22 && ckData + 22 <= b.length) {
|
|
89
|
+
comp = str4(b, ckData + 18)
|
|
90
|
+
}
|
|
91
|
+
} else if (ckId === 'SSND') {
|
|
92
|
+
if (ckData + 8 > b.length) throw Error('Truncated SSND chunk')
|
|
93
|
+
let dataOff = r32(b, ckData)
|
|
94
|
+
ssndOff = ckData + 8 + dataOff
|
|
95
|
+
ssndSize = ckSize - 8 - dataOff
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
pos = ckData + ckSize + (ckSize & 1) // pad to even
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!nCh || !nFrames || !sr || ssndOff < 0) return EMPTY
|
|
102
|
+
|
|
103
|
+
// Determine byte depth and decode strategy
|
|
104
|
+
let byteDepth = Math.ceil(bps / 8)
|
|
105
|
+
let frameBytes = byteDepth * nCh
|
|
106
|
+
let actualFrames = Math.min(nFrames, Math.floor(Math.min(ssndSize, b.length - ssndOff) / frameBytes))
|
|
107
|
+
if (actualFrames <= 0) return EMPTY
|
|
108
|
+
|
|
109
|
+
let channelData = Array.from({ length: nCh }, () => new Float32Array(actualFrames))
|
|
110
|
+
let p = ssndOff
|
|
111
|
+
|
|
112
|
+
// Compression-aware decode
|
|
113
|
+
let cUpper = comp.toUpperCase()
|
|
114
|
+
if (cUpper === 'NONE' || cUpper === 'TWOS' || comp === 'twos') {
|
|
115
|
+
// Big-endian signed integer PCM
|
|
116
|
+
decodePCM_BE(b, p, channelData, actualFrames, nCh, bps, byteDepth)
|
|
117
|
+
} else if (comp === 'sowt') {
|
|
118
|
+
// Little-endian signed integer PCM
|
|
119
|
+
decodePCM_LE(b, p, channelData, actualFrames, nCh, bps, byteDepth)
|
|
120
|
+
} else if (comp === 'fl32' || comp === 'FL32') {
|
|
121
|
+
decodeFloat32_BE(b, p, channelData, actualFrames, nCh)
|
|
122
|
+
} else if (comp === 'fl64' || comp === 'FL64') {
|
|
123
|
+
decodeFloat64_BE(b, p, channelData, actualFrames, nCh)
|
|
124
|
+
} else if (comp === 'alaw') {
|
|
125
|
+
decodeLaw(b, p, channelData, actualFrames, nCh, ALAW_TBL)
|
|
126
|
+
} else if (comp === 'ulaw' || comp === 'ULAW') {
|
|
127
|
+
decodeLaw(b, p, channelData, actualFrames, nCh, ULAW_TBL)
|
|
128
|
+
} else if (comp === 'ima4') {
|
|
129
|
+
return decodeIMA4(b, ssndOff, ssndSize, nCh, nFrames, sr)
|
|
130
|
+
} else if (comp === 'GSM ' || comp === 'gsm ') {
|
|
131
|
+
return decodeGSM(b, ssndOff, ssndSize, nCh, nFrames, sr)
|
|
132
|
+
} else {
|
|
133
|
+
throw Error('Unsupported AIFF-C compression: ' + comp)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { channelData, sampleRate: sr }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function decodePCM_BE(b, p, channels, frames, nCh, bps, byteDepth) {
|
|
140
|
+
if (bps === 8) {
|
|
141
|
+
// 8-bit: unsigned, center at 128
|
|
142
|
+
for (let i = 0; i < frames; i++)
|
|
143
|
+
for (let c = 0; c < nCh; c++)
|
|
144
|
+
channels[c][i] = (b[p++] - 128) / 128
|
|
145
|
+
} else if (bps === 16) {
|
|
146
|
+
for (let i = 0; i < frames; i++)
|
|
147
|
+
for (let c = 0; c < nCh; c++) {
|
|
148
|
+
let v = (b[p] << 8) | b[p + 1]; p += 2
|
|
149
|
+
channels[c][i] = (v > 32767 ? v - 65536 : v) / 32768
|
|
150
|
+
}
|
|
151
|
+
} else if (bps === 24) {
|
|
152
|
+
for (let i = 0; i < frames; i++)
|
|
153
|
+
for (let c = 0; c < nCh; c++) {
|
|
154
|
+
let v = (b[p] << 16) | (b[p + 1] << 8) | b[p + 2]; p += 3
|
|
155
|
+
channels[c][i] = (v > 8388607 ? v - 16777216 : v) / 8388608
|
|
156
|
+
}
|
|
157
|
+
} else if (bps === 32) {
|
|
158
|
+
for (let i = 0; i < frames; i++)
|
|
159
|
+
for (let c = 0; c < nCh; c++) {
|
|
160
|
+
let v = ((b[p] << 24) | (b[p + 1] << 16) | (b[p + 2] << 8) | b[p + 3]); p += 4
|
|
161
|
+
channels[c][i] = v / 2147483648
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
throw Error('Unsupported bit depth: ' + bps)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function decodePCM_LE(b, p, channels, frames, nCh, bps, byteDepth) {
|
|
169
|
+
if (bps === 8) {
|
|
170
|
+
for (let i = 0; i < frames; i++)
|
|
171
|
+
for (let c = 0; c < nCh; c++)
|
|
172
|
+
channels[c][i] = (b[p++] - 128) / 128
|
|
173
|
+
} else if (bps === 16) {
|
|
174
|
+
for (let i = 0; i < frames; i++)
|
|
175
|
+
for (let c = 0; c < nCh; c++) {
|
|
176
|
+
let v = b[p] | (b[p + 1] << 8); p += 2
|
|
177
|
+
channels[c][i] = (v > 32767 ? v - 65536 : v) / 32768
|
|
178
|
+
}
|
|
179
|
+
} else if (bps === 24) {
|
|
180
|
+
for (let i = 0; i < frames; i++)
|
|
181
|
+
for (let c = 0; c < nCh; c++) {
|
|
182
|
+
let v = b[p] | (b[p + 1] << 8) | (b[p + 2] << 16); p += 3
|
|
183
|
+
channels[c][i] = (v > 8388607 ? v - 16777216 : v) / 8388608
|
|
184
|
+
}
|
|
185
|
+
} else if (bps === 32) {
|
|
186
|
+
for (let i = 0; i < frames; i++)
|
|
187
|
+
for (let c = 0; c < nCh; c++) {
|
|
188
|
+
let v = b[p] | (b[p + 1] << 8) | (b[p + 2] << 16) | (b[p + 3] << 24); p += 4
|
|
189
|
+
channels[c][i] = v / 2147483648
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
throw Error('Unsupported bit depth: ' + bps)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function decodeFloat32_BE(b, p, channels, frames, nCh) {
|
|
197
|
+
let dv = new DataView(b.buffer, b.byteOffset, b.byteLength)
|
|
198
|
+
for (let i = 0; i < frames; i++)
|
|
199
|
+
for (let c = 0; c < nCh; c++) {
|
|
200
|
+
channels[c][i] = dv.getFloat32(p, false); p += 4
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function decodeFloat64_BE(b, p, channels, frames, nCh) {
|
|
205
|
+
let dv = new DataView(b.buffer, b.byteOffset, b.byteLength)
|
|
206
|
+
for (let i = 0; i < frames; i++)
|
|
207
|
+
for (let c = 0; c < nCh; c++) {
|
|
208
|
+
channels[c][i] = dv.getFloat64(p, false); p += 8
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function decodeLaw(b, p, channels, frames, nCh, tbl) {
|
|
213
|
+
for (let i = 0; i < frames; i++)
|
|
214
|
+
for (let c = 0; c < nCh; c++)
|
|
215
|
+
channels[c][i] = tbl[b[p++]] / 32768
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ===== IMA4 ADPCM (Apple IMA ADPCM) =====
|
|
219
|
+
// 34 bytes/block/channel → 64 samples. COMM nFrames = number of blocks.
|
|
220
|
+
|
|
221
|
+
const IMA_STEP = new Int16Array([7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,34,37,41,45,50,55,60,66,73,80,88,97,107,118,130,143,157,173,190,209,230,253,279,307,337,371,408,449,494,544,598,658,724,796,876,963,1060,1166,1282,1411,1552,1707,1878,2066,2272,2499,2749,3024,3327,3660,4026,4428,4871,5358,5894,6484,7132,7845,8630,9493,10442,11487,12635,13899,15289,16818,18500,20350,22385,24623,27086,29794,32767])
|
|
222
|
+
const IMA_IDX = new Int8Array([-1,-1,-1,-1,2,4,6,8,-1,-1,-1,-1,2,4,6,8])
|
|
223
|
+
|
|
224
|
+
function decodeIMA4(b, ssndOff, ssndSize, nCh, nBlocks, sr) {
|
|
225
|
+
let blockBytes = 34 * nCh
|
|
226
|
+
let totalSamples = nBlocks * 64
|
|
227
|
+
let channelData = Array.from({ length: nCh }, () => new Float32Array(totalSamples))
|
|
228
|
+
let p = ssndOff, sample = 0
|
|
229
|
+
|
|
230
|
+
for (let blk = 0; blk < nBlocks && p + blockBytes <= ssndOff + ssndSize; blk++) {
|
|
231
|
+
for (let c = 0; c < nCh; c++) {
|
|
232
|
+
let bp = p + c * 34
|
|
233
|
+
// Preamble: 16-bit BE — high 9 bits = predictor, low 7 bits = step index
|
|
234
|
+
let preamble = (b[bp] << 8) | b[bp + 1]
|
|
235
|
+
let predictor = preamble & 0xFF80 // top 9 bits, sign-extended via int16
|
|
236
|
+
if (predictor > 32767) predictor -= 65536
|
|
237
|
+
let stepIdx = preamble & 0x7F
|
|
238
|
+
if (stepIdx > 88) stepIdx = 88
|
|
239
|
+
|
|
240
|
+
let out = channelData[c]
|
|
241
|
+
for (let i = 0; i < 32; i++) {
|
|
242
|
+
let byte = b[bp + 2 + i]
|
|
243
|
+
// High nibble first, then low nibble
|
|
244
|
+
for (let nibbleIdx = 0; nibbleIdx < 2; nibbleIdx++) {
|
|
245
|
+
let nibble = nibbleIdx === 0 ? (byte >> 4) & 0xF : byte & 0xF
|
|
246
|
+
let step = IMA_STEP[stepIdx]
|
|
247
|
+
let diff = step >> 3
|
|
248
|
+
if (nibble & 1) diff += step >> 2
|
|
249
|
+
if (nibble & 2) diff += step >> 1
|
|
250
|
+
if (nibble & 4) diff += step
|
|
251
|
+
if (nibble & 8) diff = -diff
|
|
252
|
+
predictor += diff
|
|
253
|
+
if (predictor > 32767) predictor = 32767
|
|
254
|
+
if (predictor < -32768) predictor = -32768
|
|
255
|
+
stepIdx += IMA_IDX[nibble]
|
|
256
|
+
if (stepIdx < 0) stepIdx = 0
|
|
257
|
+
if (stepIdx > 88) stepIdx = 88
|
|
258
|
+
out[sample + i * 2 + nibbleIdx] = predictor / 32768
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
p += blockBytes
|
|
263
|
+
sample += 64
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return { channelData, sampleRate: sr }
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ===== GSM 6.10 (Full Rate) =====
|
|
270
|
+
// 33 bytes/frame → 160 samples. RPE-LTP speech codec.
|
|
271
|
+
// Ported from libgsm by Jutta Degener and Carsten Bormann, TU Berlin.
|
|
272
|
+
|
|
273
|
+
// Table 4.3b: Quantization levels of the LTP gain quantizer
|
|
274
|
+
const GSM_QLB = [3277, 11469, 21299, 32767]
|
|
275
|
+
// Table 4.6: Normalized direct mantissa used to compute xM/xmax
|
|
276
|
+
const GSM_FAC = [18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767]
|
|
277
|
+
|
|
278
|
+
// Saturating 16-bit add/sub
|
|
279
|
+
function sadd(a, b) { let s = a + b; return s > 32767 ? 32767 : s < -32768 ? -32768 : s }
|
|
280
|
+
function ssub(a, b) { let s = a - b; return s > 32767 ? 32767 : s < -32768 ? -32768 : s }
|
|
281
|
+
// GSM_MULT_R(a,b): (a*b + 16384) >> 15, with saturation for MIN_WORD*MIN_WORD
|
|
282
|
+
function multr(a, b) {
|
|
283
|
+
if (a === -32768 && b === -32768) return 32767
|
|
284
|
+
return ((a * b + 16384) >> 15) | 0
|
|
285
|
+
}
|
|
286
|
+
// Arithmetic shift right (sign-preserving)
|
|
287
|
+
function asr(x, n) {
|
|
288
|
+
if (n >= 16) return x < 0 ? -1 : 0
|
|
289
|
+
if (n <= -16) return 0
|
|
290
|
+
if (n < 0) return x << -n
|
|
291
|
+
return x >> n // JS >> is always arithmetic
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function decodeGSM(b, ssndOff, ssndSize, nCh, nFrames, sr) {
|
|
295
|
+
let totalFrames = Math.min(nFrames, Math.floor(ssndSize / 33))
|
|
296
|
+
let channelData = [new Float32Array(totalFrames * 160)]
|
|
297
|
+
let out = channelData[0], p = ssndOff
|
|
298
|
+
|
|
299
|
+
// Decoder state (mirrors struct gsm_state)
|
|
300
|
+
let dp0 = new Int32Array(280) // int32 to avoid overflow in intermediate calcs
|
|
301
|
+
let v = new Int32Array(9)
|
|
302
|
+
let LARpp = [new Int32Array(8), new Int32Array(8)]
|
|
303
|
+
let j = 0, nrp = 40, msr = 0
|
|
304
|
+
|
|
305
|
+
for (let f = 0; f < totalFrames; f++) {
|
|
306
|
+
let { LARc, sub } = gsmBits(b, p)
|
|
307
|
+
let wt = new Int32Array(160)
|
|
308
|
+
|
|
309
|
+
// Process 4 subframes: RPE decode + long-term synthesis
|
|
310
|
+
for (let s = 0; s < 4; s++) {
|
|
311
|
+
let sf = sub[s]
|
|
312
|
+
let erp = new Int32Array(40)
|
|
313
|
+
gsmRpeDecode(sf.xmaxc, sf.Mc, sf.xmc, erp)
|
|
314
|
+
|
|
315
|
+
// Long-term synthesis filtering (4.3.2)
|
|
316
|
+
let Nr = (sf.Nc < 40 || sf.Nc > 120) ? nrp : sf.Nc
|
|
317
|
+
nrp = Nr
|
|
318
|
+
let brp = GSM_QLB[sf.bc]
|
|
319
|
+
// drp is dp0 offset by 120; drp[k] = dp0[120+k], drp[k-Nr] = dp0[120+k-Nr]
|
|
320
|
+
for (let k = 0; k < 40; k++) {
|
|
321
|
+
let drpp = multr(brp, dp0[120 + k - Nr])
|
|
322
|
+
dp0[120 + k] = sadd(erp[k], drpp)
|
|
323
|
+
}
|
|
324
|
+
for (let k = 0; k < 40; k++) wt[s * 40 + k] = dp0[120 + k]
|
|
325
|
+
|
|
326
|
+
// Shift dp0: drp[-120+k] = drp[-80+k] for k=0..119
|
|
327
|
+
for (let k = 0; k < 120; k++) dp0[k] = dp0[k + 40]
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Short-term synthesis filter with LARp interpolation (4.2.8-4.2.9)
|
|
331
|
+
let LARpp_j = LARpp[j]
|
|
332
|
+
let LARpp_j_1 = LARpp[j ^ 1]
|
|
333
|
+
j ^= 1 // toggle for next frame
|
|
334
|
+
|
|
335
|
+
gsmDecodeLAR(LARc, LARpp_j)
|
|
336
|
+
|
|
337
|
+
let sr_out = new Int32Array(160)
|
|
338
|
+
let LARp = new Int32Array(8)
|
|
339
|
+
|
|
340
|
+
// Coefficients_0_12: LARp = 3/4 * prev + 1/4 * curr
|
|
341
|
+
for (let i = 0; i < 8; i++)
|
|
342
|
+
LARp[i] = sadd(sadd(LARpp_j_1[i] >> 2, LARpp_j[i] >> 2), LARpp_j_1[i] >> 1)
|
|
343
|
+
gsmLARpToRp(LARp)
|
|
344
|
+
gsmSynthFilter(v, LARp, 13, wt, 0, sr_out, 0)
|
|
345
|
+
|
|
346
|
+
// Coefficients_13_26: LARp = 1/2 * prev + 1/2 * curr
|
|
347
|
+
for (let i = 0; i < 8; i++)
|
|
348
|
+
LARp[i] = sadd(LARpp_j_1[i] >> 1, LARpp_j[i] >> 1)
|
|
349
|
+
gsmLARpToRp(LARp)
|
|
350
|
+
gsmSynthFilter(v, LARp, 14, wt, 13, sr_out, 13)
|
|
351
|
+
|
|
352
|
+
// Coefficients_27_39: LARp = 1/4 * prev + 3/4 * curr
|
|
353
|
+
for (let i = 0; i < 8; i++)
|
|
354
|
+
LARp[i] = sadd(sadd(LARpp_j_1[i] >> 2, LARpp_j[i] >> 2), LARpp_j[i] >> 1)
|
|
355
|
+
gsmLARpToRp(LARp)
|
|
356
|
+
gsmSynthFilter(v, LARp, 13, wt, 27, sr_out, 27)
|
|
357
|
+
|
|
358
|
+
// Coefficients_40_159: LARp = curr
|
|
359
|
+
for (let i = 0; i < 8; i++) LARp[i] = LARpp_j[i]
|
|
360
|
+
gsmLARpToRp(LARp)
|
|
361
|
+
gsmSynthFilter(v, LARp, 120, wt, 40, sr_out, 40)
|
|
362
|
+
|
|
363
|
+
// Postprocessing: de-emphasis + truncation/upscaling
|
|
364
|
+
for (let k = 0; k < 160; k++) {
|
|
365
|
+
msr = sadd(sr_out[k], multr(msr, 28180))
|
|
366
|
+
let s = sadd(msr, msr) & 0xFFF8
|
|
367
|
+
out[f * 160 + k] = (s > 32767 ? s - 65536 : s) / 32768
|
|
368
|
+
}
|
|
369
|
+
p += 33
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return { channelData, sampleRate: sr }
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// GSM 6.10 bit unpacking: 33 bytes → LARc[8] + 4 subframes
|
|
376
|
+
function gsmBits(buf, off) {
|
|
377
|
+
let bc = 0
|
|
378
|
+
function r(n) {
|
|
379
|
+
let val = 0
|
|
380
|
+
for (let i = 0; i < n; i++) {
|
|
381
|
+
val = (val << 1) | ((buf[off + (bc >> 3)] >> (7 - (bc & 7))) & 1)
|
|
382
|
+
bc++
|
|
383
|
+
}
|
|
384
|
+
return val
|
|
385
|
+
}
|
|
386
|
+
let LARc = [r(6),r(6),r(5),r(5),r(4),r(4),r(3),r(3)]
|
|
387
|
+
let sub = []
|
|
388
|
+
for (let s = 0; s < 4; s++)
|
|
389
|
+
sub.push({ Nc: r(7), bc: r(2), Mc: r(2), xmaxc: r(6), xmc: [r(3),r(3),r(3),r(3),r(3),r(3),r(3),r(3),r(3),r(3),r(3),r(3),r(3)] })
|
|
390
|
+
return { LARc, sub }
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// 4.2.8: Decoding of the coded Log-Area Ratios
|
|
394
|
+
function gsmDecodeLAR(LARc, LARpp) {
|
|
395
|
+
// B*2, MIC, INVA from tables 4.1 and 4.2
|
|
396
|
+
const B2 = [0, 0, 4096, -5120, 188, -3584, -682, -2288]
|
|
397
|
+
const MIC = [-32, -32, -16, -16, -8, -8, -4, -4]
|
|
398
|
+
const INVA = [13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708]
|
|
399
|
+
for (let i = 0; i < 8; i++) {
|
|
400
|
+
let t = sadd(LARc[i], MIC[i]) << 10
|
|
401
|
+
t = ssub(t, B2[i])
|
|
402
|
+
t = multr(INVA[i], t)
|
|
403
|
+
LARpp[i] = sadd(t, t)
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// 4.2.9.2: LARp to reflection coefficients (in-place)
|
|
408
|
+
function gsmLARpToRp(LARp) {
|
|
409
|
+
for (let i = 0; i < 8; i++) {
|
|
410
|
+
if (LARp[i] < 0) {
|
|
411
|
+
let t = LARp[i] === -32768 ? 32767 : -LARp[i]
|
|
412
|
+
LARp[i] = -(t < 11059 ? t << 1 : t < 20070 ? t + 11059 : sadd(t >> 2, 26112))
|
|
413
|
+
} else {
|
|
414
|
+
let t = LARp[i]
|
|
415
|
+
LARp[i] = t < 11059 ? t << 1 : t < 20070 ? t + 11059 : sadd(t >> 2, 26112)
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Short-term synthesis filter (4.2.10, synthesis direction)
|
|
421
|
+
function gsmSynthFilter(v, rrp, k, wt, wtOff, sr, srOff) {
|
|
422
|
+
for (let n = 0; n < k; n++) {
|
|
423
|
+
let sri = wt[wtOff + n]
|
|
424
|
+
for (let i = 7; i >= 0; i--) {
|
|
425
|
+
sri = ssub(sri, multr(rrp[i], v[i]))
|
|
426
|
+
v[i + 1] = sadd(v[i], multr(rrp[i], sri))
|
|
427
|
+
}
|
|
428
|
+
sr[srOff + n] = v[0] = sri
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// 4.2.16-4.2.17: RPE decoding (inverse quantization + grid positioning)
|
|
433
|
+
function gsmRpeDecode(xmaxc, Mc, xMc, erp) {
|
|
434
|
+
// 4.2.15: Compute exp and mant from xmaxc
|
|
435
|
+
let exp = 0, mant
|
|
436
|
+
if (xmaxc > 15) exp = (xmaxc >> 3) - 1
|
|
437
|
+
mant = xmaxc - (exp << 3)
|
|
438
|
+
if (mant === 0) { exp = -4; mant = 7 }
|
|
439
|
+
else { while (mant <= 7) { mant = (mant << 1) | 1; exp-- }; mant -= 8 }
|
|
440
|
+
|
|
441
|
+
// 4.2.16: APCM inverse quantization
|
|
442
|
+
let fac = GSM_FAC[mant]
|
|
443
|
+
let shift = 6 - exp
|
|
444
|
+
let round = shift > 1 ? 1 << (shift - 1) : 0 // gsm_asl(1, shift-1)
|
|
445
|
+
|
|
446
|
+
let xMp = new Int32Array(13)
|
|
447
|
+
for (let i = 0; i < 13; i++) {
|
|
448
|
+
let t = ((xMc[i] << 1) - 7) << 12
|
|
449
|
+
t = multr(fac, t)
|
|
450
|
+
t = sadd(t, round)
|
|
451
|
+
xMp[i] = asr(t, shift)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// 4.2.17: RPE grid positioning
|
|
455
|
+
for (let k = 0; k < 40; k++) erp[k] = 0
|
|
456
|
+
for (let i = 0; i < 13; i++) erp[Mc + 3 * i] = xMp[i]
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Whole-file decode
|
|
461
|
+
* @param {Uint8Array|ArrayBuffer} src
|
|
462
|
+
* @returns {Promise<{channelData: Float32Array[], sampleRate: number}>}
|
|
463
|
+
*/
|
|
464
|
+
export default async function decode(src) {
|
|
465
|
+
let buf = src instanceof Uint8Array ? src : src instanceof ArrayBuffer ? new Uint8Array(src) : src
|
|
466
|
+
let dec = await decoder()
|
|
467
|
+
try {
|
|
468
|
+
let result = dec.decode(buf)
|
|
469
|
+
if (!result.channelData.length) result = dec.flush()
|
|
470
|
+
return result
|
|
471
|
+
} finally {
|
|
472
|
+
dec.free()
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Create decoder instance
|
|
478
|
+
* @returns {Promise<{decode(chunk: Uint8Array): {channelData, sampleRate}, flush(), free()}>}
|
|
479
|
+
*/
|
|
480
|
+
export async function decoder() {
|
|
481
|
+
let hdr = null, left = null, freed = false
|
|
482
|
+
return {
|
|
483
|
+
decode(data) {
|
|
484
|
+
if (freed) throw Error('Decoder already freed')
|
|
485
|
+
if (!data?.length) return EMPTY
|
|
486
|
+
let chunk = data instanceof Uint8Array ? data : new Uint8Array(data)
|
|
487
|
+
if (left) { chunk = cat(left, chunk); left = null }
|
|
488
|
+
if (!hdr) {
|
|
489
|
+
hdr = scanAiffHdr(chunk)
|
|
490
|
+
if (!hdr) { left = chunk.slice(); return EMPTY }
|
|
491
|
+
// IMA4/GSM: buffer all SSND data, decode on flush
|
|
492
|
+
if (hdr.comp === 'ima4' || hdr.comp === 'GSM ' || hdr.comp === 'gsm ') {
|
|
493
|
+
left = chunk.slice()
|
|
494
|
+
return EMPTY
|
|
495
|
+
}
|
|
496
|
+
chunk = chunk.subarray(hdr.dataStart)
|
|
497
|
+
}
|
|
498
|
+
let fb = hdr.frameBytes
|
|
499
|
+
let complete = Math.floor(chunk.length / fb) * fb
|
|
500
|
+
if (!complete) { if (chunk.length) left = chunk.slice(); return EMPTY }
|
|
501
|
+
if (chunk.length > complete) left = chunk.subarray(complete).slice()
|
|
502
|
+
return decodeAiffRaw(chunk.subarray(0, complete), hdr)
|
|
503
|
+
},
|
|
504
|
+
flush() {
|
|
505
|
+
if (hdr && left && (hdr.comp === 'ima4' || hdr.comp === 'GSM ' || hdr.comp === 'gsm ')) {
|
|
506
|
+
let result = parseAiff(left)
|
|
507
|
+
left = null
|
|
508
|
+
return result
|
|
509
|
+
}
|
|
510
|
+
left = null
|
|
511
|
+
return EMPTY
|
|
512
|
+
},
|
|
513
|
+
free() { freed = true; left = null; hdr = null },
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function cat(a, b) {
|
|
518
|
+
let r = new Uint8Array(a.length + b.length)
|
|
519
|
+
r.set(a); r.set(b, a.length)
|
|
520
|
+
return r
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
function scanAiffHdr(b) {
|
|
524
|
+
if (!b || b.length < 12) return null
|
|
525
|
+
if (str4(b, 0) !== 'FORM') throw Error('Not an AIFF file')
|
|
526
|
+
let form = str4(b, 8)
|
|
527
|
+
if (form !== 'AIFF' && form !== 'AIFC') throw Error('Not an AIFF file')
|
|
528
|
+
let isAIFC = form === 'AIFC'
|
|
529
|
+
let nCh = 0, bps = 0, sr = 0, comp = 'NONE', commFound = false
|
|
530
|
+
let pos = 12, end = Math.min(8 + r32(b, 4), b.length)
|
|
531
|
+
while (pos + 8 <= end) {
|
|
532
|
+
let ckId = str4(b, pos), ckSize = r32(b, pos + 4), ckData = pos + 8
|
|
533
|
+
if (ckId === 'COMM') {
|
|
534
|
+
if (ckData + 18 > b.length) return null
|
|
535
|
+
nCh = r16(b, ckData)
|
|
536
|
+
bps = r16(b, ckData + 6)
|
|
537
|
+
sr = readF80(b, ckData + 8)
|
|
538
|
+
if (isAIFC && ckSize >= 22 && ckData + 22 <= b.length) comp = str4(b, ckData + 18)
|
|
539
|
+
commFound = true
|
|
540
|
+
} else if (ckId === 'SSND') {
|
|
541
|
+
if (!commFound) return null
|
|
542
|
+
if (ckData + 8 > b.length) return null
|
|
543
|
+
let dataOff = r32(b, ckData)
|
|
544
|
+
let dataStart = ckData + 8 + dataOff
|
|
545
|
+
let cUpper = comp.toUpperCase()
|
|
546
|
+
let byteDepth = Math.ceil(bps / 8)
|
|
547
|
+
let frameBytes
|
|
548
|
+
if (comp === 'fl32' || comp === 'FL32') frameBytes = nCh * 4
|
|
549
|
+
else if (comp === 'fl64' || comp === 'FL64') frameBytes = nCh * 8
|
|
550
|
+
else if (comp === 'alaw' || comp === 'ulaw' || comp === 'ULAW') frameBytes = nCh
|
|
551
|
+
else if (comp === 'ima4' || comp === 'GSM ' || comp === 'gsm ') frameBytes = 1 // block-based, handled via flush
|
|
552
|
+
else frameBytes = nCh * byteDepth
|
|
553
|
+
return { nCh, bps, sr, comp, byteDepth, frameBytes, dataStart, isAIFC }
|
|
554
|
+
}
|
|
555
|
+
pos = ckData + ckSize + (ckSize & 1)
|
|
556
|
+
}
|
|
557
|
+
return null
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function decodeAiffRaw(raw, hdr) {
|
|
561
|
+
let { nCh, bps, sr, comp, byteDepth, frameBytes } = hdr
|
|
562
|
+
let frames = Math.floor(raw.length / frameBytes)
|
|
563
|
+
if (!frames) return EMPTY
|
|
564
|
+
let channelData = Array.from({ length: nCh }, () => new Float32Array(frames))
|
|
565
|
+
let cUpper = comp.toUpperCase()
|
|
566
|
+
let p = 0
|
|
567
|
+
if (cUpper === 'NONE' || cUpper === 'TWOS' || comp === 'twos') {
|
|
568
|
+
decodePCM_BE(raw, 0, channelData, frames, nCh, bps, byteDepth)
|
|
569
|
+
} else if (comp === 'sowt') {
|
|
570
|
+
decodePCM_LE(raw, 0, channelData, frames, nCh, bps, byteDepth)
|
|
571
|
+
} else if (comp === 'fl32' || comp === 'FL32') {
|
|
572
|
+
decodeFloat32_BE(raw, 0, channelData, frames, nCh)
|
|
573
|
+
} else if (comp === 'fl64' || comp === 'FL64') {
|
|
574
|
+
decodeFloat64_BE(raw, 0, channelData, frames, nCh)
|
|
575
|
+
} else if (comp === 'alaw') {
|
|
576
|
+
decodeLaw(raw, 0, channelData, frames, nCh, ALAW_TBL)
|
|
577
|
+
} else if (comp === 'ulaw' || comp === 'ULAW') {
|
|
578
|
+
decodeLaw(raw, 0, channelData, frames, nCh, ULAW_TBL)
|
|
579
|
+
} else {
|
|
580
|
+
throw Error('Unsupported AIFF-C compression: ' + comp)
|
|
581
|
+
}
|
|
582
|
+
return { channelData, sampleRate: sr }
|
|
583
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@audio/decode-aiff",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "Decode AIFF/AIFF-C audio to PCM samples",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "decode-aiff.js",
|
|
7
|
+
"types": "decode-aiff.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./decode-aiff.js",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"decode-aiff.js",
|
|
14
|
+
"decode-aiff.d.ts",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"aiff",
|
|
19
|
+
"aifc",
|
|
20
|
+
"audio",
|
|
21
|
+
"decode",
|
|
22
|
+
"decoder",
|
|
23
|
+
"pcm"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"author": "audiojs",
|
|
30
|
+
"homepage": "https://github.com/audiojs/decode-aiff#readme",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/audiojs/decode-aiff.git"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=16"
|
|
37
|
+
},
|
|
38
|
+
"bugs": "https://github.com/audiojs/decode-aiff/issues",
|
|
39
|
+
"scripts": {
|
|
40
|
+
"test": "node test.js"
|
|
41
|
+
}
|
|
42
|
+
}
|