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.
Files changed (46) hide show
  1. package/bin/cli.js +8 -4
  2. package/codec/{coding/bitallocation.js → allocation/solve.js} +131 -97
  3. package/codec/allocation/source.js +69 -0
  4. package/codec/allocation/stage.js +38 -0
  5. package/codec/analysis/bands.js +68 -0
  6. package/codec/analysis/{transient.js → blocks.js} +90 -47
  7. package/codec/analysis/spectrum.js +160 -0
  8. package/codec/analysis/stage.js +32 -0
  9. package/codec/{browser/interface.js → boundary/browser.js} +1 -1
  10. package/codec/boundary/container.js +96 -0
  11. package/codec/boundary/pcm.js +193 -0
  12. package/codec/boundary/processor.js +208 -0
  13. package/codec/{io/readers.js → boundary/reader.js} +2 -1
  14. package/codec/boundary/stream.js +361 -0
  15. package/codec/{browser → boundary}/worker.js +45 -42
  16. package/codec/core/constants.js +19 -132
  17. package/codec/core/geometry.js +25 -0
  18. package/codec/core/tables.js +215 -0
  19. package/codec/dequantization.js +54 -0
  20. package/codec/index.js +12 -13
  21. package/codec/pipeline/decoder.js +10 -399
  22. package/codec/pipeline/encoder.js +12 -434
  23. package/codec/quantization/spectrum.js +67 -0
  24. package/codec/quantization/stage.js +49 -0
  25. package/codec/signal/fft.js +68 -0
  26. package/codec/{transforms → signal}/mdct.js +37 -65
  27. package/codec/signal/order.js +16 -0
  28. package/codec/signal/qmf.js +539 -0
  29. package/codec/state.js +112 -0
  30. package/codec/{io → syntax}/bitstream.js +27 -8
  31. package/codec/{io/serialization.js → syntax/frame.js} +5 -101
  32. package/codec/synthesis/bands.js +228 -0
  33. package/codec/synthesis/pcm.js +64 -0
  34. package/codec/synthesis/stage.js +17 -0
  35. package/codec/utils.js +9 -52
  36. package/dist/carta1-worker-interface.min.js.map +1 -1
  37. package/dist/carta1-worker.min.js +1 -1
  38. package/dist/carta1-worker.min.js.map +1 -1
  39. package/dist/carta1.min.js +1 -1
  40. package/dist/carta1.min.js.map +1 -1
  41. package/package.json +1 -1
  42. package/codec/coding/quantization.js +0 -149
  43. package/codec/core/buffers.js +0 -81
  44. package/codec/io/processor.js +0 -671
  45. package/codec/transforms/fft.js +0 -69
  46. package/codec/transforms/qmf.js +0 -105
@@ -1,23 +1,18 @@
1
1
  /**
2
- * Carta1 Audio Codec - Modified Discrete Cosine Transform
2
+ * Modified discrete cosine transforms backed by a complex FFT.
3
3
  *
4
- * This module implements forward and inverse MDCT transforms for the ATRAC1 codec.
5
- * The MDCT provides time-frequency analysis with perfect reconstruction and
6
- * 50% overlap between adjacent blocks to avoid blocking artifacts.
4
+ * The evaluation order is part of Carta1's numerical contract. The staged
5
+ * Float32 decomposition used by Carta5 is mathematically equivalent but does
6
+ * not preserve Carta1's encoded output or perceptual-quality floor.
7
7
  */
8
8
 
9
9
  import { FFT } from './fft.js'
10
- import {
11
- MDCT_SIZE_SHORT,
12
- MDCT_SIZE_MID,
13
- MDCT_SIZE_LONG,
14
- } from '../core/constants.js'
15
10
  import { throwError } from '../utils.js'
16
11
 
17
12
  /**
18
13
  * Base class for MDCT and IMDCT transforms
19
14
  */
