Skip to content

Commit 1a0f90f

Browse files
committed
Fix docs
1 parent 7d0b921 commit 1a0f90f

6 files changed

Lines changed: 282 additions & 64 deletions

File tree

.github/workflows/testing.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
- name: Build (All Features)
3030
run: cargo build --verbose --all-features
3131
- name: Build (examples)
32-
run: cargo build --verbose --examples
32+
run: cargo build --verbose --examples --all-features
3333
- name: Run Tests (Default Features)
3434
run: cargo nextest run
3535
- name: Run Doc Tests

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,7 @@ ctor = "0.2"
2727
default = ["dynamic_loading", "log"]
2828
dynamic_loading = ["jack-sys/dynamic_loading"]
2929
controller = ["rtrb"]
30+
31+
[[example]]
32+
name = "controlled_sine"
33+
required-features = ["controller"]

README.md

Lines changed: 75 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,102 @@
11
# JACK (for Rust)
22

3-
Rust bindings for [JACK Audio Connection Kit](<https://jackaudio.org>).
3+
Rust bindings for [JACK Audio Connection Kit](https://jackaudio.org).
44

5-
| [![Crates.io](https://img.shields.io/crates/v/jack.svg)](https://crates.io/crates/jack) | [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) |
6-
|-----------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
7-
| [![Docs.rs](https://docs.rs/jack/badge.svg)](https://docs.rs/jack) | [![Test](https://github.com/RustAudio/rust-jack/actions/workflows/testing.yml/badge.svg)](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+
[![Crates.io](https://img.shields.io/crates/v/jack.svg)](https://crates.io/crates/jack)
6+
[![Docs.rs](https://docs.rs/jack/badge.svg)](https://docs.rs/jack)
7+
[![Test](https://github.com/RustAudio/rust-jack/actions/workflows/testing.yml/badge.svg)](https://github.com/RustAudio/rust-jack/actions/workflows/testing.yml)
8+
[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9+
[:heart: Sponsor](https://github.com/sponsors/wmedrano)
910

10-
## Using JACK
11+
## Overview
1112

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.
1217

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
1719

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
2422

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
2724

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+
```
2858

29-
## FAQ
59+
See the [examples](examples/) directory for more.
3060

31-
### How do I return an `AsyncClient` with many generics?
61+
## Installation
3262

33-
This is especially useful when using `jack::contrib::ClosureProcessHandler`
34-
which may have an innaccessible type.
63+
Add to your `Cargo.toml`:
3564

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+
```
4169

42-
// With extra bounds
43-
fn make_client() -> impl 'static + AsRef<jack::Client> {
44-
todo!();
45-
}
70+
### JACK Server Setup
4671

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:
5273

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)
5480

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:
5887

5988
```sh
60-
# Set up a dummy server for tests. The script is included in this repository.
6189
./dummy_jack_server.sh &
62-
# Run tests
6390
cargo nextest run
6491
```
6592

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`
6994

70-
## Possible Issues
95+
### Troubleshooting
7196

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
7399

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
76101

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.

docs/src/contrib/controller.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,16 @@ impl ControlledProcessorTrait for VolumeProcessor {
6565
channels: &mut ProcessorChannels<Self::Command, Self::Notification>,
6666
) -> jack::Control {
6767
// Handle incoming commands
68-
channels.drain_commands(|cmd| match cmd {
69-
Command::SetVolume(v) => {
70-
self.volume = v;
71-
channels.try_notify(Notification::VolumeChanged(v));
68+
while let Some(cmd) = channels.recv_command() {
69+
match cmd {
70+
Command::SetVolume(v) => {
71+
self.volume = v;
72+
let _ = channels.try_notify(Notification::VolumeChanged(v));
73+
}
74+
Command::Mute => self.muted = true,
75+
Command::Unmute => self.muted = false,
7276
}
73-
Command::Mute => self.muted = true,
74-
Command::Unmute => self.muted = false,
75-
});
77+
}
7678

7779
// Process audio
7880
let input = self.input.as_slice(scope);
@@ -108,7 +110,7 @@ let processor = VolumeProcessor {
108110

109111
// Create the processor instance and control handle
110112
// Arguments: notification channel size, command channel size
111-
let (processor_instance, handle) = processor.instance(16, 16);
113+
let (processor_instance, mut handle) = processor.instance(16, 16);
112114

113115
// Activate the client with the processor
114116
let active_client = client.activate_async((), processor_instance).unwrap();
@@ -117,10 +119,12 @@ let active_client = client.activate_async((), processor_instance).unwrap();
117119
handle.send_command(Command::SetVolume(0.5)).unwrap();
118120

119121
// And receive notifications
120-
handle.drain_notifications(|notification| match notification {
121-
Notification::ClippingDetected => println!("Clipping detected!"),
122-
Notification::VolumeChanged(v) => println!("Volume changed to {}", v),
123-
});
122+
for notification in handle.drain_notifications() {
123+
match notification {
124+
Notification::ClippingDetected => println!("Clipping detected!"),
125+
Notification::VolumeChanged(v) => println!("Volume changed to {}", v),
126+
}
127+
}
124128
```
125129

126130
## Channel Capacities

0 commit comments

Comments
 (0)