AudioDriverKit on iPadOS: USB transport classification breaks audio routing while Thunderbolt works — MIDI remains functional

I'm developing custom AudioDriverKit and MIDI DriverKit drivers for a hardware audio-MIDI device on an M-series iPad.

I've encountered a reproducible issue where advertising the audio device's correct USB transport type prevents iPadOS from making the device available to audio applications, whereas advertising Thunderbolt allows it to function.

I've previously reported this issue through Feedback Assistant but have not received a response: FB25067968.

Environment

  • Hardware: BOSS SY-1000 connected to an M-series iPad via Apple USB-C Digital AV Multiport Adapter
  • Audio: 48 kHz, eight inputs and eight outputs, interleaved Float32
  • DriverKit SDK: 27.0
  • Xcode: 27.1
  • Minimum iPadOS: 18.0
  • AudioDriverKit deployment target: 21.0
  • Separate AudioDriverKit and MIDI DriverKit extensions using USBDriverKit
  • Proprietary USB isochronous audio transport

The SY-1000 is a USB device, not a Thunderbolt device. The physical USB connection and hardware configuration remain unchanged between tests.

Audio behavior

Configuration A — Transport type: Thunderbolt

When the audio device advertises IOUserAudioTransportType::Thunderbolt:

  • The audio driver loads and registers.
  • iPadOS makes the device available to audio applications.
  • StartDevice/StartIO is invoked.
  • Eight-channel audio input and output function.

This has been our established working configuration.

Configuration B — Transport type: USB

Changing the two transport-type assignments to IOUserAudioTransportType::USB results in:

  • Driver initialization succeeds.
  • AddObject succeeds.
  • RegisterService succeeds.
  • HAL successfully establishes its user-client connection.
  • HAL recognizes the 48 kHz, eight-channel Float32 formats.
  • iPadOS audio-route creation fails.
  • The audio device is unavailable to audio applications.
  • StartDevice/StartIO is never invoked.
  • No USB audio transfers occur.

MIDI continues working

The SY-1000's MIDI functionality remains available even when the audio device disappears.

The project uses a separate MIDI DriverKit extension, attached to the SY-1000's MIDI USB interface.

Under the failing USB audio-transport configuration:

  • The SY-1000 remains physically connected and enumerated over USB.
  • The separate MIDI driver continues to be detected.
  • MIDI functionality remains available to MIDI-capable applications.
  • Only the AudioDriverKit device fails to become available as an audio interface.

This is an important distinction: the SY-1000 has not disappeared from the USB system. The problem appears specific to AudioDriverKit/Core Audio device routing

Changing the two transport-type assignments to IOUserAudioTransportType::USB results in:

So, I think the next steps here are:

  • Capture and I/O Registry snapshot so you can see what the state of the driver stack actually "is".

  • Take a close look at the console log during the initialization sequence to see if you can determine whats different between the two cases.

I don't know what's going wrong, but my guess is that it's something more complicated/strange thats only indirectly tied to the specific transport change.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thanks, Kevin. The retained filtered console export shows a more specific failure during initialization.

With USB transport advertised, the driver registers successfully, HAL connects, and Core Audio accepts the audio formats. The subsequent route-construction path in audiomxd/VirtualAudio.plugin logs Unhandled UID for the SY-1000 audio device, followed by 'who?' (kAudioHardwareUnknownPropertyError). Audio I/O never starts. The log does not identify the property involved.

A comparison build was made using the same toolchain, with only the two transport assignments restored to Thunderbolt, apart from version stamps. Audio visibility returned and I/O could start, although other startup reliability issues remained.

Does that error sequence suggest a particular property or registration requirement that should be checked?

The original .logarchive could not be located, but the filtered console export from that capture has been preserved. I have attached it directly to this reply as four numbered .txt files, each under 10 MB. The split preserves complete log records, and the files can be read individually or concatenated in numerical order.

The related Feedback Assistant report is FB25067968.

Also, what is the recommended way to capture an I/O Registry snapshot from the iPad?

FB25067968-SY1000-Filtered-Console-Export-20261016-Part-01-of-04.txt(9.0 MB)
FB25067968-SY1000-Filtered-Console-Export-20261016-Part-02-of-04.txt(9.0 MB)
FB25067968-SY1000-Filtered-Console-Export-20261016-Part-03-of-04.txt(9.0 MB)
FB25067968-SY1000-Filtered-Console-Export-20261016-Part-04-of-04.txt(1.4 MB)

Thanks, Kevin.

The USB transport and service-termination discussions have become a little intertwined, so I'm responding here to the IOMatchCategory question in your latest reply in the IOService::Stop thread, to keep the USB transport findings together.

Yes, both DEXT personalities in the original build associated with FB25067968 included private IOMatchCategory values. I've now read your DEXT matching guide and the relevant IOKit Fundamentals documentation. You're right that these categories were inappropriate for the USB providers.

I've since removed both categories and completed two controlled tests on the iPad:

  • Setup108: With the categories removed and Thunderbolt still advertised as the audio transport type, both DEXTs attached to their intended USB providers. The registry showed exclusive ownership with no additional attached driver in the captured SY-1000 subtree. Audio appeared in AUM and worked correctly, as did MIDI.
  • Setup109: Starting from that working source, I changed only the two AudioDriverKit transport declarations from Thunderbolt to USB, apart from build identifiers. Both DEXTs still attached correctly. Audio initialization, AddObject, RegisterService and HAL user-client connection succeeded, and MIDI remained available. However, SY-1000 disappeared from AUM, with no StartDevice, StartIO or audio transfers recorded.

To clarify my original report, the physical connection has always been USB through Apple's USB-C adapter. Only the AudioDriverKit transport-type property changes between these configurations.

The private matching categories were therefore a genuine configuration mistake, now corrected, but the latest evidence suggests they do not explain the remaining USB-advertised audio-visibility failure.

I have retained I/O Registry snapshots and sysdiagnoses for both tests. Given that the intended driver attachments and HAL connection succeed in the failing configuration, is there a particular AudioDriverKit/Core Audio publication or routing requirement you would recommend examining next?

I'll keep the remaining IOOperationHandler lifetime question separate from this investigation.

Thanks again,

Luke

***AUM = the host iPadOS application that the driver serves audio-MIDI to.

So, before I get into any specifics, I want to suggest that you consider at least testing on macOS, if not switching to macOS as your "primary" testing/development platform. Note that I'm NOT suggesting you make a macOS product. I'd of course be happy if you did, but my recommendation here is ENTIRELY about helping your development process, not the product you eventually ship.

I have an extended post on this issue here, but the basic issue is that additional friction and opaqueness of iPadOS are SO high that it's basically "always" better to develop and test on macOS and then "port" to iPadOS, instead of directly targeting iPadOS.

You're already experiencing these issues. Monitoring the I/O Registry's state is a critical diagnostic tool. On iPadOS, thats a 20min process of collecting a sysdiagnose. On macOS, it's effectively instantaneous by either running "ioreg" or by using IORegistryExplorer.app to watch it "live". That's one example among MANY. I push hard on this issue because many developers feel/assume that supporting macOS is just adding extra work for no reason and, in my experience, that could not be more wrong.

I've since removed both categories and completed two controlled tests on the iPad:

Ruling out one easy mistake, did you reboot between the two tests? One common mistake I've seen in a host of different context is repeating the same testing process multiple times without realizing that the testing order ITSELF was a critical factor in the issue.

In my favorite example, I used to routinely get issues/complaints about how Maps was able to get the user location SO much faster than their app, with the assumption being that Maps was using some secret API/trick to work better. What was actually happening is that they consistently tested by launching their app, waiting for the users location, then launching Maps. And, yes, Maps was ABSOLUTELY faster. Their app turned on the GPS hardware, got the coordinate, and then Maps used the same coordinate they'd just retrieved.

