Add SupportedFormat (#168)
This commit is contained in:
parent
393206bde9
commit
87949d859b
|
@ -6,3 +6,5 @@
|
|||
and `EventLoop::pause` that can be used to create, destroy, play and pause voices.
|
||||
- Added a `VoiceId` struct that is now used to identify a voice owned by an `EventLoop`.
|
||||
- Changed `EventLoop::run()` to take a callback that is called whenever a voice requires sound data.
|
||||
- Changed `supported_formats()` to produce a list of `SupportedFormat` instead of `Format`. A
|
||||
`SupportedFormat` must then be turned into a `Format` in order to build a voice.
|
||||
|
|
|
@ -6,7 +6,8 @@ fn main() {
|
|||
.supported_formats()
|
||||
.unwrap()
|
||||
.next()
|
||||
.expect("Failed to get endpoint format");
|
||||
.expect("Failed to get endpoint format")
|
||||
.with_max_samples_rate();
|
||||
|
||||
let event_loop = cpal::EventLoop::new();
|
||||
let voice_id = event_loop.build_voice(&endpoint, &format).unwrap();
|
||||
|
|
|
@ -9,6 +9,7 @@ use Format;
|
|||
use FormatsEnumerationError;
|
||||
use SampleFormat;
|
||||
use SamplesRate;
|
||||
use SupportedFormat;
|
||||
use UnknownTypeBuffer;
|
||||
|
||||
use std::{cmp, ffi, iter, mem, ptr};
|
||||
|
@ -16,7 +17,7 @@ use std::sync::{Arc, Mutex};
|
|||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::vec::IntoIter as VecIntoIter;
|
||||
|
||||
pub type SupportedFormatsIterator = VecIntoIter<Format>;
|
||||
pub type SupportedFormatsIterator = VecIntoIter<SupportedFormat>;
|
||||
|
||||
mod enumerate;
|
||||
|
||||
|
@ -152,10 +153,9 @@ impl Endpoint {
|
|||
.expect("unable to get maximum supported rate");
|
||||
|
||||
let samples_rates = if min_rate == max_rate {
|
||||
vec![min_rate]
|
||||
/*} else if alsa::snd_pcm_hw_params_test_rate(playback_handle, hw_params.0, min_rate + 1, 0) == 0 {
|
||||
(min_rate .. max_rate + 1).collect()*/
|
||||
// TODO: code is correct but returns lots of stuff
|
||||
vec![(min_rate, max_rate)]
|
||||
} else if alsa::snd_pcm_hw_params_test_rate(playback_handle, hw_params.0, min_rate + 1, 0) == 0 {
|
||||
vec![(min_rate, max_rate)]
|
||||
} else {
|
||||
const RATES: [libc::c_uint; 13] = [
|
||||
5512,
|
||||
|
@ -180,15 +180,15 @@ impl Endpoint {
|
|||
rate,
|
||||
0) == 0
|
||||
{
|
||||
rates.push(rate);
|
||||
rates.push((rate, rate));
|
||||
}
|
||||
}
|
||||
|
||||
/*if rates.len() == 0 {
|
||||
(min_rate .. max_rate + 1).collect()
|
||||
} else {*/
|
||||
rates // TODO: code is correct but returns lots of stuff
|
||||
//}
|
||||
if rates.len() == 0 {
|
||||
vec![(min_rate, max_rate)]
|
||||
} else {
|
||||
rates
|
||||
}
|
||||
};
|
||||
|
||||
let mut min_channels = mem::uninitialized();
|
||||
|
@ -227,10 +227,11 @@ impl Endpoint {
|
|||
samples_rates.len());
|
||||
for &data_type in supported_formats.iter() {
|
||||
for channels in supported_channels.iter() {
|
||||
for &rate in samples_rates.iter() {
|
||||
output.push(Format {
|
||||
for &(min_rate, max_rate) in samples_rates.iter() {
|
||||
output.push(SupportedFormat {
|
||||
channels: channels.clone(),
|
||||
samples_rate: SamplesRate(rate as u32),
|
||||
min_samples_rate: SamplesRate(min_rate as u32),
|
||||
max_samples_rate: SamplesRate(max_rate as u32),
|
||||
data_type: data_type,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use super::Endpoint;
|
||||
|
||||
use Format;
|
||||
use SupportedFormat;
|
||||
|
||||
use std::vec::IntoIter as VecIntoIter;
|
||||
|
||||
|
@ -33,4 +34,4 @@ pub fn default_endpoint() -> Option<Endpoint> {
|
|||
Some(Endpoint)
|
||||
}
|
||||
|
||||
pub type SupportedFormatsIterator = VecIntoIter<Format>;
|
||||
pub type SupportedFormatsIterator = VecIntoIter<SupportedFormat>;
|
||||
|
|
|
@ -7,6 +7,7 @@ use FormatsEnumerationError;
|
|||
use Sample;
|
||||
use SampleFormat;
|
||||
use SamplesRate;
|
||||
use SupportedFormat;
|
||||
use UnknownTypeBuffer;
|
||||
|
||||
use std::mem;
|
||||
|
@ -30,9 +31,10 @@ impl Endpoint {
|
|||
-> Result<SupportedFormatsIterator, FormatsEnumerationError> {
|
||||
Ok(
|
||||
vec![
|
||||
Format {
|
||||
SupportedFormat {
|
||||
channels: vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight],
|
||||
samples_rate: SamplesRate(44100),
|
||||
min_samples_rate: SamplesRate(44100),
|
||||
max_samples_rate: SamplesRate(44100),
|
||||
data_type: SampleFormat::F32,
|
||||
},
|
||||
].into_iter(),
|
||||
|
|
|
@ -7,6 +7,7 @@ use CreationError;
|
|||
use Format;
|
||||
use FormatsEnumerationError;
|
||||
use Sample;
|
||||
use SupportedFormat;
|
||||
use UnknownTypeBuffer;
|
||||
|
||||
extern {
|
||||
|
@ -182,9 +183,10 @@ impl Endpoint {
|
|||
// TODO: right now cpal's API doesn't allow flexibility here
|
||||
// "44100" and "2" (channels) have also been hard-coded in the rest of the code ; if
|
||||
// this ever becomes more flexible, don't forget to change that
|
||||
Ok(vec![Format {
|
||||
Ok(vec![SupportedFormat {
|
||||
channels: vec![::ChannelPosition::BackLeft, ::ChannelPosition::BackRight],
|
||||
samples_rate: ::SamplesRate(44100),
|
||||
min_samples_rate: ::SamplesRate(44100),
|
||||
max_samples_rate: ::SamplesRate(44100),
|
||||
data_type: ::SampleFormat::F32,
|
||||
}].into_iter())
|
||||
}
|
||||
|
@ -195,7 +197,7 @@ impl Endpoint {
|
|||
}
|
||||
}
|
||||
|
||||
pub type SupportedFormatsIterator = ::std::vec::IntoIter<Format>;
|
||||
pub type SupportedFormatsIterator = ::std::vec::IntoIter<SupportedFormat>;
|
||||
|
||||
pub struct Buffer<'a, T: 'a> where T: Sample {
|
||||
temporary_buffer: Vec<T>,
|
||||
|
|
40
src/lib.rs
40
src/lib.rs
|
@ -11,7 +11,8 @@ let endpoint = cpal::default_endpoint().unwrap();
|
|||
// a `Result` to handle this situation
|
||||
|
||||
// getting a format for the PCM
|
||||
let format = endpoint.supported_formats().unwrap().next().unwrap();
|
||||
let supported_formats_range = endpoint.supported_formats().unwrap().next().unwrap();
|
||||
let format = supported_formats_range.with_max_samples_rate();
|
||||
|
||||
let event_loop = cpal::EventLoop::new();
|
||||
|
||||
|
@ -188,10 +189,10 @@ pub struct Format {
|
|||
pub struct SupportedFormatsIterator(cpal_impl::SupportedFormatsIterator);
|
||||
|
||||
impl Iterator for SupportedFormatsIterator {
|
||||
type Item = Format;
|
||||
type Item = SupportedFormat;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Format> {
|
||||
fn next(&mut self) -> Option<SupportedFormat> {
|
||||
self.0.next()
|
||||
}
|
||||
|
||||
|
@ -201,6 +202,39 @@ impl Iterator for SupportedFormatsIterator {
|
|||
}
|
||||
}
|
||||
|
||||
/// Describes a format.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct SupportedFormat {
|
||||
pub channels: Vec<ChannelPosition>,
|
||||
pub min_samples_rate: SamplesRate,
|
||||
pub max_samples_rate: SamplesRate,
|
||||
pub data_type: SampleFormat,
|
||||
}
|
||||
|
||||
impl SupportedFormat {
|
||||
/// Builds a corresponding `Format` corresponding to the maximum samples rate.
|
||||
#[inline]
|
||||
pub fn with_max_samples_rate(self) -> Format {
|
||||
Format {
|
||||
channels: self.channels,
|
||||
samples_rate: self.max_samples_rate,
|
||||
data_type: self.data_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Format> for SupportedFormat {
|
||||
#[inline]
|
||||
fn from(format: Format) -> SupportedFormat {
|
||||
SupportedFormat {
|
||||
channels: format.channels,
|
||||
min_samples_rate: format.samples_rate,
|
||||
max_samples_rate: format.samples_rate,
|
||||
data_type: format.data_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventLoop(cpal_impl::EventLoop);
|
||||
|
||||
impl EventLoop {
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::marker::PhantomData;
|
|||
use CreationError;
|
||||
use Format;
|
||||
use FormatsEnumerationError;
|
||||
use SupportedFormat;
|
||||
use UnknownTypeBuffer;
|
||||
|
||||
pub struct EventLoop;
|
||||
|
@ -84,10 +85,10 @@ impl Endpoint {
|
|||
pub struct SupportedFormatsIterator;
|
||||
|
||||
impl Iterator for SupportedFormatsIterator {
|
||||
type Item = Format;
|
||||
type Item = SupportedFormat;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Format> {
|
||||
fn next(&mut self) -> Option<SupportedFormat> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,17 +8,17 @@ use std::slice;
|
|||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
|
||||
use ChannelPosition;
|
||||
use Format;
|
||||
use FormatsEnumerationError;
|
||||
use SampleFormat;
|
||||
use SamplesRate;
|
||||
use SupportedFormat;
|
||||
|
||||
use super::check_result;
|
||||
use super::com;
|
||||
use super::ole32;
|
||||
use super::winapi;
|
||||
|
||||
pub type SupportedFormatsIterator = OptionIntoIter<Format>;
|
||||
pub type SupportedFormatsIterator = OptionIntoIter<SupportedFormat>;
|
||||
|
||||
/// Wrapper because of that stupid decision to remove `Send` and `Sync` from raw pointers.
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -236,9 +236,10 @@ impl Endpoint {
|
|||
f => panic!("Unknown data format returned by GetMixFormat: {:?}", f),
|
||||
};
|
||||
|
||||
Format {
|
||||
SupportedFormat {
|
||||
channels: channels,
|
||||
samples_rate: SamplesRate((*format_ptr).nSamplesPerSec),
|
||||
min_samples_rate: SamplesRate((*format_ptr).nSamplesPerSec),
|
||||
max_samples_rate: SamplesRate((*format_ptr).nSamplesPerSec),
|
||||
data_type: data_type,
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue