sounddiff 0.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.
Files changed (54) hide show
  1. sounddiff-0.1.0/.coderabbit.yaml +72 -0
  2. sounddiff-0.1.0/.github/CODEOWNERS +8 -0
  3. sounddiff-0.1.0/.github/FUNDING.yml +1 -0
  4. sounddiff-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +62 -0
  5. sounddiff-0.1.0/.github/ISSUE_TEMPLATE/config.yml +1 -0
  6. sounddiff-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +35 -0
  7. sounddiff-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +15 -0
  8. sounddiff-0.1.0/.github/SECURITY.md +33 -0
  9. sounddiff-0.1.0/.github/labeler.yml +23 -0
  10. sounddiff-0.1.0/.github/workflows/ci.yml +49 -0
  11. sounddiff-0.1.0/.github/workflows/labeler.yml +17 -0
  12. sounddiff-0.1.0/.github/workflows/release.yml +55 -0
  13. sounddiff-0.1.0/.github/workflows/sentry.yml +23 -0
  14. sounddiff-0.1.0/.gitignore +43 -0
  15. sounddiff-0.1.0/.pre-commit-config.yaml +19 -0
  16. sounddiff-0.1.0/CHANGELOG.md +38 -0
  17. sounddiff-0.1.0/CLAUDE.md +50 -0
  18. sounddiff-0.1.0/CODE_OF_CONDUCT.md +41 -0
  19. sounddiff-0.1.0/CONTRIBUTING.md +80 -0
  20. sounddiff-0.1.0/LICENSE +21 -0
  21. sounddiff-0.1.0/PKG-INFO +169 -0
  22. sounddiff-0.1.0/README.md +124 -0
  23. sounddiff-0.1.0/docs/api.md +196 -0
  24. sounddiff-0.1.0/docs/architecture.md +81 -0
  25. sounddiff-0.1.0/docs/contributing.md +34 -0
  26. sounddiff-0.1.0/docs/index.md +17 -0
  27. sounddiff-0.1.0/docs/install.md +84 -0
  28. sounddiff-0.1.0/docs/usage.md +112 -0
  29. sounddiff-0.1.0/examples/basic_comparison.py +33 -0
  30. sounddiff-0.1.0/examples/batch_compare.py +53 -0
  31. sounddiff-0.1.0/examples/ci_regression_test.py +62 -0
  32. sounddiff-0.1.0/pyproject.toml +105 -0
  33. sounddiff-0.1.0/scripts/generate_test_audio.py +127 -0
  34. sounddiff-0.1.0/src/sounddiff/__init__.py +3 -0
  35. sounddiff-0.1.0/src/sounddiff/__main__.py +5 -0
  36. sounddiff-0.1.0/src/sounddiff/cli.py +79 -0
  37. sounddiff-0.1.0/src/sounddiff/core.py +66 -0
  38. sounddiff-0.1.0/src/sounddiff/detection.py +164 -0
  39. sounddiff-0.1.0/src/sounddiff/formats.py +100 -0
  40. sounddiff-0.1.0/src/sounddiff/loudness.py +98 -0
  41. sounddiff-0.1.0/src/sounddiff/report.py +311 -0
  42. sounddiff-0.1.0/src/sounddiff/spectral.py +94 -0
  43. sounddiff-0.1.0/src/sounddiff/temporal.py +166 -0
  44. sounddiff-0.1.0/src/sounddiff/types.py +181 -0
  45. sounddiff-0.1.0/templates/report.html.j2 +168 -0
  46. sounddiff-0.1.0/tests/__init__.py +0 -0
  47. sounddiff-0.1.0/tests/conftest.py +83 -0
  48. sounddiff-0.1.0/tests/test_cli.py +80 -0
  49. sounddiff-0.1.0/tests/test_detection.py +94 -0
  50. sounddiff-0.1.0/tests/test_formats.py +79 -0
  51. sounddiff-0.1.0/tests/test_loudness.py +65 -0
  52. sounddiff-0.1.0/tests/test_report.py +103 -0
  53. sounddiff-0.1.0/tests/test_spectral.py +71 -0
  54. sounddiff-0.1.0/tests/test_temporal.py +66 -0
