This commit is contained in:
Chun-Min Chang 2019-03-15 16:18:00 -07:00
Родитель 2d0b6dfd29
Коммит ee9d493861
5 изменённых файлов: 162 добавлений и 250 удалений

Просмотреть файл

@ -78,11 +78,15 @@ pub trait Zero {
}
impl Zero for f32 {
fn zero() -> Self { 0.0 }
fn zero() -> Self {
0.0
}
}
impl Zero for i16 {
fn zero() -> Self { 0 }
fn zero() -> Self {
0
}
}
#[cfg(test)]
@ -139,7 +143,10 @@ fn test_auto_array_wrapper<T: Clone + Debug + PartialEq + Zero>(buf: &[T]) {
assert!(data.is_null());
// Check if push works.
auto_array.as_mut().unwrap().push(buf.as_ptr() as *const c_void, buf.len());
auto_array
.as_mut()
.unwrap()
.push(buf.as_ptr() as *const c_void, buf.len());
assert_eq!(auto_array.as_ref().unwrap().elements(), buf.len());
let data = auto_array.as_ref().unwrap().as_ptr() as *const T;

Просмотреть файл

@ -2,15 +2,12 @@ use std::fmt;
pub struct AutoRelease<T> {
ptr: *mut T,
release_func: unsafe extern fn(*mut T)
release_func: unsafe extern "C" fn(*mut T),
}
impl<T> AutoRelease<T> {
pub fn new(ptr: *mut T, release_func: unsafe extern fn(*mut T)) -> Self {
Self {
ptr,
release_func
}
pub fn new(ptr: *mut T, release_func: unsafe extern "C" fn(*mut T)) -> Self {
Self { ptr, release_func }
}
pub fn reset(&mut self, ptr: *mut T) {
@ -34,7 +31,9 @@ impl<T> AutoRelease<T> {
fn release(&self) {
if !self.ptr.is_null() {
unsafe { (self.release_func)(self.ptr); }
unsafe {
(self.release_func)(self.ptr);
}
}
}
}
@ -61,12 +60,12 @@ fn test_auto_release() {
use std::mem;
use std::ptr;
unsafe extern fn allocate() -> *mut libc::c_void {
unsafe extern "C" fn allocate() -> *mut libc::c_void {
// println!("Allocate!");
libc::calloc(1, mem::size_of::<u32>())
}
unsafe extern fn deallocate(ptr: *mut libc::c_void) {
unsafe extern "C" fn deallocate(ptr: *mut libc::c_void) {
// println!("Deallocate!");
libc::free(ptr);
}

Просмотреть файл

@ -15,9 +15,8 @@ pub const DISPATCH_QUEUE_SERIAL: sys::dispatch_queue_attr_t = 0 as sys::dispatch
pub fn create_dispatch_queue(
label: &'static str,
queue_attr: sys::dispatch_queue_attr_t
) -> sys::dispatch_queue_t
{
queue_attr: sys::dispatch_queue_attr_t,
) -> sys::dispatch_queue_t {
let label = CString::new(label);
let c_string = if label.is_ok() {
label.unwrap().as_ptr()
@ -27,20 +26,21 @@ pub fn create_dispatch_queue(
unsafe { sys::dispatch_queue_create(c_string, queue_attr) }
}
pub fn release_dispatch_queue(queue: sys::dispatch_queue_t)
{
pub fn release_dispatch_queue(queue: sys::dispatch_queue_t) {
// TODO: This is incredibly unsafe. Find another way to release the queue.
unsafe {
sys::dispatch_release(
mem::transmute::<sys::dispatch_queue_t, sys::dispatch_object_t>(queue)
);
sys::dispatch_release(mem::transmute::<
sys::dispatch_queue_t,
sys::dispatch_object_t,
>(queue));
}
}
// Send: Types that can be transferred across thread boundaries.
// FnOnce: One-time function.
pub fn async_dispatch<F>(queue: sys::dispatch_queue_t, work: F)
where F: 'static + Send + FnOnce()
where
F: 'static + Send + FnOnce(),
{
let (closure, executor) = create_closure_and_executor(work);
unsafe {
@ -51,7 +51,8 @@ pub fn async_dispatch<F>(queue: sys::dispatch_queue_t, work: F)
// Send: Types that can be transferred across thread boundaries.
// FnOnce: One-time function.
pub fn sync_dispatch<F>(queue: sys::dispatch_queue_t, work: F)
where F: 'static + Send + FnOnce()
where
F: 'static + Send + FnOnce(),
{
let (closure, executor) = create_closure_and_executor(work);
unsafe {
@ -61,18 +62,16 @@ pub fn sync_dispatch<F>(queue: sys::dispatch_queue_t, work: F)
// Return an raw pointer to a (unboxed) closure and an executor that
// will run the closure (after re-boxing the closure) when it's called.
fn create_closure_and_executor<F>(
closure: F
) -> (*mut c_void, sys::dispatch_function_t)
where F: FnOnce()
fn create_closure_and_executor<F>(closure: F) -> (*mut c_void, sys::dispatch_function_t)
where
F: FnOnce(),
{
extern fn closure_executer<F>(unboxed_closure: *mut c_void)
where F: FnOnce()
extern "C" fn closure_executer<F>(unboxed_closure: *mut c_void)
where
F: FnOnce(),
{
// Retake the leaked closure.
let closure: Box<F> = unsafe {
Box::from_raw(unboxed_closure as *mut F)
};
let closure: Box<F> = unsafe { Box::from_raw(unboxed_closure as *mut F) };
// Execute the closure.
(*closure)();
// closure is released after finishiing this function call.
@ -83,7 +82,7 @@ fn create_closure_and_executor<F>(
(
Box::into_raw(closure) as *mut c_void, // Leak the closure.
executor
executor,
)
}
@ -96,19 +95,14 @@ fn test_dispatch_async_f() {
ptr::null()
};
let queue = unsafe {
sys::dispatch_queue_create(
c_string,
DISPATCH_QUEUE_SERIAL
)
};
let queue = unsafe { sys::dispatch_queue_create(c_string, DISPATCH_QUEUE_SERIAL) };
// Allocate the `context` on heap, otherwise the `context` will be
// freed before `work` is fired and after program goes out of the
// scope of the unsafe block.
let context: Box<i32> = Box::new(123);
extern fn work(leaked_ptr: *mut c_void) {
extern "C" fn work(leaked_ptr: *mut c_void) {
let leaked_context = leaked_ptr as *mut i32;
// Retake the leaked `context`.
@ -121,7 +115,7 @@ fn test_dispatch_async_f() {
sys::dispatch_async_f(
queue,
Box::into_raw(context) as *mut c_void, // Leak the `context`.
Some(work)
Some(work),
);
}
}
@ -135,30 +129,19 @@ fn test_dispatch_sync_f() {
ptr::null()
};
let queue = unsafe {
sys::dispatch_queue_create(
c_string,
DISPATCH_QUEUE_SERIAL
)
};
let queue = unsafe { sys::dispatch_queue_create(c_string, DISPATCH_QUEUE_SERIAL) };
let mut context: i32 = 20;
extern fn work(context_ptr: *mut c_void) {
let ctx_mut_ref = unsafe {
&mut (*(context_ptr as *mut i32))
};
extern "C" fn work(context_ptr: *mut c_void) {
let ctx_mut_ref = unsafe { &mut (*(context_ptr as *mut i32)) };
assert_eq!(ctx_mut_ref, &20);
*ctx_mut_ref = 30;
}
unsafe {
sys::dispatch_sync_f(
queue,
&mut context as *mut i32 as *mut c_void,
Some(work)
);
sys::dispatch_sync_f(queue, &mut context as *mut i32 as *mut c_void, Some(work));
}
assert_eq!(context, 30);
@ -168,10 +151,7 @@ fn test_dispatch_sync_f() {
fn test_async_dispatch() {
let label = "Run with async dispatch api wrappers";
let queue = create_dispatch_queue(
label,
DISPATCH_QUEUE_SERIAL
);
let queue = create_dispatch_queue(label, DISPATCH_QUEUE_SERIAL);
struct Resource {
last_touched: Option<u32>,
@ -232,7 +212,7 @@ fn test_async_dispatch() {
});
// Make sure the resource won't be freed before the tasks are finished.
while resource.touched_count < 2 {};
while resource.touched_count < 2 {}
assert!(resource.last_touched.is_some());
assert_eq!(resource.last_touched.unwrap(), 2);
}
@ -241,10 +221,7 @@ fn test_async_dispatch() {
fn test_sync_dispatch() {
let label = "Run with sync dispatch api wrappers";
let queue = create_dispatch_queue(
label,
DISPATCH_QUEUE_SERIAL
);
let queue = create_dispatch_queue(label, DISPATCH_QUEUE_SERIAL);
struct Resource {
last_touched: Option<u32>,

Просмотреть файл

@ -9,7 +9,7 @@ use self::libc::*;
use std::{fmt, mem};
pub struct OwnedCriticalSection {
mutex: pthread_mutex_t
mutex: pthread_mutex_t,
}
// Notice that `OwnedCriticalSection` only works after `init` is called.
@ -26,7 +26,7 @@ pub struct OwnedCriticalSection {
impl OwnedCriticalSection {
pub fn new() -> Self {
OwnedCriticalSection {
mutex: PTHREAD_MUTEX_INITIALIZER
mutex: PTHREAD_MUTEX_INITIALIZER,
}
}
@ -91,9 +91,7 @@ pub struct AutoLock<'a> {
impl<'a> AutoLock<'a> {
pub fn new(mutex: &'a mut OwnedCriticalSection) -> Self {
mutex.lock();
AutoLock {
mutex,
}
AutoLock { mutex }
}
}

Просмотреть файл

@ -36,13 +36,7 @@ pub fn leak_vec<T>(v: Vec<T>) -> (*mut T, usize) {
pub fn retake_leaked_vec<T>(ptr: *mut T, len: usize) -> Vec<T> {
// TODO: It's better to set ptr to null and len to 0.
// so the address won't be used again.
unsafe {
Vec::from_raw_parts(
ptr,
len,
len
)
}
unsafe { Vec::from_raw_parts(ptr, len, len) }
}
// CFSTR doesn't be implemented in core-foundation-sys, so we create a function
@ -63,7 +57,7 @@ pub fn cfstringref_from_static_string(string: &'static str) -> sys::CFStringRef
string.len() as sys::CFIndex,
sys::kCFStringEncodingUTF8,
false as sys::Boolean,
sys::kCFAllocatorNull
sys::kCFAllocatorNull,
)
}
}
@ -80,7 +74,7 @@ pub fn cfstringref_from_string(string: &str) -> sys::CFStringRef {
string.as_ptr(),
string.len() as sys::CFIndex,
sys::kCFStringEncodingUTF8,
false as sys::Boolean
false as sys::Boolean,
)
}
}
@ -89,12 +83,7 @@ pub fn audio_object_has_property(
id: sys::AudioObjectID,
address: &sys::AudioObjectPropertyAddress,
) -> bool {
unsafe {
sys::AudioObjectHasProperty(
id,
address,
) != 0
}
unsafe { sys::AudioObjectHasProperty(id, address) != 0 }
}
pub fn audio_object_get_property_data<T>(
@ -121,13 +110,7 @@ pub fn audio_object_get_property_data_size(
size: *mut usize,
) -> sys::OSStatus {
unsafe {
sys::AudioObjectGetPropertyDataSize(
id,
address,
0,
ptr::null(),
size as *mut sys::UInt32,
)
sys::AudioObjectGetPropertyDataSize(id, address, 0, ptr::null(), size as *mut sys::UInt32)
}
}
@ -152,7 +135,7 @@ pub fn audio_object_set_property_data<T>(
// Referece:
// https://gist.github.com/ChunMinChang/f0f4a71f78d1e1c6390493ab1c9d10d3
#[allow(non_camel_case_types)]
pub type audio_object_property_listener_proc = extern fn(
pub type audio_object_property_listener_proc = extern "C" fn(
sys::AudioObjectID,
u32,
*const sys::AudioObjectPropertyAddress,
@ -165,14 +148,7 @@ pub fn audio_object_add_property_listener(
listener: audio_object_property_listener_proc,
data: *mut c_void,
) -> sys::OSStatus {
unsafe {
sys::AudioObjectAddPropertyListener(
id,
address,
Some(listener),
data
)
}
unsafe { sys::AudioObjectAddPropertyListener(id, address, Some(listener), data) }
}
pub fn audio_object_remove_property_listener(
@ -181,14 +157,7 @@ pub fn audio_object_remove_property_listener(
listener: audio_object_property_listener_proc,
data: *mut c_void,
) -> sys::OSStatus {
unsafe {
sys::AudioObjectRemovePropertyListener(
id,
address,
Some(listener),
data
)
}
unsafe { sys::AudioObjectRemovePropertyListener(id, address, Some(listener), data) }
}
pub fn audio_unit_get_property_info(
@ -197,7 +166,7 @@ pub fn audio_unit_get_property_info(
scope: sys::AudioUnitScope,
element: sys::AudioUnitElement,
size: *mut usize,
writable: *mut sys::Boolean
writable: *mut sys::Boolean,
) -> sys::OSStatus {
assert!(!unit.is_null());
unsafe {
@ -207,7 +176,7 @@ pub fn audio_unit_get_property_info(
scope,
element,
size as *mut sys::UInt32,
writable
writable,
)
}
}
@ -228,7 +197,7 @@ pub fn audio_unit_get_property<T>(
scope,
element,
data as *mut c_void,
size as *mut sys::UInt32
size as *mut sys::UInt32,
)
}
}
@ -256,7 +225,7 @@ pub fn audio_unit_set_property<T>(
pub fn audio_unit_get_parameter(
unit: sys::AudioUnit,
id: sys:: AudioUnitParameterID,
id: sys::AudioUnitParameterID,
scope: sys::AudioUnitScope,
element: sys::AudioUnitElement,
value: &mut sys::AudioUnitParameterValue,
@ -268,19 +237,19 @@ pub fn audio_unit_get_parameter(
id,
scope,
element,
value as *mut sys::AudioUnitParameterValue
value as *mut sys::AudioUnitParameterValue,
)
}
}
// https://developer.apple.com/documentation/audiotoolbox/1440111-audiounitaddpropertylistener?language=objc
#[allow(non_camel_case_types)]
pub type audio_unit_property_listener_proc = extern fn(
pub type audio_unit_property_listener_proc = extern "C" fn(
*mut c_void,
sys::AudioUnit,
sys::AudioUnitPropertyID,
sys::AudioUnitScope,
sys::AudioUnitElement
sys::AudioUnitElement,
);
pub fn audio_unit_add_property_listener(
@ -290,14 +259,7 @@ pub fn audio_unit_add_property_listener(
data: *mut c_void,
) -> sys::OSStatus {
assert!(!unit.is_null());
unsafe {
sys::AudioUnitAddPropertyListener(
unit,
id,
Some(listener),
data
)
}
unsafe { sys::AudioUnitAddPropertyListener(unit, id, Some(listener), data) }
}
pub fn audio_unit_remove_property_listener_with_user_data(
@ -307,35 +269,19 @@ pub fn audio_unit_remove_property_listener_with_user_data(
data: *mut c_void,
) -> sys::OSStatus {
assert!(!unit.is_null());
unsafe {
sys::AudioUnitRemovePropertyListenerWithUserData(
unit,
id,
Some(listener),
data
)
}
unsafe { sys::AudioUnitRemovePropertyListenerWithUserData(unit, id, Some(listener), data) }
}
pub fn audio_unit_set_parameter(
unit: sys::AudioUnit,
id: sys:: AudioUnitParameterID,
id: sys::AudioUnitParameterID,
scope: sys::AudioUnitScope,
element: sys::AudioUnitElement,
value: sys::AudioUnitParameterValue,
buffer_offset_in_frames: sys::UInt32,
) -> sys::OSStatus {
assert!(!unit.is_null());
unsafe {
sys::AudioUnitSetParameter(
unit,
id,
scope,
element,
value,
buffer_offset_in_frames
)
}
unsafe { sys::AudioUnitSetParameter(unit, id, scope, element, value, buffer_offset_in_frames) }
}
pub fn audio_unit_render(
@ -344,7 +290,7 @@ pub fn audio_unit_render(
in_time_stamp: *const sys::AudioTimeStamp,
in_output_bus_number: u32,
in_number_frames: u32,
io_data: *mut sys::AudioBufferList
io_data: *mut sys::AudioBufferList,
) -> sys::OSStatus {
assert!(!in_unit.is_null());
unsafe {
@ -354,57 +300,37 @@ pub fn audio_unit_render(
in_time_stamp,
in_output_bus_number,
in_number_frames,
io_data
io_data,
)
}
}
pub fn audio_unit_initialize(
unit: sys::AudioUnit,
) -> sys::OSStatus {
pub fn audio_unit_initialize(unit: sys::AudioUnit) -> sys::OSStatus {
assert!(!unit.is_null());
unsafe {
sys::AudioUnitInitialize(unit)
}
unsafe { sys::AudioUnitInitialize(unit) }
}
// TODO: Maybe we can merge the following two functions into something like
// `destroy_audio_unit(unit: sys::AudioUnit)` and call
// `AudioUnitUninitialize`, `AudioComponentInstanceDispose` in this
// function.
pub fn audio_unit_uninitialize(
unit: sys::AudioUnit,
) -> sys::OSStatus {
pub fn audio_unit_uninitialize(unit: sys::AudioUnit) -> sys::OSStatus {
assert!(!unit.is_null());
unsafe {
sys::AudioUnitUninitialize(unit)
}
unsafe { sys::AudioUnitUninitialize(unit) }
}
pub fn dispose_audio_unit(
unit: sys::AudioUnit,
) -> sys::OSStatus {
unsafe {
sys::AudioComponentInstanceDispose(unit)
}
pub fn dispose_audio_unit(unit: sys::AudioUnit) -> sys::OSStatus {
unsafe { sys::AudioComponentInstanceDispose(unit) }
}
pub fn audio_output_unit_start(
unit: sys::AudioUnit,
) -> sys::OSStatus {
pub fn audio_output_unit_start(unit: sys::AudioUnit) -> sys::OSStatus {
assert!(!unit.is_null());
unsafe {
sys::AudioOutputUnitStart(unit)
}
unsafe { sys::AudioOutputUnitStart(unit) }
}
pub fn audio_output_unit_stop(
unit: sys::AudioUnit,
) -> sys::OSStatus {
pub fn audio_output_unit_stop(unit: sys::AudioUnit) -> sys::OSStatus {
assert!(!unit.is_null());
unsafe {
sys::AudioOutputUnitStop(unit)
}
unsafe { sys::AudioOutputUnitStop(unit) }
}
#[test]
@ -447,10 +373,7 @@ fn test_create_cfstring_ref() {
CFRelease(cfstrref as *const c_void);
}
assert_eq!(
test_string,
cstring.to_string_lossy()
);
assert_eq!(test_string, cstring.to_string_lossy());
// TODO: Find a way to check the string's inner pointer is different.
}
@ -459,11 +382,11 @@ fn test_create_cfstring_ref() {
fn test_audio_object_add_property_listener_for_unknown_device() {
use super::DEVICES_PROPERTY_ADDRESS;
extern fn listener(
extern "C" fn listener(
id: sys::AudioObjectID,
number_of_addresses: u32,
addresses: *const sys::AudioObjectPropertyAddress,
data: *mut c_void
data: *mut c_void,
) -> sys::OSStatus {
assert!(false, "Should not be called.");
sys::kAudioHardwareUnspecifiedError as sys::OSStatus
@ -484,11 +407,11 @@ fn test_audio_object_add_property_listener_for_unknown_device() {
fn test_audio_object_remove_property_listener_for_unknown_device() {
use super::DEVICES_PROPERTY_ADDRESS;
extern fn listener(
extern "C" fn listener(
_: sys::AudioObjectID,
_: u32,
_: *const sys::AudioObjectPropertyAddress,
_: *mut c_void
_: *mut c_void,
) -> sys::OSStatus {
assert!(false, "Should not be called.");
sys::kAudioHardwareUnspecifiedError as sys::OSStatus
@ -509,11 +432,11 @@ fn test_audio_object_remove_property_listener_for_unknown_device() {
fn test_audio_object_remove_property_listener_without_adding_any_listener() {
use super::DEVICES_PROPERTY_ADDRESS;
extern fn listener(
extern "C" fn listener(
_: sys::AudioObjectID,
_: u32,
_: *const sys::AudioObjectPropertyAddress,
_: *mut c_void
_: *mut c_void,
) -> sys::OSStatus {
assert!(false, "Should not be called.");
sys::kAudioHardwareUnspecifiedError as sys::OSStatus
@ -535,11 +458,11 @@ fn test_audio_object_remove_property_listener_without_adding_any_listener() {
fn test_audio_object_add_then_remove_property_listener() {
use super::DEVICES_PROPERTY_ADDRESS;
extern fn listener(
extern "C" fn listener(
_: sys::AudioObjectID,
_: u32,
_: *const sys::AudioObjectPropertyAddress,
_: *mut c_void
_: *mut c_void,
) -> sys::OSStatus {
assert!(false, "Should not be called.");
sys::kAudioHardwareUnspecifiedError as sys::OSStatus
@ -573,15 +496,13 @@ fn test_manual_audio_object_add_property_listener() {
let mut called: u32 = 0;
extern fn listener(
extern "C" fn listener(
id: sys::AudioObjectID,
number_of_addresses: u32,
addresses: *const sys::AudioObjectPropertyAddress,
data: *mut c_void
data: *mut c_void,
) -> sys::OSStatus {
let called = unsafe {
&mut (*(data as *mut u32))
};
let called = unsafe { &mut (*(data as *mut u32)) };
*called += 1;
0 // noErr.
@ -595,7 +516,7 @@ fn test_manual_audio_object_add_property_listener() {
);
assert_eq!(r, 0);
while called == 0 {};
while called == 0 {}
let r = audio_object_remove_property_listener(
sys::kAudioObjectSystemObject,
@ -612,12 +533,12 @@ fn test_manual_audio_object_add_property_listener() {
#[test]
#[should_panic]
fn test_audio_unit_add_property_listener_for_null_unit() {
extern fn listener(
extern "C" fn listener(
_: *mut c_void,
_: sys::AudioUnit,
_: sys::AudioUnitPropertyID,
_: sys::AudioUnitScope,
_: sys::AudioUnitElement
_: sys::AudioUnitElement,
) {
assert!(false, "Should not be called.");
}
@ -634,16 +555,15 @@ fn test_audio_unit_add_property_listener_for_null_unit() {
);
}
#[test]
#[should_panic]
fn test_audio_unit_remove_property_listener_with_user_data_for_null_unit() {
extern fn listener(
extern "C" fn listener(
_: *mut c_void,
_: sys::AudioUnit,
_: sys::AudioUnitPropertyID,
_: sys::AudioUnitScope,
_: sys::AudioUnitElement
_: sys::AudioUnitElement,
) {
assert!(false, "Should not be called.");
}
@ -662,12 +582,12 @@ fn test_audio_unit_remove_property_listener_with_user_data_for_null_unit() {
#[test]
fn test_audio_unit_remove_property_listener_with_user_data_without_adding_any() {
extern fn listener(
extern "C" fn listener(
_: *mut c_void,
_: sys::AudioUnit,
_: sys::AudioUnitPropertyID,
_: sys::AudioUnitScope,
_: sys::AudioUnitElement
_: sys::AudioUnitElement,
) {
assert!(false, "Should not be called.");
}
@ -690,12 +610,12 @@ fn test_audio_unit_remove_property_listener_with_user_data_without_adding_any()
#[test]
fn test_audio_unit_add_then_remove_property_listener() {
extern fn listener(
extern "C" fn listener(
_: *mut c_void,
_: sys::AudioUnit,
_: sys::AudioUnitPropertyID,
_: sys::AudioUnitScope,
_: sys::AudioUnitElement
_: sys::AudioUnitElement,
) {
assert!(false, "Should not be called.");
}
@ -732,7 +652,7 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
macro_rules! debug_println {
($( $args:expr ),*) => {
// println!( $( $args ),* );
}
};
}
use super::device_flags;
@ -742,47 +662,50 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
let mut called: u32 = 0;
extern fn listener(
extern "C" fn listener(
data: *mut c_void,
unit: sys::AudioUnit,
id: sys::AudioUnitPropertyID,
scope: sys::AudioUnitScope,
element: sys::AudioUnitElement
element: sys::AudioUnitElement,
) {
// This callback will be fired twice. One for input or output scope,
// the other is for global scope.
debug_println!("listener > id: {}, unit: {:?}, scope: {}, element: {}, data @ {:p}",
id, unit, scope, element, data);
assert_eq!(
debug_println!(
"listener > id: {}, unit: {:?}, scope: {}, element: {}, data @ {:p}",
id,
sys::kAudioDevicePropertyBufferFrameSize
unit,
scope,
element,
data
);
assert!((scope == sys::kAudioUnitScope_Output && element == IN_ELEMENT) ||
(scope == sys::kAudioUnitScope_Input && element == OUT_ELEMENT) ||
(scope == sys::kAudioUnitScope_Global && element == GLOBAL_ELEMENT));
assert_eq!(id, sys::kAudioDevicePropertyBufferFrameSize);
assert!(
(scope == sys::kAudioUnitScope_Output && element == IN_ELEMENT)
|| (scope == sys::kAudioUnitScope_Input && element == OUT_ELEMENT)
|| (scope == sys::kAudioUnitScope_Global && element == GLOBAL_ELEMENT)
);
let mut buffer_frames: u32 = 0;
let mut size = mem::size_of::<u32>();
assert_eq!(
audio_unit_get_property(
unit,
id,
scope,
element,
&mut buffer_frames,
&mut size
),
audio_unit_get_property(unit, id, scope, element, &mut buffer_frames, &mut size),
0
);
debug_println!("updated {} buffer frames: {}",
if element == IN_ELEMENT { "input" } else { "output" }, buffer_frames);
debug_println!(
"updated {} buffer frames: {}",
if element == IN_ELEMENT {
"input"
} else {
"output"
},
buffer_frames
);
let called = unsafe {
&mut (*(data as *mut u32))
};
let called = unsafe { &mut (*(data as *mut u32)) };
*called += 1;
// It's ok to remove listener here.
@ -798,13 +721,18 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
}
let default_device = get_default_input_or_output_device();
if default_device.id == sys::kAudioObjectUnknown ||
default_device.flags == device_flags::DEV_UNKNOWN {
if default_device.id == sys::kAudioObjectUnknown
|| default_device.flags == device_flags::DEV_UNKNOWN
{
return;
}
assert!(default_device.flags.intersects(device_flags::DEV_INPUT | device_flags::DEV_OUTPUT));
assert!(!default_device.flags.contains(device_flags::DEV_INPUT | device_flags::DEV_OUTPUT));
assert!(default_device
.flags
.intersects(device_flags::DEV_INPUT | device_flags::DEV_OUTPUT));
assert!(!default_device
.flags
.contains(device_flags::DEV_INPUT | device_flags::DEV_OUTPUT));
let is_input = if default_device.flags.contains(device_flags::DEV_INPUT) {
true
@ -822,7 +750,11 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
audio_unit_get_property(
unit,
sys::kAudioDevicePropertyBufferFrameSize,
if is_input { sys::kAudioUnitScope_Output } else { sys::kAudioUnitScope_Input },
if is_input {
sys::kAudioUnitScope_Output
} else {
sys::kAudioUnitScope_Input
},
if is_input { IN_ELEMENT } else { OUT_ELEMENT },
&mut buffer_frames,
&mut size
@ -830,8 +762,11 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
0
);
debug_println!("current {} buffer frames: {}",
if is_input { "input" } else { "output" }, buffer_frames);
debug_println!(
"current {} buffer frames: {}",
if is_input { "input" } else { "output" },
buffer_frames
);
assert_eq!(
audio_unit_add_property_listener(
@ -846,14 +781,21 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
// Make sure buffer_frames will be set to a new value.
assert_ne!(buffer_frames, 0);
buffer_frames *= 2;
debug_println!("target {} buffer frames: {}",
if is_input { "input" } else { "output" }, buffer_frames);
debug_println!(
"target {} buffer frames: {}",
if is_input { "input" } else { "output" },
buffer_frames
);
assert_eq!(
audio_unit_set_property(
unit,
sys::kAudioDevicePropertyBufferFrameSize,
if is_input { sys::kAudioUnitScope_Output } else { sys::kAudioUnitScope_Input },
if is_input {
sys::kAudioUnitScope_Output
} else {
sys::kAudioUnitScope_Input
},
if is_input { IN_ELEMENT } else { OUT_ELEMENT },
&buffer_frames,
size
@ -861,7 +803,7 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
0
);
while called < 2 {};
while called < 2 {}
assert_eq!(
audio_unit_remove_property_listener_with_user_data(
@ -878,22 +820,11 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
#[cfg(test)]
fn get_default_input_or_output_device() -> super::device_info {
use super::{
audiounit_get_default_device_id,
device_flags,
device_info,
DeviceType,
};
use super::{audiounit_get_default_device_id, device_flags, device_info, DeviceType};
let mut device = device_info::new();
assert_eq!(
device.id,
sys::kAudioObjectUnknown
);
assert_eq!(
device.flags,
device_flags::DEV_UNKNOWN
);
assert_eq!(device.id, sys::kAudioObjectUnknown);
assert_eq!(device.flags, device_flags::DEV_UNKNOWN);
// let default_output_id = audiounit_get_default_device_id(DeviceType::OUTPUT);
let default_output_id = sys::kAudioObjectUnknown;