oboe
oboe copied to clipboard
setPreferredMixerAttributes for non-USB devices
After the discussion in #2190 I was thinking about setPreferredMixerAttributes, and I was wondering why only USB devices are supported. It seems to be on purpose, but not really a inherent limitation of the approach as all devices have mix port profiles, hence I was wondering what the background was.
Right now, audio policy's decision to always open mix ports at highest rate creates some awkward situations; When I play a 44.1kHz audio file in power saving mode (but not compressed offload), and I have attached AAC bluetooth headphones in A2DP offload mode, on my Pixel 7a we will get a useless double-conversion: deep buffer mix port is always opened at 48kHz, hence AF has to upsample my track, and AoC has to downsample again because the AAC codec operates at 44.1kHz via bluetooth. If the audio HAL declared 44100 sample rate, that situation would nontheless not improve because policy always prefers 48000 because it's higher. But if HAL declared 44100 and 48000, and setPreferredMixerAttributes was allowed for all device types, the app could ask policy to set sample rate to 44100 instead and the double conversion would be avoided. I'm not sure if there's another elegant solution to that problem.
After the discussion in https://github.com/google/oboe/issues/2190 I was thinking about setPreferredMixerAttributes, and I was wondering why only USB devices are supported.
Because it is originally designed for hifi mix port, which is a common use case for USB device. As it is also mentioned above, audio framework prefer highest sample rate, highest channel count, highest bit depth when opening hifi mix port. Before the preferred mixer attributes API, the audio framework will only open hifi mix port once when there is new device connected. The playback thread will be suspend if there is not active client attached to it. This helps save communication to the HAL and hardware. By this design, it is better to open the mix port at highest configuration so that clients streaming hi-res content won't be converted to lower resolution. But we also see problems that lots of music app want to stream at 44.1kHz instead of 48kHz. That is why the preferred mixer attributes is created.
Right now, audio policy's decision to always open mix ports at highest rate creates some awkward situations; When I play a 44.1kHz audio file in power saving mode (but not compressed offload), and I have attached AAC bluetooth headphones in A2DP offload mode, on my Pixel 7a we will get a useless double-conversion: deep buffer mix port is always opened at 48kHz, hence AF has to upsample my track, and AoC has to downsample again because the AAC codec operates at 44.1kHz via bluetooth.
For power saving mode, aaudio prefers to use deep buffer, which will allow CPU to suspend for a longer time for saving power. On Pixel 7a, the deep buffer is only at 48kHz so that the framework will only open it at 48kHz.
There are lots of hardware design that will cause devices have different capabilities. The framework have no control about the device capabilities.
For the 44.1kHz and 48kHz deep buffer, it is theoretically possible to solve with current implementation, but will require work from the Android manufacturers side. Imagine there is a device report two mix ports with deep buffer flag and one at 44.1kHz and one at 48kHz, which can both connected to A2DP device port. In this case, if the client streams 44.1kHz content and asks for deep buffer, it will be played via the 44.1kHz deep buffer mix port and 48kHz clients will be played via 48kHz deep buffer mix port.
and setPreferredMixerAttributes was allowed for all device types
There is also some internal discussion about making this happens. Will keep this updated.