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.
|
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`.
|
- 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 `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()
|
.supported_formats()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.next()
|
.next()
|
||||||
.expect("Failed to get endpoint format");
|
.expect("Failed to get endpoint format")
|
||||||
|
.with_max_samples_rate();
|
||||||
|
|
||||||
let event_loop = cpal::EventLoop::new();
|
let event_loop = cpal::EventLoop::new();
|
||||||
let voice_id = event_loop.build_voice(&endpoint, &format).unwrap();
|
let voice_id = event_loop.build_voice(&endpoint, &format).unwrap();
|
||||||
|
|
|
@ -9,6 +9,7 @@ use Format;
|
||||||
use FormatsEnumerationError;
|
use FormatsEnumerationError;
|
||||||
use SampleFormat;
|
use SampleFormat;
|
||||||
use SamplesRate;
|
use SamplesRate;
|
||||||
|
use SupportedFormat;
|
||||||
use UnknownTypeBuffer;
|
use UnknownTypeBuffer;
|
||||||
|
|
||||||
use std::{cmp, ffi, iter, mem, ptr};
|
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::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
use std::vec::IntoIter as VecIntoIter;
|
use std::vec::IntoIter as VecIntoIter;
|
||||||
|
|
||||||
pub type SupportedFormatsIterator = VecIntoIter<Format>;
|
pub type SupportedFormatsIterator = VecIntoIter<SupportedFormat>;
|
||||||
|
|
||||||
mod enumerate;
|
mod enumerate;
|
||||||
|
|
||||||
|
@ -152,10 +153,9 @@ impl Endpoint {
|
||||||
.expect("unable to get maximum supported rate");
|
.expect("unable to get maximum supported rate");
|
||||||
|
|
||||||
let samples_rates = if min_rate == max_rate {
|
let samples_rates = if min_rate == max_rate {
|
||||||
vec![min_rate]
|
vec![(min_rate, max_rate)]
|
||||||
/*} else if alsa::snd_pcm_hw_params_test_rate(playback_handle, hw_params.0, min_rate + 1, 0) == 0 {
|
} 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()*/
|
vec![(min_rate, max_rate)]
|
||||||
// TODO: code is correct but returns lots of stuff
|
|
||||||
} else {
|
} else {
|
||||||
const RATES: [libc::c_uint; 13] = [
|
const RATES: [libc::c_uint; 13] = [
|
||||||
5512,
|
5512,
|
||||||
|
@ -180,15 +180,15 @@ impl Endpoint {
|
||||||
rate,
|
rate,
|
||||||
0) == 0
|
0) == 0
|
||||||
{
|
{
|
||||||
rates.push(rate);
|
rates.push((rate, rate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if rates.len() == 0 {
|
if rates.len() == 0 {
|
||||||
(min_rate .. max_rate + 1).collect()
|
vec![(min_rate, max_rate)]
|
||||||
} else {*/
|
} else {
|
||||||
rates // TODO: code is correct but returns lots of stuff
|
rates
|
||||||
//}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut min_channels = mem::uninitialized();
|
let mut min_channels = mem::uninitialized();
|
||||||
|
@ -227,10 +227,11 @@ impl Endpoint {
|
||||||
samples_rates.len());
|
samples_rates.len());
|
||||||
for &data_type in supported_formats.iter() {
|
for &data_type in supported_formats.iter() {
|
||||||
for channels in supported_channels.iter() {
|
for channels in supported_channels.iter() {
|
||||||
for &rate in samples_rates.iter() {
|
for &(min_rate, max_rate) in samples_rates.iter() {
|
||||||
output.push(Format {
|
output.push(SupportedFormat {
|
||||||
channels: channels.clone(),
|
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,
|
data_type: data_type,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use super::Endpoint;
|
use super::Endpoint;
|
||||||
|
|
||||||
use Format;
|
use Format;
|
||||||
|
use SupportedFormat;
|
||||||
|
|
||||||
use std::vec::IntoIter as VecIntoIter;
|
use std::vec::IntoIter as VecIntoIter;
|
||||||
|
|
||||||
|
@ -33,4 +34,4 @@ pub fn default_endpoint() -> Option<Endpoint> {
|
||||||
Some(Endpoint)
|
Some(Endpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SupportedFormatsIterator = VecIntoIter<Format>;
|
pub type SupportedFormatsIterator = VecIntoIter<SupportedFormat>;
|
||||||
|
|
|
@ -7,6 +7,7 @@ use FormatsEnumerationError;
|
||||||
use Sample;
|
use Sample;
|
||||||
use SampleFormat;
|
use SampleFormat;
|
||||||
use SamplesRate;
|
use SamplesRate;
|
||||||
|
use SupportedFormat;
|
||||||
use UnknownTypeBuffer;
|
use UnknownTypeBuffer;
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -30,9 +31,10 @@ impl Endpoint {
|
||||||
-> Result<SupportedFormatsIterator, FormatsEnumerationError> {
|
-> Result<SupportedFormatsIterator, FormatsEnumerationError> {
|
||||||
Ok(
|
Ok(
|
||||||
vec![
|
vec![
|
||||||
Format {
|
SupportedFormat {
|
||||||
channels: vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight],
|
channels: vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight],
|
||||||
samples_rate: SamplesRate(44100),
|
min_samples_rate: SamplesRate(44100),
|
||||||
|
max_samples_rate: SamplesRate(44100),
|
||||||
data_type: SampleFormat::F32,
|
data_type: SampleFormat::F32,
|
||||||
},
|
},
|
||||||
].into_iter(),
|
].into_iter(),
|
||||||
|
|
|
@ -7,6 +7,7 @@ use CreationError;
|
||||||
use Format;
|
use Format;
|
||||||
use FormatsEnumerationError;
|
use FormatsEnumerationError;
|
||||||
use Sample;
|
use Sample;
|
||||||
|
use SupportedFormat;
|
||||||
use UnknownTypeBuffer;
|
use UnknownTypeBuffer;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
|
@ -182,9 +183,10 @@ impl Endpoint {
|
||||||
// TODO: right now cpal's API doesn't allow flexibility here
|
// 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
|
// "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
|
// this ever becomes more flexible, don't forget to change that
|
||||||
Ok(vec![Format {
|
Ok(vec![SupportedFormat {
|
||||||
channels: vec![::ChannelPosition::BackLeft, ::ChannelPosition::BackRight],
|
channels: vec![::ChannelPosition::BackLeft, ::ChannelPosition::BackRight],
|
||||||
samples_rate: ::SamplesRate(44100),
|
min_samples_rate: ::SamplesRate(44100),
|
||||||
|
max_samples_rate: ::SamplesRate(44100),
|
||||||
data_type: ::SampleFormat::F32,
|
data_type: ::SampleFormat::F32,
|
||||||
}].into_iter())
|
}].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 {
|
pub struct Buffer<'a, T: 'a> where T: Sample {
|
||||||
temporary_buffer: Vec<T>,
|
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
|
// a `Result` to handle this situation
|
||||||
|
|
||||||
// getting a format for the PCM
|
// 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();
|
let event_loop = cpal::EventLoop::new();
|
||||||
|
|
||||||
|
@ -188,10 +189,10 @@ pub struct Format {
|
||||||
pub struct SupportedFormatsIterator(cpal_impl::SupportedFormatsIterator);
|
pub struct SupportedFormatsIterator(cpal_impl::SupportedFormatsIterator);
|
||||||
|
|
||||||
impl Iterator for SupportedFormatsIterator {
|
impl Iterator for SupportedFormatsIterator {
|
||||||
type Item = Format;
|
type Item = SupportedFormat;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Format> {
|
fn next(&mut self) -> Option<SupportedFormat> {
|
||||||
self.0.next()
|
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);
|
pub struct EventLoop(cpal_impl::EventLoop);
|
||||||
|
|
||||||
impl EventLoop {
|
impl EventLoop {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::marker::PhantomData;
|
||||||
use CreationError;
|
use CreationError;
|
||||||
use Format;
|
use Format;
|
||||||
use FormatsEnumerationError;
|
use FormatsEnumerationError;
|
||||||
|
use SupportedFormat;
|
||||||
use UnknownTypeBuffer;
|
use UnknownTypeBuffer;
|
||||||
|
|
||||||
pub struct EventLoop;
|
pub struct EventLoop;
|
||||||
|
@ -84,10 +85,10 @@ impl Endpoint {
|
||||||
pub struct SupportedFormatsIterator;
|
pub struct SupportedFormatsIterator;
|
||||||
|
|
||||||
impl Iterator for SupportedFormatsIterator {
|
impl Iterator for SupportedFormatsIterator {
|
||||||
type Item = Format;
|
type Item = SupportedFormat;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Format> {
|
fn next(&mut self) -> Option<SupportedFormat> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,17 @@ use std::slice;
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
|
|
||||||
use ChannelPosition;
|
use ChannelPosition;
|
||||||
use Format;
|
|
||||||
use FormatsEnumerationError;
|
use FormatsEnumerationError;
|
||||||
use SampleFormat;
|
use SampleFormat;
|
||||||
use SamplesRate;
|
use SamplesRate;
|
||||||
|
use SupportedFormat;
|
||||||
|
|
||||||
use super::check_result;
|
use super::check_result;
|
||||||
use super::com;
|
use super::com;
|
||||||
use super::ole32;
|
use super::ole32;
|
||||||
use super::winapi;
|
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.
|
/// Wrapper because of that stupid decision to remove `Send` and `Sync` from raw pointers.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -236,9 +236,10 @@ impl Endpoint {
|
||||||
f => panic!("Unknown data format returned by GetMixFormat: {:?}", f),
|
f => panic!("Unknown data format returned by GetMixFormat: {:?}", f),
|
||||||
};
|
};
|
||||||
|
|
||||||
Format {
|
SupportedFormat {
|
||||||
channels: channels,
|
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,
|
data_type: data_type,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue