← Back to context

Comment by gok

5 months ago

The common form of this bug is way older than 10 years and isn't really specific to macOS.

The problem is that audio devices do not have an explicit concept of "balance". It's set by adjusting the level of each channel. That volume adjusting process is not reliable. It often happens over an unreliable interface where some volume adjustments are just dropped. This hits a second problem: the audio device often has the ability to adjust its levels out of band with the host audio stack. Thus your laptop has to periodically poll the device to find out what the current actual audio levels are. When your laptop sees that the volume per channel is not equal, it doesn't know if this was caused by the device itself adjusting the balance or the volume adjustment message being ignored.

So for example:

1. User tells laptop to increase volume from 50% to 60%

2. Laptop tells device's right channel to go to 60% (success)

3. Laptop tells device's left channel to go to 60% (failure)

4. Laptop checks with audio device, sees 60% on right and 50% on left

5. Laptop changes audio balance to be nudged to the right

There are some ways to mitigate the problem. The audio stack could try to detect when its level commands are being dropped, but that risks the audio stack and device "fighting" over the correct volume. Better closer-to-realtime scheduling can reduce the risk of messages being dropped.

Not sure if that's related to Apple's original problem, but in the scenario you are describing, the fix is trivial: detect when level commands are dropped and retry (up to N times / for up to X milliseconds). And don't forget to check existing volume between steps 1 and 2, so you can be made sure what the previous state was.

I don't think the "fighting" will be a problem at all - you'd have to to press volume control on device and on Mac at the same time, within milliseconds. And in the worst case, you'll run out of retries, and it will be no worse than situation today.

  • Who should detect, who should retry, and how?

    I don’t know the macOS audio stack in detail, but I work on state synchronization problems in distributed systems and my intuition for problems like this is that the “why not just” solution almost never solves such a bug completely.

    • This is not a distributed system though, it's a local device, attached by USB or on some bus. So: who should detect? device driver. Who should retry? also device driver. How? by re-issuing the same request.

      I've made drivers for badly designed hardware, and it's really not not that hard when you control the pieces. I mean, if it was Windows with all that backwards compatibility stuff and drivers written by 3rd party manufacturer than sure, it could be hard.. but Apple controls entire software stack, so they have no such excuse.

      And the most important part is that the problem is very error-tolerant. Sure, having random balance change once per day is super annoying. But instead, imagine having one random volume change command per day be ignored.. People would not even notice, it would be a great improvement.

      1 reply →