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
18 changes: 9 additions & 9 deletions examples/beep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ fn main() -> Result<(), anyhow::Error> {
let device = host
.default_output_device()
.expect("failed to find a default output device");
let format = device.default_output_format()?;
let config = device.default_output_config()?;

match format.data_type {
cpal::SampleFormat::F32 => run::<f32>(&device, &format.shape())?,
cpal::SampleFormat::I16 => run::<i16>(&device, &format.shape())?,
cpal::SampleFormat::U16 => run::<u16>(&device, &format.shape())?,
match config.sample_format() {
cpal::SampleFormat::F32 => run::<f32>(&device, &config.into())?,
cpal::SampleFormat::I16 => run::<i16>(&device, &config.into())?,
cpal::SampleFormat::U16 => run::<u16>(&device, &config.into())?,
}

Ok(())
}

fn run<T>(device: &cpal::Device, shape: &cpal::Shape) -> Result<(), anyhow::Error>
fn run<T>(device: &cpal::Device, config: &cpal::StreamConfig) -> Result<(), anyhow::Error>
where
T: cpal::Sample,
{
let sample_rate = shape.sample_rate.0 as f32;
let channels = shape.channels as usize;
let sample_rate = config.sample_rate.0 as f32;
let channels = config.channels as usize;

// Produce a sinusoid of maximum amplitude.
let mut sample_clock = 0f32;
Expand All @@ -36,7 +36,7 @@ where
let err_fn = |err| eprintln!("an error occurred on stream: {}", err);

let stream = device.build_output_stream(
shape,
config,
move |data: &mut [T]| write_data(data, channels, &mut next_value),
err_fn,
)?;
Expand Down
36 changes: 18 additions & 18 deletions examples/enumerate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,48 @@ fn main() -> Result<(), anyhow::Error> {
for (device_index, device) in devices.enumerate() {
println!(" {}. \"{}\"", device_index + 1, device.name()?);

// Input formats
if let Ok(fmt) = device.default_input_format() {
println!(" Default input stream format:\n {:?}", fmt);
// Input configs
if let Ok(conf) = device.default_input_config() {
println!(" Default input stream config:\n {:?}", conf);
}
let mut input_formats = match device.supported_input_formats() {
let mut input_configs = match device.supported_input_configs() {
Ok(f) => f.peekable(),
Err(e) => {
println!("Error: {:?}", e);
continue;
}
};
if input_formats.peek().is_some() {
println!(" All supported input stream formats:");
for (format_index, format) in input_formats.enumerate() {
if input_configs.peek().is_some() {
println!(" All supported input stream configs:");
for (config_index, config) in input_configs.enumerate() {
println!(
" {}.{}. {:?}",
device_index + 1,
format_index + 1,
format
config_index + 1,
config
);
}
}

// Output formats
if let Ok(fmt) = device.default_output_format() {
println!(" Default output stream format:\n {:?}", fmt);
// Output configs
if let Ok(conf) = device.default_output_config() {
println!(" Default output stream config:\n {:?}", conf);
}
let mut output_formats = match device.supported_output_formats() {
let mut output_configs = match device.supported_output_configs() {
Ok(f) => f.peekable(),
Err(e) => {
println!("Error: {:?}", e);
continue;
}
};
if output_formats.peek().is_some() {
println!(" All supported output stream formats:");
for (format_index, format) in output_formats.enumerate() {
if output_configs.peek().is_some() {
println!(" All supported output stream configs:");
for (config_index, config) in output_configs.enumerate() {
println!(
" {}.{}. {:?}",
device_index + 1,
format_index + 1,
format
config_index + 1,
config
);
}
}
Expand Down
18 changes: 9 additions & 9 deletions examples/feedback.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Feeds back the input stream directly into the output stream.
//!
//! Assumes that the input and output devices can use the same stream format and that they support
//! the f32 sample format.
//! Assumes that the input and output devices can use the same stream configuration and that they
//! support the f32 sample format.
//!
//! Uses a delay of `LATENCY_MS` milliseconds in case the default input and output streams are not
//! precisely synchronised.
Expand All @@ -28,12 +28,12 @@ fn main() -> Result<(), anyhow::Error> {
println!("Using default input device: \"{}\"", input_device.name()?);
println!("Using default output device: \"{}\"", output_device.name()?);

// We'll try and use the same format between streams to keep it simple
let shape = input_device.default_input_format()?.shape();
// We'll try and use the same configuration between streams to keep it simple.
let config: cpal::StreamConfig = input_device.default_input_config()?.into();

// Create a delay in case the input and output devices aren't synced.
let latency_frames = (LATENCY_MS / 1_000.0) * shape.sample_rate.0 as f32;
let latency_samples = latency_frames as usize * shape.channels as usize;
let latency_frames = (LATENCY_MS / 1_000.0) * config.sample_rate.0 as f32;
let latency_samples = latency_frames as usize * config.channels as usize;

// The buffer to share samples
let ring = RingBuffer::new(latency_samples * 2);
Expand Down Expand Up @@ -80,10 +80,10 @@ fn main() -> Result<(), anyhow::Error> {
// Build streams.
println!(
"Attempting to build both streams with f32 samples and `{:?}`.",
shape
config
);
let input_stream = input_device.build_input_stream(&shape, input_data_fn, err_fn)?;
let output_stream = output_device.build_output_stream(&shape, output_data_fn, err_fn)?;
let input_stream = input_device.build_input_stream(&config, input_data_fn, err_fn)?;
let output_stream = output_device.build_output_stream(&config, output_data_fn, err_fn)?;
println!("Successfully built streams.");

// Play the streams.
Expand Down
32 changes: 16 additions & 16 deletions examples/record_wav.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Records a WAV file (roughly 3 seconds long) using the default input device and format.
//! Records a WAV file (roughly 3 seconds long) using the default input device and config.
//!
//! The input data is recorded to "$CARGO_MANIFEST_DIR/recorded.wav".

Expand All @@ -15,18 +15,18 @@ fn main() -> Result<(), anyhow::Error> {
// Use the default host for working with audio devices.
let host = cpal::default_host();

// Setup the default input device and stream with the default input format.
// Setup the default input device and stream with the default input config.
let device = host
.default_input_device()
.expect("Failed to get default input device");
println!("Default input device: {}", device.name()?);
let format = device
.default_input_format()
.expect("Failed to get default input format");
println!("Default input format: {:?}", format);
let config = device
.default_input_config()
.expect("Failed to get default input config");
println!("Default input config: {:?}", config);
// The WAV file we're recording to.
const PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/recorded.wav");
let spec = wav_spec_from_format(&format);
let spec = wav_spec_from_config(&config);
let writer = hound::WavWriter::create(PATH, spec)?;
let writer = Arc::new(Mutex::new(Some(writer)));

Expand All @@ -40,19 +40,19 @@ fn main() -> Result<(), anyhow::Error> {
eprintln!("an error occurred on stream: {}", err);
};

let stream = match format.data_type {
let stream = match config.sample_format() {
cpal::SampleFormat::F32 => device.build_input_stream(
&format.shape(),
&config.into(),
move |data| write_input_data::<f32, f32>(data, &writer_2),
err_fn,
)?,
cpal::SampleFormat::I16 => device.build_input_stream(
&format.shape(),
&config.into(),
move |data| write_input_data::<i16, i16>(data, &writer_2),
err_fn,
)?,
cpal::SampleFormat::U16 => device.build_input_stream(
&format.shape(),
&config.into(),
move |data| write_input_data::<u16, i16>(data, &writer_2),
err_fn,
)?,
Expand All @@ -76,12 +76,12 @@ fn sample_format(format: cpal::SampleFormat) -> hound::SampleFormat {
}
}

fn wav_spec_from_format(format: &cpal::Format) -> hound::WavSpec {
fn wav_spec_from_config(config: &cpal::SupportedStreamConfig) -> hound::WavSpec {
hound::WavSpec {
channels: format.channels as _,
sample_rate: format.sample_rate.0 as _,
bits_per_sample: (format.data_type.sample_size() * 8) as _,
sample_format: sample_format(format.data_type),
channels: config.channels() as _,
sample_rate: config.sample_rate().0 as _,
bits_per_sample: (config.sample_format().sample_size() * 8) as _,
sample_format: sample_format(config.sample_format()),
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub enum DeviceNameError {

/// Error that can happen when enumerating the list of supported formats.
#[derive(Debug, Error)]
pub enum SupportedFormatsError {
pub enum SupportedStreamConfigsError {
/// The device no longer exists. This can happen if the device is disconnected while the
/// program is running.
#[error("The requested device is no longer available. For example, it has been unplugged.")]
Expand All @@ -67,7 +67,7 @@ pub enum SupportedFormatsError {

/// May occur when attempting to request the default input or output stream format from a `Device`.
#[derive(Debug, Error)]
pub enum DefaultFormatError {
pub enum DefaultStreamConfigError {
/// The device no longer exists. This can happen if the device is disconnected while the
/// program is running.
#[error("The requested device is no longer available. For example, it has been unplugged.")]
Expand All @@ -90,9 +90,9 @@ pub enum BuildStreamError {
/// program is running.
#[error("The requested device is no longer available. For example, it has been unplugged.")]
DeviceNotAvailable,
/// The required format is not supported.
#[error("The requested stream format is not supported by the device.")]
FormatNotSupported,
/// The specified stream configuration is not supported.
#[error("The requested stream configuration is not supported by the device.")]
StreamConfigNotSupported,
/// We called something the C-Layer did not understand
///
/// On ALSA device functions called with a feature they do not support will yield this. E.g.
Expand Down
Loading