Skip to content

Repository files navigation

Build Status

csound

Csound bindings for Rust.

Documentation can be found here

Table of Contents

  1. Installation
    1. Linux
    2. macOS
    3. Windows
  2. Getting Started
  3. Running the tests
  4. License
  5. Contribution

To build the Csound bindings or anything depending on this crate, you need a Csound 7.0 or newer development installation. Csound 6.x is not supported: this crate targets the Csound 7 host API, which removed and renamed a substantial part of the 6.x interface (see the upstream API migration guide).

On Linux, csound-sys generates bindings from the installed Csound headers and dynamically links the matching system libcsound64. A normal user therefore does not need to initialize the Csound Git submodule. The submodule pins the source revision built by this repository's CI and is needed by maintainers when building that pinned Csound revision.

On every platform, CSOUND_INCLUDE_DIR and CSOUND_LIB_DIR select a specific installation and take precedence over automatic discovery; see Custom installation paths. When they are unset, Linux discovery tries the csound pkg-config package and requires version 7.0 or newer. If pkg-config is unavailable, it checks the conventional /usr/local and /usr include and library paths.

Install Csound 7 and its development files through your distribution when they are available. A source installation can be built with CMake:

$ git clone https://github.com/csound/csound.git
$ cd csound/
$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
$ cmake --build build --parallel
$ sudo cmake --install build
$ sudo ldconfig

A complete Csound 7 installation includes csound.pc, the public headers (including the CMake-generated version.h and float-version.h), and libcsound64. Source installations normally use /usr/local; the build script checks that prefix if pkg-config is unavailable.

Note

Library configuration when compiled from source

To ensure the system can find the library in /usr/local/lib, follow these steps:

  1. Create a configuration file with:

    sudo nano /etc/ld.so.conf.d/csound.conf
  2. Add this path to the file:

    /usr/local/lib
    
  3. Save the file and update the library cache:

    sudo ldconfig

Unless CSOUND_INCLUDE_DIR and CSOUND_LIB_DIR are set (see Custom installation paths), the build script checks these framework locations in order:

/Library/Frameworks
/Applications/Csound
~/Library/Frameworks
/opt/homebrew/Frameworks and /opt/homebrew/lib
/usr/local/Frameworks and /usr/local/lib
/opt/local/Library/Frameworks and /opt/local/lib

A location is used when it contains CsoundLib64.framework and the version the linker uses (Versions/Current) is Csound 7, so an old Csound 6 framework is skipped. This covers the official installer, user-local CMake builds, Homebrew on Apple Silicon and Intel, and MacPorts-style prefixes.

Csound's own CMake defaults to installing the framework into $HOME/Library/Frameworks, which keeps a Csound 7 build clear of an older system-wide installation. A source build can be installed with:

$ brew install cmake ninja libsndfile bison flex
$ cd csound/
$ mkdir build && cd build
$ PATH="$(brew --prefix bison)/bin:$PATH" cmake .. -G Ninja \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=$HOME/csound7-install
$ ninja && ninja install

Homebrew's bison must precede the system one: macOS ships Bison 2.3 and Csound requires 3.x.

A framework in one of the standard locations needs no environment variables:

$ cargo build

For a custom location, set both paths; they take precedence over the locations above:

$ export CSOUND_LIB_DIR=/path/containing/CsoundLib64.framework
$ export CSOUND_INCLUDE_DIR=$CSOUND_LIB_DIR/CsoundLib64.framework/Versions/7.0/Headers
$ cargo build

The csound frontend is normally installed at /usr/local/bin/csound, a Homebrew prefix's bin/csound, or /opt/local/bin/csound. It is not required to link the crate, but tests can select it explicitly with CSOUND_BIN.

Note

Csound 7's framework records an @rpath-relative install name (@rpath/CsoundLib64.framework/Versions/7.0/CsoundLib64). Executables linking it need a matching LC_RPATH or dyld fails at load time with no LC_RPATH's found. This crate's build script emits that rpath for its own tests and examples. If you build an executable against this crate, see Executables that depend on this crate.

Unless CSOUND_INCLUDE_DIR and CSOUND_LIB_DIR are set (see Custom installation paths), the build script looks for a Csound 7 development installation under:

C:\Program Files\Csound
C:\Program Files\Csound7_x64
C:\Program Files\Csound6_x64

The legacy-named Csound6_x64 location is checked for compatibility with existing installation layouts, but its version.h must still report Csound 7 or newer. Headers may be in include or include\csound; csound64.lib may be in lib or bin.

For a custom installation, set both paths (they take precedence) and restart the shell:

setx CSOUND_INCLUDE_DIR "C:\path\to\csound7\include"
setx CSOUND_LIB_DIR "C:\path\to\csound7\lib"

The directory containing csound64.dll must also be present in PATH when running tests, examples, or applications.

To build against a specific Csound 7 installation, set both variables:

Variable Linux macOS Windows
CSOUND_INCLUDE_DIR directory with csound.h the framework's Headers directory directory with csound.h
CSOUND_LIB_DIR directory with libcsound64.so directory with CsoundLib64.framework, or the framework itself directory with csound64.lib

The pair takes precedence over pkg-config and every standard location, so an older system-wide Csound cannot be picked up by accident. For the same reason the build fails, instead of searching elsewhere, when:

  • only one of the two variables is set (a variable set to the empty string counts as unset);
  • CSOUND_INCLUDE_DIR lacks csound.h, or its version.h does not report Csound 7 or newer;
  • CSOUND_LIB_DIR does not hold a Csound 7 library. On Linux, libcsound64.so must exist, and if it links to a versioned file such as libcsound64.so.6.0, that version must be 7 or newer. On macOS, the version of the framework the linker uses (Versions/Current) must have Csound 7 headers. On Windows, csound64.lib must exist; an import library does not record its Csound version, so only the headers are checked.

On Linux and macOS the build script also records CSOUND_LIB_DIR as an rpath in this crate's own tests and examples, so they load the selected library rather than whichever Csound the dynamic loader would otherwise find. Most Linux linkers record it as a RUNPATH, which LD_LIBRARY_PATH overrides. On Windows, put the directory containing the matching csound64.dll first in PATH.

Executables need the same rpath on macOS, and on Linux when CSOUND_LIB_DIR is used. csound-sys publishes the directory as DEP_CSOUND64_RPATH, and leaves it unset when no rpath is needed. Cargo only passes that variable to crates that depend on csound-sys directly, so add csound-sys to your [dependencies] next to csound, at the version csound uses. Then re-emit the rpath from your build.rs:

fn main() {
    if let Ok(dir) = std::env::var("DEP_CSOUND64_RPATH") {
        println!("cargo:rustc-link-arg=-Wl,-rpath,{dir}");
    }
}

On macOS, csound-sys also still publishes the same directory as DEP_CSOUND64_FRAMEWORK_DIR for existing build scripts.

The API reference can be found here

For getting started withCsound-rs, you have to understand some basic concepts about Csound, before to try to use this bindigs. Please check the Get Started page in the Csound's site Get Started In addition there are csound api examples inside of the rust directory.

The easy way to get familiar with csound is to explore the examples. To get the examples we just need to clone this repository.

# Clone Csound from its repository
$ git clone https://github.com/neithanmo/csound-rs.git

Now, go to the repository directory

# Clone Csound from its repository
$ cd csound-rs

For running the examples 1 to 10 just:

# Runs the example 5
$ cargo run --release --example example5

The example 11 requires some dependencies, but you can run them through calling cargo on their own Cargo.toml file

# Runs the example 11
$ cd examples/example11
$ cargo --release build
$ cargo run

Note

On Linux, bindgen uses the installed Csound headers discovered through pkg-config or the fallback paths described above. version.h and float-version.h are generated and installed by Csound's CMake build; they do not exist in an unconfigured Csound source checkout. On all supported platforms, bindgen uses the headers from the discovered Csound development installation.

On Linux with a standard Csound 7 development installation:

$ cargo test --workspace

For a custom Linux installation, set CSOUND_LIB_DIR and CSOUND_INCLUDE_DIR as described above. See the platform sections for macOS and Windows setup.

The suite includes differential tests (tests/differential.rs) that render the same .csd twice — once with the csound command-line frontend, once through the bindings — and compare the resulting samples bit for bit. They exist to catch the failure mode this crate is most exposed to: a binding that compiles and runs but is subtly wrong, such as a changed signature or a buffer read at the wrong rate. Those mistakes type-check cleanly and then corrupt audio.

They need a csound binary built from the same source as the linked library:

$ export CSOUND_BIN=$HOME/csound7-install/bin/csound

If no suitable binary is found the differential tests skip. If one is found but reports a different version than the linked library, they fail rather than compare across versions, since that would not prove anything.

Miri and AddressSanitizer

$ just miri     # undefined behaviour in the callback trampolines' pointer handling
$ just asan     # the same trampolines running for real, under AddressSanitizer

The two are complementary because Miri cannot cross the FFI boundary: it refuses to call foreign functions, so it cannot execute a trampoline (each one begins with csoundGetHostData) nor any test that constructs a Csound. The unsafe core those trampolines delegate to — turning a C pointer and a c_int count into a slice or &str — touches no FFI and is Miri-checkable, and that is where undefined behaviour would live. just miri drives it with null pointers, zero counts and negative counts.

just asan covers the other half: the trampolines actually invoked by Csound. Doctests are excluded because they do not link under -Zbuild-std with a sanitizer enabled.

License

csound-rs is licensed under either

at your option.

Csound itself is licensed under the Lesser General Public License version 2.1 or (at your option) any later version: https://www.gnu.org/licenses/lgpl-2.1.html

Any kinds of contributions are welcome as a pull request.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in csound-rs by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

This is a Rust bindings for Csound.

Resources

Stars

23 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages