Skip to content

Latest commit

 

History

History
139 lines (105 loc) · 4.64 KB

File metadata and controls

139 lines (105 loc) · 4.64 KB

Contributing to Faustax

Thanks for your interest. Bug reports, DSP contributions and gradient-rule improvements are all welcome.

Setup

git clone https://github.com/DBraun/faustax
cd faustax
uv sync
uv run pytest

uv sync is enough for the whole test suite. The generated NNX modules are checked in, so you do not need the Faust compiler to work on Faustax — only to change a .dsp file or to work on runtime compilation.

The tests that do need Faust are marked needs_faust and skip automatically when no suitable build is found, so a plain uv run pytest is green either way. If you expected those tests to run and they skipped, check:

uv run python -c "from faustax.compile import has_nnx_backend; print(has_nnx_backend())"

Getting a Faust with the NNX backend

The NNX backend lives in Faust's master-dev branch and is not in a tagged release yet, so a Faust from Homebrew or apt will not have it. Build from source:

git clone --branch master-dev --depth 1 https://github.com/grame-cncm/faust
cd faust && make && sudo make install

Verify it — faust --version must list DSP to NNX:

$ faust --version
FAUST Version 2.87.0
Embedded backends:
   DSP to C
   DSP to C++
   DSP to NNX

Faustax finds the compiler from FAUST_BIN, then $PATH, and supports both layouts: a source checkout run out of its build tree (<root>/build/bin/faust, libraries at <root>/libraries) and an installed prefix (<prefix>/bin/faust, libraries at <prefix>/share/faust). Point at a non-default build with:

export FAUST_BIN=/path/to/faust/build/bin/faust

Adding or changing an effect

  1. Write or edit src/faustax/dsp/<name>.dsp.

  2. Regenerate the checked-in modules:

    uv run python tools/generate.py

    Commit the regenerated src/faustax/_generated/<name>.py along with the .dsp change. tools/generate.py rewrites the compiler's absolute paths to <faust> / <repo> placeholders, so the diff should not contain your home directory. If it does, run uv run python tools/generate.py --scrub-only.

  3. If the DSP pulls in a Faust library the repo has not used before, refresh the attribution table (see Licensing below).

  4. Add a test under tests/.

Licensing

Faustax is MIT, but the generated modules and two of the source modules carry third-party terms. NOTICE is the single place that records all of it, and CI checks that it stays complete.

  • Adding a .dsp that uses a new Faust library. The Faust compiler records every library and its per-function license declarations in each module's embedded json_metadata. Regenerate the attribution table and update NOTICE section 2:

    uv run python tools/collect_attribution.py          # print the table
    uv run python tools/collect_attribution.py --check  # what CI runs
  • Porting an algorithm from another project. Say so in the module docstring, naming the upstream project, its license and its copyright holder, and add an entry to NOTICE section 3. src/faustax/ops.py is the worked example.

  • Adding a dependency. Permissive licenses (MIT, BSD, Apache-2.0, ISC) can go in dependencies or dev. A copyleft dependency must not be a required one; put it in its own optional group and document it in NOTICE section 4, as dev-fdn / fdn_toolbox (GPL-3.0) is.

  • Do not commit dataset audio, or audio rendered from it. CI fails on any committed .wav, .mp3 or .flac.

By contributing you agree that your contribution is licensed under this repository's MIT license.

Style

Formatting and linting are handled by ruff via pre-commit. Install the hooks once and they run on every commit:

uv run pre-commit install
uv run pre-commit run --all-files   # or check everything by hand

The generated modules under _generated/ are excluded — never hand-edit them.

Beyond what the linter enforces:

  • Type hints and Google-style docstrings on public functions.
  • Explain what the code does now. Comments describing how it used to work belong in the commit message, not the source.
  • Prefer letting errors surface over defaulting them away: raise RuntimeError with a message that says what to do, rather than silently substituting a fallback value.

Tests

uv run pytest                     # everything that needs no Faust build
uv run pytest -k vectorize        # one area
uv run pytest --cov=faustax       # with coverage

Numerical changes need a test that pins the numbers. The vectorizer in particular is required to be bitwise-identical to the scalar module; see tests/test_vectorize.py for the comparison harness.