I am writing a (native, C) Python extension for macOS which uses the AudioUnit APIs, loading and using AudioUnit components. The Python extension is a dynamic library which is loaded by the Python interpreter (/usr/bin/python), with the code residing in the interpreter's memory space.
I have noticed that, when my code running within Python attempts to load AudioUnit components, it sees far fewer components than there are available on the system. The code works perfectly well when running in its own process, in a dynamic library loaded with dlopen into another test program, or a subprocess launched from the Python interpreter with os.system. For example, this code for counting the AudioUnits available on the system:
When I run it within the Python extension, it reports 111 components found, most of which are standard Apple AudioUnits. When I run this code otherwise, it reports considerably more components (300+, which includes third-party AudioUnits installed on the machine it is running on). Attempting to load AudioUnits that are not among the 111 also fails within the Python extension.
My questions are: why do the AudioToolbox APIs only see a subset of AudioUnits when called from a Python extension, and how can I mitigate this to access all AudioUnits available on the system? (I'm guessing it is not sandboxing, as in the cases I've tested, the binaries are raw MACH-O binaries, rather than app bundles with signatures or entitlements.)
I have noticed that, when my code running within Python attempts to load AudioUnit components, it sees far fewer components than there are available on the system. The code works perfectly well when running in its own process, in a dynamic library loaded with dlopen into another test program, or a subprocess launched from the Python interpreter with os.system. For example, this code for counting the AudioUnits available on the system:
Code Block AudioComponentDescription desc = { 0, 0, 0, 0, 0 }; AudioComponent last = nil; int count = 0; do { last = AudioComponentFindNext(last, &desc); if (last) { count += 1; } } while (last != nil); printf("Found %d components\n", count);
When I run it within the Python extension, it reports 111 components found, most of which are standard Apple AudioUnits. When I run this code otherwise, it reports considerably more components (300+, which includes third-party AudioUnits installed on the machine it is running on). Attempting to load AudioUnits that are not among the 111 also fails within the Python extension.
My questions are: why do the AudioToolbox APIs only see a subset of AudioUnits when called from a Python extension, and how can I mitigate this to access all AudioUnits available on the system? (I'm guessing it is not sandboxing, as in the cases I've tested, the binaries are raw MACH-O binaries, rather than app bundles with signatures or entitlements.)