[vlc-devel] Interesting issue with Mac audio devices

Ron Frederick ronf at timeheart.net
Mon Sep 3 23:55:37 CEST 2012

Hi Felix,

Thanks for the quick response! See my answers inline below.

On Sep 3, 2012, at 10:46 AM, Felix Paul Kühne <fkuehne.videolan at gmail.com> wrote:
> On 03.09.2012, at 18:53, Ron Frederick wrote:
>> Now that I'm using HDMI audio out from my Mac to my TV, I've noticed an interesting problem with VLC. Whenever I power the TV on & off, the Mac loses track of the audio device corresponding to the HDMI audio out.
> This is fixed in the current development source for VLC 2.0.4 and 2.1.

I see. I just tried downloading the latest 2.0.4 nightly build from http://nightlies.videolan.org/build/macosx-intel/?C=M;O=D (from August 30th), but the 32-bit version seems to crash on me when I tell it to stop playing. I don't see a recent 64-bit binary there -- the last one seems to be from back in July. Is there another place I can look for recent binaries?

I also made an attempt to update my git repo and build from source, but I haven't done this for a year or so and I'm now running Xcode 4.4.1. I don't think I even have the 10.5 or 10.6 SDKs installed on this machine now that I'm running 10.8. Are there patches available for getting VLC to build with the latest Xcode?

>> Later, when the TV is turned back on, a new audio device is added, but it has a different device ID than it did before. 
> This sounds like a bug to me. Not in VLC though, but in CoreAudio. Which OS X version do you use?

I'm running the latest - 10.8.1 build 12819, on a 3.4 GHz Core i7 27" mid-2011 iMac.

>> This issue with device IDs not being stable also affects the VLC preferences for default audio device. [...cut...] VLC does this by adding 0xF00000 to the device ID, and you so end up with a preference value of something like 15728712 (0xF00048) if the device ID you want is 0x48.
> This is not VLC, but CoreAudio, all we are storing is the AudioDeviceID provided by the AudioUnit API (see modules/audio_output/auhal.c:313).

The 0xF00000 constant I mentioned is named AOUT_VAR_SPDIF_FLAG in this file, and seems to be a VLC-specific thing. It is actually masked off by VLC before passing the device ID to CoreAudio, but the fact that it is set is then used to set the "b_supports_digital" flag. Here's a snippet from auhal.c:202:

    p_sys->i_selected_dev = val.i_int & ~AOUT_VAR_SPDIF_FLAG; /* remove SPDIF flag to get the true DeviceID */
    bool b_supports_digital = (val.i_int & AOUT_VAR_SPDIF_FLAG);
    if (b_supports_digital)
        msg_Dbg(p_aout, "audio device supports digital output");

This is set in the Probe() function:

        if (AudioDeviceSupportsDigital(p_aout, p_devices[i])) {
            val.i_int = (int)p_devices[i] | AOUT_VAR_SPDIF_FLAG;
            if (asprintf(&text.psz_string, _("%s (Encoded Output)"), psz_name) != -1) {
                var_Change(p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
                if (p_sys->i_default_dev == p_devices[i] && var_InheritBool(p_aout, "spdif")) {
                    /* We selected to prefer SPDIF output if available
                     * then this "dummy" entry should be selected */
                    var_Change(p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL);
                    var_Set(p_aout, "audio-device", val);

The device IDs not being stable is definitely a CoreAudio problem, but I've seen it now on multiple platforms, making me think Apple really doesn't make any guarantees here. Even before I began using the iMac's HDMI audio output, I used to occasionally see this problem with the optical digital audio out on my first-gen (2006 era) Mac Pro. It seemed that on boot the devices were not always added in a consistent order, and so it was somewhat random whether my VLC preference for the default audio device was honored or not after a reboot.

>> It would be great if VLC could store the preferred audio device as something like a string value, matching what appears in the "Audio Device" menu.
> This sounds like a hack to me, since what we display is a so-called "user-readible string" provided by the AudioUnit API. I doubt that there is a clean way to see which user-string patches which AudioDeviceID. An AudioDeviceID is required to set the kAudioOutputUnitProperty_CurrentDevice property correctly to choose the physical audio output device to use.
>> That way, each time it begins a new playback, it could iterate through all of the currently available audio devices and try to match the value the user had selected before, even if the device ID had changed.
> See above, this doesn't sound particularly clean to me.
> For multiple screens, we basically have the same situation: you can select your default fullscreen device, which could be an external screen. Let's assume it is one. If you unplug and start a clip, VLC will be play on the internal screen (fallback). If you take your Mac to a friend's place, attach a different external screen, VLC will play on the internal screen (fallback), since the external screens don't have the same ID. However, if you're finally heading home and attach your default device, it will play on the external screen again. CoreAudio, in fact, is supposed to work exactly the same way.

Yeah - so far, I've had fairly good luck with the screen numbers being consistent from one reboot to the next. For audio, though, there seems to be no guarantee even without a reboot. For instance, HALLab currently reports my HDMI audio output as 0x53, but when I first booted the system it was 0x48. By switching inputs on the TV away from the Mac and back, I was able to get the device ID on the Mac to change from 0x53 to 0x57. Switching away & back again changed the device ID again, to 0x5B.

>> Also, since there are separate menu items in this menu for the "encoded output" of devices capable of that, it would avoid the issue above about needing to know the VLC internal device numbering for that.
> Well, this setting is not supposed to be user-settable, precisely for the fact that no-one is usually able to predict the AudioDeviceID.

Understood, but it is a very useful thing to be able to set, especially in an application like mine where I really want VLC to always output to my TV for both full-screen video and audio. I don't mind it falling back if the TV isn't currently attached to the Mac, but otherwise I'd really like to find a way to make it always select that by default.

I completely admit that the string comparison I was suggesting is a hack. However, that string does appear to be stable, unlike the device IDs, and in my experience so far it appears to be unique at least among the built-in Apple audio outputs. I don't know for sure if you had multiple USB audio outputs of the same type whether the name would still be unique, but I'm basically looking for a way to have the preferences remember the equivalent of what the user is selecting from the "Audio Device" menu in the UI, in as reliable a fashion as possible given that the set of attached devices could change from one run to the next.
Ron Frederick
ronf at timeheart.net

More information about the vlc-devel mailing list