Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate Sample to dasp_sample #689

Merged
merged 31 commits into from
Oct 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7fb06c1
migrate Sample to dasp_sample
kawogi Sep 9, 2022
d897488
fix typos
kawogi Sep 12, 2022
1248d4c
rustfmt
kawogi Sep 12, 2022
9401c09
fix clippy warnings
kawogi Sep 12, 2022
0065fbf
fix errors on windows platform
kawogi Sep 13, 2022
768a0df
migrate Sample to SizedSample
kawogi Sep 13, 2022
1798edb
fix leftover from edition 2018 migration
kawogi Sep 14, 2022
74cfbac
update trait to SizedSample
kawogi Sep 14, 2022
c4956ac
fix leftover from edition 2018 migration
kawogi Sep 14, 2022
925c924
update trait to SizedSample
kawogi Sep 14, 2022
3a91f81
catch more unsupported sample formats
kawogi Sep 14, 2022
bb98dd5
fix leftover from edition 2018 migration
kawogi Sep 14, 2022
08acedd
fix towards edition 2021
kawogi Sep 20, 2022
e78a847
fix some clippy warnings
kawogi Sep 20, 2022
f19ceeb
Merge pull request #691 from kawogi/edition-2021
est31 Sep 20, 2022
3eae882
migrate Sample to dasp_sample
kawogi Sep 9, 2022
927753d
fix typos
kawogi Sep 12, 2022
9dbe975
rustfmt
kawogi Sep 12, 2022
0fffb4a
fix errors on windows platform
kawogi Sep 13, 2022
ad07af0
migrate Sample to SizedSample
kawogi Sep 13, 2022
c301661
fix leftover from edition 2018 migration
kawogi Sep 14, 2022
c47d40d
update trait to SizedSample
kawogi Sep 14, 2022
d13f32c
update trait to SizedSample
kawogi Sep 14, 2022
a18967b
catch more unsupported sample formats
kawogi Sep 14, 2022
2df309c
Merge branch 'dasp_sample' of github.com:kawogi/cpal into dasp_sample
kawogi Sep 20, 2022
2266f1b
migrate sample conversions to dasp
kawogi Sep 20, 2022
587ca4e
remove AsioSample
kawogi Sep 20, 2022
45732ba
add missing trait bound
kawogi Sep 20, 2022
c09df56
add missing trait bound
kawogi Sep 20, 2022
9a699ba
handle all new sample types as unsupported
kawogi Sep 20, 2022
8585624
fix more warnings
kawogi Sep 20, 2022
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ asio = ["asio-sys", "num-traits"] # Only available on Windows. See README for se

[dependencies]
thiserror = "1.0.2"
dasp_sample = "0.11.0"

[dev-dependencies]
anyhow = "1.0.12"
Expand Down
26 changes: 21 additions & 5 deletions examples/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
extern crate anyhow;
extern crate cpal;

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

