carta1 1.1.10 → 1.3.0
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/bin/cli.js +8 -4
- package/codec/{coding/bitallocation.js → allocation/solve.js} +131 -97
- package/codec/allocation/source.js +69 -0
- package/codec/allocation/stage.js +38 -0
- package/codec/analysis/bands.js +68 -0
- package/codec/analysis/{transient.js → blocks.js} +90 -47
- package/codec/analysis/spectrum.js +160 -0
- package/codec/analysis/stage.js +32 -0
- package/codec/{browser/interface.js → boundary/browser.js} +1 -1
- package/codec/boundary/container.js +96 -0
- package/codec/boundary/pcm.js +193 -0
- package/codec/boundary/processor.js +208 -0
- package/codec/{io/readers.js → boundary/reader.js} +2 -1
- package/codec/boundary/stream.js +361 -0
- package/codec/{browser → boundary}/worker.js +45 -42
- package/codec/core/constants.js +19 -132
- package/codec/core/geometry.js +25 -0
- package/codec/core/tables.js +215 -0
- package/codec/dequantization.js +54 -0
- package/codec/index.js +12 -13
- package/codec/pipeline/decoder.js +10 -399
- package/codec/pipeline/encoder.js +12 -434
- package/codec/quantization/spectrum.js +67 -0
- package/codec/quantization/stage.js +49 -0
- package/codec/signal/fft.js +68 -0
- package/codec/{transforms → signal}/mdct.js +37 -65
- package/codec/signal/order.js +16 -0
- package/codec/signal/qmf.js +539 -0
- package/codec/state.js +112 -0
- package/codec/{io → syntax}/bitstream.js +27 -8
- package/codec/{io/serialization.js → syntax/frame.js} +5 -101
- package/codec/synthesis/bands.js +228 -0
- package/codec/synthesis/pcm.js +64 -0
- package/codec/synthesis/stage.js +17 -0
- package/codec/utils.js +9 -52
- package/dist/carta1-worker-interface.min.js.map +1 -1
- package/dist/carta1-worker.min.js +1 -1
- package/dist/carta1-worker.min.js.map +1 -1
- package/dist/carta1.min.js +1 -1
- package/dist/carta1.min.js.map +1 -1
- package/package.json +1 -1
- package/codec/coding/quantization.js +0 -149
- package/codec/core/buffers.js +0 -81
- package/codec/io/processor.js +0 -671
- package/codec/transforms/fft.js +0 -69
- package/codec/transforms/qmf.js +0 -105
|
@@ -1,411 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Carta1 Audio Codec - Decoding Pipeline
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 1. Dequantization: Reconstructs MDCT coefficients from quantized data using scale factors
|
|
8
|
-
* 2. Inverse MDCT: Applies Inverse Modified Discrete Cosine Transform to frequency bands
|
|
9
|
-
* 3. QMF Synthesis: Reconstructs full-spectrum audio using quadrature mirror filters
|
|
10
|
-
*
|
|
11
|
-
* Each stage is implemented as a functional pipeline component that can be composed
|
|
12
|
-
* using the pipe utility. The pipeline maintains state through a shared context
|
|
13
|
-
* containing buffer pools and decoding options.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
pipe,
|
|
18
|
-
throwError,
|
|
19
|
-
reverseSpectrum,
|
|
20
|
-
extractBandCoefficients,
|
|
21
|
-
} from '../utils.js'
|
|
22
|
-
import { qmfSynthesis } from '../transforms/qmf.js'
|
|
23
|
-
import { imdct64, imdct256, imdct512, overlapAdd } from '../transforms/mdct.js'
|
|
24
|
-
import { dequantize } from '../coding/quantization.js'
|
|
25
|
-
import { BufferPool } from '../core/buffers.js'
|
|
26
|
-
import {
|
|
27
|
-
BFU_BAND_BOUNDARIES,
|
|
28
|
-
BFU_START_LONG,
|
|
29
|
-
BFU_START_SHORT,
|
|
30
|
-
WORD_LENGTH_BITS,
|
|
31
|
-
WINDOW_SHORT,
|
|
32
|
-
MDCT_SIZE_LONG,
|
|
33
|
-
MDCT_BAND_CONFIGS,
|
|
34
|
-
MDCT_SHORT_BLOCK_SIZE,
|
|
35
|
-
MDCT_TAIL_WINDOW_SIZE,
|
|
36
|
-
} from '../core/constants.js'
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Dequantization Stage - Reconstructs MDCT coefficients from quantized data
|
|
40
|
-
*
|
|
41
|
-
* Reverses the quantization process by:
|
|
42
|
-
* - Reconstructing coefficient values using scale factors and word lengths
|
|
43
|
-
* - Organizing coefficients back into Block Floating Units (BFUs)
|
|
44
|
-
* - Preparing coefficient array for inverse MDCT transform
|
|
45
|
-
*
|
|
46
|
-
* Uses the same BFU organization as the encoder but reconstructs the original
|
|
47
|
-
* coefficient values from the quantized representation.
|
|
48
|
-
*
|
|
49
|
-
* @returns {Function} Stage function that processes quantized frame data
|
|
50
|
-
* @throws {Error} If bufferPool is not provided in context
|
|
51
|
-
*/
|
|
52
|
-
export function dequantizationStage() {
|
|
53
|
-
/**
|
|
54
|
-
* Reconstruct MDCT coefficients from quantized data
|
|
55
|
-
* @param {Object} frameData - Quantized frame data
|
|
56
|
-
* @param {number} frameData.nBfu - Number of active BFUs
|
|
57
|
-
* @param {Int32Array} frameData.scaleFactorIndices - Scale factor indices for each BFU
|
|
58
|
-
* @param {Int32Array} frameData.wordLengthIndices - Word length indices for each BFU
|
|
59
|
-
* @param {Array<Int32Array>} frameData.quantizedCoefficients - Quantized coefficient data
|
|
60
|
-
* @param {Array<number>} frameData.blockModes - Block modes for each band
|
|
61
|
-
* @returns {Object} Dequantization results
|
|
62
|
-
* @returns {Float32Array} returns.coefficients - Reconstructed MDCT coefficients (512 samples)
|
|
63
|
-
* @returns {Array<number>} returns.blockModes - Block modes for each band
|
|
64
|
-
*/
|
|
65
|
-
return (frameData) => {
|
|
66
|
-
const coefficients = new Float32Array(512)
|
|
67
|
-
const {
|
|
68
|
-
nBfu,
|
|
69
|
-
scaleFactorIndices,
|
|
70
|
-
wordLengthIndices,
|
|
71
|
-
quantizedCoefficients,
|
|
72
|
-
blockModes,
|
|
73
|
-
} = frameData
|
|
74
|
-
|
|
75
|
-
for (let bfu = 0; bfu < nBfu; bfu++) {
|
|
76
|
-
const bitsPerSample = WORD_LENGTH_BITS[wordLengthIndices[bfu]]
|
|
77
|
-
|
|
78
|
-
let band = 0
|
|
79
|
-
if (bfu >= BFU_BAND_BOUNDARIES[0]) band = 1
|
|
80
|
-
if (bfu >= BFU_BAND_BOUNDARIES[1]) band = 2
|
|
81
|
-
|
|
82
|
-
const isLongBlock = blockModes[band] === 0
|
|
83
|
-
const position = isLongBlock ? BFU_START_LONG[bfu] : BFU_START_SHORT[bfu]
|
|
84
|
-
|
|
85
|
-
if (bitsPerSample > 0) {
|
|
86
|
-
const quantized = quantizedCoefficients[bfu]
|
|
87
|
-
const dequantized = dequantize(
|
|
88
|
-
quantized,
|
|
89
|
-
scaleFactorIndices[bfu],
|
|
90
|
-
bitsPerSample
|
|
91
|
-
)
|
|
92
|
-
coefficients.set(dequantized, position)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return { coefficients, blockModes }
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Inverse MDCT Stage - Transforms frequency coefficients back to time domain
|
|
102
|
-
*
|
|
103
|
-
* Applies Inverse Modified Discrete Cosine Transform to reconstruct time-domain
|
|
104
|
-
* samples from frequency coefficients. The transform size depends on block modes:
|
|
105
|
-
* - Long blocks: 512/256 samples for steady-state signals
|
|
106
|
-
* - Short blocks: 64 samples for transient signals
|
|
107
|
-
*
|
|
108
|
-
* Applies windowing and overlap-add processing to prevent blocking artifacts.
|
|
109
|
-
* Mid and high bands are spectrally unreversed from ATRAC1 format.
|
|
110
|
-
*
|
|
111
|
-
* @param {Object} context - Pipeline context containing bufferPool
|
|
112
|
-
* @param {BufferPool} context.bufferPool - Shared buffer pool for efficient memory management
|
|
113
|
-
* @returns {Function} Stage function that processes dequantization results
|
|
114
|
-
* @throws {Error} If bufferPool is not provided in context
|
|
115
|
-
*/
|
|
116
|
-
export function imdctStage(context) {
|
|
117
|
-
const bufferPool =
|
|
118
|
-
context?.bufferPool ?? throwError('imdctStage: bufferPool is required')
|
|
119
|
-
const overlapBuffers = bufferPool.imdctOverlap
|
|
120
|
-
|
|
121
|
-
// Transform function mapping for each band
|
|
122
|
-
const TRANSFORM_FUNCS = [imdct256, imdct256, imdct512]
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Inverse transform a single frequency band.
|
|
126
|
-
* @param {Float32Array} coeffs
|
|
127
|
-
* @param {number} bandIndex
|
|
128
|
-
* @param {number} blockMode
|
|
129
|
-
* @param {Float32Array} overlapBuffer
|
|
130
|
-
* @param {Object} bufferPool
|
|
131
|
-
* @param {Object} config
|
|
132
|
-
* @returns {Float32Array}
|
|
133
|
-
*/
|
|
134
|
-
function transformBand(
|
|
135
|
-
coeffs,
|
|
136
|
-
bandIndex,
|
|
137
|
-
blockMode,
|
|
138
|
-
overlapBuffer,
|
|
139
|
-
bufferPool,
|
|
140
|
-
config
|
|
141
|
-
) {
|
|
142
|
-
const isLongBlock = blockMode === 0
|
|
143
|
-
const transformFunc = TRANSFORM_FUNCS[bandIndex]
|
|
144
|
-
|
|
145
|
-
if (isLongBlock) {
|
|
146
|
-
return inverseLongBlock(
|
|
147
|
-
coeffs,
|
|
148
|
-
bandIndex,
|
|
149
|
-
overlapBuffer,
|
|
150
|
-
bufferPool,
|
|
151
|
-
config,
|
|
152
|
-
transformFunc
|
|
153
|
-
)
|
|
154
|
-
} else {
|
|
155
|
-
return inverseShortBlocks(
|
|
156
|
-
coeffs,
|
|
157
|
-
bandIndex,
|
|
158
|
-
overlapBuffer,
|
|
159
|
-
bufferPool,
|
|
160
|
-
config
|
|
161
|
-
)
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Inverse transform using long block.
|
|
167
|
-
* @param {Float32Array} coeffs
|
|
168
|
-
* @param {number} bandIndex
|
|
169
|
-
* @param {Float32Array} overlapBuffer
|
|
170
|
-
* @param {Object} bufferPool
|
|
171
|
-
* @param {Object} config
|
|
172
|
-
* @param {Object} transformFunc
|
|
173
|
-
* @returns {Float32Array}
|
|
174
|
-
*/
|
|
175
|
-
function inverseLongBlock(
|
|
176
|
-
coeffs,
|
|
177
|
-
bandIndex,
|
|
178
|
-
overlapBuffer,
|
|
179
|
-
bufferPool,
|
|
180
|
-
config,
|
|
181
|
-
transformFunc
|
|
182
|
-
) {
|
|
183
|
-
// Unreverse spectral reversal for mid/high bands
|
|
184
|
-
let blockSpecs = coeffs
|
|
185
|
-
if (bandIndex > 0) {
|
|
186
|
-
blockSpecs = reverseSpectrum(coeffs, bufferPool.reversalBuffers)
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Apply inverse transform
|
|
190
|
-
const inv = transformFunc.transform(blockSpecs, bufferPool.mdctBuffers)
|
|
191
|
-
const invStart = inv.length / 4
|
|
192
|
-
|
|
193
|
-
// Prepare output buffer
|
|
194
|
-
const invBuf = bufferPool.transformBuffers[MDCT_SIZE_LONG]
|
|
195
|
-
invBuf.fill(0)
|
|
196
|
-
|
|
197
|
-
// Copy transformed samples
|
|
198
|
-
for (let i = 0; i < config.size; i++) {
|
|
199
|
-
invBuf[i] = inv[invStart + i]
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Handle overlap-add with previous frame
|
|
203
|
-
const prevBuf = overlapBuffer.slice(
|
|
204
|
-
config.size * 2 - MDCT_TAIL_WINDOW_SIZE,
|
|
205
|
-
config.size * 2
|
|
206
|
-
)
|
|
207
|
-
const dstPart = overlapAdd(
|
|
208
|
-
prevBuf.slice(0, MDCT_TAIL_WINDOW_SIZE),
|
|
209
|
-
invBuf.slice(0, MDCT_TAIL_WINDOW_SIZE),
|
|
210
|
-
WINDOW_SHORT
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
overlapBuffer.set(dstPart, 0)
|
|
214
|
-
|
|
215
|
-
// Save tail for next frame
|
|
216
|
-
for (let i = 0; i < MDCT_TAIL_WINDOW_SIZE; i++) {
|
|
217
|
-
prevBuf[i] = invBuf[MDCT_TAIL_WINDOW_SIZE + i]
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Copy main samples
|
|
221
|
-
const copyLen = bandIndex === 2 ? 240 : 112
|
|
222
|
-
for (let i = 0; i < copyLen; i++) {
|
|
223
|
-
overlapBuffer[32 + i] = invBuf[MDCT_TAIL_WINDOW_SIZE + i]
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// Copy final samples
|
|
227
|
-
for (let i = 0; i < MDCT_TAIL_WINDOW_SIZE; i++) {
|
|
228
|
-
overlapBuffer[config.size * 2 - MDCT_TAIL_WINDOW_SIZE + i] =
|
|
229
|
-
invBuf[config.size - MDCT_TAIL_WINDOW_SIZE + i]
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
return overlapBuffer.slice(0, config.size)
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Inverse transform using short blocks.
|
|
237
|
-
* @param {Float32Array} coeffs
|
|
238
|
-
* @param {number} bandIndex
|
|
239
|
-
* @param {Float32Array} overlapBuffer
|
|
240
|
-
* @param {Object} bufferPool
|
|
241
|
-
* @param {Object} config
|
|
242
|
-
* @returns {Float32Array}
|
|
243
|
-
*/
|
|
244
|
-
function inverseShortBlocks(
|
|
245
|
-
coeffs,
|
|
246
|
-
bandIndex,
|
|
247
|
-
overlapBuffer,
|
|
248
|
-
bufferPool,
|
|
249
|
-
config
|
|
250
|
-
) {
|
|
251
|
-
const numBlocks = 1 << (config.size === 256 ? 3 : 2)
|
|
252
|
-
const invBuf = bufferPool.transformBuffers[MDCT_SIZE_LONG]
|
|
253
|
-
invBuf.fill(0)
|
|
254
|
-
|
|
255
|
-
const prevBuf = overlapBuffer.slice(
|
|
256
|
-
config.size * 2 - MDCT_TAIL_WINDOW_SIZE,
|
|
257
|
-
config.size * 2
|
|
258
|
-
)
|
|
259
|
-
|
|
260
|
-
let start = 0
|
|
261
|
-
let pos = 0
|
|
262
|
-
|
|
263
|
-
for (let block = 0; block < numBlocks; block++) {
|
|
264
|
-
// Extract block coefficients
|
|
265
|
-
let blockSpecs = coeffs.slice(pos, pos + MDCT_SHORT_BLOCK_SIZE)
|
|
266
|
-
|
|
267
|
-
// Unreverse spectral reversal for mid/high bands
|
|
268
|
-
if (bandIndex > 0) {
|
|
269
|
-
blockSpecs = reverseSpectrum(blockSpecs, bufferPool.reversalBuffers)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Apply inverse transform
|
|
273
|
-
const inv = imdct64.transform(blockSpecs, bufferPool.mdctBuffers)
|
|
274
|
-
const invStart = inv.length / 4
|
|
275
|
-
|
|
276
|
-
// Copy to intermediate buffer
|
|
277
|
-
for (let i = 0; i < MDCT_SHORT_BLOCK_SIZE; i++) {
|
|
278
|
-
invBuf[start + i] = inv[invStart + i]
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Overlap-add with previous block
|
|
282
|
-
const dstPart = overlapAdd(
|
|
283
|
-
prevBuf.slice(0, MDCT_TAIL_WINDOW_SIZE),
|
|
284
|
-
invBuf.slice(start, start + MDCT_TAIL_WINDOW_SIZE),
|
|
285
|
-
WINDOW_SHORT
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
overlapBuffer.set(dstPart, start)
|
|
289
|
-
|
|
290
|
-
// Save tail for next block
|
|
291
|
-
for (let i = 0; i < MDCT_TAIL_WINDOW_SIZE; i++) {
|
|
292
|
-
prevBuf[i] = invBuf[start + MDCT_TAIL_WINDOW_SIZE + i]
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
start += MDCT_SHORT_BLOCK_SIZE
|
|
296
|
-
pos += MDCT_SHORT_BLOCK_SIZE
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Copy final tail samples
|
|
300
|
-
for (let i = 0; i < MDCT_TAIL_WINDOW_SIZE; i++) {
|
|
301
|
-
overlapBuffer[config.size * 2 - MDCT_TAIL_WINDOW_SIZE + i] =
|
|
302
|
-
invBuf[config.size - MDCT_TAIL_WINDOW_SIZE + i]
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return overlapBuffer.slice(0, config.size)
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Transform coefficients back to time domain using inverse MDCT
|
|
310
|
-
* @param {Object} input - Dequantization results
|
|
311
|
-
* @param {Float32Array} input.coefficients - MDCT coefficients (512 samples)
|
|
312
|
-
* @param {Array<number>} input.blockModes - Block modes for each band
|
|
313
|
-
* @returns {Array<Float32Array>} Three reconstructed frequency bands [low, mid, high]
|
|
314
|
-
*/
|
|
315
|
-
return (input) => {
|
|
316
|
-
const { coefficients, blockModes } = input
|
|
317
|
-
|
|
318
|
-
return MDCT_BAND_CONFIGS.map((config, bandIndex) => {
|
|
319
|
-
const bandCoeffs = extractBandCoefficients(coefficients, bandIndex)
|
|
320
|
-
return transformBand(
|
|
321
|
-
bandCoeffs,
|
|
322
|
-
bandIndex,
|
|
323
|
-
blockModes[bandIndex],
|
|
324
|
-
overlapBuffers[bandIndex],
|
|
325
|
-
bufferPool,
|
|
326
|
-
config
|
|
327
|
-
)
|
|
328
|
-
})
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* QMF Synthesis Stage - Reconstructs full-spectrum audio from frequency bands
|
|
334
|
-
*
|
|
335
|
-
* Performs two-stage QMF synthesis to reconstruct the full-spectrum signal
|
|
336
|
-
* from three frequency bands:
|
|
337
|
-
* - Low band (0-5.5kHz): processed at full resolution
|
|
338
|
-
* - Mid band (5.5-11kHz): processed at half resolution
|
|
339
|
-
* - High band (11-22kHz): processed at quarter resolution with delay compensation
|
|
340
|
-
*
|
|
341
|
-
* This is the inverse operation of the QMF analysis performed during encoding,
|
|
342
|
-
* combining the separate frequency bands back into a single wideband signal.
|
|
343
|
-
*
|
|
344
|
-
* @param {Object} context - Pipeline context containing bufferPool
|
|
345
|
-
* @param {BufferPool} context.bufferPool - Shared buffer pool for efficient memory management
|
|
346
|
-
* @returns {Function} Stage function that processes inverse MDCT results
|
|
347
|
-
* @throws {Error} If bufferPool is not provided in context
|
|
4
|
+
* The frame pipeline reads as dequantization, then synthesis. Byte unpacking
|
|
5
|
+
* remains the responsibility of deserializeFrame().
|
|
348
6
|
*/
|
|
349
|
-
export function qmfSynthesisStage(context) {
|
|
350
|
-
const bufferPool =
|
|
351
|
-
context?.bufferPool ??
|
|
352
|
-
throwError('qmfSynthesisStage: bufferPool is required')
|
|
353
|
-
const delays = bufferPool.qmfDelays
|
|
354
7
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
*/
|
|
360
|
-
return (bands) => {
|
|
361
|
-
// Apply high band delay compensation
|
|
362
|
-
const delayedHigh = bufferPool.qmfWorkBuffers.highBandDelay[bands[2].length]
|
|
363
|
-
delayedHigh.set(delays.highBand)
|
|
364
|
-
delayedHigh.set(bands[2], delays.highBand.length)
|
|
365
|
-
|
|
366
|
-
const highBand = delayedHigh.slice(0, bands[0].length * 2)
|
|
367
|
-
delays.highBand = delayedHigh.slice(bands[0].length * 2)
|
|
368
|
-
|
|
369
|
-
// Second stage synthesis: combine low and mid bands
|
|
370
|
-
const stage2 = qmfSynthesis(
|
|
371
|
-
bands[0],
|
|
372
|
-
bands[1],
|
|
373
|
-
delays.midBand,
|
|
374
|
-
bufferPool.qmfWorkBuffers
|
|
375
|
-
)
|
|
376
|
-
delays.midBand = stage2.newDelay
|
|
377
|
-
|
|
378
|
-
// First stage synthesis: combine result with high band
|
|
379
|
-
const stage1 = qmfSynthesis(
|
|
380
|
-
stage2.output,
|
|
381
|
-
highBand,
|
|
382
|
-
delays.lowBand,
|
|
383
|
-
bufferPool.qmfWorkBuffers
|
|
384
|
-
)
|
|
385
|
-
delays.lowBand = stage1.newDelay
|
|
386
|
-
|
|
387
|
-
return stage1.output
|
|
388
|
-
}
|
|
389
|
-
}
|
|
8
|
+
import { dequantize } from '../dequantization.js'
|
|
9
|
+
import { BufferPool } from '../state.js'
|
|
10
|
+
import { synthesize } from '../synthesis/stage.js'
|
|
11
|
+
import { pipe } from '../utils.js'
|
|
390
12
|
|
|
391
13
|
/**
|
|
392
|
-
* Create ATRAC1
|
|
393
|
-
*
|
|
394
|
-
* Constructs a complete decoding pipeline that transforms ATRAC1 compressed format
|
|
395
|
-
* back into PCM audio samples. The pipeline processes quantized data through
|
|
396
|
-
* dequantization, inverse MDCT transform, and QMF synthesis.
|
|
397
|
-
*
|
|
398
|
-
* The returned function can be called repeatedly to decode audio frames,
|
|
399
|
-
* maintaining state through the shared buffer pool for efficient processing.
|
|
400
|
-
*
|
|
401
|
-
* @param {BufferPool} [bufferPool=new BufferPool()] - Shared buffer pool for state
|
|
402
|
-
* @returns {Function} Decoding pipeline function that processes quantized frame data
|
|
14
|
+
* Create an ATRAC1 decoder.
|
|
403
15
|
*
|
|
404
|
-
* @
|
|
405
|
-
*
|
|
406
|
-
* const result = decoder(quantizedFrame) // Returns reconstructed PCM samples
|
|
16
|
+
* @param {BufferPool} [bufferPool=new BufferPool()]
|
|
17
|
+
* @returns {Function}
|
|
407
18
|
*/
|
|
408
19
|
export function decode(bufferPool = new BufferPool()) {
|
|
409
20
|
const context = { bufferPool }
|
|
410
|
-
return pipe(context,
|
|
21
|
+
return pipe(context, dequantize, synthesize)
|
|
411
22
|
}
|