carta1 1.1.0 → 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/bin/cli.js CHANGED
@@ -156,7 +156,7 @@ class ProgressTracker {
156
156
  * Provides async iteration over WAV file frames for memory-efficient
157
157
  * processing of large audio files. Automatically handles:
158
158
  * - Multi-channel deinterleaving
159
- * - Bit depth conversion to float32
159
+ * - Bit depth conversion to Float64
160
160
  * - Frame padding for the last partial frame
161
161
  *
162
162
  * @class
@@ -225,9 +225,9 @@ class WavReader {
225
225
  * Async iterator for streaming WAV file frames
226
226
  *
227
227
  * @param {number} [frameSize=SAMPLES_PER_FRAME] - Samples per frame
228
- * @yields {Float32Array|Array<Float32Array>} Audio frame data
229
- * - Mono: Float32Array of samples
230
- * - Stereo: [left, right] Float32Arrays
228
+ * @yields {Float64Array|Array<Float64Array>} Audio frame data
229
+ * - Mono: Float64Array of samples
230
+ * - Stereo: [left, right] Float64Arrays
231
231
  */
232
232
  async *[Symbol.asyncIterator](frameSize = SAMPLES_PER_FRAME) {
233
233
  const fileStream = fs.createReadStream(this.filePath)
@@ -305,23 +305,23 @@ class WavReader {
305
305
  }
306
306
 
307
307
  /**
308
- * Process raw PCM buffer into float32 frame data
308
+ * Process raw PCM buffer into float64 frame data
309
309
  *
310
310
  * @private
311
311
  * @param {Buffer} frameBuffer - Raw PCM data
312
312
  * @param {number} frameSize - Number of samples per channel
313
- * @returns {Float32Array|Array<Float32Array>} Processed frame data
313
+ * @returns {Float64Array|Array<Float64Array>} Processed frame data
314
314
  */
315
315
  _processFrameBuffer(frameBuffer, frameSize) {
316
316
  if (this.channels === 1) {
317
- const frame = new Float32Array(frameSize)
317
+ const frame = new Float64Array(frameSize)
318
318
  for (let i = 0; i < frameSize; i++) {
319
319
  frame[i] = this._sampleToFloat(frameBuffer, i * (this.bitDepth / 8))
320
320
  }
321
321
  return frame
322
322
  } else {
323
- const left = new Float32Array(frameSize)
324
- const right = new Float32Array(frameSize)
323
+ const left = new Float64Array(frameSize)
324
+ const right = new Float64Array(frameSize)
325
325
  for (let i = 0; i < frameSize; i++) {
326
326
  const offset = i * this.channels * (this.bitDepth / 8)
327
327
  left[i] = this._sampleToFloat(frameBuffer, offset)
@@ -332,7 +332,7 @@ class WavReader {
332
332
  }
333
333
 
334
334
  /**
335
- * Convert PCM sample to normalized float32 value
335
+ * Convert PCM sample to normalized Float64 value
336
336
  *
337
337
  * @private
338
338
  * @param {Buffer} buffer - PCM data buffer
@@ -10,13 +10,13 @@ import { FFT } from '../transforms/fft.js'
10
10
 
11
11
  /**
12
12
  * Perform FFT on time-domain samples and return magnitude spectrum
13
- * @param {Float32Array} samples - Time-domain samples
13
+ * @param {Float64Array} samples - Time-domain samples
14
14
  * @param {number} fftSize - FFT size (must be power of 2)
15
- * @returns {Float32Array} Magnitude spectrum (positive frequencies only)
15
+ * @returns {Float64Array} Magnitude spectrum (positive frequencies only)
16
16
  */
17
17
  export function performFFT(samples, fftSize) {
18
- const real = new Float32Array(fftSize)
19
- const imag = new Float32Array(fftSize)
18
+ const real = new Float64Array(fftSize)
19
+ const imag = new Float64Array(fftSize)
20
20
 
21
21
  // Copy samples with zero-padding if necessary
22
22
  const copyLen = Math.min(samples.length, fftSize)
@@ -26,7 +26,7 @@ export function performFFT(samples, fftSize) {
26
26
  FFT.fft(real, imag)
27
27
 
28
28
  // Calculate magnitude spectrum for positive frequencies
29
- const magnitude = new Float32Array(fftSize / 2)
29
+ const magnitude = new Float64Array(fftSize / 2)
30
30
  for (let i = 0; i < fftSize / 2; i++) {
31
31
  magnitude[i] = Math.sqrt(real[i] * real[i] + imag[i] * imag[i])
32
32
  }
@@ -36,8 +36,8 @@ export function performFFT(samples, fftSize) {
36
36
 
37
37
  /**
38
38
  * Detect transients by analyzing spectral changes between frames
39
- * @param {Float32Array} currentCoeffs - Current frame coefficients
40
- * @param {Float32Array} prevCoeffs - Previous frame coefficients
39
+ * @param {Float64Array} currentCoeffs - Current frame coefficients
40
+ * @param {Float64Array} prevCoeffs - Previous frame coefficients
41
41
  * @param {number} threshold - Detection threshold
42
42
  * @returns {boolean} True if transient detected
43
43
  */
@@ -56,8 +56,8 @@ export function detectTransient(currentCoeffs, prevCoeffs, threshold) {
56
56
 
57
57
  /**
58
58
  * Calculate all spectral features for transient detection
59
- * @param {Float32Array} currentCoeffs - Current frame coefficients
60
- * @param {Float32Array} prevCoeffs - Previous frame coefficients
59
+ * @param {Float64Array} currentCoeffs - Current frame coefficients
60
+ * @param {Float64Array} prevCoeffs - Previous frame coefficients
61
61
  * @returns {Object} Computed spectral features
62
62
  */
63
63
  function calculateSpectralFeatures(currentCoeffs, prevCoeffs) {
@@ -114,7 +114,7 @@ function calculateSpectralFlux(currentCoeffs, prevCoeffs) {
114
114
  /**
115
115
  * Calculate spectral flatness (geometric mean / arithmetic mean)
116
116
  * Measures how noise-like vs tonal the spectrum is
117
- * @param {Float32Array} coeffs - Spectral coefficients
117
+ * @param {Float64Array} coeffs - Spectral coefficients
118
118
  * @returns {number} Flatness measure (0 = tonal, 1 = noise-like)
119
119
  */
120
120
  function calculateSpectralFlatness(coeffs) {
@@ -143,7 +143,7 @@ function calculateSpectralFlatness(coeffs) {
143
143
  /**
144
144
  * Calculate ratio of high-frequency to total energy
145
145
  * High values indicate bright/harsh sounds that are perceptually important
146
- * @param {Float32Array} coeffs - Spectral coefficients
146
+ * @param {Float64Array} coeffs - Spectral coefficients
147
147
  * @returns {number} High-frequency energy ratio (0-1)
148
148
  */
149
149
  function calculateHighFrequencyRatio(coeffs) {
@@ -165,8 +165,8 @@ function calculateHighFrequencyRatio(coeffs) {
165
165
 
166
166
  /**
167
167
  * Calculate energy change between frames in dB
168
- * @param {Float32Array} currentCoeffs - Current frame coefficients
169
- * @param {Float32Array} prevCoeffs - Previous frame coefficients
168
+ * @param {Float64Array} currentCoeffs - Current frame coefficients
169
+ * @param {Float64Array} prevCoeffs - Previous frame coefficients
170
170
  * @returns {number} Energy change in dB (positive values only)
171
171
  */
172
172
  function calculateEnergyChange(currentCoeffs, prevCoeffs) {
@@ -64,9 +64,9 @@ class Carta1Worker {
64
64
  /**
65
65
  * Encode PCM audio to ATRAC1 format
66
66
  *
67
- * @param {Float32Array|Array<Float32Array>} pcmData - PCM audio data
68
- * - Mono: Float32Array
69
- * - Stereo: [left, right] Float32Arrays
67
+ * @param {Float64Array|Array<Float64Array>} pcmData - PCM audio data
68
+ * - Mono: Float64Array
69
+ * - Stereo: [left, right] Float64Arrays
70
70
  * @param {Object} [options={}] - Encoder options
71
71
  * @param {number} [options.transientThresholdLow] - Low band transient threshold
72
72
  * @param {number} [options.transientThresholdMid] - Mid band transient threshold
@@ -56,7 +56,7 @@ self.onmessage = async (e) => {
56
56
  /**
57
57
  * Encode PCM audio data to ATRAC1 format
58
58
  *
59
- * @param {Array<Float32Array>} pcmData - PCM audio data [mono] or [left, right]
59
+ * @param {Array<Float64Array>} pcmData - PCM audio data [mono] or [left, right]
60
60
  * @param {Object} options - Encoder options
61
61
  * @returns {Promise<Object>} Encoded AEA blob
62
62
  */
@@ -29,16 +29,13 @@ import {
29
29
  BITS_PER_BFU_METADATA,
30
30
  MAX_WORD_LENGTH_INDEX,
31
31
  WORD_LENGTH_BITS,
32
- LP_DISTORTION_CONSTANT,
33
- SF_POW_P,
34
- POW2_POS_P,
35
- POW2_NEG_P,
32
+ INV_POWER_OF_TWO,
36
33
  SCALE_FACTORS,
37
34
  } from '../core/constants.js'
38
35
 
39
36
  /**
40
37
  * Allocate bits to BFUs using optimized greedy Lp-RDO
41
- * @param {Array<Float32Array>} bfuData
38
+ * @param {Array<Float64Array>} bfuData
42
39
  * @param {Int32Array} bfuSizes
43
40
  * @param {number} maxBfuCount
44
41
  * @returns {{bfuCount:number, allocation:Int32Array, scaleFactorIndices:Int32Array}}
@@ -64,21 +61,8 @@ export function allocateBits(bfuData, bfuSizes, maxBfuCount) {
64
61
  * while staying within the bit budget. It uses a priority queue (max-heap) to greedily allocate
65
62
  * bits to the BFUs that provide the greatest distortion reduction per bit spent.
66
63
  *
67
- * Mathematical Model:
68
- * Distortion for b bits is modeled as:
69
- * D(b) = C * 2^{-p * b} for b >= 1
70
- * D(0) = C * 2^{ p } (finite large step for "mute" case)
71
- * where C = N * (sf^p) * k, with N = BFU length, sf = scale factor, p and k constants.
72
- *
73
- * Hence, for an upgrade from b1 -> b2 (b2 > b1), ΔD = D(b1) - D(b2) can be computed with 2 table lookups.
74
- *
75
- * Precomputed tables:
76
- * POW2_NEG_P[b] = 2^{-p*b} for b=0..maxBits
77
- * POW2_POS_P = 2^{ p}
78
- * SF_POW_P[sfIndex] = (SCALE_FACTORS[sfIndex])^p
79
- *
80
64
  * @param {number} activeBfuCount
81
- * @param {Array<Float32Array>} bfuData
65
+ * @param {Array<Float64Array>} bfuData
82
66
  * @param {Int32Array} bfuSizes
83
67
  * @param {number} remainingBits
84
68
  * @returns {{wordLengths: Int32Array, scaleFactorIndices: Int32Array}}
@@ -87,38 +71,31 @@ function distributeBitsRDO(activeBfuCount, bfuData, bfuSizes, remainingBits) {
87
71
  const scaleFactorTable = new Int32Array(NUM_BFUS)
88
72
  const wordLengths = new Int32Array(activeBfuCount)
89
73
 
90
- const baseWeight = new Float64Array(activeBfuCount) // C above
91
- for (let bfuIndex = 0; bfuIndex < activeBfuCount; bfuIndex++) {
92
- const sz = bfuSizes[bfuIndex] | 0
93
- if (sz > 0) {
94
- const sfi = findScaleFactor(bfuData[bfuIndex].subarray(0, sz))
95
- scaleFactorTable[bfuIndex] = sfi
96
- baseWeight[bfuIndex] = sz * SF_POW_P[sfi] * LP_DISTORTION_CONSTANT
97
- } else {
98
- scaleFactorTable[bfuIndex] = 0
99
- baseWeight[bfuIndex] = 0
100
- }
101
- }
102
-
103
74
  const heapIndices = []
104
75
  const heapPriorities = []
105
- const deltaDist = (bfuIndex, currentWl, nextWl) => {
106
- const base = baseWeight[bfuIndex]
107
- if (base === 0) return 0
76
+
77
+ const deltaDistPerCoeff = (bfuIndex, currentWl, nextWl) => {
78
+ const sfi = scaleFactorTable[bfuIndex]
79
+ const scaleFactor = SCALE_FACTORS[sfi]
80
+ if (scaleFactor === 0) return 0
108
81
 
109
82
  const bits1 = WORD_LENGTH_BITS[currentWl] | 0
110
83
  const bits2 = WORD_LENGTH_BITS[nextWl] | 0
111
84
 
112
- const f1 = bits1 === 0 ? POW2_POS_P : POW2_NEG_P[bits1]
113
- const f2 = POW2_NEG_P[bits2]
85
+ const f1 = bits1 === 0 ? 2.0 : INV_POWER_OF_TWO[bits1]
86
+ const f2 = INV_POWER_OF_TWO[bits2]
114
87
 
115
- return base * (f1 - f2)
88
+ return scaleFactor * (f1 - f2)
116
89
  }
117
90
 
118
91
  for (let bfuIndex = 0; bfuIndex < activeBfuCount; bfuIndex++) {
119
92
  const sz = bfuSizes[bfuIndex] | 0
120
93
  if (sz === 0) continue
121
- if (scaleFactorTable[bfuIndex] === 0) continue
94
+
95
+ const sfi = findScaleFactor(bfuData[bfuIndex].subarray(0, sz))
96
+ scaleFactorTable[bfuIndex] = sfi
97
+
98
+ if (sfi === 0) continue
122
99
 
123
100
  const currentWl = 0
124
101
  const nextWl = 1
@@ -126,11 +103,9 @@ function distributeBitsRDO(activeBfuCount, bfuData, bfuSizes, remainingBits) {
126
103
  (WORD_LENGTH_BITS[nextWl] - WORD_LENGTH_BITS[currentWl]) | 0
127
104
  if (deltaBits <= 0) continue
128
105
 
129
- const deltaCost = deltaBits * sz
130
- const dd = deltaDist(bfuIndex, currentWl, nextWl)
131
-
106
+ const ddPerCoeff = deltaDistPerCoeff(bfuIndex, currentWl, nextWl)
132
107
  heapIndices.push(bfuIndex)
133
- heapPriorities.push(dd / deltaCost) // priority = ΔD / ΔR
108
+ heapPriorities.push(ddPerCoeff / deltaBits)
134
109
  }
135
110
 
136
111
  // Heapify
@@ -159,7 +134,7 @@ function distributeBitsRDO(activeBfuCount, bfuData, bfuSizes, remainingBits) {
159
134
  const nxt2 = nxt + 1
160
135
  const deltaBits2 = (WORD_LENGTH_BITS[nxt2] - WORD_LENGTH_BITS[nxt]) | 0
161
136
  if (deltaBits2 > 0) {
162
- heapPriorities[0] = deltaDist(bfu, nxt, nxt2) / (deltaBits2 * sz)
137
+ heapPriorities[0] = deltaDistPerCoeff(bfu, nxt, nxt2) / deltaBits2
163
138
  siftDown(heapIndices, heapPriorities, 0)
164
139
  } else {
165
140
  popRoot(heapIndices, heapPriorities)
@@ -175,42 +150,18 @@ function distributeBitsRDO(activeBfuCount, bfuData, bfuSizes, remainingBits) {
175
150
  /**
176
151
  * Find the optimal scale factor index for a set of coefficients.
177
152
  * Same semantics as the original.
178
- * @param {Float32Array} coefficients
153
+ * @param {Float64Array} coefficients
179
154
  * @returns {number}
180
155
  */
181
156
  export function findScaleFactor(coefficients) {
182
157
  let maxAmplitude = 0.0
183
- const n = coefficients.length | 0
184
- let i = 0
185
- const n4 = n & ~3
186
- for (; i < n4; i += 4) {
187
- const a0 = Math.abs(coefficients[i])
188
- const a1 = Math.abs(coefficients[i + 1])
189
- const a2 = Math.abs(coefficients[i + 2])
190
- const a3 = Math.abs(coefficients[i + 3])
191
- if (a0 > maxAmplitude) maxAmplitude = a0
192
- if (a1 > maxAmplitude) maxAmplitude = a1
193
- if (a2 > maxAmplitude) maxAmplitude = a2
194
- if (a3 > maxAmplitude) maxAmplitude = a3
195
- }
196
- for (; i < n; i++) {
158
+ for (let i = 0; i < coefficients.length; i++) {
197
159
  const a = Math.abs(coefficients[i])
198
160
  if (a > maxAmplitude) maxAmplitude = a
199
161
  }
200
162
  if (maxAmplitude === 0) return 0
201
-
202
- // Binary search
203
- let low = 0
204
- let high = SCALE_FACTORS.length - 1
205
- while (low < high) {
206
- const mid = (low + high) >> 1
207
- if (maxAmplitude <= SCALE_FACTORS[mid]) {
208
- high = mid
209
- } else {
210
- low = mid + 1
211
- }
212
- }
213
- return low
163
+ const index = Math.ceil(3 * (Math.log2(maxAmplitude) + 21))
164
+ return Math.max(0, Math.min(63, index))
214
165
  }
215
166
 
216
167
  /**
@@ -26,7 +26,7 @@ import {
26
26
 
27
27
  /**
28
28
  * Quantize coefficients.
29
- * @param {Float32Array} coefficients
29
+ * @param {Float64Array} coefficients
30
30
  * @param {number} scaleFactorIndex
31
31
  * @param {number} bitsPerSample
32
32
  * @returns {Int32Array} out
@@ -35,7 +35,6 @@ export function quantize(coefficients, scaleFactorIndex, bitsPerSample) {
35
35
  const length = coefficients.length
36
36
  const out = new Int32Array(length)
37
37
  if (bitsPerSample === 0 || scaleFactorIndex === 0) {
38
- // Zero fast path
39
38
  out.fill(0, 0, length)
40
39
  return out
41
40
  }
@@ -45,7 +44,7 @@ export function quantize(coefficients, scaleFactorIndex, bitsPerSample) {
45
44
  const normFactor = quantRange / scaleFactor
46
45
 
47
46
  const hi = quantRange
48
- const lo = -quantRange - 1
47
+ const lo = -quantRange
49
48
 
50
49
  for (let i = 0; i < length; i++) {
51
50
  const x = coefficients[i] * normFactor
@@ -61,20 +60,19 @@ export function quantize(coefficients, scaleFactorIndex, bitsPerSample) {
61
60
  * @param {Int32Array} quantized
62
61
  * @param {number} scaleFactorIndex
63
62
  * @param {number} bitsPerSample
64
- * @returns {Float32Array}
63
+ * @returns {Float64Array}
65
64
  */
66
65
  export function dequantize(quantized, scaleFactorIndex, bitsPerSample) {
67
66
  if (bitsPerSample === 0 || scaleFactorIndex === 0) {
68
- return new Float32Array(quantized.length)
67
+ return new Float64Array(quantized.length)
69
68
  }
70
69
 
71
70
  const scaleFactor = SCALE_FACTORS[scaleFactorIndex]
72
71
  const quantRange = (1 << (bitsPerSample - QUANTIZATION_SIGN_BIT_SHIFT)) - 1
73
- const denormFactor = scaleFactor / quantRange
74
72
 
75
- const deq = new Float32Array(quantized.length)
73
+ const deq = new Float64Array(quantized.length)
76
74
  for (let i = 0; i < quantized.length; i++) {
77
- deq[i] = quantized[i] * denormFactor
75
+ deq[i] = (quantized[i] * scaleFactor) / quantRange
78
76
  }
79
77
  return deq
80
78
  }
@@ -101,9 +99,9 @@ export function dequantize(quantized, scaleFactorIndex, bitsPerSample) {
101
99
  * - Long blocks (mode 0): Higher frequency resolution, fewer temporal segments
102
100
  * - Short blocks (mode 1): Lower frequency resolution, more temporal segments
103
101
  *
104
- * @param {Float32Array} coefficients
102
+ * @param {Float64Array} coefficients
105
103
  * @param {Array<number>} blockModes
106
- * @returns {{bfuData: Array<Float32Array>, bfuSizes: Array<number>, bfuCount: number}}
104
+ * @returns {{bfuData: Array<Float64Array>, bfuSizes: Array<number>, bfuCount: number}}
107
105
  */
108
106
  export function groupIntoBFUs(coefficients, blockModes) {
109
107
  const bfuData = []
@@ -123,7 +121,7 @@ export function groupIntoBFUs(coefficients, blockModes) {
123
121
  const size = SPECS_PER_BFU[bfuIndex]
124
122
  const startPos = startPositions[bfuIndex] - bandStart
125
123
  const endPos = startPos + size
126
- const bfu = new Float32Array(size)
124
+ const bfu = new Float64Array(size)
127
125
 
128
126
  if (startPos >= 0 && endPos <= bandSize) {
129
127
  bfu.set(coefficients.subarray(bandStart + startPos, bandStart + endPos))
@@ -2,91 +2,80 @@
2
2
  * Carta1 Audio Codec - Buffer Management
3
3
  */
4
4
 
5
- import {
6
- NUM_BFUS,
7
- MAX_BFU_SIZE,
8
- QMF_DELAY,
9
- QMF_HIGH_BAND_DELAY,
10
- } from './constants.js'
5
+ import { QMF_DELAY, QMF_HIGH_BAND_DELAY } from './constants.js'
11
6
 
12
7
  export class BufferPool {
13
8
  constructor() {
14
9
  // Transform buffers
15
10
  this.transformBuffers = {
16
- 64: new Float32Array(64),
17
- 128: new Float32Array(128),
18
- 256: new Float32Array(256),
19
- 512: new Float32Array(512),
11
+ 64: new Float64Array(64),
12
+ 128: new Float64Array(128),
13
+ 256: new Float64Array(256),
14
+ 512: new Float64Array(512),
20
15
  }
21
16
 
22
17
  // QMF work buffers
23
18
  this.qmfWorkBuffers = {
24
19
  delay: {
25
- 128: new Float32Array(QMF_DELAY + 128),
26
- 256: new Float32Array(QMF_DELAY + 256),
27
- 512: new Float32Array(QMF_DELAY + 512),
20
+ 128: new Float64Array(QMF_DELAY + 128),
21
+ 256: new Float64Array(QMF_DELAY + 256),
22
+ 512: new Float64Array(QMF_DELAY + 512),
28
23
  },
29
24
  highBandDelay: {
30
- 128: new Float32Array(QMF_HIGH_BAND_DELAY + 128),
31
- 256: new Float32Array(QMF_HIGH_BAND_DELAY + 256),
25
+ 128: new Float64Array(QMF_HIGH_BAND_DELAY + 128),
26
+ 256: new Float64Array(QMF_HIGH_BAND_DELAY + 256),
32
27
  },
33
28
  }
34
29
 
35
30
  // QMF delay lines
36
31
  this.qmfDelays = {
37
- lowBand: new Float32Array(QMF_DELAY),
38
- midBand: new Float32Array(QMF_DELAY),
39
- highBand: new Float32Array(QMF_HIGH_BAND_DELAY),
32
+ lowBand: new Float64Array(QMF_DELAY),
33
+ midBand: new Float64Array(QMF_DELAY),
34
+ highBand: new Float64Array(QMF_HIGH_BAND_DELAY),
40
35
  }
41
36
 
42
37
  // Transient detector
43
38
  this.transientDetection = [
44
- new Float32Array(64),
45
- new Float32Array(64),
46
- new Float32Array(128),
39
+ new Float64Array(64),
40
+ new Float64Array(64),
41
+ new Float64Array(128),
47
42
  ]
48
43
 
49
44
  // MDCT/IMDCT work buffers
50
45
  this.mdctBuffers = {
51
46
  16: {
52
- real: new Float32Array(16),
53
- imag: new Float32Array(16),
47
+ real: new Float64Array(16),
48
+ imag: new Float64Array(16),
54
49
  },
55
50
  64: {
56
- real: new Float32Array(64),
57
- imag: new Float32Array(64),
51
+ real: new Float64Array(64),
52
+ imag: new Float64Array(64),
58
53
  },
59
54
  128: {
60
- real: new Float32Array(128),
61
- imag: new Float32Array(128),
55
+ real: new Float64Array(128),
56
+ imag: new Float64Array(128),
62
57
  },
63
58
  }
64
59
 
65
- // MDCT overlap buffers (encoder)
60
+ // MDCT overlap buffers
66
61
  this.mdctOverlap = [
67
- new Float32Array(32),
68
- new Float32Array(32),
69
- new Float32Array(32),
62
+ new Float64Array(32),
63
+ new Float64Array(32),
64
+ new Float64Array(32),
70
65
  ]
71
66
 
72
- // IMDCT overlap buffers (decoder)
67
+ // IMDCT overlap buffers
73
68
  this.imdctOverlap = [
74
- new Float32Array(256),
75
- new Float32Array(256),
76
- new Float32Array(512),
69
+ new Float64Array(256),
70
+ new Float64Array(256),
71
+ new Float64Array(512),
77
72
  ]
78
73
 
79
74
  // Spectrum reversal buffers
80
75
  this.reversalBuffers = {
81
- 32: new Float32Array(32),
82
- 128: new Float32Array(128),
83
- 256: new Float32Array(256),
84
- }
85
-
86
- // Bit allocation buffers
87
- this.bfuData = new Array(NUM_BFUS)
88
- for (let i = 0; i < NUM_BFUS; i++) {
89
- this.bfuData[i] = new Float32Array(MAX_BFU_SIZE)
76
+ 32: new Float64Array(32),
77
+ 128: new Float64Array(128),
78
+ 256: new Float64Array(256),
90
79
  }
91
80
  }
92
81
  }