carta1 1.1.9 → 1.2.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 (44) hide show
  1. package/README.md +149 -75
  2. package/bin/cli.js +8 -4
  3. package/codec/{coding/bitallocation.js → allocation/solve.js} +131 -97
  4. package/codec/allocation/source.js +69 -0
  5. package/codec/allocation/stage.js +38 -0
  6. package/codec/analysis/bands.js +49 -0
  7. package/codec/analysis/{transient.js → blocks.js} +90 -47
  8. package/codec/analysis/spectrum.js +160 -0
  9. package/codec/analysis/stage.js +32 -0
  10. package/codec/{browser/interface.js → boundary/browser.js} +1 -1
  11. package/codec/boundary/container.js +96 -0
  12. package/codec/boundary/pcm.js +193 -0
  13. package/codec/boundary/processor.js +208 -0
  14. package/codec/{io/readers.js → boundary/reader.js} +2 -1
  15. package/codec/boundary/stream.js +361 -0
  16. package/codec/{browser → boundary}/worker.js +45 -42
  17. package/codec/core/constants.js +9 -131
  18. package/codec/core/geometry.js +25 -0
  19. package/codec/core/tables.js +117 -0
  20. package/codec/dequantization.js +54 -0
  21. package/codec/index.js +12 -11
  22. package/codec/pipeline/decoder.js +10 -399
  23. package/codec/pipeline/encoder.js +12 -434
  24. package/codec/quantization/spectrum.js +67 -0
  25. package/codec/quantization/stage.js +45 -0
  26. package/codec/{transforms/qmf.js → signal/bands.js} +8 -5
  27. package/codec/{transforms → signal}/fft.js +1 -1
  28. package/codec/{transforms/mdct.js → signal/spectrum.js} +16 -1
  29. package/codec/{core/buffers.js → state.js} +46 -35
  30. package/codec/{io → syntax}/bitstream.js +28 -9
  31. package/codec/{io/serialization.js → syntax/frame.js} +5 -101
  32. package/codec/synthesis/bands.js +201 -0
  33. package/codec/synthesis/pcm.js +50 -0
  34. package/codec/synthesis/stage.js +17 -0
  35. package/codec/utils.js +9 -52
  36. package/dist/carta1-worker-interface.min.js +1 -1
  37. package/dist/carta1-worker-interface.min.js.map +1 -1
  38. package/dist/carta1-worker.min.js +1 -1
  39. package/dist/carta1-worker.min.js.map +1 -1
  40. package/dist/carta1.min.js +1 -1
  41. package/dist/carta1.min.js.map +1 -1
  42. package/package.json +16 -16
  43. package/codec/coding/quantization.js +0 -149
  44. package/codec/io/processor.js +0 -558
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "carta1",
3
- "version": "1.1.9",
4
- "description": "An ATRAC1 audio codec implementation in JS",
3
+ "version": "1.2.0",
4
+ "description": "An ATRAC1 audio codec implementation in JavaScript",
5
5
  "type": "module",
6
6
  "main": "codec/index.js",
7
7
  "bin": {
@@ -22,12 +22,12 @@
22
22
  "lint": "eslint bin/ codec/ tests/",
23
23
  "format": "prettier --write .",
24
24
  "build": "webpack --config webpack.config.js",
25
- "prepublishOnly": "npm run lint && npm run test && npm run build"
25
+ "check": "npm run lint && npm test && npm run build",
26
+ "prepublishOnly": "npm run check"
26
27
  },
27
28
  "dependencies": {
28
29
  "cli-progress": "^3.12.0",
29
- "colors": "^1.4.0",
30
- "commander": "^11.0.0",
30
+ "commander": "^11.1.0",
31
31
  "wav": "^1.0.2"
32
32
  },
33
33
  "engines": {
@@ -54,18 +54,18 @@
54
54
  },
55
55
  "homepage": "https://github.com/aynik/carta1#readme",