@@ -0,0 +1,72 @@
1
+ # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
2
+ # sounddiff — Python CLI for structured audio comparison
3
+ inheritance: true
4
+
5
+ reviews:
6
+ request_changes_workflow: true
7
+ profile: assertive
8
+ pre_merge_checks:
9
+ docstrings:
10
+ mode: "off"
11
+ title:
12
+ mode: warning
13
+ description:
14
+ mode: warning
15
+ path_filters:
16
+ - "!CLAUDE.md"
17
+ - "!docs/**"
18
+ - "!.coderabbit.yaml"
19
+ - "!scripts/**"
20
+ path_instructions:
21
+ - path: "src/sounddiff/**/*.py"
22
+ instructions: |
23
+ sounddiff is a Python 3.10+ CLI tool for structured audio comparison.
24
+ Uses numpy, scipy, pyloudnorm for DSP. Click for CLI. Rich for terminal output.
25
+ mypy strict mode. Ruff for linting and formatting.
26
+
27
+ Review priorities (highest to lowest):
28
+ 1. Correctness of DSP algorithms (loudness, spectral, correlation math)
29
+ 2. Type safety (all public functions must have complete type annotations)
30
+ 3. Edge cases in audio processing (empty signals, mono/stereo, different sample rates)
31
+ 4. Performance issues with measurable impact on large audio files
32
+ 5. Error handling (clear messages for file not found, unsupported format, corrupt audio)
33
+
34
+ Known patterns, DO NOT flag:
35
+ - `from __future__ import annotations` at top of every module (PEP 604 unions on 3.10)
36
+ - `np.ndarray` without generic parameters (numpy typing is limited)
37
+ - `pyloudnorm` and `soundfile` are untyped (ignore_missing_imports in mypy config)
38
+ - Frozen dataclasses for all result types (immutability is intentional)
39
+ - Properties on frozen dataclasses for computed deltas (avoids storing derived values)
40
+
41
+ Do NOT flag:
42
+ - Missing docstrings on private functions (underscore-prefixed)
43
+ - Import ordering (ruff handles this)
44
+ - Line length (ruff formatter handles this)
45
+ - path: "src/sounddiff/cli.py"
46
+ instructions: |
47
+ CLI entry point using Click. Review for:
48
+ - Clear error messages for all failure modes
49
+ - Correct exit codes (0 success, 1 for errors)
50
+ - No unhandled exceptions reaching the user
51
+ - path: "src/sounddiff/{loudness,spectral,temporal,detection}.py"
52
+ instructions: |
53
+ Core DSP modules. Review with extra care for:
54
+ - Mathematical correctness (dB conversions, RMS calculations, correlation)
55
+ - Handling of edge cases (silence, single-sample files, DC offset)
56
+ - Numerical stability (division by zero, log of zero)
57
+ - Consistent units (always dB, Hz, seconds — never raw sample counts in output)
58
+ - path: "tests/**/*.py"
59
+ instructions: |
60
+ Test suite using pytest and hypothesis. Review for:
61
+ - Test isolation (no shared mutable state between tests)
62
+ - Meaningful assertions (not just "doesn't crash")
63
+ - Edge case coverage (empty input, mono, extreme values)
64
+ - Deterministic test audio generation (fixed seeds, no randomness without rng fixture)
65
+
66
+ tools:
67
+ ruff:
68
+ enabled: true
69
+
70
+ knowledge_base:
71
+ web_search:
72
+ enabled: false
@@ -0,0 +1,8 @@
1
+ # Default owners for everything
2
+ * @claudesystemblueio
3
+
4
+ # Core audio analysis
5
+ src/sounddiff/loudness.py @claudesystemblueio
6
+ src/sounddiff/spectral.py @claudesystemblueio
7
+ src/sounddiff/temporal.py @claudesystemblueio
8
+ src/sounddiff/detection.py @claudesystemblueio
@@ -0,0 +1 @@
1
+ github: [systemblueteam]
@@ -0,0 +1,62 @@
1
+ name: Bug Report
2
+ description: Report a bug in sounddiff
3
+ title: "[Bug]: "
4
+ labels: ["bug"]
5
+ body:
6
+ - type: textarea
7
+ id: description
8
+ attributes:
9
+ label: What happened?
10
+ description: A clear description of the bug.
11
+ placeholder: When I run sounddiff on two WAV files...
12
+ validations:
13
+ required: true
14
+ - type: textarea
15
+ id: expected
16
+ attributes:
17
+ label: What did you expect?
18
+ description: What should have happened instead.
19
+ validations:
20
+ required: true
21
+ - type: textarea
22
+ id: reproduce
23
+ attributes:
24
+ label: Steps to reproduce
25
+ description: Minimal steps to reproduce the issue.
26
+ placeholder: |
27
+ 1. Run `sounddiff a.wav b.wav`
28
+ 2. See error...
29
+ validations:
30
+ required: true
31
+ - type: input
32
+ id: version
33
+ attributes:
34
+ label: sounddiff version
35
+ description: Output of `sounddiff --version`
36
+ placeholder: "0.1.0"
37
+ validations:
38
+ required: true
39
+ - type: input
40
+ id: python
41
+ attributes:
42
+ label: Python version
43
+ description: Output of `python --version`
44
+ placeholder: "3.12.0"
45
+ validations:
46
+ required: true
47
+ - type: dropdown
48
+ id: os
49
+ attributes:
50
+ label: Operating system
51
+ options:
52
+ - macOS
53
+ - Linux
54
+ - Windows
55
+ - Other
56
+ validations:
57
+ required: true
58
+ - type: textarea
59
+ id: audio
60
+ attributes:
61
+ label: Audio file details
62
+ description: Format, sample rate, channels, duration of the files involved (if relevant).
@@ -0,0 +1 @@
1
+ blank_issues_enabled: true
@@ -0,0 +1,35 @@
1
+ name: Feature Request
2
+ description: Suggest a new feature for sounddiff
3
+ title: "[Feature]: "
4
+ labels: ["enhancement"]
5
+ body:
6
+ - type: textarea
7
+ id: problem
8
+ attributes:
9
+ label: What problem does this solve?
10
+ description: Describe the use case or workflow this feature would improve.
11
+ validations:
12
+ required: true
13
+ - type: textarea
14
+ id: solution
15
+ attributes:
16
+ label: Proposed solution
17
+ description: How do you think this should work? CLI interface, output format, etc.
18
+ validations:
19
+ required: true
20
+ - type: textarea
21
+ id: alternatives
22
+ attributes:
23
+ label: Alternatives considered
24
+ description: Any other approaches you've thought about.
25
+ - type: dropdown
26
+ id: area
27
+ attributes:
28
+ label: Area
29
+ options:
30
+ - Audio analysis
31
+ - CLI / UX
32
+ - Output formats
33
+ - Performance
34
+ - Documentation
35
+ - Other
@@ -0,0 +1,15 @@
1
+ ## What changed
2
+
3
+ <!-- Brief description of the changes -->
4
+
5
+ ## Why
6
+
7
+ <!-- Motivation: what problem does this solve? -->
8
+
9
+ ## How to verify
10
+
11
+ <!-- Steps to test this change -->
12
+
13
+ ## Closes
14
+
15
+ <!-- Closes #issue_number -->
@@ -0,0 +1,33 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ |---------|--------------------|
7
+ | 0.1.x | :white_check_mark: |
8
+
9
+ ## Reporting a Vulnerability
10
+
11
+ If you discover a security vulnerability, please report it responsibly.
12
+
13
+ **Do not open a public issue.**
14
+
15
+ Email security concerns to **dev@systemblue.io** with:
16
+
17
+ 1. Description of the vulnerability
18
+ 2. Steps to reproduce
19
+ 3. Potential impact
20
+ 4. Suggested fix (if any)
21
+
22
+ We will acknowledge receipt within 48 hours and provide a timeline for a fix. Security patches are prioritized over all other work.
23
+
24
+ ## Scope
25
+
26
+ sounddiff processes audio files from disk. Relevant security concerns include:
27
+
28
+ - Path traversal in file handling
29
+ - Denial of service via malformed audio files
30
+ - Dependency vulnerabilities
31
+ - Secret leakage in CI/CD
32
+
33
+ We run [gitleaks](https://github.com/gitleaks/gitleaks) in CI and as a pre-commit hook to prevent accidental secret commits.
@@ -0,0 +1,23 @@
1
+ audio-core:
2
+ - changed-files:
3
+ - any-glob-to-any-file:
4
+ - src/sounddiff/loudness.py
5
+ - src/sounddiff/spectral.py
6
+ - src/sounddiff/temporal.py
7
+ - src/sounddiff/detection.py
8
+
9
+ cli:
10
+ - changed-files:
11
+ - any-glob-to-any-file:
12
+ - src/sounddiff/cli.py
13
+
14
+ docs:
15
+ - changed-files:
16
+ - any-glob-to-any-file:
17
+ - docs/**
18
+ - "*.md"
19
+
20
+ tests:
21
+ - changed-files:
22
+ - any-glob-to-any-file:
23
+ - tests/**
@@ -0,0 +1,49 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: actions/setup-python@v5
15
+ with:
16
+ python-version: "3.13"
17
+ - name: Install dependencies
18
+ run: pip install -e ".[dev]"
19
+ - name: Ruff lint
20
+ run: ruff check .
21
+ - name: Ruff format
22
+ run: ruff format --check .
23
+ - name: mypy
24
+ run: mypy src
25
+
26
+ test:
27
+ runs-on: ubuntu-latest
28
+ strategy:
29
+ matrix:
30
+ python-version: ["3.10", "3.13"]
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+ - uses: actions/setup-python@v5
34
+ with:
35
+ python-version: ${{ matrix.python-version }}
36
+ - name: Install system dependencies
37
+ run: sudo apt-get update && sudo apt-get install -y libsndfile1
38
+ - name: Install dependencies
39
+ run: pip install -e ".[dev]"
40
+ - name: Generate test audio
41
+ run: python scripts/generate_test_audio.py
42
+ - name: Run tests
43
+ run: pytest --cov=sounddiff --cov-report=xml
44
+ - name: Upload coverage
45
+ if: matrix.python-version == '3.13'
46
+ uses: codecov/codecov-action@v4
47
+ with:
48
+ file: ./coverage.xml
49
+ fail_ci_if_error: false
@@ -0,0 +1,17 @@
1
+ name: Labeler
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize]
6
+
7
+ permissions:
8
+ contents: read
9
+ pull-requests: write
10
+
11
+ jobs:
12
+ label:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/labeler@v5
16
+ with:
17
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,55 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ build:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.13"
20
+ - name: Install build tools
21
+ run: pip install build
22
+ - name: Build sdist and wheel
23
+ run: python -m build
24
+ - name: Upload artifacts
25
+ uses: actions/upload-artifact@v4
26
+ with:
27
+ name: dist
28
+ path: dist/
29
+
30
+ publish:
31
+ needs: build
32
+ runs-on: ubuntu-latest
33
+ environment: pypi
34
+ permissions:
35
+ id-token: write
36
+ steps:
37
+ - name: Download artifacts
38
+ uses: actions/download-artifact@v4
39
+ with:
40
+ name: dist
41
+ path: dist/
42
+ - name: Publish to PyPI
43
+ uses: pypa/gh-action-pypi-publish@release/v1
44
+
45
+ github-release:
46
+ needs: build
47
+ runs-on: ubuntu-latest
48
+ permissions:
49
+ contents: write
50
+ steps:
51
+ - uses: actions/checkout@v4
52
+ - name: Create GitHub Release
53
+ uses: softprops/action-gh-release@v2
54
+ with:
55
+ generate_release_notes: true
@@ -0,0 +1,23 @@
1
+ name: Sentry Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ sentry-release:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ with:
14
+ fetch-depth: 0
15
+ - name: Create Sentry Release
16
+ uses: getsentry/action-release@v3
17
+ env:
18
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
19
+ SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
20
+ SENTRY_PROJECT: sounddiff
21
+ with:
22
+ environment: production
23
+ version: ${{ github.ref_name }}
@@ -0,0 +1,43 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg-info/
7
+ *.egg
8
+ dist/
9
+ build/
10
+ .eggs/
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+ ENV/
16
+
17
+ # IDE
18
+ .idea/
19
+ .vscode/
20
+ *.swp
21
+ *.swo
22
+ *~
23
+ .DS_Store
24
+
25
+ # Testing
26
+ .pytest_cache/
27
+ .coverage
28
+ htmlcov/
29
+ .mypy_cache/
30
+ .ruff_cache/
31
+ .hypothesis/
32
+
33
+ # Distribution
34
+ *.whl
35
+ *.tar.gz
36
+
37
+ # Generated test audio
38
+ tests/fixtures/*.wav
39
+ tests/fixtures/*.flac
40
+
41
+ # Environment
42
+ .env
43
+ .env.*
@@ -0,0 +1,19 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.9.0
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+ - repo: https://github.com/pre-commit/mirrors-mypy
9
+ rev: v1.14.0
10
+ hooks:
11
+ - id: mypy
12
+ additional_dependencies: [types-click]
13
+ args: [--config-file=pyproject.toml]
14
+ pass_filenames: false
15
+ entry: mypy src
16
+ - repo: https://github.com/gitleaks/gitleaks
17
+ rev: v8.22.0
18
+ hooks:
19
+ - id: gitleaks
@@ -0,0 +1,38 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-03-26
9
+
10
+ ### Added
11
+
12
+ - Integrated LUFS comparison (ITU-R BS.1770 via pyloudnorm)
13
+ - True peak measurement (dBTP)
14
+ - Loudness range (LRA) comparison per EBU R128
15
+ - Spectral band energy comparison (low/mid/high, configurable bands)
16
+ - Waveform cross-correlation for segment similarity scoring
17
+ - Segment change detection: added, removed, shifted, or changed sections
18
+ - Clipping detection with timestamp, channel, and sample count
19
+ - Silence detection with configurable threshold and minimum duration
20
+ - Audio file loading via soundfile (WAV, FLAC, OGG, AIFF)
21
+ - CLI with click: `sounddiff <file1> <file2>`
22
+ - Terminal output with rich (colored, grouped by category)
23
+ - JSON output for scripts and CI pipelines
24
+ - HTML report output (self-contained, jinja2 templates)
25
+ - `--no-color` flag for plain terminal output
26
+ - `--version` flag
27
+ - Sample rate mismatch warnings
28
+ - Duration difference display in metadata section
29
+ - Test suite with 60 tests (pytest + hypothesis)
30
+ - CI pipeline (Python 3.10, 3.13 on Ubuntu)
31
+ - Documentation (install, usage, API reference, architecture)
32
+
33
+ ### Fixed
34
+
35
+ - Terminal output no longer prints twice
36
+ - Spectral band delta no longer shows absurd values for near-zero energy bands
37
+
38
+ [0.1.0]: https://github.com/systemblueteam/sounddiff/releases/tag/v0.1.0
@@ -0,0 +1,50 @@
1
+ # sounddiff
2
+
3
+ Structured audio comparison CLI. Python 3.10+, src layout, hatchling build.
4
+
5
+ ## Build & Test
6
+
7
+ ```sh
8
+ pip install -e ".[dev]"
9
+ python scripts/generate_test_audio.py
10
+ pytest
11
+ ruff check . && ruff format --check . && mypy src
12
+ ```
13
+
14
+ ## Architecture
15
+
16
+ ```
17
+ src/sounddiff/
18
+ types.py # Dataclasses for all results
19
+ formats.py # Audio I/O via soundfile
20
+ loudness.py # LUFS, true peak, LRA (pyloudnorm)
21
+ spectral.py # Band energy comparison (numpy FFT)
22
+ temporal.py # Cross-correlation, segment detection
23
+ detection.py # Clipping, silence detection
24
+ core.py # Pipeline orchestration
25
+ cli.py # Click CLI entry point
26
+ report.py # Output formatters (terminal/JSON/HTML)
27
+ ```
28
+
29
+ ## Conventions
30
+
31
+ - **Ruff** for linting and formatting. No black, isort, or flake8.
32
+ - **mypy strict mode.** Type hints everywhere.
33
+ - **Google-style docstrings** on all public functions.
34
+ - **Conventional commits.** `feat:`, `fix:`, `docs:`, `test:`, `chore:`, `refactor:`.
35
+ - **One concern per PR.** Small, focused diffs. Squash merge.
36
+ - **pytest + hypothesis** for testing. Property-based tests for DSP functions.
37
+ - **Test audio is generated, not committed.** Run `scripts/generate_test_audio.py`.
38
+ - **No `# type: ignore` without a comment.**
39
+
40
+ ## Key dependencies
41
+
42
+ | Package | Purpose |
43
+ |---------|---------|
44
+ | soundfile | Audio I/O (wav, flac, ogg, aiff) |
45
+ | numpy | Array math, FFT, correlation |
46
+ | scipy | Signal processing, filtering |
47
+ | pyloudnorm | ITU-R BS.1770 LUFS measurement |
48
+ | click | CLI framework |
49
+ | rich | Terminal formatting |
50
+ | jinja2 | HTML report templates |
@@ -0,0 +1,41 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment:
12
+
13
+ * Using welcoming and inclusive language
14
+ * Being respectful of differing viewpoints and experiences
15
+ * Gracefully accepting constructive criticism
16
+ * Focusing on what is best for the community
17
+ * Showing empathy towards other community members
18
+
19
+ Examples of unacceptable behavior:
20
+
21
+ * The use of sexualized language or imagery and unwelcome sexual attention or advances
22
+ * Trolling, insulting/derogatory comments, and personal or political attacks
23
+ * Public or private harassment
24
+ * Publishing others' private information without explicit permission
25
+ * Other conduct which could reasonably be considered inappropriate in a professional setting
26
+
27
+ ## Enforcement Responsibilities
28
+
29
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
30
+
31
+ ## Scope
32
+
33
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces.
34
+
35
+ ## Enforcement
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the project maintainers at dev@systemblue.io. All complaints will be reviewed and investigated promptly and fairly.
38
+
39
+ ## Attribution
40
+
41
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
@@ -0,0 +1,80 @@
1
+ # Contributing to sounddiff
2
+
3
+ Contributions are welcome. This guide covers everything you need to get set up and submit a pull request.
4
+
5
+ ## Development setup
6
+
7
+ 1. Fork and clone the repo
8
+ 2. Create a virtual environment: `python -m venv .venv && source .venv/bin/activate`
9
+ 3. Install dev dependencies: `pip install -e ".[dev]"`
10
+ 4. Install pre-commit hooks: `pre-commit install`
11
+ 5. Generate test audio fixtures: `python scripts/generate_test_audio.py`
12
+ 6. Run the test suite: `pytest`
13
+
14
+ If all tests pass, your environment is ready.
15
+
16
+ ## Finding work
17
+
18
+ The [issue board](https://github.com/systemblueteam/sounddiff/issues) is organized by milestone. Issues labeled [`good first issue`](https://github.com/systemblueteam/sounddiff/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) are scoped for newcomers and include enough context to get started without deep DSP knowledge.
19
+
20
+ If you want to work on something, leave a comment on the issue so nobody duplicates effort. If you have an idea that isn't on the board, open an issue first so we can align on scope before you write code.
21
+
22
+ ## Development workflow
23
+
24
+ 1. Create a branch from `main`: `git checkout -b feat/42-your-description`
25
+ 2. Make your changes and write tests for new behavior
26
+ 3. Run the full check: `ruff check . && ruff format --check . && mypy src && pytest`
27
+ 4. Commit using [conventional commits](https://www.conventionalcommits.org/): `feat: add stereo field analysis`
28
+ 5. Push your branch and open a PR against `main`
29
+
30
+ ## Pull request guidelines
31
+
32
+ - **One concern per PR.** Keep diffs focused and reviewable.
33
+ - **Reference the issue** in your PR body: `Closes #42`
34
+ - **CI must pass** before review. The pipeline runs ruff, mypy, and pytest across Python 3.10-3.13 on Linux and macOS.
35
+ - **[CodeRabbit](https://coderabbit.ai) reviews every PR automatically.** Address its feedback or explain your reasoning if you disagree.
36
+ - Maintainers will review within a few days. If a week goes by without a response, ping us in the PR.
37
+
38
+ ## Code standards
39
+
40
+ **Formatting and linting** are handled by [ruff](https://docs.astral.sh/ruff/). Pre-commit hooks run automatically, so you don't need to think about formatting manually.
41
+
42
+ **Type annotations** are required on all public functions. [mypy](https://mypy.readthedocs.io/) runs in strict mode.
43
+
44
+ **Docstrings** follow [Google style](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) on public functions. Private functions (underscore-prefixed) don't require them.
45
+
46
+ **No `# type: ignore`** without a comment explaining why.
47
+
48
+ ## Testing
49
+
50
+ Every new feature needs tests. Every bug fix needs a regression test.
51
+
52
+ We use [pytest](https://docs.pytest.org/) for the test suite and [hypothesis](https://hypothesis.readthedocs.io/) for property-based testing on DSP functions. Test audio is generated deterministically by `scripts/generate_test_audio.py` and is not committed to the repo. This keeps the repo lightweight and tests reproducible.
53
+
54
+ If you're unsure how to test something, ask in the issue. We'd rather help you write a good test than skip testing.
55
+
56
+ ## Conventions
57
+
58
+ ### Branch naming
59
+
60
+ Include the issue number when there is one:
61
+
62
+ - `feat/42-segment-detection`
63
+ - `fix/17-clipping-threshold`
64
+ - `docs/8-usage-guide`
65
+ - `chore/12-ci-update`
66
+
67
+ ### Commit messages
68
+
69
+ ```text
70
+ feat: add spectral band comparison
71
+ fix: handle mono files in loudness calculation
72
+ docs: add installation guide
73
+ test: add property tests for temporal alignment
74
+ chore: update CI to Python 3.13
75
+ refactor: extract segment detection into its own module
76
+ ```
77
+
78
+ ## Questions
79
+
80
+ Open an [issue](https://github.com/systemblueteam/sounddiff/issues). We're happy to help with anything from setup problems to architecture questions.