#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "full"))]
fn main() {
Expand All @@ -16,15 +20,27 @@ fn main() {
let config = device.default_output_config().unwrap();

match config.sample_format() {
cpal::SampleFormat::F32 => run::<f32>(&device, &config.into()).unwrap(),
cpal::SampleFormat::I8 => run::<i8>(&device, &config.into()).unwrap(),
cpal::SampleFormat::I16 => run::<i16>(&device, &config.into()).unwrap(),
// cpal::SampleFormat::I24 => run::<I24>(&device, &config.into()).unwrap(),
cpal::SampleFormat::I32 => run::<i32>(&device, &config.into()).unwrap(),
// cpal::SampleFormat::I48 => run::<I48>(&device, &config.into()).unwrap(),
cpal::SampleFormat::I64 => run::<i64>(&device, &config.into()).unwrap(),
cpal::SampleFormat::U8 => run::<u8>(&device, &config.into()).unwrap(),
cpal::SampleFormat::U16 => run::<u16>(&device, &config.into()).unwrap(),
// cpal::SampleFormat::U24 => run::<U24>(&device, &config.into()).unwrap(),
cpal::SampleFormat::U32 => run::<u32>(&device, &config.into()).unwrap(),
// cpal::SampleFormat::U48 => run::<U48>(&device, &config.into()).unwrap(),
cpal::SampleFormat::U64 => run::<u64>(&device, &config.into()).unwrap(),
cpal::SampleFormat::F32 => run::<f32>(&device, &config.into()).unwrap(),
cpal::SampleFormat::F64 => run::<f64>(&device, &config.into()).unwrap(),
sample_format => panic!("Unsupported sample format '{sample_format}'"),
}
}

fn run<T>(device: &cpal::Device, config: &cpal::StreamConfig) -> Result<(), anyhow::Error>
where
T: cpal::Sample,
T: SizedSample + FromSample<f32>,
{
let sample_rate = config.sample_rate.0 as f32;
let channels = config.channels as usize;
Expand Down Expand Up @@ -54,10 +70,10 @@ where

fn write_data<T>(output: &mut [T], channels: usize, next_sample: &mut dyn FnMut() -> f32)
where
T: cpal::Sample,
T: Sample + FromSample<f32>,
{
for frame in output.chunks_mut(channels) {
let value: T = cpal::Sample::from::<f32>(&next_sample());
let value: T = T::from_sample(next_sample());
for sample in frame.iter_mut() {
*sample = value;
}
Expand Down
26 changes: 21 additions & 5 deletions examples/beep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ extern crate clap;
extern crate cpal;

use clap::arg;
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{
traits::{DeviceTrait, HostTrait, StreamTrait},
SizedSample,
};
use cpal::{FromSample, Sample};

#[derive(Debug)]
struct Opt {
Expand Down Expand Up @@ -84,15 +88,27 @@ fn main() -> anyhow::Result<()> {
println!("Default output config: {:?}", config);

match config.sample_format() {
cpal::SampleFormat::F32 => run::<f32>(&device, &config.into()),
cpal::SampleFormat::I8 => run::<i8>(&device, &config.into()),
cpal::SampleFormat::I16 => run::<i16>(&device, &config.into()),
// cpal::SampleFormat::I24 => run::<I24>(&device, &config.into()),
cpal::SampleFormat::I32 => run::<i32>(&device, &config.into()),
// cpal::SampleFormat::I48 => run::<I48>(&device, &config.into()),
cpal::SampleFormat::I64 => run::<i64>(&device, &config.into()),
cpal::SampleFormat::U8 => run::<u8>(&device, &config.into()),
cpal::SampleFormat::U16 => run::<u16>(&device, &config.into()),
// cpal::SampleFormat::U24 => run::<U24>(&device, &config.into()),
cpal::SampleFormat::U32 => run::<u32>(&device, &config.into()),
// cpal::SampleFormat::U48 => run::<U48>(&device, &config.into()),
cpal::SampleFormat::U64 => run::<u64>(&device, &config.into()),
cpal::SampleFormat::F32 => run::<f32>(&device, &config.into()),
cpal::SampleFormat::F64 => run::<f64>(&device, &config.into()),
sample_format => panic!("Unsupported sample format '{sample_format}'"),
}
}

pub fn run<T>(device: &cpal::Device, config: &cpal::StreamConfig) -> Result<(), anyhow::Error>
where
T: cpal::Sample,
T: SizedSample + FromSample<f32>,
{
let sample_rate = config.sample_rate.0 as f32;
let channels = config.channels as usize;
Expand Down Expand Up @@ -122,10 +138,10 @@ where

fn write_data<T>(output: &mut [T], channels: usize, next_sample: &mut dyn FnMut() -> f32)
where
T: cpal::Sample,
T: Sample + FromSample<f32>,
{
for frame in output.chunks_mut(channels) {
let value: T = cpal::Sample::from::<f32>(&next_sample());
let value: T = T::from_sample(next_sample());
for sample in frame.iter_mut() {
*sample = value;
}
Expand Down
33 changes: 22 additions & 11 deletions examples/record_wav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ extern crate hound;

use clap::arg;
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{FromSample, Sample};
use std::fs::File;
use std::io::BufWriter;
use std::sync::{Arc, Mutex};
Expand Down Expand Up @@ -112,21 +113,31 @@ fn main() -> Result<(), anyhow::Error> {
};

let stream = match config.sample_format() {
cpal::SampleFormat::F32 => device.build_input_stream(
cpal::SampleFormat::I8 => device.build_input_stream(
&config.into(),
move |data, _: &_| write_input_data::<f32, f32>(data, &writer_2),
move |data, _: &_| write_input_data::<i8, i8>(data, &writer_2),
err_fn,
)?,
cpal::SampleFormat::I16 => device.build_input_stream(
&config.into(),
move |data, _: &_| write_input_data::<i16, i16>(data, &writer_2),
err_fn,
)?,
cpal::SampleFormat::U16 => device.build_input_stream(
cpal::SampleFormat::I32 => device.build_input_stream(
&config.into(),
move |data, _: &_| write_input_data::<u16, i16>(data, &writer_2),
move |data, _: &_| write_input_data::<i32, i32>(data, &writer_2),
err_fn,
)?,
cpal::SampleFormat::F32 => device.build_input_stream(
&config.into(),
move |data, _: &_| write_input_data::<f32, f32>(data, &writer_2),
err_fn,
)?,
sample_format => {
return Err(anyhow::Error::msg(format!(
"Unsupported sample format '{sample_format}'"
)))
}
};

stream.play()?;
Expand All @@ -140,10 +151,10 @@ fn main() -> Result<(), anyhow::Error> {
}

fn sample_format(format: cpal::SampleFormat) -> hound::SampleFormat {
match format {
cpal::SampleFormat::U16 => hound::SampleFormat::Int,
cpal::SampleFormat::I16 => hound::SampleFormat::Int,
cpal::SampleFormat::F32 => hound::SampleFormat::Float,
if format.is_float() {
hound::SampleFormat::Float
} else {
hound::SampleFormat::Int
}
}

Expand All @@ -160,13 +171,13 @@ type WavWriterHandle = Arc<Mutex<Option<hound::WavWriter<BufWriter<File>>>>>;

fn write_input_data<T, U>(input: &[T], writer: &WavWriterHandle)
where
T: cpal::Sample,
U: cpal::Sample + hound::Sample,
T: Sample,
U: Sample + hound::Sample + FromSample<T>,
{
if let Ok(mut guard) = writer.try_lock() {
if let Some(writer) = guard.as_mut() {
for &sample in input.iter() {
let sample: U = cpal::Sample::from(&sample);
let sample: U = U::from_sample(sample);
writer.write_sample(sample).ok();
}
}
Expand Down
28 changes: 23 additions & 5 deletions examples/synth_tones.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ extern crate anyhow;
extern crate clap;
extern crate cpal;

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

fn main() -> anyhow::Result<()> {
let stream = stream_setup_for(sample_next)?;
Expand Down Expand Up @@ -43,9 +47,23 @@ where
let (_host, device, config) = host_device_setup()?;

match config.sample_format() {
cpal::SampleFormat::F32 => stream_make::<f32, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::I8 => stream_make::<i8, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::I16 => stream_make::<i16, _>(&device, &config.into(), on_sample),
// cpal::SampleFormat::I24 => stream_make::<I24, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::I32 => stream_make::<i32, _>(&device, &config.into(), on_sample),
// cpal::SampleFormat::I48 => stream_make::<I48, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::I64 => stream_make::<i64, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::U8 => stream_make::<u8, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::U16 => stream_make::<u16, _>(&device, &config.into(), on_sample),
// cpal::SampleFormat::U24 => stream_make::<U24, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::U32 => stream_make::<u32, _>(&device, &config.into(), on_sample),
// cpal::SampleFormat::U48 => stream_make::<U48, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::U64 => stream_make::<u64, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::F32 => stream_make::<f32, _>(&device, &config.into(), on_sample),
cpal::SampleFormat::F64 => stream_make::<f64, _>(&device, &config.into(), on_sample),
sample_format => Err(anyhow::Error::msg(format!(
"Unsupported sample format '{sample_format}'"
))),
}
}

Expand All @@ -70,7 +88,7 @@ pub fn stream_make<T, F>(
on_sample: F,
) -> Result<cpal::Stream, anyhow::Error>
where
T: cpal::Sample,
T: SizedSample + FromSample<f32>,
F: FnMut(&mut SampleRequestOptions) -> f32 + std::marker::Send + 'static + Copy,
{
let sample_rate = config.sample_rate.0 as f32;
Expand All @@ -96,11 +114,11 @@ where

fn on_window<T, F>(output: &mut [T], request: &mut SampleRequestOptions, mut on_sample: F)
where
T: cpal::Sample,
T: Sample + FromSample<f32>,
F: FnMut(&mut SampleRequestOptions) -> f32 + std::marker::Send + 'static,
{
for frame in output.chunks_mut(request.nchannels) {
let value: T = cpal::Sample::from::<f32>(&on_sample(request));
let value: T = T::from_sample(on_sample(request));
for sample in frame.iter_mut() {
*sample = value;
}
Expand Down
54 changes: 46 additions & 8 deletions src/host/alsa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ impl Device {
let hw_params = alsa::pcm::HwParams::any(handle)?;

// TODO: check endianness
const FORMATS: [(SampleFormat, alsa::pcm::Format); 3] = [
//SND_PCM_FORMAT_S8,
//SND_PCM_FORMAT_U8,
const FORMATS: [(SampleFormat, alsa::pcm::Format); 8] = [
(SampleFormat::I8, alsa::pcm::Format::S8),
(SampleFormat::U8, alsa::pcm::Format::U8),
(SampleFormat::I16, alsa::pcm::Format::S16LE),
//SND_PCM_FORMAT_S16_BE,
(SampleFormat::U16, alsa::pcm::Format::U16LE),
Expand All @@ -323,13 +323,13 @@ impl Device {
//SND_PCM_FORMAT_S24_BE,
//SND_PCM_FORMAT_U24_LE,
//SND_PCM_FORMAT_U24_BE,
//SND_PCM_FORMAT_S32_LE,
(SampleFormat::I32, alsa::pcm::Format::S32LE),
//SND_PCM_FORMAT_S32_BE,
//SND_PCM_FORMAT_U32_LE,
(SampleFormat::U32, alsa::pcm::Format::U32LE),
//SND_PCM_FORMAT_U32_BE,
(SampleFormat::F32, alsa::pcm::Format::FloatLE),
//SND_PCM_FORMAT_FLOAT_BE,
//SND_PCM_FORMAT_FLOAT64_LE,
(SampleFormat::F64, alsa::pcm::Format::Float64LE),
//SND_PCM_FORMAT_FLOAT64_BE,
//SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
//SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
Expand Down Expand Up @@ -892,7 +892,7 @@ impl Stream {
let thread = thread::Builder::new()
.name("cpal_alsa_in".to_owned())
.spawn(move || {
input_stream_worker(rx, &*stream, &mut data_callback, &mut error_callback);
input_stream_worker(rx, &stream, &mut data_callback, &mut error_callback);
})
.unwrap();
Stream {
Expand All @@ -917,7 +917,7 @@ impl Stream {
let thread = thread::Builder::new()
.name("cpal_alsa_out".to_owned())
.spawn(move || {
output_stream_worker(rx, &*stream, &mut data_callback, &mut error_callback);
output_stream_worker(rx, &stream, &mut data_callback, &mut error_callback);
})
.unwrap();
Stream {
Expand Down Expand Up @@ -956,15 +956,53 @@ fn set_hw_params_from_format(

let sample_format = if cfg!(target_endian = "big") {
match sample_format {
SampleFormat::I8 => alsa::pcm::Format::S8,
SampleFormat::I16 => alsa::pcm::Format::S16BE,
// SampleFormat::I24 => alsa::pcm::Format::S24BE,
SampleFormat::I32 => alsa::pcm::Format::S32BE,
// SampleFormat::I48 => alsa::pcm::Format::S48BE,
// SampleFormat::I64 => alsa::pcm::Format::S64BE,
SampleFormat::U8 => alsa::pcm::Format::U8,
SampleFormat::U16 => alsa::pcm::Format::U16BE,
// SampleFormat::U24 => alsa::pcm::Format::U24BE,
SampleFormat::U32 => alsa::pcm::Format::U32BE,
// SampleFormat::U48 => alsa::pcm::Format::U48BE,
// SampleFormat::U64 => alsa::pcm::Format::U64BE,
SampleFormat::F32 => alsa::pcm::Format::FloatBE,
SampleFormat::F64 => alsa::pcm::Format::Float64BE,
sample_format => {
return Err(BackendSpecificError {
description: format!(
"Sample format '{}' is not supported by this backend",
sample_format
),
})
}
}
} else {
match sample_format {
SampleFormat::I8 => alsa::pcm::Format::S8,
SampleFormat::I16 => alsa::pcm::Format::S16LE,
// SampleFormat::I24 => alsa::pcm::Format::S24LE,
SampleFormat::I32 => alsa::pcm::Format::S32LE,
// SampleFormat::I48 => alsa::pcm::Format::S48LE,
// SampleFormat::I64 => alsa::pcm::Format::S64LE,
SampleFormat::U8 => alsa::pcm::Format::U8,
SampleFormat::U16 => alsa::pcm::Format::U16LE,
// SampleFormat::U24 => alsa::pcm::Format::U24LE,
SampleFormat::U32 => alsa::pcm::Format::U32LE,
// SampleFormat::U48 => alsa::pcm::Format::U48LE,
// SampleFormat::U64 => alsa::pcm::Format::U64LE,
SampleFormat::F32 => alsa::pcm::Format::FloatLE,
SampleFormat::F64 => alsa::pcm::Format::Float64LE,
sample_format => {
return Err(BackendSpecificError {
description: format!(
"Sample format '{}' is not supported by this backend",
sample_format
),
})
}
}
};

Expand Down
Loading