Skip to content

Commit

Permalink
fix tests
Browse files Browse the repository at this point in the history
leave unimplemented placeholder for examples
  • Loading branch information
julientregoat committed Oct 14, 2020
1 parent 6d165bc commit 131cb84
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 19 deletions.
1 change: 1 addition & 0 deletions examples/beep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ fn main() -> Result<(), anyhow::Error> {
cpal::SampleFormat::I16 => run::<i16>(&device, &config.into())?,
cpal::SampleFormat::I32 => run::<i32>(&device, &config.into())?,
cpal::SampleFormat::U16 => run::<u16>(&device, &config.into())?,
cpal::SampleFormat::I24 => unimplemented!()
}

Ok(())
Expand Down
2 changes: 2 additions & 0 deletions examples/record_wav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ fn main() -> Result<(), anyhow::Error> {
move |data, _: &_| write_input_data::<i16, i16>(data, &writer_2),
err_fn,
)?,
cpal::SampleFormat::I24 => unimplemented!(),
cpal::SampleFormat::I32 => device.build_input_stream(
&config.into(),
move |data, _: &_| write_input_data::<i32, i32>(data, &writer_2),
Expand Down Expand Up @@ -79,6 +80,7 @@ fn sample_format(format: cpal::SampleFormat) -> hound::SampleFormat {
hound::SampleFormat::Int
}
cpal::SampleFormat::F32 => hound::SampleFormat::Float,
cpal::SampleFormat::I24 => unimplemented!()
}
}

Expand Down
49 changes: 43 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
//! SampleFormat::I16 => device.build_output_stream(&config, write_silence::<i16>, err_fn),
//! SampleFormat::I32 => device.build_output_stream(&config, write_silence::<i32>, err_fn),
//! SampleFormat::U16 => device.build_output_stream(&config, write_silence::<u16>, err_fn),
//! SampleFormat::I24 => unimplemented!(),
//! }.unwrap();
//!
//! fn write_silence<T: Sample>(data: &mut [T], _: &cpal::OutputCallbackInfo) {
Expand Down Expand Up @@ -603,14 +604,16 @@ impl SupportedStreamConfigRange {
/// - f32
/// - i16
/// - u16
/// - i32
/// - i24
///
/// **Sample rate**:
///
/// - 44100 (cd quality)
/// - Max sample rate
pub fn cmp_default_heuristics(&self, other: &Self) -> std::cmp::Ordering {
use std::cmp::Ordering::Equal;
use SampleFormat::{F32, I16, I32, U16};
use SampleFormat::{F32, I16, I32, U16, I24};

let cmp_stereo = (self.channels == 2).cmp(&(other.channels == 2));
if cmp_stereo != Equal {
Expand Down Expand Up @@ -642,6 +645,16 @@ impl SupportedStreamConfigRange {
return cmp_u16;
}

let cmp_i32 = (self.sample_format == I32).cmp(&(other.sample_format == I32));
if cmp_i32 != Equal {
return cmp_i32;
}

let cmp_i24 = (self.sample_format == I24).cmp(&(other.sample_format == I24));
if cmp_i24 != Equal {
return cmp_i24;
}

const HZ_44100: SampleRate = SampleRate(44_100);
let r44100_in_self = self.min_sample_rate <= HZ_44100 && HZ_44100 <= self.max_sample_rate;
let r44100_in_other =
Expand Down Expand Up @@ -693,6 +706,20 @@ fn test_cmp_default_heuristics() {
max_sample_rate: SampleRate(22050),
sample_format: SampleFormat::F32,
},
SupportedStreamConfigRange {
buffer_size: SupportedBufferSize::Range { min: 256, max: 512 },
channels: 2,
min_sample_rate: SampleRate(1),
max_sample_rate: SampleRate(96000),
sample_format: SampleFormat::I24,
},
SupportedStreamConfigRange {
buffer_size: SupportedBufferSize::Range { min: 256, max: 512 },
channels: 2,
min_sample_rate: SampleRate(1),
max_sample_rate: SampleRate(96000),
sample_format: SampleFormat::I32,
},
];

formats.sort_by(|a, b| a.cmp_default_heuristics(b));
Expand All @@ -703,25 +730,35 @@ fn test_cmp_default_heuristics() {
assert_eq!(formats[0].max_sample_rate(), SampleRate(96000));
assert_eq!(formats[0].channels(), 1);

assert_eq!(formats[1].sample_format(), SampleFormat::U16);
assert_eq!(formats[1].sample_format(), SampleFormat::I24);
assert_eq!(formats[1].min_sample_rate(), SampleRate(1));
assert_eq!(formats[1].max_sample_rate(), SampleRate(96000));
assert_eq!(formats[1].channels(), 2);

assert_eq!(formats[2].sample_format(), SampleFormat::I16);
assert_eq!(formats[2].sample_format(), SampleFormat::I32);
assert_eq!(formats[2].min_sample_rate(), SampleRate(1));
assert_eq!(formats[2].max_sample_rate(), SampleRate(96000));
assert_eq!(formats[2].channels(), 2);

assert_eq!(formats[3].sample_format(), SampleFormat::F32);
assert_eq!(formats[3].sample_format(), SampleFormat::U16);
assert_eq!(formats[3].min_sample_rate(), SampleRate(1));
assert_eq!(formats[3].max_sample_rate(), SampleRate(22050));
assert_eq!(formats[3].max_sample_rate(), SampleRate(96000));
assert_eq!(formats[3].channels(), 2);

assert_eq!(formats[4].sample_format(), SampleFormat::F32);
assert_eq!(formats[4].sample_format(), SampleFormat::I16);
assert_eq!(formats[4].min_sample_rate(), SampleRate(1));
assert_eq!(formats[4].max_sample_rate(), SampleRate(96000));
assert_eq!(formats[4].channels(), 2);

assert_eq!(formats[5].sample_format(), SampleFormat::F32);
assert_eq!(formats[5].min_sample_rate(), SampleRate(1));
assert_eq!(formats[5].max_sample_rate(), SampleRate(22050));
assert_eq!(formats[5].channels(), 2);

assert_eq!(formats[6].sample_format(), SampleFormat::F32);
assert_eq!(formats[6].min_sample_rate(), SampleRate(1));
assert_eq!(formats[6].max_sample_rate(), SampleRate(96000));
assert_eq!(formats[6].channels(), 2);
}

impl From<SupportedStreamConfig> for StreamConfig {
Expand Down
89 changes: 76 additions & 13 deletions src/samples_formats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ unsafe impl Sample for u16 {

#[inline]
fn to_f32(&self) -> f32 {
*self as f32 / ::std::u16::MAX as f32
self.to_i16().to_f32()
}

#[inline]
Expand Down Expand Up @@ -142,11 +142,13 @@ unsafe impl Sample for f32 {
*self
}

/// This function inherently returns a lossy value due to scaling.
#[inline]
fn to_u16(&self) -> u16 {
(((*self + 1.0) * 0.5) * ::std::u16::MAX as f32).round() as u16
}

/// This function inherently returns a lossy value due to scaling.
#[inline]
fn to_i16(&self) -> i16 {
if *self >= 0.0 {
Expand All @@ -156,6 +158,7 @@ unsafe impl Sample for f32 {
}
}

/// This function inherently returns a lossy value due to scaling.
#[inline]
fn to_i24(&self) -> Padded24 {
let result: f32;
Expand All @@ -169,7 +172,11 @@ unsafe impl Sample for f32 {

#[inline]
fn to_i32(&self) -> i32 {
(*self as f64 * std::i32::MAX as f64).round() as i32
if self.is_sign_positive() {
(*self as f64 * std::i32::MAX as f64).round() as i32
} else {
(*self as f64 * -(std::i32::MIN as f64)).round() as i32
}
}

#[inline]
Expand Down Expand Up @@ -250,11 +257,13 @@ unsafe impl Sample for Padded24 {
}
}

/// This function inherently returns a lossy value due to scaling.
#[inline]
fn to_i16(&self) -> i16 {
self.to_f32().to_i16()
}

/// This function inherently returns a lossy value due to scaling.
#[inline]
fn to_u16(&self) -> u16 {
self.to_f32().to_u16()
Expand All @@ -265,7 +274,6 @@ unsafe impl Sample for Padded24 {
*self
}


#[inline]
fn to_i32(&self) -> i32 {
self.to_f32().to_i32()
Expand All @@ -283,6 +291,7 @@ unsafe impl Sample for Padded24 {
unsafe impl Sample for i32 {
const FORMAT: SampleFormat = SampleFormat::I32;

/// This function inherently returns a lossy value due to scaling.
#[inline]
fn to_f32(&self) -> f32 {
if *self < 0 {
Expand All @@ -292,16 +301,19 @@ unsafe impl Sample for i32 {
}
}

/// This function inherently returns a lossy value due to scaling.
#[inline]
fn to_i16(&self) -> i16 {
self.to_f32().to_i16()
}

/// This function inherently returns a lossy value due to scaling.
#[inline]
fn to_u16(&self) -> u16 {
self.to_f32().to_u16()
}

/// This function inherently returns a lossy value due to scaling.
#[inline]
fn to_i24(&self) -> Padded24 {
self.to_f32().to_i24()
Expand All @@ -321,10 +333,63 @@ unsafe impl Sample for i32 {
}
}

// TODO add _to_i24 tests

#[cfg(test)]
mod test {
use super::Sample;
use super::{Sample, Padded24};

#[test]
fn i24_to_i16() {
assert_eq!(Padded24::new(Padded24::MAX).to_i16(), std::i16::MAX);
assert_eq!(Padded24::new(Padded24::MIN / 2).to_i16(), std::i16::MIN / 2);
assert_eq!(Padded24::new(Padded24::MIN).to_i16(), std::i16::MIN);
assert_eq!(Padded24::new(0).to_i16(), 0);
}

#[test]
fn i24_to_i24() {
// let max = Padded24::new(Padded24::MAX);
// let min = Padded24::new(Padded24::MIN);

// assert_eq!(max.to_i16(), std::i16::MAX);
// assert_eq!((std::i32::MIN / 2).to_i16(), std::i16::MIN / 2);
// assert_eq!(std::i32::MIN.to_i16(), std::i16::MIN);
// assert_eq!(0i32.to_i16(), 0);
}


#[test]
fn i24_to_i32() {
assert_eq!(Padded24::new(Padded24::MAX).to_i32(), std::i32::MAX);
assert_eq!(Padded24::new(Padded24::MIN / 2).to_i32(), std::i32::MIN / 2);
assert_eq!(Padded24::new(Padded24::MIN).to_i32(), std::i32::MIN);
assert_eq!(Padded24::new(0).to_i32(), 0);
}

#[test]
fn i24_to_u16() {
assert_eq!(Padded24::new(Padded24::MAX).to_u16(), std::u16::MAX);
// half of the int max will be 3/4 of the uint max
assert_eq!(
Padded24::new(Padded24::MAX / 2).to_u16(),
(std::u16::MAX as f32 / 4.0 * 3.0).round() as u16
);
assert_eq!(Padded24::new(Padded24::MIN).to_u16(), std::u16::MIN);
}

#[test]
fn i24_to_f32() {
let max = Padded24::new(Padded24::MAX);
let min = Padded24::new(Padded24::MIN);

assert_eq!(max.to_f32(), 1.0f32);
assert_eq!(max.to_f32() / 8.0, 0.125f32);
assert_eq!(max.to_f32() / -16.0, -0.0625f32);
assert_eq!(max.to_f32() / -4.0, -0.25f32);
assert_eq!(min.to_f32(), -1.0f32);
assert_eq!(Padded24::new(0).to_f32(), 0f32);
}

#[test]
fn i32_to_i16() {
Expand All @@ -346,8 +411,8 @@ mod test {
fn i32_to_u16() {
assert_eq!(std::i32::MAX.to_u16(), std::u16::MAX);
assert_eq!(
(std::i32::MIN / 2).to_u16(),
(std::u16::MAX as f32 / 4f32) as u16
0i32.to_u16(),
(std::u16::MAX as f32 / 2.0).round() as u16
);
assert_eq!(std::i32::MIN.to_u16(), std::u16::MIN);
}
Expand All @@ -373,9 +438,8 @@ mod test {
#[test]
fn i16_to_i32() {
assert_eq!(0i16.to_i32(), 0);
assert_eq!((-467i16).to_i32(), -467);
assert_eq!(std::i16::MAX.to_i32(), std::i16::MAX as i32);
assert_eq!(std::i16::MIN.to_i32(), std::i16::MIN as i32);
assert_eq!(std::i16::MAX.to_i32(), std::i32::MAX);
assert_eq!(std::i16::MIN.to_i32(), std::i32::MIN);
}

#[test]
Expand Down Expand Up @@ -405,10 +469,9 @@ mod test {

#[test]
fn u16_to_i32() {
assert_eq!(32768u16.to_i32(), 0);
assert_eq!(16384u16.to_i32(), -16384);
assert_eq!(65535u16.to_i32(), std::i16::MAX as i32);
assert_eq!(0u16.to_i32(), std::i16::MIN as i32);
assert_eq!(((std::u16::MAX as f32 / 2.0).round() as u16).to_i32(), 0);
assert_eq!(std::u16::MAX.to_i32(), std::i32::MAX);
assert_eq!(std::u16::MIN.to_i32(), std::i32::MIN);
}

#[test]
Expand Down

0 comments on commit 131cb84

Please sign in to comment.