aaudio: add support for 24 and 32 bit PCM
Add new formats: AAUDIO_FORMAT_PCM_I24_PACKED
and AAUDIO_FORMAT_PCM_I32.
Pass formats to Legacy AudioTrack and AuddioRecord.
Request 24_PACKED in AAudio Service for MMAP streams.
Also add a flowgraph module for converting the I32 data
to/from FLOAT.
Bug: 65067568
Bug: 157671580
Test: To determine which format the MMAP path is using for the DSP,
Test: adb shell dumpsys media.aaudio
Test: then look for the "Exclusive MMAP Endpoints" and "Format:".
Test: The formats listed are the internal AudioFlinger formats:
Test: 1=16_BIT, 3=32_BIT, 4=8_24_BIT, 5=FLOAT, 6=24_BIT_PACKED
Test: atest AAudioTestCases
Test: adb shell write_sine_callback -? # to list new formats
Test: adb shell write_sine_callback -pl -f3 # MMAP LOWLAT I24_PACKED
Test: adb shell write_sine_callback -pl -f4 # MMAP LOWLAT I32
Test: # Legacy LOWLAT I24_PACKED
Test: adb shell write_sine_callback -pl -f3 -m1
Test: adb shell write_sine_callback -pl -f4 -m1 # Legacy LOWLAT I32
Test: adb shell write_sine_callback -pn -f3 # Legacy I24_PACKED
Test: adb shell write_sine_callback -pn -f4 # Legacy I32
Change-Id: Ibe13bfd54425d110f50f89eb10c63872a2f99839
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 5bccfd5..85b2057 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -72,24 +72,46 @@
aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamRequest &request) {
aaudio_result_t result = AAUDIO_OK;
- audio_config_base_t config;
- audio_port_handle_t deviceId;
-
copyFrom(request.getConstantConfiguration());
-
- const audio_attributes_t attributes = getAudioAttributesFrom(this);
-
mMmapClient.clientUid = request.getUserId();
mMmapClient.clientPid = request.getProcessId();
mMmapClient.packageName.setTo(String16(""));
+ audio_format_t audioFormat = getFormat();
+
+ // FLOAT is not directly supported by the HAL so ask for a 24-bit.
+ bool isHighResRequested = audioFormat == AUDIO_FORMAT_PCM_FLOAT
+ || audioFormat == AUDIO_FORMAT_PCM_32_BIT;
+ if (isHighResRequested) {
+ // TODO remove these logs when finished debugging.
+ ALOGD("%s() change format from %d to 24_BIT_PACKED", __func__, audioFormat);
+ audioFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ }
+
+ result = openWithFormat(audioFormat);
+ if (result == AAUDIO_OK) return result;
+
+ // TODO The HAL and AudioFlinger should be recommending a format if the open fails.
+ // But that recommendation is not propagating back from the HAL.
+ // So for now just try something very likely to work.
+ if (result == AAUDIO_ERROR_UNAVAILABLE && audioFormat == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
+ ALOGD("%s() 24_BIT failed, perhaps due to format. Try again with 16_BIT", __func__);
+ audioFormat = AUDIO_FORMAT_PCM_16_BIT;
+ result = openWithFormat(audioFormat);
+ }
+ return result;
+}
+
+aaudio_result_t AAudioServiceEndpointMMAP::openWithFormat(audio_format_t audioFormat) {
+ aaudio_result_t result = AAUDIO_OK;
+ audio_config_base_t config;
+ audio_port_handle_t deviceId;
+
+ const audio_attributes_t attributes = getAudioAttributesFrom(this);
+
mRequestedDeviceId = deviceId = getDeviceId();
// Fill in config
- audio_format_t audioFormat = getFormat();
- if (audioFormat == AUDIO_FORMAT_DEFAULT || audioFormat == AUDIO_FORMAT_PCM_FLOAT) {
- audioFormat = AUDIO_FORMAT_PCM_16_BIT;
- }
config.format = audioFormat;
int32_t aaudioSampleRate = getSampleRate();