Skip to content

feat(coreaudio): report device transport as InterfaceType - #1345

Open
jplot wants to merge 1 commit into
RustAudio:masterfrom
jplot:feat/coreaudio-transport-type
Open

feat(coreaudio): report device transport as InterfaceType#1345
jplot wants to merge 1 commit into
RustAudio:masterfrom
jplot:feat/coreaudio-transport-type

Conversation

@jplot

@jplot jplot commented Aug 30, 2026

Copy link
Copy Markdown

Motivation

On macOS, interface_type() is only set for aggregate devices — built-in
microphones, USB interfaces and Bluetooth headsets all report Unknown.

The WASAPI backend already fills this field from its endpoint properties.
CoreAudio exposes the same information through kAudioDevicePropertyTransportType,
and InterfaceType already has variants for nearly every value it returns, so
this closes the asymmetry without an API change.

Result

Same machine, before and after — all four are ordinary devices, not edge cases:

Device Before After
MacBook Pro Microphone Unknown BuiltIn
MacBook Pro Speakers Unknown BuiltIn
BlackHole 2ch Unknown Virtual
Microsoft Teams Audio Unknown Virtual

Notes

  • Returns Option, so an unmapped transport leaves the field unset rather than
    claiming Unknown.
  • is_aggregate_device() is kept as a fallback: TransportType reports grup
    for aggregates too, and I would rather not drop a path I cannot reproduce.
  • airp (AirPlay) maps to Network — the one mapping I would gladly change.
  • Tested on macOS 26.6 against built-in and virtual devices. The FireWire, PCI
    and DisplayPort arms are unverified: no such hardware here.

interface_type() was only set for aggregate devices on macOS; everything else,
including built-in microphones and USB interfaces, reported Unknown.

kAudioDevicePropertyTransportType names the connection, and InterfaceType
already has variants for nearly every value it returns. The WASAPI backend
fills the same field from its endpoint properties, so this closes an asymmetry
rather than adding an API.

is_aggregate_device() stays as a fallback: TransportType reports "grup" for
aggregates too, and the two agree where both apply.
Copilot AI lite review requested due to automatic review settings August 30, 2026 12:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The property query introduces undefined behavior and omits the supported AVB network transport.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +448 to +462
const AIRPLAY: u32 = u32::from_be_bytes(*b"airp");

match transport {
BUILT_IN => Some(InterfaceType::BuiltIn),
USB => Some(InterfaceType::Usb),
BLUETOOTH | BLUETOOTH_LE => Some(InterfaceType::Bluetooth),
VIRTUAL => Some(InterfaceType::Virtual),
AGGREGATE => Some(InterfaceType::Aggregate),
THUNDERBOLT => Some(InterfaceType::Thunderbolt),
HDMI => Some(InterfaceType::Hdmi),
DISPLAY_PORT => Some(InterfaceType::DisplayPort),
FIREWIRE => Some(InterfaceType::FireWire),
PCI => Some(InterfaceType::Pci),
AIRPLAY => Some(InterfaceType::Network),
_ => None,
Comment on lines +418 to +428
let data_size = size_of::<u32>() as u32;

// SAFETY: AudioObjectGetPropertyData writes a UInt32 for
// kAudioDevicePropertyTransportType. The status is checked before use.
let status = unsafe {
AudioObjectGetPropertyData(
self.audio_device_id,
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
@roderickvd

Copy link
Copy Markdown
Member

Thanks for your contribution! I re-ran the failed Copilot review you requested; if you'd please process those points?

Comment thread CHANGELOG.md
- `InputStreamTimestamp`/`OutputStreamTimestamp` merged into `StreamTimestamp`; `capture`/`playback` renamed `device`.
- Renamed the `wasm-beep` and `audioworklet-beep` examples to `webaudio` and `audioworklet`.
- **ALSA**: Update `alsa` dependency to 0.12.
- **CoreAudio**: `DeviceDescription::interface_type()` now reports the device transport (built-in, USB, Bluetooth, Thunderbolt, HDMI, and others) instead of only marking aggregate devices.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a bit shorter by removing the examples in the parentheses.

}

// Four-character codes from AudioHardwareBase.h.
const BUILT_IN: u32 = u32::from_be_bytes(*b"bltn");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following are already exported by objc2_core_audio:

pub const kAudioDeviceTransportTypeUnknown: u32 = 0;
pub const kAudioDeviceTransportTypeBuiltIn: u32 = 0x626c746e;
pub const kAudioDeviceTransportTypeAggregate: u32 = 0x67727570;
pub const kAudioDeviceTransportTypeVirtual: u32 = 0x76697274;
pub const kAudioDeviceTransportTypePCI: u32 = 0x70636920;
pub const kAudioDeviceTransportTypeUSB: u32 = 0x75736220;
pub const kAudioDeviceTransportTypeFireWire: u32 = 0x31333934;
pub const kAudioDeviceTransportTypeBluetooth: u32 = 0x626c7565;
pub const kAudioDeviceTransportTypeBluetoothLE: u32 = 0x626c6561;
pub const kAudioDeviceTransportTypeHDMI: u32 = 0x68646d69;
pub const kAudioDeviceTransportTypeDisplayPort: u32 = 0x64707274;
pub const kAudioDeviceTransportTypeAirPlay: u32 = 0x61697270;
pub const kAudioDeviceTransportTypeAVB: u32 = 0x65617662;
pub const kAudioDeviceTransportTypeThunderbolt: u32 = 0x7468756e;
pub const kAudioDeviceTransportTypeContinuityCaptureWired: u32 = 0x63637764;
pub const kAudioDeviceTransportTypeContinuityCaptureWireless: u32 = 0x6363776c;
pub const kAudioDeviceTransportTypeContinuityCapture: u32 = 0x63636170;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants