run rustfmt
This commit is contained in:
Родитель
2d0b6dfd29
Коммит
ee9d493861
|
@ -78,11 +78,15 @@ pub trait Zero {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Zero for f32 {
|
impl Zero for f32 {
|
||||||
fn zero() -> Self { 0.0 }
|
fn zero() -> Self {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Zero for i16 {
|
impl Zero for i16 {
|
||||||
fn zero() -> Self { 0 }
|
fn zero() -> Self {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -139,7 +143,10 @@ fn test_auto_array_wrapper<T: Clone + Debug + PartialEq + Zero>(buf: &[T]) {
|
||||||
assert!(data.is_null());
|
assert!(data.is_null());
|
||||||
|
|
||||||
// Check if push works.
|
// 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());
|
assert_eq!(auto_array.as_ref().unwrap().elements(), buf.len());
|
||||||
|
|
||||||
let data = auto_array.as_ref().unwrap().as_ptr() as *const T;
|
let data = auto_array.as_ref().unwrap().as_ptr() as *const T;
|
||||||
|
|
|
@ -2,15 +2,12 @@ use std::fmt;
|
||||||
|
|
||||||
pub struct AutoRelease<T> {
|
pub struct AutoRelease<T> {
|
||||||
ptr: *mut T,
|
ptr: *mut T,
|
||||||
release_func: unsafe extern fn(*mut T)
|
release_func: unsafe extern "C" fn(*mut T),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AutoRelease<T> {
|
impl<T> AutoRelease<T> {
|
||||||
pub fn new(ptr: *mut T, release_func: unsafe extern fn(*mut T)) -> Self {
|
pub fn new(ptr: *mut T, release_func: unsafe extern "C" fn(*mut T)) -> Self {
|
||||||
Self {
|
Self { ptr, release_func }
|
||||||
ptr,
|
|
||||||
release_func
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self, ptr: *mut T) {
|
pub fn reset(&mut self, ptr: *mut T) {
|
||||||
|
@ -34,7 +31,9 @@ impl<T> AutoRelease<T> {
|
||||||
|
|
||||||
fn release(&self) {
|
fn release(&self) {
|
||||||
if !self.ptr.is_null() {
|
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::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
unsafe extern fn allocate() -> *mut libc::c_void {
|
unsafe extern "C" fn allocate() -> *mut libc::c_void {
|
||||||
// println!("Allocate!");
|
// println!("Allocate!");
|
||||||
libc::calloc(1, mem::size_of::<u32>())
|
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!");
|
// println!("Deallocate!");
|
||||||
libc::free(ptr);
|
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(
|
pub fn create_dispatch_queue(
|
||||||
label: &'static str,
|
label: &'static str,
|
||||||
queue_attr: sys::dispatch_queue_attr_t
|
queue_attr: sys::dispatch_queue_attr_t,
|
||||||
) -> sys::dispatch_queue_t
|
) -> sys::dispatch_queue_t {
|
||||||
{
|
|
||||||
let label = CString::new(label);
|
let label = CString::new(label);
|
||||||
let c_string = if label.is_ok() {
|
let c_string = if label.is_ok() {
|
||||||
label.unwrap().as_ptr()
|
label.unwrap().as_ptr()
|
||||||
|
@ -27,20 +26,21 @@ pub fn create_dispatch_queue(
|
||||||
unsafe { sys::dispatch_queue_create(c_string, queue_attr) }
|
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.
|
// TODO: This is incredibly unsafe. Find another way to release the queue.
|
||||||
unsafe {
|
unsafe {
|
||||||
sys::dispatch_release(
|
sys::dispatch_release(mem::transmute::<
|
||||||
mem::transmute::<sys::dispatch_queue_t, sys::dispatch_object_t>(queue)
|
sys::dispatch_queue_t,
|
||||||
);
|
sys::dispatch_object_t,
|
||||||
|
>(queue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send: Types that can be transferred across thread boundaries.
|
// Send: Types that can be transferred across thread boundaries.
|
||||||
// FnOnce: One-time function.
|
// FnOnce: One-time function.
|
||||||
pub fn async_dispatch<F>(queue: sys::dispatch_queue_t, work: F)
|
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);
|
let (closure, executor) = create_closure_and_executor(work);
|
||||||
unsafe {
|
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.
|
// Send: Types that can be transferred across thread boundaries.
|
||||||
// FnOnce: One-time function.
|
// FnOnce: One-time function.
|
||||||
pub fn sync_dispatch<F>(queue: sys::dispatch_queue_t, work: F)
|
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);
|
let (closure, executor) = create_closure_and_executor(work);
|
||||||
unsafe {
|
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
|
// 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.
|
// will run the closure (after re-boxing the closure) when it's called.
|
||||||
fn create_closure_and_executor<F>(
|
fn create_closure_and_executor<F>(closure: F) -> (*mut c_void, sys::dispatch_function_t)
|
||||||
closure: F
|
where
|
||||||
) -> (*mut c_void, sys::dispatch_function_t)
|
F: FnOnce(),
|
||||||
where F: FnOnce()
|
|
||||||
{
|
{
|
||||||
extern fn closure_executer<F>(unboxed_closure: *mut c_void)
|
extern "C" fn closure_executer<F>(unboxed_closure: *mut c_void)
|
||||||
where F: FnOnce()
|
where
|
||||||
|
F: FnOnce(),
|
||||||
{
|
{
|
||||||
// Retake the leaked closure.
|
// Retake the leaked closure.
|
||||||
let closure: Box<F> = unsafe {
|
let closure: Box<F> = unsafe { Box::from_raw(unboxed_closure as *mut F) };
|
||||||
Box::from_raw(unboxed_closure as *mut F)
|
|
||||||
};
|
|
||||||
// Execute the closure.
|
// Execute the closure.
|
||||||
(*closure)();
|
(*closure)();
|
||||||
// closure is released after finishiing this function call.
|
// 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.
|
Box::into_raw(closure) as *mut c_void, // Leak the closure.
|
||||||
executor
|
executor,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,19 +95,14 @@ fn test_dispatch_async_f() {
|
||||||
ptr::null()
|
ptr::null()
|
||||||
};
|
};
|
||||||
|
|
||||||
let queue = unsafe {
|
let queue = unsafe { sys::dispatch_queue_create(c_string, DISPATCH_QUEUE_SERIAL) };
|
||||||
sys::dispatch_queue_create(
|
|
||||||
c_string,
|
|
||||||
DISPATCH_QUEUE_SERIAL
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allocate the `context` on heap, otherwise the `context` will be
|
// Allocate the `context` on heap, otherwise the `context` will be
|
||||||
// freed before `work` is fired and after program goes out of the
|
// freed before `work` is fired and after program goes out of the
|
||||||
// scope of the unsafe block.
|
// scope of the unsafe block.
|
||||||
let context: Box<i32> = Box::new(123);
|
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;
|
let leaked_context = leaked_ptr as *mut i32;
|
||||||
|
|
||||||
// Retake the leaked `context`.
|
// Retake the leaked `context`.
|
||||||
|
@ -121,7 +115,7 @@ fn test_dispatch_async_f() {
|
||||||
sys::dispatch_async_f(
|
sys::dispatch_async_f(
|
||||||
queue,
|
queue,
|
||||||
Box::into_raw(context) as *mut c_void, // Leak the `context`.
|
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()
|
ptr::null()
|
||||||
};
|
};
|
||||||
|
|
||||||
let queue = unsafe {
|
let queue = unsafe { sys::dispatch_queue_create(c_string, DISPATCH_QUEUE_SERIAL) };
|
||||||
sys::dispatch_queue_create(
|
|
||||||
c_string,
|
|
||||||
DISPATCH_QUEUE_SERIAL
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut context: i32 = 20;
|
let mut context: i32 = 20;
|
||||||
|
|
||||||
extern fn work(context_ptr: *mut c_void) {
|
extern "C" fn work(context_ptr: *mut c_void) {
|
||||||
let ctx_mut_ref = unsafe {
|
let ctx_mut_ref = unsafe { &mut (*(context_ptr as *mut i32)) };
|
||||||
&mut (*(context_ptr as *mut i32))
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(ctx_mut_ref, &20);
|
assert_eq!(ctx_mut_ref, &20);
|
||||||
*ctx_mut_ref = 30;
|
*ctx_mut_ref = 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
sys::dispatch_sync_f(
|
sys::dispatch_sync_f(queue, &mut context as *mut i32 as *mut c_void, Some(work));
|
||||||
queue,
|
|
||||||
&mut context as *mut i32 as *mut c_void,
|
|
||||||
Some(work)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(context, 30);
|
assert_eq!(context, 30);
|
||||||
|
@ -168,10 +151,7 @@ fn test_dispatch_sync_f() {
|
||||||
fn test_async_dispatch() {
|
fn test_async_dispatch() {
|
||||||
let label = "Run with async dispatch api wrappers";
|
let label = "Run with async dispatch api wrappers";
|
||||||
|
|
||||||
let queue = create_dispatch_queue(
|
let queue = create_dispatch_queue(label, DISPATCH_QUEUE_SERIAL);
|
||||||
label,
|
|
||||||
DISPATCH_QUEUE_SERIAL
|
|
||||||
);
|
|
||||||
|
|
||||||
struct Resource {
|
struct Resource {
|
||||||
last_touched: Option<u32>,
|
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.
|
// 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!(resource.last_touched.is_some());
|
||||||
assert_eq!(resource.last_touched.unwrap(), 2);
|
assert_eq!(resource.last_touched.unwrap(), 2);
|
||||||
}
|
}
|
||||||
|
@ -241,10 +221,7 @@ fn test_async_dispatch() {
|
||||||
fn test_sync_dispatch() {
|
fn test_sync_dispatch() {
|
||||||
let label = "Run with sync dispatch api wrappers";
|
let label = "Run with sync dispatch api wrappers";
|
||||||
|
|
||||||
let queue = create_dispatch_queue(
|
let queue = create_dispatch_queue(label, DISPATCH_QUEUE_SERIAL);
|
||||||
label,
|
|
||||||
DISPATCH_QUEUE_SERIAL
|
|
||||||
);
|
|
||||||
|
|
||||||
struct Resource {
|
struct Resource {
|
||||||
last_touched: Option<u32>,
|
last_touched: Option<u32>,
|
||||||
|
|
|
@ -9,7 +9,7 @@ use self::libc::*;
|
||||||
use std::{fmt, mem};
|
use std::{fmt, mem};
|
||||||
|
|
||||||
pub struct OwnedCriticalSection {
|
pub struct OwnedCriticalSection {
|
||||||
mutex: pthread_mutex_t
|
mutex: pthread_mutex_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notice that `OwnedCriticalSection` only works after `init` is called.
|
// Notice that `OwnedCriticalSection` only works after `init` is called.
|
||||||
|
@ -26,7 +26,7 @@ pub struct OwnedCriticalSection {
|
||||||
impl OwnedCriticalSection {
|
impl OwnedCriticalSection {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
OwnedCriticalSection {
|
OwnedCriticalSection {
|
||||||
mutex: PTHREAD_MUTEX_INITIALIZER
|
mutex: PTHREAD_MUTEX_INITIALIZER,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,9 +91,7 @@ pub struct AutoLock<'a> {
|
||||||
impl<'a> AutoLock<'a> {
|
impl<'a> AutoLock<'a> {
|
||||||
pub fn new(mutex: &'a mut OwnedCriticalSection) -> Self {
|
pub fn new(mutex: &'a mut OwnedCriticalSection) -> Self {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
AutoLock {
|
AutoLock { mutex }
|
||||||
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> {
|
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.
|
// TODO: It's better to set ptr to null and len to 0.
|
||||||
// so the address won't be used again.
|
// so the address won't be used again.
|
||||||
unsafe {
|
unsafe { Vec::from_raw_parts(ptr, len, len) }
|
||||||
Vec::from_raw_parts(
|
|
||||||
ptr,
|
|
||||||
len,
|
|
||||||
len
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CFSTR doesn't be implemented in core-foundation-sys, so we create a function
|
// 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,
|
string.len() as sys::CFIndex,
|
||||||
sys::kCFStringEncodingUTF8,
|
sys::kCFStringEncodingUTF8,
|
||||||
false as sys::Boolean,
|
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.as_ptr(),
|
||||||
string.len() as sys::CFIndex,
|
string.len() as sys::CFIndex,
|
||||||
sys::kCFStringEncodingUTF8,
|
sys::kCFStringEncodingUTF8,
|
||||||
false as sys::Boolean
|
false as sys::Boolean,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,12 +83,7 @@ pub fn audio_object_has_property(
|
||||||
id: sys::AudioObjectID,
|
id: sys::AudioObjectID,
|
||||||
address: &sys::AudioObjectPropertyAddress,
|
address: &sys::AudioObjectPropertyAddress,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
unsafe {
|
unsafe { sys::AudioObjectHasProperty(id, address) != 0 }
|
||||||
sys::AudioObjectHasProperty(
|
|
||||||
id,
|
|
||||||
address,
|
|
||||||
) != 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio_object_get_property_data<T>(
|
pub fn audio_object_get_property_data<T>(
|
||||||
|
@ -121,13 +110,7 @@ pub fn audio_object_get_property_data_size(
|
||||||
size: *mut usize,
|
size: *mut usize,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
unsafe {
|
unsafe {
|
||||||
sys::AudioObjectGetPropertyDataSize(
|
sys::AudioObjectGetPropertyDataSize(id, address, 0, ptr::null(), size as *mut sys::UInt32)
|
||||||
id,
|
|
||||||
address,
|
|
||||||
0,
|
|
||||||
ptr::null(),
|
|
||||||
size as *mut sys::UInt32,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +135,7 @@ pub fn audio_object_set_property_data<T>(
|
||||||
// Referece:
|
// Referece:
|
||||||
// https://gist.github.com/ChunMinChang/f0f4a71f78d1e1c6390493ab1c9d10d3
|
// https://gist.github.com/ChunMinChang/f0f4a71f78d1e1c6390493ab1c9d10d3
|
||||||
#[allow(non_camel_case_types)]
|
#[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,
|
sys::AudioObjectID,
|
||||||
u32,
|
u32,
|
||||||
*const sys::AudioObjectPropertyAddress,
|
*const sys::AudioObjectPropertyAddress,
|
||||||
|
@ -165,14 +148,7 @@ pub fn audio_object_add_property_listener(
|
||||||
listener: audio_object_property_listener_proc,
|
listener: audio_object_property_listener_proc,
|
||||||
data: *mut c_void,
|
data: *mut c_void,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
unsafe {
|
unsafe { sys::AudioObjectAddPropertyListener(id, address, Some(listener), data) }
|
||||||
sys::AudioObjectAddPropertyListener(
|
|
||||||
id,
|
|
||||||
address,
|
|
||||||
Some(listener),
|
|
||||||
data
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio_object_remove_property_listener(
|
pub fn audio_object_remove_property_listener(
|
||||||
|
@ -181,14 +157,7 @@ pub fn audio_object_remove_property_listener(
|
||||||
listener: audio_object_property_listener_proc,
|
listener: audio_object_property_listener_proc,
|
||||||
data: *mut c_void,
|
data: *mut c_void,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
unsafe {
|
unsafe { sys::AudioObjectRemovePropertyListener(id, address, Some(listener), data) }
|
||||||
sys::AudioObjectRemovePropertyListener(
|
|
||||||
id,
|
|
||||||
address,
|
|
||||||
Some(listener),
|
|
||||||
data
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio_unit_get_property_info(
|
pub fn audio_unit_get_property_info(
|
||||||
|
@ -197,7 +166,7 @@ pub fn audio_unit_get_property_info(
|
||||||
scope: sys::AudioUnitScope,
|
scope: sys::AudioUnitScope,
|
||||||
element: sys::AudioUnitElement,
|
element: sys::AudioUnitElement,
|
||||||
size: *mut usize,
|
size: *mut usize,
|
||||||
writable: *mut sys::Boolean
|
writable: *mut sys::Boolean,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
assert!(!unit.is_null());
|
assert!(!unit.is_null());
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -207,7 +176,7 @@ pub fn audio_unit_get_property_info(
|
||||||
scope,
|
scope,
|
||||||
element,
|
element,
|
||||||
size as *mut sys::UInt32,
|
size as *mut sys::UInt32,
|
||||||
writable
|
writable,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +197,7 @@ pub fn audio_unit_get_property<T>(
|
||||||
scope,
|
scope,
|
||||||
element,
|
element,
|
||||||
data as *mut c_void,
|
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(
|
pub fn audio_unit_get_parameter(
|
||||||
unit: sys::AudioUnit,
|
unit: sys::AudioUnit,
|
||||||
id: sys:: AudioUnitParameterID,
|
id: sys::AudioUnitParameterID,
|
||||||
scope: sys::AudioUnitScope,
|
scope: sys::AudioUnitScope,
|
||||||
element: sys::AudioUnitElement,
|
element: sys::AudioUnitElement,
|
||||||
value: &mut sys::AudioUnitParameterValue,
|
value: &mut sys::AudioUnitParameterValue,
|
||||||
|
@ -268,19 +237,19 @@ pub fn audio_unit_get_parameter(
|
||||||
id,
|
id,
|
||||||
scope,
|
scope,
|
||||||
element,
|
element,
|
||||||
value as *mut sys::AudioUnitParameterValue
|
value as *mut sys::AudioUnitParameterValue,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://developer.apple.com/documentation/audiotoolbox/1440111-audiounitaddpropertylistener?language=objc
|
// https://developer.apple.com/documentation/audiotoolbox/1440111-audiounitaddpropertylistener?language=objc
|
||||||
#[allow(non_camel_case_types)]
|
#[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,
|
*mut c_void,
|
||||||
sys::AudioUnit,
|
sys::AudioUnit,
|
||||||
sys::AudioUnitPropertyID,
|
sys::AudioUnitPropertyID,
|
||||||
sys::AudioUnitScope,
|
sys::AudioUnitScope,
|
||||||
sys::AudioUnitElement
|
sys::AudioUnitElement,
|
||||||
);
|
);
|
||||||
|
|
||||||
pub fn audio_unit_add_property_listener(
|
pub fn audio_unit_add_property_listener(
|
||||||
|
@ -290,14 +259,7 @@ pub fn audio_unit_add_property_listener(
|
||||||
data: *mut c_void,
|
data: *mut c_void,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
assert!(!unit.is_null());
|
assert!(!unit.is_null());
|
||||||
unsafe {
|
unsafe { sys::AudioUnitAddPropertyListener(unit, id, Some(listener), data) }
|
||||||
sys::AudioUnitAddPropertyListener(
|
|
||||||
unit,
|
|
||||||
id,
|
|
||||||
Some(listener),
|
|
||||||
data
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio_unit_remove_property_listener_with_user_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,
|
data: *mut c_void,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
assert!(!unit.is_null());
|
assert!(!unit.is_null());
|
||||||
unsafe {
|
unsafe { sys::AudioUnitRemovePropertyListenerWithUserData(unit, id, Some(listener), data) }
|
||||||
sys::AudioUnitRemovePropertyListenerWithUserData(
|
|
||||||
unit,
|
|
||||||
id,
|
|
||||||
Some(listener),
|
|
||||||
data
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio_unit_set_parameter(
|
pub fn audio_unit_set_parameter(
|
||||||
unit: sys::AudioUnit,
|
unit: sys::AudioUnit,
|
||||||
id: sys:: AudioUnitParameterID,
|
id: sys::AudioUnitParameterID,
|
||||||
scope: sys::AudioUnitScope,
|
scope: sys::AudioUnitScope,
|
||||||
element: sys::AudioUnitElement,
|
element: sys::AudioUnitElement,
|
||||||
value: sys::AudioUnitParameterValue,
|
value: sys::AudioUnitParameterValue,
|
||||||
buffer_offset_in_frames: sys::UInt32,
|
buffer_offset_in_frames: sys::UInt32,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
assert!(!unit.is_null());
|
assert!(!unit.is_null());
|
||||||
unsafe {
|
unsafe { sys::AudioUnitSetParameter(unit, id, scope, element, value, buffer_offset_in_frames) }
|
||||||
sys::AudioUnitSetParameter(
|
|
||||||
unit,
|
|
||||||
id,
|
|
||||||
scope,
|
|
||||||
element,
|
|
||||||
value,
|
|
||||||
buffer_offset_in_frames
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio_unit_render(
|
pub fn audio_unit_render(
|
||||||
|
@ -344,7 +290,7 @@ pub fn audio_unit_render(
|
||||||
in_time_stamp: *const sys::AudioTimeStamp,
|
in_time_stamp: *const sys::AudioTimeStamp,
|
||||||
in_output_bus_number: u32,
|
in_output_bus_number: u32,
|
||||||
in_number_frames: u32,
|
in_number_frames: u32,
|
||||||
io_data: *mut sys::AudioBufferList
|
io_data: *mut sys::AudioBufferList,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
assert!(!in_unit.is_null());
|
assert!(!in_unit.is_null());
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -354,57 +300,37 @@ pub fn audio_unit_render(
|
||||||
in_time_stamp,
|
in_time_stamp,
|
||||||
in_output_bus_number,
|
in_output_bus_number,
|
||||||
in_number_frames,
|
in_number_frames,
|
||||||
io_data
|
io_data,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio_unit_initialize(
|
pub fn audio_unit_initialize(unit: sys::AudioUnit) -> sys::OSStatus {
|
||||||
unit: sys::AudioUnit,
|
|
||||||
) -> sys::OSStatus {
|
|
||||||
assert!(!unit.is_null());
|
assert!(!unit.is_null());
|
||||||
unsafe {
|
unsafe { sys::AudioUnitInitialize(unit) }
|
||||||
sys::AudioUnitInitialize(unit)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe we can merge the following two functions into something like
|
// TODO: Maybe we can merge the following two functions into something like
|
||||||
// `destroy_audio_unit(unit: sys::AudioUnit)` and call
|
// `destroy_audio_unit(unit: sys::AudioUnit)` and call
|
||||||
// `AudioUnitUninitialize`, `AudioComponentInstanceDispose` in this
|
// `AudioUnitUninitialize`, `AudioComponentInstanceDispose` in this
|
||||||
// function.
|
// function.
|
||||||
pub fn audio_unit_uninitialize(
|
pub fn audio_unit_uninitialize(unit: sys::AudioUnit) -> sys::OSStatus {
|
||||||
unit: sys::AudioUnit,
|
|
||||||
) -> sys::OSStatus {
|
|
||||||
assert!(!unit.is_null());
|
assert!(!unit.is_null());
|
||||||
unsafe {
|
unsafe { sys::AudioUnitUninitialize(unit) }
|
||||||
sys::AudioUnitUninitialize(unit)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispose_audio_unit(
|
pub fn dispose_audio_unit(unit: sys::AudioUnit) -> sys::OSStatus {
|
||||||
unit: sys::AudioUnit,
|
unsafe { sys::AudioComponentInstanceDispose(unit) }
|
||||||
) -> sys::OSStatus {
|
|
||||||
unsafe {
|
|
||||||
sys::AudioComponentInstanceDispose(unit)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio_output_unit_start(
|
pub fn audio_output_unit_start(unit: sys::AudioUnit) -> sys::OSStatus {
|
||||||
unit: sys::AudioUnit,
|
|
||||||
) -> sys::OSStatus {
|
|
||||||
assert!(!unit.is_null());
|
assert!(!unit.is_null());
|
||||||
unsafe {
|
unsafe { sys::AudioOutputUnitStart(unit) }
|
||||||
sys::AudioOutputUnitStart(unit)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn audio_output_unit_stop(
|
pub fn audio_output_unit_stop(unit: sys::AudioUnit) -> sys::OSStatus {
|
||||||
unit: sys::AudioUnit,
|
|
||||||
) -> sys::OSStatus {
|
|
||||||
assert!(!unit.is_null());
|
assert!(!unit.is_null());
|
||||||
unsafe {
|
unsafe { sys::AudioOutputUnitStop(unit) }
|
||||||
sys::AudioOutputUnitStop(unit)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -447,10 +373,7 @@ fn test_create_cfstring_ref() {
|
||||||
CFRelease(cfstrref as *const c_void);
|
CFRelease(cfstrref as *const c_void);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(test_string, cstring.to_string_lossy());
|
||||||
test_string,
|
|
||||||
cstring.to_string_lossy()
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO: Find a way to check the string's inner pointer is different.
|
// 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() {
|
fn test_audio_object_add_property_listener_for_unknown_device() {
|
||||||
use super::DEVICES_PROPERTY_ADDRESS;
|
use super::DEVICES_PROPERTY_ADDRESS;
|
||||||
|
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
id: sys::AudioObjectID,
|
id: sys::AudioObjectID,
|
||||||
number_of_addresses: u32,
|
number_of_addresses: u32,
|
||||||
addresses: *const sys::AudioObjectPropertyAddress,
|
addresses: *const sys::AudioObjectPropertyAddress,
|
||||||
data: *mut c_void
|
data: *mut c_void,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
assert!(false, "Should not be called.");
|
assert!(false, "Should not be called.");
|
||||||
sys::kAudioHardwareUnspecifiedError as sys::OSStatus
|
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() {
|
fn test_audio_object_remove_property_listener_for_unknown_device() {
|
||||||
use super::DEVICES_PROPERTY_ADDRESS;
|
use super::DEVICES_PROPERTY_ADDRESS;
|
||||||
|
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
_: sys::AudioObjectID,
|
_: sys::AudioObjectID,
|
||||||
_: u32,
|
_: u32,
|
||||||
_: *const sys::AudioObjectPropertyAddress,
|
_: *const sys::AudioObjectPropertyAddress,
|
||||||
_: *mut c_void
|
_: *mut c_void,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
assert!(false, "Should not be called.");
|
assert!(false, "Should not be called.");
|
||||||
sys::kAudioHardwareUnspecifiedError as sys::OSStatus
|
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() {
|
fn test_audio_object_remove_property_listener_without_adding_any_listener() {
|
||||||
use super::DEVICES_PROPERTY_ADDRESS;
|
use super::DEVICES_PROPERTY_ADDRESS;
|
||||||
|
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
_: sys::AudioObjectID,
|
_: sys::AudioObjectID,
|
||||||
_: u32,
|
_: u32,
|
||||||
_: *const sys::AudioObjectPropertyAddress,
|
_: *const sys::AudioObjectPropertyAddress,
|
||||||
_: *mut c_void
|
_: *mut c_void,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
assert!(false, "Should not be called.");
|
assert!(false, "Should not be called.");
|
||||||
sys::kAudioHardwareUnspecifiedError as sys::OSStatus
|
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() {
|
fn test_audio_object_add_then_remove_property_listener() {
|
||||||
use super::DEVICES_PROPERTY_ADDRESS;
|
use super::DEVICES_PROPERTY_ADDRESS;
|
||||||
|
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
_: sys::AudioObjectID,
|
_: sys::AudioObjectID,
|
||||||
_: u32,
|
_: u32,
|
||||||
_: *const sys::AudioObjectPropertyAddress,
|
_: *const sys::AudioObjectPropertyAddress,
|
||||||
_: *mut c_void
|
_: *mut c_void,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
assert!(false, "Should not be called.");
|
assert!(false, "Should not be called.");
|
||||||
sys::kAudioHardwareUnspecifiedError as sys::OSStatus
|
sys::kAudioHardwareUnspecifiedError as sys::OSStatus
|
||||||
|
@ -573,15 +496,13 @@ fn test_manual_audio_object_add_property_listener() {
|
||||||
|
|
||||||
let mut called: u32 = 0;
|
let mut called: u32 = 0;
|
||||||
|
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
id: sys::AudioObjectID,
|
id: sys::AudioObjectID,
|
||||||
number_of_addresses: u32,
|
number_of_addresses: u32,
|
||||||
addresses: *const sys::AudioObjectPropertyAddress,
|
addresses: *const sys::AudioObjectPropertyAddress,
|
||||||
data: *mut c_void
|
data: *mut c_void,
|
||||||
) -> sys::OSStatus {
|
) -> sys::OSStatus {
|
||||||
let called = unsafe {
|
let called = unsafe { &mut (*(data as *mut u32)) };
|
||||||
&mut (*(data as *mut u32))
|
|
||||||
};
|
|
||||||
*called += 1;
|
*called += 1;
|
||||||
|
|
||||||
0 // noErr.
|
0 // noErr.
|
||||||
|
@ -595,7 +516,7 @@ fn test_manual_audio_object_add_property_listener() {
|
||||||
);
|
);
|
||||||
assert_eq!(r, 0);
|
assert_eq!(r, 0);
|
||||||
|
|
||||||
while called == 0 {};
|
while called == 0 {}
|
||||||
|
|
||||||
let r = audio_object_remove_property_listener(
|
let r = audio_object_remove_property_listener(
|
||||||
sys::kAudioObjectSystemObject,
|
sys::kAudioObjectSystemObject,
|
||||||
|
@ -612,12 +533,12 @@ fn test_manual_audio_object_add_property_listener() {
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_audio_unit_add_property_listener_for_null_unit() {
|
fn test_audio_unit_add_property_listener_for_null_unit() {
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
_: *mut c_void,
|
_: *mut c_void,
|
||||||
_: sys::AudioUnit,
|
_: sys::AudioUnit,
|
||||||
_: sys::AudioUnitPropertyID,
|
_: sys::AudioUnitPropertyID,
|
||||||
_: sys::AudioUnitScope,
|
_: sys::AudioUnitScope,
|
||||||
_: sys::AudioUnitElement
|
_: sys::AudioUnitElement,
|
||||||
) {
|
) {
|
||||||
assert!(false, "Should not be called.");
|
assert!(false, "Should not be called.");
|
||||||
}
|
}
|
||||||
|
@ -634,16 +555,15 @@ fn test_audio_unit_add_property_listener_for_null_unit() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_audio_unit_remove_property_listener_with_user_data_for_null_unit() {
|
fn test_audio_unit_remove_property_listener_with_user_data_for_null_unit() {
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
_: *mut c_void,
|
_: *mut c_void,
|
||||||
_: sys::AudioUnit,
|
_: sys::AudioUnit,
|
||||||
_: sys::AudioUnitPropertyID,
|
_: sys::AudioUnitPropertyID,
|
||||||
_: sys::AudioUnitScope,
|
_: sys::AudioUnitScope,
|
||||||
_: sys::AudioUnitElement
|
_: sys::AudioUnitElement,
|
||||||
) {
|
) {
|
||||||
assert!(false, "Should not be called.");
|
assert!(false, "Should not be called.");
|
||||||
}
|
}
|
||||||
|
@ -662,12 +582,12 @@ fn test_audio_unit_remove_property_listener_with_user_data_for_null_unit() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_audio_unit_remove_property_listener_with_user_data_without_adding_any() {
|
fn test_audio_unit_remove_property_listener_with_user_data_without_adding_any() {
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
_: *mut c_void,
|
_: *mut c_void,
|
||||||
_: sys::AudioUnit,
|
_: sys::AudioUnit,
|
||||||
_: sys::AudioUnitPropertyID,
|
_: sys::AudioUnitPropertyID,
|
||||||
_: sys::AudioUnitScope,
|
_: sys::AudioUnitScope,
|
||||||
_: sys::AudioUnitElement
|
_: sys::AudioUnitElement,
|
||||||
) {
|
) {
|
||||||
assert!(false, "Should not be called.");
|
assert!(false, "Should not be called.");
|
||||||
}
|
}
|
||||||
|
@ -690,12 +610,12 @@ fn test_audio_unit_remove_property_listener_with_user_data_without_adding_any()
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_audio_unit_add_then_remove_property_listener() {
|
fn test_audio_unit_add_then_remove_property_listener() {
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
_: *mut c_void,
|
_: *mut c_void,
|
||||||
_: sys::AudioUnit,
|
_: sys::AudioUnit,
|
||||||
_: sys::AudioUnitPropertyID,
|
_: sys::AudioUnitPropertyID,
|
||||||
_: sys::AudioUnitScope,
|
_: sys::AudioUnitScope,
|
||||||
_: sys::AudioUnitElement
|
_: sys::AudioUnitElement,
|
||||||
) {
|
) {
|
||||||
assert!(false, "Should not be called.");
|
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 {
|
macro_rules! debug_println {
|
||||||
($( $args:expr ),*) => {
|
($( $args:expr ),*) => {
|
||||||
// println!( $( $args ),* );
|
// println!( $( $args ),* );
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
use super::device_flags;
|
use super::device_flags;
|
||||||
|
@ -742,47 +662,50 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
|
||||||
|
|
||||||
let mut called: u32 = 0;
|
let mut called: u32 = 0;
|
||||||
|
|
||||||
extern fn listener(
|
extern "C" fn listener(
|
||||||
data: *mut c_void,
|
data: *mut c_void,
|
||||||
unit: sys::AudioUnit,
|
unit: sys::AudioUnit,
|
||||||
id: sys::AudioUnitPropertyID,
|
id: sys::AudioUnitPropertyID,
|
||||||
scope: sys::AudioUnitScope,
|
scope: sys::AudioUnitScope,
|
||||||
element: sys::AudioUnitElement
|
element: sys::AudioUnitElement,
|
||||||
) {
|
) {
|
||||||
// This callback will be fired twice. One for input or output scope,
|
// This callback will be fired twice. One for input or output scope,
|
||||||
// the other is for global scope.
|
// the other is for global scope.
|
||||||
debug_println!("listener > id: {}, unit: {:?}, scope: {}, element: {}, data @ {:p}",
|
debug_println!(
|
||||||
id, unit, scope, element, data);
|
"listener > id: {}, unit: {:?}, scope: {}, element: {}, data @ {:p}",
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
id,
|
id,
|
||||||
sys::kAudioDevicePropertyBufferFrameSize
|
unit,
|
||||||
|
scope,
|
||||||
|
element,
|
||||||
|
data
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!((scope == sys::kAudioUnitScope_Output && element == IN_ELEMENT) ||
|
assert_eq!(id, sys::kAudioDevicePropertyBufferFrameSize);
|
||||||
(scope == sys::kAudioUnitScope_Input && element == OUT_ELEMENT) ||
|
|
||||||
(scope == sys::kAudioUnitScope_Global && element == GLOBAL_ELEMENT));
|
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 buffer_frames: u32 = 0;
|
||||||
let mut size = mem::size_of::<u32>();
|
let mut size = mem::size_of::<u32>();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
audio_unit_get_property(
|
audio_unit_get_property(unit, id, scope, element, &mut buffer_frames, &mut size),
|
||||||
unit,
|
|
||||||
id,
|
|
||||||
scope,
|
|
||||||
element,
|
|
||||||
&mut buffer_frames,
|
|
||||||
&mut size
|
|
||||||
),
|
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_println!("updated {} buffer frames: {}",
|
debug_println!(
|
||||||
if element == IN_ELEMENT { "input" } else { "output" }, buffer_frames);
|
"updated {} buffer frames: {}",
|
||||||
|
if element == IN_ELEMENT {
|
||||||
|
"input"
|
||||||
|
} else {
|
||||||
|
"output"
|
||||||
|
},
|
||||||
|
buffer_frames
|
||||||
|
);
|
||||||
|
|
||||||
let called = unsafe {
|
let called = unsafe { &mut (*(data as *mut u32)) };
|
||||||
&mut (*(data as *mut u32))
|
|
||||||
};
|
|
||||||
*called += 1;
|
*called += 1;
|
||||||
|
|
||||||
// It's ok to remove listener here.
|
// 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();
|
let default_device = get_default_input_or_output_device();
|
||||||
if default_device.id == sys::kAudioObjectUnknown ||
|
if default_device.id == sys::kAudioObjectUnknown
|
||||||
default_device.flags == device_flags::DEV_UNKNOWN {
|
|| default_device.flags == device_flags::DEV_UNKNOWN
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(default_device.flags.intersects(device_flags::DEV_INPUT | device_flags::DEV_OUTPUT));
|
assert!(default_device
|
||||||
assert!(!default_device.flags.contains(device_flags::DEV_INPUT | device_flags::DEV_OUTPUT));
|
.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) {
|
let is_input = if default_device.flags.contains(device_flags::DEV_INPUT) {
|
||||||
true
|
true
|
||||||
|
@ -822,7 +750,11 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
|
||||||
audio_unit_get_property(
|
audio_unit_get_property(
|
||||||
unit,
|
unit,
|
||||||
sys::kAudioDevicePropertyBufferFrameSize,
|
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 },
|
if is_input { IN_ELEMENT } else { OUT_ELEMENT },
|
||||||
&mut buffer_frames,
|
&mut buffer_frames,
|
||||||
&mut size
|
&mut size
|
||||||
|
@ -830,8 +762,11 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_println!("current {} buffer frames: {}",
|
debug_println!(
|
||||||
if is_input { "input" } else { "output" }, buffer_frames);
|
"current {} buffer frames: {}",
|
||||||
|
if is_input { "input" } else { "output" },
|
||||||
|
buffer_frames
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
audio_unit_add_property_listener(
|
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.
|
// Make sure buffer_frames will be set to a new value.
|
||||||
assert_ne!(buffer_frames, 0);
|
assert_ne!(buffer_frames, 0);
|
||||||
buffer_frames *= 2;
|
buffer_frames *= 2;
|
||||||
debug_println!("target {} buffer frames: {}",
|
debug_println!(
|
||||||
if is_input { "input" } else { "output" }, buffer_frames);
|
"target {} buffer frames: {}",
|
||||||
|
if is_input { "input" } else { "output" },
|
||||||
|
buffer_frames
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
audio_unit_set_property(
|
audio_unit_set_property(
|
||||||
unit,
|
unit,
|
||||||
sys::kAudioDevicePropertyBufferFrameSize,
|
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 },
|
if is_input { IN_ELEMENT } else { OUT_ELEMENT },
|
||||||
&buffer_frames,
|
&buffer_frames,
|
||||||
size
|
size
|
||||||
|
@ -861,7 +803,7 @@ fn test_audio_unit_add_then_fire_then_remove_property_listener() {
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
while called < 2 {};
|
while called < 2 {}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
audio_unit_remove_property_listener_with_user_data(
|
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)]
|
#[cfg(test)]
|
||||||
fn get_default_input_or_output_device() -> super::device_info {
|
fn get_default_input_or_output_device() -> super::device_info {
|
||||||
use super::{
|
use super::{audiounit_get_default_device_id, device_flags, device_info, DeviceType};
|
||||||
audiounit_get_default_device_id,
|
|
||||||
device_flags,
|
|
||||||
device_info,
|
|
||||||
DeviceType,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut device = device_info::new();
|
let mut device = device_info::new();
|
||||||
assert_eq!(
|
assert_eq!(device.id, sys::kAudioObjectUnknown);
|
||||||
device.id,
|
assert_eq!(device.flags, device_flags::DEV_UNKNOWN);
|
||||||
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 = audiounit_get_default_device_id(DeviceType::OUTPUT);
|
||||||
let default_output_id = sys::kAudioObjectUnknown;
|
let default_output_id = sys::kAudioObjectUnknown;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче