Skip to content

Commit

Permalink
Rename stream Format types to Config
Browse files Browse the repository at this point in the history
This implements the changes described at RustAudio#370.

This commit implements only the `null` and `alsa` backends - the rest
will be implemented in follow-up commits.

Closes RustAudio#370.
  • Loading branch information
mitchmindtree committed Jan 27, 2020
1 parent ae910e3 commit 9c781bd
Show file tree
Hide file tree
Showing 10 changed files with 287 additions and 272 deletions.
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(fmt) = device.default_input_config() {
println!(" Default input stream config:\n {:?}", fmt);
}
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(fmt) = device.default_output_config() {
println!(" Default output stream config:\n {:?}", fmt);
}
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
4 changes: 2 additions & 2 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 Down
Loading

0 comments on commit 9c781bd

Please sign in to comment.