Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions .github/workflows/platforms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ on:

env:
# MSRV varies by backend due to platform-specific dependencies
MSRV_AAUDIO: "1.82"
MSRV_AAUDIO: "1.85"
MSRV_ALSA: "1.82"
MSRV_COREAUDIO: "1.80"
MSRV_JACK: "1.82"
MSRV_PIPEWIRE: "1.82"
MSRV_PIPEWIRE: "1.85"
MSRV_PULSEAUDIO: "1.88"
MSRV_WASIP1: "1.78"
MSRV_WASM: "1.82"
MSRV_WASM: "1.85"
MSRV_WINDOWS: "1.82"

PACKAGES_LINUX: libasound2-dev libjack-jackd2-dev libjack-jackd2-0 libdbus-1-dev libpipewire-0.3-dev
Expand Down Expand Up @@ -160,6 +160,32 @@ jobs:
- name: Check examples (all features)
run: cross +${{ steps.msrv.outputs.all-features }} test --features=jack,pulseaudio --workspace --verbose --target ${{ env.TARGET }}

pipewire-bookworm:
name: pipewire-bookworm
runs-on: ubuntu-latest
container:
image: buildpack-deps:bookworm
steps:
- uses: actions/checkout@v5

- name: Install audio packages
run: |
apt-get update -qq
apt-get install -y --no-install-recommends libclang-dev libasound2-dev libpipewire-0.3-dev

- name: Install Rust (${{ env.MSRV_PIPEWIRE }})
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.MSRV_PIPEWIRE }}

- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
key: pipewire-bookworm

- name: Check PipeWire on Debian Bookworm
run: cargo check --features pipewire --workspace --verbose

# Windows (x86_64 and i686)
windows:
strategy:
Expand Down Expand Up @@ -543,6 +569,7 @@ jobs:
needs:
- linux
- linux-armv7
- pipewire-bookworm
- windows
- macos
- android
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **AAudio**: `supported_input_configs` and `supported_output_configs` now return an error for
direction-mismatched devices (e.g. querying input configs on an output-only device) instead of
silently returning an empty list.
- **AAudio**: Bump MSRV to 1.85.
- **AAudio**: Buffers with default sizes are now dynamically tuned.
- **ALSA**: Device disconnection now stops the stream with `StreamError::DeviceNotAvailable` instead of looping.
- **ALSA**: Polling errors trigger underrun recovery instead of looping.
Expand All @@ -38,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **JACK**: Timestamps now use the precise hardware deadline.
- **Linux/BSD**: Default host now is, in order from first to last available: PipeWire, PulseAudio, ALSA.
- **WASAPI**: Timestamps now include hardware pipeline latency.
- **WebAudio**: Bump MSRV to 1.85.
- **WebAudio**: Timestamps now include base and output latency.
- **WebAudio**: Initial buffer scheduling offset now scales with buffer duration.

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ Low-level library for audio input and output in pure Rust.

The minimum Rust version required depends on which audio backend and features you're using, as each platform has different dependencies:

- **AAudio (Android):** Rust **1.82**
- **AAudio (Android):** Rust **1.85**
- **ALSA (Linux/BSD):** Rust **1.82**
- **CoreAudio (macOS/iOS):** Rust **1.80**
- **JACK (Linux/BSD/macOS/Windows):** Rust **1.82**
- **PipeWire (Linux/BSD):** Rust **1.82**
- **PipeWire (Linux/BSD):** Rust **1.85**
- **PulseAudio (Linux/BSD):** Rust **1.88**
- **WASAPI/ASIO (Windows):** Rust **1.82**
- **WASM (`wasm32-unknown`):** Rust **1.82**
- **WASM (`wasm32-unknown`):** Rust **1.85**
- **WASM (`wasm32-wasip1`):** Rust **1.78**
- **WASM (`audioworklet`):** Rust **nightly** (requires `-Zbuild-std` for atomics support)

Expand Down
2 changes: 1 addition & 1 deletion examples/wasm-beep/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "wasm-beep"
description = "cpal beep example for WebAssembly"
version = "0.1.0"
edition = "2021"
rust-version = "1.82"
rust-version = "1.85"

[lib]
crate-type = ["cdylib"]
Expand Down
35 changes: 10 additions & 25 deletions src/host/pipewire/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,6 @@ struct PwTime {
/// For output: how far ahead of the driver our next sample will be played.
/// For input: how long ago the data in the buffer was captured.
delay_ns: i64,
/// Quantum size in samples (frames) for this graph cycle.
quantum: u64,
}

/// Returns a hardware timestamp for the current graph cycle, or `None` if
Expand All @@ -196,7 +194,6 @@ fn pw_stream_time(stream: &pw::stream::Stream) -> Option<PwTime> {
Some(PwTime {
now_ns: t.now,
delay_ns,
quantum: t.size,
})
}

Expand All @@ -211,18 +208,12 @@ where
frames: usize,
data: &Data,
) -> Result<(), BackendSpecificError> {
self.last_quantum.store(frames as u64, Ordering::Relaxed);
let (callback, capture) = match pw_stream_time(stream) {
Some(PwTime {
now_ns,
delay_ns,
quantum,
}) => {
self.last_quantum.store(quantum, Ordering::Relaxed);
(
StreamInstant::from_nanos(now_ns),
StreamInstant::from_nanos(now_ns - delay_ns),
)
}
Some(PwTime { now_ns, delay_ns }) => (
StreamInstant::from_nanos(now_ns),
StreamInstant::from_nanos(now_ns - delay_ns),
),
None => {
let cb = stream_timestamp_fallback(self.created_instance)?;
let pl = cb
Expand Down Expand Up @@ -252,18 +243,12 @@ where
frames: usize,
data: &mut Data,
) -> Result<(), BackendSpecificError> {
self.last_quantum.store(frames as u64, Ordering::Relaxed);
let (callback, playback) = match pw_stream_time(stream) {
Some(PwTime {
now_ns,
delay_ns,
quantum,
}) => {
self.last_quantum.store(quantum, Ordering::Relaxed);
(
StreamInstant::from_nanos(now_ns),
StreamInstant::from_nanos(now_ns + delay_ns),
)
}
Some(PwTime { now_ns, delay_ns }) => (
StreamInstant::from_nanos(now_ns),
StreamInstant::from_nanos(now_ns + delay_ns),
),
None => {
let cb = stream_timestamp_fallback(self.created_instance)?;
let pl = cb
Expand Down
Loading