diff --git a/core/api/current.txt b/core/api/current.txt index f2eb59bb5534f..2f01265a26ac6 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -22635,16 +22635,32 @@ package android.media { field public static final String KEY_VIDEO_QP_P_MIN = "video-qp-p-min"; field public static final String KEY_WIDTH = "width"; field public static final String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm"; + field public static final String MIMETYPE_AUDIO_AAC_ELD = "audio/mp4a.40.39"; + field public static final String MIMETYPE_AUDIO_AAC_HE_V1 = "audio/mp4a.40.05"; + field public static final String MIMETYPE_AUDIO_AAC_HE_V2 = "audio/mp4a.40.29"; + field public static final String MIMETYPE_AUDIO_AAC_LC = "audio/mp4a.40.02"; + field public static final String MIMETYPE_AUDIO_AAC_XHE = "audio/mp4a.40.42"; field public static final String MIMETYPE_AUDIO_AC3 = "audio/ac3"; field public static final String MIMETYPE_AUDIO_AC4 = "audio/ac4"; field public static final String MIMETYPE_AUDIO_AMR_NB = "audio/3gpp"; field public static final String MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb"; + field public static final String MIMETYPE_AUDIO_DOLBY_MAT = "audio/vnd.dolby.mat"; + field public static final String MIMETYPE_AUDIO_DOLBY_TRUEHD = "audio/vnd.dolby.mlp"; + field public static final String MIMETYPE_AUDIO_DRA = "audio/vnd.dra"; + field public static final String MIMETYPE_AUDIO_DTS = "audio/vnd.dts"; + field public static final String MIMETYPE_AUDIO_DTS_HD = "audio/vnd.dts.hd"; + field public static final String MIMETYPE_AUDIO_DTS_UHD = "audio/vnd.dts.uhd"; field public static final String MIMETYPE_AUDIO_EAC3 = "audio/eac3"; field public static final String MIMETYPE_AUDIO_EAC3_JOC = "audio/eac3-joc"; field public static final String MIMETYPE_AUDIO_FLAC = "audio/flac"; field public static final String MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw"; field public static final String MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw"; + field public static final String MIMETYPE_AUDIO_IEC61937 = "audio/x-iec61937"; field public static final String MIMETYPE_AUDIO_MPEG = "audio/mpeg"; + field public static final String MIMETYPE_AUDIO_MPEGH_BL_L3 = "audio/mhm1.03"; + field public static final String MIMETYPE_AUDIO_MPEGH_BL_L4 = "audio/mhm1.04"; + field public static final String MIMETYPE_AUDIO_MPEGH_LC_L3 = "audio/mhm1.0d"; + field public static final String MIMETYPE_AUDIO_MPEGH_LC_L4 = "audio/mhm1.0e"; field public static final String MIMETYPE_AUDIO_MPEGH_MHA1 = "audio/mha1"; field public static final String MIMETYPE_AUDIO_MPEGH_MHM1 = "audio/mhm1"; field public static final String MIMETYPE_AUDIO_MSGSM = "audio/gsm"; diff --git a/core/java/android/hardware/soundtrigger/ConversionUtil.java b/core/java/android/hardware/soundtrigger/ConversionUtil.java index ad0dc0965b0ae..35a974b6f57e0 100644 --- a/core/java/android/hardware/soundtrigger/ConversionUtil.java +++ b/core/java/android/hardware/soundtrigger/ConversionUtil.java @@ -18,6 +18,7 @@ package android.hardware.soundtrigger; import android.annotation.Nullable; import android.media.AudioFormat; +import android.media.audio.common.AidlConversion; import android.media.audio.common.AudioConfig; import android.media.soundtrigger.AudioCapabilities; import android.media.soundtrigger.ConfidenceLevel; @@ -197,7 +198,8 @@ class ConversionUtil { int modelHandle, int captureSession, RecognitionEvent aidlEvent) { // The API recognition event doesn't allow for a null audio format, even though it doesn't // always make sense. We thus replace it with a default. - AudioFormat audioFormat = aidl2apiAudioFormatWithDefault(aidlEvent.audioConfig); + AudioFormat audioFormat = aidl2apiAudioFormatWithDefault( + aidlEvent.audioConfig, true /*isInput*/); return new SoundTrigger.GenericRecognitionEvent( aidlEvent.status, modelHandle, aidlEvent.captureAvailable, captureSession, @@ -215,7 +217,8 @@ class ConversionUtil { } // The API recognition event doesn't allow for a null audio format, even though it doesn't // always make sense. We thus replace it with a default. - AudioFormat audioFormat = aidl2apiAudioFormatWithDefault(aidlEvent.common.audioConfig); + AudioFormat audioFormat = aidl2apiAudioFormatWithDefault( + aidlEvent.common.audioConfig, true /*isInput*/); return new SoundTrigger.KeyphraseRecognitionEvent(aidlEvent.common.status, modelHandle, aidlEvent.common.captureAvailable, captureSession, aidlEvent.common.captureDelayMs, @@ -224,107 +227,15 @@ class ConversionUtil { apiExtras); } - public static AudioFormat aidl2apiAudioFormat(AudioConfig audioConfig) { - AudioFormat.Builder apiBuilder = new AudioFormat.Builder(); - apiBuilder.setSampleRate(audioConfig.sampleRateHz); - apiBuilder.setChannelMask(aidl2apiChannelInMask(audioConfig.channelMask)); - apiBuilder.setEncoding(aidl2apiEncoding(audioConfig.format)); - return apiBuilder.build(); - } - - // Same as above, but in case of a null input returns a non-null valid output. - public static AudioFormat aidl2apiAudioFormatWithDefault(@Nullable AudioConfig audioConfig) { + // In case of a null input returns a non-null valid output. + public static AudioFormat aidl2apiAudioFormatWithDefault( + @Nullable AudioConfig audioConfig, boolean isInput) { if (audioConfig != null) { - return aidl2apiAudioFormat(audioConfig); + return AidlConversion.aidl2api_AudioConfig_AudioFormat(audioConfig, isInput); } return new AudioFormat.Builder().build(); } - public static int aidl2apiEncoding(int aidlFormat) { - switch (aidlFormat) { - case android.media.audio.common.AudioFormat.PCM - | android.media.audio.common.AudioFormat.PCM_SUB_16_BIT: - return AudioFormat.ENCODING_PCM_16BIT; - - case android.media.audio.common.AudioFormat.PCM - | android.media.audio.common.AudioFormat.PCM_SUB_8_BIT: - return AudioFormat.ENCODING_PCM_8BIT; - - case android.media.audio.common.AudioFormat.PCM - | android.media.audio.common.AudioFormat.PCM_SUB_FLOAT: - case android.media.audio.common.AudioFormat.PCM - | android.media.audio.common.AudioFormat.PCM_SUB_8_24_BIT: - case android.media.audio.common.AudioFormat.PCM - | android.media.audio.common.AudioFormat.PCM_SUB_24_BIT_PACKED: - case android.media.audio.common.AudioFormat.PCM - | android.media.audio.common.AudioFormat.PCM_SUB_32_BIT: - return AudioFormat.ENCODING_PCM_FLOAT; - - case android.media.audio.common.AudioFormat.AC3: - return AudioFormat.ENCODING_AC3; - - case android.media.audio.common.AudioFormat.E_AC3: - return AudioFormat.ENCODING_E_AC3; - - case android.media.audio.common.AudioFormat.DTS: - return AudioFormat.ENCODING_DTS; - - case android.media.audio.common.AudioFormat.DTS_HD: - return AudioFormat.ENCODING_DTS_HD; - - case android.media.audio.common.AudioFormat.MP3: - return AudioFormat.ENCODING_MP3; - - case android.media.audio.common.AudioFormat.AAC - | android.media.audio.common.AudioFormat.AAC_SUB_LC: - return AudioFormat.ENCODING_AAC_LC; - - case android.media.audio.common.AudioFormat.AAC - | android.media.audio.common.AudioFormat.AAC_SUB_HE_V1: - return AudioFormat.ENCODING_AAC_HE_V1; - - case android.media.audio.common.AudioFormat.AAC - | android.media.audio.common.AudioFormat.AAC_SUB_HE_V2: - return AudioFormat.ENCODING_AAC_HE_V2; - - case android.media.audio.common.AudioFormat.IEC61937: - return AudioFormat.ENCODING_IEC61937; - - case android.media.audio.common.AudioFormat.DOLBY_TRUEHD: - return AudioFormat.ENCODING_DOLBY_TRUEHD; - - case android.media.audio.common.AudioFormat.AAC - | android.media.audio.common.AudioFormat.AAC_SUB_ELD: - return AudioFormat.ENCODING_AAC_ELD; - - case android.media.audio.common.AudioFormat.AAC - | android.media.audio.common.AudioFormat.AAC_SUB_XHE: - return AudioFormat.ENCODING_AAC_XHE; - - case android.media.audio.common.AudioFormat.AC4: - return AudioFormat.ENCODING_AC4; - - case android.media.audio.common.AudioFormat.E_AC3 - | android.media.audio.common.AudioFormat.E_AC3_SUB_JOC: - return AudioFormat.ENCODING_E_AC3_JOC; - - case android.media.audio.common.AudioFormat.MAT: - case android.media.audio.common.AudioFormat.MAT - | android.media.audio.common.AudioFormat.MAT_SUB_1_0: - case android.media.audio.common.AudioFormat.MAT - | android.media.audio.common.AudioFormat.MAT_SUB_2_0: - case android.media.audio.common.AudioFormat.MAT - | android.media.audio.common.AudioFormat.MAT_SUB_2_1: - return AudioFormat.ENCODING_DOLBY_MAT; - - case android.media.audio.common.AudioFormat.DEFAULT: - return AudioFormat.ENCODING_DEFAULT; - - default: - return AudioFormat.ENCODING_INVALID; - } - } - public static int api2aidlModelParameter(int apiParam) { switch (apiParam) { case ModelParams.THRESHOLD_FACTOR: @@ -334,12 +245,6 @@ class ConversionUtil { } } - public static int aidl2apiChannelInMask(int aidlMask) { - // We're assuming AudioFormat.CHANNEL_IN_* constants are kept in sync with - // android.media.audio.common.AudioChannelMask. - return aidlMask; - } - public static SoundTrigger.ModelParamRange aidl2apiModelParameterRange( @Nullable ModelParameterRange aidlRange) { if (aidlRange == null) { diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 0d7d8f812880a..21a327c4959a0 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -162,6 +162,7 @@ cc_library_shared { "android_util_CharsetUtils.cpp", "android_util_MemoryIntArray.cpp", "android_util_Process.cpp", + "android_media_audio_common_AidlConversion.cpp", "android_media_AudioDeviceAttributes.cpp", "android_media_AudioEffectDescriptor.cpp", "android_media_AudioRecord.cpp", @@ -242,6 +243,7 @@ cc_library_shared { ], shared_libs: [ + "android.media.audio.common.types-V1-cpp", "audioclient-types-aidl-cpp", "audioflinger-aidl-cpp", "audiopolicy-types-aidl-cpp", @@ -288,6 +290,7 @@ cc_library_shared { "libmediametrics", "libmeminfo", "libaudioclient", + "libaudioclient_aidl_conversion", "libaudiofoundation", "libaudiopolicy", "libusbhost", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 5e11b6a427e56..91179c2770120 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -98,6 +98,7 @@ extern int register_android_media_AudioVolumeGroups(JNIEnv *env); extern int register_android_media_AudioVolumeGroupChangeHandler(JNIEnv *env); extern int register_android_media_MicrophoneInfo(JNIEnv *env); extern int register_android_media_ToneGenerator(JNIEnv *env); +extern int register_android_media_audio_common_AidlConversion(JNIEnv* env); extern int register_android_media_midi(JNIEnv *env); namespace android { @@ -1618,6 +1619,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_media_MicrophoneInfo), REG_JNI(register_android_media_RemoteDisplay), REG_JNI(register_android_media_ToneGenerator), + REG_JNI(register_android_media_audio_common_AidlConversion), REG_JNI(register_android_media_midi), REG_JNI(register_android_opengl_classes), diff --git a/core/jni/android_media_audio_common_AidlConversion.cpp b/core/jni/android_media_audio_common_AidlConversion.cpp new file mode 100644 index 0000000000000..6dcaf76d6b571 --- /dev/null +++ b/core/jni/android_media_audio_common_AidlConversion.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "AidlConversion" + +#include +#include +#include +#include +#include +#include + +#include "core_jni_helpers.h" + +namespace { + +using namespace android; + +#define PACKAGE "android/media/audio/common" +#define CLASSNAME PACKAGE "/AidlConversion" + +template +int aidl2legacy(JNIEnv* env, jobject clazz, jobject jParcel, const ConvFunc& conv, + int fallbackValue) { + if (Parcel* parcel = parcelForJavaObject(env, jParcel); parcel != nullptr) { + AidlType aidl{}; + if (status_t status = aidl.readFromParcel(parcel); status == OK) { + auto legacy = conv(aidl); + if (legacy.ok()) { + return legacy.value(); + } + } else { + ALOGE("aidl2legacy: Failed to read from parcel: %d", status); + } + } else { + ALOGE("aidl2legacy: Failed to retrieve the native parcel from Java parcel"); + } + return fallbackValue; +} + +template +jobject legacy2aidl(JNIEnv* env, jobject clazz, LegacyType legacy, const ConvFunc& conv) { + auto aidl = conv(legacy); + if (!aidl.ok()) { + return 0; + } + if (jobject jParcel = createJavaParcelObject(env); jParcel != 0) { + if (Parcel* parcel = parcelForJavaObject(env, jParcel); parcel != nullptr) { + if (status_t status = aidl.value().writeToParcel(parcel); status == OK) { + parcel->setDataPosition(0); + return jParcel; + } + } else { + ALOGE("legacy2aidl: Failed to retrieve the native parcel from Java parcel"); + } + env->DeleteLocalRef(jParcel); + } else { + ALOGE("legacy2aidl: Failed to create Java parcel"); + } + return 0; +} + +int aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t(JNIEnv* env, jobject clazz, + jobject jParcel, jboolean isInput) { + return aidl2legacy( + env, clazz, jParcel, + [isInput](const media::audio::common::AudioChannelLayout& l) { + return aidl2legacy_AudioChannelLayout_audio_channel_mask_t(l, isInput); + }, + AUDIO_CHANNEL_INVALID); +} + +jobject legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel( + JNIEnv* env, jobject clazz, int /*audio_channel_mask_t*/ legacy, jboolean isInput) { + return legacy2aidl( + env, clazz, static_cast(legacy), + [isInput](audio_channel_mask_t m) { + return legacy2aidl_audio_channel_mask_t_AudioChannelLayout(m, isInput); + }); +} + +int aidl2legacy_AudioFormatDescription_Parcel_audio_format_t(JNIEnv* env, jobject clazz, + jobject jParcel) { + return aidl2legacy< + media::audio::common:: + AudioFormatDescription>(env, clazz, jParcel, + aidl2legacy_AudioFormatDescription_audio_format_t, + AUDIO_FORMAT_INVALID); +} + +jobject legacy2aidl_audio_format_t_AudioFormatDescription_Parcel(JNIEnv* env, jobject clazz, + int /*audio_format_t*/ legacy) { + return legacy2aidl(env, clazz, static_cast(legacy), + legacy2aidl_audio_format_t_AudioFormatDescription); +} + +const JNINativeMethod gMethods[] = { + {"aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t", "(Landroid/os/Parcel;Z)I", + reinterpret_cast(aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t)}, + {"legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel", "(IZ)Landroid/os/Parcel;", + reinterpret_cast(legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel)}, + {"aidl2legacy_AudioFormatDescription_Parcel_audio_format_t", "(Landroid/os/Parcel;)I", + reinterpret_cast(aidl2legacy_AudioFormatDescription_Parcel_audio_format_t)}, + {"legacy2aidl_audio_format_t_AudioFormatDescription_Parcel", "(I)Landroid/os/Parcel;", + reinterpret_cast(legacy2aidl_audio_format_t_AudioFormatDescription_Parcel)}, +}; + +} // namespace + +int register_android_media_audio_common_AidlConversion(JNIEnv* env) { + return RegisterMethodsOrDie(env, CLASSNAME, gMethods, NELEM(gMethods)); +} diff --git a/media/Android.bp b/media/Android.bp index cf4a0b1005d70..82d61601f580f 100644 --- a/media/Android.bp +++ b/media/Android.bp @@ -35,6 +35,7 @@ aidl_interface { "aidl/android/media/soundtrigger_middleware/SoundTriggerModuleDescriptor.aidl", ], imports: [ + "android.media.audio.common.types", "android.media.soundtrigger.types", "media_permission-aidl", ], @@ -45,20 +46,29 @@ aidl_interface { vendor_available: true, host_supported: true, double_loadable: true, - flags: ["-Werror", "-Weverything", ], + flags: [ + "-Werror", + "-Weverything", + ], local_include_dir: "aidl", srcs: [ - "aidl/android/media/audio/common/AudioChannelMask.aidl", + "aidl/android/media/audio/common/AudioChannelLayout.aidl", "aidl/android/media/audio/common/AudioConfig.aidl", - "aidl/android/media/audio/common/AudioFormat.aidl", + "aidl/android/media/audio/common/AudioFormatDescription.aidl", + "aidl/android/media/audio/common/AudioFormatType.aidl", "aidl/android/media/audio/common/AudioOffloadInfo.aidl", "aidl/android/media/audio/common/AudioStreamType.aidl", "aidl/android/media/audio/common/AudioUsage.aidl", + "aidl/android/media/audio/common/PcmType.aidl", ], stability: "vintf", backend: { cpp: { - enabled: true, + min_sdk_version: "29", + apex_available: [ + "//apex_available:platform", + "com.android.media", + ], }, java: { sdk_version: "module_current", @@ -74,7 +84,10 @@ aidl_interface { aidl_interface { name: "android.media.soundtrigger.types", vendor_available: true, - flags: ["-Werror", "-Weverything", ], + flags: [ + "-Werror", + "-Weverything", + ], local_include_dir: "aidl", srcs: [ "aidl/android/media/soundtrigger/AudioCapabilities.aidl", diff --git a/media/aidl/android/media/audio/common/AudioChannelLayout.aidl b/media/aidl/android/media/audio/common/AudioChannelLayout.aidl new file mode 100644 index 0000000000000..4f34372ae2a1f --- /dev/null +++ b/media/aidl/android/media/audio/common/AudioChannelLayout.aidl @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.audio.common; + +/** + * This structure describes a layout of a multi-channel stream. + * There are two possible ways for representing a layout: + * + * - indexed mask, which tells what channels of an audio frame are used, but + * doesn't label them in any way, thus a correspondence between channels in + * the same position of frames originating from different streams must be + * established externally; + * + * - layout mask, which gives a label to each channel, thus allowing to + * match channels between streams of different layouts. + * + * Both representations are agnostic of the direction of audio transfer. Also, + * by construction, the number of bits set to '1' in the mask indicates the + * number of channels in the audio frame. A channel mask per se only defines the + * presence or absence of a channel, not the order. Please see 'INTERLEAVE_*' + * constants for the platform convention of order. + * + * The structure also defines a "voice mask" which is a special case of + * layout mask, intended for processing voice audio from telecommunication + * use cases. + * + * {@hide} + */ +@JavaDerive(equals = true, toString = true) +@VintfStability +union AudioChannelLayout { + /** + * This variant is used for representing the "null" ("none") value + * for the channel layout. The field value must always be '0'. + */ + int none = 0; + /** + * This variant is used for indicating an "invalid" layout for use by the + * framework only. HAL implementations must not accept or emit + * AudioChannelLayout values for this variant. The field value must always + * be '0'. + */ + int invalid = 0; + /** + * This variant is used for representing indexed masks. The mask indicates + * what channels are used. For example, the mask that specifies to use only + * channels 1 and 3 when interacting with a multi-channel device is defined + * as a combination of the 1st and the 3rd bits and thus is equal to 5. See + * also the 'INDEX_MASK_*' constants. The 'indexMask' field must have at + * least one bit set. + */ + int indexMask; + /** + * This variant is used for representing layout masks. + * It is recommended to use one of 'LAYOUT_*' values. The 'layoutMask' field + * must have at least one bit set. + */ + int layoutMask; + /** + * This variant is used for processing of voice audio input and output. + * It is recommended to use one of 'VOICE_*' values. The 'voiceMask' field + * must have at least one bit set. + */ + int voiceMask; + + /** + * 'INDEX_MASK_*' constants define how many channels are used. + * The mask constants below are 'canonical' masks. Each 'INDEX_MASK_N' + * constant declares that all N channels are used and arranges + * them starting from the LSB. + */ + const int INDEX_MASK_1 = (1 << 1) - 1; + const int INDEX_MASK_2 = (1 << 2) - 1; + const int INDEX_MASK_3 = (1 << 3) - 1; + const int INDEX_MASK_4 = (1 << 4) - 1; + const int INDEX_MASK_5 = (1 << 5) - 1; + const int INDEX_MASK_6 = (1 << 6) - 1; + const int INDEX_MASK_7 = (1 << 7) - 1; + const int INDEX_MASK_8 = (1 << 8) - 1; + const int INDEX_MASK_9 = (1 << 9) - 1; + const int INDEX_MASK_10 = (1 << 10) - 1; + const int INDEX_MASK_11 = (1 << 11) - 1; + const int INDEX_MASK_12 = (1 << 12) - 1; + const int INDEX_MASK_13 = (1 << 13) - 1; + const int INDEX_MASK_14 = (1 << 14) - 1; + const int INDEX_MASK_15 = (1 << 15) - 1; + const int INDEX_MASK_16 = (1 << 16) - 1; + const int INDEX_MASK_17 = (1 << 17) - 1; + const int INDEX_MASK_18 = (1 << 18) - 1; + const int INDEX_MASK_19 = (1 << 19) - 1; + const int INDEX_MASK_20 = (1 << 20) - 1; + const int INDEX_MASK_21 = (1 << 21) - 1; + const int INDEX_MASK_22 = (1 << 22) - 1; + const int INDEX_MASK_23 = (1 << 23) - 1; + const int INDEX_MASK_24 = (1 << 24) - 1; + + /** + * 'LAYOUT_*' constants define channel layouts recognized by + * the audio system. The order of the channels in the frame is assumed + * to be from the LSB to MSB for all the bits set to '1'. + */ + const int LAYOUT_MONO = CHANNEL_FRONT_LEFT; + const int LAYOUT_STEREO = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT; + const int LAYOUT_2POINT1 = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_LOW_FREQUENCY; + const int LAYOUT_TRI = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER; + const int LAYOUT_TRI_BACK = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_BACK_CENTER; + const int LAYOUT_3POINT1 = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER | + CHANNEL_LOW_FREQUENCY; + const int LAYOUT_2POINT0POINT2 = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT; + const int LAYOUT_2POINT1POINT2 = + LAYOUT_2POINT0POINT2 | CHANNEL_LOW_FREQUENCY; + const int LAYOUT_3POINT0POINT2 = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_FRONT_CENTER | + CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT; + const int LAYOUT_3POINT1POINT2 = + LAYOUT_3POINT0POINT2 | CHANNEL_LOW_FREQUENCY; + const int LAYOUT_QUAD = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT; + const int LAYOUT_QUAD_SIDE = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT; + const int LAYOUT_SURROUND = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER; + const int LAYOUT_PENTA = LAYOUT_QUAD | CHANNEL_FRONT_CENTER; + const int LAYOUT_5POINT1 = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | + CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT; + const int LAYOUT_5POINT1_SIDE = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | + CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT; + const int LAYOUT_5POINT1POINT2 = LAYOUT_5POINT1 | + CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT; + const int LAYOUT_5POINT1POINT4 = LAYOUT_5POINT1 | + CHANNEL_TOP_FRONT_LEFT | CHANNEL_TOP_FRONT_RIGHT | + CHANNEL_TOP_BACK_LEFT | CHANNEL_TOP_BACK_RIGHT; + const int LAYOUT_6POINT1 = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | + CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT | CHANNEL_BACK_CENTER; + const int LAYOUT_7POINT1 = LAYOUT_5POINT1 | + CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT; + const int LAYOUT_7POINT1POINT2 = LAYOUT_7POINT1 | + CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT; + const int LAYOUT_7POINT1POINT4 = LAYOUT_7POINT1 | + CHANNEL_TOP_FRONT_LEFT | CHANNEL_TOP_FRONT_RIGHT | + CHANNEL_TOP_BACK_LEFT | CHANNEL_TOP_BACK_RIGHT; + const int LAYOUT_9POINT1POINT4 = LAYOUT_7POINT1POINT4 | + CHANNEL_FRONT_WIDE_LEFT | CHANNEL_FRONT_WIDE_RIGHT; + const int LAYOUT_9POINT1POINT6 = LAYOUT_9POINT1POINT4 | + CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT; + const int LAYOUT_13POINT_360RA = + CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_FRONT_CENTER | + CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT | + CHANNEL_TOP_FRONT_LEFT | CHANNEL_TOP_FRONT_RIGHT | + CHANNEL_TOP_FRONT_CENTER | + CHANNEL_TOP_BACK_LEFT | CHANNEL_TOP_BACK_RIGHT | + CHANNEL_BOTTOM_FRONT_LEFT | CHANNEL_BOTTOM_FRONT_RIGHT | + CHANNEL_BOTTOM_FRONT_CENTER; + const int LAYOUT_22POINT2 = LAYOUT_7POINT1POINT4 | + CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER | + CHANNEL_BACK_CENTER | CHANNEL_TOP_CENTER | + CHANNEL_TOP_FRONT_CENTER | CHANNEL_TOP_BACK_CENTER | + CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT | + CHANNEL_BOTTOM_FRONT_LEFT | CHANNEL_BOTTOM_FRONT_RIGHT | + CHANNEL_BOTTOM_FRONT_CENTER | + CHANNEL_LOW_FREQUENCY_2; + const int LAYOUT_MONO_HAPTIC_A = + LAYOUT_MONO | CHANNEL_HAPTIC_A; + const int LAYOUT_STEREO_HAPTIC_A = + LAYOUT_STEREO | CHANNEL_HAPTIC_A; + const int LAYOUT_HAPTIC_AB = + CHANNEL_HAPTIC_A | CHANNEL_HAPTIC_B; + const int LAYOUT_MONO_HAPTIC_AB = + LAYOUT_MONO | LAYOUT_HAPTIC_AB; + const int LAYOUT_STEREO_HAPTIC_AB = + LAYOUT_STEREO | LAYOUT_HAPTIC_AB; + const int LAYOUT_FRONT_BACK = + CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER; + + /** + * Expresses the convention when stereo audio samples are stored interleaved + * in an array. This should improve readability by allowing code to use + * symbolic indices instead of hard-coded [0] and [1]. + * + * For multi-channel beyond stereo, the platform convention is that channels + * are interleaved in order from least significant channel mask bit to most + * significant channel mask bit, with unused bits skipped. Any exceptions + * to this convention will be noted at the appropriate API. + */ + const int INTERLEAVE_LEFT = 0; + const int INTERLEAVE_RIGHT = 1; + + /** + * 'CHANNEL_*' constants are used to build 'LAYOUT_*' masks. Each constant + * must have exactly one bit set. The values do not match + * 'android.media.AudioFormat.CHANNEL_OUT_*' constants from the SDK + * for better efficiency in masks processing. + */ + const int CHANNEL_FRONT_LEFT = 1 << 0; + const int CHANNEL_FRONT_RIGHT = 1 << 1; + const int CHANNEL_FRONT_CENTER = 1 << 2; + const int CHANNEL_LOW_FREQUENCY = 1 << 3; + const int CHANNEL_BACK_LEFT = 1 << 4; + const int CHANNEL_BACK_RIGHT = 1 << 5; + const int CHANNEL_FRONT_LEFT_OF_CENTER = 1 << 6; + const int CHANNEL_FRONT_RIGHT_OF_CENTER = 1 << 7; + const int CHANNEL_BACK_CENTER = 1 << 8; + const int CHANNEL_SIDE_LEFT = 1 << 9; + const int CHANNEL_SIDE_RIGHT = 1 << 10; + const int CHANNEL_TOP_CENTER = 1 << 11; + const int CHANNEL_TOP_FRONT_LEFT = 1 << 12; + const int CHANNEL_TOP_FRONT_CENTER = 1 << 13; + const int CHANNEL_TOP_FRONT_RIGHT = 1 << 14; + const int CHANNEL_TOP_BACK_LEFT = 1 << 15; + const int CHANNEL_TOP_BACK_CENTER = 1 << 16; + const int CHANNEL_TOP_BACK_RIGHT = 1 << 17; + const int CHANNEL_TOP_SIDE_LEFT = 1 << 18; + const int CHANNEL_TOP_SIDE_RIGHT = 1 << 19; + const int CHANNEL_BOTTOM_FRONT_LEFT = 1 << 20; + const int CHANNEL_BOTTOM_FRONT_CENTER = 1 << 21; + const int CHANNEL_BOTTOM_FRONT_RIGHT = 1 << 22; + const int CHANNEL_LOW_FREQUENCY_2 = 1 << 23; + const int CHANNEL_FRONT_WIDE_LEFT = 1 << 24; + const int CHANNEL_FRONT_WIDE_RIGHT = 1 << 25; + /** + * Haptic channels are not part of multichannel standards, however they + * enhance user experience when playing so they are packed together with the + * channels of the program. To avoid collision with positional channels the + * values for haptic channels start at the MSB of an integer (after the sign + * bit) and move down to LSB. + */ + const int CHANNEL_HAPTIC_B = 1 << 29; + const int CHANNEL_HAPTIC_A = 1 << 30; + + /** + * 'VOICE_*' constants define layouts for voice audio. The order of the + * channels in the frame is assumed to be from the LSB to MSB for all the + * bits set to '1'. + */ + const int VOICE_UPLINK_MONO = CHANNEL_VOICE_UPLINK; + const int VOICE_DNLINK_MONO = CHANNEL_VOICE_DNLINK; + const int VOICE_CALL_MONO = CHANNEL_VOICE_UPLINK | CHANNEL_VOICE_DNLINK; + + /** + * 'CHANNEL_VOICE_*' constants are used to build 'VOICE_*' masks. Each + * constant must have exactly one bit set. Use the same values as + * 'android.media.AudioFormat.CHANNEL_IN_VOICE_*' constants from the SDK. + */ + const int CHANNEL_VOICE_UPLINK = 0x4000; + const int CHANNEL_VOICE_DNLINK = 0x8000; +} diff --git a/media/aidl/android/media/audio/common/AudioChannelMask.aidl b/media/aidl/android/media/audio/common/AudioChannelMask.aidl deleted file mode 100644 index 17be8dd5461f7..0000000000000 --- a/media/aidl/android/media/audio/common/AudioChannelMask.aidl +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - // This file has been semi-automatically generated using hidl2aidl from its counterpart in - // hardware/interfaces/audio/common/5.0/types.hal - -package android.media.audio.common; - -/** - * A channel mask per se only defines the presence or absence of a channel, not - * the order. - * - * The channel order convention is that channels are interleaved in order from - * least significant channel mask bit to most significant channel mask bit, - * with unused bits skipped. For example for stereo, LEFT would be first, - * followed by RIGHT. - * Any exceptions to this convention are noted at the appropriate API. - * - * AudioChannelMask is an opaque type and its internal layout should not be - * assumed as it may change in the future. Instead, always use functions - * to examine it. - * - * These are the current representations: - * - * REPRESENTATION_POSITION - * is a channel mask representation for position assignment. Each low-order - * bit corresponds to the spatial position of a transducer (output), or - * interpretation of channel (input). The user of a channel mask needs to - * know the context of whether it is for output or input. The constants - * OUT_* or IN_* apply to the bits portion. It is not permitted for no bits - * to be set. - * - * REPRESENTATION_INDEX - * is a channel mask representation for index assignment. Each low-order - * bit corresponds to a selected channel. There is no platform - * interpretation of the various bits. There is no concept of output or - * input. It is not permitted for no bits to be set. - * - * All other representations are reserved for future use. - * - * Warning: current representation distinguishes between input and output, but - * this will not the be case in future revisions of the platform. Wherever there - * is an ambiguity between input and output that is currently resolved by - * checking the channel mask, the implementer should look for ways to fix it - * with additional information outside of the mask. - * - * TODO: this should be replaced with strings or other mechanisms that are easy to extend, in line - * with the audio HAL conventions. - * {@hide} - */ -@VintfStability -@Backing(type="int") -enum AudioChannelMask { - /** - * must be 0 for compatibility - */ - REPRESENTATION_POSITION = 0, - /** - * 1 is reserved for future use - */ - REPRESENTATION_INDEX = 2, - /** - * 3 is reserved for future use - * - * - * These can be a complete value of AudioChannelMask - */ - NONE = 0x0, - INVALID = 0xC0000000, - /** - * These can be the bits portion of an AudioChannelMask - * with representation REPRESENTATION_POSITION. - * - * - * output channels - */ - OUT_FRONT_LEFT = 0x1, - OUT_FRONT_RIGHT = 0x2, - OUT_FRONT_CENTER = 0x4, - OUT_LOW_FREQUENCY = 0x8, - OUT_BACK_LEFT = 0x10, - OUT_BACK_RIGHT = 0x20, - OUT_FRONT_LEFT_OF_CENTER = 0x40, - OUT_FRONT_RIGHT_OF_CENTER = 0x80, - OUT_BACK_CENTER = 0x100, - OUT_SIDE_LEFT = 0x200, - OUT_SIDE_RIGHT = 0x400, - OUT_TOP_CENTER = 0x800, - OUT_TOP_FRONT_LEFT = 0x1000, - OUT_TOP_FRONT_CENTER = 0x2000, - OUT_TOP_FRONT_RIGHT = 0x4000, - OUT_TOP_BACK_LEFT = 0x8000, - OUT_TOP_BACK_CENTER = 0x10000, - OUT_TOP_BACK_RIGHT = 0x20000, - OUT_TOP_SIDE_LEFT = 0x40000, - OUT_TOP_SIDE_RIGHT = 0x80000, - /** - * Haptic channel characteristics are specific to a device and - * only used to play device specific resources (eg: ringtones). - * The HAL can freely map A and B to haptic controllers, the - * framework shall not interpret those values and forward them - * from the device audio assets. - */ - OUT_HAPTIC_A = 0x20000000, - OUT_HAPTIC_B = 0x10000000, - - OUT_MONO = OUT_FRONT_LEFT, - OUT_STEREO = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT), - OUT_2POINT1 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_LOW_FREQUENCY), - OUT_2POINT0POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT), - OUT_2POINT1POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT | OUT_LOW_FREQUENCY), - OUT_3POINT0POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER | OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT), - OUT_3POINT1POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER | OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT | OUT_LOW_FREQUENCY), - OUT_QUAD = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_BACK_LEFT | OUT_BACK_RIGHT), - OUT_QUAD_BACK = OUT_QUAD, - /** - * like OUT_QUAD_BACK with *_SIDE_* instead of *_BACK_* - */ - OUT_QUAD_SIDE = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_SIDE_LEFT | OUT_SIDE_RIGHT), - OUT_SURROUND = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER | OUT_BACK_CENTER), - OUT_PENTA = (OUT_QUAD | OUT_FRONT_CENTER), - OUT_5POINT1 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER | OUT_LOW_FREQUENCY | OUT_BACK_LEFT | OUT_BACK_RIGHT), - OUT_5POINT1_BACK = OUT_5POINT1, - /** - * like OUT_5POINT1_BACK with *_SIDE_* instead of *_BACK_* - */ - OUT_5POINT1_SIDE = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER | OUT_LOW_FREQUENCY | OUT_SIDE_LEFT | OUT_SIDE_RIGHT), - OUT_5POINT1POINT2 = (OUT_5POINT1 | OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT), - OUT_5POINT1POINT4 = (OUT_5POINT1 | OUT_TOP_FRONT_LEFT | OUT_TOP_FRONT_RIGHT | OUT_TOP_BACK_LEFT | OUT_TOP_BACK_RIGHT), - OUT_6POINT1 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER | OUT_LOW_FREQUENCY | OUT_BACK_LEFT | OUT_BACK_RIGHT | OUT_BACK_CENTER), - /** - * matches the correct AudioFormat.CHANNEL_OUT_7POINT1_SURROUND - */ - OUT_7POINT1 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER | OUT_LOW_FREQUENCY | OUT_BACK_LEFT | OUT_BACK_RIGHT | OUT_SIDE_LEFT | OUT_SIDE_RIGHT), - OUT_7POINT1POINT2 = (OUT_7POINT1 | OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT), - OUT_7POINT1POINT4 = (OUT_7POINT1 | OUT_TOP_FRONT_LEFT | OUT_TOP_FRONT_RIGHT | OUT_TOP_BACK_LEFT | OUT_TOP_BACK_RIGHT), - OUT_MONO_HAPTIC_A = (OUT_FRONT_LEFT | OUT_HAPTIC_A), - OUT_STEREO_HAPTIC_A = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_HAPTIC_A), - OUT_HAPTIC_AB = (OUT_HAPTIC_A | OUT_HAPTIC_B), - OUT_MONO_HAPTIC_AB = (OUT_FRONT_LEFT | OUT_HAPTIC_A | OUT_HAPTIC_B), - OUT_STEREO_HAPTIC_AB = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_HAPTIC_A | OUT_HAPTIC_B), - - /** - * These are bits only, not complete values - * - * - * input channels - */ - IN_LEFT = 0x4, - IN_RIGHT = 0x8, - IN_FRONT = 0x10, - IN_BACK = 0x20, - IN_LEFT_PROCESSED = 0x40, - IN_RIGHT_PROCESSED = 0x80, - IN_FRONT_PROCESSED = 0x100, - IN_BACK_PROCESSED = 0x200, - IN_PRESSURE = 0x400, - IN_X_AXIS = 0x800, - IN_Y_AXIS = 0x1000, - IN_Z_AXIS = 0x2000, - IN_BACK_LEFT = 0x10000, - IN_BACK_RIGHT = 0x20000, - IN_CENTER = 0x40000, - IN_LOW_FREQUENCY = 0x100000, - IN_TOP_LEFT = 0x200000, - IN_TOP_RIGHT = 0x400000, - IN_VOICE_UPLINK = 0x4000, - IN_VOICE_DNLINK = 0x8000, -// TODO(ytai): Aliases not currently supported in AIDL - can inline the values. -// IN_MONO = IN_FRONT, -// IN_STEREO = (IN_LEFT | IN_RIGHT), -// IN_FRONT_BACK = (IN_FRONT | IN_BACK), -// IN_6 = (IN_LEFT | IN_RIGHT | IN_FRONT | IN_BACK | IN_LEFT_PROCESSED | IN_RIGHT_PROCESSED), -// IN_2POINT0POINT2 = (IN_LEFT | IN_RIGHT | IN_TOP_LEFT | IN_TOP_RIGHT), -// IN_2POINT1POINT2 = (IN_LEFT | IN_RIGHT | IN_TOP_LEFT | IN_TOP_RIGHT | IN_LOW_FREQUENCY), -// IN_3POINT0POINT2 = (IN_LEFT | IN_CENTER | IN_RIGHT | IN_TOP_LEFT | IN_TOP_RIGHT), -// IN_3POINT1POINT2 = (IN_LEFT | IN_CENTER | IN_RIGHT | IN_TOP_LEFT | IN_TOP_RIGHT | IN_LOW_FREQUENCY), -// IN_5POINT1 = (IN_LEFT | IN_CENTER | IN_RIGHT | IN_BACK_LEFT | IN_BACK_RIGHT | IN_LOW_FREQUENCY), -// IN_VOICE_UPLINK_MONO = (IN_VOICE_UPLINK | IN_MONO), -// IN_VOICE_DNLINK_MONO = (IN_VOICE_DNLINK | IN_MONO), -// IN_VOICE_CALL_MONO = (IN_VOICE_UPLINK_MONO | IN_VOICE_DNLINK_MONO), -// COUNT_MAX = 30, -// INDEX_HDR = REPRESENTATION_INDEX << COUNT_MAX, -// INDEX_MASK_1 = INDEX_HDR | ((1 << 1) - 1), -// INDEX_MASK_2 = INDEX_HDR | ((1 << 2) - 1), -// INDEX_MASK_3 = INDEX_HDR | ((1 << 3) - 1), -// INDEX_MASK_4 = INDEX_HDR | ((1 << 4) - 1), -// INDEX_MASK_5 = INDEX_HDR | ((1 << 5) - 1), -// INDEX_MASK_6 = INDEX_HDR | ((1 << 6) - 1), -// INDEX_MASK_7 = INDEX_HDR | ((1 << 7) - 1), -// INDEX_MASK_8 = INDEX_HDR | ((1 << 8) - 1), -// INDEX_MASK_9 = INDEX_HDR | ((1 << 9) - 1), -// INDEX_MASK_10 = INDEX_HDR | ((1 << 10) - 1), -// INDEX_MASK_11 = INDEX_HDR | ((1 << 11) - 1), -// INDEX_MASK_12 = INDEX_HDR | ((1 << 12) - 1), -// INDEX_MASK_13 = INDEX_HDR | ((1 << 13) - 1), -// INDEX_MASK_14 = INDEX_HDR | ((1 << 14) - 1), -// INDEX_MASK_15 = INDEX_HDR | ((1 << 15) - 1), -// INDEX_MASK_16 = INDEX_HDR | ((1 << 16) - 1), -// INDEX_MASK_17 = INDEX_HDR | ((1 << 17) - 1), -// INDEX_MASK_18 = INDEX_HDR | ((1 << 18) - 1), -// INDEX_MASK_19 = INDEX_HDR | ((1 << 19) - 1), -// INDEX_MASK_20 = INDEX_HDR | ((1 << 20) - 1), -// INDEX_MASK_21 = INDEX_HDR | ((1 << 21) - 1), -// INDEX_MASK_22 = INDEX_HDR | ((1 << 22) - 1), -// INDEX_MASK_23 = INDEX_HDR | ((1 << 23) - 1), -// INDEX_MASK_24 = INDEX_HDR | ((1 << 24) - 1), -} diff --git a/media/aidl/android/media/audio/common/AudioConfig.aidl b/media/aidl/android/media/audio/common/AudioConfig.aidl index d1285611f44e7..4a264d84bf0cb 100644 --- a/media/aidl/android/media/audio/common/AudioConfig.aidl +++ b/media/aidl/android/media/audio/common/AudioConfig.aidl @@ -14,12 +14,10 @@ * limitations under the License. */ - // This file has been semi-automatically generated using hidl2aidl from its counterpart in - // hardware/interfaces/audio/common/5.0/types.hal - package android.media.audio.common; -import android.media.audio.common.AudioFormat; +import android.media.audio.common.AudioChannelLayout; +import android.media.audio.common.AudioFormatDescription; import android.media.audio.common.AudioOffloadInfo; /** @@ -31,8 +29,8 @@ import android.media.audio.common.AudioOffloadInfo; @VintfStability parcelable AudioConfig { int sampleRateHz; - int channelMask; - AudioFormat format = AudioFormat.INVALID; + AudioChannelLayout channelMask; + AudioFormatDescription format; AudioOffloadInfo offloadInfo; long frameCount; } diff --git a/media/aidl/android/media/audio/common/AudioFormat.aidl b/media/aidl/android/media/audio/common/AudioFormat.aidl deleted file mode 100644 index 73fbca25a578d..0000000000000 --- a/media/aidl/android/media/audio/common/AudioFormat.aidl +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - // This file has been semi-automatically generated using hidl2aidl from its counterpart in - // hardware/interfaces/audio/common/5.0/types.hal - -package android.media.audio.common; - -/** - * Audio format is a 32-bit word that consists of: - * main format field (upper 8 bits) - * sub format field (lower 24 bits). - * - * The main format indicates the main codec type. The sub format field indicates - * options and parameters for each format. The sub format is mainly used for - * record to indicate for instance the requested bitrate or profile. It can - * also be used for certain formats to give informations not present in the - * encoded audio stream (e.g. octet alignement for AMR). - * - * {@hide} - */ -@VintfStability -@Backing(type="int") -enum AudioFormat { - INVALID = 0xFFFFFFFF, - DEFAULT = 0, - PCM = 0x00000000, - MP3 = 0x01000000, - AMR_NB = 0x02000000, - AMR_WB = 0x03000000, - AAC = 0x04000000, - /** - * Deprecated, Use AAC_HE_V1 - */ - HE_AAC_V1 = 0x05000000, - /** - * Deprecated, Use AAC_HE_V2 - */ - HE_AAC_V2 = 0x06000000, - VORBIS = 0x07000000, - OPUS = 0x08000000, - AC3 = 0x09000000, - E_AC3 = 0x0A000000, - DTS = 0x0B000000, - DTS_HD = 0x0C000000, - /** - * IEC61937 is encoded audio wrapped in 16-bit PCM. - */ - IEC61937 = 0x0D000000, - DOLBY_TRUEHD = 0x0E000000, - EVRC = 0x10000000, - EVRCB = 0x11000000, - EVRCWB = 0x12000000, - EVRCNW = 0x13000000, - AAC_ADIF = 0x14000000, - WMA = 0x15000000, - WMA_PRO = 0x16000000, - AMR_WB_PLUS = 0x17000000, - MP2 = 0x18000000, - QCELP = 0x19000000, - DSD = 0x1A000000, - FLAC = 0x1B000000, - ALAC = 0x1C000000, - APE = 0x1D000000, - AAC_ADTS = 0x1E000000, - SBC = 0x1F000000, - APTX = 0x20000000, - APTX_HD = 0x21000000, - AC4 = 0x22000000, - LDAC = 0x23000000, - /** - * Dolby Metadata-enhanced Audio Transmission - */ - MAT = 0x24000000, - AAC_LATM = 0x25000000, - CELT = 0x26000000, - APTX_ADAPTIVE = 0x27000000, - LHDC = 0x28000000, - LHDC_LL = 0x29000000, - APTX_TWSP = 0x2A000000, - /** - * Deprecated - */ - MAIN_MASK = 0xFF000000, - SUB_MASK = 0x00FFFFFF, - /** - * Subformats - */ - PCM_SUB_16_BIT = 0x1, - PCM_SUB_8_BIT = 0x2, - PCM_SUB_32_BIT = 0x3, - PCM_SUB_8_24_BIT = 0x4, - PCM_SUB_FLOAT = 0x5, - PCM_SUB_24_BIT_PACKED = 0x6, - MP3_SUB_NONE = 0x0, - AMR_SUB_NONE = 0x0, - AAC_SUB_MAIN = 0x1, - AAC_SUB_LC = 0x2, - AAC_SUB_SSR = 0x4, - AAC_SUB_LTP = 0x8, - AAC_SUB_HE_V1 = 0x10, - AAC_SUB_SCALABLE = 0x20, - AAC_SUB_ERLC = 0x40, - AAC_SUB_LD = 0x80, - AAC_SUB_HE_V2 = 0x100, - AAC_SUB_ELD = 0x200, - AAC_SUB_XHE = 0x300, - VORBIS_SUB_NONE = 0x0, - E_AC3_SUB_JOC = 0x1, - MAT_SUB_1_0 = 0x1, - MAT_SUB_2_0 = 0x2, - MAT_SUB_2_1 = 0x3, -// TODO(ytai): Aliases not currently supported in AIDL - can inline the values. -// /** -// * Aliases -// * -// * -// * note != AudioFormat.ENCODING_PCM_16BIT -// */ -// PCM_16_BIT = (PCM | PCM_SUB_16_BIT), -// /** -// * note != AudioFormat.ENCODING_PCM_8BIT -// */ -// PCM_8_BIT = (PCM | PCM_SUB_8_BIT), -// PCM_32_BIT = (PCM | PCM_SUB_32_BIT), -// PCM_8_24_BIT = (PCM | PCM_SUB_8_24_BIT), -// PCM_FLOAT = (PCM | PCM_SUB_FLOAT), -// PCM_24_BIT_PACKED = (PCM | PCM_SUB_24_BIT_PACKED), -// AAC_MAIN = (AAC | AAC_SUB_MAIN), -// AAC_LC = (AAC | AAC_SUB_LC), -// AAC_SSR = (AAC | AAC_SUB_SSR), -// AAC_LTP = (AAC | AAC_SUB_LTP), -// AAC_HE_V1 = (AAC | AAC_SUB_HE_V1), -// AAC_SCALABLE = (AAC | AAC_SUB_SCALABLE), -// AAC_ERLC = (AAC | AAC_SUB_ERLC), -// AAC_LD = (AAC | AAC_SUB_LD), -// AAC_HE_V2 = (AAC | AAC_SUB_HE_V2), -// AAC_ELD = (AAC | AAC_SUB_ELD), -// AAC_XHE = (AAC | AAC_SUB_XHE), -// AAC_ADTS_MAIN = (AAC_ADTS | AAC_SUB_MAIN), -// AAC_ADTS_LC = (AAC_ADTS | AAC_SUB_LC), -// AAC_ADTS_SSR = (AAC_ADTS | AAC_SUB_SSR), -// AAC_ADTS_LTP = (AAC_ADTS | AAC_SUB_LTP), -// AAC_ADTS_HE_V1 = (AAC_ADTS | AAC_SUB_HE_V1), -// AAC_ADTS_SCALABLE = (AAC_ADTS | AAC_SUB_SCALABLE), -// AAC_ADTS_ERLC = (AAC_ADTS | AAC_SUB_ERLC), -// AAC_ADTS_LD = (AAC_ADTS | AAC_SUB_LD), -// AAC_ADTS_HE_V2 = (AAC_ADTS | AAC_SUB_HE_V2), -// AAC_ADTS_ELD = (AAC_ADTS | AAC_SUB_ELD), -// AAC_ADTS_XHE = (AAC_ADTS | AAC_SUB_XHE), -// E_AC3_JOC = (E_AC3 | E_AC3_SUB_JOC), -// MAT_1_0 = (MAT | MAT_SUB_1_0), -// MAT_2_0 = (MAT | MAT_SUB_2_0), -// MAT_2_1 = (MAT | MAT_SUB_2_1), -// AAC_LATM_LC = (AAC_LATM | AAC_SUB_LC), -// AAC_LATM_HE_V1 = (AAC_LATM | AAC_SUB_HE_V1), -// AAC_LATM_HE_V2 = (AAC_LATM | AAC_SUB_HE_V2), -} diff --git a/media/aidl/android/media/audio/common/AudioFormatDescription.aidl b/media/aidl/android/media/audio/common/AudioFormatDescription.aidl new file mode 100644 index 0000000000000..2aea8ddcd6d7b --- /dev/null +++ b/media/aidl/android/media/audio/common/AudioFormatDescription.aidl @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.audio.common; + +import android.media.audio.common.AudioFormatType; +import android.media.audio.common.PcmType; + +/** + * An extensible type for specifying audio formats. All formats are largely + * divided into two classes: PCM and non-PCM (bitstreams). Bitstreams can + * be encapsulated into PCM streams. + * + * The type defined in a way to make each format uniquely identifiable, so + * that if the framework and the HAL construct a value for the same type + * (e.g. PCM 16 bit), they will produce identical parcelables which will have + * identical hashes. This makes possible deduplicating type descriptions + * by the framework when they are received from different HAL modules without + * relying on having some centralized registry of enumeration values. + * + * {@hide} + */ +@JavaDerive(equals = true, toString = true) +@VintfStability +parcelable AudioFormatDescription { + /** + * The type of the audio format. See the 'AudioFormatType' for the + * list of supported values. + */ + AudioFormatType type = AudioFormatType.DEFAULT; + /** + * The type of the PCM stream or the transport stream for PCM + * encapsulations. See 'PcmType' for the list of supported values. + */ + PcmType pcm = PcmType.DEFAULT; + /** + * Optional encoding specification. Must be left empty when: + * + * - 'type == DEFAULT && pcm == DEFAULT' -- that means "default" type; + * - 'type == PCM' -- that means a regular PCM stream (not an encapsulation + * of an encoded bitstream). + * + * For PCM encapsulations of encoded bitstreams (e.g. an encapsulation + * according to IEC-61937 standard), the value of the 'pcm' field must + * be set accordingly, as an example, PCM_INT_16_BIT must be used for + * IEC-61937. Note that 'type == NON_PCM' in this case. + * + * Encoding names mostly follow IANA standards for media types (MIME), and + * frameworks/av/media/libstagefright/foundation/MediaDefs.cpp with the + * latter having priority. Since there are still many audio types not found + * in any of these lists, the following rules are applied: + * + * - If there is a direct MIME type for the encoding, the MIME type name + * is used as is, e.g. "audio/eac3" for the EAC-3 format. + * - If the encoding is a "subformat" of a MIME-registered format, + * the latter is augmented with a suffix, e.g. "audio/eac3-joc" for the + * JOC extension of EAC-3. + * - If it's a proprietary format, a "vnd." prefix is added, similar to + * IANA rules, e.g. "audio/vnd.dolby.truehd". + * - Otherwise, "x-" prefix is added, e.g. "audio/x-iec61937". + * - All MIME types not found in the IANA formats list have an associated + * comment. + * + * For PCM encapsulations with a known bitstream format, the latter + * is added to the encapsulation encoding as a suffix, after a "+" char. + * For example, an IEC61937 encapsulation of AC3 has the following + * representation: + * type = NON_PCM, + * pcm = PcmType.INT_16_BIT, + * encoding = "audio/x-iec61937+audio/ac3" + */ + @utf8InCpp String encoding; +} diff --git a/media/aidl/android/media/audio/common/AudioFormatType.aidl b/media/aidl/android/media/audio/common/AudioFormatType.aidl new file mode 100644 index 0000000000000..17594017973fa --- /dev/null +++ b/media/aidl/android/media/audio/common/AudioFormatType.aidl @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.audio.common; + +/** + * The type of the audio format. Only used as part of 'AudioFormatDescription' + * structure. + */ +@VintfStability +@Backing(type="byte") +enum AudioFormatType { + /** + * "Default" type is used when the client does not care about the actual + * format. All fields of 'AudioFormatDescription' must have default / empty + * / null values. + */ + DEFAULT = 0, + /** + * When the 'encoding' field of 'AudioFormatDescription' is not empty, it + * specifies the codec used for bitstream (non-PCM) data. It is also used + * in the case when the bitstream data is encapsulated into a PCM stream, + * see the documentation for 'AudioFormatDescription'. + */ + NON_PCM = DEFAULT, + /** + * PCM type. The 'pcm' field of 'AudioFormatDescription' is used to specify + * the actual sample size and representation. + */ + PCM = 1, + /** + * Value reserved for system use only. HALs must never return this value to + * the system or accept it from the system. + */ + SYS_RESERVED_INVALID = -1, +} diff --git a/media/aidl/android/media/audio/common/AudioOffloadInfo.aidl b/media/aidl/android/media/audio/common/AudioOffloadInfo.aidl index 7be5e6aadcb3e..b6b548751873a 100644 --- a/media/aidl/android/media/audio/common/AudioOffloadInfo.aidl +++ b/media/aidl/android/media/audio/common/AudioOffloadInfo.aidl @@ -14,12 +14,10 @@ * limitations under the License. */ - // This file has been semi-automatically generated using hidl2aidl from its counterpart in - // hardware/interfaces/audio/common/5.0/types.hal - package android.media.audio.common; -import android.media.audio.common.AudioFormat; +import android.media.audio.common.AudioChannelLayout; +import android.media.audio.common.AudioFormatDescription; import android.media.audio.common.AudioStreamType; import android.media.audio.common.AudioUsage; @@ -32,8 +30,8 @@ import android.media.audio.common.AudioUsage; @VintfStability parcelable AudioOffloadInfo { int sampleRateHz; - int channelMask; - AudioFormat format = AudioFormat.INVALID; + AudioChannelLayout channelMask; + AudioFormatDescription format; AudioStreamType streamType = AudioStreamType.INVALID; int bitRatePerSecond; long durationMicroseconds; @@ -43,4 +41,3 @@ parcelable AudioOffloadInfo { int bufferSize; AudioUsage usage = AudioUsage.INVALID; } - diff --git a/media/aidl/android/media/audio/common/PcmType.aidl b/media/aidl/android/media/audio/common/PcmType.aidl new file mode 100644 index 0000000000000..db77769226e91 --- /dev/null +++ b/media/aidl/android/media/audio/common/PcmType.aidl @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.audio.common; + +/** + * The type of the encoding used for representing PCM samples. Only used as + * part of 'AudioFormatDescription' structure. + */ +@VintfStability +@Backing(type="byte") +enum PcmType { + /** + * "Default" value used when the type 'AudioFormatDescription' is "default". + */ + DEFAULT = 0, + /** + * Unsigned 8-bit integer. + */ + UINT_8_BIT = DEFAULT, + /** + * Signed 16-bit integer. + */ + INT_16_BIT = 1, + /** + * Signed 32-bit integer. + */ + INT_32_BIT = 2, + /** + * Q8.24 fixed point format. + */ + FIXED_Q_8_24 = 3, + /** + * IEEE 754 32-bit floating point format. + */ + FLOAT_32_BIT = 4, + /** + * Signed 24-bit integer. + */ + INT_24_BIT = 5, +} diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioChannelLayout.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioChannelLayout.aidl new file mode 100644 index 0000000000000..6845ac1f6e1fc --- /dev/null +++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioChannelLayout.aidl @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.media.audio.common; +/* @hide */ +@JavaDerive(equals=true, toString=true) @VintfStability +union AudioChannelLayout { + int none = 0; + int invalid = 0; + int indexMask; + int layoutMask; + int voiceMask; + const int INDEX_MASK_1 = 1; + const int INDEX_MASK_2 = 3; + const int INDEX_MASK_3 = 7; + const int INDEX_MASK_4 = 15; + const int INDEX_MASK_5 = 31; + const int INDEX_MASK_6 = 63; + const int INDEX_MASK_7 = 127; + const int INDEX_MASK_8 = 255; + const int INDEX_MASK_9 = 511; + const int INDEX_MASK_10 = 1023; + const int INDEX_MASK_11 = 2047; + const int INDEX_MASK_12 = 4095; + const int INDEX_MASK_13 = 8191; + const int INDEX_MASK_14 = 16383; + const int INDEX_MASK_15 = 32767; + const int INDEX_MASK_16 = 65535; + const int INDEX_MASK_17 = 131071; + const int INDEX_MASK_18 = 262143; + const int INDEX_MASK_19 = 524287; + const int INDEX_MASK_20 = 1048575; + const int INDEX_MASK_21 = 2097151; + const int INDEX_MASK_22 = 4194303; + const int INDEX_MASK_23 = 8388607; + const int INDEX_MASK_24 = 16777215; + const int LAYOUT_MONO = 1; + const int LAYOUT_STEREO = 3; + const int LAYOUT_2POINT1 = 11; + const int LAYOUT_TRI = 7; + const int LAYOUT_TRI_BACK = 259; + const int LAYOUT_3POINT1 = 15; + const int LAYOUT_2POINT0POINT2 = 786435; + const int LAYOUT_2POINT1POINT2 = 786443; + const int LAYOUT_3POINT0POINT2 = 786439; + const int LAYOUT_3POINT1POINT2 = 786447; + const int LAYOUT_QUAD = 51; + const int LAYOUT_QUAD_SIDE = 1539; + const int LAYOUT_SURROUND = 263; + const int LAYOUT_PENTA = 55; + const int LAYOUT_5POINT1 = 63; + const int LAYOUT_5POINT1_SIDE = 1551; + const int LAYOUT_5POINT1POINT2 = 786495; + const int LAYOUT_5POINT1POINT4 = 184383; + const int LAYOUT_6POINT1 = 319; + const int LAYOUT_7POINT1 = 1599; + const int LAYOUT_7POINT1POINT2 = 788031; + const int LAYOUT_7POINT1POINT4 = 185919; + const int LAYOUT_9POINT1POINT4 = 50517567; + const int LAYOUT_9POINT1POINT6 = 51303999; + const int LAYOUT_13POINT_360RA = 7534087; + const int LAYOUT_22POINT2 = 16777215; + const int LAYOUT_MONO_HAPTIC_A = 1073741825; + const int LAYOUT_STEREO_HAPTIC_A = 1073741827; + const int LAYOUT_HAPTIC_AB = 1610612736; + const int LAYOUT_MONO_HAPTIC_AB = 1610612737; + const int LAYOUT_STEREO_HAPTIC_AB = 1610612739; + const int LAYOUT_FRONT_BACK = 260; + const int INTERLEAVE_LEFT = 0; + const int INTERLEAVE_RIGHT = 1; + const int CHANNEL_FRONT_LEFT = 1; + const int CHANNEL_FRONT_RIGHT = 2; + const int CHANNEL_FRONT_CENTER = 4; + const int CHANNEL_LOW_FREQUENCY = 8; + const int CHANNEL_BACK_LEFT = 16; + const int CHANNEL_BACK_RIGHT = 32; + const int CHANNEL_FRONT_LEFT_OF_CENTER = 64; + const int CHANNEL_FRONT_RIGHT_OF_CENTER = 128; + const int CHANNEL_BACK_CENTER = 256; + const int CHANNEL_SIDE_LEFT = 512; + const int CHANNEL_SIDE_RIGHT = 1024; + const int CHANNEL_TOP_CENTER = 2048; + const int CHANNEL_TOP_FRONT_LEFT = 4096; + const int CHANNEL_TOP_FRONT_CENTER = 8192; + const int CHANNEL_TOP_FRONT_RIGHT = 16384; + const int CHANNEL_TOP_BACK_LEFT = 32768; + const int CHANNEL_TOP_BACK_CENTER = 65536; + const int CHANNEL_TOP_BACK_RIGHT = 131072; + const int CHANNEL_TOP_SIDE_LEFT = 262144; + const int CHANNEL_TOP_SIDE_RIGHT = 524288; + const int CHANNEL_BOTTOM_FRONT_LEFT = 1048576; + const int CHANNEL_BOTTOM_FRONT_CENTER = 2097152; + const int CHANNEL_BOTTOM_FRONT_RIGHT = 4194304; + const int CHANNEL_LOW_FREQUENCY_2 = 8388608; + const int CHANNEL_FRONT_WIDE_LEFT = 16777216; + const int CHANNEL_FRONT_WIDE_RIGHT = 33554432; + const int CHANNEL_HAPTIC_B = 536870912; + const int CHANNEL_HAPTIC_A = 1073741824; + const int VOICE_UPLINK_MONO = 16384; + const int VOICE_DNLINK_MONO = 32768; + const int VOICE_CALL_MONO = 49152; + const int CHANNEL_VOICE_UPLINK = 16384; + const int CHANNEL_VOICE_DNLINK = 32768; +} diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioChannelMask.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioChannelMask.aidl deleted file mode 100644 index c3af3bfdfde74..0000000000000 --- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioChannelMask.aidl +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */// This file has been semi-automatically generated using hidl2aidl from its counterpart in -// hardware/interfaces/audio/common/5.0/types.hal -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.media.audio.common; -/* @hide */ -@Backing(type="int") @VintfStability -enum AudioChannelMask { - REPRESENTATION_POSITION = 0, - REPRESENTATION_INDEX = 2, - NONE = 0, - INVALID = -1073741824, - OUT_FRONT_LEFT = 1, - OUT_FRONT_RIGHT = 2, - OUT_FRONT_CENTER = 4, - OUT_LOW_FREQUENCY = 8, - OUT_BACK_LEFT = 16, - OUT_BACK_RIGHT = 32, - OUT_FRONT_LEFT_OF_CENTER = 64, - OUT_FRONT_RIGHT_OF_CENTER = 128, - OUT_BACK_CENTER = 256, - OUT_SIDE_LEFT = 512, - OUT_SIDE_RIGHT = 1024, - OUT_TOP_CENTER = 2048, - OUT_TOP_FRONT_LEFT = 4096, - OUT_TOP_FRONT_CENTER = 8192, - OUT_TOP_FRONT_RIGHT = 16384, - OUT_TOP_BACK_LEFT = 32768, - OUT_TOP_BACK_CENTER = 65536, - OUT_TOP_BACK_RIGHT = 131072, - OUT_TOP_SIDE_LEFT = 262144, - OUT_TOP_SIDE_RIGHT = 524288, - OUT_HAPTIC_A = 536870912, - OUT_HAPTIC_B = 268435456, - OUT_MONO = 1, - OUT_STEREO = 3, - OUT_2POINT1 = 11, - OUT_2POINT0POINT2 = 786435, - OUT_2POINT1POINT2 = 786443, - OUT_3POINT0POINT2 = 786439, - OUT_3POINT1POINT2 = 786447, - OUT_QUAD = 51, - OUT_QUAD_BACK = 51, - OUT_QUAD_SIDE = 1539, - OUT_SURROUND = 263, - OUT_PENTA = 55, - OUT_5POINT1 = 63, - OUT_5POINT1_BACK = 63, - OUT_5POINT1_SIDE = 1551, - OUT_5POINT1POINT2 = 786495, - OUT_5POINT1POINT4 = 184383, - OUT_6POINT1 = 319, - OUT_7POINT1 = 1599, - OUT_7POINT1POINT2 = 788031, - OUT_7POINT1POINT4 = 185919, - OUT_MONO_HAPTIC_A = 536870913, - OUT_STEREO_HAPTIC_A = 536870915, - OUT_HAPTIC_AB = 805306368, - OUT_MONO_HAPTIC_AB = 805306369, - OUT_STEREO_HAPTIC_AB = 805306371, - IN_LEFT = 4, - IN_RIGHT = 8, - IN_FRONT = 16, - IN_BACK = 32, - IN_LEFT_PROCESSED = 64, - IN_RIGHT_PROCESSED = 128, - IN_FRONT_PROCESSED = 256, - IN_BACK_PROCESSED = 512, - IN_PRESSURE = 1024, - IN_X_AXIS = 2048, - IN_Y_AXIS = 4096, - IN_Z_AXIS = 8192, - IN_BACK_LEFT = 65536, - IN_BACK_RIGHT = 131072, - IN_CENTER = 262144, - IN_LOW_FREQUENCY = 1048576, - IN_TOP_LEFT = 2097152, - IN_TOP_RIGHT = 4194304, - IN_VOICE_UPLINK = 16384, - IN_VOICE_DNLINK = 32768, -} diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfig.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfig.aidl index c11eb76857d22..5fdeb4c649e26 100644 --- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfig.aidl +++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfig.aidl @@ -12,8 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */// This file has been semi-automatically generated using hidl2aidl from its counterpart in -// hardware/interfaces/audio/common/5.0/types.hal + */ /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -37,8 +36,8 @@ package android.media.audio.common; @JavaDerive(equals=true, toString=true) @VintfStability parcelable AudioConfig { int sampleRateHz; - int channelMask; - android.media.audio.common.AudioFormat format = android.media.audio.common.AudioFormat.INVALID; + android.media.audio.common.AudioChannelLayout channelMask; + android.media.audio.common.AudioFormatDescription format; android.media.audio.common.AudioOffloadInfo offloadInfo; long frameCount; } diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioFormat.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioFormat.aidl deleted file mode 100644 index b7c86599a2c4e..0000000000000 --- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioFormat.aidl +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */// This file has been semi-automatically generated using hidl2aidl from its counterpart in -// hardware/interfaces/audio/common/5.0/types.hal -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.media.audio.common; -/* @hide */ -@Backing(type="int") @VintfStability -enum AudioFormat { - INVALID = -1, - DEFAULT = 0, - PCM = 0, - MP3 = 16777216, - AMR_NB = 33554432, - AMR_WB = 50331648, - AAC = 67108864, - HE_AAC_V1 = 83886080, - HE_AAC_V2 = 100663296, - VORBIS = 117440512, - OPUS = 134217728, - AC3 = 150994944, - E_AC3 = 167772160, - DTS = 184549376, - DTS_HD = 201326592, - IEC61937 = 218103808, - DOLBY_TRUEHD = 234881024, - EVRC = 268435456, - EVRCB = 285212672, - EVRCWB = 301989888, - EVRCNW = 318767104, - AAC_ADIF = 335544320, - WMA = 352321536, - WMA_PRO = 369098752, - AMR_WB_PLUS = 385875968, - MP2 = 402653184, - QCELP = 419430400, - DSD = 436207616, - FLAC = 452984832, - ALAC = 469762048, - APE = 486539264, - AAC_ADTS = 503316480, - SBC = 520093696, - APTX = 536870912, - APTX_HD = 553648128, - AC4 = 570425344, - LDAC = 587202560, - MAT = 603979776, - AAC_LATM = 620756992, - CELT = 637534208, - APTX_ADAPTIVE = 654311424, - LHDC = 671088640, - LHDC_LL = 687865856, - APTX_TWSP = 704643072, - MAIN_MASK = -16777216, - SUB_MASK = 16777215, - PCM_SUB_16_BIT = 1, - PCM_SUB_8_BIT = 2, - PCM_SUB_32_BIT = 3, - PCM_SUB_8_24_BIT = 4, - PCM_SUB_FLOAT = 5, - PCM_SUB_24_BIT_PACKED = 6, - MP3_SUB_NONE = 0, - AMR_SUB_NONE = 0, - AAC_SUB_MAIN = 1, - AAC_SUB_LC = 2, - AAC_SUB_SSR = 4, - AAC_SUB_LTP = 8, - AAC_SUB_HE_V1 = 16, - AAC_SUB_SCALABLE = 32, - AAC_SUB_ERLC = 64, - AAC_SUB_LD = 128, - AAC_SUB_HE_V2 = 256, - AAC_SUB_ELD = 512, - AAC_SUB_XHE = 768, - VORBIS_SUB_NONE = 0, - E_AC3_SUB_JOC = 1, - MAT_SUB_1_0 = 1, - MAT_SUB_2_0 = 2, - MAT_SUB_2_1 = 3, -} diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioFormatDescription.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioFormatDescription.aidl new file mode 100644 index 0000000000000..58c75ebc1ae2f --- /dev/null +++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioFormatDescription.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.media.audio.common; +/* @hide */ +@JavaDerive(equals=true, toString=true) @VintfStability +parcelable AudioFormatDescription { + android.media.audio.common.AudioFormatType type = android.media.audio.common.AudioFormatType.DEFAULT; + android.media.audio.common.PcmType pcm = android.media.audio.common.PcmType.DEFAULT; + @utf8InCpp String encoding; +} diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioFormatType.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioFormatType.aidl new file mode 100644 index 0000000000000..b94c850002d86 --- /dev/null +++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioFormatType.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.media.audio.common; +@Backing(type="byte") @VintfStability +enum AudioFormatType { + DEFAULT = 0, + NON_PCM = 0, + PCM = 1, + SYS_RESERVED_INVALID = -1, +} diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioOffloadInfo.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioOffloadInfo.aidl index b5d889ea5d0b2..9404a4bdc162a 100644 --- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioOffloadInfo.aidl +++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioOffloadInfo.aidl @@ -12,8 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */// This file has been semi-automatically generated using hidl2aidl from its counterpart in -// hardware/interfaces/audio/common/5.0/types.hal + */ /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -37,8 +36,8 @@ package android.media.audio.common; @JavaDerive(equals=true, toString=true) @VintfStability parcelable AudioOffloadInfo { int sampleRateHz; - int channelMask; - android.media.audio.common.AudioFormat format = android.media.audio.common.AudioFormat.INVALID; + android.media.audio.common.AudioChannelLayout channelMask; + android.media.audio.common.AudioFormatDescription format; android.media.audio.common.AudioStreamType streamType = android.media.audio.common.AudioStreamType.INVALID; int bitRatePerSecond; long durationMicroseconds; diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/PcmType.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/PcmType.aidl new file mode 100644 index 0000000000000..42c4679fe1252 --- /dev/null +++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/PcmType.aidl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.media.audio.common; +@Backing(type="byte") @VintfStability +enum PcmType { + DEFAULT = 0, + UINT_8_BIT = 0, + INT_16_BIT = 1, + INT_32_BIT = 2, + FIXED_Q_8_24 = 3, + FLOAT_32_BIT = 4, + INT_24_BIT = 5, +} diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index a8199c4d028e3..5cdb89838159d 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -495,6 +495,12 @@ public final class AudioFormat implements Parcelable { public static final int CHANNEL_OUT_FRONT_WIDE_LEFT = 0x4000000; /** Front wide right output channel (see FWR in channel diagram) */ public static final int CHANNEL_OUT_FRONT_WIDE_RIGHT = 0x8000000; + /** @hide + * Haptic channels can be used by internal framework code. Use the same values as in native. + */ + public static final int CHANNEL_OUT_HAPTIC_B = 0x10000000; + /** @hide */ + public static final int CHANNEL_OUT_HAPTIC_A = 0x20000000; public static final int CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT; public static final int CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT); diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 9bf0db52f66d7..16543b0d41422 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -174,6 +174,67 @@ public final class MediaFormat { public static final String MIMETYPE_AUDIO_MPEGH_MHA1 = "audio/mha1"; /** MIME type for MPEG-H Audio single stream, encapsulated in MHAS */ public static final String MIMETYPE_AUDIO_MPEGH_MHM1 = "audio/mhm1"; + /** MIME type for DTS (up to 5.1 channels) audio stream. */ + public static final String MIMETYPE_AUDIO_DTS = "audio/vnd.dts"; + /** MIME type for DTS HD (up to 7.1 channels) audio stream. */ + public static final String MIMETYPE_AUDIO_DTS_HD = "audio/vnd.dts.hd"; + /** MIME type for DTS UHD (object-based) audio stream. */ + public static final String MIMETYPE_AUDIO_DTS_UHD = "audio/vnd.dts.uhd"; + /** MIME type for Dynamic Resolution Adaptation (DRA) audio stream. */ + public static final String MIMETYPE_AUDIO_DRA = "audio/vnd.dra"; + /** MIME type for Dolby Metadata-enhanced Audio Transmission (MAT) audio stream. */ + public static final String MIMETYPE_AUDIO_DOLBY_MAT = "audio/vnd.dolby.mat"; + /** MIME type for Dolby TrueHD audio format, based on Meridian Lossless Packing (MLP). */ + public static final String MIMETYPE_AUDIO_DOLBY_TRUEHD = "audio/vnd.dolby.mlp"; + /** + * MIME type for AAC Low Complexity (LC) audio stream. Uses the scheme defined by + * RFC 6381 with OTI of MPEG-4 (40) and AOT of AAC LC (2) from ISO/IEC 14496-3. + */ + public static final String MIMETYPE_AUDIO_AAC_LC = "audio/mp4a.40.02"; + /** + * MIME type for HE-AAC v1 (LC + SBR) audio stream. Uses the scheme defined by + * RFC 6381 with OTI of MPEG-4 (40) and AOT of AAC SBR (5) from ISO/IEC 14496-3. + */ + public static final String MIMETYPE_AUDIO_AAC_HE_V1 = "audio/mp4a.40.05"; + /** + * MIME type for HE-AAC v2 (LC + SBR + PS) audio stream. Uses the scheme defined by + * RFC 6381 with OTI of MPEG-4 (40) and AOT of PS (29) from ISO/IEC 14496-3. + */ + public static final String MIMETYPE_AUDIO_AAC_HE_V2 = "audio/mp4a.40.29"; + /** + * MIME type for AAC Enhanced Low Delay (ELD) audio stream. Uses the scheme defined by + * RFC 6381 with OTI of MPEG-4 (40) and AOT of ELD (39) from ISO/IEC 14496-3. + */ + public static final String MIMETYPE_AUDIO_AAC_ELD = "audio/mp4a.40.39"; + /** + * MIME type for AAC XHE audio stream. Uses the scheme defined by + * RFC 6381 with OTI of MPEG-4 (40) and AOT of USAC (42) from ISO/IEC 14496-3. + */ + public static final String MIMETYPE_AUDIO_AAC_XHE = "audio/mp4a.40.42"; + /** + * MIME type for MPEG-H Baseline (BL) Profile L3 audio stream. Uses the scheme defined by + * RFC 6381 with mpegh3daProfileLevelIndication for main profile/L3 (0x3) from ISO/IEC 23008-3. + */ + public static final String MIMETYPE_AUDIO_MPEGH_BL_L3 = "audio/mhm1.03"; + /** + * MIME type for MPEG-H Baseline (BL) Profile L4 audio stream. Uses the scheme defined by + * RFC 6381 with mpegh3daProfileLevelIndication for main profile/L4 (0x4) from ISO/IEC 23008-3. + */ + public static final String MIMETYPE_AUDIO_MPEGH_BL_L4 = "audio/mhm1.04"; + /** + * MIME type for MPEG-H Low Complexity (LC) L3 audio stream. Uses the scheme defined by + * RFC 6381 with mpegh3daProfileLevelIndication for LC profile/L3 (0xD) from ISO/IEC 23008-3. + */ + public static final String MIMETYPE_AUDIO_MPEGH_LC_L3 = "audio/mhm1.0d"; + /** + * MIME type for MPEG-H Low Complexity (LC) L4 audio stream. Uses the scheme defined by + * RFC 6381 with mpegh3daProfileLevelIndication for LC profile/L4 (0xE) from ISO/IEC 23008-3. + */ + public static final String MIMETYPE_AUDIO_MPEGH_LC_L4 = "audio/mhm1.0e"; + /** + * MIME type for the IEC61937 audio stream encapsulation. This type isn't defined by IANA. + */ + public static final String MIMETYPE_AUDIO_IEC61937 = "audio/x-iec61937"; /** * MIME type for HEIF still image data encoded in HEVC. diff --git a/media/java/android/media/audio/common/AidlConversion.java b/media/java/android/media/audio/common/AidlConversion.java new file mode 100644 index 0000000000000..3b589343f15dc --- /dev/null +++ b/media/java/android/media/audio/common/AidlConversion.java @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.audio.common; + +import android.annotation.NonNull; +import android.media.AudioFormat; +import android.media.MediaFormat; +import android.os.Parcel; + +import com.android.internal.annotations.VisibleForTesting; + +/** + * This class provides utility functions for converting between + * the AIDL types defined in 'android.media.audio.common' and: + * - SDK (Java API) types from 'android.media'; + * - legacy native (system/audio.h) types. + * + * Methods that convert between AIDL and SDK types are called + * using the following pattern: + * + * aidl2api_AIDL-type-name_SDK-type-name + * api2aidl_SDK-type-name_AIDL-type-name + * + * Methods that convert between AIDL and legacy types are called + * using the following pattern: + * + * aidl2legacy_AIDL-type-name_native-type-name + * legacy2aidl_native-type-name_AIDL-type-name + * + * @hide + */ +@VisibleForTesting +public class AidlConversion { + /** Convert from AIDL AudioChannelLayout to legacy audio_channel_mask_t. */ + @VisibleForTesting + public static int /*audio_channel_mask_t*/ aidl2legacy_AudioChannelLayout_audio_channel_mask_t( + @NonNull AudioChannelLayout aidl, boolean isInput) { + Parcel out = Parcel.obtain(); + aidl.writeToParcel(out, 0); + out.setDataPosition(0); + try { + return aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t(out, isInput); + } finally { + out.recycle(); + } + } + + /** Convert from legacy audio_channel_mask_t to AIDL AudioChannelLayout. */ + @VisibleForTesting + public static AudioChannelLayout legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + int /*audio_channel_mask_t*/ legacy, boolean isInput) { + Parcel in = legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel(legacy, isInput); + if (in != null) { + try { + return AudioChannelLayout.CREATOR.createFromParcel(in); + } finally { + in.recycle(); + } + } + throw new IllegalArgumentException("Invalid legacy audio " + + (isInput ? "input" : "output") + " channel mask: " + legacy); + } + + /** Convert from AIDL AudioFormatDescription to legacy audio_format_t. */ + @VisibleForTesting + public static int /*audio_format_t*/ aidl2legacy_AudioFormatDescription_audio_format_t( + @NonNull AudioFormatDescription aidl) { + Parcel out = Parcel.obtain(); + aidl.writeToParcel(out, 0); + out.setDataPosition(0); + try { + return aidl2legacy_AudioFormatDescription_Parcel_audio_format_t(out); + } finally { + out.recycle(); + } + } + + /** Convert from legacy audio_format_t to AIDL AudioFormatDescription. */ + @VisibleForTesting + public static @NonNull AudioFormatDescription legacy2aidl_audio_format_t_AudioFormatDescription( + int /*audio_format_t*/ legacy) { + Parcel in = legacy2aidl_audio_format_t_AudioFormatDescription_Parcel(legacy); + if (in != null) { + try { + return AudioFormatDescription.CREATOR.createFromParcel(in); + } finally { + in.recycle(); + } + } + throw new IllegalArgumentException("Invalid legacy audio format: " + legacy); + } + + /** Convert from legacy audio_stream_type_t to AIDL AudioStreamType. */ + @VisibleForTesting + public static int legacy2aidl_audio_stream_type_t_AudioStreamType( + int /*audio_stream_type_t*/ legacy) { + // Relies on the fact that AudioStreamType was converted from + // the HIDL definition which uses the same constant values as system/audio.h + return legacy; + } + + /** Convert from legacy audio_usage_t to AIDL AudioUsage. */ + @VisibleForTesting + public static int legacy2aidl_audio_usage_t_AudioUsage(int /*audio_usage_t*/ legacy) { + // Relies on the fact that AudioUsage was converted from + // the HIDL definition which uses the same constant values as system/audio.h + return legacy; + } + + /** Convert from AIDL AudioChannelLayout to SDK AudioFormat.CHANNEL_*. */ + @VisibleForTesting + public static int aidl2api_AudioChannelLayout_AudioFormatChannelMask( + @NonNull AudioChannelLayout aidlMask, boolean isInput) { + switch (aidlMask.getTag()) { + case AudioChannelLayout.none: + return isInput ? AudioFormat.CHANNEL_IN_DEFAULT : AudioFormat.CHANNEL_OUT_DEFAULT; + case AudioChannelLayout.invalid: + return AudioFormat.CHANNEL_INVALID; + case AudioChannelLayout.indexMask: + // Note that for a proper building of SDK AudioFormat one must + // call either 'setChannelMask' or 'setChannelIndexMask' depending + // on the variant of AudioChannelLayout. The integer representations + // of positional and indexed channel masks are indistinguishable in + // the SDK. + return aidlMask.getIndexMask(); + case AudioChannelLayout.layoutMask: + if (isInput) { + switch (aidlMask.getLayoutMask()) { + case AudioChannelLayout.LAYOUT_MONO: + return AudioFormat.CHANNEL_IN_MONO; + case AudioChannelLayout.LAYOUT_STEREO: + return AudioFormat.CHANNEL_IN_STEREO; + case AudioChannelLayout.LAYOUT_FRONT_BACK: + return AudioFormat.CHANNEL_IN_FRONT_BACK; + default: + return AudioFormat.CHANNEL_INVALID; + } + } else { + switch (aidlMask.getLayoutMask()) { + case AudioChannelLayout.LAYOUT_MONO: + return AudioFormat.CHANNEL_OUT_MONO; + case AudioChannelLayout.LAYOUT_STEREO: + return AudioFormat.CHANNEL_OUT_STEREO; + case AudioChannelLayout.LAYOUT_2POINT1: + return AudioFormat.CHANNEL_OUT_FRONT_LEFT + | AudioFormat.CHANNEL_OUT_FRONT_RIGHT + | AudioFormat.CHANNEL_OUT_LOW_FREQUENCY; + case AudioChannelLayout.LAYOUT_TRI: + return AudioFormat.CHANNEL_OUT_FRONT_LEFT + | AudioFormat.CHANNEL_OUT_FRONT_RIGHT + | AudioFormat.CHANNEL_OUT_FRONT_CENTER; + case AudioChannelLayout.LAYOUT_TRI_BACK: + return AudioFormat.CHANNEL_OUT_FRONT_LEFT + | AudioFormat.CHANNEL_OUT_FRONT_RIGHT + | AudioFormat.CHANNEL_OUT_BACK_CENTER; + case AudioChannelLayout.LAYOUT_3POINT1: + return AudioFormat.CHANNEL_OUT_FRONT_LEFT + | AudioFormat.CHANNEL_OUT_FRONT_RIGHT + | AudioFormat.CHANNEL_OUT_FRONT_CENTER + | AudioFormat.CHANNEL_OUT_LOW_FREQUENCY; + case AudioChannelLayout.LAYOUT_2POINT0POINT2: + return AudioFormat.CHANNEL_OUT_FRONT_LEFT + | AudioFormat.CHANNEL_OUT_FRONT_RIGHT + | AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT + | AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT; + case AudioChannelLayout.LAYOUT_2POINT1POINT2: + return AudioFormat.CHANNEL_OUT_FRONT_LEFT + | AudioFormat.CHANNEL_OUT_FRONT_RIGHT + | AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT + | AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT + | AudioFormat.CHANNEL_OUT_LOW_FREQUENCY; + case AudioChannelLayout.LAYOUT_3POINT0POINT2: + return AudioFormat.CHANNEL_OUT_FRONT_LEFT + | AudioFormat.CHANNEL_OUT_FRONT_RIGHT + | AudioFormat.CHANNEL_OUT_FRONT_CENTER + | AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT + | AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT; + case AudioChannelLayout.LAYOUT_3POINT1POINT2: + return AudioFormat.CHANNEL_OUT_FRONT_LEFT + | AudioFormat.CHANNEL_OUT_FRONT_RIGHT + | AudioFormat.CHANNEL_OUT_FRONT_CENTER + | AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT + | AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT + | AudioFormat.CHANNEL_OUT_LOW_FREQUENCY; + case AudioChannelLayout.LAYOUT_QUAD: + return AudioFormat.CHANNEL_OUT_QUAD; + case AudioChannelLayout.LAYOUT_QUAD_SIDE: + return AudioFormat.CHANNEL_OUT_QUAD_SIDE; + case AudioChannelLayout.LAYOUT_SURROUND: + return AudioFormat.CHANNEL_OUT_SURROUND; + case AudioChannelLayout.LAYOUT_PENTA: + return AudioFormat.CHANNEL_OUT_QUAD + | AudioFormat.CHANNEL_OUT_FRONT_CENTER; + case AudioChannelLayout.LAYOUT_5POINT1: + return AudioFormat.CHANNEL_OUT_5POINT1; + case AudioChannelLayout.LAYOUT_5POINT1_SIDE: + return AudioFormat.CHANNEL_OUT_5POINT1_SIDE; + case AudioChannelLayout.LAYOUT_5POINT1POINT2: + return AudioFormat.CHANNEL_OUT_5POINT1POINT2; + case AudioChannelLayout.LAYOUT_5POINT1POINT4: + return AudioFormat.CHANNEL_OUT_5POINT1POINT4; + case AudioChannelLayout.LAYOUT_6POINT1: + return AudioFormat.CHANNEL_OUT_FRONT_LEFT + | AudioFormat.CHANNEL_OUT_FRONT_RIGHT + | AudioFormat.CHANNEL_OUT_FRONT_CENTER + | AudioFormat.CHANNEL_OUT_LOW_FREQUENCY + | AudioFormat.CHANNEL_OUT_BACK_LEFT + | AudioFormat.CHANNEL_OUT_BACK_RIGHT + | AudioFormat.CHANNEL_OUT_BACK_CENTER; + case AudioChannelLayout.LAYOUT_7POINT1: + return AudioFormat.CHANNEL_OUT_7POINT1_SURROUND; + case AudioChannelLayout.LAYOUT_7POINT1POINT2: + return AudioFormat.CHANNEL_OUT_7POINT1POINT2; + case AudioChannelLayout.LAYOUT_7POINT1POINT4: + return AudioFormat.CHANNEL_OUT_7POINT1POINT4; + case AudioChannelLayout.LAYOUT_9POINT1POINT4: + return AudioFormat.CHANNEL_OUT_9POINT1POINT4; + case AudioChannelLayout.LAYOUT_9POINT1POINT6: + return AudioFormat.CHANNEL_OUT_9POINT1POINT6; + case AudioChannelLayout.LAYOUT_13POINT_360RA: + return AudioFormat.CHANNEL_OUT_13POINT_360RA; + case AudioChannelLayout.LAYOUT_22POINT2: + return AudioFormat.CHANNEL_OUT_22POINT2; + case AudioChannelLayout.LAYOUT_MONO_HAPTIC_A: + return AudioFormat.CHANNEL_OUT_MONO + | AudioFormat.CHANNEL_OUT_HAPTIC_A; + case AudioChannelLayout.LAYOUT_STEREO_HAPTIC_A: + return AudioFormat.CHANNEL_OUT_STEREO + | AudioFormat.CHANNEL_OUT_HAPTIC_A; + case AudioChannelLayout.LAYOUT_HAPTIC_AB: + return AudioFormat.CHANNEL_OUT_HAPTIC_A + | AudioFormat.CHANNEL_OUT_HAPTIC_B; + case AudioChannelLayout.LAYOUT_MONO_HAPTIC_AB: + return AudioFormat.CHANNEL_OUT_MONO + | AudioFormat.CHANNEL_OUT_HAPTIC_A + | AudioFormat.CHANNEL_OUT_HAPTIC_B; + case AudioChannelLayout.LAYOUT_STEREO_HAPTIC_AB: + return AudioFormat.CHANNEL_OUT_STEREO + | AudioFormat.CHANNEL_OUT_HAPTIC_A + | AudioFormat.CHANNEL_OUT_HAPTIC_B; + case AudioChannelLayout.LAYOUT_FRONT_BACK: + return AudioFormat.CHANNEL_OUT_FRONT_CENTER + | AudioFormat.CHANNEL_OUT_BACK_CENTER; + default: + return AudioFormat.CHANNEL_INVALID; + } + } + case AudioChannelLayout.voiceMask: + if (isInput) { + switch (aidlMask.getVoiceMask()) { + // AudioFormat input masks match legacy native masks directly, + // thus we add AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO here. + case AudioChannelLayout.VOICE_UPLINK_MONO: + return AudioFormat.CHANNEL_IN_VOICE_UPLINK + | AudioFormat.CHANNEL_IN_MONO; + case AudioChannelLayout.VOICE_DNLINK_MONO: + return AudioFormat.CHANNEL_IN_VOICE_DNLINK + | AudioFormat.CHANNEL_IN_MONO; + case AudioChannelLayout.VOICE_CALL_MONO: + return AudioFormat.CHANNEL_IN_VOICE_UPLINK + | AudioFormat.CHANNEL_IN_VOICE_DNLINK + | AudioFormat.CHANNEL_IN_MONO; + } + } + return AudioFormat.CHANNEL_INVALID; + default: + return AudioFormat.CHANNEL_INVALID; + } + } + + /** Convert from AIDL AudioConfig to SDK AudioFormat. */ + @VisibleForTesting + public static @NonNull AudioFormat aidl2api_AudioConfig_AudioFormat( + @NonNull AudioConfig audioConfig, boolean isInput) { + AudioFormat.Builder apiBuilder = new AudioFormat.Builder(); + apiBuilder.setSampleRate(audioConfig.sampleRateHz); + if (audioConfig.channelMask.getTag() != AudioChannelLayout.indexMask) { + apiBuilder.setChannelMask(aidl2api_AudioChannelLayout_AudioFormatChannelMask( + audioConfig.channelMask, isInput)); + } else { + apiBuilder.setChannelIndexMask(aidl2api_AudioChannelLayout_AudioFormatChannelMask( + audioConfig.channelMask, isInput)); + } + apiBuilder.setEncoding(aidl2api_AudioFormat_AudioFormatEncoding(audioConfig.format)); + return apiBuilder.build(); + } + + /** Convert from AIDL AudioFormat to SDK AudioFormat.ENCODING_*. */ + @VisibleForTesting + public static int aidl2api_AudioFormat_AudioFormatEncoding( + @NonNull AudioFormatDescription aidlFormat) { + switch (aidlFormat.type) { + case AudioFormatType.PCM: + switch (aidlFormat.pcm) { + case PcmType.UINT_8_BIT: + return AudioFormat.ENCODING_PCM_8BIT; + case PcmType.INT_16_BIT: + return AudioFormat.ENCODING_PCM_16BIT; + case PcmType.INT_32_BIT: + return AudioFormat.ENCODING_PCM_32BIT; + case PcmType.FIXED_Q_8_24: + case PcmType.FLOAT_32_BIT: + return AudioFormat.ENCODING_PCM_FLOAT; + case PcmType.INT_24_BIT: + return AudioFormat.ENCODING_PCM_24BIT_PACKED; + default: + return AudioFormat.ENCODING_INVALID; + } + case AudioFormatType.NON_PCM: // same as DEFAULT + if (aidlFormat.encoding != null && !aidlFormat.encoding.isEmpty()) { + if (MediaFormat.MIMETYPE_AUDIO_AC3.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_AC3; + } else if (MediaFormat.MIMETYPE_AUDIO_EAC3.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_E_AC3; + } else if (MediaFormat.MIMETYPE_AUDIO_DTS.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_DTS; + } else if (MediaFormat.MIMETYPE_AUDIO_DTS_HD.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_DTS_HD; + } else if (MediaFormat.MIMETYPE_AUDIO_MPEG.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_MP3; + } else if (MediaFormat.MIMETYPE_AUDIO_AAC_LC.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_AAC_LC; + } else if (MediaFormat.MIMETYPE_AUDIO_AAC_HE_V1.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_AAC_HE_V1; + } else if (MediaFormat.MIMETYPE_AUDIO_AAC_HE_V2.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_AAC_HE_V2; + } else if (MediaFormat.MIMETYPE_AUDIO_IEC61937.equals(aidlFormat.encoding) + && aidlFormat.pcm == PcmType.INT_16_BIT) { + return AudioFormat.ENCODING_IEC61937; + } else if (MediaFormat.MIMETYPE_AUDIO_DOLBY_TRUEHD.equals( + aidlFormat.encoding)) { + return AudioFormat.ENCODING_DOLBY_TRUEHD; + } else if (MediaFormat.MIMETYPE_AUDIO_AAC_ELD.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_AAC_ELD; + } else if (MediaFormat.MIMETYPE_AUDIO_AAC_XHE.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_AAC_XHE; + } else if (MediaFormat.MIMETYPE_AUDIO_AC4.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_AC4; + } else if (MediaFormat.MIMETYPE_AUDIO_EAC3_JOC.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_E_AC3_JOC; + } else if (MediaFormat.MIMETYPE_AUDIO_DOLBY_MAT.equals(aidlFormat.encoding) + || aidlFormat.encoding.startsWith( + MediaFormat.MIMETYPE_AUDIO_DOLBY_MAT + ".")) { + return AudioFormat.ENCODING_DOLBY_MAT; + } else if (MediaFormat.MIMETYPE_AUDIO_OPUS.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_OPUS; + } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_BL_L3.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_MPEGH_BL_L3; + } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_BL_L4.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_MPEGH_BL_L4; + } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_LC_L3.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_MPEGH_LC_L3; + } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_LC_L4.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_MPEGH_LC_L4; + } else if (MediaFormat.MIMETYPE_AUDIO_DTS_UHD.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_DTS_UHD; + } else if (MediaFormat.MIMETYPE_AUDIO_DRA.equals(aidlFormat.encoding)) { + return AudioFormat.ENCODING_DRA; + } else { + return AudioFormat.ENCODING_INVALID; + } + } else { + return AudioFormat.ENCODING_DEFAULT; + } + case AudioFormatType.SYS_RESERVED_INVALID: + default: + return AudioFormat.ENCODING_INVALID; + } + } + + private static native int aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t( + Parcel aidl, boolean isInput); + private static native Parcel legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel( + int legacy, boolean isInput); + private static native int aidl2legacy_AudioFormatDescription_Parcel_audio_format_t( + Parcel aidl); + private static native Parcel legacy2aidl_audio_format_t_AudioFormatDescription_Parcel( + int legacy); +} diff --git a/media/tests/aidltests/Android.bp b/media/tests/aidltests/Android.bp new file mode 100644 index 0000000000000..c3d5fa2ae224e --- /dev/null +++ b/media/tests/aidltests/Android.bp @@ -0,0 +1,40 @@ +// +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "AidlConversionUnitTests", + srcs: ["src/**/*.java"], + static_libs: [ + "androidx.test.rules", + "platform-test-annotations", + ], + libs: [ + "framework", + ], + sdk_version: "current", + platform_apis: true, + test_suites: ["device-tests"], + certificate: "platform", +} diff --git a/media/tests/aidltests/AndroidManifest.xml b/media/tests/aidltests/AndroidManifest.xml new file mode 100644 index 0000000000000..ffa895af34577 --- /dev/null +++ b/media/tests/aidltests/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + diff --git a/media/tests/aidltests/AndroidTest.xml b/media/tests/aidltests/AndroidTest.xml new file mode 100644 index 0000000000000..fb27a3c6bdd4a --- /dev/null +++ b/media/tests/aidltests/AndroidTest.xml @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java b/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java new file mode 100644 index 0000000000000..c9e79e699a4d8 --- /dev/null +++ b/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.audio.common; + +import android.media.AudioFormat; +import android.media.AudioSystem; +import android.media.MediaFormat; +import android.platform.test.annotations.Presubmit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Unit tests for AidlConversion utilities. + * + * Run with "atest AidlConversionUnitTests". + */ +@Presubmit +@RunWith(JUnit4.class) +public final class AidlConversionUnitTests { + + private static final String TAG = "AidlConvTests"; + + @Test + public void testAudioChannelConversionApiDefault() { + final AudioChannelLayout aidl = new AudioChannelLayout(); + final int api = AidlConversion.aidl2api_AudioChannelLayout_AudioFormatChannelMask( + aidl, false /*isInput*/); + assertEquals(AudioFormat.CHANNEL_OUT_DEFAULT, api); + final int apiInput = AidlConversion.aidl2api_AudioChannelLayout_AudioFormatChannelMask( + aidl, true /*isInput*/); + assertEquals(AudioFormat.CHANNEL_IN_DEFAULT, apiInput); + } + + @Test + public void testAudioChannelConversionApiOutput() { + final AudioChannelLayout aidl = AudioChannelLayout.layoutMask( + AudioChannelLayout.LAYOUT_MONO); + final int api = AidlConversion.aidl2api_AudioChannelLayout_AudioFormatChannelMask( + aidl, false /*isInput*/); + assertEquals(AudioFormat.CHANNEL_OUT_MONO, api); + } + + @Test + public void testAudioChannelConversionApiInput() { + final AudioChannelLayout aidl = AudioChannelLayout.layoutMask( + AudioChannelLayout.LAYOUT_MONO); + final int api = AidlConversion.aidl2api_AudioChannelLayout_AudioFormatChannelMask( + aidl, true /*isInput*/); + assertEquals(AudioFormat.CHANNEL_IN_MONO, api); + } + + @Test + public void testAudioChannelConversionApiIndex() { + final AudioChannelLayout aidl = AudioChannelLayout.indexMask( + AudioChannelLayout.INDEX_MASK_1); + final int api = AidlConversion.aidl2api_AudioChannelLayout_AudioFormatChannelMask( + aidl, false /*isInput*/); + assertEquals(1, api); + final int apiInput = AidlConversion.aidl2api_AudioChannelLayout_AudioFormatChannelMask( + aidl, true /*isInput*/); + assertEquals(1, apiInput); + } + + @Test + public void testAudioChannelConversionApiVoice() { + final AudioChannelLayout aidl = AudioChannelLayout.voiceMask( + AudioChannelLayout.VOICE_UPLINK_MONO); + final int api = AidlConversion.aidl2api_AudioChannelLayout_AudioFormatChannelMask( + aidl, true /*isInput*/); + assertEquals(AudioFormat.CHANNEL_IN_VOICE_UPLINK | AudioFormat.CHANNEL_IN_MONO, api); + } + + @Test + public void testAudioConfigConfersionApiIndex() { + final AudioConfig aidl = new AudioConfig(); + aidl.sampleRateHz = 8000; + aidl.channelMask = AudioChannelLayout.indexMask(AudioChannelLayout.INDEX_MASK_1); + aidl.format = createPcm16FormatAidl(); + // Other fields in AudioConfig are irrelevant. + final AudioFormat api = AidlConversion.aidl2api_AudioConfig_AudioFormat( + aidl, false /*isInput*/); + final AudioFormat apiInput = AidlConversion.aidl2api_AudioConfig_AudioFormat( + aidl, true /*isInput*/); + assertEquals(api, apiInput); + assertEquals(8000, api.getSampleRate()); + assertEquals(1, api.getChannelIndexMask()); + assertEquals(AudioFormat.ENCODING_PCM_16BIT, api.getEncoding()); + } + + @Test + public void testAudioConfigConfersionApiLayout() { + final AudioConfig aidl = new AudioConfig(); + aidl.sampleRateHz = 8000; + aidl.channelMask = AudioChannelLayout.layoutMask(AudioChannelLayout.LAYOUT_MONO); + aidl.format = createPcm16FormatAidl(); + // Other fields in AudioConfig are irrelevant. + final AudioFormat api = AidlConversion.aidl2api_AudioConfig_AudioFormat( + aidl, false /*isInput*/); + assertEquals(8000, api.getSampleRate()); + assertEquals(AudioFormat.CHANNEL_OUT_MONO, api.getChannelMask()); + assertEquals(AudioFormat.ENCODING_PCM_16BIT, api.getEncoding()); + final AudioFormat apiInput = AidlConversion.aidl2api_AudioConfig_AudioFormat( + aidl, true /*isInput*/); + assertEquals(8000, apiInput.getSampleRate()); + assertEquals(AudioFormat.CHANNEL_IN_MONO, apiInput.getChannelMask()); + assertEquals(AudioFormat.ENCODING_PCM_16BIT, apiInput.getEncoding()); + } + + @Test + public void testAudioFormatConversionApiDefault() { + final AudioFormatDescription aidl = new AudioFormatDescription(); + final int api = AidlConversion.aidl2api_AudioFormat_AudioFormatEncoding(aidl); + assertEquals(AudioFormat.ENCODING_DEFAULT, api); + } + + @Test + public void testAudioFormatConversionApiPcm16() { + final AudioFormatDescription aidl = createPcm16FormatAidl(); + final int api = AidlConversion.aidl2api_AudioFormat_AudioFormatEncoding(aidl); + assertEquals(AudioFormat.ENCODING_PCM_16BIT, api); + } + + @Test + public void testAudioFormatConversionApiAacLc() { + final AudioFormatDescription aidl = new AudioFormatDescription(); + aidl.type = AudioFormatType.NON_PCM; + aidl.encoding = MediaFormat.MIMETYPE_AUDIO_AAC_LC; + final int api = AidlConversion.aidl2api_AudioFormat_AudioFormatEncoding(aidl); + assertEquals(AudioFormat.ENCODING_AAC_LC, api); + } + + @Test + public void testAudioChannelConversionLegacyDefault() { + final int legacy = 0; /*AUDIO_CHANNEL_NONE*/ + final AudioChannelLayout aidl = + AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + legacy, false /*isInput*/); + final AudioChannelLayout aidlInput = + AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + legacy, true /*isInput*/); + assertEquals(aidl, aidlInput); + assertEquals(AudioChannelLayout.none, aidl.getTag()); + final int legacyBack = + AidlConversion.aidl2legacy_AudioChannelLayout_audio_channel_mask_t( + aidl, false /*isInput*/); + final int legacyBackInput = + AidlConversion.aidl2legacy_AudioChannelLayout_audio_channel_mask_t( + aidl, true /*isInput*/); + assertEquals(legacy, legacyBack); + assertEquals(legacy, legacyBackInput); + } + + @Test + public void testAudioChannelConversionLegacyOutput() { + final int legacy = 1; /*AUDIO_CHANNEL_OUT_MONO*/ + final AudioChannelLayout aidl = + AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + legacy, false /*isInput*/); + assertEquals(AudioChannelLayout.layoutMask, aidl.getTag()); + assertEquals(AudioChannelLayout.LAYOUT_MONO, aidl.getLayoutMask()); + final int legacyBack = + AidlConversion.aidl2legacy_AudioChannelLayout_audio_channel_mask_t( + aidl, false /*isInput*/); + assertEquals(legacy, legacyBack); + } + + @Test + public void testAudioChannelConversionLegacyInput() { + final int legacy = 0x10; /*AUDIO_CHANNEL_IN_MONO*/ + final AudioChannelLayout aidl = + AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + legacy, true /*isInput*/); + assertEquals(AudioChannelLayout.layoutMask, aidl.getTag()); + assertEquals(AudioChannelLayout.LAYOUT_MONO, aidl.getLayoutMask()); + final int legacyBack = + AidlConversion.aidl2legacy_AudioChannelLayout_audio_channel_mask_t( + aidl, true /*isInput*/); + assertEquals(legacy, legacyBack); + } + + @Test + public void testAudioChannelConversionLegacyIndex() { + final int legacy = 0x80000001; /*AUDIO_CHANNEL_INDEX_MASK_1*/ + final AudioChannelLayout aidl = + AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + legacy, false /*isInput*/); + final AudioChannelLayout aidlInput = + AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + legacy, true /*isInput*/); + assertEquals(aidl, aidlInput); + assertEquals(AudioChannelLayout.indexMask, aidl.getTag()); + assertEquals(AudioChannelLayout.INDEX_MASK_1, aidl.getIndexMask()); + final int legacyBack = + AidlConversion.aidl2legacy_AudioChannelLayout_audio_channel_mask_t( + aidl, false /*isInput*/); + final int legacyBackInput = + AidlConversion.aidl2legacy_AudioChannelLayout_audio_channel_mask_t( + aidl, true /*isInput*/); + assertEquals(legacy, legacyBack); + assertEquals(legacy, legacyBackInput); + } + + @Test + public void testAudioChannelConversionLegacyVoice() { + final int legacy = 0x4010; /*AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO*/ + final AudioChannelLayout aidl = + AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + legacy, true /*isInput*/); + assertEquals(AudioChannelLayout.voiceMask, aidl.getTag()); + assertEquals(AudioChannelLayout.VOICE_UPLINK_MONO, aidl.getVoiceMask()); + final int legacyBack = + AidlConversion.aidl2legacy_AudioChannelLayout_audio_channel_mask_t( + aidl, true /*isInput*/); + assertEquals(legacy, legacyBack); + } + + @Test + public void testAudioFormatConversionLegacyDefault() { + final int legacy = AudioSystem.AUDIO_FORMAT_DEFAULT; + final AudioFormatDescription aidl = + AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription(legacy); + assertEquals(AudioFormatType.DEFAULT, aidl.type); + assertNotNull(aidl.encoding); + assertTrue(aidl.encoding.isEmpty()); + final int legacyBack = + AidlConversion.aidl2legacy_AudioFormatDescription_audio_format_t(aidl); + assertEquals(legacy, legacyBack); + } + + @Test + public void testAudioFormatConversionLegacyPcm16() { + final int legacy = 1; /*AUDIO_FORMAT_PCM_16_BIT*/ + final AudioFormatDescription aidl = + AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription(legacy); + assertEquals(AudioFormatType.PCM, aidl.type); + assertEquals(PcmType.INT_16_BIT, aidl.pcm); + final int legacyBack = + AidlConversion.aidl2legacy_AudioFormatDescription_audio_format_t(aidl); + assertEquals(legacy, legacyBack); + } + + @Test + public void testAudioFormatConversionLegacyAac() { + final int legacy = AudioSystem.AUDIO_FORMAT_AAC; + final AudioFormatDescription aidl = + AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription(legacy); + assertEquals(AudioFormatType.NON_PCM, aidl.type); + assertNotNull(aidl.encoding); + assertFalse(aidl.encoding.isEmpty()); + final int legacyBack = + AidlConversion.aidl2legacy_AudioFormatDescription_audio_format_t(aidl); + assertEquals(legacy, legacyBack); + } + + private AudioFormatDescription createPcm16FormatAidl() { + final AudioFormatDescription aidl = new AudioFormatDescription(); + aidl.type = AudioFormatType.PCM; + aidl.pcm = PcmType.INT_16_BIT; + return aidl; + } +} diff --git a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java index e006b65255264..c170603cc7b65 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java @@ -21,6 +21,9 @@ import android.annotation.Nullable; import android.hardware.audio.common.V2_0.Uuid; import android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback; import android.hardware.soundtrigger.V2_3.ISoundTriggerHw; +import android.media.audio.common.AidlConversion; +import android.media.audio.common.AudioConfig; +import android.media.audio.common.AudioOffloadInfo; import android.media.soundtrigger.AudioCapabilities; import android.media.soundtrigger.ConfidenceLevel; import android.media.soundtrigger.ModelParameter; @@ -36,8 +39,6 @@ import android.media.soundtrigger.RecognitionMode; import android.media.soundtrigger.RecognitionStatus; import android.media.soundtrigger.SoundModel; import android.media.soundtrigger.SoundModelType; -import android.media.audio.common.AudioConfig; -import android.media.audio.common.AudioOffloadInfo; import android.os.HidlMemory; import android.os.HidlMemoryUtil; import android.os.ParcelFileDescriptor; @@ -303,7 +304,7 @@ class ConversionUtil { aidlEvent.captureDelayMs = hidlEvent.captureDelayMs; aidlEvent.capturePreambleMs = hidlEvent.capturePreambleMs; aidlEvent.triggerInData = hidlEvent.triggerInData; - aidlEvent.audioConfig = hidl2aidlAudioConfig(hidlEvent.audioConfig); + aidlEvent.audioConfig = hidl2aidlAudioConfig(hidlEvent.audioConfig, true /*isInput*/); aidlEvent.data = new byte[hidlEvent.data.size()]; for (int i = 0; i < aidlEvent.data.length; ++i) { aidlEvent.data[i] = hidlEvent.data.get(i); @@ -348,13 +349,16 @@ class ConversionUtil { static @NonNull AudioConfig hidl2aidlAudioConfig( - @NonNull android.hardware.audio.common.V2_0.AudioConfig hidlConfig) { + @NonNull android.hardware.audio.common.V2_0.AudioConfig hidlConfig, boolean isInput) { AudioConfig aidlConfig = new AudioConfig(); - // TODO(ytai): channelMask and format might need a more careful conversion to make sure the - // constants match. aidlConfig.sampleRateHz = hidlConfig.sampleRateHz; - aidlConfig.channelMask = hidlConfig.channelMask; - aidlConfig.format = hidlConfig.format; + // Relies on the fact that HIDL AudioChannelMask uses the same constant values as + // system/audio.h. + aidlConfig.channelMask = AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + hidlConfig.channelMask, isInput); + // Relies on the fact that HIDL AudioFormat uses the same constant values as system/audio.h. + aidlConfig.format = AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription( + hidlConfig.format); aidlConfig.offloadInfo = hidl2aidlOffloadInfo(hidlConfig.offloadInfo); aidlConfig.frameCount = hidlConfig.frameCount; return aidlConfig; @@ -364,19 +368,23 @@ class ConversionUtil { AudioOffloadInfo hidl2aidlOffloadInfo( @NonNull android.hardware.audio.common.V2_0.AudioOffloadInfo hidlInfo) { AudioOffloadInfo aidlInfo = new AudioOffloadInfo(); - // TODO(ytai): channelMask, format, streamType and usage might need a more careful - // conversion to make sure the constants match. aidlInfo.sampleRateHz = hidlInfo.sampleRateHz; - aidlInfo.channelMask = hidlInfo.channelMask; - aidlInfo.format = hidlInfo.format; - aidlInfo.streamType = hidlInfo.streamType; + // Relies on the fact that HIDL AudioChannelMask uses the same constant values as + // system/audio.h. + aidlInfo.channelMask = AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + hidlInfo.channelMask, false /*isInput*/); + // Relies on the fact that HIDL AudioFormat uses the same constant values as system/audio.h. + aidlInfo.format = AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription( + hidlInfo.format); + aidlInfo.streamType = AidlConversion.legacy2aidl_audio_stream_type_t_AudioStreamType( + hidlInfo.streamType); aidlInfo.bitRatePerSecond = hidlInfo.bitRatePerSecond; aidlInfo.durationMicroseconds = hidlInfo.durationMicroseconds; aidlInfo.hasVideo = hidlInfo.hasVideo; aidlInfo.isStreaming = hidlInfo.isStreaming; aidlInfo.bitWidth = hidlInfo.bitWidth; aidlInfo.bufferSize = hidlInfo.bufferSize; - aidlInfo.usage = hidlInfo.usage; + aidlInfo.usage = AidlConversion.legacy2aidl_audio_usage_t_AudioUsage(hidlInfo.usage); return aidlInfo; } diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java index 4eca298f68a7b..6ed9dde43f66e 100644 --- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java +++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java @@ -23,9 +23,12 @@ import static org.junit.Assert.assertTrue; import android.annotation.NonNull; import android.hardware.soundtrigger.V2_1.ISoundTriggerHw; import android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback; -import android.media.audio.common.AudioChannelMask; +import android.media.AudioFormat; +import android.media.MediaFormat; +import android.media.audio.common.AudioChannelLayout; import android.media.audio.common.AudioConfig; -import android.media.audio.common.AudioFormat; +import android.media.audio.common.AudioFormatDescription; +import android.media.audio.common.AudioFormatType; import android.media.soundtrigger.AudioCapabilities; import android.media.soundtrigger.ConfidenceLevel; import android.media.soundtrigger.Phrase; @@ -53,6 +56,8 @@ import java.util.List; * corresponding objects generated by the system under test. */ class TestUtil { + private static final int AUDIO_FORMAT_MP3 = 0x01000000; // matches native + static SoundModel createGenericSoundModel() { return createSoundModel(SoundModelType.GENERIC); } @@ -310,8 +315,8 @@ class TestUtil { halEvent.capturePreambleMs = 345; halEvent.triggerInData = true; halEvent.audioConfig.sampleRateHz = 456; - halEvent.audioConfig.channelMask = AudioChannelMask.IN_LEFT; - halEvent.audioConfig.format = AudioFormat.MP3; + halEvent.audioConfig.channelMask = AudioFormat.CHANNEL_IN_MONO; // matches native + halEvent.audioConfig.format = AUDIO_FORMAT_MP3; // hwEvent.audioConfig.offloadInfo is irrelevant. halEvent.data.add((byte) 31); halEvent.data.add((byte) 32); @@ -319,6 +324,13 @@ class TestUtil { return halEvent; } + static AudioFormatDescription createAudioFormatMp3() { + AudioFormatDescription format = new AudioFormatDescription(); + format.type = AudioFormatType.NON_PCM; + format.encoding = MediaFormat.MIMETYPE_AUDIO_MPEG; // MP3 + return format; + } + static RecognitionEvent createRecognitionEvent(@RecognitionStatus int status) { RecognitionEvent event = new RecognitionEvent(); event.status = status; @@ -329,8 +341,9 @@ class TestUtil { event.triggerInData = true; event.audioConfig = new AudioConfig(); event.audioConfig.sampleRateHz = 456; - event.audioConfig.channelMask = AudioChannelMask.IN_LEFT; - event.audioConfig.format = AudioFormat.MP3; + event.audioConfig.channelMask = AudioChannelLayout.layoutMask( + AudioChannelLayout.LAYOUT_MONO); + event.audioConfig.format = createAudioFormatMp3(); //event.audioConfig.offloadInfo is irrelevant. event.data = new byte[]{31, 32, 33}; return event; @@ -355,8 +368,9 @@ class TestUtil { assertEquals(345, event.capturePreambleMs); assertTrue(event.triggerInData); assertEquals(456, event.audioConfig.sampleRateHz); - assertEquals(AudioChannelMask.IN_LEFT, event.audioConfig.channelMask); - assertEquals(AudioFormat.MP3, event.audioConfig.format); + assertEquals(AudioChannelLayout.layoutMask(AudioChannelLayout.LAYOUT_MONO), + event.audioConfig.channelMask); + assertEquals(createAudioFormatMp3(), event.audioConfig.format); assertArrayEquals(new byte[]{31, 32, 33}, event.data); }