cridecoder 0.1.2__tar.gz → 0.2.1__tar.gz
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.
- cridecoder-0.2.1/.github/copilot-instructions.md +105 -0
- cridecoder-0.2.1/.github/dependabot.yml +31 -0
- cridecoder-0.2.1/.github/workflows/ci.yml +46 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/.github/workflows/release-crate.yml +1 -1
- {cridecoder-0.1.2 → cridecoder-0.2.1}/.github/workflows/release-python.yml +9 -9
- cridecoder-0.2.1/AGENTS.md +128 -0
- cridecoder-0.2.1/CLAUDE.md +6 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/Cargo.lock +1 -1
- {cridecoder-0.1.2 → cridecoder-0.2.1}/Cargo.toml +8 -8
- {cridecoder-0.1.2 → cridecoder-0.2.1}/PKG-INFO +60 -11
- cridecoder-0.2.1/README.md +137 -0
- cridecoder-0.2.1/cridecoder.pyi +114 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/pyproject.toml +2 -1
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/acb/afs.rs +4 -1
- cridecoder-0.2.1/src/acb/builder.rs +1984 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/acb/consts.rs +45 -6
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/acb/extractor.rs +64 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/acb.rs +5 -1
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/hca/bitreader.rs +4 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/hca/cipher.rs +2 -2
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/hca/decoder.rs +3 -2
- cridecoder-0.2.1/src/hca/encoder.rs +1336 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/hca/hca_file.rs +1 -1
- cridecoder-0.2.1/src/hca.rs +16 -0
- cridecoder-0.2.1/src/lib.rs +37 -0
- cridecoder-0.2.1/src/python.rs +603 -0
- cridecoder-0.2.1/src/usm/builder.rs +593 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/usm/extractor.rs +65 -6
- cridecoder-0.2.1/src/usm.rs +16 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/tests/integration_tests.rs +370 -3
- cridecoder-0.2.1/tests/test_python.py +332 -0
- cridecoder-0.1.2/.github/copilot-Instructions.md +0 -51
- cridecoder-0.1.2/.github/workflows/ci.yml +0 -32
- cridecoder-0.1.2/AGENTS.md +0 -74
- cridecoder-0.1.2/README.md +0 -88
- cridecoder-0.1.2/src/hca.rs +0 -12
- cridecoder-0.1.2/src/lib.rs +0 -27
- cridecoder-0.1.2/src/python.rs +0 -152
- cridecoder-0.1.2/src/usm.rs +0 -12
- {cridecoder-0.1.2 → cridecoder-0.2.1}/.gitignore +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/LICENSE +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/examples/debug_acb.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/examples/test_acb.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/examples/test_hca.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/examples/test_usm.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/acb/track.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/acb/utf.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/hca/ath.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/hca/imdct.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/hca/tables.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/reader.rs +0 -0
- {cridecoder-0.1.2 → cridecoder-0.2.1}/src/usm/metadata.rs +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Copilot Instructions for cridecoder
|
|
2
|
+
|
|
3
|
+
## Project Context
|
|
4
|
+
|
|
5
|
+
This is a pure Rust library (`cridecoder`) for decoding CRI Middleware audio/video formats (ACB, HCA, USM). The CRI format implementation is based on [vgmstream](https://github.com/vgmstream/vgmstream). It also provides optional Python bindings via pyo3/maturin.
|
|
6
|
+
|
|
7
|
+
## Code Style
|
|
8
|
+
|
|
9
|
+
- **Rust edition**: 2021
|
|
10
|
+
- **Error handling**: Use `thiserror` derive macros for error enums
|
|
11
|
+
- **Binary I/O**: Use the `reader.rs` wrapper around `byteorder` for all binary reading
|
|
12
|
+
- **Text encoding**: CRI formats use Shift-JIS; use `encoding_rs::SHIFT_JIS` for decoding
|
|
13
|
+
- **Module structure**: Use Rust 2018+ flat module style (`src/acb.rs` + `src/acb/` directory), not `mod.rs`
|
|
14
|
+
- **Feature gates**: Python bindings use `#[cfg(feature = "python")]` — pure Rust builds should not depend on pyo3
|
|
15
|
+
- **Tests**: Unit tests are inline `#[cfg(test)] mod tests`, integration tests are in `tests/`
|
|
16
|
+
|
|
17
|
+
## Important Notes
|
|
18
|
+
|
|
19
|
+
- The `ClHca` struct (HCA decoder state) is very large (~200KB on stack). Use `RUST_MIN_STACK=16777216` when running integration tests
|
|
20
|
+
- ACB files may contain embedded AWB data or reference external `.awb` files
|
|
21
|
+
- HCA files support encryption — use `HcaDecoder::set_key()` or `KeyTest` for key testing
|
|
22
|
+
- USM files contain interleaved video (M2V) and audio (ADX) chunks with XOR masking
|
|
23
|
+
|
|
24
|
+
## Public API
|
|
25
|
+
|
|
26
|
+
```rust
|
|
27
|
+
// ACB
|
|
28
|
+
pub fn extract_acb_from_file(path, output_dir) -> Result<Option<Vec<String>>>
|
|
29
|
+
pub fn extract_acb(reader, output_dir, awb_reader) -> Result<Vec<String>>
|
|
30
|
+
|
|
31
|
+
// HCA
|
|
32
|
+
pub struct HcaDecoder { ... }
|
|
33
|
+
impl HcaDecoder {
|
|
34
|
+
pub fn from_file(path) -> Result<Self>
|
|
35
|
+
pub fn from_reader(reader) -> Result<Self>
|
|
36
|
+
pub fn info(&self) -> &HcaInfo
|
|
37
|
+
pub fn decode_to_wav(&mut self, writer) -> Result<()>
|
|
38
|
+
pub fn decode_all(&mut self) -> Result<Vec<f32>>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// USM
|
|
42
|
+
pub fn extract_usm_file(path, output_dir, key, export_audio) -> Result<Vec<PathBuf>>
|
|
43
|
+
pub fn extract_usm(reader, output_dir, name, key, export_audio) -> Result<Vec<PathBuf>>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Testing
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cargo test # Unit tests only
|
|
50
|
+
RUST_MIN_STACK=16777216 cargo test # Full test suite (needs test fixture files)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Git commits
|
|
54
|
+
|
|
55
|
+
All commit subjects must follow:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
[Type] Short description starting with capital letter
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Allowed types:
|
|
62
|
+
|
|
63
|
+
| Type | Usage |
|
|
64
|
+
|-----------|-------------------------------------------------------|
|
|
65
|
+
| `[Feat]` | New feature or capability |
|
|
66
|
+
| `[Fix]` | Bug fix |
|
|
67
|
+
| `[Chore]` | Maintenance, refactoring, dependency or build changes |
|
|
68
|
+
| `[Docs]` | Documentation-only changes |
|
|
69
|
+
|
|
70
|
+
Rules:
|
|
71
|
+
|
|
72
|
+
- Description starts with a capital letter.
|
|
73
|
+
- Use imperative mood: `Add ...`, not `Added ...`.
|
|
74
|
+
- No trailing period.
|
|
75
|
+
- Keep the subject at or below roughly 70 characters.
|
|
76
|
+
- **Agent attribution uses the standard Git `Co-authored-by:` trailer in the commit body, not a free-form `Agent:` line.** This makes GitHub render the co-author avatar on the commit page. The trailer must be on its own line, separated from the subject by a blank line, in the form `Co-authored-by: <Display Name> <email>`. Suggested values per agent:
|
|
77
|
+
- Claude (any 4.x): `Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>` (substitute the actual model, e.g. `Claude Sonnet 4.6`, `Claude Haiku 4.5`)
|
|
78
|
+
- Codex: `Co-authored-by: Codex <noreply@openai.com>`
|
|
79
|
+
- Copilot: `Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>`
|
|
80
|
+
|
|
81
|
+
Examples from this repo's history:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
[Feat] Add encoding Python bindings
|
|
85
|
+
[Fix] Resolve check and clippy warnings
|
|
86
|
+
[Chore] Configure Dependabot updates
|
|
87
|
+
[Feat] Add encoding support but not tested in game
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## GitHub Actions workflows
|
|
91
|
+
|
|
92
|
+
Use the standardized workflow layout in `.github/workflows`:
|
|
93
|
+
|
|
94
|
+
- `ci.yml` runs on `main` pushes, pull requests targeting `main`, and manual dispatch.
|
|
95
|
+
- Rust CI order: `cargo fmt --all -- --check`, `cargo check --locked --all-targets`, `cargo clippy --locked --all-targets -- -D warnings`, then `cargo test --locked`.
|
|
96
|
+
- `release-crate.yml` publishes the Rust crate and keeps its package-specific release flow.
|
|
97
|
+
- `release-python.yml` builds and publishes Python artifacts and keeps its package-specific release flow.
|
|
98
|
+
|
|
99
|
+
Workflow maintenance rules:
|
|
100
|
+
|
|
101
|
+
- Keep workflow filenames and top-level names aligned: `CI`, `Release`, `Docker`, and optional package-specific names.
|
|
102
|
+
- Use `actions/checkout@v6`, `actions/setup-go@v6`, `actions/upload-artifact@v7`, `actions/download-artifact@v8`, `softprops/action-gh-release@v3`, and current Docker actions (`setup-buildx@v4`, `login@v4`, `metadata@v6`, `build-push@v7`).
|
|
103
|
+
- Keep `permissions` minimal: `contents: read` for CI/Docker build-only work, `contents: write` for release publishing, and `packages: write` only when pushing container images.
|
|
104
|
+
- Use workflow `concurrency` keyed by workflow name and ref, with release jobs using `release-${{ github.ref_name }}` and `cancel-in-progress: false`.
|
|
105
|
+
- Do not reintroduce legacy workflow names such as `rust-ci.yml`, `build.yml`, `release-build.yml`, `docker-build.yml`, or `docker-release.yml` unless a package-specific workflow already exists and is intentionally preserved.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "cargo"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
day: "monday"
|
|
8
|
+
time: "09:00"
|
|
9
|
+
timezone: "Asia/Shanghai"
|
|
10
|
+
commit-message:
|
|
11
|
+
prefix: "[Chore] "
|
|
12
|
+
|
|
13
|
+
- package-ecosystem: "uv"
|
|
14
|
+
directory: "/"
|
|
15
|
+
schedule:
|
|
16
|
+
interval: "weekly"
|
|
17
|
+
day: "monday"
|
|
18
|
+
time: "09:00"
|
|
19
|
+
timezone: "Asia/Shanghai"
|
|
20
|
+
commit-message:
|
|
21
|
+
prefix: "[Chore] "
|
|
22
|
+
|
|
23
|
+
- package-ecosystem: "github-actions"
|
|
24
|
+
directory: "/"
|
|
25
|
+
schedule:
|
|
26
|
+
interval: "weekly"
|
|
27
|
+
day: "monday"
|
|
28
|
+
time: "09:00"
|
|
29
|
+
timezone: "Asia/Shanghai"
|
|
30
|
+
commit-message:
|
|
31
|
+
prefix: "[Chore] "
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
env:
|
|
18
|
+
CARGO_TERM_COLOR: always
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
rust:
|
|
22
|
+
name: Rust checks
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout
|
|
26
|
+
uses: actions/checkout@v6
|
|
27
|
+
|
|
28
|
+
- name: Install Rust stable
|
|
29
|
+
uses: dtolnay/rust-toolchain@stable
|
|
30
|
+
with:
|
|
31
|
+
components: rustfmt, clippy
|
|
32
|
+
|
|
33
|
+
- name: Cache Rust artifacts
|
|
34
|
+
uses: Swatinem/rust-cache@v2
|
|
35
|
+
|
|
36
|
+
- name: Check formatting
|
|
37
|
+
run: cargo fmt --all -- --check
|
|
38
|
+
|
|
39
|
+
- name: Check build
|
|
40
|
+
run: cargo check --locked --all-targets
|
|
41
|
+
|
|
42
|
+
- name: Run Clippy
|
|
43
|
+
run: cargo clippy --locked --all-targets -- -D warnings
|
|
44
|
+
|
|
45
|
+
- name: Run tests
|
|
46
|
+
run: cargo test --locked
|
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
matrix:
|
|
23
23
|
target: [x86_64, aarch64]
|
|
24
24
|
steps:
|
|
25
|
-
- uses: actions/checkout@
|
|
25
|
+
- uses: actions/checkout@v6
|
|
26
26
|
- name: Set version from tag
|
|
27
27
|
if: github.event_name == 'release'
|
|
28
28
|
run: |
|
|
@@ -37,7 +37,7 @@ jobs:
|
|
|
37
37
|
sccache: "true"
|
|
38
38
|
manylinux: auto
|
|
39
39
|
- name: Upload wheels
|
|
40
|
-
uses: actions/upload-artifact@
|
|
40
|
+
uses: actions/upload-artifact@v7
|
|
41
41
|
with:
|
|
42
42
|
name: wheels-linux-${{ matrix.target }}
|
|
43
43
|
path: dist
|
|
@@ -51,7 +51,7 @@ jobs:
|
|
|
51
51
|
matrix:
|
|
52
52
|
target: [x86_64, aarch64]
|
|
53
53
|
steps:
|
|
54
|
-
- uses: actions/checkout@
|
|
54
|
+
- uses: actions/checkout@v6
|
|
55
55
|
- name: Set version from tag
|
|
56
56
|
if: github.event_name == 'release'
|
|
57
57
|
run: |
|
|
@@ -76,7 +76,7 @@ jobs:
|
|
|
76
76
|
args: --release --out dist --find-interpreter
|
|
77
77
|
sccache: "true"
|
|
78
78
|
- name: Upload wheels
|
|
79
|
-
uses: actions/upload-artifact@
|
|
79
|
+
uses: actions/upload-artifact@v7
|
|
80
80
|
with:
|
|
81
81
|
name: wheels-macos-${{ matrix.target }}
|
|
82
82
|
path: dist
|
|
@@ -87,7 +87,7 @@ jobs:
|
|
|
87
87
|
windows:
|
|
88
88
|
runs-on: windows-latest
|
|
89
89
|
steps:
|
|
90
|
-
- uses: actions/checkout@
|
|
90
|
+
- uses: actions/checkout@v6
|
|
91
91
|
- name: Set version from tag
|
|
92
92
|
if: github.event_name == 'release'
|
|
93
93
|
shell: bash
|
|
@@ -113,7 +113,7 @@ jobs:
|
|
|
113
113
|
args: --release --out dist --find-interpreter
|
|
114
114
|
sccache: "true"
|
|
115
115
|
- name: Upload wheels
|
|
116
|
-
uses: actions/upload-artifact@
|
|
116
|
+
uses: actions/upload-artifact@v7
|
|
117
117
|
with:
|
|
118
118
|
name: wheels-windows-x64
|
|
119
119
|
path: dist
|
|
@@ -124,7 +124,7 @@ jobs:
|
|
|
124
124
|
sdist:
|
|
125
125
|
runs-on: ubuntu-latest
|
|
126
126
|
steps:
|
|
127
|
-
- uses: actions/checkout@
|
|
127
|
+
- uses: actions/checkout@v6
|
|
128
128
|
- name: Set version from tag
|
|
129
129
|
if: github.event_name == 'release'
|
|
130
130
|
run: |
|
|
@@ -137,7 +137,7 @@ jobs:
|
|
|
137
137
|
command: sdist
|
|
138
138
|
args: --out dist
|
|
139
139
|
- name: Upload sdist
|
|
140
|
-
uses: actions/upload-artifact@
|
|
140
|
+
uses: actions/upload-artifact@v7
|
|
141
141
|
with:
|
|
142
142
|
name: wheels-sdist
|
|
143
143
|
path: dist
|
|
@@ -156,7 +156,7 @@ jobs:
|
|
|
156
156
|
permissions:
|
|
157
157
|
id-token: write
|
|
158
158
|
steps:
|
|
159
|
-
- uses: actions/download-artifact@
|
|
159
|
+
- uses: actions/download-artifact@v8
|
|
160
160
|
with:
|
|
161
161
|
pattern: wheels-*
|
|
162
162
|
merge-multiple: true
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
**cridecoder** is a pure Rust library for decoding CRI Middleware formats, with optional Python bindings via pyo3/maturin.
|
|
6
|
+
|
|
7
|
+
### Credits
|
|
8
|
+
|
|
9
|
+
CRI format implementation is based on [vgmstream](https://github.com/vgmstream/vgmstream).
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
src/
|
|
15
|
+
├── lib.rs # Crate root, re-exports public API, #[pymodule] (behind "python" feature)
|
|
16
|
+
├── reader.rs # Binary reader utilities (endianness, primitive types, alignment)
|
|
17
|
+
├── acb.rs # ACB module root (re-exports submodules)
|
|
18
|
+
├── acb/
|
|
19
|
+
│ ├── consts.rs # ACB/UTF constants and helpers
|
|
20
|
+
│ ├── utf.rs # CRI UTF table parser
|
|
21
|
+
│ ├── afs.rs # AFS2 archive parser
|
|
22
|
+
│ ├── track.rs # Track list extraction from ACB
|
|
23
|
+
│ └── extractor.rs # ACB extraction logic
|
|
24
|
+
├── hca.rs # HCA module root (re-exports submodules)
|
|
25
|
+
├── hca/
|
|
26
|
+
│ ├── decoder.rs # Core HCA decoder (ClHca, header parsing, block decoding)
|
|
27
|
+
│ ├── hca_file.rs # High-level HcaDecoder with streaming, WAV output, key testing
|
|
28
|
+
│ ├── tables.rs # Lookup tables for HCA decoding
|
|
29
|
+
│ ├── cipher.rs # HCA encryption/decryption cipher
|
|
30
|
+
│ ├── ath.rs # ATH (Absolute Threshold of Hearing) tables
|
|
31
|
+
│ ├── bitreader.rs # Bit-level reader/writer
|
|
32
|
+
│ └── imdct.rs # Inverse MDCT transform
|
|
33
|
+
├── usm.rs # USM module root (re-exports submodules)
|
|
34
|
+
├── usm/
|
|
35
|
+
│ ├── extractor.rs # USM extraction (video/audio stream demuxing)
|
|
36
|
+
│ └── metadata.rs # USM metadata reading and JSON export
|
|
37
|
+
└── python.rs # Python bindings (behind "python" feature)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Key Types
|
|
41
|
+
|
|
42
|
+
- `extract_acb_from_file()` / `extract_acb()` — ACB extraction entry points
|
|
43
|
+
- `HcaDecoder` — High-level HCA to WAV/PCM decoder
|
|
44
|
+
- `extract_usm_file()` / `extract_usm()` — USM extraction entry points
|
|
45
|
+
- `ClHca` — Low-level HCA decoder state machine
|
|
46
|
+
|
|
47
|
+
## Building
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Pure Rust
|
|
51
|
+
cargo build
|
|
52
|
+
cargo test # Unit tests only
|
|
53
|
+
RUST_MIN_STACK=16777216 cargo test # Unit + integration tests (HCA needs larger stack)
|
|
54
|
+
|
|
55
|
+
# Python extension
|
|
56
|
+
python3 -m maturin build --release
|
|
57
|
+
|
|
58
|
+
# crates.io dry run
|
|
59
|
+
cargo publish --dry-run --allow-dirty
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Testing
|
|
63
|
+
|
|
64
|
+
- **Unit tests**: Inline `#[cfg(test)] mod tests` in most modules
|
|
65
|
+
- **Integration tests**: `tests/integration_tests.rs` — requires `se_0126_01.acb` and `0703.usm` test fixtures in project root
|
|
66
|
+
- Integration tests need `RUST_MIN_STACK=16777216` due to large `ClHca` struct
|
|
67
|
+
|
|
68
|
+
## Conventions
|
|
69
|
+
|
|
70
|
+
- Use `thiserror` for error types
|
|
71
|
+
- Use `byteorder` for binary reading via the `reader.rs` wrapper
|
|
72
|
+
- Use `encoding_rs` for Shift-JIS text decoding (CRI uses Shift-JIS strings)
|
|
73
|
+
- Public API lives in module root files (`acb.rs`, `hca.rs`, `usm.rs`); internals are `mod` (private)
|
|
74
|
+
- Python bindings are behind `#[cfg(feature = "python")]` so they're opt-in
|
|
75
|
+
|
|
76
|
+
## Git commits
|
|
77
|
+
|
|
78
|
+
All commit subjects must follow:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
[Type] Short description starting with capital letter
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Allowed types:
|
|
85
|
+
|
|
86
|
+
| Type | Usage |
|
|
87
|
+
|-----------|-------------------------------------------------------|
|
|
88
|
+
| `[Feat]` | New feature or capability |
|
|
89
|
+
| `[Fix]` | Bug fix |
|
|
90
|
+
| `[Chore]` | Maintenance, refactoring, dependency or build changes |
|
|
91
|
+
| `[Docs]` | Documentation-only changes |
|
|
92
|
+
|
|
93
|
+
Rules:
|
|
94
|
+
|
|
95
|
+
- Description starts with a capital letter.
|
|
96
|
+
- Use imperative mood: `Add ...`, not `Added ...`.
|
|
97
|
+
- No trailing period.
|
|
98
|
+
- Keep the subject at or below roughly 70 characters.
|
|
99
|
+
- **Agent attribution uses the standard Git `Co-authored-by:` trailer in the commit body, not a free-form `Agent:` line.** This makes GitHub render the co-author avatar on the commit page. The trailer must be on its own line, separated from the subject by a blank line, in the form `Co-authored-by: <Display Name> <email>`. Suggested values per agent:
|
|
100
|
+
- Claude (any 4.x): `Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>` (substitute the actual model, e.g. `Claude Sonnet 4.6`, `Claude Haiku 4.5`)
|
|
101
|
+
- Codex: `Co-authored-by: Codex <noreply@openai.com>`
|
|
102
|
+
- Copilot: `Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>`
|
|
103
|
+
|
|
104
|
+
Examples from this repo's history:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
[Feat] Add encoding Python bindings
|
|
108
|
+
[Fix] Resolve check and clippy warnings
|
|
109
|
+
[Chore] Configure Dependabot updates
|
|
110
|
+
[Feat] Add encoding support but not tested in game
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## GitHub Actions workflows
|
|
114
|
+
|
|
115
|
+
Use the standardized workflow layout in `.github/workflows`:
|
|
116
|
+
|
|
117
|
+
- `ci.yml` runs on `main` pushes, pull requests targeting `main`, and manual dispatch.
|
|
118
|
+
- Rust CI order: `cargo fmt --all -- --check`, `cargo check --locked --all-targets`, `cargo clippy --locked --all-targets -- -D warnings`, then `cargo test --locked`.
|
|
119
|
+
- `release-crate.yml` publishes the Rust crate and keeps its package-specific release flow.
|
|
120
|
+
- `release-python.yml` builds and publishes Python artifacts and keeps its package-specific release flow.
|
|
121
|
+
|
|
122
|
+
Workflow maintenance rules:
|
|
123
|
+
|
|
124
|
+
- Keep workflow filenames and top-level names aligned: `CI`, `Release`, `Docker`, and optional package-specific names.
|
|
125
|
+
- Use `actions/checkout@v6`, `actions/setup-go@v6`, `actions/upload-artifact@v7`, `actions/download-artifact@v8`, `softprops/action-gh-release@v3`, and current Docker actions (`setup-buildx@v4`, `login@v4`, `metadata@v6`, `build-push@v7`).
|
|
126
|
+
- Keep `permissions` minimal: `contents: read` for CI/Docker build-only work, `contents: write` for release publishing, and `packages: write` only when pushing container images.
|
|
127
|
+
- Use workflow `concurrency` keyed by workflow name and ref, with release jobs using `release-${{ github.ref_name }}` and `cancel-in-progress: false`.
|
|
128
|
+
- Do not reintroduce legacy workflow names such as `rust-ci.yml`, `build.yml`, `release-build.yml`, `docker-build.yml`, or `docker-release.yml` unless a package-specific workflow already exists and is intentionally preserved.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "cridecoder"
|
|
3
|
-
version = "0.1
|
|
3
|
+
version = "0.2.1"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
description = "CRI codec library for ACB/AWB, HCA audio, and USM video extraction"
|
|
6
6
|
license = "MIT"
|
|
@@ -16,16 +16,16 @@ exclude = ["*.acb", "*.usm", "*.hca", "*.wav", "*.m2v", "test_output_*"]
|
|
|
16
16
|
crate-type = ["cdylib", "rlib"]
|
|
17
17
|
|
|
18
18
|
[dependencies]
|
|
19
|
-
byteorder = "1
|
|
20
|
-
thiserror = "2
|
|
21
|
-
encoding_rs = "0.8
|
|
22
|
-
serde = { version = "1
|
|
23
|
-
serde_json = "1
|
|
24
|
-
hex = "0.4
|
|
19
|
+
byteorder = "1"
|
|
20
|
+
thiserror = "2"
|
|
21
|
+
encoding_rs = "0.8"
|
|
22
|
+
serde = { version = "1", features = ["derive"] }
|
|
23
|
+
serde_json = "1"
|
|
24
|
+
hex = "0.4"
|
|
25
25
|
pyo3 = { version = "0.28", features = ["extension-module"], optional = true }
|
|
26
26
|
|
|
27
27
|
[dev-dependencies]
|
|
28
|
-
tempfile = "3
|
|
28
|
+
tempfile = "3"
|
|
29
29
|
|
|
30
30
|
[features]
|
|
31
31
|
default = []
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cridecoder
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -18,7 +18,7 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
|
18
18
|
|
|
19
19
|
# cridecoder
|
|
20
20
|
|
|
21
|
-
A pure Rust library for CRI Middleware codec decoding. Supports ACB/AWB audio containers, HCA (High Compression Audio) decoding, and USM video container extraction.
|
|
21
|
+
A pure Rust library for CRI Middleware codec encoding and decoding. Supports ACB/AWB audio containers, HCA (High Compression Audio) encoding/decoding, and USM video container extraction/building.
|
|
22
22
|
|
|
23
23
|
## Credits
|
|
24
24
|
|
|
@@ -26,11 +26,12 @@ This project's CRI format implementation is based on and inspired by [vgmstream]
|
|
|
26
26
|
|
|
27
27
|
## Features
|
|
28
28
|
|
|
29
|
-
- **ACB/AWB Extraction** — Parse CRI ACB audio containers
|
|
30
|
-
- **HCA Decoding** —
|
|
31
|
-
- **USM Extraction** — Extract
|
|
29
|
+
- **ACB/AWB Extraction & Building** — Parse and create CRI ACB audio containers
|
|
30
|
+
- **HCA Encoding & Decoding** — Encode PCM to HCA, decode HCA to PCM/WAV
|
|
31
|
+
- **USM Extraction & Building** — Extract or create USM video containers
|
|
32
32
|
- **USM Metadata** — Read and export USM metadata as structured JSON
|
|
33
33
|
- **Key Testing** — Test decryption keys for encrypted HCA files
|
|
34
|
+
- **Encryption Support** — Encode HCA with encryption keys
|
|
34
35
|
- **Pure Rust** — No C dependencies, works on any platform Rust supports
|
|
35
36
|
|
|
36
37
|
## Usage
|
|
@@ -60,6 +61,22 @@ if let Some(tracks) = tracks {
|
|
|
60
61
|
}
|
|
61
62
|
```
|
|
62
63
|
|
|
64
|
+
### ACB Building
|
|
65
|
+
|
|
66
|
+
```rust
|
|
67
|
+
use std::io::Cursor;
|
|
68
|
+
use cridecoder::{AcbBuilder, TrackInput};
|
|
69
|
+
|
|
70
|
+
let hca_data = std::fs::read("track.hca").unwrap();
|
|
71
|
+
let track = TrackInput::new("my_track", 0, hca_data);
|
|
72
|
+
|
|
73
|
+
let mut builder = AcbBuilder::new();
|
|
74
|
+
builder.add_track(track);
|
|
75
|
+
|
|
76
|
+
let mut output = Cursor::new(Vec::new());
|
|
77
|
+
builder.build(&mut output, None).unwrap();
|
|
78
|
+
```
|
|
79
|
+
|
|
63
80
|
### HCA to WAV
|
|
64
81
|
|
|
65
82
|
```rust
|
|
@@ -74,6 +91,23 @@ let mut output = File::create("output.wav").unwrap();
|
|
|
74
91
|
decoder.decode_to_wav(&mut output).unwrap();
|
|
75
92
|
```
|
|
76
93
|
|
|
94
|
+
### PCM to HCA
|
|
95
|
+
|
|
96
|
+
```rust
|
|
97
|
+
use std::io::Cursor;
|
|
98
|
+
use cridecoder::{HcaEncoder, HcaEncoderConfig};
|
|
99
|
+
|
|
100
|
+
// Generate or load PCM samples (interleaved stereo f32)
|
|
101
|
+
let samples: Vec<f32> = vec![0.0; 44100 * 2]; // 1 second of silence
|
|
102
|
+
|
|
103
|
+
let config = HcaEncoderConfig::new(44100, 2) // 44.1kHz stereo
|
|
104
|
+
.with_bitrate(256_000); // 256 kbps
|
|
105
|
+
|
|
106
|
+
let mut encoder = HcaEncoder::new(config).unwrap();
|
|
107
|
+
let mut output = Cursor::new(Vec::new());
|
|
108
|
+
encoder.encode(&samples, &mut output).unwrap();
|
|
109
|
+
```
|
|
110
|
+
|
|
77
111
|
### USM Extraction
|
|
78
112
|
|
|
79
113
|
```rust
|
|
@@ -92,14 +126,29 @@ for file in &files {
|
|
|
92
126
|
}
|
|
93
127
|
```
|
|
94
128
|
|
|
129
|
+
### USM Building
|
|
130
|
+
|
|
131
|
+
```rust
|
|
132
|
+
use std::io::Cursor;
|
|
133
|
+
use cridecoder::UsmBuilder;
|
|
134
|
+
|
|
135
|
+
let video_data = std::fs::read("video.m2v").unwrap();
|
|
136
|
+
|
|
137
|
+
let builder = UsmBuilder::new("my_video".to_string())
|
|
138
|
+
.video(video_data);
|
|
139
|
+
|
|
140
|
+
let mut output = Cursor::new(Vec::new());
|
|
141
|
+
builder.build(&mut output).unwrap();
|
|
142
|
+
```
|
|
143
|
+
|
|
95
144
|
## Supported Formats
|
|
96
145
|
|
|
97
|
-
| Format | Description |
|
|
98
|
-
|
|
99
|
-
| ACB | CRI Audio Container | Extract
|
|
100
|
-
| AWB | CRI Audio Waveform Bank |
|
|
101
|
-
| HCA | High Compression Audio |
|
|
102
|
-
| USM | CRI Video Container | Extract
|
|
146
|
+
| Format | Description | Operations |
|
|
147
|
+
|--------|-------------|------------|
|
|
148
|
+
| ACB | CRI Audio Container | Extract / Build |
|
|
149
|
+
| AWB | CRI Audio Waveform Bank | Extract / Build |
|
|
150
|
+
| HCA | High Compression Audio | Encode / Decode |
|
|
151
|
+
| USM | CRI Video Container | Extract / Build |
|
|
103
152
|
|
|
104
153
|
## License
|
|
105
154
|
|