volumecontrol 0.1.1

Cross-platform crate to control system audio volume
Documentation

volumecontrol

Crates.io docs.rs CI License: MIT

A cross-platform Rust library for querying and controlling system audio volume.

volumecontrol exposes a single, unified API that works on Linux (PulseAudio), Windows (WASAPI), and macOS (CoreAudio). The correct backend is selected automatically at compile time — no feature flags or platform-specific imports are needed in your code.


Table of Contents


Repository Structure

volumecontrol/                   ← workspace root
├── Cargo.toml                   ← workspace manifest & cross-compilation config
├── Cargo.lock                   ← locked dependency versions
├── LICENSE                      ← MIT license
├── README.md                    ← this file
├── AGENTS.md                    ← AI agent contribution instructions
│
├── volumecontrol-core/          ← platform-independent traits & error types
│   └── src/
│       ├── lib.rs               ← public re-exports
│       ├── traits.rs            ← AudioDevice trait definition
│       └── error.rs             ← AudioError enum
│
├── volumecontrol-linux/         ← PulseAudio backend (feature: pulseaudio)
├── volumecontrol-windows/       ← WASAPI backend       (feature: wasapi)
├── volumecontrol-macos/         ← CoreAudio backend    (feature: coreaudio)
│
└── volumecontrol/               ← cross-platform wrapper crate
    └── src/lib.rs               ← selects the right backend via #[cfg(target_os)]
Crate Purpose
volumecontrol-core AudioDevice trait, AudioError enum, shared utilities
volumecontrol-linux AudioDevice impl using PulseAudio
volumecontrol-windows AudioDevice impl using WASAPI
volumecontrol-macos AudioDevice impl using CoreAudio
volumecontrol Selects the right backend at compile time via #[cfg(target_os)]

Getting Started

volumecontrol lets you read and change the system audio volume from Rust with a single, cross-platform API:

use volumecontrol::AudioDevice;

fn main() -> Result<(), volumecontrol::AudioError> {
    let device = AudioDevice::from_default()?;
    println!("Current volume: {}%", device.get_vol()?);
    Ok(())
}

Platform requirements

Platform Backend System library required
Linux PulseAudio libpulse-dev (e.g. via apt)
Windows WASAPI built into Windows — nothing extra
macOS CoreAudio built into macOS — nothing extra

Installation

Add volumecontrol to your Cargo.toml:

[dependencies]
volumecontrol = "0.1"

Linux users: install the PulseAudio development headers before building:

# Debian / Ubuntu
sudo apt-get install libpulse-dev

# Fedora / RHEL
sudo dnf install pulseaudio-libs-devel

# Arch Linux
sudo pacman -S libpulse

Once the system library is in place, build as usual:

cargo build

Usage

Open the default audio device

use volumecontrol::AudioDevice;

let device = AudioDevice::from_default()?;

Look up a device by ID or name

// By exact device identifier returned from list()
let device = AudioDevice::from_id("alsa_output.pci-0000_00_1f.3.analog-stereo")?;

// By a partial name match (case-insensitive substring search)
let device = AudioDevice::from_name("Speakers")?;

List all available audio devices

let devices = AudioDevice::list()?;
for info in &devices {
    // DeviceInfo implements Display as "name (id)"
    println!("{info}");
}

Read device ID and name

// Display shows "name (id)" — useful for logs and CLI output
println!("{device}");

// id() returns the opaque platform identifier used by from_id() and list()
println!("Device id:   {}", device.id());

// name() returns the human-readable label used by from_name() and list()
println!("Device name: {}", device.name());

Both values are guaranteed to be non-empty.

Read and change the volume

// Volume is always in the range 0..=100
let vol = device.get_vol()?;
println!("Volume: {vol}%");

device.set_vol(50)?;   // set to 50 %

Mute / unmute

if device.is_mute()? {
    println!("Device is muted");
}

device.set_mute(true)?;   // mute
device.set_mute(false)?;  // unmute

Error handling

All methods return Result<_, AudioError>. The error variants are:

Variant Meaning
DeviceNotFound No device matched the given id or name
InitializationFailed The audio subsystem could not be initialised
ListFailed Listing available devices failed
GetVolumeFailed Could not read the current volume
SetVolumeFailed Could not change the volume
GetMuteFailed Could not read the mute state
SetMuteFailed Could not change the mute state
Unsupported Operation not supported on this platform
EndpointLockPoisoned A thread panicked while holding the audio endpoint lock (Windows)

How to Collaborate

Contributions are very welcome! Please follow these steps:

1. Open an issue first

For non-trivial changes (new features, API changes, new platform backends) open a GitHub issue to discuss the idea before investing time in a pull request.

2. Fork & clone

git clone https://github.com/<your-username>/volumecontrol.git
cd volumecontrol

3. Create a feature branch

git checkout -b feature/my-improvement

4. Make your changes

  • Follow the Rust API Guidelines.
  • Document every public item with a /// doc comment.
  • Add # Errors sections to fallible functions.
  • Never use unwrap() or expect() — propagate errors with ?.
  • All unsafe code must be hidden behind a safe wrapper and annotated with a // SAFETY: comment.
  • Use thiserror for any new error types.

5. Run the toolchain

# Check the whole workspace
cargo check --workspace

# Run all tests
cargo test --workspace

# Lint (no warnings allowed)
cargo clippy --workspace --all-targets --all-features -- -D warnings

# Format
cargo fmt --all

All four commands must pass before submitting a pull request.

6. Submit a pull request

Push your branch and open a pull request against main. Describe what you changed and why. Link the relevant issue if one exists.

Coding style summary

Topic Rule
Formatting cargo fmt defaults (enforced by CI)
Naming snake_case for files and modules
Errors thiserror-derived enums; no unwrap/expect
Unsafe code Private helpers only; // SAFETY: required
Tests #[cfg(test)] mod tests block in the same file
Documentation /// for every public item; //! for crates

Built with AI

This project was built 100% with GitHub Copilot (Claude Opus & Claude Sonnet models) as an experiment in driving an AI to produce a production-ready Rust crate — from architecture and API design to platform-specific backends, CI pipelines, and documentation.

No human wrote any Rust source code directly; every implementation decision, refactor, and fix was produced by the AI under human direction.


License

This project is licensed under the MIT License.
See the LICENSE file for the full text.


Contact / Further Information

If you have a question that is not suited for a public issue, you can reach the maintainer through their GitHub profile.