20
- class MDCTBase {
15
+ class MdctBase {
21
16
  constructor(size, scale) {
22
17
  this.size = size
23
18
  this.halfSize = size >> 1
@@ -40,7 +35,7 @@ class MDCTBase {
40
35
  /**
41
36
  * Forward MDCT transform
42
37
  */
43
- export class MDCT extends MDCTBase {
38
+ export class MDCT extends MdctBase {
44
39
  constructor(size, scale) {
45
40
  super(size, scale)
46
41
  }
@@ -51,7 +46,12 @@ export class MDCT extends MDCTBase {
51
46
  * @param {Object} mdctBuffers - Optional work buffers for FFT
52
47
  * @returns {Float32Array} Frequency-domain MDCT coefficients
53
48
  */
54
- transform(input, mdctBuffers = null) {
49
+ transform(
50
+ input,
51
+ mdctBuffers = null,
52
+ destination = null,
53
+ destinationOffset = 0
54
+ ) {
55
55
  const buffers =
56
56
  mdctBuffers?.[this.fftSize] ??
57
57
  throwError(`MDCT.transform: mdctBuffers[${this.fftSize}] is required`)
@@ -61,9 +61,9 @@ export class MDCT extends MDCTBase {
61
61
  `MDCT.transform: mdctBuffers[${this.fftSize}].real is required`
62
62
  )
63
63
  const imag =
64
- buffers?.imag ??
64
+ buffers?.imaginary ??
65
65
  throwError(
66
- `MDCT.transform: mdctBuffers[${this.fftSize}].imag is required`
66
+ `MDCT.transform: mdctBuffers[${this.fftSize}].imaginary is required`
67
67
  )
68
68
 
69
69
  const n4 = this.quarterSize
@@ -104,18 +104,18 @@ export class MDCT extends MDCTBase {
104
104
  imag[idx] = im * c - r * s
105
105
  }
106
106
 
107
- FFT.fft(real, imag)
107
+ FFT.transform(real, imag)
108
108
 
109
109
  // Post-FFT processing
110
- const output = new Float32Array(this.halfSize)
110
+ const output = destination ?? new Float32Array(this.halfSize)
111
111
  for (let i = 0; i < this.fftSize; i++) {
112
112
  const c = this.sinCosTable[i * 2]
113
113
  const s = this.sinCosTable[i * 2 + 1]
114
114
  const re = real[i]
115
115
  const im = imag[i]
116
116
 
117
- output[i * 2] = -re * c - im * s
118
- output[this.halfSize - 1 - i * 2] = -re * s + im * c
117
+ output[destinationOffset + i * 2] = -re * c - im * s
118
+ output[destinationOffset + this.halfSize - 1 - i * 2] = -re * s + im * c
119
119
  }
120
120
 
121
121
  return output
@@ -125,7 +125,7 @@ export class MDCT extends MDCTBase {
125
125
  /**
126
126
  * Inverse MDCT transform
127
127
  */
128
- export class IMDCT extends MDCTBase {
128
+ export class IMDCT extends MdctBase {
129
129
  constructor(size, scale = null) {
130
130
  super(size, scale || size)
131
131
  }
@@ -136,7 +136,12 @@ export class IMDCT extends MDCTBase {
136
136
  * @param {Object} mdctBuffers - Optional work buffers for FFT
137
137
  * @returns {Float32Array} Time-domain output samples
138
138
  */
139
- transform(input, mdctBuffers = null) {
139
+ transform(
140
+ input,
141
+ mdctBuffers = null,
142
+ destination = null,
143
+ destinationOffset = 0
144
+ ) {
140
145
  const buffers =
141
146
  mdctBuffers?.[this.fftSize] ??
142
147
  throwError(`IMDCT.transform: mdctBuffers[${this.fftSize}] is required`)
@@ -146,9 +151,9 @@ export class IMDCT extends MDCTBase {
146
151
  `IMDCT.transform: mdctBuffers[${this.fftSize}].real is required`
147
152
  )
148
153
  const imag =
149
- buffers?.imag ??
154
+ buffers?.imaginary ??
150
155
  throwError(
151
- `IMDCT.transform: mdctBuffers[${this.fftSize}].imag is required`
156
+ `IMDCT.transform: mdctBuffers[${this.fftSize}].imaginary is required`
152
157
  )
153
158
 
154
159
  const n4 = this.quarterSize
@@ -169,10 +174,10 @@ export class IMDCT extends MDCTBase {
169
174
  imag[i] = im * c - r * s
170
175
  }
171
176
 
172
- FFT.fft(real, imag)
177
+ FFT.transform(real, imag)
173
178
 
174
179
  // Post-FFT butterfly
175
- const output = new Float32Array(this.size)
180
+ const output = destination ?? new Float32Array(this.size)
176
181
 
177
182
  for (let i = 0; i < this.fftSize / 2; i++) {
178
183
  const i2 = i * 2
@@ -184,10 +189,10 @@ export class IMDCT extends MDCTBase {
184
189
  const r1 = re * c + im * s
185
190
  const i1 = re * s - im * c
186
191
 
187
- output[n34 - 1 - i2] = r1
188
- output[n34 + i2] = r1
189
- output[n4 + i2] = i1
190
- output[n4 - 1 - i2] = -i1
192
+ output[destinationOffset + n34 - 1 - i2] = r1
193
+ output[destinationOffset + n34 + i2] = r1
194
+ output[destinationOffset + n4 + i2] = i1
195
+ output[destinationOffset + n4 - 1 - i2] = -i1
191
196
  }
192
197
 
193
198
  for (let i = this.fftSize / 2; i < this.fftSize; i++) {
@@ -201,45 +206,12 @@ export class IMDCT extends MDCTBase {
201
206
  const r1 = re * c + im * s
202
207
  const i1 = re * s - im * c
203
208
 
204
- output[n34 - 1 - idx] = r1
205
- output[idx - n4] = -r1
206
- output[n4 + idx] = i1
207
- output[5 * n4 - 1 - idx] = i1
209
+ output[destinationOffset + n34 - 1 - idx] = r1
210
+ output[destinationOffset + idx - n4] = -r1
211
+ output[destinationOffset + n4 + idx] = i1
212
+ output[destinationOffset + 5 * n4 - 1 - idx] = i1
208
213
  }
209
214
 
210
215
  return output
211
216
  }
212
217
  }
213
-
214
- // Pre-instantiated transforms
215
- export const mdct64 = new MDCT(MDCT_SIZE_SHORT, 0.5)
216
- export const mdct256 = new MDCT(MDCT_SIZE_MID, 0.5)
217
- export const mdct512 = new MDCT(MDCT_SIZE_LONG, 1.0)
218
-
219
- export const imdct64 = new IMDCT(MDCT_SIZE_SHORT, MDCT_SIZE_SHORT * 8)
220
- export const imdct256 = new IMDCT(MDCT_SIZE_MID, MDCT_SIZE_MID * 8)
221
- export const imdct512 = new IMDCT(MDCT_SIZE_LONG, MDCT_SIZE_LONG * 4)
222
-
223
- /**
224
- * Perform overlap-add operation for MDCT reconstruction
225
- * @param {Float32Array} prev - Previous block samples
226
- * @param {Float32Array} curr - Current block samples
227
- * @param {Float32Array} window - Window function coefficients
228
- * @returns {Float32Array} Overlap-added output samples
229
- */
230
- export function overlapAdd(prev, curr, window) {
231
- const size = prev.length
232
- const output = new Float32Array(size * 2)
233
-
234
- for (let i = 0; i < size; i++) {
235
- const w1 = window[i]
236
- const w2 = window[2 * size - 1 - i]
237
- const p = prev[i]
238
- const c = curr[size - 1 - i]
239
-
240
- output[i] = p * w2 - c * w1
241
- output[2 * size - 1 - i] = p * w1 + c * w2
242
- }
243
-
244
- return output
245
- }
@@ -0,0 +1,16 @@
1
+ /** ATRAC1 spectral ordering. */
2
+
3
+ /**
4
+ * Reverse spectral order for ATRAC1 mid and high bands.
5
+ *
6
+ * @param {Float32Array} spectrum Spectrum in transform order.
7
+ * @param {object} reversalBuffers Reusable outputs indexed by spectrum length.
8
+ * @returns {Float32Array} Reversed spectrum.
9
+ */
10
+ export function reverseSpectrum(spectrum, reversalBuffers) {
11
+ const reversed = reversalBuffers[spectrum.length]
12
+ for (let index = 0; index < spectrum.length; index++) {
13
+ reversed[index] = spectrum[spectrum.length - 1 - index]
14
+ }
15
+ return reversed
16
+ }