--- /dev/null
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+#ifndef HIDL_GENERATED_android_hardware_audio_common_V2_0_EXPORTED_CONSTANTS_H_
+#define HIDL_GENERATED_android_hardware_audio_common_V2_0_EXPORTED_CONSTANTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ AUDIO_STREAM_DEFAULT = -1, // (-1)
+ AUDIO_STREAM_MIN = 0,
+ AUDIO_STREAM_VOICE_CALL = 0,
+ AUDIO_STREAM_SYSTEM = 1,
+ AUDIO_STREAM_RING = 2,
+ AUDIO_STREAM_MUSIC = 3,
+ AUDIO_STREAM_ALARM = 4,
+ AUDIO_STREAM_NOTIFICATION = 5,
+ AUDIO_STREAM_BLUETOOTH_SCO = 6,
+ AUDIO_STREAM_ENFORCED_AUDIBLE = 7,
+ AUDIO_STREAM_DTMF = 8,
+ AUDIO_STREAM_TTS = 9,
+ AUDIO_STREAM_ACCESSIBILITY = 10,
+ AUDIO_STREAM_REROUTING = 11,
+ AUDIO_STREAM_PATCH = 12,
+ AUDIO_STREAM_PUBLIC_CNT = 10, // (AUDIO_STREAM_TTS + 1)
+ AUDIO_STREAM_FOR_POLICY_CNT = 12, // AUDIO_STREAM_PATCH
+ AUDIO_STREAM_CNT = 13, // (AUDIO_STREAM_PATCH + 1)
+} audio_stream_type_t;
+
+typedef enum {
+ AUDIO_SOURCE_DEFAULT = 0,
+ AUDIO_SOURCE_MIC = 1,
+ AUDIO_SOURCE_VOICE_UPLINK = 2,
+ AUDIO_SOURCE_VOICE_DOWNLINK = 3,
+ AUDIO_SOURCE_VOICE_CALL = 4,
+ AUDIO_SOURCE_CAMCORDER = 5,
+ AUDIO_SOURCE_VOICE_RECOGNITION = 6,
+ AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
+ AUDIO_SOURCE_REMOTE_SUBMIX = 8,
+ AUDIO_SOURCE_UNPROCESSED = 9,
+ AUDIO_SOURCE_CNT = 10,
+ AUDIO_SOURCE_MAX = 9, // (AUDIO_SOURCE_CNT - 1)
+ AUDIO_SOURCE_FM_TUNER = 1998,
+ AUDIO_SOURCE_HOTWORD = 1999,
+} audio_source_t;
+
+typedef enum {
+ AUDIO_SESSION_OUTPUT_STAGE = -1, // (-1)
+ AUDIO_SESSION_OUTPUT_MIX = 0,
+ AUDIO_SESSION_ALLOCATE = 0,
+ AUDIO_SESSION_NONE = 0,
+} audio_session_t;
+
+typedef enum {
+ AUDIO_FORMAT_INVALID = 4294967295u, // 0xFFFFFFFFUL
+ AUDIO_FORMAT_DEFAULT = 0u, // 0
+ AUDIO_FORMAT_PCM = 0u, // 0x00000000UL
+ AUDIO_FORMAT_MP3 = 16777216u, // 0x01000000UL
+ AUDIO_FORMAT_AMR_NB = 33554432u, // 0x02000000UL
+ AUDIO_FORMAT_AMR_WB = 50331648u, // 0x03000000UL
+ AUDIO_FORMAT_AAC = 67108864u, // 0x04000000UL
+ AUDIO_FORMAT_HE_AAC_V1 = 83886080u, // 0x05000000UL
+ AUDIO_FORMAT_HE_AAC_V2 = 100663296u, // 0x06000000UL
+ AUDIO_FORMAT_VORBIS = 117440512u, // 0x07000000UL
+ AUDIO_FORMAT_OPUS = 134217728u, // 0x08000000UL
+ AUDIO_FORMAT_AC3 = 150994944u, // 0x09000000UL
+ AUDIO_FORMAT_E_AC3 = 167772160u, // 0x0A000000UL
+ AUDIO_FORMAT_DTS = 184549376u, // 0x0B000000UL
+ AUDIO_FORMAT_DTS_HD = 201326592u, // 0x0C000000UL
+ AUDIO_FORMAT_IEC61937 = 218103808u, // 0x0D000000UL
+ AUDIO_FORMAT_DOLBY_TRUEHD = 234881024u, // 0x0E000000UL
+ AUDIO_FORMAT_MAIN_MASK = 4278190080u, // 0xFF000000UL
+ AUDIO_FORMAT_SUB_MASK = 16777215u, // 0x00FFFFFFUL
+ AUDIO_FORMAT_PCM_SUB_16_BIT = 1u, // 0x1
+ AUDIO_FORMAT_PCM_SUB_8_BIT = 2u, // 0x2
+ AUDIO_FORMAT_PCM_SUB_32_BIT = 3u, // 0x3
+ AUDIO_FORMAT_PCM_SUB_8_24_BIT = 4u, // 0x4
+ AUDIO_FORMAT_PCM_SUB_FLOAT = 5u, // 0x5
+ AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED = 6u, // 0x6
+ AUDIO_FORMAT_MP3_SUB_NONE = 0u, // 0x0
+ AUDIO_FORMAT_AMR_SUB_NONE = 0u, // 0x0
+ AUDIO_FORMAT_AAC_SUB_MAIN = 1u, // 0x1
+ AUDIO_FORMAT_AAC_SUB_LC = 2u, // 0x2
+ AUDIO_FORMAT_AAC_SUB_SSR = 4u, // 0x4
+ AUDIO_FORMAT_AAC_SUB_LTP = 8u, // 0x8
+ AUDIO_FORMAT_AAC_SUB_HE_V1 = 16u, // 0x10
+ AUDIO_FORMAT_AAC_SUB_SCALABLE = 32u, // 0x20
+ AUDIO_FORMAT_AAC_SUB_ERLC = 64u, // 0x40
+ AUDIO_FORMAT_AAC_SUB_LD = 128u, // 0x80
+ AUDIO_FORMAT_AAC_SUB_HE_V2 = 256u, // 0x100
+ AUDIO_FORMAT_AAC_SUB_ELD = 512u, // 0x200
+ AUDIO_FORMAT_VORBIS_SUB_NONE = 0u, // 0x0
+ AUDIO_FORMAT_PCM_16_BIT = 1u, // (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_16_BIT)
+ AUDIO_FORMAT_PCM_8_BIT = 2u, // (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_8_BIT)
+ AUDIO_FORMAT_PCM_32_BIT = 3u, // (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_32_BIT)
+ AUDIO_FORMAT_PCM_8_24_BIT = 4u, // (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_8_24_BIT)
+ AUDIO_FORMAT_PCM_FLOAT = 5u, // (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_FLOAT)
+ AUDIO_FORMAT_PCM_24_BIT_PACKED = 6u, // (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED)
+ AUDIO_FORMAT_AAC_MAIN = 67108865u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_MAIN)
+ AUDIO_FORMAT_AAC_LC = 67108866u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_LC)
+ AUDIO_FORMAT_AAC_SSR = 67108868u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_SSR)
+ AUDIO_FORMAT_AAC_LTP = 67108872u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_LTP)
+ AUDIO_FORMAT_AAC_HE_V1 = 67108880u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_HE_V1)
+ AUDIO_FORMAT_AAC_SCALABLE = 67108896u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_SCALABLE)
+ AUDIO_FORMAT_AAC_ERLC = 67108928u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_ERLC)
+ AUDIO_FORMAT_AAC_LD = 67108992u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_LD)
+ AUDIO_FORMAT_AAC_HE_V2 = 67109120u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_HE_V2)
+ AUDIO_FORMAT_AAC_ELD = 67109376u, // (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_ELD)
+} audio_format_t;
+
+enum {
+ FCC_2 = 2,
+ FCC_8 = 8,
+};
+
+enum {
+ AUDIO_CHANNEL_REPRESENTATION_POSITION = 0u, // 0
+ AUDIO_CHANNEL_REPRESENTATION_INDEX = 2u, // 2
+ AUDIO_CHANNEL_NONE = 0u, // 0x0
+ AUDIO_CHANNEL_INVALID = 3221225472u, // 0xC0000000
+ AUDIO_CHANNEL_OUT_FRONT_LEFT = 1u, // 0x1
+ AUDIO_CHANNEL_OUT_FRONT_RIGHT = 2u, // 0x2
+ AUDIO_CHANNEL_OUT_FRONT_CENTER = 4u, // 0x4
+ AUDIO_CHANNEL_OUT_LOW_FREQUENCY = 8u, // 0x8
+ AUDIO_CHANNEL_OUT_BACK_LEFT = 16u, // 0x10
+ AUDIO_CHANNEL_OUT_BACK_RIGHT = 32u, // 0x20
+ AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 64u, // 0x40
+ AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 128u, // 0x80
+ AUDIO_CHANNEL_OUT_BACK_CENTER = 256u, // 0x100
+ AUDIO_CHANNEL_OUT_SIDE_LEFT = 512u, // 0x200
+ AUDIO_CHANNEL_OUT_SIDE_RIGHT = 1024u, // 0x400
+ AUDIO_CHANNEL_OUT_TOP_CENTER = 2048u, // 0x800
+ AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT = 4096u, // 0x1000
+ AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER = 8192u, // 0x2000
+ AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT = 16384u, // 0x4000
+ AUDIO_CHANNEL_OUT_TOP_BACK_LEFT = 32768u, // 0x8000
+ AUDIO_CHANNEL_OUT_TOP_BACK_CENTER = 65536u, // 0x10000
+ AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT = 131072u, // 0x20000
+ AUDIO_CHANNEL_OUT_MONO = 1u, // AUDIO_CHANNEL_OUT_FRONT_LEFT
+ AUDIO_CHANNEL_OUT_STEREO = 3u, // (AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT)
+ AUDIO_CHANNEL_OUT_QUAD = 51u, // (((AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT) | AUDIO_CHANNEL_OUT_BACK_LEFT) | AUDIO_CHANNEL_OUT_BACK_RIGHT)
+ AUDIO_CHANNEL_OUT_QUAD_BACK = 51u, // AUDIO_CHANNEL_OUT_QUAD
+ AUDIO_CHANNEL_OUT_QUAD_SIDE = 1539u, // (((AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT) | AUDIO_CHANNEL_OUT_SIDE_LEFT) | AUDIO_CHANNEL_OUT_SIDE_RIGHT)
+ AUDIO_CHANNEL_OUT_5POINT1 = 63u, // (((((AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT) | AUDIO_CHANNEL_OUT_FRONT_CENTER) | AUDIO_CHANNEL_OUT_LOW_FREQUENCY) | AUDIO_CHANNEL_OUT_BACK_LEFT) | AUDIO_CHANNEL_OUT_BACK_RIGHT)
+ AUDIO_CHANNEL_OUT_5POINT1_BACK = 63u, // AUDIO_CHANNEL_OUT_5POINT1
+ AUDIO_CHANNEL_OUT_5POINT1_SIDE = 1551u, // (((((AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT) | AUDIO_CHANNEL_OUT_FRONT_CENTER) | AUDIO_CHANNEL_OUT_LOW_FREQUENCY) | AUDIO_CHANNEL_OUT_SIDE_LEFT) | AUDIO_CHANNEL_OUT_SIDE_RIGHT)
+ AUDIO_CHANNEL_OUT_7POINT1 = 1599u, // (((((((AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT) | AUDIO_CHANNEL_OUT_FRONT_CENTER) | AUDIO_CHANNEL_OUT_LOW_FREQUENCY) | AUDIO_CHANNEL_OUT_BACK_LEFT) | AUDIO_CHANNEL_OUT_BACK_RIGHT) | AUDIO_CHANNEL_OUT_SIDE_LEFT) | AUDIO_CHANNEL_OUT_SIDE_RIGHT)
+ AUDIO_CHANNEL_OUT_ALL = 262143u, // (((((((((((((((((AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT) | AUDIO_CHANNEL_OUT_FRONT_CENTER) | AUDIO_CHANNEL_OUT_LOW_FREQUENCY) | AUDIO_CHANNEL_OUT_BACK_LEFT) | AUDIO_CHANNEL_OUT_BACK_RIGHT) | AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER) | AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER) | AUDIO_CHANNEL_OUT_BACK_CENTER) | AUDIO_CHANNEL_OUT_SIDE_LEFT) | AUDIO_CHANNEL_OUT_SIDE_RIGHT) | AUDIO_CHANNEL_OUT_TOP_CENTER) | AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT) | AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER) | AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT) | AUDIO_CHANNEL_OUT_TOP_BACK_LEFT) | AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) | AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT)
+ AUDIO_CHANNEL_IN_LEFT = 4u, // 0x4
+ AUDIO_CHANNEL_IN_RIGHT = 8u, // 0x8
+ AUDIO_CHANNEL_IN_FRONT = 16u, // 0x10
+ AUDIO_CHANNEL_IN_BACK = 32u, // 0x20
+ AUDIO_CHANNEL_IN_LEFT_PROCESSED = 64u, // 0x40
+ AUDIO_CHANNEL_IN_RIGHT_PROCESSED = 128u, // 0x80
+ AUDIO_CHANNEL_IN_FRONT_PROCESSED = 256u, // 0x100
+ AUDIO_CHANNEL_IN_BACK_PROCESSED = 512u, // 0x200
+ AUDIO_CHANNEL_IN_PRESSURE = 1024u, // 0x400
+ AUDIO_CHANNEL_IN_X_AXIS = 2048u, // 0x800
+ AUDIO_CHANNEL_IN_Y_AXIS = 4096u, // 0x1000
+ AUDIO_CHANNEL_IN_Z_AXIS = 8192u, // 0x2000
+ AUDIO_CHANNEL_IN_VOICE_UPLINK = 16384u, // 0x4000
+ AUDIO_CHANNEL_IN_VOICE_DNLINK = 32768u, // 0x8000
+ AUDIO_CHANNEL_IN_MONO = 16u, // AUDIO_CHANNEL_IN_FRONT
+ AUDIO_CHANNEL_IN_STEREO = 12u, // (AUDIO_CHANNEL_IN_LEFT | AUDIO_CHANNEL_IN_RIGHT)
+ AUDIO_CHANNEL_IN_FRONT_BACK = 48u, // (AUDIO_CHANNEL_IN_FRONT | AUDIO_CHANNEL_IN_BACK)
+ AUDIO_CHANNEL_IN_ALL = 65532u, // (((((((((((((AUDIO_CHANNEL_IN_LEFT | AUDIO_CHANNEL_IN_RIGHT) | AUDIO_CHANNEL_IN_FRONT) | AUDIO_CHANNEL_IN_BACK) | AUDIO_CHANNEL_IN_LEFT_PROCESSED) | AUDIO_CHANNEL_IN_RIGHT_PROCESSED) | AUDIO_CHANNEL_IN_FRONT_PROCESSED) | AUDIO_CHANNEL_IN_BACK_PROCESSED) | AUDIO_CHANNEL_IN_PRESSURE) | AUDIO_CHANNEL_IN_X_AXIS) | AUDIO_CHANNEL_IN_Y_AXIS) | AUDIO_CHANNEL_IN_Z_AXIS) | AUDIO_CHANNEL_IN_VOICE_UPLINK) | AUDIO_CHANNEL_IN_VOICE_DNLINK)
+ AUDIO_INTERLEAVE_LEFT = 0u, // 0
+ AUDIO_INTERLEAVE_RIGHT = 1u, // 1
+ AUDIO_CHANNEL_COUNT_MAX = 30u, // 30
+ AUDIO_CHANNEL_INDEX_HDR = 2147483648u, // (AUDIO_CHANNEL_REPRESENTATION_INDEX << AUDIO_CHANNEL_COUNT_MAX)
+ AUDIO_CHANNEL_INDEX_MASK_1 = 2147483649u, // (AUDIO_CHANNEL_INDEX_HDR | ((1 << 1) - 1))
+ AUDIO_CHANNEL_INDEX_MASK_2 = 2147483651u, // (AUDIO_CHANNEL_INDEX_HDR | ((1 << 2) - 1))
+ AUDIO_CHANNEL_INDEX_MASK_3 = 2147483655u, // (AUDIO_CHANNEL_INDEX_HDR | ((1 << 3) - 1))
+ AUDIO_CHANNEL_INDEX_MASK_4 = 2147483663u, // (AUDIO_CHANNEL_INDEX_HDR | ((1 << 4) - 1))
+ AUDIO_CHANNEL_INDEX_MASK_5 = 2147483679u, // (AUDIO_CHANNEL_INDEX_HDR | ((1 << 5) - 1))
+ AUDIO_CHANNEL_INDEX_MASK_6 = 2147483711u, // (AUDIO_CHANNEL_INDEX_HDR | ((1 << 6) - 1))
+ AUDIO_CHANNEL_INDEX_MASK_7 = 2147483775u, // (AUDIO_CHANNEL_INDEX_HDR | ((1 << 7) - 1))
+ AUDIO_CHANNEL_INDEX_MASK_8 = 2147483903u, // (AUDIO_CHANNEL_INDEX_HDR | ((1 << 8) - 1))
+};
+
+typedef enum {
+ AUDIO_MODE_INVALID = -2, // (-2)
+ AUDIO_MODE_CURRENT = -1, // (-1)
+ AUDIO_MODE_NORMAL = 0,
+ AUDIO_MODE_RINGTONE = 1,
+ AUDIO_MODE_IN_CALL = 2,
+ AUDIO_MODE_IN_COMMUNICATION = 3,
+ AUDIO_MODE_CNT = 4,
+ AUDIO_MODE_MAX = 3, // (AUDIO_MODE_CNT - 1)
+} audio_mode_t;
+
+enum {
+ AUDIO_DEVICE_NONE = 0u, // 0x0
+ AUDIO_DEVICE_BIT_IN = 2147483648u, // 0x80000000
+ AUDIO_DEVICE_BIT_DEFAULT = 1073741824u, // 0x40000000
+ AUDIO_DEVICE_OUT_EARPIECE = 1u, // 0x1
+ AUDIO_DEVICE_OUT_SPEAKER = 2u, // 0x2
+ AUDIO_DEVICE_OUT_WIRED_HEADSET = 4u, // 0x4
+ AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 8u, // 0x8
+ AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 16u, // 0x10
+ AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 32u, // 0x20
+ AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 64u, // 0x40
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 128u, // 0x80
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 256u, // 0x100
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 512u, // 0x200
+ AUDIO_DEVICE_OUT_AUX_DIGITAL = 1024u, // 0x400
+ AUDIO_DEVICE_OUT_HDMI = 1024u, // AUDIO_DEVICE_OUT_AUX_DIGITAL
+ AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 2048u, // 0x800
+ AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 4096u, // 0x1000
+ AUDIO_DEVICE_OUT_USB_ACCESSORY = 8192u, // 0x2000
+ AUDIO_DEVICE_OUT_USB_DEVICE = 16384u, // 0x4000
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 32768u, // 0x8000
+ AUDIO_DEVICE_OUT_TELEPHONY_TX = 65536u, // 0x10000
+ AUDIO_DEVICE_OUT_LINE = 131072u, // 0x20000
+ AUDIO_DEVICE_OUT_HDMI_ARC = 262144u, // 0x40000
+ AUDIO_DEVICE_OUT_SPDIF = 524288u, // 0x80000
+ AUDIO_DEVICE_OUT_FM = 1048576u, // 0x100000
+ AUDIO_DEVICE_OUT_AUX_LINE = 2097152u, // 0x200000
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE = 4194304u, // 0x400000
+ AUDIO_DEVICE_OUT_IP = 8388608u, // 0x800000
+ AUDIO_DEVICE_OUT_BUS = 16777216u, // 0x1000000
+ AUDIO_DEVICE_OUT_DEFAULT = 1073741824u, // AUDIO_DEVICE_BIT_DEFAULT
+ AUDIO_DEVICE_OUT_ALL = 1107296255u, // (((((((((((((((((((((((((AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER) | AUDIO_DEVICE_OUT_WIRED_HEADSET) | AUDIO_DEVICE_OUT_WIRED_HEADPHONE) | AUDIO_DEVICE_OUT_BLUETOOTH_SCO) | AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) | AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) | AUDIO_DEVICE_OUT_HDMI) | AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET) | AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) | AUDIO_DEVICE_OUT_USB_ACCESSORY) | AUDIO_DEVICE_OUT_USB_DEVICE) | AUDIO_DEVICE_OUT_REMOTE_SUBMIX) | AUDIO_DEVICE_OUT_TELEPHONY_TX) | AUDIO_DEVICE_OUT_LINE) | AUDIO_DEVICE_OUT_HDMI_ARC) | AUDIO_DEVICE_OUT_SPDIF) | AUDIO_DEVICE_OUT_FM) | AUDIO_DEVICE_OUT_AUX_LINE) | AUDIO_DEVICE_OUT_SPEAKER_SAFE) | AUDIO_DEVICE_OUT_IP) | AUDIO_DEVICE_OUT_BUS) | AUDIO_DEVICE_OUT_DEFAULT)
+ AUDIO_DEVICE_OUT_ALL_A2DP = 896u, // ((AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)
+ AUDIO_DEVICE_OUT_ALL_SCO = 112u, // ((AUDIO_DEVICE_OUT_BLUETOOTH_SCO | AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) | AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)
+ AUDIO_DEVICE_OUT_ALL_USB = 24576u, // (AUDIO_DEVICE_OUT_USB_ACCESSORY | AUDIO_DEVICE_OUT_USB_DEVICE)
+ AUDIO_DEVICE_IN_COMMUNICATION = 2147483649u, // (AUDIO_DEVICE_BIT_IN | 0x1)
+ AUDIO_DEVICE_IN_AMBIENT = 2147483650u, // (AUDIO_DEVICE_BIT_IN | 0x2)
+ AUDIO_DEVICE_IN_BUILTIN_MIC = 2147483652u, // (AUDIO_DEVICE_BIT_IN | 0x4)
+ AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = 2147483656u, // (AUDIO_DEVICE_BIT_IN | 0x8)
+ AUDIO_DEVICE_IN_WIRED_HEADSET = 2147483664u, // (AUDIO_DEVICE_BIT_IN | 0x10)
+ AUDIO_DEVICE_IN_AUX_DIGITAL = 2147483680u, // (AUDIO_DEVICE_BIT_IN | 0x20)
+ AUDIO_DEVICE_IN_HDMI = 2147483680u, // AUDIO_DEVICE_IN_AUX_DIGITAL
+ AUDIO_DEVICE_IN_VOICE_CALL = 2147483712u, // (AUDIO_DEVICE_BIT_IN | 0x40)
+ AUDIO_DEVICE_IN_TELEPHONY_RX = 2147483712u, // AUDIO_DEVICE_IN_VOICE_CALL
+ AUDIO_DEVICE_IN_BACK_MIC = 2147483776u, // (AUDIO_DEVICE_BIT_IN | 0x80)
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX = 2147483904u, // (AUDIO_DEVICE_BIT_IN | 0x100)
+ AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET = 2147484160u, // (AUDIO_DEVICE_BIT_IN | 0x200)
+ AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET = 2147484672u, // (AUDIO_DEVICE_BIT_IN | 0x400)
+ AUDIO_DEVICE_IN_USB_ACCESSORY = 2147485696u, // (AUDIO_DEVICE_BIT_IN | 0x800)
+ AUDIO_DEVICE_IN_USB_DEVICE = 2147487744u, // (AUDIO_DEVICE_BIT_IN | 0x1000)
+ AUDIO_DEVICE_IN_FM_TUNER = 2147491840u, // (AUDIO_DEVICE_BIT_IN | 0x2000)
+ AUDIO_DEVICE_IN_TV_TUNER = 2147500032u, // (AUDIO_DEVICE_BIT_IN | 0x4000)
+ AUDIO_DEVICE_IN_LINE = 2147516416u, // (AUDIO_DEVICE_BIT_IN | 0x8000)
+ AUDIO_DEVICE_IN_SPDIF = 2147549184u, // (AUDIO_DEVICE_BIT_IN | 0x10000)
+ AUDIO_DEVICE_IN_BLUETOOTH_A2DP = 2147614720u, // (AUDIO_DEVICE_BIT_IN | 0x20000)
+ AUDIO_DEVICE_IN_LOOPBACK = 2147745792u, // (AUDIO_DEVICE_BIT_IN | 0x40000)
+ AUDIO_DEVICE_IN_IP = 2148007936u, // (AUDIO_DEVICE_BIT_IN | 0x80000)
+ AUDIO_DEVICE_IN_BUS = 2148532224u, // (AUDIO_DEVICE_BIT_IN | 0x100000)
+ AUDIO_DEVICE_IN_DEFAULT = 3221225472u, // (AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT)
+ AUDIO_DEVICE_IN_ALL = 3223322623u, // (((((((((((((((((((((AUDIO_DEVICE_IN_COMMUNICATION | AUDIO_DEVICE_IN_AMBIENT) | AUDIO_DEVICE_IN_BUILTIN_MIC) | AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) | AUDIO_DEVICE_IN_WIRED_HEADSET) | AUDIO_DEVICE_IN_HDMI) | AUDIO_DEVICE_IN_TELEPHONY_RX) | AUDIO_DEVICE_IN_BACK_MIC) | AUDIO_DEVICE_IN_REMOTE_SUBMIX) | AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET) | AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) | AUDIO_DEVICE_IN_USB_ACCESSORY) | AUDIO_DEVICE_IN_USB_DEVICE) | AUDIO_DEVICE_IN_FM_TUNER) | AUDIO_DEVICE_IN_TV_TUNER) | AUDIO_DEVICE_IN_LINE) | AUDIO_DEVICE_IN_SPDIF) | AUDIO_DEVICE_IN_BLUETOOTH_A2DP) | AUDIO_DEVICE_IN_LOOPBACK) | AUDIO_DEVICE_IN_IP) | AUDIO_DEVICE_IN_BUS) | AUDIO_DEVICE_IN_DEFAULT)
+ AUDIO_DEVICE_IN_ALL_SCO = 2147483656u, // AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET
+ AUDIO_DEVICE_IN_ALL_USB = 2147489792u, // (AUDIO_DEVICE_IN_USB_ACCESSORY | AUDIO_DEVICE_IN_USB_DEVICE)
+};
+
+typedef enum {
+ AUDIO_OUTPUT_FLAG_NONE = 0, // 0x0
+ AUDIO_OUTPUT_FLAG_DIRECT = 1, // 0x1
+ AUDIO_OUTPUT_FLAG_PRIMARY = 2, // 0x2
+ AUDIO_OUTPUT_FLAG_FAST = 4, // 0x4
+ AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 8, // 0x8
+ AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD = 16, // 0x10
+ AUDIO_OUTPUT_FLAG_NON_BLOCKING = 32, // 0x20
+ AUDIO_OUTPUT_FLAG_HW_AV_SYNC = 64, // 0x40
+ AUDIO_OUTPUT_FLAG_TTS = 128, // 0x80
+ AUDIO_OUTPUT_FLAG_RAW = 256, // 0x100
+ AUDIO_OUTPUT_FLAG_SYNC = 512, // 0x200
+ AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO = 1024, // 0x400
+} audio_output_flags_t;
+
+typedef enum {
+ AUDIO_INPUT_FLAG_NONE = 0, // 0x0
+ AUDIO_INPUT_FLAG_FAST = 1, // 0x1
+ AUDIO_INPUT_FLAG_HW_HOTWORD = 2, // 0x2
+ AUDIO_INPUT_FLAG_RAW = 4, // 0x4
+ AUDIO_INPUT_FLAG_SYNC = 8, // 0x8
+} audio_input_flags_t;
+
+enum {
+ AUDIO_GAIN_MODE_JOINT = 1u, // 0x1
+ AUDIO_GAIN_MODE_CHANNELS = 2u, // 0x2
+ AUDIO_GAIN_MODE_RAMP = 4u, // 0x4
+};
+
+typedef enum {
+ AUDIO_PORT_ROLE_NONE = 0,
+ AUDIO_PORT_ROLE_SOURCE = 1,
+ AUDIO_PORT_ROLE_SINK = 2,
+} audio_port_role_t;
+
+typedef enum {
+ AUDIO_PORT_TYPE_NONE = 0,
+ AUDIO_PORT_TYPE_DEVICE = 1,
+ AUDIO_PORT_TYPE_MIX = 2,
+ AUDIO_PORT_TYPE_SESSION = 3,
+} audio_port_type_t;
+
+enum {
+ AUDIO_PORT_CONFIG_SAMPLE_RATE = 1u, // 0x1
+ AUDIO_PORT_CONFIG_CHANNEL_MASK = 2u, // 0x2
+ AUDIO_PORT_CONFIG_FORMAT = 4u, // 0x4
+ AUDIO_PORT_CONFIG_GAIN = 8u, // 0x8
+ AUDIO_PORT_CONFIG_ALL = 15u, // (((AUDIO_PORT_CONFIG_SAMPLE_RATE | AUDIO_PORT_CONFIG_CHANNEL_MASK) | AUDIO_PORT_CONFIG_FORMAT) | AUDIO_PORT_CONFIG_GAIN)
+};
+
+typedef enum {
+ AUDIO_LATENCY_LOW = 0,
+ AUDIO_LATENCY_NORMAL = 1,
+} audio_mix_latency_class_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HIDL_GENERATED_android_hardware_audio_common_V2_0_EXPORTED_CONSTANTS_H_
#include <cutils/bitops.h>
-__BEGIN_DECLS
-
-/* The macro FCC_2 highlights places where there are 2-channel assumptions.
- * This is typically due to legacy implementation of stereo input or output.
- * Search also for "2", "left", "right", "[0]", "[1]", ">> 16", "<< 16", etc.
- * Do not change this value.
- */
-#define FCC_2 2 // FCC_2 = Fixed Channel Count 2
+#include "audio-base.h"
-/* The macro FCC_8 highlights places where there are 8-channel assumptions.
- * This is typically due to audio mixer and resampler limitations.
- * Do not change this value without verifying all locations that use it.
- */
-#define FCC_8 8 // FCC_8 = Fixed Channel Count 8
+__BEGIN_DECLS
/* The enums were moved here mostly from
* frameworks/base/include/media/AudioSystem.h
typedef int audio_io_handle_t;
#define AUDIO_IO_HANDLE_NONE 0
-/* Audio stream types */
-typedef enum {
- /* These values must kept in sync with
- * frameworks/base/media/java/android/media/AudioSystem.java
- */
- AUDIO_STREAM_DEFAULT = -1,
- AUDIO_STREAM_MIN = 0,
- AUDIO_STREAM_VOICE_CALL = 0,
- AUDIO_STREAM_SYSTEM = 1,
- AUDIO_STREAM_RING = 2,
- AUDIO_STREAM_MUSIC = 3,
- AUDIO_STREAM_ALARM = 4,
- AUDIO_STREAM_NOTIFICATION = 5,
- AUDIO_STREAM_BLUETOOTH_SCO = 6,
- AUDIO_STREAM_ENFORCED_AUDIBLE = 7, /* Sounds that cannot be muted by user
- * and must be routed to speaker
- */
- AUDIO_STREAM_DTMF = 8,
- AUDIO_STREAM_TTS = 9, /* Transmitted Through Speaker.
- * Plays over speaker only, silent on other devices.
- */
- AUDIO_STREAM_ACCESSIBILITY = 10, /* For accessibility talk back prompts */
- AUDIO_STREAM_REROUTING = 11, /* For dynamic policy output mixes */
- AUDIO_STREAM_PATCH = 12, /* For internal audio flinger tracks. Fixed volume */
- AUDIO_STREAM_PUBLIC_CNT = AUDIO_STREAM_TTS + 1,
- AUDIO_STREAM_FOR_POLICY_CNT = AUDIO_STREAM_PATCH, /* number of streams considered by
- audio policy for volume and routing */
- AUDIO_STREAM_CNT = AUDIO_STREAM_PATCH + 1,
-} audio_stream_type_t;
-
/* Do not change these values without updating their counterparts
* in frameworks/base/media/java/android/media/AudioAttributes.java
*/
AUDIO_FLAG_LOW_LATENCY = 0x100,
};
-/* Do not change these values without updating their counterparts
- * in frameworks/base/media/java/android/media/MediaRecorder.java,
- * frameworks/av/services/audiopolicy/AudioPolicyService.cpp,
- * and system/media/audio_effects/include/audio_effects/audio_effects_conf.h!
- */
-typedef enum {
- AUDIO_SOURCE_DEFAULT = 0,
- AUDIO_SOURCE_MIC = 1,
- AUDIO_SOURCE_VOICE_UPLINK = 2,
- AUDIO_SOURCE_VOICE_DOWNLINK = 3,
- AUDIO_SOURCE_VOICE_CALL = 4,
- AUDIO_SOURCE_CAMCORDER = 5,
- AUDIO_SOURCE_VOICE_RECOGNITION = 6,
- AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
- AUDIO_SOURCE_REMOTE_SUBMIX = 8, /* Source for the mix to be presented remotely. */
- /* An example of remote presentation is Wifi Display */
- /* where a dongle attached to a TV can be used to */
- /* play the mix captured by this audio source. */
- AUDIO_SOURCE_UNPROCESSED = 9, /* Source for unprocessed sound.
- Usage examples include level measurement and raw
- signal analysis. */
- AUDIO_SOURCE_CNT,
- AUDIO_SOURCE_MAX = AUDIO_SOURCE_CNT - 1,
- AUDIO_SOURCE_FM_TUNER = 1998,
- AUDIO_SOURCE_HOTWORD = 1999, /* A low-priority, preemptible audio source for
- for background software hotword detection.
- Same tuning as AUDIO_SOURCE_VOICE_RECOGNITION.
- Used only internally to the framework. Not exposed
- at the audio HAL. */
-} audio_source_t;
-
/* Audio attributes */
#define AUDIO_ATTRIBUTES_TAGS_MAX_SIZE 256
typedef struct {
char tags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE]; /* UTF8 */
} audio_attributes_t;
-/* special audio session values
- * do not need to have audio_unique_id_get_use(session) == AUDIO_UNIQUE_ID_USE_SESSION
- * (XXX: should this be living in the audio effects land?)
- */
-typedef enum {
- /* session for effects attached to a particular output stream
- * (value must be less than 0)
- */
- AUDIO_SESSION_OUTPUT_STAGE = -1,
-
- /* session for effects applied to output mix. These effects can
- * be moved by audio policy manager to another output stream
- * (value must be 0)
- */
- AUDIO_SESSION_OUTPUT_MIX = 0,
-
- /* application does not specify an explicit session ID to be used,
- * and requests a new session ID to be allocated
- * TODO use unique values for AUDIO_SESSION_OUTPUT_MIX and AUDIO_SESSION_ALLOCATE,
- * after all uses have been updated from 0 to the appropriate symbol, and have been tested.
- * Corresponds to AudioManager.AUDIO_SESSION_ID_GENERATE and AudioSystem.AUDIO_SESSION_ALLOCATE.
- */
- AUDIO_SESSION_ALLOCATE = 0,
-
- /* For use with AudioRecord::start(), this indicates no trigger session.
- * It is also used with output tracks and patch tracks, which never have a session.
- */
- AUDIO_SESSION_NONE = 0,
-} audio_session_t;
-
/* a unique ID allocated by AudioFlinger for use as an audio_io_handle_t, audio_session_t,
* effect ID (int), audio_module_handle_t, and audio_patch_handle_t.
* Audio port IDs (audio_port_handle_t) are allocated by AudioPolicy
/* Reserved audio_unique_id_t values. FIXME: not a complete list. */
#define AUDIO_UNIQUE_ID_ALLOCATE AUDIO_SESSION_ALLOCATE
-/* Audio sub formats (see enum audio_format). */
-
-/* PCM sub formats */
-typedef enum {
- /* All of these are in native byte order */
- AUDIO_FORMAT_PCM_SUB_16_BIT = 0x1, /* DO NOT CHANGE - PCM signed 16 bits */
- AUDIO_FORMAT_PCM_SUB_8_BIT = 0x2, /* DO NOT CHANGE - PCM unsigned 8 bits */
- AUDIO_FORMAT_PCM_SUB_32_BIT = 0x3, /* PCM signed .31 fixed point */
- AUDIO_FORMAT_PCM_SUB_8_24_BIT = 0x4, /* PCM signed 8.23 fixed point */
- AUDIO_FORMAT_PCM_SUB_FLOAT = 0x5, /* PCM single-precision floating point */
- AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED = 0x6, /* PCM signed .23 fixed point packed in 3 bytes */
-} audio_format_pcm_sub_fmt_t;
-
-/* The audio_format_*_sub_fmt_t declarations are not currently used */
-
-/* MP3 sub format field definition : can use 11 LSBs in the same way as MP3
- * frame header to specify bit rate, stereo mode, version...
- */
-typedef enum {
- AUDIO_FORMAT_MP3_SUB_NONE = 0x0,
-} audio_format_mp3_sub_fmt_t;
-
-/* AMR NB/WB sub format field definition: specify frame block interleaving,
- * bandwidth efficient or octet aligned, encoding mode for recording...
- */
-typedef enum {
- AUDIO_FORMAT_AMR_SUB_NONE = 0x0,
-} audio_format_amr_sub_fmt_t;
-
-/* AAC sub format field definition: specify profile or bitrate for recording... */
-typedef enum {
- AUDIO_FORMAT_AAC_SUB_MAIN = 0x1,
- AUDIO_FORMAT_AAC_SUB_LC = 0x2,
- AUDIO_FORMAT_AAC_SUB_SSR = 0x4,
- AUDIO_FORMAT_AAC_SUB_LTP = 0x8,
- AUDIO_FORMAT_AAC_SUB_HE_V1 = 0x10,
- AUDIO_FORMAT_AAC_SUB_SCALABLE = 0x20,
- AUDIO_FORMAT_AAC_SUB_ERLC = 0x40,
- AUDIO_FORMAT_AAC_SUB_LD = 0x80,
- AUDIO_FORMAT_AAC_SUB_HE_V2 = 0x100,
- AUDIO_FORMAT_AAC_SUB_ELD = 0x200,
-} audio_format_aac_sub_fmt_t;
-
-/* VORBIS sub format field definition: specify quality for recording... */
-typedef enum {
- AUDIO_FORMAT_VORBIS_SUB_NONE = 0x0,
-} audio_format_vorbis_sub_fmt_t;
-
-
-/* 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).
- */
-typedef enum {
- AUDIO_FORMAT_INVALID = 0xFFFFFFFFUL,
- AUDIO_FORMAT_DEFAULT = 0,
- AUDIO_FORMAT_PCM = 0x00000000UL, /* DO NOT CHANGE */
- AUDIO_FORMAT_MP3 = 0x01000000UL,
- AUDIO_FORMAT_AMR_NB = 0x02000000UL,
- AUDIO_FORMAT_AMR_WB = 0x03000000UL,
- AUDIO_FORMAT_AAC = 0x04000000UL,
- AUDIO_FORMAT_HE_AAC_V1 = 0x05000000UL, /* Deprecated, Use AUDIO_FORMAT_AAC_HE_V1*/
- AUDIO_FORMAT_HE_AAC_V2 = 0x06000000UL, /* Deprecated, Use AUDIO_FORMAT_AAC_HE_V2*/
- AUDIO_FORMAT_VORBIS = 0x07000000UL,
- AUDIO_FORMAT_OPUS = 0x08000000UL,
- AUDIO_FORMAT_AC3 = 0x09000000UL,
- AUDIO_FORMAT_E_AC3 = 0x0A000000UL,
- AUDIO_FORMAT_DTS = 0x0B000000UL,
- AUDIO_FORMAT_DTS_HD = 0x0C000000UL,
- // IEC61937 is encoded audio wrapped in 16-bit PCM.
- AUDIO_FORMAT_IEC61937 = 0x0D000000UL,
- AUDIO_FORMAT_DOLBY_TRUEHD = 0x0E000000UL,
- AUDIO_FORMAT_MAIN_MASK = 0xFF000000UL, /* Deprecated. Use audio_get_main_format() */
- AUDIO_FORMAT_SUB_MASK = 0x00FFFFFFUL,
-
- /* Aliases */
- /* note != AudioFormat.ENCODING_PCM_16BIT */
- AUDIO_FORMAT_PCM_16_BIT = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_16_BIT),
- /* note != AudioFormat.ENCODING_PCM_8BIT */
- AUDIO_FORMAT_PCM_8_BIT = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_8_BIT),
- AUDIO_FORMAT_PCM_32_BIT = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_32_BIT),
- AUDIO_FORMAT_PCM_8_24_BIT = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_8_24_BIT),
- AUDIO_FORMAT_PCM_FLOAT = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_FLOAT),
- AUDIO_FORMAT_PCM_24_BIT_PACKED = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED),
- AUDIO_FORMAT_AAC_MAIN = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_MAIN),
- AUDIO_FORMAT_AAC_LC = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_LC),
- AUDIO_FORMAT_AAC_SSR = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_SSR),
- AUDIO_FORMAT_AAC_LTP = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_LTP),
- AUDIO_FORMAT_AAC_HE_V1 = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_HE_V1),
- AUDIO_FORMAT_AAC_SCALABLE = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_SCALABLE),
- AUDIO_FORMAT_AAC_ERLC = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_ERLC),
- AUDIO_FORMAT_AAC_LD = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_LD),
- AUDIO_FORMAT_AAC_HE_V2 = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_HE_V2),
- AUDIO_FORMAT_AAC_ELD = (AUDIO_FORMAT_AAC |
- AUDIO_FORMAT_AAC_SUB_ELD),
-} audio_format_t;
-
-/* For the channel mask for position assignment representation */
-enum {
-
-/* These can be a complete audio_channel_mask_t. */
-
- AUDIO_CHANNEL_NONE = 0x0,
- AUDIO_CHANNEL_INVALID = 0xC0000000,
-
-/* These can be the bits portion of an audio_channel_mask_t
- * with representation AUDIO_CHANNEL_REPRESENTATION_POSITION.
- * Using these bits as a complete audio_channel_mask_t is deprecated.
- */
-
- /* output channels */
- AUDIO_CHANNEL_OUT_FRONT_LEFT = 0x1,
- AUDIO_CHANNEL_OUT_FRONT_RIGHT = 0x2,
- AUDIO_CHANNEL_OUT_FRONT_CENTER = 0x4,
- AUDIO_CHANNEL_OUT_LOW_FREQUENCY = 0x8,
- AUDIO_CHANNEL_OUT_BACK_LEFT = 0x10,
- AUDIO_CHANNEL_OUT_BACK_RIGHT = 0x20,
- AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40,
- AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80,
- AUDIO_CHANNEL_OUT_BACK_CENTER = 0x100,
- AUDIO_CHANNEL_OUT_SIDE_LEFT = 0x200,
- AUDIO_CHANNEL_OUT_SIDE_RIGHT = 0x400,
- AUDIO_CHANNEL_OUT_TOP_CENTER = 0x800,
- AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT = 0x1000,
- AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER = 0x2000,
- AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT = 0x4000,
- AUDIO_CHANNEL_OUT_TOP_BACK_LEFT = 0x8000,
- AUDIO_CHANNEL_OUT_TOP_BACK_CENTER = 0x10000,
- AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT = 0x20000,
-
-/* TODO: should these be considered complete channel masks, or only bits? */
-
- AUDIO_CHANNEL_OUT_MONO = AUDIO_CHANNEL_OUT_FRONT_LEFT,
- AUDIO_CHANNEL_OUT_STEREO = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT),
- AUDIO_CHANNEL_OUT_QUAD = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_BACK_LEFT |
- AUDIO_CHANNEL_OUT_BACK_RIGHT),
- AUDIO_CHANNEL_OUT_QUAD_BACK = AUDIO_CHANNEL_OUT_QUAD,
- /* like AUDIO_CHANNEL_OUT_QUAD_BACK with *_SIDE_* instead of *_BACK_* */
- AUDIO_CHANNEL_OUT_QUAD_SIDE = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_SIDE_LEFT |
- AUDIO_CHANNEL_OUT_SIDE_RIGHT),
- AUDIO_CHANNEL_OUT_5POINT1 = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_CENTER |
- AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
- AUDIO_CHANNEL_OUT_BACK_LEFT |
- AUDIO_CHANNEL_OUT_BACK_RIGHT),
- AUDIO_CHANNEL_OUT_5POINT1_BACK = AUDIO_CHANNEL_OUT_5POINT1,
- /* like AUDIO_CHANNEL_OUT_5POINT1_BACK with *_SIDE_* instead of *_BACK_* */
- AUDIO_CHANNEL_OUT_5POINT1_SIDE = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_CENTER |
- AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
- AUDIO_CHANNEL_OUT_SIDE_LEFT |
- AUDIO_CHANNEL_OUT_SIDE_RIGHT),
- // matches the correct AudioFormat.CHANNEL_OUT_7POINT1_SURROUND definition for 7.1
- AUDIO_CHANNEL_OUT_7POINT1 = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_CENTER |
- AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
- AUDIO_CHANNEL_OUT_BACK_LEFT |
- AUDIO_CHANNEL_OUT_BACK_RIGHT |
- AUDIO_CHANNEL_OUT_SIDE_LEFT |
- AUDIO_CHANNEL_OUT_SIDE_RIGHT),
- AUDIO_CHANNEL_OUT_ALL = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_CENTER |
- AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
- AUDIO_CHANNEL_OUT_BACK_LEFT |
- AUDIO_CHANNEL_OUT_BACK_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
- AUDIO_CHANNEL_OUT_BACK_CENTER|
- AUDIO_CHANNEL_OUT_SIDE_LEFT|
- AUDIO_CHANNEL_OUT_SIDE_RIGHT|
- AUDIO_CHANNEL_OUT_TOP_CENTER|
- AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT|
- AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER|
- AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT|
- AUDIO_CHANNEL_OUT_TOP_BACK_LEFT|
- AUDIO_CHANNEL_OUT_TOP_BACK_CENTER|
- AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT),
-
-/* These are bits only, not complete values */
-
- /* input channels */
- AUDIO_CHANNEL_IN_LEFT = 0x4,
- AUDIO_CHANNEL_IN_RIGHT = 0x8,
- AUDIO_CHANNEL_IN_FRONT = 0x10,
- AUDIO_CHANNEL_IN_BACK = 0x20,
- AUDIO_CHANNEL_IN_LEFT_PROCESSED = 0x40,
- AUDIO_CHANNEL_IN_RIGHT_PROCESSED = 0x80,
- AUDIO_CHANNEL_IN_FRONT_PROCESSED = 0x100,
- AUDIO_CHANNEL_IN_BACK_PROCESSED = 0x200,
- AUDIO_CHANNEL_IN_PRESSURE = 0x400,
- AUDIO_CHANNEL_IN_X_AXIS = 0x800,
- AUDIO_CHANNEL_IN_Y_AXIS = 0x1000,
- AUDIO_CHANNEL_IN_Z_AXIS = 0x2000,
- AUDIO_CHANNEL_IN_VOICE_UPLINK = 0x4000,
- AUDIO_CHANNEL_IN_VOICE_DNLINK = 0x8000,
-
-/* TODO: should these be considered complete channel masks, or only bits, or deprecated? */
-
- AUDIO_CHANNEL_IN_MONO = AUDIO_CHANNEL_IN_FRONT,
- AUDIO_CHANNEL_IN_STEREO = (AUDIO_CHANNEL_IN_LEFT | AUDIO_CHANNEL_IN_RIGHT),
- AUDIO_CHANNEL_IN_FRONT_BACK = (AUDIO_CHANNEL_IN_FRONT | AUDIO_CHANNEL_IN_BACK),
- AUDIO_CHANNEL_IN_ALL = (AUDIO_CHANNEL_IN_LEFT |
- AUDIO_CHANNEL_IN_RIGHT |
- AUDIO_CHANNEL_IN_FRONT |
- AUDIO_CHANNEL_IN_BACK|
- AUDIO_CHANNEL_IN_LEFT_PROCESSED |
- AUDIO_CHANNEL_IN_RIGHT_PROCESSED |
- AUDIO_CHANNEL_IN_FRONT_PROCESSED |
- AUDIO_CHANNEL_IN_BACK_PROCESSED|
- AUDIO_CHANNEL_IN_PRESSURE |
- AUDIO_CHANNEL_IN_X_AXIS |
- AUDIO_CHANNEL_IN_Y_AXIS |
- AUDIO_CHANNEL_IN_Z_AXIS |
- AUDIO_CHANNEL_IN_VOICE_UPLINK |
- AUDIO_CHANNEL_IN_VOICE_DNLINK),
-};
-
/* A channel mask per se only defines the presence or absence of a channel, not the order.
* But see AUDIO_INTERLEAVE_* below for the platform convention of order.
*
*/
typedef uint32_t audio_channel_mask_t;
-/* Maximum number of channels for all representations */
-#define AUDIO_CHANNEL_COUNT_MAX 30
-
/* log(2) of maximum number of representations, not part of public API */
#define AUDIO_CHANNEL_REPRESENTATION_LOG2 2
-/* Representations */
-typedef enum {
- AUDIO_CHANNEL_REPRESENTATION_POSITION = 0, // must be zero for compatibility
- // 1 is reserved for future use
- AUDIO_CHANNEL_REPRESENTATION_INDEX = 2,
- // 3 is reserved for future use
-} audio_channel_representation_t;
-
-/* The channel index masks defined here are the canonical masks for 1 to 8 channel
- * endpoints and apply to both source and sink.
- */
-enum {
- AUDIO_CHANNEL_INDEX_HDR = AUDIO_CHANNEL_REPRESENTATION_INDEX << AUDIO_CHANNEL_COUNT_MAX,
- AUDIO_CHANNEL_INDEX_MASK_1 = AUDIO_CHANNEL_INDEX_HDR | ((1 << 1) - 1),
- AUDIO_CHANNEL_INDEX_MASK_2 = AUDIO_CHANNEL_INDEX_HDR | ((1 << 2) - 1),
- AUDIO_CHANNEL_INDEX_MASK_3 = AUDIO_CHANNEL_INDEX_HDR | ((1 << 3) - 1),
- AUDIO_CHANNEL_INDEX_MASK_4 = AUDIO_CHANNEL_INDEX_HDR | ((1 << 4) - 1),
- AUDIO_CHANNEL_INDEX_MASK_5 = AUDIO_CHANNEL_INDEX_HDR | ((1 << 5) - 1),
- AUDIO_CHANNEL_INDEX_MASK_6 = AUDIO_CHANNEL_INDEX_HDR | ((1 << 6) - 1),
- AUDIO_CHANNEL_INDEX_MASK_7 = AUDIO_CHANNEL_INDEX_HDR | ((1 << 7) - 1),
- AUDIO_CHANNEL_INDEX_MASK_8 = AUDIO_CHANNEL_INDEX_HDR | ((1 << 8) - 1),
- // FIXME FCC_8
-};
-
/* The return value is undefined if the channel mask is invalid. */
static inline uint32_t audio_channel_mask_get_bits(audio_channel_mask_t channel)
{
return channel & ((1 << AUDIO_CHANNEL_COUNT_MAX) - 1);
}
+typedef uint32_t audio_channel_representation_t;
+
/* The return value is undefined if the channel mask is invalid. */
static inline audio_channel_representation_t audio_channel_mask_get_representation(
audio_channel_mask_t channel)
return (audio_channel_mask_t) ((representation << AUDIO_CHANNEL_COUNT_MAX) | bits);
}
-/* 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.
- */
-enum {
- AUDIO_INTERLEAVE_LEFT = 0,
- AUDIO_INTERLEAVE_RIGHT = 1,
-};
-
-typedef enum {
- AUDIO_MODE_INVALID = -2,
- AUDIO_MODE_CURRENT = -1,
- AUDIO_MODE_NORMAL = 0,
- AUDIO_MODE_RINGTONE = 1,
- AUDIO_MODE_IN_CALL = 2,
- AUDIO_MODE_IN_COMMUNICATION = 3,
-
- AUDIO_MODE_CNT,
- AUDIO_MODE_MAX = AUDIO_MODE_CNT - 1,
-} audio_mode_t;
-
/* This enum is deprecated */
typedef enum {
AUDIO_IN_ACOUSTICS_NONE = 0,
AUDIO_IN_ACOUSTICS_TX_DISABLE = 0,
} audio_in_acoustics_t;
-enum {
- AUDIO_DEVICE_NONE = 0x0,
- /* reserved bits */
- AUDIO_DEVICE_BIT_IN = 0x80000000,
- AUDIO_DEVICE_BIT_DEFAULT = 0x40000000,
- /* output devices */
- AUDIO_DEVICE_OUT_EARPIECE = 0x1,
- AUDIO_DEVICE_OUT_SPEAKER = 0x2,
- AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4,
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
- AUDIO_DEVICE_OUT_AUX_DIGITAL = 0x400,
- AUDIO_DEVICE_OUT_HDMI = AUDIO_DEVICE_OUT_AUX_DIGITAL,
- /* uses an analog connection (multiplexed over the USB connector pins for instance) */
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800,
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000,
- /* USB accessory mode: your Android device is a USB device and the dock is a USB host */
- AUDIO_DEVICE_OUT_USB_ACCESSORY = 0x2000,
- /* USB host mode: your Android device is a USB host and the dock is a USB device */
- AUDIO_DEVICE_OUT_USB_DEVICE = 0x4000,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 0x8000,
- /* Telephony voice TX path */
- AUDIO_DEVICE_OUT_TELEPHONY_TX = 0x10000,
- /* Analog jack with line impedance detected */
- AUDIO_DEVICE_OUT_LINE = 0x20000,
- /* HDMI Audio Return Channel */
- AUDIO_DEVICE_OUT_HDMI_ARC = 0x40000,
- /* S/PDIF out */
- AUDIO_DEVICE_OUT_SPDIF = 0x80000,
- /* FM transmitter out */
- AUDIO_DEVICE_OUT_FM = 0x100000,
- /* Line out for av devices */
- AUDIO_DEVICE_OUT_AUX_LINE = 0x200000,
- /* limited-output speaker device for acoustic safety */
- AUDIO_DEVICE_OUT_SPEAKER_SAFE = 0x400000,
- AUDIO_DEVICE_OUT_IP = 0x800000,
- /* audio bus implemented by the audio system (e.g an MOST stereo channel) */
- AUDIO_DEVICE_OUT_BUS = 0x1000000,
- AUDIO_DEVICE_OUT_DEFAULT = AUDIO_DEVICE_BIT_DEFAULT,
- AUDIO_DEVICE_OUT_ALL = (AUDIO_DEVICE_OUT_EARPIECE |
- AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
- AUDIO_DEVICE_OUT_HDMI |
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_USB_ACCESSORY |
- AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX |
- AUDIO_DEVICE_OUT_TELEPHONY_TX |
- AUDIO_DEVICE_OUT_LINE |
- AUDIO_DEVICE_OUT_HDMI_ARC |
- AUDIO_DEVICE_OUT_SPDIF |
- AUDIO_DEVICE_OUT_FM |
- AUDIO_DEVICE_OUT_AUX_LINE |
- AUDIO_DEVICE_OUT_SPEAKER_SAFE |
- AUDIO_DEVICE_OUT_IP |
- AUDIO_DEVICE_OUT_BUS |
- AUDIO_DEVICE_OUT_DEFAULT),
- AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
- AUDIO_DEVICE_OUT_ALL_SCO = (AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
- AUDIO_DEVICE_OUT_ALL_USB = (AUDIO_DEVICE_OUT_USB_ACCESSORY |
- AUDIO_DEVICE_OUT_USB_DEVICE),
- /* input devices */
- AUDIO_DEVICE_IN_COMMUNICATION = AUDIO_DEVICE_BIT_IN | 0x1,
- AUDIO_DEVICE_IN_AMBIENT = AUDIO_DEVICE_BIT_IN | 0x2,
- AUDIO_DEVICE_IN_BUILTIN_MIC = AUDIO_DEVICE_BIT_IN | 0x4,
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = AUDIO_DEVICE_BIT_IN | 0x8,
- AUDIO_DEVICE_IN_WIRED_HEADSET = AUDIO_DEVICE_BIT_IN | 0x10,
- AUDIO_DEVICE_IN_AUX_DIGITAL = AUDIO_DEVICE_BIT_IN | 0x20,
- AUDIO_DEVICE_IN_HDMI = AUDIO_DEVICE_IN_AUX_DIGITAL,
- /* Telephony voice RX path */
- AUDIO_DEVICE_IN_VOICE_CALL = AUDIO_DEVICE_BIT_IN | 0x40,
- AUDIO_DEVICE_IN_TELEPHONY_RX = AUDIO_DEVICE_IN_VOICE_CALL,
- AUDIO_DEVICE_IN_BACK_MIC = AUDIO_DEVICE_BIT_IN | 0x80,
- AUDIO_DEVICE_IN_REMOTE_SUBMIX = AUDIO_DEVICE_BIT_IN | 0x100,
- AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x200,
- AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x400,
- AUDIO_DEVICE_IN_USB_ACCESSORY = AUDIO_DEVICE_BIT_IN | 0x800,
- AUDIO_DEVICE_IN_USB_DEVICE = AUDIO_DEVICE_BIT_IN | 0x1000,
- /* FM tuner input */
- AUDIO_DEVICE_IN_FM_TUNER = AUDIO_DEVICE_BIT_IN | 0x2000,
- /* TV tuner input */
- AUDIO_DEVICE_IN_TV_TUNER = AUDIO_DEVICE_BIT_IN | 0x4000,
- /* Analog jack with line impedance detected */
- AUDIO_DEVICE_IN_LINE = AUDIO_DEVICE_BIT_IN | 0x8000,
- /* S/PDIF in */
- AUDIO_DEVICE_IN_SPDIF = AUDIO_DEVICE_BIT_IN | 0x10000,
- AUDIO_DEVICE_IN_BLUETOOTH_A2DP = AUDIO_DEVICE_BIT_IN | 0x20000,
- AUDIO_DEVICE_IN_LOOPBACK = AUDIO_DEVICE_BIT_IN | 0x40000,
- AUDIO_DEVICE_IN_IP = AUDIO_DEVICE_BIT_IN | 0x80000,
- /* audio bus implemented by the audio system (e.g an MOST stereo channel) */
- AUDIO_DEVICE_IN_BUS = AUDIO_DEVICE_BIT_IN | 0x100000,
- AUDIO_DEVICE_IN_DEFAULT = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT,
-
- AUDIO_DEVICE_IN_ALL = (AUDIO_DEVICE_IN_COMMUNICATION |
- AUDIO_DEVICE_IN_AMBIENT |
- AUDIO_DEVICE_IN_BUILTIN_MIC |
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_IN_WIRED_HEADSET |
- AUDIO_DEVICE_IN_HDMI |
- AUDIO_DEVICE_IN_TELEPHONY_RX |
- AUDIO_DEVICE_IN_BACK_MIC |
- AUDIO_DEVICE_IN_REMOTE_SUBMIX |
- AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET |
- AUDIO_DEVICE_IN_USB_ACCESSORY |
- AUDIO_DEVICE_IN_USB_DEVICE |
- AUDIO_DEVICE_IN_FM_TUNER |
- AUDIO_DEVICE_IN_TV_TUNER |
- AUDIO_DEVICE_IN_LINE |
- AUDIO_DEVICE_IN_SPDIF |
- AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
- AUDIO_DEVICE_IN_LOOPBACK |
- AUDIO_DEVICE_IN_IP |
- AUDIO_DEVICE_IN_BUS |
- AUDIO_DEVICE_IN_DEFAULT),
- AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
- AUDIO_DEVICE_IN_ALL_USB = (AUDIO_DEVICE_IN_USB_ACCESSORY |
- AUDIO_DEVICE_IN_USB_DEVICE),
-};
-
typedef uint32_t audio_devices_t;
-/* the audio output flags serve two purposes:
- * - when an AudioTrack is created they indicate a "wish" to be connected to an
- * output stream with attributes corresponding to the specified flags
- * - when present in an output profile descriptor listed for a particular audio
- * hardware module, they indicate that an output stream can be opened that
- * supports the attributes indicated by the flags.
- * the audio policy manager will try to match the flags in the request
- * (when getOuput() is called) to an available output stream.
- */
-typedef enum {
- AUDIO_OUTPUT_FLAG_NONE = 0x0, // no attributes
- AUDIO_OUTPUT_FLAG_DIRECT = 0x1, // this output directly connects a track
- // to one output stream: no software mixer
- AUDIO_OUTPUT_FLAG_PRIMARY = 0x2, // this output is the primary output of
- // the device. It is unique and must be
- // present. It is opened by default and
- // receives routing, audio mode and volume
- // controls related to voice calls.
- AUDIO_OUTPUT_FLAG_FAST = 0x4, // output supports "fast tracks",
- // defined elsewhere
- AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8, // use deep audio buffers
- AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD = 0x10, // offload playback of compressed
- // streams to hardware codec
- AUDIO_OUTPUT_FLAG_NON_BLOCKING = 0x20, // use non-blocking write
- AUDIO_OUTPUT_FLAG_HW_AV_SYNC = 0x40, // output uses a hardware A/V synchronization source
- AUDIO_OUTPUT_FLAG_TTS = 0x80, // output for streams transmitted through speaker
- // at a sample rate high enough to accommodate
- // lower-range ultrasonic playback
- AUDIO_OUTPUT_FLAG_RAW = 0x100, // minimize signal processing
- AUDIO_OUTPUT_FLAG_SYNC = 0x200, // synchronize I/O streams
-
- AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO = 0x400, // Audio stream contains compressed audio in
- // SPDIF data bursts, not PCM.
-} audio_output_flags_t;
-
-/* The audio input flags are analogous to audio output flags.
- * Currently they are used only when an AudioRecord is created,
- * to indicate a preference to be connected to an input stream with
- * attributes corresponding to the specified flags.
- */
-typedef enum {
- AUDIO_INPUT_FLAG_NONE = 0x0, // no attributes
- AUDIO_INPUT_FLAG_FAST = 0x1, // prefer an input that supports "fast tracks"
- AUDIO_INPUT_FLAG_HW_HOTWORD = 0x2, // prefer an input that captures from hw hotword source
- AUDIO_INPUT_FLAG_RAW = 0x4, // minimize signal processing
- AUDIO_INPUT_FLAG_SYNC = 0x8, // synchronize I/O streams
-
-} audio_input_flags_t;
-
/* Additional information about compressed streams offloaded to
* hardware playback
* The version and size fields must be initialized by the caller by using
* will then implement gain control functions that will use the following data
* structures. */
-/* Type of gain control exposed by an audio port */
-#define AUDIO_GAIN_MODE_JOINT 0x1 /* supports joint channel gain control */
-#define AUDIO_GAIN_MODE_CHANNELS 0x2 /* supports separate channel gain control */
-#define AUDIO_GAIN_MODE_RAMP 0x4 /* supports gain ramps */
-
typedef uint32_t audio_gain_mode_t;
* audio end point at the edge of the system managed by the module exposing
* the interface. */
-/* Audio port role: either source or sink */
-typedef enum {
- AUDIO_PORT_ROLE_NONE,
- AUDIO_PORT_ROLE_SOURCE,
- AUDIO_PORT_ROLE_SINK,
-} audio_port_role_t;
-
-/* Audio port type indicates if it is a session (e.g AudioTrack),
- * a mix (e.g PlaybackThread output) or a physical device
- * (e.g AUDIO_DEVICE_OUT_SPEAKER) */
-typedef enum {
- AUDIO_PORT_TYPE_NONE,
- AUDIO_PORT_TYPE_DEVICE,
- AUDIO_PORT_TYPE_MIX,
- AUDIO_PORT_TYPE_SESSION,
-} audio_port_type_t;
-
/* Each port has a unique ID or handle allocated by policy manager */
typedef int audio_port_handle_t;
#define AUDIO_PORT_HANDLE_NONE 0
audio_session_t session; /* audio session */
};
-/* Flags indicating which fields are to be considered in struct audio_port_config */
-#define AUDIO_PORT_CONFIG_SAMPLE_RATE 0x1
-#define AUDIO_PORT_CONFIG_CHANNEL_MASK 0x2
-#define AUDIO_PORT_CONFIG_FORMAT 0x4
-#define AUDIO_PORT_CONFIG_GAIN 0x8
-#define AUDIO_PORT_CONFIG_ALL (AUDIO_PORT_CONFIG_SAMPLE_RATE | \
- AUDIO_PORT_CONFIG_CHANNEL_MASK | \
- AUDIO_PORT_CONFIG_FORMAT | \
- AUDIO_PORT_CONFIG_GAIN)
-
/* audio port configuration structure used to specify a particular configuration of
* an audio port */
struct audio_port_config {
char address[AUDIO_DEVICE_MAX_ADDRESS_LEN];
};
-/* Latency class of the audio mix */
-typedef enum {
- AUDIO_LATENCY_LOW,
- AUDIO_LATENCY_NORMAL,
-} audio_mix_latency_class_t;
-
/* extension for audio port structure when the audio port is a sub mix */
struct audio_port_mix_ext {
audio_module_handle_t hw_module; /* module the stream is attached to */
srcs: [
"channels.c",
- "fifo.c",
+ "fifo.cpp",
"format.c",
"limiter.c",
"minifloat.c",
name: "libfifo",
defaults: ["audio_utils_defaults"],
srcs: [
- "fifo.c",
+ "fifo.cpp",
"primitives.c",
"roundup.c",
],
--- /dev/null
+# How to build and view documentation
+
+* doxygen Doxyfile
+* cd html
+* python -m SimpleHTTPServer
+* open in web browser
+ http://localhost:8000/classaudio__utils__fifo.html
+* when done: rm -rf html
+++ /dev/null
-/*
- * Copyright (C) 2015 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_NDEBUG 0
-#define LOG_TAG "audio_utils_fifo"
-
-#include <stdlib.h>
-#include <string.h>
-#include <audio_utils/fifo.h>
-#include <audio_utils/roundup.h>
-#include <cutils/atomic.h>
-#include <cutils/log.h>
-
-void audio_utils_fifo_init(struct audio_utils_fifo *fifo, size_t frameCount, size_t frameSize,
- void *buffer)
-{
- // We would need a 64-bit roundup to support larger frameCount.
- ALOG_ASSERT(fifo != NULL && frameCount > 0 && frameSize > 0 && buffer != NULL);
- fifo->mFrameCount = frameCount;
- fifo->mFrameCountP2 = roundup(frameCount);
- fifo->mFudgeFactor = fifo->mFrameCountP2 - fifo->mFrameCount;
- fifo->mFrameSize = frameSize;
- fifo->mBuffer = buffer;
- fifo->mFront = 0;
- fifo->mRear = 0;
-}
-
-void audio_utils_fifo_deinit(struct audio_utils_fifo *fifo __unused)
-{
-}
-
-// Return a new index as the sum of an old index (either mFront or mRear) and a specified increment.
-static inline int32_t audio_utils_fifo_sum(struct audio_utils_fifo *fifo, int32_t index,
- uint32_t increment)
-{
- if (fifo->mFudgeFactor) {
- uint32_t mask = fifo->mFrameCountP2 - 1;
- ALOG_ASSERT((index & mask) < fifo->mFrameCount);
- ALOG_ASSERT(/*0 <= increment &&*/ increment <= fifo->mFrameCountP2);
- if ((index & mask) + increment >= fifo->mFrameCount) {
- increment += fifo->mFudgeFactor;
- }
- index += increment;
- ALOG_ASSERT((index & mask) < fifo->mFrameCount);
- return index;
- } else {
- return index + increment;
- }
-}
-
-// Return the difference between two indices: rear - front, where 0 <= difference <= mFrameCount.
-static inline size_t audio_utils_fifo_diff(struct audio_utils_fifo *fifo, int32_t rear,
- int32_t front)
-{
- int32_t diff = rear - front;
- if (fifo->mFudgeFactor) {
- uint32_t mask = ~(fifo->mFrameCountP2 - 1);
- int32_t genDiff = (rear & mask) - (front & mask);
- if (genDiff != 0) {
- ALOG_ASSERT(genDiff == (int32_t) fifo->mFrameCountP2);
- diff -= fifo->mFudgeFactor;
- }
- }
- // FIFO should not be overfull
- ALOG_ASSERT(0 <= diff && diff <= (int32_t) fifo->mFrameCount);
- return (size_t) diff;
-}
-
-ssize_t audio_utils_fifo_write(struct audio_utils_fifo *fifo, const void *buffer, size_t count)
-{
- int32_t front = android_atomic_acquire_load(&fifo->mFront);
- int32_t rear = fifo->mRear;
- size_t availToWrite = fifo->mFrameCount - audio_utils_fifo_diff(fifo, rear, front);
- if (availToWrite > count) {
- availToWrite = count;
- }
- rear &= fifo->mFrameCountP2 - 1;
- size_t part1 = fifo->mFrameCount - rear;
- if (part1 > availToWrite) {
- part1 = availToWrite;
- }
- if (part1 > 0) {
- memcpy((char *) fifo->mBuffer + (rear * fifo->mFrameSize), buffer,
- part1 * fifo->mFrameSize);
- size_t part2 = availToWrite - part1;
- if (part2 > 0) {
- memcpy(fifo->mBuffer, (char *) buffer + (part1 * fifo->mFrameSize),
- part2 * fifo->mFrameSize);
- }
- android_atomic_release_store(audio_utils_fifo_sum(fifo, fifo->mRear, availToWrite),
- &fifo->mRear);
- }
- return availToWrite;
-}
-
-ssize_t audio_utils_fifo_read(struct audio_utils_fifo *fifo, void *buffer, size_t count)
-{
- int32_t rear = android_atomic_acquire_load(&fifo->mRear);
- int32_t front = fifo->mFront;
- size_t availToRead = audio_utils_fifo_diff(fifo, rear, front);
- if (availToRead > count) {
- availToRead = count;
- }
- front &= fifo->mFrameCountP2 - 1;
- size_t part1 = fifo->mFrameCount - front;
- if (part1 > availToRead) {
- part1 = availToRead;
- }
- if (part1 > 0) {
- memcpy(buffer, (char *) fifo->mBuffer + (front * fifo->mFrameSize),
- part1 * fifo->mFrameSize);
- size_t part2 = availToRead - part1;
- if (part2 > 0) {
- memcpy((char *) buffer + (part1 * fifo->mFrameSize), fifo->mBuffer,
- part2 * fifo->mFrameSize);
- }
- android_atomic_release_store(audio_utils_fifo_sum(fifo, fifo->mFront, availToRead),
- &fifo->mFront);
- }
- return availToRead;
-}
--- /dev/null
+/*
+ * Copyright (C) 2015 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_NDEBUG 0
+#define LOG_TAG "audio_utils_fifo"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+// FIXME futex portion is not supported on Mac, should use the Mac alternative
+#ifdef __linux__
+#include <linux/futex.h>
+#include <sys/syscall.h>
+#else
+#define FUTEX_WAIT 0
+#define FUTEX_WAIT_PRIVATE 0
+#define FUTEX_WAKE 0
+#define FUTEX_WAKE_PRIVATE 0
+#endif
+
+#include <audio_utils/fifo.h>
+#include <audio_utils/roundup.h>
+#include <cutils/log.h>
+#include <utils/Errors.h>
+
+static int sys_futex(void *addr1, int op, int val1, struct timespec *timeout, void *addr2, int val3)
+{
+#ifdef __linux__
+ return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
+#else
+ (void) addr1;
+ (void) op;
+ (void) val1;
+ (void) timeout;
+ (void) addr2;
+ (void) val3;
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+audio_utils_fifo_base::audio_utils_fifo_base(uint32_t frameCount,
+ audio_utils_fifo_index& sharedRear, audio_utils_fifo_index *throttleFront)
+ __attribute__((no_sanitize("integer"))) :
+ mFrameCount(frameCount), mFrameCountP2(roundup(frameCount)),
+ mFudgeFactor(mFrameCountP2 - mFrameCount),
+ mIsPrivate(true),
+ mSharedRear(sharedRear), mThrottleFront(throttleFront)
+{
+ // actual upper bound on frameCount will depend on the frame size
+ LOG_ALWAYS_FATAL_IF(frameCount == 0 || frameCount > ((uint32_t) INT_MAX));
+}
+
+audio_utils_fifo_base::~audio_utils_fifo_base()
+{
+}
+
+uint32_t audio_utils_fifo_base::sum(uint32_t index, uint32_t increment)
+ __attribute__((no_sanitize("integer")))
+{
+ if (mFudgeFactor) {
+ uint32_t mask = mFrameCountP2 - 1;
+ ALOG_ASSERT((index & mask) < mFrameCount);
+ ALOG_ASSERT(increment <= mFrameCountP2);
+ if ((index & mask) + increment >= mFrameCount) {
+ increment += mFudgeFactor;
+ }
+ index += increment;
+ ALOG_ASSERT((index & mask) < mFrameCount);
+ return index;
+ } else {
+ return index + increment;
+ }
+}
+
+int32_t audio_utils_fifo_base::diff(uint32_t rear, uint32_t front, size_t *lost)
+ __attribute__((no_sanitize("integer")))
+{
+ uint32_t diff = rear - front;
+ if (mFudgeFactor) {
+ uint32_t mask = mFrameCountP2 - 1;
+ uint32_t rearMasked = rear & mask;
+ uint32_t frontMasked = front & mask;
+ if (rearMasked >= mFrameCount || frontMasked >= mFrameCount) {
+ return -EIO;
+ }
+ uint32_t genDiff = (rear & ~mask) - (front & ~mask);
+ if (genDiff != 0) {
+ if (genDiff > mFrameCountP2) {
+ if (lost != NULL) {
+ // TODO provide a more accurate estimate
+ *lost = (genDiff / mFrameCountP2) * mFrameCount;
+ }
+ return -EOVERFLOW;
+ }
+ diff -= mFudgeFactor;
+ }
+ }
+ // FIFO should not be overfull
+ if (diff > mFrameCount) {
+ if (lost != NULL) {
+ *lost = diff - mFrameCount;
+ }
+ return -EOVERFLOW;
+ }
+ return (int32_t) diff;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+audio_utils_fifo::audio_utils_fifo(uint32_t frameCount, uint32_t frameSize, void *buffer,
+ audio_utils_fifo_index& sharedRear, audio_utils_fifo_index *throttleFront)
+ __attribute__((no_sanitize("integer"))) :
+ audio_utils_fifo_base(frameCount, sharedRear, throttleFront),
+ mFrameSize(frameSize), mBuffer(buffer)
+{
+ // maximum value of frameCount * frameSize is INT_MAX (2^31 - 1), not 2^31, because we need to
+ // be able to distinguish successful and error return values from read and write.
+ LOG_ALWAYS_FATAL_IF(frameCount == 0 || frameSize == 0 || buffer == NULL ||
+ frameCount > ((uint32_t) INT_MAX) / frameSize);
+}
+
+audio_utils_fifo::audio_utils_fifo(uint32_t frameCount, uint32_t frameSize, void *buffer,
+ bool throttlesWriter) :
+ audio_utils_fifo(frameCount, frameSize, buffer, mSingleProcessSharedRear,
+ throttlesWriter ? &mSingleProcessSharedFront : NULL)
+{
+}
+
+audio_utils_fifo::~audio_utils_fifo()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+audio_utils_fifo_provider::audio_utils_fifo_provider() :
+ mObtained(0)
+{
+}
+
+audio_utils_fifo_provider::~audio_utils_fifo_provider()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+audio_utils_fifo_writer::audio_utils_fifo_writer(audio_utils_fifo& fifo) :
+ audio_utils_fifo_provider(), mFifo(fifo), mLocalRear(0),
+ mLowLevelArm(fifo.mFrameCount), mHighLevelTrigger(0), mArmed(false),
+ mEffectiveFrames(fifo.mFrameCount)
+{
+}
+
+audio_utils_fifo_writer::~audio_utils_fifo_writer()
+{
+}
+
+ssize_t audio_utils_fifo_writer::write(const void *buffer, size_t count, struct timespec *timeout)
+ __attribute__((no_sanitize("integer")))
+{
+ audio_utils_iovec iovec[2];
+ ssize_t availToWrite = obtain(iovec, count, timeout);
+ if (availToWrite > 0) {
+ memcpy((char *) mFifo.mBuffer + iovec[0].mOffset * mFifo.mFrameSize, buffer,
+ iovec[0].mLength * mFifo.mFrameSize);
+ if (iovec[1].mLength > 0) {
+ memcpy((char *) mFifo.mBuffer + iovec[1].mOffset * mFifo.mFrameSize,
+ (char *) buffer + (iovec[0].mLength * mFifo.mFrameSize),
+ iovec[1].mLength * mFifo.mFrameSize);
+ }
+ release(availToWrite);
+ }
+ return availToWrite;
+}
+
+ssize_t audio_utils_fifo_writer::obtain(audio_utils_iovec iovec[2], size_t count,
+ struct timespec *timeout)
+ __attribute__((no_sanitize("integer")))
+{
+ size_t availToWrite;
+ if (mFifo.mThrottleFront != NULL) {
+ uint32_t front;
+ for (;;) {
+ front = atomic_load_explicit(&mFifo.mThrottleFront->mIndex,
+ std::memory_order_acquire);
+ int32_t filled = mFifo.diff(mLocalRear, front, NULL /*lost*/);
+ if (filled < 0) {
+ mObtained = 0;
+ return (ssize_t) filled;
+ }
+ availToWrite = mEffectiveFrames > (uint32_t) filled ?
+ mEffectiveFrames - (uint32_t) filled : 0;
+ // TODO pull out "count == 0"
+ if (count == 0 || availToWrite > 0 || timeout == NULL ||
+ (timeout->tv_sec == 0 && timeout->tv_nsec == 0)) {
+ break;
+ }
+ int err = sys_futex(&mFifo.mThrottleFront->mIndex,
+ mFifo.mIsPrivate ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, front, timeout, NULL, 0);
+ if (err < 0) {
+ switch (errno) {
+ case EWOULDBLOCK:
+ case EINTR:
+ case ETIMEDOUT:
+ break;
+ default:
+ LOG_ALWAYS_FATAL("unexpected err=%d errno=%d", err, errno);
+ break;
+ }
+ }
+ timeout = NULL;
+ }
+ } else {
+ availToWrite = mEffectiveFrames;
+ }
+ if (availToWrite > count) {
+ availToWrite = count;
+ }
+ uint32_t rearMasked = mLocalRear & (mFifo.mFrameCountP2 - 1);
+ size_t part1 = mFifo.mFrameCount - rearMasked;
+ if (part1 > availToWrite) {
+ part1 = availToWrite;
+ }
+ size_t part2 = part1 > 0 ? availToWrite - part1 : 0;
+ iovec[0].mOffset = rearMasked;
+ iovec[0].mLength = part1;
+ iovec[1].mOffset = 0;
+ iovec[1].mLength = part2;
+ mObtained = availToWrite;
+ return availToWrite;
+}
+
+void audio_utils_fifo_writer::release(size_t count)
+ __attribute__((no_sanitize("integer")))
+{
+ if (count > 0) {
+ LOG_ALWAYS_FATAL_IF(count > mObtained);
+ if (mFifo.mThrottleFront != NULL) {
+ uint32_t front = atomic_load_explicit(&mFifo.mThrottleFront->mIndex,
+ std::memory_order_acquire);
+ int32_t filled = mFifo.diff(mLocalRear, front, NULL /*lost*/);
+ mLocalRear = mFifo.sum(mLocalRear, count);
+ atomic_store_explicit(&mFifo.mSharedRear.mIndex, mLocalRear,
+ std::memory_order_release);
+ if (filled >= 0) {
+ if (filled + count <= mLowLevelArm) {
+ mArmed = true;
+ }
+ if (mArmed && filled + count >= mHighLevelTrigger) {
+ int err = sys_futex(&mFifo.mSharedRear.mIndex,
+ mFifo.mIsPrivate ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
+ INT_MAX /*waiters*/, NULL, NULL, 0);
+ // err is number of processes woken up
+ if (err < 0) {
+ LOG_ALWAYS_FATAL("%s: unexpected err=%d errno=%d", __func__, err, errno);
+ }
+ mArmed = false;
+ }
+ }
+ } else {
+ mLocalRear = mFifo.sum(mLocalRear, count);
+ atomic_store_explicit(&mFifo.mSharedRear.mIndex, mLocalRear,
+ std::memory_order_release);
+ }
+ mObtained -= count;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+audio_utils_fifo_reader::audio_utils_fifo_reader(audio_utils_fifo& fifo, bool throttlesWriter) :
+ audio_utils_fifo_provider(), mFifo(fifo), mLocalFront(0),
+ mThrottleFront(throttlesWriter ? mFifo.mThrottleFront : NULL),
+ mHighLevelArm(0), mLowLevelTrigger(mFifo.mFrameCount), mArmed(false)
+{
+}
+
+audio_utils_fifo_reader::~audio_utils_fifo_reader()
+{
+ // TODO Need a way to pass throttle capability to the another reader, should one reader exit.
+}
+
+ssize_t audio_utils_fifo_reader::read(void *buffer, size_t count, struct timespec *timeout,
+ size_t *lost)
+ __attribute__((no_sanitize("integer")))
+{
+ audio_utils_iovec iovec[2];
+ ssize_t availToRead = obtain(iovec, count, timeout, lost);
+ if (availToRead > 0) {
+ memcpy(buffer, (char *) mFifo.mBuffer + iovec[0].mOffset * mFifo.mFrameSize,
+ iovec[0].mLength * mFifo.mFrameSize);
+ if (iovec[1].mLength > 0) {
+ memcpy((char *) buffer + (iovec[0].mLength * mFifo.mFrameSize),
+ (char *) mFifo.mBuffer + iovec[1].mOffset * mFifo.mFrameSize,
+ iovec[1].mLength * mFifo.mFrameSize);
+ }
+ release(availToRead);
+ }
+ return availToRead;
+}
+
+ssize_t audio_utils_fifo_reader::obtain(audio_utils_iovec iovec[2], size_t count,
+ struct timespec *timeout)
+ __attribute__((no_sanitize("integer")))
+{
+ return obtain(iovec, count, timeout, NULL);
+}
+
+void audio_utils_fifo_reader::release(size_t count)
+ __attribute__((no_sanitize("integer")))
+{
+ if (count > 0) {
+ LOG_ALWAYS_FATAL_IF(count > mObtained);
+ if (mThrottleFront != NULL) {
+ uint32_t rear = atomic_load_explicit(&mFifo.mSharedRear.mIndex,
+ std::memory_order_acquire);
+ int32_t filled = mFifo.diff(rear, mLocalFront, NULL /*lost*/);
+ mLocalFront = mFifo.sum(mLocalFront, count);
+ atomic_store_explicit(&mThrottleFront->mIndex, mLocalFront,
+ std::memory_order_release);
+ if (filled >= 0) {
+ if (filled - count >= mHighLevelArm) {
+ mArmed = true;
+ }
+ if (mArmed && filled - count <= mLowLevelTrigger) {
+ int err = sys_futex(&mFifo.mSharedRear.mIndex,
+ mFifo.mIsPrivate ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
+ 1 /*waiters*/, NULL, NULL, 0);
+ // err is number of processes woken up
+ if (err < 0 || err > 1) {
+ LOG_ALWAYS_FATAL("%s: unexpected err=%d errno=%d", __func__, err, errno);
+ }
+ mArmed = false;
+ }
+ }
+ } else {
+ mLocalFront = mFifo.sum(mLocalFront, count);
+ }
+ mObtained -= count;
+ }
+}
+
+ssize_t audio_utils_fifo_reader::obtain(audio_utils_iovec iovec[2], size_t count,
+ struct timespec *timeout, size_t *lost)
+ __attribute__((no_sanitize("integer")))
+{
+ uint32_t rear;
+ for (;;) {
+ rear = atomic_load_explicit(&mFifo.mSharedRear.mIndex,
+ std::memory_order_acquire);
+ // TODO pull out "count == 0"
+ if (count == 0 || rear != mLocalFront || timeout == NULL ||
+ (timeout->tv_sec == 0 && timeout->tv_nsec == 0)) {
+ break;
+ }
+ int err = sys_futex(&mFifo.mSharedRear.mIndex,
+ mFifo.mIsPrivate ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT,
+ rear, timeout, NULL, 0);
+ if (err < 0) {
+ switch (errno) {
+ case EWOULDBLOCK:
+ case EINTR:
+ case ETIMEDOUT:
+ break;
+ default:
+ LOG_ALWAYS_FATAL("unexpected err=%d errno=%d", err, errno);
+ break;
+ }
+ }
+ timeout = NULL;
+ }
+ int32_t filled = mFifo.diff(rear, mLocalFront, lost);
+ if (filled < 0) {
+ if (filled == -EOVERFLOW) {
+ mLocalFront = rear;
+ }
+ mObtained = 0;
+ return (ssize_t) filled;
+ }
+ size_t availToRead = (size_t) filled;
+ if (availToRead > count) {
+ availToRead = count;
+ }
+ uint32_t frontMasked = mLocalFront & (mFifo.mFrameCountP2 - 1);
+ size_t part1 = mFifo.mFrameCount - frontMasked;
+ if (part1 > availToRead) {
+ part1 = availToRead;
+ }
+ size_t part2 = part1 > 0 ? availToRead - part1 : 0;
+ iovec[0].mOffset = frontMasked;
+ iovec[0].mLength = part1;
+ iovec[1].mOffset = 0;
+ iovec[1].mLength = part2;
+ mObtained = availToRead;
+ return availToRead;
+}
#ifndef ANDROID_AUDIO_FIFO_H
#define ANDROID_AUDIO_FIFO_H
+#include <atomic>
#include <stdlib.h>
-// FIXME use atomic_int_least32_t and new atomic operations instead of legacy Android ones
-// #include <stdatomic.h>
-
-#ifdef __cplusplus
-extern "C" {
+#ifndef __cplusplus
+#error C API is no longer supported
#endif
-// Single writer, single reader non-blocking FIFO.
-// Writer and reader must be in same process.
+/** An index that may optionally be placed in shared memory.
+ * Must be Plain Old Data (POD), so no virtual methods are allowed.
+ * If in shared memory, exactly one process must explicitly call the constructor via placement new.
+ */
+struct audio_utils_fifo_index {
+ friend class audio_utils_fifo_reader;
+ friend class audio_utils_fifo_writer;
+
+public:
+ audio_utils_fifo_index() : mIndex(0) { }
+
+private:
+ // Linux futex is 32 bits regardless of platform.
+ // It would make more sense to declare this as atomic_uint32_t, but there is no such type name.
+ std::atomic_uint_least32_t mIndex; // accessed by both sides using atomic operations
+ static_assert(sizeof(mIndex) == sizeof(uint32_t), "mIndex must be 32 bits");
+
+ // TODO Abstract out atomic operations to here
+ // TODO Replace friend by setter and getter, and abstract the futex
+};
+
+// Base class for single writer, single-reader or multi-reader non-blocking FIFO.
+// The base class manipulates frame indices only, and has no knowledge of frame sizes or the buffer.
+
+class audio_utils_fifo_base {
+
+protected:
+
+/* Construct FIFO base class
+ *
+ * \param sharedRear Writer's rear index in shared memory.
+ * \param throttleFront Pointer to the front index of at most one reader that throttles the
+ * writer, or NULL for no throttling.
+ */
+ audio_utils_fifo_base(uint32_t frameCount, audio_utils_fifo_index& sharedRear,
+ // TODO inconsistent & vs *
+ audio_utils_fifo_index *throttleFront = NULL);
+ /*virtual*/ ~audio_utils_fifo_base();
+
+/** Return a new index as the sum of a validated index and a specified increment.
+ *
+ * \param index Caller should supply a validated mFront or mRear.
+ * \param increment Value to be added to the index <= mFrameCount.
+ *
+ * \return the sum of index plus increment.
+ */
+ uint32_t sum(uint32_t index, uint32_t increment);
+
+/** Return the difference between two indices: rear - front.
+ *
+ * \param rear Caller should supply an unvalidated mRear.
+ * \param front Caller should supply an unvalidated mFront.
+ * \param lost If non-NULL, set to the approximate number of lost frames.
+ *
+ * \return the zero or positive difference <= mFrameCount, or a negative error code.
+ */
+ int32_t diff(uint32_t rear, uint32_t front, size_t *lost);
-// No user-serviceable parts within.
-struct audio_utils_fifo {
// These fields are const after initialization
- size_t mFrameCount; // max number of significant frames to be stored in the FIFO > 0
- size_t mFrameCountP2; // roundup(mFrameCount)
- size_t mFudgeFactor; // mFrameCountP2 - mFrameCount, the number of "wasted" frames after
- // the end of mBuffer. Only the indices are wasted, not any memory.
- size_t mFrameSize; // size of each frame in bytes
- void *mBuffer; // pointer to caller-allocated buffer of size mFrameCount frames
-
- volatile int32_t mFront; // frame index of first frame slot available to read, or read index
- volatile int32_t mRear; // frame index of next frame slot available to write, or write index
+ const uint32_t mFrameCount; // max number of significant frames to be stored in the FIFO > 0
+ const uint32_t mFrameCountP2; // roundup(mFrameCount)
+ const uint32_t mFudgeFactor; // mFrameCountP2 - mFrameCount, the number of "wasted" frames
+ // after the end of mBuffer. Only the indices are wasted, not any
+ // memory.
+
+ // TODO always true for now, will be extended later to support false
+ const bool mIsPrivate; // whether reader and writer virtual address spaces are the same
+
+ audio_utils_fifo_index& mSharedRear;
+
+ // Pointer to the front index of at most one reader that throttles the writer,
+ // or NULL for no throttling
+ audio_utils_fifo_index* mThrottleFront;
};
+////////////////////////////////////////////////////////////////////////////////
+
+// Same as above, but understands frame sizes and knows about the buffer but does not own it.
+// Writer and reader must be in same process.
+
+class audio_utils_fifo : audio_utils_fifo_base {
+
+ friend class audio_utils_fifo_reader;
+ friend class audio_utils_fifo_writer;
+
+public:
+
/**
- * Initialize a FIFO object.
+ * Construct a FIFO object: multi-process.
*
- * \param fifo Pointer to the FIFO object.
* \param frameCount Max number of significant frames to be stored in the FIFO > 0.
* If writes and reads always use the same count, and that count is a divisor of
* frameCount, then the writes and reads will never do a partial transfer.
- * \param frameSize Size of each frame in bytes.
+ * \param frameSize Size of each frame in bytes > 0, and frameSize * frameCount <= INT_MAX.
* \param buffer Pointer to a caller-allocated buffer of frameCount frames.
+ * \param sharedRear Writer's rear index in shared memory.
+ * \param throttleFront Pointer to the front index of at most one reader that throttles the
+ * writer, or NULL for no throttling.
*/
-void audio_utils_fifo_init(struct audio_utils_fifo *fifo, size_t frameCount, size_t frameSize,
- void *buffer);
+ audio_utils_fifo(uint32_t frameCount, uint32_t frameSize, void *buffer,
+ // TODO inconsistent & vs *
+ audio_utils_fifo_index& sharedRear, audio_utils_fifo_index *throttleFront = NULL);
/**
- * De-initialize a FIFO object.
- *
- * \param fifo Pointer to the FIFO object.
+ * Construct a FIFO object: single-process.
+ * \param throttlesWriter Whether there is a reader that throttles the writer.
*/
-void audio_utils_fifo_deinit(struct audio_utils_fifo *fifo);
+ audio_utils_fifo(uint32_t frameCount, uint32_t frameSize, void *buffer,
+ bool throttlesWriter = false);
+
+ /*virtual*/ ~audio_utils_fifo();
+
+private:
+
+ // These fields are const after initialization
+ const uint32_t mFrameSize; // size of each frame in bytes
+ void * const mBuffer; // pointer to caller-allocated buffer of size mFrameCount frames
+
+ // only used for single-process constructor
+ audio_utils_fifo_index mSingleProcessSharedRear;
+
+ // only used for single-process constructor when throttlesWriter == true
+ audio_utils_fifo_index mSingleProcessSharedFront;
+};
+
+// Describes one virtually contiguous fragment of a logically contiguous slice.
+// Compare to struct iovec for readv(2) and writev(2).
+struct audio_utils_iovec {
+ uint32_t mOffset; // in frames, relative to mBuffer, undefined if mLength == 0
+ uint32_t mLength; // in frames
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Based on frameworks/av/include/media/AudioBufferProvider.h
+class audio_utils_fifo_provider {
+public:
+ audio_utils_fifo_provider();
+ virtual ~audio_utils_fifo_provider();
+
+// The count is the maximum number of desired frames, not the minimum number of desired frames.
+// See the high/low setpoints for something which is close to, but not the same as, a true minimum.
+
+// The timeout indicates the maximum time to wait for at least one frame, not for all frames.
+// NULL is equivalent to non-blocking.
+// FIXME specify timebase, relative/absolute etc
+
+// Error codes for ssize_t return value:
+// -EIO corrupted indices (reader or writer)
+// -EOVERFLOW reader is not keeping up with writer (reader only)
+ virtual ssize_t obtain(audio_utils_iovec iovec[2], size_t count, struct timespec *timeout) = 0;
+
+ virtual void release(size_t count) = 0;
+
+protected:
+ // Number of frames obtained at most recent obtain(), less number of frames released
+ uint32_t mObtained;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class audio_utils_fifo_writer : public audio_utils_fifo_provider {
+
+public:
+ // Single-process and multi-process use same constructor here, but different 'fifo' constructors
+ audio_utils_fifo_writer(audio_utils_fifo& fifo);
+ virtual ~audio_utils_fifo_writer();
/**
* Write to FIFO.
*
- * \param fifo Pointer to the FIFO object.
- * \param buffer Pointer to source buffer containing 'count' frames of data.
- * \param count Desired number of frames to write.
+ * \param buffer Pointer to source buffer containing 'count' frames of data.
+ * \param count Desired number of frames to write.
+ * \param timeout NULL and zero fields are both non-blocking.
*
* \return actual number of frames written <= count.
*
* The actual transfer count may be zero if the FIFO is full,
* or partial if the FIFO was almost full.
- * A negative return value indicates an error. Currently there are no errors defined.
+ * A negative return value indicates an error.
*/
-ssize_t audio_utils_fifo_write(struct audio_utils_fifo *fifo, const void *buffer, size_t count);
+ ssize_t write(const void *buffer, size_t count, struct timespec *timeout = NULL);
+
+ // Implement audio_utils_fifo_provider
+ virtual ssize_t obtain(audio_utils_iovec iovec[2], size_t count, struct timespec *timeout);
+ virtual void release(size_t count);
+
+ // TODO add error checks and getters
+ void setHighLevelTrigger(uint32_t level) { mHighLevelTrigger = level; }
+ void setEffectiveFrames(uint32_t effectiveFrames) { mEffectiveFrames = effectiveFrames; }
+
+private:
+ audio_utils_fifo& mFifo;
+
+ // Accessed by writer only using ordinary operations
+ uint32_t mLocalRear; // frame index of next frame slot available to write, or write index
+
+ // TODO needs a state transition diagram for threshold and arming process
+ uint32_t mLowLevelArm; // arm if filled <= threshold
+ uint32_t mHighLevelTrigger; // trigger reader if armed and filled >= threshold
+ bool mArmed;
+
+ uint32_t mEffectiveFrames; // current effective buffer size, <= mFifo.mFrameCount
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class audio_utils_fifo_reader : public audio_utils_fifo_provider {
+
+public:
+ // At most one reader can specify throttlesWriter == true
+ audio_utils_fifo_reader(audio_utils_fifo& fifo, bool throttlesWriter = true);
+ virtual ~audio_utils_fifo_reader();
/** Read from FIFO.
*
- * \param fifo Pointer to the FIFO object.
- * \param buffer Pointer to destination buffer to be filled with up to 'count' frames of data.
- * \param count Desired number of frames to read.
+ * \param buffer Pointer to destination buffer to be filled with up to 'count' frames of data.
+ * \param count Desired number of frames to read.
+ * \param timeout NULL and zero fields are both non-blocking.
+ * \param lost If non-NULL, set to the approximate number of lost frames before re-sync.
*
* \return actual number of frames read <= count.
*
* The actual transfer count may be zero if the FIFO is empty,
* or partial if the FIFO was almost empty.
- * A negative return value indicates an error. Currently there are no errors defined.
+ * A negative return value indicates an error.
*/
-ssize_t audio_utils_fifo_read(struct audio_utils_fifo *fifo, void *buffer, size_t count);
+ ssize_t read(void *buffer, size_t count, struct timespec *timeout = NULL, size_t *lost = NULL);
-#ifdef __cplusplus
-}
-#endif
+ // Implement audio_utils_fifo_provider
+ virtual ssize_t obtain(audio_utils_iovec iovec[2], size_t count, struct timespec *timeout);
+ virtual void release(size_t count);
+
+ // Extended parameter list for reader only
+ ssize_t obtain(audio_utils_iovec iovec[2], size_t count, struct timespec *timeout,
+ size_t *lost);
+
+private:
+ audio_utils_fifo& mFifo;
+
+ // Accessed by reader only using ordinary operations
+ uint32_t mLocalFront; // frame index of first frame slot available to read, or read index
+
+ // Points to shared front index if this reader throttles writer, or NULL if we don't throttle
+ audio_utils_fifo_index* mThrottleFront;
+
+ // TODO not used yet
+ uint32_t mHighLevelArm; // arm if filled >= threshold
+ uint32_t mLowLevelTrigger; // trigger writer if armed and filled <= threshold
+ bool mArmed;
+
+};
#endif // !ANDROID_AUDIO_FIFO_H
],
}
+cc_binary {
+ name: "fifo_multiprocess",
+ host_supported: false,
+ srcs: ["fifo_multiprocess.cpp"],
+ shared_libs: ["libaudioutils", "libcutils"],
+ static_libs: ["libsndfile"],
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+}
+
+cc_binary_host {
+ name: "fifo_threads",
+ // TODO move getch.c and .h to a utility library
+ srcs: [
+ "fifo_threads.cpp",
+ "getch.c",
+ ],
+ static_libs: [
+ "libaudioutils",
+ "liblog",
+ ],
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+}
+
cc_binary_host {
name: "limiter_tests",
srcs: ["limiter_tests.c"],
cflags: [
"-Werror",
"-Wall",
+ "-UNDEBUG",
],
}
--- /dev/null
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <new>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <audio_utils/fifo.h>
+#include <cutils/ashmem.h>
+
+#define FRAME_COUNT 2048
+#define FRAME_SIZE sizeof(int16_t)
+#define BUFFER_SIZE (FRAME_COUNT * FRAME_SIZE)
+
+int main(int argc __unused, char **argv __unused)
+{
+ // TODO Add error checking for ashmem_create_region and mmap
+
+ const int frontFd = ashmem_create_region("front", sizeof(audio_utils_fifo_index));
+ printf("frontFd=%d\n", frontFd);
+
+ const int rearFd = ashmem_create_region("rear", sizeof(audio_utils_fifo_index));
+ printf("rearFd=%d\n", rearFd);
+
+ const int dataFd = ashmem_create_region("buffer", BUFFER_SIZE);
+ printf("dataFd=%d\n", dataFd);
+
+ // next two index constructors must execute exactly once, so we do it in the parent
+
+ audio_utils_fifo_index *frontIndex = (audio_utils_fifo_index *) mmap(NULL,
+ sizeof(audio_utils_fifo_index), PROT_READ | PROT_WRITE, MAP_SHARED, frontFd, (off_t) 0);
+ printf("parent frontIndex=%p\n", frontIndex);
+ (void) new(frontIndex) audio_utils_fifo_index();
+
+ audio_utils_fifo_index *rearIndex = (audio_utils_fifo_index *) mmap(NULL,
+ sizeof(audio_utils_fifo_index), PROT_READ | PROT_WRITE, MAP_SHARED, rearFd, (off_t) 0);
+ printf("parent rearIndex=%p\n", rearIndex);
+ (void) new(rearIndex) audio_utils_fifo_index();
+
+ int16_t *data = (int16_t *) mmap(NULL, sizeof(audio_utils_fifo_index), PROT_READ | PROT_WRITE,
+ MAP_SHARED, dataFd, (off_t) 0);
+ printf("parent data=%p\n", data);
+ memset(data, 0, BUFFER_SIZE);
+
+ const int pageSize = getpagesize();
+ printf("page size=%d\n", pageSize);
+
+ // create writer
+
+ printf("fork writer:\n");
+ const pid_t pidWriter = fork();
+ // TODO check if pidWriter < 0
+ if (!pidWriter) {
+
+ // Child inherits the parent's read/write mapping of front index.
+ // To confirm that there are no attempts to write to the front index,
+ // unmap it and then re-map it as read-only.
+ int ok = munmap(frontIndex, sizeof(audio_utils_fifo_index));
+ printf("writer unmap front ok=%d\n", ok);
+ ok = ashmem_set_prot_region(frontFd, PROT_READ);
+ printf("writer prot read front ok=%d\n", ok);
+ // The pagesize * 4 offset confirms that we don't assume identical mapping in both processes
+ frontIndex = (audio_utils_fifo_index *) mmap((char *) frontIndex + pageSize * 4,
+ sizeof(audio_utils_fifo_index), PROT_READ, MAP_SHARED | MAP_FIXED, frontFd,
+ (off_t) 0);
+ printf("writer frontIndex=%p\n", frontIndex);
+
+ // Retain our read/write mapping of rear index and data
+ audio_utils_fifo fifo(FRAME_COUNT, FRAME_SIZE, data, *rearIndex, frontIndex);
+ audio_utils_fifo_writer writer(fifo);
+
+ sleep(2);
+
+ for (int16_t value = 1; value <= 20; value++) {
+ printf("writing %d\n", value);
+ const ssize_t actual = writer.write(&value, 1);
+ if (actual != 1) {
+ printf("wrote unexpected actual = %zd\n", actual);
+ break;
+ }
+ sleep(1);
+ }
+
+ (void) close(frontFd);
+ (void) close(rearFd);
+ (void) close(dataFd);
+
+ return EXIT_SUCCESS;
+ }
+
+ // The sleep(2) above and sleep(1) here ensure that the order is:
+ // a. writer initializes
+ // b. reader initializes
+ // c. reader starts the read loop
+ // d. writer starts the write loop
+ // Actually, as long as (a) precedes (d) and (b) precedes (c), the order does not matter.
+ // TODO test all valid sequences.
+ sleep(1);
+
+ // create reader
+
+ printf("fork reader:\n");
+ const pid_t pidReader = fork();
+ // TODO check if pidReader < 0
+ if (!pidReader) {
+
+ // Child inherits the parent's read/write mapping of rear index.
+ // To confirm that there are no attempts to write to the rear index,
+ // unmap it and then re-map it as read-only.
+ int ok = munmap(rearIndex, sizeof(audio_utils_fifo_index));
+ printf("reader unmap rear ok=%d\n", ok);
+ ok = ashmem_set_prot_region(rearFd, PROT_READ);
+ printf("reader prot read rear ok=%d\n", ok);
+ // The pagesize * 4 offset confirms that we don't assume identical mapping in both processes
+ rearIndex = (audio_utils_fifo_index *) mmap((char *) rearIndex + pageSize * 4,
+ sizeof(audio_utils_fifo_index), PROT_READ, MAP_SHARED | MAP_FIXED, rearFd, (off_t) 0);
+ printf("reader rearIndex=%p\n", rearIndex);
+
+ // Similarly for the data
+ ok = munmap(data, BUFFER_SIZE);
+ printf("reader unmap data ok=%d\n", ok);
+ ok = ashmem_set_prot_region(dataFd, PROT_READ);
+ printf("reader prot read data ok=%d\n", ok);
+ // The pagesize * 8 offset confirms that we don't assume identical mapping in both processes
+ data = (int16_t *) mmap((char *) data + pageSize * 8, BUFFER_SIZE, PROT_READ,
+ MAP_SHARED | MAP_FIXED, dataFd, (off_t) 0);
+ printf("reader data=%p\n", data);
+
+ // Retain our read/write mapping of front index
+ audio_utils_fifo fifo(FRAME_COUNT, FRAME_SIZE, data, *rearIndex, frontIndex);
+ audio_utils_fifo_reader reader(fifo);
+
+ for (;;) {
+ int16_t value;
+ struct timespec timeout = {
+ .tv_sec = 1,
+ .tv_nsec = 0
+ };
+ const ssize_t actual = reader.read(&value, 1, &timeout);
+ switch (actual) {
+ case 0:
+ break;
+ case 1:
+ printf("read %d\n", value);
+ if (value == 20) {
+ goto out;
+ }
+ break;
+ default:
+ printf("read unexpected actual = %zd\n", actual);
+ goto out;
+ }
+ }
+out:
+
+ (void) close(frontFd);
+ (void) close(rearFd);
+ (void) close(dataFd);
+
+ return EXIT_SUCCESS;
+ }
+
+ int status;
+ pid_t pid = waitpid(pidWriter, &status, 0);
+ if (pid == pidWriter) {
+ printf("writer exited with status %d\n", status);
+ } else {
+ printf("waitpid on writer = %d\n", pid);
+ }
+ pid = waitpid(pidReader, &status, 0);
+ if (pid == pidReader) {
+ printf("reader exited with status %d\n", status);
+ } else {
+ printf("waitpid on reader = %d\n", pid);
+ }
+
+ // next two index destructors must execute exactly once, so we do it in the parent
+ frontIndex->~audio_utils_fifo_index();
+ rearIndex->~audio_utils_fifo_index();
+
+ int ok = munmap(frontIndex, sizeof(audio_utils_fifo_index));
+ printf("parent unmap front ok=%d\n", ok);
+ ok = munmap(rearIndex, sizeof(audio_utils_fifo_index));
+ printf("parent unmap rear ok=%d\n", ok);
+ ok = munmap(data, BUFFER_SIZE);
+ printf("parent unmap data ok=%d\n", ok);
+
+ (void) close(frontFd);
+ (void) close(rearFd);
+ (void) close(dataFd);
+
+ return EXIT_SUCCESS;
+}
// Test program for audio_utils FIFO library.
// This only tests the single-threaded aspects, not the barriers.
+#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <audio_utils/fifo.h>
#include <audio_utils/sndfile.h>
+#ifndef min
+#define min(x, y) (((x) < (y)) ? (x) : (y))
+#endif
+
int main(int argc, char **argv)
{
- size_t frameCount = 256;
- size_t maxFramesPerRead = 1;
- size_t maxFramesPerWrite = 1;
+ size_t frameCount = 0;
+ size_t maxFramesPerRead = 0;
+ size_t maxFramesPerWrite = 0;
+ bool readerThrottlesWriter = true;
int i;
for (i = 1; i < argc; i++) {
char *arg = argv[i];
if (arg[0] != '-')
break;
switch (arg[1]) {
- case 'c': // FIFO frame count
+ case 'f': // FIFO frame count
frameCount = atoi(&arg[2]);
break;
case 'r': // maximum frame count per read from FIFO
maxFramesPerRead = atoi(&arg[2]);
break;
+ case 't': // disable throttling of writer by reader
+ readerThrottlesWriter = false;
+ break;
case 'w': // maximum frame count per write to FIFO
maxFramesPerWrite = atoi(&arg[2]);
break;
goto usage;
}
}
+ if (frameCount == 0) {
+ frameCount = 256;
+ }
+ if (maxFramesPerRead == 0) {
+ maxFramesPerRead = frameCount;
+ }
+ if (maxFramesPerWrite == 0) {
+ maxFramesPerWrite = frameCount;
+ }
if (argc - i != 2) {
usage:
- fprintf(stderr, "usage: %s [-c#] in.wav out.wav\n", argv[0]);
+ fprintf(stderr, "usage: %s [-f#] [-r#] [-t] [-w#] in.wav out.wav\n", argv[0]);
return EXIT_FAILURE;
}
char *inputFile = argv[i];
perror(inputFile);
return EXIT_FAILURE;
}
- // sf_readf_short() does conversion, so not strictly necessary to check the file format.
- // But I want to do "cmp" on input and output files afterwards,
- // and it is easier if they are all the same format.
- // Enforcing that everything is 16-bit is convenient for this.
- if ((sfinfoin.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) !=
- (SF_FORMAT_WAV | SF_FORMAT_PCM_16)) {
+ switch (sfinfoin.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) {
+ case SF_FORMAT_WAV | SF_FORMAT_PCM_16:
+ case SF_FORMAT_WAV | SF_FORMAT_PCM_U8:
+ break;
+ default:
fprintf(stderr, "%s: unsupported format\n", inputFile);
sf_close(sfin);
return EXIT_FAILURE;
short *outputBuffer = new short[sfinfoin.frames * sfinfoin.channels];
size_t framesWritten = 0;
size_t framesRead = 0;
- struct audio_utils_fifo fifo;
short *fifoBuffer = new short[frameCount * sfinfoin.channels];
- audio_utils_fifo_init(&fifo, frameCount, frameSize, fifoBuffer);
+ audio_utils_fifo fifo(frameCount, frameSize, fifoBuffer);
+ audio_utils_fifo_writer fifoWriter(fifo);
+ audio_utils_fifo_reader fifoReader(fifo, readerThrottlesWriter);
int fifoWriteCount = 0, fifoReadCount = 0;
int fifoFillLevel = 0, minFillLevel = INT_MAX, maxFillLevel = INT_MIN;
for (;;) {
size_t framesToWrite = sfinfoin.frames - framesWritten;
size_t framesToRead = sfinfoin.frames - framesRead;
- if (framesToWrite == 0 && framesToRead == 0) {
+ if (framesToWrite == 0 && (framesToRead == 0 || !readerThrottlesWriter)) {
break;
}
framesToWrite = maxFramesPerWrite;
}
framesToWrite = rand() % (framesToWrite + 1);
- ssize_t actualWritten = audio_utils_fifo_write(&fifo,
+ ssize_t actualWritten = fifoWriter.write(
&inputBuffer[framesWritten * sfinfoin.channels], framesToWrite);
+ //printf("wrote %d out of %d\n", (int) actualWritten, (int) framesToWrite);
if (actualWritten < 0 || (size_t) actualWritten > framesToWrite) {
fprintf(stderr, "write to FIFO failed\n");
break;
}
+ if (actualWritten < min((int) frameCount - fifoFillLevel, (int) framesToWrite)) {
+ fprintf(stderr, "only wrote %d when should have written min(%d, %d)\n",
+ (int) actualWritten, (int) frameCount - fifoFillLevel, (int) framesToWrite);
+ }
framesWritten += actualWritten;
if (actualWritten > 0) {
fifoWriteCount++;
fifoFillLevel += actualWritten;
if (fifoFillLevel > maxFillLevel) {
maxFillLevel = fifoFillLevel;
- if (maxFillLevel > (int) frameCount)
- abort();
+ if (maxFillLevel > (int) frameCount) {
+ if (readerThrottlesWriter) {
+ printf("maxFillLevel=%d > frameCount=%d\n", maxFillLevel, (int) frameCount);
+ abort();
+ }
+ }
}
if (framesToRead > maxFramesPerRead) {
framesToRead = maxFramesPerRead;
}
framesToRead = rand() % (framesToRead + 1);
- ssize_t actualRead = audio_utils_fifo_read(&fifo,
+ ssize_t actualRead = fifoReader.read(
&outputBuffer[framesRead * sfinfoin.channels], framesToRead);
+ //printf("read %d out of %d\n", (int) actualRead, (int) framesToRead);
if (actualRead < 0 || (size_t) actualRead > framesToRead) {
- fprintf(stderr, "read from FIFO failed\n");
- break;
+ switch (actualRead) {
+ case -EIO:
+ fprintf(stderr, "read from FIFO failed: corrupted indices\n");
+ abort();
+ break;
+ case -EOVERFLOW:
+ if (readerThrottlesWriter) {
+ fprintf(stderr, "read from FIFO failed: unexpected overflow\n");
+ abort();
+ }
+ printf("warning: reader lost frames\n");
+ actualRead = 0;
+ break;
+ default:
+ if (actualRead < 0) {
+ fprintf(stderr, "read from FIFO failed: unexpected error code %d\n",
+ (int) actualRead);
+ } else {
+ fprintf(stderr, "read from FIFO failed: actualRead=%d > framesToRead=%d\n",
+ (int) actualRead, (int) framesToRead);
+ }
+ abort();
+ }
+ }
+ if (actualRead < min(fifoFillLevel, (int) framesToRead)) {
+ //fprintf(stderr, "only read %d when should have read min(%d, %d)\n",
+ // (int) actualRead, fifoFillLevel, (int) framesToRead);
}
framesRead += actualRead;
if (actualRead > 0) {
fifoFillLevel -= actualRead;
if (fifoFillLevel < minFillLevel) {
minFillLevel = fifoFillLevel;
- if (minFillLevel < 0)
+ if (minFillLevel < 0) {
+ printf("minFillLevel=%d < 0\n", minFillLevel);
abort();
+ }
}
}
+ delete[] inputBuffer;
+ inputBuffer = NULL;
+ delete[] fifoBuffer;
+ fifoBuffer = NULL;
+
printf("FIFO non-empty writes: %d, non-empty reads: %d\n", fifoWriteCount, fifoReadCount);
printf("fill=%d, min=%d, max=%d\n", fifoFillLevel, minFillLevel, maxFillLevel);
- audio_utils_fifo_deinit(&fifo);
- delete[] fifoBuffer;
SF_INFO sfinfoout;
memset(&sfinfoout, 0, sizeof(sfinfoout));
return EXIT_FAILURE;
}
sf_count_t actualWritten = sf_writef_short(sfout, outputBuffer, framesRead);
- delete[] inputBuffer;
delete[] outputBuffer;
- delete[] fifoBuffer;
+ outputBuffer = NULL;
+
if (actualWritten != (sf_count_t) framesRead) {
fprintf(stderr, "%s: unexpected error\n", outputFile);
sf_close(sfout);
--- /dev/null
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <audio_utils/fifo.h>
+extern "C" {
+#include "getch.h"
+}
+
+struct Context {
+ audio_utils_fifo_writer *mInputWriter;
+ audio_utils_fifo_reader *mInputReader;
+ audio_utils_fifo_writer *mTransferWriter;
+ audio_utils_fifo_reader *mTransferReader;
+ audio_utils_fifo_writer *mOutputWriter;
+ audio_utils_fifo_reader *mOutputReader;
+};
+
+void *input_routine(void *arg)
+{
+ Context *context = (Context *) arg;
+ for (;;) {
+ struct timespec timeout;
+ timeout.tv_sec = 3;
+ timeout.tv_nsec = 0;
+ char buffer[4];
+ ssize_t actual = context->mInputReader->read(buffer, sizeof(buffer), &timeout);
+ if (actual == 0) {
+ (void) write(1, "t", 1);
+ } else if (actual > 0) {
+ actual = context->mTransferWriter->write(buffer, actual, &timeout);
+ //printf("transfer.write actual = %d\n", (int) actual);
+ } else {
+ printf("input.read actual = %d\n", (int) actual);
+ }
+ }
+ return NULL;
+}
+
+void *output_routine(void *arg)
+{
+ Context *context = (Context *) arg;
+ for (;;) {
+ struct timespec timeout;
+ timeout.tv_sec = 5;
+ timeout.tv_nsec = 0;
+ char buffer[4];
+ ssize_t actual = context->mTransferReader->read(buffer, sizeof(buffer), &timeout);
+ if (actual == 0) {
+ (void) write(1, "T", 1);
+ } else if (actual > 0) {
+ actual = context->mOutputWriter->write(buffer, actual, &timeout);
+ //printf("output.write actual = %d\n", (int) actual);
+ } else {
+ printf("transfer.read actual = %d\n", (int) actual);
+ }
+ }
+ return NULL;
+}
+
+int main(int argc, char **argv)
+{
+ set_conio_terminal_mode();
+ argc = argc + 0;
+ argv = &argv[0];
+
+ char inputBuffer[64];
+ audio_utils_fifo inputFifo(sizeof(inputBuffer) /*frameCount*/, 1 /*frameSize*/, inputBuffer);
+ audio_utils_fifo_writer inputWriter(inputFifo);
+ audio_utils_fifo_reader inputReader(inputFifo, true /*readerThrottlesWriter*/);
+ inputWriter.setHighLevelTrigger(3);
+
+ char transferBuffer[64];
+ audio_utils_fifo transferFifo(sizeof(transferBuffer) /*frameCount*/, 1 /*frameSize*/,
+ transferBuffer);
+ audio_utils_fifo_writer transferWriter(transferFifo);
+ audio_utils_fifo_reader transferReader(transferFifo, true /*readerThrottlesWriter*/);
+ transferWriter.setEffectiveFrames(2);
+
+ char outputBuffer[64];
+ audio_utils_fifo outputFifo(sizeof(outputBuffer) /*frameCount*/, 1 /*frameSize*/, outputBuffer);
+ audio_utils_fifo_writer outputWriter(outputFifo);
+ audio_utils_fifo_reader outputReader(outputFifo, true /*readerThrottlesWriter*/);
+
+ Context context;
+ context.mInputWriter = &inputWriter;
+ context.mInputReader = &inputReader;
+ context.mTransferWriter = &transferWriter;
+ context.mTransferReader = &transferReader;
+ context.mOutputWriter = &outputWriter;
+ context.mOutputReader = &outputReader;
+
+ pthread_t input_thread;
+ int ok = pthread_create(&input_thread, (const pthread_attr_t *) NULL, input_routine,
+ (void *) &context);
+ pthread_t output_thread;
+ ok = pthread_create(&output_thread, (const pthread_attr_t *) NULL, output_routine,
+ (void *) &context);
+ ok = ok + 0;
+
+ for (;;) {
+ char buffer[1];
+ struct timespec timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 0;
+ ssize_t actual = outputReader.read(buffer, sizeof(buffer), &timeout);
+ if (actual == 1) {
+ printf("%c", buffer[0]);
+ fflush(stdout);
+ } else if (actual != 0) {
+ printf("outputReader.read actual = %d\n", (int) actual);
+ }
+ if (kbhit()) {
+ int ch = getch();
+ if (ch <= 0 || ch == 3) {
+ break;
+ }
+ buffer[0] = ch;
+ actual = inputWriter.write(buffer, sizeof(buffer), &timeout);
+ if (actual != 1) {
+ printf("inputWriter.write actual = %d\n", (int) actual);
+ }
+ }
+ }
+ reset_terminal_mode();
+}
--- /dev/null
+../../../../frameworks/wilhelm/tests/sandbox/getch.c
\ No newline at end of file
--- /dev/null
+../../../../frameworks/wilhelm/tests/sandbox/getch.h
\ No newline at end of file
$(audio_client_sources)
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
LOCAL_SHARED_LIBRARIES := $(audio_service_shared_libraries)
-LOCAL_CFLAGS := -Wall -std=c++14
+LOCAL_CFLAGS := -Wall -Werror -std=c++14
include $(BUILD_SHARED_LIBRARY)
# Unit tests for the Brillo audio service.
libBionicGtestMain \
libchrome_test_helpers \
libgmock
-LOCAL_CFLAGS := -Wno-sign-compare -Wall
+LOCAL_CFLAGS := -Wno-sign-compare -Wall -Werror
include $(BUILD_NATIVE_TEST)
#include <string.h>
#include <stdint.h>
#include <cutils/compiler.h>
-#include <system/camera_vendor_tags.h>
#ifdef __cplusplus
extern "C" {