|
1 | 1 | # JACK (for Rust) |
2 | 2 |
|
3 | | -Rust bindings for [JACK Audio Connection Kit](<https://jackaudio.org>). |
| 3 | +Rust bindings for [JACK Audio Connection Kit](https://jackaudio.org). |
4 | 4 |
|
5 | | -| [](https://crates.io/crates/jack) | [](https://opensource.org/licenses/MIT) | |
6 | | -|-----------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| |
7 | | -| [](https://docs.rs/jack) | [](https://github.com/RustAudio/rust-jack/actions/workflows/testing.yml) | |
8 | | -| [📚 Documentation](https://rustaudio.github.io/rust-jack) | [:heart: Sponsor](<https://github.com/sponsors/wmedrano>) | |
| 5 | +[](https://crates.io/crates/jack) |
| 6 | +[](https://docs.rs/jack) |
| 7 | +[](https://github.com/RustAudio/rust-jack/actions/workflows/testing.yml) |
| 8 | +[](https://opensource.org/licenses/MIT) |
| 9 | +[:heart: Sponsor](https://github.com/sponsors/wmedrano) |
9 | 10 |
|
10 | | -## Using JACK |
| 11 | +## Overview |
11 | 12 |
|
| 13 | +JACK is a low-latency audio server that allows multiple applications to share |
| 14 | +audio and MIDI devices and route signals between each other. This crate provides |
| 15 | +safe Rust bindings to create JACK clients that can process audio and MIDI in |
| 16 | +real-time. |
12 | 17 |
|
13 | | -The JACK server is usually started by the user or system. Clients can request |
14 | | -that the JACK server is started on demand when they connect, but this can be |
15 | | -disabled by creating a client with the `NO_START_SERVER` option or |
16 | | -`ClientOptions::default()`. |
| 18 | +## Documentation |
17 | 19 |
|
18 | | -- Linux and BSD users may install JACK1, JACK2 (preferred for low latency), or |
19 | | - Pipewire JACK (preferred for ease of use) from their system package manager. |
20 | | -- Windows users may install JACK from the [official |
21 | | - website](<http://jackaudio.org/downloads/>) or [Chocolatey](<https://community.chocolatey.org/packages/jack>). |
22 | | -- MacOS users may install JACK from the [official |
23 | | - website](<http://jackaudio.org/downloads/>) or [Homebrew](<https://formulae.brew.sh/formula/jack>). |
| 20 | +- [Guide](https://rustaudio.github.io/rust-jack) - Quickstart, features, and tutorials |
| 21 | +- [API Reference](https://docs.rs/jack/) - Complete API documentation |
24 | 22 |
|
25 | | -Refer to the [docs.rs documentation](<https://docs.rs/jack/>) for details about |
26 | | -the API. For more general documentation, visit <https://rustaudio.github.io/rust-jack>. |
| 23 | +## Quick Example |
27 | 24 |
|
| 25 | +```rust |
| 26 | +use std::io; |
| 27 | + |
| 28 | +fn main() { |
| 29 | + // Create a JACK client |
| 30 | + let (client, _status) = |
| 31 | + jack::Client::new("rust_jack_simple", jack::ClientOptions::default()).unwrap(); |
| 32 | + |
| 33 | + // Register input and output ports |
| 34 | + let in_port = client |
| 35 | + .register_port("input", jack::AudioIn::default()) |
| 36 | + .unwrap(); |
| 37 | + let mut out_port = client |
| 38 | + .register_port("output", jack::AudioOut::default()) |
| 39 | + .unwrap(); |
| 40 | + |
| 41 | + // Create a processing callback that copies input to output |
| 42 | + let process = jack::contrib::ClosureProcessHandler::new( |
| 43 | + move |_: &jack::Client, ps: &jack::ProcessScope| -> jack::Control { |
| 44 | + out_port.as_mut_slice(ps).clone_from_slice(in_port.as_slice(ps)); |
| 45 | + jack::Control::Continue |
| 46 | + }, |
| 47 | + ); |
| 48 | + |
| 49 | + // Activate the client |
| 50 | + let _active_client = client.activate_async((), process).unwrap(); |
| 51 | + |
| 52 | + // Wait for user to quit |
| 53 | + println!("Press enter to quit..."); |
| 54 | + let mut input = String::new(); |
| 55 | + io::stdin().read_line(&mut input).ok(); |
| 56 | +} |
| 57 | +``` |
28 | 58 |
|
29 | | -## FAQ |
| 59 | +See the [examples](examples/) directory for more. |
30 | 60 |
|
31 | | -### How do I return an `AsyncClient` with many generics? |
| 61 | +## Installation |
32 | 62 |
|
33 | | -This is especially useful when using `jack::contrib::ClosureProcessHandler` |
34 | | -which may have an innaccessible type. |
| 63 | +Add to your `Cargo.toml`: |
35 | 64 |
|
36 | | -```rust |
37 | | -// Shortest and allows access to the underlying client. |
38 | | -fn make_client() -> impl AsRef<jack::Client> { |
39 | | - todo!() |
40 | | -} |
| 65 | +```toml |
| 66 | +[dependencies] |
| 67 | +jack = "0.13" |
| 68 | +``` |
41 | 69 |
|
42 | | -// With extra bounds |
43 | | -fn make_client() -> impl 'static + AsRef<jack::Client> { |
44 | | - todo!(); |
45 | | -} |
| 70 | +### JACK Server Setup |
46 | 71 |
|
47 | | -// For the full async client |
48 | | -fn async_client() -> impl jack::AsyncClient<impl Any, impl Any> { |
49 | | - todo!(); |
50 | | -} |
51 | | -``` |
| 72 | +A JACK server must be running for clients to connect. Install one of: |
52 | 73 |
|
53 | | -# Testing |
| 74 | +- **Linux/BSD**: JACK2 (lowest latency), Pipewire JACK (easiest), or JACK1 via |
| 75 | + your package manager |
| 76 | +- **Windows**: [Official installer](http://jackaudio.org/downloads/) or |
| 77 | + [Chocolatey](https://community.chocolatey.org/packages/jack) |
| 78 | +- **macOS**: [Official installer](http://jackaudio.org/downloads/) or |
| 79 | + [Homebrew](https://formulae.brew.sh/formula/jack) |
54 | 80 |
|
55 | | -Testing requires setting up a dummy server and running the tests using a single |
56 | | -thread. `rust-jack` automatically configures `cargo nextest` to use a single |
57 | | -thread. |
| 81 | +By default, clients request the server to start on demand. Use |
| 82 | +`ClientOptions::default()` or the `NO_START_SERVER` flag to disable this. |
| 83 | + |
| 84 | +## Testing |
| 85 | + |
| 86 | +Tests require a dummy JACK server and must run single-threaded: |
58 | 87 |
|
59 | 88 | ```sh |
60 | | -# Set up a dummy server for tests. The script is included in this repository. |
61 | 89 | ./dummy_jack_server.sh & |
62 | | -# Run tests |
63 | 90 | cargo nextest run |
64 | 91 | ``` |
65 | 92 |
|
66 | | -Note: If cargo nextest is not available, use `RUST_TEST_THREADS=1 cargo test` to |
67 | | -run in single threaded mode. |
68 | | - |
| 93 | +If `cargo nextest` is unavailable: `RUST_TEST_THREADS=1 cargo test` |
69 | 94 |
|
70 | | -## Possible Issues |
| 95 | +### Troubleshooting |
71 | 96 |
|
72 | | -If the tests are failing, a possible gotcha may be timing issues. |
| 97 | +- Use `cargo nextest` instead of `cargo test` for better handling of timing-sensitive tests |
| 98 | +- Try libjack2 or pipewire-jack if tests fail with your current JACK implementation |
73 | 99 |
|
74 | | -1. If using `cargo test`, try `cargo nextest`. The `cargo nextest` |
75 | | - configuration is set up to run single threaded and to retry flaky tests. |
| 100 | +## License |
76 | 101 |
|
77 | | -Another case is that libjack may be broken on your setup. Try using libjack2 or |
78 | | -pipewire-jack. |
| 102 | +MIT - see [LICENSE](LICENSE) for details. |
0 commit comments