sox-effects 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.
@@ -0,0 +1,14 @@
1
+ version: 2
2
+
3
+ updates:
4
+ - package-ecosystem: github-actions
5
+ directory: "/"
6
+ schedule:
7
+ interval: yearly
8
+ open-pull-requests-limit: 1
9
+ cooldown:
10
+ default-days: 30
11
+ groups:
12
+ actions:
13
+ patterns:
14
+ - "*"
@@ -0,0 +1,186 @@
1
+ name: CI
2
+ permissions: {}
3
+
4
+ on:
5
+ push:
6
+ branches:
7
+ - main
8
+ pull_request:
9
+ branches:
10
+ - main
11
+ workflow_call: # Called by the release workflow, which publishes the dists built here.
12
+
13
+ concurrency:
14
+ group: ci-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ lint:
19
+ name: Linters
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
23
+ steps:
24
+ - name: Checkout code
25
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
26
+ with:
27
+ persist-credentials: false
28
+
29
+ - name: zizmor
30
+ uses: zizmorcore/zizmor-action@45d7276c9ca790aabd705e31ca99c6185c3e76dd # v0.8.1
31
+
32
+ - name: Install SoX
33
+ run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libsox-dev # ty builds the package
34
+
35
+ - name: prek
36
+ uses: j178/prek-action@1382ad72dea72f9d53832f2bcb65b3e87a947204 # v3.0.1
37
+
38
+ test:
39
+ name: Test source code (${{ matrix.os }}, Python ${{ matrix.python-version }})
40
+ runs-on: ${{ matrix.os }}
41
+ needs: lint
42
+ strategy:
43
+ fail-fast: false
44
+ matrix:
45
+ os:
46
+ - ubuntu-latest
47
+ - macos-latest
48
+ python-version:
49
+ - "3.12"
50
+ - "3.13"
51
+ - "3.14"
52
+ steps:
53
+ - name: Checkout code
54
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
55
+ with:
56
+ persist-credentials: false
57
+
58
+ - name: Install SoX (Linux)
59
+ if: runner.os == 'Linux'
60
+ run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libsox-dev sox
61
+
62
+ - name: Install SoX (macOS)
63
+ if: runner.os == 'macOS'
64
+ run: brew install sox
65
+
66
+ - name: Install uv
67
+ uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
68
+ with:
69
+ version: "latest"
70
+ enable-cache: false
71
+ python-version: ${{ matrix.python-version }}
72
+
73
+ - name: Run tests
74
+ run: uv run --locked --group test pytest
75
+
76
+ test-lowest:
77
+ name: Test with the lowest supported dependencies (${{ matrix.os }})
78
+ runs-on: ${{ matrix.os }}
79
+ needs: lint
80
+ strategy:
81
+ fail-fast: false
82
+ matrix:
83
+ os:
84
+ - ubuntu-latest
85
+ - macos-latest
86
+ steps:
87
+ - name: Checkout code
88
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
89
+ with:
90
+ persist-credentials: false
91
+
92
+ - name: Install SoX (Linux)
93
+ if: runner.os == 'Linux'
94
+ run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libsox-dev sox
95
+
96
+ - name: Install SoX (macOS)
97
+ if: runner.os == 'macOS'
98
+ run: brew install sox
99
+
100
+ - name: Install uv
101
+ uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
102
+ with:
103
+ version: "latest"
104
+ enable-cache: false
105
+ python-version: "3.12"
106
+
107
+ - name: Lock the lowest dependencies
108
+ run: uv lock --resolution lowest-direct
109
+
110
+ - name: Run tests
111
+ run: uv run --locked --resolution lowest-direct --group test pytest
112
+
113
+ build-wheels:
114
+ name: Build wheels (${{ matrix.os }})
115
+ runs-on: ${{ matrix.os }}
116
+ needs: [test, test-lowest]
117
+ strategy:
118
+ fail-fast: false
119
+ matrix:
120
+ os:
121
+ - ubuntu-22.04
122
+ - ubuntu-22.04-arm
123
+ - macos-15
124
+ permissions:
125
+ artifact-metadata: write # Create the artifact storage record
126
+ attestations: write # Write the build provenance to the repository attestation store
127
+ id-token: write # Sigstore signing of the provenance
128
+ steps:
129
+ - name: Checkout code
130
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
131
+ with:
132
+ persist-credentials: false
133
+ fetch-depth: 0 # setuptools-scm needs the tags
134
+
135
+ - name: Build wheels
136
+ uses: pypa/cibuildwheel@f9b966cfadf4109556cadc5bb39ddb72d0ce664e # v4.3.5
137
+ with:
138
+ output-dir: dist
139
+
140
+ - name: Attest build provenance
141
+ if: startsWith(github.ref, 'refs/tags/')
142
+ uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
143
+ with:
144
+ subject-path: dist/*.whl
145
+
146
+ - name: Upload wheels
147
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
148
+ with:
149
+ name: dist-wheels-${{ matrix.os }}
150
+ path: dist/*.whl
151
+
152
+ build-sdist:
153
+ name: Build sdist
154
+ runs-on: ubuntu-latest
155
+ needs: [test, test-lowest]
156
+ permissions:
157
+ artifact-metadata: write # Create the artifact storage record
158
+ attestations: write # Write the build provenance to the repository attestation store
159
+ id-token: write # Sigstore signing of the provenance
160
+ steps:
161
+ - name: Checkout code
162
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
163
+ with:
164
+ persist-credentials: false
165
+ fetch-depth: 0 # setuptools-scm needs the tags to compute the version
166
+
167
+ - name: Install uv
168
+ uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
169
+ with:
170
+ version: "latest"
171
+ enable-cache: false
172
+
173
+ - name: Build sdist
174
+ run: uv build --sdist
175
+
176
+ - name: Attest build provenance
177
+ if: startsWith(github.ref, 'refs/tags/')
178
+ uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
179
+ with:
180
+ subject-path: dist/*.tar.gz
181
+
182
+ - name: Upload sdist
183
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
184
+ with:
185
+ name: dist-sdist
186
+ path: dist/*.tar.gz
@@ -0,0 +1,75 @@
1
+ name: Release workflow
2
+ permissions: {}
3
+
4
+ on:
5
+ push:
6
+ tags:
7
+ - "*"
8
+
9
+ concurrency:
10
+ group: release-${{ github.ref }}
11
+ cancel-in-progress: false
12
+
13
+ jobs:
14
+ ci:
15
+ name: CI
16
+ uses: $/.github/workflows/ci.yml
17
+ # The called jobs can't get more than what is granted here: this is the union of what they request.
18
+ permissions:
19
+ security-events: write # Upload zizmor's SARIF report
20
+ artifact-metadata: write # Create the artifact storage record
21
+ attestations: write # Write the build provenance to the repository attestation store
22
+ id-token: write # Sigstore signing of the provenance
23
+
24
+ publish-to-pypi:
25
+ name: Publish to PyPI
26
+ runs-on: ubuntu-latest
27
+ needs: ci
28
+ environment:
29
+ name: publish-to-pypi
30
+ permissions:
31
+ id-token: write # Needed for trusted publishing, and to sign the attestations
32
+ steps:
33
+ - name: Download all dists
34
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
35
+ with:
36
+ pattern: dist-*
37
+ merge-multiple: true
38
+ path: dist/
39
+
40
+ - name: Install uv
41
+ uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
42
+ with:
43
+ version: "latest"
44
+ enable-cache: false
45
+
46
+ - name: Generate PEP 740 attestations
47
+ uses: astral-sh/attest-action@f589a42a7efb6fe400b4f400de60b4bc90390027 # v0.0.6
48
+
49
+ - name: Upload to PyPI
50
+ run: uv publish --trusted-publishing always
51
+
52
+ github-release:
53
+ name: GitHub release
54
+ runs-on: ubuntu-latest
55
+ needs: publish-to-pypi # Only tag a release once it is actually on PyPI.
56
+ permissions:
57
+ contents: write # Create GitHub release
58
+ steps:
59
+ - name: Checkout code
60
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
61
+ with:
62
+ persist-credentials: false
63
+
64
+ - name: Download all dists
65
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
66
+ with:
67
+ pattern: dist-*
68
+ merge-multiple: true
69
+ path: ./dist/
70
+
71
+ - name: Create release
72
+ env:
73
+ GITHUB_TOKEN: ${{ github.token }}
74
+ TAG: ${{ github.ref_name }}
75
+ run: gh release create "$TAG" --verify-tag ./dist/*
@@ -0,0 +1,12 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+ *.so
12
+ .pytest_cache
@@ -0,0 +1,31 @@
1
+ cmake_minimum_required(VERSION 3.20)
2
+ project(${SKBUILD_PROJECT_NAME} LANGUAGES CXX)
3
+
4
+ find_package(Python 3.12 REQUIRED COMPONENTS Interpreter Development.Module ${SKBUILD_SABI_COMPONENT})
5
+ find_package(nanobind CONFIG REQUIRED)
6
+
7
+ if(NOT "$ENV{SOX_ROOT}" STREQUAL "")
8
+ find_path(SOX_INCLUDE_DIR sox.h PATHS "$ENV{SOX_ROOT}/include" PATH_SUFFIXES sox NO_DEFAULT_PATH)
9
+ else()
10
+ find_program(SOX_EXECUTABLE sox)
11
+ if(SOX_EXECUTABLE)
12
+ file(REAL_PATH "${SOX_EXECUTABLE}" _sox)
13
+ cmake_path(GET _sox PARENT_PATH _sox_bin)
14
+ cmake_path(GET _sox_bin PARENT_PATH _sox_root)
15
+ endif()
16
+ find_path(
17
+ SOX_INCLUDE_DIR sox.h
18
+ HINTS "${_sox_root}/include"
19
+ PATHS /usr/include /usr/local/include /opt/homebrew/include
20
+ PATH_SUFFIXES sox # RHEL/Fedora sox-devel installs include/sox/sox.h
21
+ )
22
+ endif()
23
+ if(NOT SOX_INCLUDE_DIR)
24
+ message(FATAL_ERROR "sox.h not found: install the libsox headers (libsox-dev, sox-devel, brew install sox) or set SOX_ROOT")
25
+ endif()
26
+
27
+ nanobind_add_module(_C STABLE_ABI NB_STATIC src/sox_effects/sox_effects.cpp)
28
+ target_compile_features(_C PRIVATE cxx_std_17)
29
+ target_include_directories(_C PRIVATE "${SOX_INCLUDE_DIR}")
30
+ target_link_libraries(_C PRIVATE ${CMAKE_DL_LIBS})
31
+ install(TARGETS _C LIBRARY DESTINATION sox_effects)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Maxime Poli.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: sox-effects
3
+ Version: 0.1.0
4
+ Summary: Minimal libsox effects bindings for any array
5
+ Author: Maxime Poli
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.12
8
+ Description-Content-Type: text/markdown
9
+
10
+ # sox-effects
11
+
12
+ Apply [SoX](https://sox.sourceforge.net/) audio effects (pitch, reverb, tempo, gain, …) directly to arrays from
13
+ NumPy, PyTorch, JAX, or any library that supports DLPack or the buffer protocol. It has no Python dependencies,
14
+ and replaces `torchaudio.sox_effects.apply_effects_tensor`, which was removed from torchaudio.
15
+
16
+ ## Installation
17
+
18
+ ```sh
19
+ pip install sox-effects
20
+ ```
21
+
22
+ You'll also need the SoX library on your system:
23
+
24
+ ```sh
25
+ apt install libsox3 # Debian / Ubuntu
26
+ dnf install sox # Fedora / RHEL
27
+ brew install sox # macOS
28
+ ```
29
+
30
+ It works with Python >= 3.12, on Linux and macOS.
31
+
32
+ ## Quick start
33
+
34
+ ```python
35
+ import numpy as np, sox_effects
36
+
37
+ wav = np.random.randn(2, 16000).astype(np.float32) * 0.1 # (channels, time), float32, CPU
38
+ out, sr = sox_effects.apply_effects(
39
+ wav, 16000, [["gain", "-n"], ["pitch", "200"], ["reverb", "50"], ["rate", "16000"]]
40
+ )
41
+ sox_effects.effect_names() # list the available effects
42
+ ```
43
+
44
+ Effects and their arguments are the same as on the `sox` command line. The output comes back in the same
45
+ library as the input (a torch tensor in, a torch tensor out), without copies at the boundaries.
46
+ For `(time, channels)` arrays, pass `channels_first=False`.
47
+
48
+ ### Random augmentation
49
+
50
+ `EffectChain` lets you build a chain of effects step by step. Every SoX effect is available as a
51
+ method, and any argument given as a function is re-drawn each time you call `apply`:
52
+
53
+ ```python
54
+ import random
55
+ from sox_effects import EffectChain
56
+
57
+ chain = EffectChain().pitch("-q", lambda: random.randint(-300, 300)).rate(16000).reverb(50).channels(1)
58
+ out, sr = chain.apply(wav, 16000)
59
+ ```
60
+
61
+ ## Good to know
62
+
63
+ - **Inputs are strict.** Arrays must be 2D, float32 and on the CPU: anything else raises an error.
64
+ SoX effects aren't differentiable, so torch tensors that require grad are rejected too: call
65
+ `.detach()` first (no copy) to cut the gradient explicitly. Dataset tensors used for augmentation
66
+ don't require grad, so this only concerns outputs of a network.
67
+ - **Keep values in [-1, 1].** SoX silently clips anything outside this range, including what an
68
+ effect pushes past full scale (e.g. `gain +10`). Use `["gain", "-n"]` or `vol` to stay safe.
69
+ - **The output may change shape.** `speed`, `pitch` and `tempo` change the length, and `speed` and
70
+ `pitch` also change the sample rate: add `["rate", "<sr>"]` to get back to your rate. `reverb`
71
+ turns mono into stereo: add `["channels", "1"]`. Nothing is added for you, so with a
72
+ `DataLoader` you may need to crop/pad or use a custom `collate_fn`.
73
+ - **Always pass arguments.** SoX's defaults aren't always sensible: `["tempo"]` on its own never
74
+ returns.
75
+ - **Go faster with `-q`.** For augmentation, quick mode trades a little quality for speed:
76
+ `["pitch", "-q", "200"]`, `["tempo", "-q", "1.1"]`, `["rate", "-q", "16000"]` (the latter can
77
+ alias). Put `-q` before the effect's other arguments.
78
+ - **Parallelism.** Threads run in parallel, but `DataLoader` worker processes are the safer choice.
79
+ With `spawn`/`forkserver` workers, use regular functions instead of lambdas in an `EffectChain`
80
+ (lambdas can't be pickled).
81
+ - Effects that read or write files (`spectrogram`, `noiseprof`, `noisered`, `splice`) aren't supported.
82
+
83
+ ## Troubleshooting
84
+
85
+ `import sox_effects` always works; the SoX library is only loaded on the first call. If it can't be
86
+ found, install it as shown above, or point `LIBSOX_PATH` to the library file (e.g.
87
+ `libsox.so.3`).
88
+
89
+ ## Development
90
+
91
+ The extension is built with [nanobind](https://github.com/wjakob/nanobind) and
92
+ [scikit-build-core](https://github.com/scikit-build/scikit-build-core). Building from source only needs the
93
+ `sox.h` header, which is looked up in `$SOX_ROOT/include`, next to the `sox` executable on your `PATH`, or in
94
+ `/usr`, `/usr/local` and `/opt/homebrew` (as `include/sox.h` or `include/sox/sox.h`).
95
+
96
+ ```sh
97
+ uv run --group test pytest # or: pip install . --group test && pytest
98
+ ```
99
+
100
+ The tests run against NumPy, PyTorch and JAX, which are test dependencies only.
101
+
102
+ The extension uses the Python stable ABI, so a single build works across all Python versions >= 3.12.
103
+
104
+ ## License
105
+
106
+ sox-effects is released under the MIT License. It builds on the approach from
107
+ [torchaudio](https://github.com/pytorch/audio) (BSD 2-Clause License) and
108
+ [WavAugment](https://github.com/facebookresearch/WavAugment) (MIT License).
@@ -0,0 +1,99 @@
1
+ # sox-effects
2
+
3
+ Apply [SoX](https://sox.sourceforge.net/) audio effects (pitch, reverb, tempo, gain, …) directly to arrays from
4
+ NumPy, PyTorch, JAX, or any library that supports DLPack or the buffer protocol. It has no Python dependencies,
5
+ and replaces `torchaudio.sox_effects.apply_effects_tensor`, which was removed from torchaudio.
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ pip install sox-effects
11
+ ```
12
+
13
+ You'll also need the SoX library on your system:
14
+
15
+ ```sh
16
+ apt install libsox3 # Debian / Ubuntu
17
+ dnf install sox # Fedora / RHEL
18
+ brew install sox # macOS
19
+ ```
20
+
21
+ It works with Python >= 3.12, on Linux and macOS.
22
+
23
+ ## Quick start
24
+
25
+ ```python
26
+ import numpy as np, sox_effects
27
+
28
+ wav = np.random.randn(2, 16000).astype(np.float32) * 0.1 # (channels, time), float32, CPU
29
+ out, sr = sox_effects.apply_effects(
30
+ wav, 16000, [["gain", "-n"], ["pitch", "200"], ["reverb", "50"], ["rate", "16000"]]
31
+ )
32
+ sox_effects.effect_names() # list the available effects
33
+ ```
34
+
35
+ Effects and their arguments are the same as on the `sox` command line. The output comes back in the same
36
+ library as the input (a torch tensor in, a torch tensor out), without copies at the boundaries.
37
+ For `(time, channels)` arrays, pass `channels_first=False`.
38
+
39
+ ### Random augmentation
40
+
41
+ `EffectChain` lets you build a chain of effects step by step. Every SoX effect is available as a
42
+ method, and any argument given as a function is re-drawn each time you call `apply`:
43
+
44
+ ```python
45
+ import random
46
+ from sox_effects import EffectChain
47
+
48
+ chain = EffectChain().pitch("-q", lambda: random.randint(-300, 300)).rate(16000).reverb(50).channels(1)
49
+ out, sr = chain.apply(wav, 16000)
50
+ ```
51
+
52
+ ## Good to know
53
+
54
+ - **Inputs are strict.** Arrays must be 2D, float32 and on the CPU: anything else raises an error.
55
+ SoX effects aren't differentiable, so torch tensors that require grad are rejected too: call
56
+ `.detach()` first (no copy) to cut the gradient explicitly. Dataset tensors used for augmentation
57
+ don't require grad, so this only concerns outputs of a network.
58
+ - **Keep values in [-1, 1].** SoX silently clips anything outside this range, including what an
59
+ effect pushes past full scale (e.g. `gain +10`). Use `["gain", "-n"]` or `vol` to stay safe.
60
+ - **The output may change shape.** `speed`, `pitch` and `tempo` change the length, and `speed` and
61
+ `pitch` also change the sample rate: add `["rate", "<sr>"]` to get back to your rate. `reverb`
62
+ turns mono into stereo: add `["channels", "1"]`. Nothing is added for you, so with a
63
+ `DataLoader` you may need to crop/pad or use a custom `collate_fn`.
64
+ - **Always pass arguments.** SoX's defaults aren't always sensible: `["tempo"]` on its own never
65
+ returns.
66
+ - **Go faster with `-q`.** For augmentation, quick mode trades a little quality for speed:
67
+ `["pitch", "-q", "200"]`, `["tempo", "-q", "1.1"]`, `["rate", "-q", "16000"]` (the latter can
68
+ alias). Put `-q` before the effect's other arguments.
69
+ - **Parallelism.** Threads run in parallel, but `DataLoader` worker processes are the safer choice.
70
+ With `spawn`/`forkserver` workers, use regular functions instead of lambdas in an `EffectChain`
71
+ (lambdas can't be pickled).
72
+ - Effects that read or write files (`spectrogram`, `noiseprof`, `noisered`, `splice`) aren't supported.
73
+
74
+ ## Troubleshooting
75
+
76
+ `import sox_effects` always works; the SoX library is only loaded on the first call. If it can't be
77
+ found, install it as shown above, or point `LIBSOX_PATH` to the library file (e.g.
78
+ `libsox.so.3`).
79
+
80
+ ## Development
81
+
82
+ The extension is built with [nanobind](https://github.com/wjakob/nanobind) and
83
+ [scikit-build-core](https://github.com/scikit-build/scikit-build-core). Building from source only needs the
84
+ `sox.h` header, which is looked up in `$SOX_ROOT/include`, next to the `sox` executable on your `PATH`, or in
85
+ `/usr`, `/usr/local` and `/opt/homebrew` (as `include/sox.h` or `include/sox/sox.h`).
86
+
87
+ ```sh
88
+ uv run --group test pytest # or: pip install . --group test && pytest
89
+ ```
90
+
91
+ The tests run against NumPy, PyTorch and JAX, which are test dependencies only.
92
+
93
+ The extension uses the Python stable ABI, so a single build works across all Python versions >= 3.12.
94
+
95
+ ## License
96
+
97
+ sox-effects is released under the MIT License. It builds on the approach from
98
+ [torchaudio](https://github.com/pytorch/audio) (BSD 2-Clause License) and
99
+ [WavAugment](https://github.com/facebookresearch/WavAugment) (MIT License).
@@ -0,0 +1,48 @@
1
+ exclude = "uv.lock"
2
+
3
+ [[repos]]
4
+ repo = "builtin"
5
+ hooks = [
6
+ { id = "trailing-whitespace" },
7
+ { id = "end-of-file-fixer" },
8
+ { id = "check-added-large-files" },
9
+ ]
10
+
11
+ [[repos]]
12
+ repo = "https://github.com/zizmorcore/zizmor-pre-commit"
13
+ rev = "v1.30.1"
14
+ hooks = [{ id = "zizmor" }]
15
+
16
+ [[repos]]
17
+ repo = "https://github.com/crate-ci/typos"
18
+ rev = "v1.51.1"
19
+ hooks = [{ id = "typos" }]
20
+
21
+ [[repos]]
22
+ repo = "https://github.com/tombi-toml/tombi-pre-commit"
23
+ rev = "v1.7.3"
24
+ hooks = [
25
+ # { id = "tombi-format" },
26
+ # { id = "tombi-lint" }, # Fail for [[tool.dynamic-metadata]]
27
+ ]
28
+
29
+ [[repos]]
30
+ repo = "https://github.com/astral-sh/ruff-pre-commit"
31
+ rev = "v0.17.0"
32
+ hooks = [
33
+ { id = "ruff-check", args = ["--fix"] },
34
+ { id = "ruff-format" },
35
+ ]
36
+
37
+ [[repos]]
38
+ repo = "https://github.com/astral-sh/uv-pre-commit"
39
+ rev = "0.13.0"
40
+ hooks = [
41
+ { id = "uv-lock" },
42
+ { id = "uv-audit" },
43
+ ]
44
+
45
+ [[repos]]
46
+ repo = "https://github.com/astral-sh/ty-pre-commit"
47
+ rev = "v0.0.99"
48
+ hooks = [{ id = "ty", args = ["--group", "test"] }]
@@ -0,0 +1,57 @@
1
+ [project]
2
+ name = "sox-effects"
3
+ description = "Minimal libsox effects bindings for any array"
4
+ readme = "README.md"
5
+ requires-python = ">=3.12"
6
+ license = "MIT"
7
+ authors = [{ name = "Maxime Poli" }]
8
+ dependencies = []
9
+ dynamic = ["version"]
10
+
11
+ [dependency-groups]
12
+ test = [
13
+ "jax>=0.12.0",
14
+ "numpy>=2.2.6",
15
+ "pytest>=9.2.0",
16
+ "torch>=2.10",
17
+ ]
18
+
19
+ [build-system]
20
+ requires = ["nanobind>=3.1.0", "scikit-build-core>=1.1.1", "setuptools-scm>=10.3.4"]
21
+ build-backend = "scikit_build_core.build"
22
+
23
+ [tool.cibuildwheel]
24
+ build = "cp312-*" # abi3: a single wheel per platform covers Python >= 3.12
25
+ skip = "*-musllinux_*"
26
+ test-command = "python -c \"import sox_effects; assert sox_effects.effect_names()\""
27
+
28
+ [tool.cibuildwheel.linux]
29
+ # sox.h for the build (sox-devel is in PowerTools on manylinux_2_28, CRB on manylinux_2_34), libsox for the test.
30
+ before-all = "dnf install -y 'dnf-command(config-manager)' && (dnf config-manager --set-enabled powertools || dnf config-manager --set-enabled crb) && dnf install -y sox-devel"
31
+
32
+ [tool.cibuildwheel.macos]
33
+ before-all = "brew install sox"
34
+
35
+ [[tool.dynamic-metadata]]
36
+ provider = "scikit_build_core.metadata.setuptools_scm"
37
+
38
+ [tool.ruff]
39
+ line-length = 119
40
+
41
+ [tool.scikit-build]
42
+ minimum-version = "build-system.requires"
43
+ build-dir = "build/{wheel_tag}"
44
+ wheel.py-api = "cp312"
45
+
46
+ [tool.setuptools_scm]
47
+
48
+ [tool.typos.default.extend-words]
49
+ writeable = "writeable"
50
+
51
+ [tool.uv]
52
+ cache-keys = [
53
+ { file = "pyproject.toml" },
54
+ { file = "CMakeLists.txt" },
55
+ { file = "src/sox_effects/sox_effects.cpp" },
56
+ { git = { commit = true, tags = true } },
57
+ ]