56
56
  "devDependencies": {
57
- "@babel/core": "^7.27.7",
58
- "@babel/preset-env": "^7.27.2",
59
- "babel-loader": "^10.0.0",
60
- "eslint": "^9.30.0",
61
- "eslint-config-prettier": "^10.1.5",
62
- "eslint-plugin-prettier": "^5.5.1",
57
+ "@babel/core": "^7.29.7",
58
+ "@babel/preset-env": "^7.29.7",
59
+ "babel-loader": "^10.1.1",
60
+ "eslint": "^9.39.5",
61
+ "eslint-config-prettier": "^10.1.8",
62
+ "eslint-plugin-prettier": "^5.5.6",
63
63
  "husky": "^9.1.7",
64
- "lint-staged": "^16.1.2",
65
- "prettier": "^3.6.2",
66
- "terser-webpack-plugin": "^5.3.14",
67
- "vitest": "^3.2.4",
68
- "webpack": "^5.99.9",
64
+ "lint-staged": "^16.4.0",
65
+ "prettier": "^3.9.6",
66
+ "terser-webpack-plugin": "^5.6.1",
67
+ "vitest": "^3.2.7",
68
+ "webpack": "^5.109.2",
69
69
  "webpack-cli": "^6.0.1"
70
70
  },
71
71
  "lint-staged": {
@@ -1,149 +0,0 @@
1
- /**
2
- * Carta1 Audio Codec - Quantization Module
3
- *
4
- * This module handles the quantization and dequantization of MDCT frequency coefficients
5
- * for the Carta1 audio codec. It provides functions to convert floating-point frequency
6
- * domain data into integer representations suitable for bitstream encoding.
7
- *
8
- * Key functions:
9
- * - Quantization of coefficients using scale factors and bit depths
10
- * - Dequantization for reconstruction during decoding
11
- * - BFU (Band Frequency Unit) organization for psychoacoustic processing
12
- *
13
- * The quantization process uses configurable scale factors to maintain audio quality
14
- * while achieving the target compression ratio. The module supports both uniform
15
- * and non-uniform quantization schemes based on perceptual importance.
16
- */
17
-
18
- import {
19
- SPECS_PER_BFU,
20
- BFU_START_LONG,
21
- BFU_START_SHORT,
22
- BFU_BAND_BOUNDARIES,
23
- SCALE_FACTORS,
24
- QUANTIZATION_SIGN_BIT_SHIFT,
25
- } from '../core/constants.js'
26
-
27
- /**
28
- * Quantize coefficients.
29
- * @param {Float32Array} coefficients
30
- * @param {number} scaleFactorIndex
31
- * @param {number} bitsPerSample
32
- * @returns {Int32Array} out
33
- */
34
- export function quantize(coefficients, scaleFactorIndex, bitsPerSample) {
35
- const length = coefficients.length
36
- const out = new Int32Array(length)
37
- if (bitsPerSample === 0 || scaleFactorIndex === 0) {
38
- out.fill(0, 0, length)
39
- return out
40
- }
41
-
42
- const scaleFactor = SCALE_FACTORS[scaleFactorIndex]
43
- const quantRange = (1 << (bitsPerSample - QUANTIZATION_SIGN_BIT_SHIFT)) - 1
44
- const normFactor = quantRange / scaleFactor
45
-
46
- const hi = quantRange
47
- const lo = -quantRange
48
-
49
- for (let i = 0; i < length; i++) {
50
- const x = coefficients[i] * normFactor
51
- const y = (x + (x >= 0 ? 0.5 : -0.5)) | 0
52
- out[i] = y > hi ? hi : y < lo ? lo : y
53
- }
54
-
55
- return out
56
- }
57
-
58
- /**
59
- * Dequantize coefficients.
60
- * @param {Int32Array} quantized
61
- * @param {number} scaleFactorIndex
62
- * @param {number} bitsPerSample
63
- * @returns {Float32Array}
64
- */
65
- export function dequantize(quantized, scaleFactorIndex, bitsPerSample) {
66
- if (bitsPerSample === 0 || scaleFactorIndex === 0) {
67
- return new Float32Array(quantized.length)
68
- }
69
-
70
- const scaleFactor = SCALE_FACTORS[scaleFactorIndex]
71
- const quantRange = (1 << (bitsPerSample - QUANTIZATION_SIGN_BIT_SHIFT)) - 1
72
-
73
- const deq = new Float32Array(quantized.length)
74
- for (let i = 0; i < quantized.length; i++) {
75
- deq[i] = (quantized[i] * scaleFactor) / quantRange
76
- }
77
- return deq
78
- }
79
-
80
- /**
81
- * Groups MDCT coefficients into Band Frequency Units (BFUs) for bit allocation.
82
- *
83
- * This function organizes frequency-domain coefficients into perceptually meaningful
84
- * frequency bands (BFUs) based on the block modes for each of the three frequency bands.
85
- * It handles both long and short blocks, with different frequency resolutions and
86
- * BFU start positions for each block type.
87
- *
88
- * The function implements copy-avoidance optimization: when a BFU slice is fully
89
- * contained within a frequency band, it directly copies the data without buffer
90
- * filling. For BFUs that span band boundaries or extend beyond the available
91
- * coefficients, it handles partial copying and zero-padding appropriately.
92
- *
93
- * Frequency Band Structure:
94
- * - Band 0: 0-128 coefficients (low frequencies)
95
- * - Band 1: 128-256 coefficients (mid frequencies)
96
- * - Band 2: 256-512 coefficients (high frequencies)
97
- *
98
- * Block Types:
99
- * - Long blocks (mode 0): Higher frequency resolution, fewer temporal segments
100
- * - Short blocks (mode 1): Lower frequency resolution, more temporal segments
101
- *
102
- * @param {Float32Array} coefficients
103
- * @param {Array<number>} blockModes
104
- * @returns {{bfuData: Array<Float32Array>, bfuSizes: Array<number>, bfuCount: number}}
105
- */
106
- export function groupIntoBFUs(coefficients, blockModes) {
107
- const bfuData = []
108
- const bfuSizes = []
109
-
110
- let coeffIndex = 0
111
- let bfuIndex = 0
112
-
113
- for (let band = 0; band < 3; band++) {
114
- const bandStart = coeffIndex
115
- const bandSize = band === 2 ? 256 : 128
116
- const bandEnd = band < 2 ? BFU_BAND_BOUNDARIES[band] : SPECS_PER_BFU.length
117
- const isLongBlock = blockModes[band] === 0
118
- const startPositions = isLongBlock ? BFU_START_LONG : BFU_START_SHORT
119
-
120
- while (bfuIndex < bandEnd) {
121
- const size = SPECS_PER_BFU[bfuIndex]
122
- const startPos = startPositions[bfuIndex] - bandStart
123
- const endPos = startPos + size
124
- const bfu = new Float32Array(size)
125
-
126
- if (startPos >= 0 && endPos <= bandSize) {
127
- bfu.set(coefficients.subarray(bandStart + startPos, bandStart + endPos))
128
- } else {
129
- bfu.fill(0)
130
- if (startPos < bandSize && endPos > 0) {
131
- const srcStart = Math.max(0, startPos)
132
- const srcEnd = Math.min(bandSize, endPos)
133
- bfu.set(
134
- coefficients.subarray(bandStart + srcStart, bandStart + srcEnd),
135
- Math.max(0, -startPos)
136
- )
137
- }
138
- }
139
-
140
- bfuData.push(bfu)
141
- bfuSizes.push(size)
142
- bfuIndex++
143
- }
144
-
145
- coeffIndex += bandSize
146
- }
147
-
148
- return { bfuData, bfuSizes, bfuCount: bfuIndex }
149
- }