Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use audio workgroups for supernova DSP thread pool. #5624

Open
Spacechild1 opened this issue Nov 26, 2021 · 3 comments
Open

Use audio workgroups for supernova DSP thread pool. #5624

Spacechild1 opened this issue Nov 26, 2021 · 3 comments

Comments

@Spacechild1
Copy link
Contributor

macOS 11 has a new API for managing audio threads that cooperate with each other. I think this would be appropriate for supernova's DSP thread pool.

Here's an introduction: https://developer.apple.com/documentation/audiotoolbox/workgroup_management/understanding_audio_workgroups

And here's a code example which might be relevant for our use case: https://developer.apple.com/documentation/audiotoolbox/workgroup_management/adding_parallel_real-time_threads_to_audio_workgroups

Should be rather simple to implement. I just don't have access to a macOS 11 machine.

@scztt
Copy link
Contributor

scztt commented Feb 28, 2023

I looked at this last summer. Unfortunately, the new API's require access to specific CoreAudio objects in order to set the workgroup properties. This is a problem for two reasons:

  1. supernova is built on top of PortAudio, and we have very little access to platform-specific objects and data via the PortAudio API (by design: it's an audio hardware abstraction). While we MIGHT be able to root around and find the right CoreAudio object we need on the SuperCollider side (though I couldn't immediately see how), this still probably belongs in PortAudio in the end anyway, since it IS supposed to abstract platform details from the client code.
  2. It was not obvious how to get the right CoreAudio objects required for the workspace API's from the objects that PortAudio creates in it's MacOS implementation (see https://developer.apple.com/documentation/apple-silicon/porting-your-audio-code-to-apple-silicon#Prioritize-Realtime-Threads-Using-Workgroups). Probably there IS a way to do this, but it was not obvious and would likely require some substantial code change.

Sadly there is no mention of this on the PortAudio github, and indeed there are many years-old MacOS issues open in that repo, and it doesn't seem like the platform is very actively maintained.

@Spacechild1
Copy link
Contributor Author

Spacechild1 commented Feb 28, 2023

Hi Scott, thanks for looking into this!

supernova is built on top of PortAudio, and we have very little access to platform-specific objects and data via the PortAudio API (by design: it's an audio hardware abstraction).

FWIW, portaudio offers platform specific extension APIs, e.g. pa_asio.h, pa_jack.h, pa_linux_alsa.h, pa_mac_core.h, etc. (https://github.com/PortAudio/portaudio/tree/master/include)

In fact, pa_win_wasapi.h even has a method for accessing the underlying native objects:
https://github.com/PortAudio/portaudio/blob/5b5feb3a331b674cfc71009414514000685bf547/include/pa_win_wasapi.h#L354-L362

A similar function for CoreAudio might already be sufficient. On the other hand, something like PaMacCore_GetWorkgroup() might be even better.

@scztt
Copy link
Contributor

scztt commented Mar 3, 2023

IIRC We would need access to the AudioUnit, which has a property corresponding to the correct os_workgroup_t (which is in turn the key to the rest of the important workgroup API's). The mac-specific API's only expose a AudioDeviceID - it wasn't obvious to me what the relationship between this and an AudioUnit, and whether we could get one from another. Without that, it would be straightforward enough to add a way to access the os_workgroup_t via a mac-specific PortAudio API's, but obviously this would need to be added to PA.

I seem to recall that there were a few confounding factors to making this work, but ultimately I think whatever part of PA has access to the AudioUnit could in turn supply the workgroup. Given that there's a separate in and out device, I was never totally sure what the relationship between the workgroups for these is: my assumption is that an in and out device both being used by the same process would have the same workgroup, but the fact that you can fetch the workgroup property of each of these separately make it feel like... I was possibly misinterpreting this.

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

No branches or pull requests

2 participants