Exactly the same kind of issues can happen with DriverKit if your driver isn't unloading completely "clean", as the configuration from the previous run disrupts the next run.

I have retained I/O Registry snapshots and sysdiagnoses for both tests. Given that the intended driver attachments and HAL connection succeed in the failing configuration, is there a particular AudioDriverKit/Core Audio publication or routing requirement you would recommend examining next?

So, I don't have any specific suggestion, but here's the general process:

(1) Check the registry across the full lifecycle

That means comparing three registry states for both configuration:

  1. The registry state before your device attached.

  2. The registry state with the device attached and your drive loaded.

  3. The registry state after the device was removed.

The key here is that 1 & 2 should be "the same" and that #2 should "look right". Next, you should also compare the registry states of your two configurations ("USB" and "Thunderbolt"), focussing not just on your immediate driver, but also on the configuration of everything that attached above your driver.

(2) Compare the two console runs.

So, the first thing here is to simply look at everything you're logging. The log I saw couldn't really be analyzed due to redaction, but the logging I outlined here show you clearly logging "something" and it's worth understanding what that is.

Related to that point, there's another basic question I'd overlooked- why is your DEXT exiting? Regardless of what the audio system does, I'd expect/assume you're DEXT would "own" your hardware, so it would state active as long as the device was attached, regardless of what the audio system did. Am I missing something about your architecture? Why is your DEXT going away so quickly?

Finally, what's left is comparing the working and failing console logs. There's obviously a lot of unrelated component noise, but with a bit of care you can generally line up the to logs against each other, synchronize the two logs based on logging that's common to both logs, then move forward in time until the logs diverge. Wherever they diverged is going to be your best clue as to what's going wrong.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

As a first strike, I've completed some additional physical testing to investigate whether the audio publication failure could be caused by retained device state or the absence of a reboot.

The results are consistent across two independent M-series iPads:

  1. M1 iPad Pro: The USB transport configuration continued to fail after a full reboot. The SY-1000 did not appear as an audio device in the DAW/host.

  2. M3 iPad Air: I repeated the test on a second iPad that had never previously had the driver installed. Both the Audio and MIDI DriverKit extensions installed and activated successfully, but the SY-1000 again failed to appear as an audio device in the DAW/host.

For comparison, the Thunderbolt transport configuration continues to provide functional eight-channel audio on the M1 iPad Pro.

These results make retained device registration or the absence of a reboot less likely explanations. The underlying difference in audio publication remains unresolved.

Regarding your other observations:

  • Unexpected DEXT termination: I haven't yet established why the extension appears to terminate while the USB device remains physically attached. I agree that this behaviour warrants investigation independently of whether Core Audio successfully publishes the device.
  • I/O Registry: A complete comparison of the working and failing configurations, including the services above the driver and their state throughout attachment and removal, remains to be completed.
  • Console logs: I also agree that identifying the first meaningful divergence between the two configurations is important. I haven't yet isolated a definitive divergence that explains the publication failure.

Given these outstanding questions, I intend to follow your recommendation to investigate the same DriverKit implementation on macOS. This should provide better visibility into service attachment, termination, the I/O Registry hierarchy and Core Audio publication, while also helping establish whether the behaviour is specific to iPadOS.

One practical concern I'd like to mention is that this approach can be quite restrictive for independent developers without access to multiple Macs. In my case, I already have the manufacturer's fully functional SY-1000 driver installed on my development Mac. Isolating that driver and switching between configurations introduces additional complications and risks disrupting an otherwise working audio environment. I certainly appreciate the diagnostic advantages of macOS, but I wanted to highlight the practical difficulties involved.

The ultimate objective remains a functional iPadOS driver, but using macOS as a diagnostic environment seems to be the most logical next step. Thanks again for your time and insights.