OSDN Git Service

Merge "Removes gnu designated initializers." am: 594952f2a2 am: e72d1d1206 am: 9e36579d55
authorColin Cross <ccross@android.com>
Fri, 7 Oct 2016 00:10:37 +0000 (00:10 +0000)
committerandroid-build-merger <android-build-merger@google.com>
Fri, 7 Oct 2016 00:10:37 +0000 (00:10 +0000)
am: cb5d4c6038

Change-Id: Ibc603eaa5413040eb5bf090c21f88132836ba624

15 files changed:
audio/include/system/audio-base.h [new file with mode: 0644]
audio/include/system/audio.h
audio_utils/Android.bp
audio_utils/README.md [new file with mode: 0644]
audio_utils/fifo.c [deleted file]
audio_utils/fifo.cpp [new file with mode: 0644]
audio_utils/include/audio_utils/fifo.h
audio_utils/tests/Android.bp
audio_utils/tests/fifo_multiprocess.cpp [new file with mode: 0644]
audio_utils/tests/fifo_tests.cpp
audio_utils/tests/fifo_threads.cpp [new file with mode: 0644]
audio_utils/tests/getch.c [new symlink]
audio_utils/tests/getch.h [new symlink]
brillo/audio/audioservice/Android.mk
camera/include/system/camera_metadata.h

diff --git a/audio/include/system/audio-base.h b/audio/include/system/audio-base.h
new file mode 100644 (file)
index 0000000..8018d0b
--- /dev/null
@@ -0,0 +1,316 @@
+// 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_
index d7a90ea..4f9b3a5 100644 (file)
 
 #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
@@ -52,36 +41,6 @@ __BEGIN_DECLS
 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
  */
@@ -138,37 +97,6 @@ enum {
     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 {
@@ -179,36 +107,6 @@ 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
@@ -239,253 +137,6 @@ static inline audio_unique_id_use_t audio_unique_id_get_use(audio_unique_id_t id
 /* 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.
  *
@@ -519,42 +170,17 @@ enum {
  */
 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)
@@ -593,32 +219,6 @@ static inline audio_channel_mask_t audio_channel_mask_from_representation_and_bi
     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,
@@ -630,194 +230,8 @@ typedef enum {
     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
@@ -915,11 +329,6 @@ typedef enum {
  * 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;
 
 
@@ -964,23 +373,6 @@ struct audio_gain_config  {
  * 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
@@ -1017,16 +409,6 @@ struct audio_port_config_session_ext {
     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 {
@@ -1062,12 +444,6 @@ struct audio_port_device_ext {
     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 */
index 969ed07..fa8fc42 100644 (file)
@@ -19,7 +19,7 @@ cc_library {
 
     srcs: [
         "channels.c",
-        "fifo.c",
+        "fifo.cpp",
         "format.c",
         "limiter.c",
         "minifloat.c",
@@ -77,7 +77,7 @@ cc_library_static {
     name: "libfifo",
     defaults: ["audio_utils_defaults"],
     srcs: [
-        "fifo.c",
+        "fifo.cpp",
         "primitives.c",
         "roundup.c",
     ],
diff --git a/audio_utils/README.md b/audio_utils/README.md
new file mode 100644 (file)
index 0000000..df78972
--- /dev/null
@@ -0,0 +1,8 @@
+# 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
diff --git a/audio_utils/fifo.c b/audio_utils/fifo.c
deleted file mode 100644 (file)
index c818a50..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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;
-}
diff --git a/audio_utils/fifo.cpp b/audio_utils/fifo.cpp
new file mode 100644 (file)
index 0000000..f19f93b
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * 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;
+}
index f882368..53099b6 100644 (file)
 #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
index 2d5f1a4..6fa3f82 100644 (file)
@@ -35,6 +35,35 @@ cc_binary {
     ],
 }
 
+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"],
@@ -42,5 +71,6 @@ cc_binary_host {
     cflags: [
         "-Werror",
         "-Wall",
+        "-UNDEBUG",
     ],
 }
diff --git a/audio_utils/tests/fifo_multiprocess.cpp b/audio_utils/tests/fifo_multiprocess.cpp
new file mode 100644 (file)
index 0000000..0965749
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * 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;
+}
index 99e73c9..f4fc1d3 100644 (file)
 // 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;
@@ -48,10 +57,19 @@ int main(int argc, char **argv)
             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];
@@ -64,12 +82,11 @@ usage:
         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;
@@ -87,15 +104,16 @@ usage:
     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;
         }
 
@@ -103,12 +121,17 @@ usage:
             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++;
@@ -116,19 +139,49 @@ usage:
         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) {
@@ -137,14 +190,19 @@ usage:
         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));
@@ -157,9 +215,9 @@ usage:
         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);
diff --git a/audio_utils/tests/fifo_threads.cpp b/audio_utils/tests/fifo_threads.cpp
new file mode 100644 (file)
index 0000000..92a2eae
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * 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();
+}
diff --git a/audio_utils/tests/getch.c b/audio_utils/tests/getch.c
new file mode 120000 (symlink)
index 0000000..472d85b
--- /dev/null
@@ -0,0 +1 @@
+../../../../frameworks/wilhelm/tests/sandbox/getch.c
\ No newline at end of file
diff --git a/audio_utils/tests/getch.h b/audio_utils/tests/getch.h
new file mode 120000 (symlink)
index 0000000..094c1b0
--- /dev/null
@@ -0,0 +1 @@
+../../../../frameworks/wilhelm/tests/sandbox/getch.h
\ No newline at end of file
index 07d7300..492b21c 100644 (file)
@@ -63,7 +63,7 @@ LOCAL_SRC_FILES := \
   $(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.
@@ -105,5 +105,5 @@ LOCAL_STATIC_LIBRARIES := \
   libBionicGtestMain \
   libchrome_test_helpers \
   libgmock
-LOCAL_CFLAGS := -Wno-sign-compare -Wall
+LOCAL_CFLAGS := -Wno-sign-compare -Wall -Werror
 include $(BUILD_NATIVE_TEST)
index 9de902b..4e322bd 100644 (file)
@@ -20,7 +20,6 @@
 #include <string.h>
 #include <stdint.h>
 #include <cutils/compiler.h>
-#include <system/camera_vendor_tags.h>
 
 #ifdef __cplusplus
 extern "C" {