aaudio: implement new USAGE, CONTENT_TYPE and INPUT_PRESET
Pass these audio attributes to AudioFlinger.
Bug: 68052449
Bug: 62104146
Test: test_attributes.cpp will be moved to CTS when ready
Change-Id: Ib8804614d95dcf1b85e51ec1f5569892e017a991
diff --git a/media/libaaudio/libaaudio.map.txt b/media/libaaudio/libaaudio.map.txt
index 2ba5250..fca7b50 100644
--- a/media/libaaudio/libaaudio.map.txt
+++ b/media/libaaudio/libaaudio.map.txt
@@ -17,6 +17,9 @@
AAudioStreamBuilder_setSharingMode;
AAudioStreamBuilder_setDirection;
AAudioStreamBuilder_setBufferCapacityInFrames;
+ AAudioStreamBuilder_setUsage;
+ AAudioStreamBuilder_setContentType;
+ AAudioStreamBuilder_setInputPreset;
AAudioStreamBuilder_openStream;
AAudioStreamBuilder_delete;
AAudioStream_close;
@@ -42,6 +45,9 @@
AAudioStream_getFormat;
AAudioStream_getSharingMode;
AAudioStream_getDirection;
+ AAudioStream_getUsage;
+ AAudioStream_getContentType;
+ AAudioStream_getInputPreset;
AAudioStream_getFramesWritten;
AAudioStream_getFramesRead;
AAudioStream_getTimestamp;
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
index 153fce3..97672a0 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
@@ -50,6 +50,12 @@
if (status != NO_ERROR) goto error;
status = parcel->writeInt32(getBufferCapacity());
if (status != NO_ERROR) goto error;
+ status = parcel->writeInt32((int32_t) getUsage());
+ if (status != NO_ERROR) goto error;
+ status = parcel->writeInt32((int32_t) getContentType());
+ if (status != NO_ERROR) goto error;
+ status = parcel->writeInt32((int32_t) getInputPreset());
+ if (status != NO_ERROR) goto error;
return NO_ERROR;
error:
ALOGE("AAudioStreamConfiguration.writeToParcel(): write failed = %d", status);
@@ -69,16 +75,25 @@
setSamplesPerFrame(value);
status = parcel->readInt32(&value);
if (status != NO_ERROR) goto error;
- setSharingMode(value);
+ setSharingMode((aaudio_sharing_mode_t) value);
status = parcel->readInt32(&value);
if (status != NO_ERROR) goto error;
- setFormat(value);
+ setFormat((aaudio_format_t) value);
status = parcel->readInt32(&value);
if (status != NO_ERROR) goto error;
setDirection((aaudio_direction_t) value);
status = parcel->readInt32(&value);
if (status != NO_ERROR) goto error;
setBufferCapacity(value);
+ status = parcel->readInt32(&value);
+ if (status != NO_ERROR) goto error;
+ setUsage((aaudio_usage_t) value);
+ status = parcel->readInt32(&value);
+ if (status != NO_ERROR) goto error;
+ setContentType((aaudio_content_type_t) value);
+ status = parcel->readInt32(&value);
+ if (status != NO_ERROR) goto error;
+ setInputPreset((aaudio_input_preset_t) value);
return NO_ERROR;
error:
ALOGE("AAudioStreamConfiguration.readFromParcel(): read failed = %d", status);
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index bb007ac..9e5ca8e 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -177,6 +177,24 @@
streamBuilder->setSharingMode(sharingMode);
}
+AAUDIO_API void AAudioStreamBuilder_setUsage(AAudioStreamBuilder* builder,
+ aaudio_usage_t usage) {
+ AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+ streamBuilder->setUsage(usage);
+}
+
+AAUDIO_API void AAudioStreamBuilder_setContentType(AAudioStreamBuilder* builder,
+ aaudio_content_type_t contentType) {
+ AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+ streamBuilder->setContentType(contentType);
+}
+
+AAUDIO_API void AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder* builder,
+ aaudio_input_preset_t inputPreset) {
+ AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+ streamBuilder->setInputPreset(inputPreset);
+}
+
AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder,
int32_t frames)
{
@@ -447,6 +465,24 @@
return audioStream->getSharingMode();
}
+AAUDIO_API aaudio_usage_t AAudioStream_getUsage(AAudioStream* stream)
+{
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->getUsage();
+}
+
+AAUDIO_API aaudio_content_type_t AAudioStream_getContentType(AAudioStream* stream)
+{
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->getContentType();
+}
+
+AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* stream)
+{
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->getInputPreset();
+}
+
AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream)
{
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index 6400eb4..23c4eb8 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -42,6 +42,9 @@
mAudioFormat = other.mAudioFormat;
mDirection = other.mDirection;
mBufferCapacity = other.mBufferCapacity;
+ mUsage = other.mUsage;
+ mContentType = other.mContentType;
+ mInputPreset = other.mInputPreset;
}
aaudio_result_t AAudioStreamParameters::validate() const {
@@ -98,6 +101,54 @@
// break;
}
+ switch (mUsage) {
+ case AAUDIO_UNSPECIFIED:
+ case AAUDIO_USAGE_MEDIA:
+ case AAUDIO_USAGE_VOICE_COMMUNICATION:
+ case AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
+ case AAUDIO_USAGE_ALARM:
+ case AAUDIO_USAGE_NOTIFICATION:
+ case AAUDIO_USAGE_NOTIFICATION_RINGTONE:
+ case AAUDIO_USAGE_NOTIFICATION_EVENT:
+ case AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
+ case AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+ case AAUDIO_USAGE_ASSISTANCE_SONIFICATION:
+ case AAUDIO_USAGE_GAME:
+ case AAUDIO_USAGE_ASSISTANT:
+ break; // valid
+ default:
+ ALOGE("usage not valid = %d", mUsage);
+ return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ // break;
+ }
+
+ switch (mContentType) {
+ case AAUDIO_UNSPECIFIED:
+ case AAUDIO_CONTENT_TYPE_MUSIC:
+ case AAUDIO_CONTENT_TYPE_MOVIE:
+ case AAUDIO_CONTENT_TYPE_SONIFICATION:
+ case AAUDIO_CONTENT_TYPE_SPEECH:
+ break; // valid
+ default:
+ ALOGE("content type not valid = %d", mContentType);
+ return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ // break;
+ }
+
+ switch (mInputPreset) {
+ case AAUDIO_UNSPECIFIED:
+ case AAUDIO_INPUT_PRESET_GENERIC:
+ case AAUDIO_INPUT_PRESET_CAMCORDER:
+ case AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION:
+ case AAUDIO_INPUT_PRESET_VOICE_RECOGNITION:
+ case AAUDIO_INPUT_PRESET_UNPROCESSED:
+ break; // valid
+ default:
+ ALOGE("input preset not valid = %d", mInputPreset);
+ return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ // break;
+ }
+
return AAUDIO_OK;
}
@@ -109,5 +160,8 @@
ALOGD("mAudioFormat = %6d", (int)mAudioFormat);
ALOGD("mDirection = %6d", mDirection);
ALOGD("mBufferCapacity = %6d", mBufferCapacity);
+ ALOGD("mUsage = %6d", mUsage);
+ ALOGD("mContentType = %6d", mContentType);
+ ALOGD("mInputPreset = %6d", mInputPreset);
}
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.h b/media/libaaudio/src/core/AAudioStreamParameters.h
index 5e67c93..0c173f5 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.h
+++ b/media/libaaudio/src/core/AAudioStreamParameters.h
@@ -88,6 +88,30 @@
mDirection = direction;
}
+ aaudio_usage_t getUsage() const {
+ return mUsage;
+ }
+
+ void setUsage(aaudio_usage_t usage) {
+ mUsage = usage;
+ }
+
+ aaudio_content_type_t getContentType() const {
+ return mContentType;
+ }
+
+ void setContentType(aaudio_content_type_t contentType) {
+ mContentType = contentType;
+ }
+
+ aaudio_input_preset_t getInputPreset() const {
+ return mInputPreset;
+ }
+
+ void setInputPreset(aaudio_input_preset_t inputPreset) {
+ mInputPreset = inputPreset;
+ }
+
int32_t calculateBytesPerFrame() const {
return getSamplesPerFrame() * AAudioConvert_formatToSizeInBytes(getFormat());
}
@@ -109,6 +133,9 @@
aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
aaudio_format_t mAudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
aaudio_direction_t mDirection = AAUDIO_DIRECTION_OUTPUT;
+ aaudio_usage_t mUsage = AAUDIO_UNSPECIFIED;
+ aaudio_content_type_t mContentType = AAUDIO_UNSPECIFIED;
+ aaudio_input_preset_t mInputPreset = AAUDIO_UNSPECIFIED;
int32_t mBufferCapacity = AAUDIO_UNSPECIFIED;
};
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 8f5f5d3..289e0db 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -74,15 +74,28 @@
}
// Copy parameters from the Builder because the Builder may be deleted after this call.
+ // TODO AudioStream should be a subclass of AudioStreamParameters
mSamplesPerFrame = builder.getSamplesPerFrame();
mSampleRate = builder.getSampleRate();
mDeviceId = builder.getDeviceId();
mFormat = builder.getFormat();
mSharingMode = builder.getSharingMode();
mSharingModeMatchRequired = builder.isSharingModeMatchRequired();
-
mPerformanceMode = builder.getPerformanceMode();
+ mUsage = builder.getUsage();
+ if (mUsage == AAUDIO_UNSPECIFIED) {
+ mUsage = AAUDIO_USAGE_MEDIA;
+ }
+ mContentType = builder.getContentType();
+ if (mContentType == AAUDIO_UNSPECIFIED) {
+ mContentType = AAUDIO_CONTENT_TYPE_MUSIC;
+ }
+ mInputPreset = builder.getInputPreset();
+ if (mInputPreset == AAUDIO_UNSPECIFIED) {
+ mInputPreset = AAUDIO_INPUT_PRESET_GENERIC;
+ }
+
// callbacks
mFramesPerDataCallback = builder.getFramesPerDataCallback();
mDataCallbackProc = builder.getDataCallbackProc();
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index b5d7fd5..82e7189 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -204,6 +204,18 @@
virtual aaudio_direction_t getDirection() const = 0;
+ aaudio_usage_t getUsage() const {
+ return mUsage;
+ }
+
+ aaudio_content_type_t getContentType() const {
+ return mContentType;
+ }
+
+ aaudio_input_preset_t getInputPreset() const {
+ return mInputPreset;
+ }
+
/**
* This is only valid after setSamplesPerFrame() and setFormat() have been called.
*/
@@ -471,6 +483,9 @@
aaudio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED;
aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
+ aaudio_usage_t mUsage = AAUDIO_USAGE_MEDIA;
+ aaudio_content_type_t mContentType = AAUDIO_CONTENT_TYPE_MUSIC;
+ aaudio_input_preset_t mInputPreset = AAUDIO_INPUT_PRESET_GENERIC;
// callback ----------------------------------
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 55eed92..5f4ab9b 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -104,11 +104,24 @@
? AUDIO_PORT_HANDLE_NONE
: getDeviceId();
+ const audio_content_type_t contentType =
+ AAudioConvert_contentTypeToInternal(builder.getContentType());
+ const audio_source_t source =
+ AAudioConvert_inputPresetToAudioSource(builder.getInputPreset());
+
+ const audio_attributes_t attributes = {
+ .content_type = contentType,
+ .usage = AUDIO_USAGE_UNKNOWN, // only used for output
+ .source = source,
+ .flags = flags, // If attributes are set then the other flags parameter is ignored.
+ .tags = ""
+ };
+
mAudioRecord = new AudioRecord(
mOpPackageName // const String16& opPackageName TODO does not compile
);
mAudioRecord->set(
- AUDIO_SOURCE_VOICE_RECOGNITION,
+ AUDIO_SOURCE_DEFAULT, // ignored because we pass attributes below
getSampleRate(),
format,
channelMask,
@@ -122,7 +135,7 @@
flags,
AUDIO_UID_INVALID, // DEFAULT uid
-1, // DEFAULT pid
- NULL, // DEFAULT audio_attributes_t
+ &attributes,
selectedDeviceId
);
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 5113278..17a8d52 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -121,9 +121,22 @@
? AUDIO_PORT_HANDLE_NONE
: getDeviceId();
+ const audio_content_type_t contentType =
+ AAudioConvert_contentTypeToInternal(builder.getContentType());
+ const audio_usage_t usage =
+ AAudioConvert_usageToInternal(builder.getUsage());
+
+ const audio_attributes_t attributes = {
+ .content_type = contentType,
+ .usage = usage,
+ .source = AUDIO_SOURCE_DEFAULT, // only used for recording
+ .flags = flags, // If attributes are set then the other flags parameter is ignored.
+ .tags = ""
+ };
+
mAudioTrack = new AudioTrack();
mAudioTrack->set(
- (audio_stream_type_t) AUDIO_STREAM_MUSIC,
+ AUDIO_STREAM_DEFAULT, // ignored because we pass attributes below
getSampleRate(),
format,
channelMask,
@@ -139,7 +152,7 @@
NULL, // DEFAULT audio_offload_info_t
AUDIO_UID_INVALID, // DEFAULT uid
-1, // DEFAULT pid
- NULL, // DEFAULT audio_attributes_t
+ &attributes,
// WARNING - If doNotReconnect set true then audio stops after plugging and unplugging
// headphones a few times.
false, // DEFAULT doNotReconnect,
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index f709f41..c6adf33 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -26,6 +26,7 @@
#include "aaudio/AAudio.h"
#include <aaudio/AAudioTesting.h>
#include <math.h>
+#include <system/audio-base.h>
#include "utility/AAudioUtilities.h"
@@ -283,6 +284,61 @@
return aaudioFormat;
}
+// Make a message string from the condition.
+#define STATIC_ASSERT(condition) static_assert(condition, #condition)
+
+audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage) {
+ // The public aaudio_content_type_t constants are supposed to have the same
+ // values as the internal audio_content_type_t values.
+ STATIC_ASSERT(AAUDIO_USAGE_MEDIA == AUDIO_USAGE_MEDIA);
+ STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION == AUDIO_USAGE_VOICE_COMMUNICATION);
+ STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING
+ == AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING);
+ STATIC_ASSERT(AAUDIO_USAGE_ALARM == AUDIO_USAGE_ALARM);
+ STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION == AUDIO_USAGE_NOTIFICATION);
+ STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_RINGTONE
+ == AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE);
+ STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_EVENT == AUDIO_USAGE_NOTIFICATION_EVENT);
+ STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY);
+ STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE
+ == AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
+ STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_SONIFICATION == AUDIO_USAGE_ASSISTANCE_SONIFICATION);
+ STATIC_ASSERT(AAUDIO_USAGE_GAME == AUDIO_USAGE_GAME);
+ STATIC_ASSERT(AAUDIO_USAGE_ASSISTANT == AUDIO_USAGE_ASSISTANT);
+ if (usage == AAUDIO_UNSPECIFIED) {
+ usage = AAUDIO_USAGE_MEDIA;
+ }
+ return (audio_usage_t) usage; // same value
+}
+
+audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType) {
+ // The public aaudio_content_type_t constants are supposed to have the same
+ // values as the internal audio_content_type_t values.
+ STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MUSIC == AUDIO_CONTENT_TYPE_MUSIC);
+ STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SPEECH == AUDIO_CONTENT_TYPE_SPEECH);
+ STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SONIFICATION == AUDIO_CONTENT_TYPE_SONIFICATION);
+ STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MOVIE == AUDIO_CONTENT_TYPE_MOVIE);
+ if (contentType == AAUDIO_UNSPECIFIED) {
+ contentType = AAUDIO_CONTENT_TYPE_MUSIC;
+ }
+ return (audio_content_type_t) contentType; // same value
+}
+
+audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset) {
+ // The public aaudio_input_preset_t constants are supposed to have the same
+ // values as the internal audio_source_t values.
+ STATIC_ASSERT(AAUDIO_UNSPECIFIED == AUDIO_SOURCE_DEFAULT);
+ STATIC_ASSERT(AAUDIO_INPUT_PRESET_GENERIC == AUDIO_SOURCE_MIC);
+ STATIC_ASSERT(AAUDIO_INPUT_PRESET_CAMCORDER == AUDIO_SOURCE_CAMCORDER);
+ STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION);
+ STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION);
+ STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED);
+ if (preset == AAUDIO_UNSPECIFIED) {
+ preset = AAUDIO_INPUT_PRESET_GENERIC;
+ }
+ return (audio_source_t) preset; // same value
+}
+
int32_t AAudioConvert_framesToBytes(int32_t numFrames,
int32_t bytesPerFrame,
int32_t *sizeInBytes) {
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index 3afa976..f2347f5 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -167,6 +167,29 @@
aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t format);
+
+/**
+ * Note that this function does not validate the passed in value.
+ * That is done somewhere else.
+ * @return internal value
+ */
+
+audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage);
+
+/**
+ * Note that this function does not validate the passed in value.
+ * That is done somewhere else.
+ * @return internal value
+ */
+audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType);
+
+/**
+ * Note that this function does not validate the passed in value.
+ * That is done somewhere else.
+ * @return internal audio source
+ */
+audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset);
+
/**
* @return the size of a sample of the given format in bytes or AAUDIO_ERROR_ILLEGAL_ARGUMENT
*/