carta1 1.0.19 → 1.0.21
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 +1 -1
- package/codec/io/processor.js +1 -1
- package/codec/io/serialization.js +7 -7
- package/codec/pipeline/decoder.js +11 -11
- package/codec/pipeline/encoder.js +6 -6
- package/codec/transforms/fft.js +73 -161
- package/codec/transforms/mdct.js +26 -6
- package/codec/transforms/qmf.js +4 -2
- 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/bin/cli.js
CHANGED
|
@@ -552,7 +552,7 @@ async function dumpFile(inputFile, outputFile, options) {
|
|
|
552
552
|
offset: offset,
|
|
553
553
|
offsetHex: '0x' + offset.toString(16),
|
|
554
554
|
nBfu: frame.nBfu,
|
|
555
|
-
|
|
555
|
+
blockModes: frame.blockModes,
|
|
556
556
|
scaleFactorIndices: Array.from(frame.scaleFactorIndices),
|
|
557
557
|
wordLengthIndices: Array.from(frame.wordLengthIndices),
|
|
558
558
|
hasNonZeroScaleFactors: frame.scaleFactorIndices.some((sf) => sf > 0),
|
package/codec/io/processor.js
CHANGED
|
@@ -286,7 +286,7 @@ export class AudioProcessor {
|
|
|
286
286
|
static _createDummyFrame() {
|
|
287
287
|
return {
|
|
288
288
|
nBfu: 0,
|
|
289
|
-
|
|
289
|
+
blockModes: [0, 0, 0],
|
|
290
290
|
scaleFactorIndices: new Int32Array(0),
|
|
291
291
|
wordLengthIndices: new Int32Array(0),
|
|
292
292
|
quantizedCoefficients: [],
|
|
@@ -32,7 +32,7 @@ import { packBits, unpackBits, unpackSignedBits } from './bitstream.js'
|
|
|
32
32
|
* Serializes encoded frame data into binary format
|
|
33
33
|
* @param {Object} frameData - The encoded frame data to serialize
|
|
34
34
|
* @param {number} frameData.nBfu - Number of block floating units
|
|
35
|
-
* @param {number[]} frameData.
|
|
35
|
+
* @param {number[]} frameData.blockModes - Block modes for each band [0-2]
|
|
36
36
|
* @param {Int32Array} frameData.scaleFactorIndices - Scale factor indices for each BFU
|
|
37
37
|
* @param {Int32Array} frameData.wordLengthIndices - Word length indices for each BFU
|
|
38
38
|
* @param {Int32Array[]} frameData.quantizedCoefficients - Quantized spectral coefficients
|
|
@@ -45,9 +45,9 @@ export function serializeFrame(frameData) {
|
|
|
45
45
|
// Pack header (16 bits)
|
|
46
46
|
const bfuIndex = BFU_AMOUNTS.indexOf(frameData.nBfu)
|
|
47
47
|
const header =
|
|
48
|
-
((2 - frameData.
|
|
49
|
-
((2 - frameData.
|
|
50
|
-
((3 - frameData.
|
|
48
|
+
((2 - frameData.blockModes[0]) << 14) |
|
|
49
|
+
((2 - frameData.blockModes[1]) << 12) |
|
|
50
|
+
((3 - frameData.blockModes[2]) << 10) |
|
|
51
51
|
(bfuIndex << 5)
|
|
52
52
|
|
|
53
53
|
view.setUint16(0, header, false)
|
|
@@ -102,7 +102,7 @@ export function serializeFrame(frameData) {
|
|
|
102
102
|
* @param {Uint8Array} buffer - Binary frame data buffer
|
|
103
103
|
* @returns {Object} Deserialized frame data
|
|
104
104
|
* @returns {number} returns.nBfu - Number of block floating units
|
|
105
|
-
* @returns {number[]} returns.
|
|
105
|
+
* @returns {number[]} returns.blockModes - Block modes for each band
|
|
106
106
|
* @returns {Int32Array} returns.scaleFactorIndices - Scale factor indices for each BFU
|
|
107
107
|
* @returns {Int32Array} returns.wordLengthIndices - Word length indices for each BFU
|
|
108
108
|
* @returns {Int32Array[]} returns.quantizedCoefficients - Quantized spectral coefficients
|
|
@@ -117,7 +117,7 @@ export function deserializeFrame(buffer) {
|
|
|
117
117
|
|
|
118
118
|
// Unpack header
|
|
119
119
|
const header = view.getUint16(0, false)
|
|
120
|
-
const
|
|
120
|
+
const blockModes = [
|
|
121
121
|
2 - ((header >> 14) & 3),
|
|
122
122
|
2 - ((header >> 12) & 3),
|
|
123
123
|
3 - ((header >> 10) & 3),
|
|
@@ -171,7 +171,7 @@ export function deserializeFrame(buffer) {
|
|
|
171
171
|
scaleFactorIndices,
|
|
172
172
|
wordLengthIndices,
|
|
173
173
|
quantizedCoefficients,
|
|
174
|
-
|
|
174
|
+
blockModes,
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
|
|
@@ -57,10 +57,10 @@ export function dequantizationStage() {
|
|
|
57
57
|
* @param {Int32Array} frameData.scaleFactorIndices - Scale factor indices for each BFU
|
|
58
58
|
* @param {Int32Array} frameData.wordLengthIndices - Word length indices for each BFU
|
|
59
59
|
* @param {Array<Int32Array>} frameData.quantizedCoefficients - Quantized coefficient data
|
|
60
|
-
* @param {Array<number>} frameData.
|
|
61
|
-
* @returns {
|
|
62
|
-
* @returns {Float32Array} returns
|
|
63
|
-
* @returns {Array<number>} returns
|
|
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
64
|
*/
|
|
65
65
|
return (frameData) => {
|
|
66
66
|
const coefficients = new Float32Array(512)
|
|
@@ -69,7 +69,7 @@ export function dequantizationStage() {
|
|
|
69
69
|
scaleFactorIndices,
|
|
70
70
|
wordLengthIndices,
|
|
71
71
|
quantizedCoefficients,
|
|
72
|
-
|
|
72
|
+
blockModes,
|
|
73
73
|
} = frameData
|
|
74
74
|
|
|
75
75
|
for (let bfu = 0; bfu < nBfu; bfu++) {
|
|
@@ -79,7 +79,7 @@ export function dequantizationStage() {
|
|
|
79
79
|
if (bfu >= BFU_BAND_BOUNDARIES[0]) band = 1
|
|
80
80
|
if (bfu >= BFU_BAND_BOUNDARIES[1]) band = 2
|
|
81
81
|
|
|
82
|
-
const isLongBlock =
|
|
82
|
+
const isLongBlock = blockModes[band] === 0
|
|
83
83
|
const position = isLongBlock ? BFU_START_LONG[bfu] : BFU_START_SHORT[bfu]
|
|
84
84
|
|
|
85
85
|
if (bitsPerSample > 0) {
|
|
@@ -93,7 +93,7 @@ export function dequantizationStage() {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
return
|
|
96
|
+
return { coefficients, blockModes }
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
@@ -287,13 +287,13 @@ export function imdctStage(context) {
|
|
|
287
287
|
|
|
288
288
|
/**
|
|
289
289
|
* Transform coefficients back to time domain using inverse MDCT
|
|
290
|
-
* @param {
|
|
291
|
-
* @param {Float32Array} input
|
|
292
|
-
* @param {Array<number>} input
|
|
290
|
+
* @param {Object} input - Dequantization results
|
|
291
|
+
* @param {Float32Array} input.coefficients - MDCT coefficients (512 samples)
|
|
292
|
+
* @param {Array<number>} input.blockModes - Block modes for each band
|
|
293
293
|
* @returns {Array<Float32Array>} Three reconstructed frequency bands [low, mid, high]
|
|
294
294
|
*/
|
|
295
295
|
return (input) => {
|
|
296
|
-
const
|
|
296
|
+
const { coefficients, blockModes } = input
|
|
297
297
|
|
|
298
298
|
return MDCT_BAND_CONFIGS.map((config, bandIndex) => {
|
|
299
299
|
const bandCoeffs = extractBandCoefficients(coefficients, bandIndex)
|
|
@@ -126,7 +126,7 @@ export function blockSelectorStage(context) {
|
|
|
126
126
|
* @param {Array<Float32Array>} input.bands - Three frequency bands [low, mid, high]
|
|
127
127
|
* @returns {Object} Block selection results
|
|
128
128
|
* @returns {Array<Float32Array>} returns.bands - Original frequency bands
|
|
129
|
-
* @returns {Array<number>} returns.blockModes - Block
|
|
129
|
+
* @returns {Array<number>} returns.blockModes - Block modes for each band
|
|
130
130
|
*/
|
|
131
131
|
return (input) => {
|
|
132
132
|
const { bands } = input
|
|
@@ -298,12 +298,12 @@ export function mdctStage(context) {
|
|
|
298
298
|
* Transform frequency bands using MDCT
|
|
299
299
|
* @param {Object} input - Block selection results
|
|
300
300
|
* @param {Array<Float32Array>} input.bands - Three frequency bands
|
|
301
|
-
* @param {Array<number>} input.blockModes - Block
|
|
301
|
+
* @param {Array<number>} input.blockModes - Block modes for each band
|
|
302
302
|
* @param {any} input.originalFrame - Original frame data (passed through)
|
|
303
303
|
* @returns {Object} MDCT transform results
|
|
304
304
|
* @returns {Array<Float32Array>} returns.bands - Original frequency bands
|
|
305
305
|
* @returns {Float32Array} returns.coefficients - MDCT coefficients (512 samples)
|
|
306
|
-
* @returns {Array<number>} returns.blockModes - Block
|
|
306
|
+
* @returns {Array<number>} returns.blockModes - Block modes
|
|
307
307
|
* @returns {any} returns.originalFrame - Original frame data
|
|
308
308
|
*/
|
|
309
309
|
return (input) => {
|
|
@@ -356,13 +356,13 @@ export function quantizationStage(context) {
|
|
|
356
356
|
* Perform psychoacoustic analysis and quantization
|
|
357
357
|
* @param {Object} input - MDCT transform results
|
|
358
358
|
* @param {Float32Array} input.coefficients - MDCT coefficients
|
|
359
|
-
* @param {Array<number>} input.blockModes - Block
|
|
359
|
+
* @param {Array<number>} input.blockModes - Block modes
|
|
360
360
|
* @returns {Object} Quantization results ready for bitstream encoding
|
|
361
361
|
* @returns {number} returns.nBfu - Number of active BFUs
|
|
362
362
|
* @returns {Int32Array} returns.scaleFactorIndices - Scale factor indices for each BFU
|
|
363
363
|
* @returns {Int32Array} returns.wordLengthIndices - Word length indices for each BFU
|
|
364
364
|
* @returns {Array<Int32Array>} returns.quantizedCoefficients - Quantized coefficient data
|
|
365
|
-
* @returns {Array<number>} returns.
|
|
365
|
+
* @returns {Array<number>} returns.blockModes - Block modes for each band
|
|
366
366
|
*/
|
|
367
367
|
return (input) => {
|
|
368
368
|
const { coefficients, blockModes } = input
|
|
@@ -399,7 +399,7 @@ export function quantizationStage(context) {
|
|
|
399
399
|
scaleFactorIndices,
|
|
400
400
|
wordLengthIndices: allocation.slice(0, selectedBfuCount),
|
|
401
401
|
quantizedCoefficients,
|
|
402
|
-
|
|
402
|
+
blockModes,
|
|
403
403
|
}
|
|
404
404
|
}
|
|
405
405
|
}
|
package/codec/transforms/fft.js
CHANGED
|
@@ -12,12 +12,8 @@ export class FFT {
|
|
|
12
12
|
*/
|
|
13
13
|
static fft(real, imag) {
|
|
14
14
|
const n = real.length
|
|
15
|
-
if (n !== imag.length)
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
if ((n & (n - 1)) !== 0) {
|
|
19
|
-
throw new Error('Input size must be a power of 2.')
|
|
20
|
-
}
|
|
15
|
+
if (n !== imag.length) throw new Error('Mismatched array lengths.')
|
|
16
|
+
if ((n & (n - 1)) !== 0) throw new Error('Length must be power of 2.')
|
|
21
17
|
if (n <= 1) return
|
|
22
18
|
|
|
23
19
|
let cache = FFT._cache.get(n)
|
|
@@ -26,168 +22,91 @@ export class FFT {
|
|
|
26
22
|
FFT._cache.set(n, cache)
|
|
27
23
|
}
|
|
28
24
|
|
|
29
|
-
const
|
|
25
|
+
const bitRev = cache.bitRev
|
|
26
|
+
const cosTbl = cache.cos
|
|
27
|
+
const sinTbl = cache.sin
|
|
30
28
|
|
|
31
|
-
// Bit
|
|
29
|
+
// Bit reversal
|
|
32
30
|
for (let i = 0; i < n; i++) {
|
|
33
31
|
const j = bitRev[i]
|
|
34
32
|
if (j > i) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const tempI = imag[i]
|
|
33
|
+
let tr = real[i]
|
|
34
|
+
let ti = imag[i]
|
|
38
35
|
real[i] = real[j]
|
|
39
36
|
imag[i] = imag[j]
|
|
40
|
-
real[j] =
|
|
41
|
-
imag[j] =
|
|
37
|
+
real[j] = tr
|
|
38
|
+
imag[j] = ti
|
|
42
39
|
}
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
//
|
|
46
|
-
// Stride 2 - no twiddle factors needed
|
|
42
|
+
// First stage: stride=2
|
|
47
43
|
for (let i = 0; i < n; i += 2) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
imag[i + 1] = evenI - oddI
|
|
44
|
+
let r0 = real[i],
|
|
45
|
+
i0 = imag[i]
|
|
46
|
+
let r1 = real[i + 1],
|
|
47
|
+
i1 = imag[i + 1]
|
|
48
|
+
real[i] = r0 + r1
|
|
49
|
+
imag[i] = i0 + i1
|
|
50
|
+
real[i + 1] = r0 - r1
|
|
51
|
+
imag[i + 1] = i0 - i1
|
|
57
52
|
}
|
|
58
53
|
|
|
59
|
-
//
|
|
54
|
+
// Second stage: stride=4
|
|
60
55
|
if (n >= 4) {
|
|
61
56
|
for (let i = 0; i < n; i += 4) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
let
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
real[i] =
|
|
69
|
-
imag[i] =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
real[i + 1] = evenR + tR
|
|
83
|
-
imag[i + 1] = evenI + tI
|
|
84
|
-
real[i + 3] = evenR - tR
|
|
85
|
-
imag[i + 3] = evenI - tI
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Stride 8 - unrolled for better performance
|
|
90
|
-
if (n >= 8) {
|
|
91
|
-
for (let i = 0; i < n; i += 8) {
|
|
92
|
-
// W^0 = 1
|
|
93
|
-
let idx0 = i
|
|
94
|
-
let idx4 = i + 4
|
|
95
|
-
let r0 = real[idx0],
|
|
96
|
-
i0 = imag[idx0]
|
|
97
|
-
let r4 = real[idx4],
|
|
98
|
-
i4 = imag[idx4]
|
|
99
|
-
real[idx0] = r0 + r4
|
|
100
|
-
imag[idx0] = i0 + i4
|
|
101
|
-
real[idx4] = r0 - r4
|
|
102
|
-
imag[idx4] = i0 - i4
|
|
103
|
-
|
|
104
|
-
// W^1 = cos(-π/4) - i*sin(-π/4)
|
|
105
|
-
let idx1 = i + 1
|
|
106
|
-
let idx5 = i + 5
|
|
107
|
-
r0 = real[idx1]
|
|
108
|
-
i0 = imag[idx1]
|
|
109
|
-
r4 = real[idx5]
|
|
110
|
-
i4 = imag[idx5]
|
|
111
|
-
const sqrt2_2 = 0.7071067811865476
|
|
112
|
-
let tR = sqrt2_2 * (r4 + i4)
|
|
113
|
-
let tI = sqrt2_2 * (i4 - r4)
|
|
114
|
-
real[idx1] = r0 + tR
|
|
115
|
-
imag[idx1] = i0 + tI
|
|
116
|
-
real[idx5] = r0 - tR
|
|
117
|
-
imag[idx5] = i0 - tI
|
|
118
|
-
|
|
119
|
-
// W^2 = -i
|
|
120
|
-
let idx2 = i + 2
|
|
121
|
-
let idx6 = i + 6
|
|
122
|
-
r0 = real[idx2]
|
|
123
|
-
i0 = imag[idx2]
|
|
124
|
-
r4 = real[idx6]
|
|
125
|
-
i4 = imag[idx6]
|
|
126
|
-
tR = i4
|
|
127
|
-
tI = -r4
|
|
128
|
-
real[idx2] = r0 + tR
|
|
129
|
-
imag[idx2] = i0 + tI
|
|
130
|
-
real[idx6] = r0 - tR
|
|
131
|
-
imag[idx6] = i0 - tI
|
|
132
|
-
|
|
133
|
-
// W^3 = cos(-3π/4) - i*sin(-3π/4)
|
|
134
|
-
let idx3 = i + 3
|
|
135
|
-
let idx7 = i + 7
|
|
136
|
-
r0 = real[idx3]
|
|
137
|
-
i0 = imag[idx3]
|
|
138
|
-
r4 = real[idx7]
|
|
139
|
-
i4 = imag[idx7]
|
|
140
|
-
tR = sqrt2_2 * (-r4 + i4)
|
|
141
|
-
tI = sqrt2_2 * (-r4 - i4)
|
|
142
|
-
real[idx3] = r0 + tR
|
|
143
|
-
imag[idx3] = i0 + tI
|
|
144
|
-
real[idx7] = r0 - tR
|
|
145
|
-
imag[idx7] = i0 - tI
|
|
57
|
+
let r0 = real[i],
|
|
58
|
+
i0 = imag[i]
|
|
59
|
+
let r2 = real[i + 2],
|
|
60
|
+
i2 = imag[i + 2]
|
|
61
|
+
real[i] = r0 + r2
|
|
62
|
+
imag[i] = i0 + i2
|
|
63
|
+
real[i + 2] = r0 - r2
|
|
64
|
+
imag[i + 2] = i0 - i2
|
|
65
|
+
|
|
66
|
+
r0 = real[i + 1]
|
|
67
|
+
i0 = imag[i + 1]
|
|
68
|
+
r2 = real[i + 3]
|
|
69
|
+
i2 = imag[i + 3]
|
|
70
|
+
// W^1 = -i
|
|
71
|
+
let tR = i2
|
|
72
|
+
let tI = -r2
|
|
73
|
+
real[i + 1] = r0 + tR
|
|
74
|
+
imag[i + 1] = i0 + tI
|
|
75
|
+
real[i + 3] = r0 - tR
|
|
76
|
+
imag[i + 3] = i0 - tI
|
|
146
77
|
}
|
|
147
78
|
}
|
|
148
79
|
|
|
149
|
-
//
|
|
150
|
-
for (let stride =
|
|
80
|
+
// Higher stages
|
|
81
|
+
for (let stride = 8; stride <= n; stride <<= 1) {
|
|
151
82
|
const halfStride = stride >>> 1
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
let
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
real[oddIdx] = r0 - r1
|
|
166
|
-
imag[oddIdx] = i0 - i1
|
|
167
|
-
|
|
168
|
-
// Remaining butterflies with twiddle factors
|
|
169
|
-
let twiddleIdx = step
|
|
83
|
+
const tblStep = n / stride
|
|
84
|
+
for (let base = 0; base < n; base += stride) {
|
|
85
|
+
// k = 0
|
|
86
|
+
let r0 = real[base],
|
|
87
|
+
i0 = imag[base]
|
|
88
|
+
let r1 = real[base + halfStride],
|
|
89
|
+
i1 = imag[base + halfStride]
|
|
90
|
+
real[base] = r0 + r1
|
|
91
|
+
imag[base] = i0 + i1
|
|
92
|
+
real[base + halfStride] = r0 - r1
|
|
93
|
+
imag[base + halfStride] = i0 - i1
|
|
94
|
+
|
|
95
|
+
let tw = tblStep
|
|
170
96
|
for (let k = 1; k < halfStride; k++) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
real[evenIdx] = evenR + tR
|
|
186
|
-
imag[evenIdx] = evenI + tI
|
|
187
|
-
real[oddIdx] = evenR - tR
|
|
188
|
-
imag[oddIdx] = evenI - tI
|
|
189
|
-
|
|
190
|
-
twiddleIdx += step
|
|
97
|
+
const c = cosTbl[tw]
|
|
98
|
+
const s = sinTbl[tw]
|
|
99
|
+
r1 = real[base + k]
|
|
100
|
+
i1 = imag[base + k]
|
|
101
|
+
let r2 = real[base + k + halfStride]
|
|
102
|
+
let i2 = imag[base + k + halfStride]
|
|
103
|
+
let tr = r2 * c - i2 * s
|
|
104
|
+
let ti = r2 * s + i2 * c
|
|
105
|
+
real[base + k] = r1 + tr
|
|
106
|
+
imag[base + k] = i1 + ti
|
|
107
|
+
real[base + k + halfStride] = r1 - tr
|
|
108
|
+
imag[base + k + halfStride] = i1 - ti
|
|
109
|
+
tw += tblStep
|
|
191
110
|
}
|
|
192
111
|
}
|
|
193
112
|
}
|
|
@@ -198,27 +117,20 @@ export class FFT {
|
|
|
198
117
|
* @private
|
|
199
118
|
*/
|
|
200
119
|
static _buildCache(n) {
|
|
201
|
-
const log2n = Math.log2(n) | 0
|
|
202
|
-
|
|
203
|
-
// Optimized bit-reversal using iterative approach
|
|
204
120
|
const bitRev = new Uint32Array(n)
|
|
121
|
+
const log2n = Math.log2(n) | 0
|
|
205
122
|
for (let i = 1; i < n; i++) {
|
|
206
123
|
bitRev[i] = (bitRev[i >>> 1] >>> 1) | ((i & 1) << (log2n - 1))
|
|
207
124
|
}
|
|
208
|
-
|
|
209
|
-
// Pre-compute twiddle factors with better precision
|
|
210
125
|
const halfN = n >>> 1
|
|
211
126
|
const cosTbl = new Float32Array(halfN)
|
|
212
127
|
const sinTbl = new Float32Array(halfN)
|
|
213
|
-
|
|
214
|
-
// Use higher precision calculation then cast to Float32
|
|
215
|
-
const angleStep = (-2 * Math.PI) / n
|
|
128
|
+
const ang = (-2 * Math.PI) / n
|
|
216
129
|
for (let i = 0; i < halfN; i++) {
|
|
217
|
-
const
|
|
218
|
-
cosTbl[i] = Math.
|
|
219
|
-
sinTbl[i] = Math.
|
|
130
|
+
const a = ang * i
|
|
131
|
+
cosTbl[i] = Math.cos(a)
|
|
132
|
+
sinTbl[i] = Math.sin(a)
|
|
220
133
|
}
|
|
221
|
-
|
|
222
134
|
return { bitRev, cos: cosTbl, sin: sinTbl }
|
|
223
135
|
}
|
|
224
136
|
}
|
package/codec/transforms/mdct.js
CHANGED
|
@@ -52,9 +52,19 @@ export class MDCT extends MDCTBase {
|
|
|
52
52
|
* @returns {Float32Array} Frequency-domain MDCT coefficients
|
|
53
53
|
*/
|
|
54
54
|
transform(input, mdctBuffers = null) {
|
|
55
|
-
const buffers =
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
const buffers =
|
|
56
|
+
mdctBuffers?.[this.fftSize] ??
|
|
57
|
+
throwError(`MDCT.transform: mdctBuffers[${this.fftSize}] is required`)
|
|
58
|
+
const real =
|
|
59
|
+
buffers?.real ??
|
|
60
|
+
throwError(
|
|
61
|
+
`MDCT.transform: mdctBuffers[${this.fftSize}].real is required`
|
|
62
|
+
)
|
|
63
|
+
const imag =
|
|
64
|
+
buffers?.imag ??
|
|
65
|
+
throwError(
|
|
66
|
+
`MDCT.transform: mdctBuffers[${this.fftSize}].imag is required`
|
|
67
|
+
)
|
|
58
68
|
|
|
59
69
|
const n4 = this.quarterSize
|
|
60
70
|
const n34 = 3 * n4
|
|
@@ -127,9 +137,19 @@ export class IMDCT extends MDCTBase {
|
|
|
127
137
|
* @returns {Float32Array} Time-domain output samples
|
|
128
138
|
*/
|
|
129
139
|
transform(input, mdctBuffers = null) {
|
|
130
|
-
const buffers =
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
const buffers =
|
|
141
|
+
mdctBuffers?.[this.fftSize] ??
|
|
142
|
+
throwError(`IMDCT.transform: mdctBuffers[${this.fftSize}] is required`)
|
|
143
|
+
const real =
|
|
144
|
+
buffers?.real ??
|
|
145
|
+
throwError(
|
|
146
|
+
`IMDCT.transform: mdctBuffers[${this.fftSize}].real is required`
|
|
147
|
+
)
|
|
148
|
+
const imag =
|
|
149
|
+
buffers?.imag ??
|
|
150
|
+
throwError(
|
|
151
|
+
`IMDCT.transform: mdctBuffers[${this.fftSize}].imag is required`
|
|
152
|
+
)
|
|
133
153
|
|
|
134
154
|
const n4 = this.quarterSize
|
|
135
155
|
const n34 = 3 * n4
|
package/codec/transforms/qmf.js
CHANGED
|
@@ -22,7 +22,7 @@ export function qmfAnalysis(input, delayLine, qmfWorkBuffers = null) {
|
|
|
22
22
|
|
|
23
23
|
const workBuffer =
|
|
24
24
|
qmfWorkBuffers?.delay?.[inputLength] ??
|
|
25
|
-
throwError(
|
|
25
|
+
throwError(`qmfAnalysis: qmfWorkBuffers.delay[${inputLength}] is required`)
|
|
26
26
|
workBuffer.set(delayLine)
|
|
27
27
|
workBuffer.set(input, delayLine.length)
|
|
28
28
|
|
|
@@ -68,7 +68,9 @@ export function qmfSynthesis(
|
|
|
68
68
|
|
|
69
69
|
const workBuffer =
|
|
70
70
|
qmfWorkBuffers?.delay?.[outputLength] ??
|
|
71
|
-
throwError(
|
|
71
|
+
throwError(
|
|
72
|
+
`qmfSynthesis: qmfWorkBuffers.delay[${outputLength}] is required`
|
|
73
|
+
)
|
|
72
74
|
workBuffer.set(delayLine)
|
|
73
75
|
|
|
74
76
|
// Upsample and merge
|