phantom-audio 1.1.0__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.
- phantom_audio-1.1.0/.github/ISSUE_TEMPLATE/bug_report.md +35 -0
- phantom_audio-1.1.0/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
- phantom_audio-1.1.0/.github/PULL_REQUEST_TEMPLATE.md +22 -0
- phantom_audio-1.1.0/.gitignore +64 -0
- phantom_audio-1.1.0/CLAUDE.md +87 -0
- phantom_audio-1.1.0/CODE_OF_CONDUCT.md +16 -0
- phantom_audio-1.1.0/CONTRIBUTING.md +107 -0
- phantom_audio-1.1.0/LICENSE +664 -0
- phantom_audio-1.1.0/PKG-INFO +338 -0
- phantom_audio-1.1.0/README.md +278 -0
- phantom_audio-1.1.0/SECURITY.md +47 -0
- phantom_audio-1.1.0/docs/workflows/server-comparison.md +46 -0
- phantom_audio-1.1.0/docs/workflows/setup-guide.md +115 -0
- phantom_audio-1.1.0/docs/workflows/workflow-diagnostic-fix.md +57 -0
- phantom_audio-1.1.0/docs/workflows/workflow-full-mix.md +60 -0
- phantom_audio-1.1.0/docs/workflows/workflow-mastering.md +61 -0
- phantom_audio-1.1.0/docs/workflows/workflow-parallel-comp.md +46 -0
- phantom_audio-1.1.0/docs/workflows/workflow-session-setup.md +59 -0
- phantom_audio-1.1.0/docs/workflows/workflow-sidechain.md +52 -0
- phantom_audio-1.1.0/docs/workflows/workflow-vocal-chain.md +47 -0
- phantom_audio-1.1.0/examples/demo.wav +0 -0
- phantom_audio-1.1.0/plugin/.claude-plugin/plugin.json +11 -0
- phantom_audio-1.1.0/pyproject.toml +101 -0
- phantom_audio-1.1.0/scripts/pre-push +33 -0
- phantom_audio-1.1.0/src/phantom/__init__.py +113 -0
- phantom_audio-1.1.0/src/phantom/__main__.py +9 -0
- phantom_audio-1.1.0/src/phantom/_diagnostics.py +29 -0
- phantom_audio-1.1.0/src/phantom/_profiles.py +335 -0
- phantom_audio-1.1.0/src/phantom/_rounding.py +43 -0
- phantom_audio-1.1.0/src/phantom/_utils.py +144 -0
- phantom_audio-1.1.0/src/phantom/audio.py +218 -0
- phantom_audio-1.1.0/src/phantom/cli/__init__.py +118 -0
- phantom_audio-1.1.0/src/phantom/cli/_formatting.py +244 -0
- phantom_audio-1.1.0/src/phantom/cli/analyze.py +376 -0
- phantom_audio-1.1.0/src/phantom/cli/compare.py +392 -0
- phantom_audio-1.1.0/src/phantom/cli/doctor.py +243 -0
- phantom_audio-1.1.0/src/phantom/cli/render.py +180 -0
- phantom_audio-1.1.0/src/phantom/cli/separate.py +82 -0
- phantom_audio-1.1.0/src/phantom/cli/setup.py +217 -0
- phantom_audio-1.1.0/src/phantom/cli/setup_reaper.py +284 -0
- phantom_audio-1.1.0/src/phantom/cli/uninstall.py +233 -0
- phantom_audio-1.1.0/src/phantom/cli/update.py +266 -0
- phantom_audio-1.1.0/src/phantom/comparison/__init__.py +61 -0
- phantom_audio-1.1.0/src/phantom/comparison/_common.py +280 -0
- phantom_audio-1.1.0/src/phantom/comparison/match.py +138 -0
- phantom_audio-1.1.0/src/phantom/comparison/profile.py +135 -0
- phantom_audio-1.1.0/src/phantom/comparison/reference.py +143 -0
- phantom_audio-1.1.0/src/phantom/dynamics.py +133 -0
- phantom_audio-1.1.0/src/phantom/exceptions.py +52 -0
- phantom_audio-1.1.0/src/phantom/loudness.py +137 -0
- phantom_audio-1.1.0/src/phantom/masking.py +338 -0
- phantom_audio-1.1.0/src/phantom/phase.py +304 -0
- phantom_audio-1.1.0/src/phantom/problems.py +701 -0
- phantom_audio-1.1.0/src/phantom/profiles/__init__.py +1 -0
- phantom_audio-1.1.0/src/phantom/profiles/ambient.json +19 -0
- phantom_audio-1.1.0/src/phantom/profiles/edm.json +19 -0
- phantom_audio-1.1.0/src/phantom/profiles/electronic.json +19 -0
- phantom_audio-1.1.0/src/phantom/profiles/hip-hop.json +19 -0
- phantom_audio-1.1.0/src/phantom/profiles/lo-fi.json +19 -0
- phantom_audio-1.1.0/src/phantom/profiles/metal.json +19 -0
- phantom_audio-1.1.0/src/phantom/profiles/pop.json +19 -0
- phantom_audio-1.1.0/src/phantom/profiles/rock-metal.json +19 -0
- phantom_audio-1.1.0/src/phantom/profiles/rock.json +19 -0
- phantom_audio-1.1.0/src/phantom/py.typed +0 -0
- phantom_audio-1.1.0/src/phantom/separation.py +148 -0
- phantom_audio-1.1.0/src/phantom/server.py +524 -0
- phantom_audio-1.1.0/src/phantom/spectral.py +198 -0
- phantom_audio-1.1.0/src/phantom/stereo.py +221 -0
- phantom_audio-1.1.0/tests/__init__.py +0 -0
- phantom_audio-1.1.0/tests/conftest.py +430 -0
- phantom_audio-1.1.0/tests/test_audio.py +550 -0
- phantom_audio-1.1.0/tests/test_cli_analyze.py +290 -0
- phantom_audio-1.1.0/tests/test_cli_compare.py +136 -0
- phantom_audio-1.1.0/tests/test_cli_doctor.py +85 -0
- phantom_audio-1.1.0/tests/test_cli_formatting.py +278 -0
- phantom_audio-1.1.0/tests/test_cli_render.py +144 -0
- phantom_audio-1.1.0/tests/test_cli_separate.py +151 -0
- phantom_audio-1.1.0/tests/test_cli_setup.py +99 -0
- phantom_audio-1.1.0/tests/test_cli_setup_reaper.py +195 -0
- phantom_audio-1.1.0/tests/test_cli_uninstall.py +174 -0
- phantom_audio-1.1.0/tests/test_cli_update.py +380 -0
- phantom_audio-1.1.0/tests/test_comparison.py +855 -0
- phantom_audio-1.1.0/tests/test_dynamics.py +272 -0
- phantom_audio-1.1.0/tests/test_dynamics_crossvalidation.py +124 -0
- phantom_audio-1.1.0/tests/test_exceptions.py +116 -0
- phantom_audio-1.1.0/tests/test_live_cli.py +273 -0
- phantom_audio-1.1.0/tests/test_live_mcp.py +405 -0
- phantom_audio-1.1.0/tests/test_loudness.py +287 -0
- phantom_audio-1.1.0/tests/test_loudness_crossvalidation.py +157 -0
- phantom_audio-1.1.0/tests/test_masking.py +459 -0
- phantom_audio-1.1.0/tests/test_models.py +1132 -0
- phantom_audio-1.1.0/tests/test_phase.py +453 -0
- phantom_audio-1.1.0/tests/test_problems.py +631 -0
- phantom_audio-1.1.0/tests/test_profiles.py +491 -0
- phantom_audio-1.1.0/tests/test_separation.py +300 -0
- phantom_audio-1.1.0/tests/test_server.py +639 -0
- phantom_audio-1.1.0/tests/test_server_integration.py +110 -0
- phantom_audio-1.1.0/tests/test_spectral.py +275 -0
- phantom_audio-1.1.0/tests/test_spectral_crossvalidation.py +135 -0
- phantom_audio-1.1.0/tests/test_stereo.py +333 -0
- phantom_audio-1.1.0/tests/test_utils.py +180 -0
- phantom_audio-1.1.0/uv.lock +3344 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Report a problem with Phantom
|
|
4
|
+
labels: bug
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Description
|
|
8
|
+
|
|
9
|
+
A clear description of the bug.
|
|
10
|
+
|
|
11
|
+
## Steps to Reproduce
|
|
12
|
+
|
|
13
|
+
1. ...
|
|
14
|
+
2. ...
|
|
15
|
+
3. ...
|
|
16
|
+
|
|
17
|
+
## Expected Behavior
|
|
18
|
+
|
|
19
|
+
What you expected to happen.
|
|
20
|
+
|
|
21
|
+
## Actual Behavior
|
|
22
|
+
|
|
23
|
+
What actually happened. Include error messages or tracebacks if available.
|
|
24
|
+
|
|
25
|
+
## Environment
|
|
26
|
+
|
|
27
|
+
- **OS:** (e.g., macOS 15, Ubuntu 24.04, Windows 11)
|
|
28
|
+
- **Python version:** (e.g., 3.12.5)
|
|
29
|
+
- **Phantom version:** (run `phantom --version` or `python -c "import phantom; print(phantom.__version__)"`)
|
|
30
|
+
- **Installation method:** (pip, uv, from source)
|
|
31
|
+
- **Optional extras installed:** (separation, matching, processing)
|
|
32
|
+
|
|
33
|
+
## Additional Context
|
|
34
|
+
|
|
35
|
+
Any other relevant information (audio file details, MCP client, etc.).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest an idea for Phantom
|
|
4
|
+
labels: enhancement
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Problem
|
|
8
|
+
|
|
9
|
+
What problem does this feature solve? What's missing?
|
|
10
|
+
|
|
11
|
+
## Proposed Solution
|
|
12
|
+
|
|
13
|
+
How would you like this to work?
|
|
14
|
+
|
|
15
|
+
## Alternatives Considered
|
|
16
|
+
|
|
17
|
+
Any other approaches you've thought about.
|
|
18
|
+
|
|
19
|
+
## Additional Context
|
|
20
|
+
|
|
21
|
+
Any other relevant information (use cases, examples, references).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
Brief description of what this PR does and why.
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
- ...
|
|
8
|
+
- ...
|
|
9
|
+
|
|
10
|
+
## Test Plan
|
|
11
|
+
|
|
12
|
+
How was this tested?
|
|
13
|
+
|
|
14
|
+
- [ ] New tests added
|
|
15
|
+
- [ ] Existing tests pass
|
|
16
|
+
|
|
17
|
+
## Checklist
|
|
18
|
+
|
|
19
|
+
- [ ] Tests pass (`uv run pytest tests/ -x -q`)
|
|
20
|
+
- [ ] Linting passes (`uv tool run ruff check src/ tests/`)
|
|
21
|
+
- [ ] Formatting passes (`uv tool run ruff format --check src/ tests/`)
|
|
22
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Audio files — managed outside git
|
|
2
|
+
*.wav
|
|
3
|
+
*.mp3
|
|
4
|
+
*.flac
|
|
5
|
+
*.aiff
|
|
6
|
+
*.ogg
|
|
7
|
+
*.m4a
|
|
8
|
+
!examples/demo.wav
|
|
9
|
+
|
|
10
|
+
# Live test audio -- not committed (D-02)
|
|
11
|
+
tests/fixtures/live/
|
|
12
|
+
|
|
13
|
+
# DAW project files
|
|
14
|
+
*.cpr
|
|
15
|
+
*.bak
|
|
16
|
+
*.flp
|
|
17
|
+
|
|
18
|
+
# OS
|
|
19
|
+
.DS_Store
|
|
20
|
+
Thumbs.db
|
|
21
|
+
|
|
22
|
+
# Claude local
|
|
23
|
+
.claude.local.md
|
|
24
|
+
|
|
25
|
+
# Environment
|
|
26
|
+
.env
|
|
27
|
+
.env.*
|
|
28
|
+
|
|
29
|
+
# Python
|
|
30
|
+
__pycache__/
|
|
31
|
+
*.py[cod]
|
|
32
|
+
*$py.class
|
|
33
|
+
*.egg-info/
|
|
34
|
+
dist/
|
|
35
|
+
build/
|
|
36
|
+
*.egg
|
|
37
|
+
.pytest_cache/
|
|
38
|
+
.venv/
|
|
39
|
+
venv/
|
|
40
|
+
|
|
41
|
+
# Development planning (internal only)
|
|
42
|
+
.planning/
|
|
43
|
+
|
|
44
|
+
# Claude Code local config
|
|
45
|
+
.claude/
|
|
46
|
+
.mcp.json
|
|
47
|
+
|
|
48
|
+
# Internal design specs and milestone plans
|
|
49
|
+
docs/superpowers/
|
|
50
|
+
|
|
51
|
+
# Skill evaluation workspaces (contain local paths)
|
|
52
|
+
plugin/eval-workspaces/
|
|
53
|
+
|
|
54
|
+
# Local skill development
|
|
55
|
+
plugin/skills-local/
|
|
56
|
+
|
|
57
|
+
# Reference materials
|
|
58
|
+
resources/
|
|
59
|
+
|
|
60
|
+
# autoresearch runs
|
|
61
|
+
.autoresearch/
|
|
62
|
+
|
|
63
|
+
# Local working files
|
|
64
|
+
.superpowers/
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code when working with the Phantom codebase.
|
|
4
|
+
|
|
5
|
+
## Project
|
|
6
|
+
|
|
7
|
+
Phantom is an AI audio engineering system. It combines an MCP server for audio analysis with Claude Code skills encoding professional mixing/mastering expertise, integrated with Reaper via MCP for DAW control.
|
|
8
|
+
|
|
9
|
+
**Core Value:** Claude can analyze any audio file or set of stems and produce actionable, measurement-backed mixing and mastering guidance calibrated to a reference target.
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
13
|
+
- **MCP Server** (`src/phantom/`) -- Python, audio analysis via Essentia + scipy/numpy, served through FastMCP
|
|
14
|
+
- **Claude Code Plugin** (`plugin/`) -- 5 domain expert skills: mix-engineer, effects-engineer, mastering-engineer, audio-diagnostician, session-architect
|
|
15
|
+
- **CLI** (`src/phantom/cli/`) -- Rich terminal interface for analysis, comparison, separation, rendering
|
|
16
|
+
- **Reference Profiles** (`src/phantom/profiles/`) -- 9 genre spectral and dynamics targets as JSON
|
|
17
|
+
- **DAW Control** -- via external Reaper MCP server (TwelveTake recommended)
|
|
18
|
+
|
|
19
|
+
## Tech Stack
|
|
20
|
+
|
|
21
|
+
| Library | Purpose |
|
|
22
|
+
|---------|---------|
|
|
23
|
+
| Python 3.10+ | Runtime |
|
|
24
|
+
| essentia | Primary analysis engine (spectral, loudness, problem detection) |
|
|
25
|
+
| scipy / numpy | Signal processing, array operations |
|
|
26
|
+
| soundfile | WAV I/O |
|
|
27
|
+
| pydantic | Typed response models |
|
|
28
|
+
| FastMCP 2.x | MCP server framework |
|
|
29
|
+
| click + rich | CLI interface |
|
|
30
|
+
|
|
31
|
+
Optional: demucs (stem separation), matchering (reference matching, GPLv3), pedalboard (audio processing)
|
|
32
|
+
|
|
33
|
+
## Conventions
|
|
34
|
+
|
|
35
|
+
### Code Patterns
|
|
36
|
+
|
|
37
|
+
- All analysis modules follow: input guard -> analyze -> return Pydantic model
|
|
38
|
+
- Optional dependencies use lazy imports with `DependencyMissingError`
|
|
39
|
+
- `PhantomError` hierarchy with musician-friendly error messages
|
|
40
|
+
- Env var configuration: `PHANTOM_AUDIO_DIR`, `PHANTOM_OUTPUT_DIR`, `PHANTOM_MAX_DURATION`, `PHANTOM_MAX_FILE_SIZE`
|
|
41
|
+
|
|
42
|
+
### Testing
|
|
43
|
+
|
|
44
|
+
- All tests use synthetic audio fixtures (no real audio committed)
|
|
45
|
+
- pytest 8.x with pytest-asyncio
|
|
46
|
+
- Run: `uv run pytest tests/ -x -q`
|
|
47
|
+
|
|
48
|
+
### Pre-push Checks
|
|
49
|
+
|
|
50
|
+
- Linting: `uv tool run ruff check src/ tests/`
|
|
51
|
+
- Formatting: `uv tool run ruff format --check src/ tests/`
|
|
52
|
+
- Tests: `uv run pytest tests/ -x -q --tb=short`
|
|
53
|
+
- Hook: `scripts/pre-push` (auto-runs on git push)
|
|
54
|
+
|
|
55
|
+
## Privacy
|
|
56
|
+
|
|
57
|
+
Artist personal information must never appear in commits or public-facing documentation. Reference artists by first name only in internal docs, never in committed code.
|
|
58
|
+
|
|
59
|
+
## Key Decisions
|
|
60
|
+
|
|
61
|
+
- **AGPL-3.0** -- open source, copyleft (commercial licensing available separately)
|
|
62
|
+
- **Reaper over Cubase** for DAW integration (900+ API functions vs sandboxed JS)
|
|
63
|
+
- **Monorepo** -- MCP server usable by any MCP client, skills are Claude Code specific
|
|
64
|
+
- **Essentia as primary engine** -- 10-25x faster than librosa for feature extraction
|
|
65
|
+
- **Dynamic reference system** -- accepts artist name, genre, song title, or WAV file as mixing/mastering target
|
|
66
|
+
|
|
67
|
+
## Entry Points
|
|
68
|
+
|
|
69
|
+
| Command | Source | Description |
|
|
70
|
+
|---------|--------|-------------|
|
|
71
|
+
| `phantom` | `src/phantom/cli/__init__.py` | CLI entry point (click group) |
|
|
72
|
+
| `phantom-mcp` | `src/phantom/server.py` | MCP server entry point |
|
|
73
|
+
|
|
74
|
+
### MCP Tools (17)
|
|
75
|
+
|
|
76
|
+
`analyze_spectrum`, `analyze_loudness`, `analyze_dynamics`, `analyze_stereo`, `analyze_phase`, `compare_phase`, `detect_problems`, `analyze_masking`, `analyze_masking_matrix`, `multi_stem_masking`, `compare_to_profile`, `compare_to_reference`, `match_to_reference`, `separate_stems`, `full_diagnostic`, `batch_diagnostic`, `setup_reaper`
|
|
77
|
+
|
|
78
|
+
### CLI Commands
|
|
79
|
+
|
|
80
|
+
`phantom analyze`, `phantom compare`, `phantom separate`, `phantom render`, `phantom setup-reaper`, `phantom serve`
|
|
81
|
+
|
|
82
|
+
## Contributing
|
|
83
|
+
|
|
84
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
|
|
85
|
+
|
|
86
|
+
<!-- For detailed internal technical research (dependency analysis, alternatives considered, -->
|
|
87
|
+
<!-- version pinning rationale), see .claude.local.md (not committed). -->
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
This project follows the **Contributor Covenant Code of Conduct, version 2.1**.
|
|
4
|
+
|
|
5
|
+
The full text is available at:
|
|
6
|
+
https://www.contributor-covenant.org/version/2/1/code_of_conduct/
|
|
7
|
+
|
|
8
|
+
## Enforcement
|
|
9
|
+
|
|
10
|
+
Instances of unacceptable behavior may be reported to the project team at **phantom-audio@proton.me**.
|
|
11
|
+
|
|
12
|
+
All complaints will be reviewed and investigated promptly and fairly. The project team is obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
13
|
+
|
|
14
|
+
## Attribution
|
|
15
|
+
|
|
16
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Contributing to Phantom
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to Phantom! This guide will help you get started.
|
|
4
|
+
|
|
5
|
+
Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md) in all interactions.
|
|
6
|
+
|
|
7
|
+
Contributions are welcome under the [AGPL-3.0](LICENSE) license (inbound = outbound).
|
|
8
|
+
|
|
9
|
+
## Development Setup
|
|
10
|
+
|
|
11
|
+
1. Fork and clone the repository:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git clone https://github.com/YOUR_USERNAME/phantom.git
|
|
15
|
+
cd phantom
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
2. Install dependencies (requires Python 3.10+ and [uv](https://docs.astral.sh/uv/)):
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv sync --dev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or with pip:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install -e ".[dev]"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
3. Install the pre-push hook:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ln -sf ../../scripts/pre-push .git/hooks/pre-push
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
4. Run the test suite:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv run pytest tests/ -x -q
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Code Style
|
|
43
|
+
|
|
44
|
+
- **Linting:** `uv tool run ruff check src/ tests/`
|
|
45
|
+
- **Formatting:** `uv tool run ruff format src/ tests/`
|
|
46
|
+
- The pre-push hook runs both automatically before each push
|
|
47
|
+
- No manual type checking required (essentia lacks type stubs)
|
|
48
|
+
|
|
49
|
+
## Architecture Overview
|
|
50
|
+
|
|
51
|
+
- `src/phantom/` — Core analysis modules, MCP server, CLI entry points
|
|
52
|
+
- `plugin/` — Claude Code plugin with 5 domain expert skills
|
|
53
|
+
- `tests/` — All tests use synthetic audio fixtures (no real audio files in repo)
|
|
54
|
+
- `docs/workflows/` — DAW integration workflow documentation
|
|
55
|
+
- `src/phantom/profiles/` — Genre reference profiles (JSON)
|
|
56
|
+
|
|
57
|
+
See [CLAUDE.md](CLAUDE.md) for deeper architectural guidance.
|
|
58
|
+
|
|
59
|
+
## How to Contribute
|
|
60
|
+
|
|
61
|
+
**Bug reports:** Use the [bug report template](https://github.com/fadelabs/phantom/issues/new?template=bug_report.md)
|
|
62
|
+
|
|
63
|
+
**Feature requests:** Use the [feature request template](https://github.com/fadelabs/phantom/issues/new?template=feature_request.md)
|
|
64
|
+
|
|
65
|
+
**Pull requests:**
|
|
66
|
+
|
|
67
|
+
1. Fork the repository
|
|
68
|
+
2. Create a feature branch (`git checkout -b feature/my-feature`)
|
|
69
|
+
3. Implement your changes
|
|
70
|
+
4. Ensure all checks pass
|
|
71
|
+
5. Open a pull request
|
|
72
|
+
|
|
73
|
+
All PRs require:
|
|
74
|
+
|
|
75
|
+
- Tests passing (`uv run pytest tests/ -x -q`)
|
|
76
|
+
- Ruff linting clean (`uv tool run ruff check src/ tests/`)
|
|
77
|
+
- Ruff formatting clean (`uv tool run ruff format --check src/ tests/`)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
New analysis features should follow existing module patterns: input guard, analyze, return Pydantic model. See any module in `src/phantom/` for examples.
|
|
81
|
+
|
|
82
|
+
Optional dependencies must use lazy imports with `DependencyMissingError`.
|
|
83
|
+
|
|
84
|
+
## Testing
|
|
85
|
+
|
|
86
|
+
- All tests use synthetic audio fixtures generated in `tests/conftest.py`
|
|
87
|
+
- Never commit real audio files to the repository
|
|
88
|
+
- Run a single test file: `uv run pytest tests/test_spectral.py -x -v`
|
|
89
|
+
- Run the full suite: `uv run pytest tests/ -v`
|
|
90
|
+
- Test marker: `@pytest.mark.live` for tests requiring real audio (gitignored fixtures)
|
|
91
|
+
|
|
92
|
+
## Optional Dependencies
|
|
93
|
+
|
|
94
|
+
Phantom uses a tiered dependency system:
|
|
95
|
+
|
|
96
|
+
| Tier | Packages | Install |
|
|
97
|
+
|------|----------|---------|
|
|
98
|
+
| **Core** | essentia, scipy, numpy, soundfile, pydantic, FastMCP | `uv sync` |
|
|
99
|
+
| **Dev** | pytest, ruff, pyloudnorm | `uv sync --dev` |
|
|
100
|
+
| **Separation** | demucs, torch | `uv sync --extra separation` |
|
|
101
|
+
| **Matching** | matchering (GPLv3) | `uv sync --extra matching` |
|
|
102
|
+
| **Processing** | pedalboard | `uv sync --extra processing` |
|
|
103
|
+
| **Analysis** | librosa | `uv sync --extra analysis` |
|
|
104
|
+
|
|
105
|
+
## License
|
|
106
|
+
|
|
107
|
+
By submitting a contribution, you agree that your work is licensed under [AGPL-3.0](LICENSE), the same license as the project.
|