commit
44d03c017d
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
|
||||
name = "cpal"
|
||||
version = "0.0.18"
|
||||
version = "0.0.19"
|
||||
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
||||
description = "Cross-platform audio playing library in pure Rust."
|
||||
repository = "https://github.com/tomaka/cpal"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
|
||||
name = "alsa-sys"
|
||||
version = "0.0.6"
|
||||
version = "0.0.7"
|
||||
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
||||
build = "build.rs"
|
||||
description = "Bindings for the ALSA project (Advanced Linux Sound Architecture)"
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(libc)]
|
||||
#![allow(missing_copy_implementations)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
|
|
@ -1,20 +1,28 @@
|
|||
#![feature(core)]
|
||||
|
||||
extern crate cpal;
|
||||
|
||||
// TODO: manual replacement for unstable `std::iter::iterate`
|
||||
struct Iter {
|
||||
value: f32,
|
||||
}
|
||||
|
||||
impl Iterator for Iter {
|
||||
type Item = f32;
|
||||
|
||||
fn next(&mut self) -> Option<f32> {
|
||||
self.value += 0.03;
|
||||
Some(self.value)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut channel = cpal::Voice::new();
|
||||
|
||||
// producing a sinusoid
|
||||
let mut data_source =
|
||||
std::iter::iterate(0.0f32, |f| f + 0.03)
|
||||
let mut data_source = Iter { value: 0.0 }
|
||||
.map(|angle| {
|
||||
use std::num::Float;
|
||||
use std::num::Int;
|
||||
|
||||
let angle = angle.sin();
|
||||
|
||||
let max: u16 = Int::max_value();
|
||||
let max: u16 = std::u16::MAX;
|
||||
let value = (max as f32 / 2.0) + (angle * (max as f32 / 2.0));
|
||||
value as u16
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ pub struct Buffer<'a, T> {
|
|||
impl Voice {
|
||||
pub fn new() -> Voice {
|
||||
unsafe {
|
||||
let name = ffi::CString::from_slice(b"default");
|
||||
let name = ffi::CString::new(b"default".to_vec()).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();
|
||||
|
@ -110,8 +110,9 @@ fn check_errors(err: libc::c_int) -> Result<(), String> {
|
|||
|
||||
if err < 0 {
|
||||
unsafe {
|
||||
let s = String::from_utf8(ffi::c_str_to_bytes(&alsa::snd_strerror(err)).to_vec());
|
||||
return Err(s.unwrap());
|
||||
let s = ffi::CStr::from_ptr(alsa::snd_strerror(err)).to_bytes().to_vec();
|
||||
let s = String::from_utf8(s).unwrap();
|
||||
return Err(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,19 +97,19 @@ mod test {
|
|||
#[test]
|
||||
fn remove_channels() {
|
||||
let result = convert_channels(&[1u16, 2, 3, 1, 2, 3], 3, 2);
|
||||
assert_eq!(result.as_slice(), [1, 2, 1, 2]);
|
||||
assert_eq!(result, [1, 2, 1, 2]);
|
||||
|
||||
let result = convert_channels(&[1u16, 2, 3, 4, 1, 2, 3, 4], 4, 1);
|
||||
assert_eq!(result.as_slice(), [1, 1]);
|
||||
assert_eq!(result, [1, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_channels() {
|
||||
let result = convert_channels(&[1u16, 2, 1, 2], 2, 3);
|
||||
assert_eq!(result.as_slice(), [1, 2, 1, 1, 2, 1]);
|
||||
assert_eq!(result, [1, 2, 1, 1, 2, 1]);
|
||||
|
||||
let result = convert_channels(&[1u16, 2, 1, 2], 2, 4);
|
||||
assert_eq!(result.as_slice(), [1, 2, 1, 2, 1, 2, 1, 2]);
|
||||
assert_eq!(result, [1, 2, 1, 2, 1, 2, 1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -123,7 +123,7 @@ mod test {
|
|||
let result = convert_samples_rate(&[1u16, 16, 2, 17, 3, 18, 4, 19],
|
||||
::SamplesRate(44100), ::SamplesRate(22050), 2);
|
||||
|
||||
assert_eq!(result.as_slice(), [1, 16, 3, 18]);
|
||||
assert_eq!(result, [1, 16, 3, 18]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -131,6 +131,6 @@ mod test {
|
|||
let result = convert_samples_rate(&[2u16, 16, 4, 18, 6, 20, 8, 22],
|
||||
::SamplesRate(22050), ::SamplesRate(44100), 2);
|
||||
|
||||
assert_eq!(result.as_slice(), [2, 16, 3, 17, 4, 18, 5, 19, 6, 20, 7, 21, 8, 22]);
|
||||
assert_eq!(result, [2, 16, 3, 17, 4, 18, 5, 19, 6, 20, 7, 21, 8, 22]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,6 @@ a conversion on your data.
|
|||
If you have the possibility, you should try to match the format of the voice.
|
||||
|
||||
*/
|
||||
#![feature(box_syntax, core, unsafe_destructor, thread_sleep, std_misc)]
|
||||
|
||||
pub use samples_formats::{SampleFormat, Sample};
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
@ -261,7 +259,6 @@ impl<'a, T> DerefMut for Buffer<'a, T> where T: Sample {
|
|||
}
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<'a, T> Drop for Buffer<'a, T> where T: Sample {
|
||||
fn drop(&mut self) {
|
||||
if let Some(conversion) = self.conversion.take() {
|
||||
|
|
|
@ -51,8 +51,7 @@ impl Voice {
|
|||
//
|
||||
let frames_available = {
|
||||
let mut padding = mem::uninitialized();
|
||||
let f = self.audio_client.as_mut().unwrap().lpVtbl
|
||||
.as_ref().unwrap().GetCurrentPadding;
|
||||
let f = (&*(&mut *self.audio_client).lpVtbl).GetCurrentPadding;
|
||||
let hresult = f(self.audio_client, &mut padding);
|
||||
check_result(hresult).unwrap();
|
||||
self.max_frames_in_buffer - padding
|
||||
|
@ -60,7 +59,7 @@ impl Voice {
|
|||
|
||||
if frames_available == 0 {
|
||||
// TODO:
|
||||
::std::thread::sleep(::std::time::duration::Duration::milliseconds(1));
|
||||
::std::thread::sleep_ms(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -72,7 +71,7 @@ impl Voice {
|
|||
// loading buffer
|
||||
let (buffer_data, buffer_len) = {
|
||||
let mut buffer: *mut winapi::BYTE = mem::uninitialized();
|
||||
let f = self.render_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().GetBuffer;
|
||||
let f = (&*(&mut *self.render_client).lpVtbl).GetBuffer;
|
||||
let hresult = f(self.render_client, frames_available,
|
||||
&mut buffer as *mut *mut libc::c_uchar);
|
||||
check_result(hresult).unwrap();
|
||||
|
@ -99,7 +98,7 @@ impl Voice {
|
|||
pub fn play(&mut self) {
|
||||
if !self.playing {
|
||||
unsafe {
|
||||
let f = self.audio_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().Start;
|
||||
let f = (&*(&mut *self.audio_client).lpVtbl).Start;
|
||||
let hresult = f(self.audio_client);
|
||||
check_result(hresult).unwrap();
|
||||
}
|
||||
|
@ -111,7 +110,7 @@ impl Voice {
|
|||
pub fn pause(&mut self) {
|
||||
if self.playing {
|
||||
unsafe {
|
||||
let f = self.audio_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().Stop;
|
||||
let f = (&*(&mut *self.audio_client).lpVtbl).Stop;
|
||||
let hresult = f(self.audio_client);
|
||||
check_result(hresult).unwrap();
|
||||
}
|
||||
|
@ -128,12 +127,12 @@ impl Drop for Voice {
|
|||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
{
|
||||
let f = self.render_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().Release;
|
||||
let f = (&*(&mut *self.render_client).lpVtbl).Release;
|
||||
f(self.render_client);
|
||||
}
|
||||
|
||||
{
|
||||
let f = self.audio_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().Release;
|
||||
let f = (&*(&mut *self.audio_client).lpVtbl).Release;
|
||||
f(self.audio_client);
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +149,7 @@ impl<'a, T> Buffer<'a, T> {
|
|||
pub fn finish(self) {
|
||||
// releasing buffer
|
||||
unsafe {
|
||||
let f = self.render_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().ReleaseBuffer;
|
||||
let f = (&*(&mut *self.render_client).lpVtbl).ReleaseBuffer;
|
||||
let hresult = f(self.render_client, self.frames as u32, 0);
|
||||
check_result(hresult).unwrap();
|
||||
};
|
||||
|
@ -172,27 +171,27 @@ fn init() -> Result<Voice, String> {
|
|||
mem::transmute(&mut enumerator));
|
||||
|
||||
try!(check_result(hresult));
|
||||
enumerator.as_mut().unwrap()
|
||||
&mut *enumerator
|
||||
};
|
||||
|
||||
// getting the default end-point
|
||||
let device = {
|
||||
let mut device: *mut winapi::IMMDevice = mem::uninitialized();
|
||||
let f = enumerator.lpVtbl.as_ref().unwrap().GetDefaultAudioEndpoint;
|
||||
let f = (&*(&mut *enumerator).lpVtbl).GetDefaultAudioEndpoint;
|
||||
let hresult = f(enumerator, winapi::EDataFlow::eRender, winapi::ERole::eConsole,
|
||||
mem::transmute(&mut device));
|
||||
try!(check_result(hresult));
|
||||
device.as_mut().unwrap()
|
||||
&mut *device
|
||||
};
|
||||
|
||||
// activating in order to get a `IAudioClient`
|
||||
let audio_client = {
|
||||
let audio_client: &mut winapi::IAudioClient = {
|
||||
let mut audio_client: *mut winapi::IAudioClient = mem::uninitialized();
|
||||
let f = device.lpVtbl.as_ref().unwrap().Activate;
|
||||
let f = (&*(&mut *device).lpVtbl).Activate;
|
||||
let hresult = f(device, &winapi::IID_IAudioClient, winapi::CLSCTX_ALL,
|
||||
ptr::null_mut(), mem::transmute(&mut audio_client));
|
||||
try!(check_result(hresult));
|
||||
audio_client.as_mut().unwrap()
|
||||
&mut *audio_client
|
||||
};
|
||||
|
||||
// computing the format and initializing the device
|
||||
|
@ -208,19 +207,20 @@ fn init() -> Result<Voice, String> {
|
|||
};
|
||||
|
||||
let mut format_ptr: *mut winapi::WAVEFORMATEX = mem::uninitialized();
|
||||
let f = audio_client.lpVtbl.as_ref().unwrap().IsFormatSupported;
|
||||
let f = (&*(&mut *audio_client).lpVtbl).IsFormatSupported;
|
||||
let hresult = f(audio_client, winapi::AUDCLNT_SHAREMODE::AUDCLNT_SHAREMODE_SHARED,
|
||||
&format_attempt, &mut format_ptr);
|
||||
try!(check_result(hresult));
|
||||
|
||||
let format = match format_ptr.as_ref() {
|
||||
Some(f) => f,
|
||||
None => &format_attempt,
|
||||
let format = if format_ptr.is_null() {
|
||||
&format_attempt
|
||||
} else {
|
||||
&*format_ptr
|
||||
};
|
||||
|
||||
let format_copy = ptr::read(format);
|
||||
|
||||
let f = audio_client.lpVtbl.as_ref().unwrap().Initialize;
|
||||
let f = (&*(&mut *audio_client).lpVtbl).Initialize;
|
||||
let hresult = f(audio_client, winapi::AUDCLNT_SHAREMODE::AUDCLNT_SHAREMODE_SHARED,
|
||||
0, 10000000, 0, format, ptr::null());
|
||||
|
||||
|
@ -236,7 +236,7 @@ fn init() -> Result<Voice, String> {
|
|||
//
|
||||
let max_frames_in_buffer = {
|
||||
let mut max_frames_in_buffer = mem::uninitialized();
|
||||
let f = audio_client.lpVtbl.as_ref().unwrap().GetBufferSize;
|
||||
let f = (&*(&mut *audio_client).lpVtbl).GetBufferSize;
|
||||
let hresult = f(audio_client, &mut max_frames_in_buffer);
|
||||
try!(check_result(hresult));
|
||||
max_frames_in_buffer
|
||||
|
@ -245,11 +245,11 @@ fn init() -> Result<Voice, String> {
|
|||
//
|
||||
let render_client = {
|
||||
let mut render_client: *mut winapi::IAudioRenderClient = mem::uninitialized();
|
||||
let f = audio_client.lpVtbl.as_ref().unwrap().GetService;
|
||||
let f = (&*(&mut *audio_client).lpVtbl).GetService;
|
||||
let hresult = f(audio_client, &winapi::IID_IAudioRenderClient,
|
||||
mem::transmute(&mut render_client));
|
||||
try!(check_result(hresult));
|
||||
render_client.as_mut().unwrap()
|
||||
&mut *render_client
|
||||
};
|
||||
|
||||
Ok(Voice {
|
||||
|
|
Loading…
Reference in New Issue