use std::ffi::c_void;
use objc::runtime::{Class, Object};
#[allow(unused_imports)]
use objc::{msg_send, sel, sel_impl};
#[repr(C)]
#[allow(dead_code)]
pub(super) struct AudioStreamBasicDescription {
pub(super) sample_rate: f64,
pub(super) format_id: u32,
pub(super) format_flags: u32,
pub(super) bytes_per_packet: u32,
pub(super) frames_per_packet: u32,
pub(super) bytes_per_frame: u32,
pub(super) channels_per_frame: u32,
pub(super) bits_per_channel: u32,
pub(super) reserved: u32,
}
#[repr(C)]
pub(super) struct AudioObjectPropertyAddress {
pub(super) selector: u32,
pub(super) scope: u32,
pub(super) element: u32,
}
#[allow(dead_code)]
pub(super) const K_AUDIO_FORMAT_LINEAR_PCM: u32 = 0x6C70_636D; #[allow(dead_code)]
pub(super) const K_AUDIO_FORMAT_FLAG_SIGNED_INTEGER: u32 = 0x0004;
#[allow(dead_code)]
pub(super) const K_AUDIO_FORMAT_FLAG_PACKED: u32 = 0x0008;
pub(super) const K_AUDIO_OBJECT_PROPERTY_SELECTOR_DEVICES: u32 = 0x6465_7623; pub(super) const K_AUDIO_OBJECT_PROPERTY_SELECTOR_DEFAULT_INPUT: u32 = 0x6471_6966;
pub(super) const K_AUDIO_OBJECT_PROPERTY_SELECTOR_DEFAULT_OUTPUT: u32 = 0x6471_6F66;
pub(super) const K_AUDIO_OBJECT_PROPERTY_SELECTOR_NAME: u32 = 0x6C6E_616D; pub(super) const K_AUDIO_OBJECT_PROPERTY_SELECTOR_STREAMS: u32 = 0x7374_726D; pub(super) const K_AUDIO_OBJECT_PROPERTY_SELECTOR_NOMINAL_SAMPLE_RATE: u32 = 0x6E73_7274;
pub(super) const K_AUDIO_OBJECT_PROPERTY_SCOPE_GLOBAL: u32 = 0x676C_6F62; pub(super) const K_AUDIO_OBJECT_PROPERTY_SCOPE_INPUT: u32 = 0x696E_7074; pub(super) const K_AUDIO_OBJECT_PROPERTY_SCOPE_OUTPUT: u32 = 0x6F757470; pub(super) const K_AUDIO_OBJECT_PROPERTY_ELEMENT_MAIN: u32 = 0;
pub(super) const K_AUDIO_OBJECT_SYSTEM_OBJECT: u32 = 1;
extern "C" {
pub(super) fn AudioObjectGetPropertyDataSize(
object_id: u32,
address: *const AudioObjectPropertyAddress,
qualifier_data_size: u32,
qualifier_data: *const c_void,
out_data_size: *mut u32,
) -> i32;
pub(super) fn AudioObjectGetPropertyData(
object_id: u32,
address: *const AudioObjectPropertyAddress,
qualifier_data_size: u32,
qualifier_data: *const c_void,
io_data_size: *mut u32,
out_data: *mut c_void,
) -> i32;
}
pub(super) fn objc_class(name: &str) -> *const Class {
use std::ffi::CString;
let c = CString::new(name).unwrap_or_default();
unsafe { objc::runtime::objc_getClass(c.as_ptr()) }
}
pub(super) fn ns_string_from_str(s: &str) -> *mut Object {
let cls = objc_class("NSString");
if cls.is_null() {
return std::ptr::null_mut();
}
unsafe {
let obj: *mut Object = msg_send![cls, alloc];
msg_send![obj, initWithBytes: s.as_ptr() as *const c_void
length: s.len()
encoding: 4u64] }
}
pub(super) fn cf_string_to_string(cf_str: *const c_void) -> String {
if cf_str.is_null() {
return String::new();
}
use core_foundation::base::TCFType;
use core_foundation::string::CFStringRef;
let cf =
unsafe { core_foundation::string::CFString::wrap_under_create_rule(cf_str as CFStringRef) };
cf.to_string()
}
pub(super) fn ns_string_to_rust(ns: *mut Object) -> String {
if ns.is_null() {
return String::new();
}
let utf8: *const u8 = unsafe { msg_send![ns, UTF8String] };
if utf8.is_null() {
return String::new();
}
unsafe {
std::ffi::CStr::from_ptr(utf8 as *const std::ffi::c_char)
.to_string_lossy()
.into_owned()
}
}
pub(super) fn release_objc_object(obj: *mut Object) {
if !obj.is_null() {
unsafe {
let _: () = msg_send![obj, release];
}
}
}