Various ALSA fixes
This commit is contained in:
parent
0a13991f86
commit
5fa41538a6
|
@ -9,7 +9,11 @@ fn main() {
|
|||
for (endpoint_index, endpoint) in endpoints.enumerate() {
|
||||
println!("{}. Endpoint \"{}\" Audio formats: ", endpoint_index + 1, endpoint.get_name());
|
||||
|
||||
let formats = endpoint.get_supported_formats_list().unwrap();
|
||||
let formats = match endpoint.get_supported_formats_list() {
|
||||
Ok(f) => f,
|
||||
Err(e) => { println!("Error: {:?}", e); continue; }
|
||||
};
|
||||
|
||||
for (format_index, format) in formats.enumerate() {
|
||||
println!("{}.{}. {:?}", endpoint_index + 1, format_index + 1, format);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ use super::check_errors;
|
|||
use super::Endpoint;
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::CString;
|
||||
use std::mem;
|
||||
|
||||
use libc;
|
||||
|
@ -91,6 +92,18 @@ impl Iterator for EndpointsIterator {
|
|||
}
|
||||
|
||||
if let Some(name) = name {
|
||||
// trying to open the PCM device to see if it can be opened
|
||||
let name_zeroed = CString::new(name.clone()).unwrap();
|
||||
let mut playback_handle = mem::uninitialized();
|
||||
if alsa::snd_pcm_open(&mut playback_handle, name_zeroed.as_ptr() as *const _,
|
||||
alsa::SND_PCM_STREAM_PLAYBACK, alsa::SND_PCM_NONBLOCK) == 0
|
||||
{
|
||||
alsa::snd_pcm_close(playback_handle);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ignoring the `null` device
|
||||
if name != "null" {
|
||||
return Some(Endpoint(name));
|
||||
}
|
||||
|
@ -102,6 +115,5 @@ impl Iterator for EndpointsIterator {
|
|||
|
||||
#[inline]
|
||||
pub fn get_default_endpoint() -> Option<Endpoint> {
|
||||
// TODO: do in a different way?
|
||||
Some(Endpoint("default".to_owned()))
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use FormatsEnumerationError;
|
|||
use SampleFormat;
|
||||
use SamplesRate;
|
||||
|
||||
use std::{ffi, iter, mem, ptr};
|
||||
use std::{ffi, cmp, iter, mem, ptr};
|
||||
use std::vec::IntoIter as VecIntoIter;
|
||||
use std::sync::Mutex;
|
||||
|
||||
|
@ -28,12 +28,19 @@ impl Endpoint {
|
|||
unsafe {
|
||||
let mut playback_handle = mem::uninitialized();
|
||||
let device_name = ffi::CString::new(self.0.clone()).unwrap();
|
||||
check_errors(alsa::snd_pcm_open(&mut playback_handle, device_name.as_ptr() as *const _,
|
||||
alsa::SND_PCM_STREAM_PLAYBACK,
|
||||
alsa::SND_PCM_NONBLOCK)).unwrap();
|
||||
|
||||
match alsa::snd_pcm_open(&mut playback_handle, device_name.as_ptr() as *const _,
|
||||
alsa::SND_PCM_STREAM_PLAYBACK, alsa::SND_PCM_NONBLOCK)
|
||||
{
|
||||
-16 /* determined empirically */ => return Err(FormatsEnumerationError::DeviceNotAvailable),
|
||||
e => check_errors(e).unwrap()
|
||||
}
|
||||
|
||||
let hw_params = HwParams::alloc();
|
||||
check_errors(alsa::snd_pcm_hw_params_any(playback_handle, hw_params.0)).unwrap();
|
||||
match check_errors(alsa::snd_pcm_hw_params_any(playback_handle, hw_params.0)) {
|
||||
Err(_) => return Ok(Vec::new().into_iter()),
|
||||
Ok(_) => ()
|
||||
};
|
||||
|
||||
// TODO: check endianess
|
||||
const FORMATS: [(SampleFormat, alsa::snd_pcm_format_t); 3] = [
|
||||
|
@ -128,6 +135,7 @@ impl Endpoint {
|
|||
check_errors(alsa::snd_pcm_hw_params_get_channels_min(hw_params.0, &mut min_channels)).unwrap();
|
||||
let mut max_channels = mem::uninitialized();
|
||||
check_errors(alsa::snd_pcm_hw_params_get_channels_max(hw_params.0, &mut max_channels)).unwrap();
|
||||
let max_channels = cmp::min(max_channels, 32); // TODO: limiting to 32 channels or too much stuff is returned
|
||||
let supported_channels = (min_channels .. max_channels + 1).filter_map(|num| {
|
||||
if alsa::snd_pcm_hw_params_test_channels(playback_handle, hw_params.0, num) == 0 {
|
||||
Some(iter::repeat(ChannelPosition::FrontLeft).take(num as usize).collect::<Vec<_>>()) // FIXME:
|
||||
|
@ -158,7 +166,7 @@ impl Endpoint {
|
|||
|
||||
#[inline]
|
||||
pub fn get_name(&self) -> String {
|
||||
"unknown".to_owned() // TODO:
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,9 +207,12 @@ impl Voice {
|
|||
let name = ffi::CString::new(endpoint.0.clone()).unwrap();
|
||||
|
||||
let mut playback_handle = mem::uninitialized();
|
||||
check_errors(alsa::snd_pcm_open(&mut playback_handle, name.as_ptr(),
|
||||
alsa::SND_PCM_STREAM_PLAYBACK,
|
||||
alsa::SND_PCM_NONBLOCK)).unwrap();
|
||||
match alsa::snd_pcm_open(&mut playback_handle, name.as_ptr(),
|
||||
alsa::SND_PCM_STREAM_PLAYBACK, alsa::SND_PCM_NONBLOCK)
|
||||
{
|
||||
-16 /* determined empirically */ => return Err(CreationError::DeviceNotAvailable),
|
||||
e => check_errors(e).unwrap()
|
||||
}
|
||||
|
||||
// TODO: check endianess
|
||||
let data_type = match format.data_type {
|
||||
|
@ -218,7 +229,6 @@ impl Voice {
|
|||
check_errors(alsa::snd_pcm_hw_params_set_channels(playback_handle, hw_params.0, format.channels.len() as libc::c_uint)).unwrap();
|
||||
check_errors(alsa::snd_pcm_hw_params(playback_handle, hw_params.0)).unwrap();
|
||||
|
||||
|
||||
check_errors(alsa::snd_pcm_prepare(playback_handle)).unwrap();
|
||||
|
||||
Ok(Voice {
|
||||
|
|
Loading…
Reference in New Issue