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
2 changes: 1 addition & 1 deletion .github/workflows/cpal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
- name: Run clippy
run: cargo clippy --all --all-features
- name: Run clippy for Android target
run: cargo clippy --all --features asio --target armv7-linux-androideabi
run: cargo clippy --all --target armv7-linux-androideabi

cargo-publish:
if: github.event_name == 'release'
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Add `DeviceTrait::id` method that returns a stable audio device ID.
- Add `HostTrait::device_by_id` to select a device by its stable ID.
- Add `Display` and `FromStr` implementations for `HostId`.
- Add support for custom `Host`s, `Device`s, and `Stream`s.
- Add `Sample::bits_per_sample` method.
- Update `audio_thread_priority` to 0.34.
Expand Down
14 changes: 7 additions & 7 deletions examples/beep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use cpal::{
#[command(version, about = "CPAL beep example", long_about = None)]
struct Opt {
/// The audio device to use
#[arg(short, long, default_value_t = String::from("default"))]
device: String,
#[arg(short, long)]
device: Option<String>,

/// Use the JACK host
#[cfg(all(
Expand Down Expand Up @@ -63,14 +63,14 @@ fn main() -> anyhow::Result<()> {
))]
let host = cpal::default_host();

let device = if opt.device == "default" {
host.default_output_device()
let device = if let Some(device) = opt.device {
let id = &device.parse().expect("failed to parse device id");
host.device_by_id(id)
} else {
host.output_devices()?
.find(|x| x.name().map(|y| y == opt.device).unwrap_or(false))
host.default_output_device()
}
.expect("failed to find output device");
println!("Output device: {}", device.name()?);
println!("Output device: {}", device.id()?);

let config = device.default_output_config().unwrap();
println!("Default output config: {config:?}");
Expand Down
11 changes: 9 additions & 2 deletions examples/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use std::sync::{
Arc,
};

use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{
traits::{DeviceTrait, HostTrait, StreamTrait},
DeviceDescription, DeviceDescriptionBuilder,
};
use cpal::{FromSample, Sample};

#[allow(dead_code)]
Expand Down Expand Up @@ -53,7 +56,11 @@ impl DeviceTrait for MyDevice {
type Stream = MyStream;

fn name(&self) -> Result<String, cpal::DeviceNameError> {
Ok(String::from("custom device"))
Ok(String::from("custom"))
}

fn description(&self) -> Result<DeviceDescription, cpal::DeviceNameError> {
Ok(DeviceDescriptionBuilder::new("Custom Device".to_string()).build())
}

fn id(&self) -> Result<cpal::DeviceId, cpal::DeviceIdError> {
Expand Down
19 changes: 16 additions & 3 deletions examples/enumerate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,28 @@ fn main() -> Result<(), anyhow::Error> {
println!("{}", host_id.name());
let host = cpal::host_from_id(host_id)?;

let default_in = host.default_input_device().map(|e| e.name().unwrap());
let default_out = host.default_output_device().map(|e| e.name().unwrap());
let default_in = host
.default_input_device()
.map(|dev| dev.id().unwrap())
.map(|id| id.to_string());
let default_out = host
.default_output_device()
.map(|dev| dev.id().unwrap())
.map(|id| id.to_string());
println!(" Default Input Device:\n {default_in:?}");
println!(" Default Output Device:\n {default_out:?}");

let devices = host.devices()?;
println!(" Devices: ");
for (device_index, device) in devices.enumerate() {
println!(" {}. \"{}\"", device_index + 1, device.name()?);
let id = device
.id()
.map_or("Unknown ID".to_string(), |id| id.to_string());
if let Ok(desc) = device.description() {
println!(" {}. {id} ({})", device_index + 1, desc);
} else {
println!(" {}. {id}", device_index + 1);
}

// Input configs
if let Ok(conf) = device.default_input_config() {
Expand Down
28 changes: 14 additions & 14 deletions examples/feedback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ use ringbuf::{
#[command(version, about = "CPAL feedback example", long_about = None)]
struct Opt {
/// The input audio device to use
#[arg(short, long, value_name = "IN", default_value_t = String::from("default"))]
input_device: String,
#[arg(short, long, value_name = "IN")]
input_device: Option<String>,

/// The output audio device to use
#[arg(short, long, value_name = "OUT", default_value_t = String::from("default"))]
output_device: String,
#[arg(short, long, value_name = "OUT")]
output_device: Option<String>,

/// Specify the delay between input and output
#[arg(short, long, value_name = "DELAY_MS", default_value_t = 150.0)]
Expand Down Expand Up @@ -81,24 +81,24 @@ fn main() -> anyhow::Result<()> {
let host = cpal::default_host();

// Find devices.
let input_device = if opt.input_device == "default" {
host.default_input_device()
let input_device = if let Some(device) = opt.input_device {
let id = &device.parse().expect("failed to parse input device id");
host.device_by_id(id)
} else {
host.input_devices()?
.find(|x| x.name().map(|y| y == opt.input_device).unwrap_or(false))
host.default_input_device()
}
.expect("failed to find input device");

let output_device = if opt.output_device == "default" {
host.default_output_device()
let output_device = if let Some(device) = opt.output_device {
let id = &device.parse().expect("failed to parse output device id");
host.device_by_id(id)
} else {
host.output_devices()?
.find(|x| x.name().map(|y| y == opt.output_device).unwrap_or(false))
host.default_output_device()
}
.expect("failed to find output device");

println!("Using input device: \"{}\"", input_device.name()?);
println!("Using output device: \"{}\"", output_device.name()?);
println!("Using input device: \"{}\"", input_device.id()?);
println!("Using output device: \"{}\"", output_device.id()?);

// We'll try and use the same configuration between streams to keep it simple.
let config: cpal::StreamConfig = input_device.default_input_config()?.into();
Expand Down
19 changes: 8 additions & 11 deletions examples/record_wav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ use std::sync::{Arc, Mutex};
#[command(version, about = "CPAL record_wav example", long_about = None)]
struct Opt {
/// The audio device to use.
/// For the default microphone, use "default".
/// For recording system output, use "default-output".
#[arg(short, long, default_value_t = String::from("default"))]
device: String,
#[arg(short, long)]
device: Option<String>,

/// How long to record, in seconds
#[arg(long, default_value_t = 3)]
Expand Down Expand Up @@ -75,16 +73,15 @@ fn main() -> Result<(), anyhow::Error> {
let host = cpal::default_host();

// Set up the input device and stream with the default input config.
let device = match opt.device.as_str() {
"default" => host.default_input_device(),
"default-output" => host.default_output_device(),
name => host
.input_devices()?
.find(|x| x.name().map(|y| y == name).unwrap_or(false)),
let device = if let Some(device) = opt.device {
let id = &device.parse().expect("failed to parse input device id");
host.device_by_id(id)
} else {
host.default_input_device()
}
.expect("failed to find input device");

println!("Input device: {}", device.name()?);
println!("Input device: {}", device.id()?);

let config = if device.supports_input() {
device.default_input_config()
Expand Down
4 changes: 2 additions & 2 deletions examples/synth_tones.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ pub fn host_device_setup(
let device = host
.default_output_device()
.ok_or_else(|| anyhow::Error::msg("Default output device is not available"))?;
println!("Output device : {}", device.name()?);
println!("Output device: {}", device.id()?);

let config = device.default_output_config()?;
println!("Default output config : {config:?}");
println!("Default output config: {config:?}");

Ok((host, device, config))
}
Expand Down
Loading