Try using the model id as group id. (#64)
It works for the all the external devices that I have, but not for the built-in mic/speakers and the trrs plug.
This commit is contained in:
Родитель
ab319780de
Коммит
aa80b3ff3b
|
@ -21,6 +21,23 @@ pub fn get_device_uid(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_device_model_uid(
|
||||
id: AudioDeviceID,
|
||||
devtype: DeviceType,
|
||||
) -> std::result::Result<StringRef, OSStatus> {
|
||||
assert_ne!(id, kAudioObjectUnknown);
|
||||
|
||||
let address = get_property_address(Property::ModelUID, devtype);
|
||||
let mut size = mem::size_of::<CFStringRef>();
|
||||
let mut uid: CFStringRef = ptr::null();
|
||||
let err = audio_object_get_property_data(id, &address, &mut size, &mut uid);
|
||||
if err == NO_ERR {
|
||||
Ok(StringRef::new(uid as _))
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_device_source(
|
||||
id: AudioDeviceID,
|
||||
devtype: DeviceType,
|
||||
|
@ -276,6 +293,7 @@ pub enum Property {
|
|||
DeviceStreamFormat,
|
||||
DeviceStreams,
|
||||
DeviceUID,
|
||||
ModelUID,
|
||||
HardwareDefaultInputDevice,
|
||||
HardwareDefaultOutputDevice,
|
||||
HardwareDevices,
|
||||
|
@ -298,6 +316,7 @@ impl From<Property> for AudioObjectPropertySelector {
|
|||
Property::DeviceStreamFormat => kAudioDevicePropertyStreamFormat,
|
||||
Property::DeviceStreams => kAudioDevicePropertyStreams,
|
||||
Property::DeviceUID => kAudioDevicePropertyDeviceUID,
|
||||
Property::ModelUID => kAudioDevicePropertyModelUID,
|
||||
Property::HardwareDefaultInputDevice => kAudioHardwarePropertyDefaultInputDevice,
|
||||
Property::HardwareDefaultOutputDevice => kAudioHardwarePropertyDefaultOutputDevice,
|
||||
Property::HardwareDevices => kAudioHardwarePropertyDevices,
|
||||
|
|
|
@ -1506,7 +1506,6 @@ fn create_cubeb_device_info(
|
|||
Ok(uid) => {
|
||||
let c_string = uid.into_cstring();
|
||||
dev_info.device_id = c_string.into_raw();
|
||||
dev_info.group_id = dev_info.device_id;
|
||||
}
|
||||
Err(e) => {
|
||||
cubeb_log!(
|
||||
|
@ -1518,6 +1517,21 @@ fn create_cubeb_device_info(
|
|||
}
|
||||
}
|
||||
|
||||
match get_device_model_uid(devid, devtype) {
|
||||
Ok(uid) => {
|
||||
let c_string = uid.into_cstring();
|
||||
dev_info.group_id = c_string.into_raw();
|
||||
}
|
||||
Err(e) => {
|
||||
cubeb_log!(
|
||||
"Cannot get the model uid for device {} in {:?} scope. Error: {}",
|
||||
devid,
|
||||
devtype,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let label = match get_device_label(devid, devtype) {
|
||||
Ok(label) => label.into_cstring(),
|
||||
Err(e) => {
|
||||
|
@ -1630,14 +1644,14 @@ fn destroy_cubeb_device_info(device: &mut ffi::cubeb_device_info) {
|
|||
// This should be mapped to the memory allocation in create_cubeb_device_info.
|
||||
// Set the pointers to null in case it points to some released memory.
|
||||
unsafe {
|
||||
if !device.device_id.is_null() {
|
||||
// group_id is a mirror to device_id, so we could skip it.
|
||||
assert!(!device.group_id.is_null());
|
||||
assert_eq!(device.device_id, device.group_id);
|
||||
let _ = CString::from_raw(device.device_id as *mut _);
|
||||
device.device_id = ptr::null();
|
||||
device.group_id = ptr::null();
|
||||
}
|
||||
assert!(!device.device_id.is_null());
|
||||
let _ = CString::from_raw(device.device_id as *mut _);
|
||||
device.device_id = ptr::null();
|
||||
|
||||
assert!(!device.group_id.is_null());
|
||||
let _ = CString::from_raw(device.group_id as *mut _);
|
||||
device.group_id = ptr::null();
|
||||
|
||||
if !device.friendly_name.is_null() {
|
||||
let _ = CString::from_raw(device.friendly_name as *mut _);
|
||||
device.friendly_name = ptr::null();
|
||||
|
|
|
@ -1394,7 +1394,8 @@ fn test_create_cubeb_device_info() {
|
|||
assert_eq!(info.devid as AudioObjectID, id);
|
||||
assert!(!info.device_id.is_null());
|
||||
assert!(!info.friendly_name.is_null());
|
||||
assert_eq!(info.group_id, info.device_id);
|
||||
assert!(!info.group_id.is_null());
|
||||
|
||||
// TODO: Hit a kAudioHardwareUnknownPropertyError for AirPods
|
||||
// assert!(!info.vendor_name.is_null());
|
||||
|
||||
|
@ -1495,8 +1496,8 @@ fn test_device_destroy() {
|
|||
let vendor_name = CString::new("test: vendor name").unwrap();
|
||||
|
||||
device.device_id = device_id.into_raw();
|
||||
// The group_id is a mirror to device_id in our implementation, so we could skip it.
|
||||
device.group_id = device.device_id;
|
||||
let group_id = CString::new("test: group id").unwrap();
|
||||
device.group_id = group_id.into_raw();
|
||||
device.friendly_name = friendly_name.into_raw();
|
||||
device.vendor_name = vendor_name.into_raw();
|
||||
|
||||
|
@ -1508,15 +1509,6 @@ fn test_device_destroy() {
|
|||
assert!(device.vendor_name.is_null());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_device_destroy_with_different_device_id_and_group_id() {
|
||||
let mut device = ffi::cubeb_device_info::default();
|
||||
device.device_id = 0xdeaddead as *const _;
|
||||
device.group_id = 0xdeadbeef as *const _;
|
||||
destroy_cubeb_device_info(&mut device);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_device_destroy_empty_device() {
|
||||
let mut device = ffi::cubeb_device_info::default();
|
||||
|
|
Загрузка…
Ссылка в новой задаче