diff options
-rw-r--r-- | audio/include/system/audio.h | 111 | ||||
-rwxr-xr-x | audio_effects/include/audio_effects/audio_effects_conf.h | 5 | ||||
-rw-r--r-- | audio_route/audio_route.c | 55 | ||||
-rw-r--r-- | audio_utils/format.c | 29 |
4 files changed, 198 insertions, 2 deletions
diff --git a/audio/include/system/audio.h b/audio/include/system/audio.h index 2f33b2b5..0517b85e 100644 --- a/audio/include/system/audio.h +++ b/audio/include/system/audio.h @@ -262,6 +262,21 @@ typedef enum { AUDIO_FORMAT_E_AC3 = 0x0A000000UL, AUDIO_FORMAT_DTS = 0x0B000000UL, AUDIO_FORMAT_DTS_HD = 0x0C000000UL, + AUDIO_FORMAT_EVRC = 0x10000000UL, + AUDIO_FORMAT_QCELP = 0x11000000UL, + AUDIO_FORMAT_WMA = 0x12000000UL, + AUDIO_FORMAT_WMA_PRO = 0x13000000UL, + AUDIO_FORMAT_AAC_ADIF = 0x14000000UL, + AUDIO_FORMAT_EVRCB = 0x15000000UL, + AUDIO_FORMAT_EVRCWB = 0x16000000UL, + AUDIO_FORMAT_AMR_WB_PLUS = 0x17000000UL, + AUDIO_FORMAT_MP2 = 0x18000000UL, + AUDIO_FORMAT_EVRCNW = 0x19000000UL, + AUDIO_FORMAT_PCM_OFFLOAD = 0x1A000000UL, + AUDIO_FORMAT_FLAC = 0x1B000000UL, + AUDIO_FORMAT_ALAC = 0x1C000000UL, + AUDIO_FORMAT_APE = 0x1D000000UL, + AUDIO_FORMAT_AAC_ADTS = 0x1E000000UL, AUDIO_FORMAT_MAIN_MASK = 0xFF000000UL, AUDIO_FORMAT_SUB_MASK = 0x00FFFFFFUL, @@ -300,6 +315,31 @@ typedef enum { AUDIO_FORMAT_AAC_SUB_HE_V2), AUDIO_FORMAT_AAC_ELD = (AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_ELD), + AUDIO_FORMAT_AAC_ADTS_MAIN = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_MAIN), + AUDIO_FORMAT_AAC_ADTS_LC = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_LC), + AUDIO_FORMAT_AAC_ADTS_SSR = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_SSR), + AUDIO_FORMAT_AAC_ADTS_LTP = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_LTP), + AUDIO_FORMAT_AAC_ADTS_HE_V1 = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_HE_V1), + AUDIO_FORMAT_AAC_ADTS_SCALABLE = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_SCALABLE), + AUDIO_FORMAT_AAC_ADTS_ERLC = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_ERLC), + AUDIO_FORMAT_AAC_ADTS_LD = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_LD), + AUDIO_FORMAT_AAC_ADTS_HE_V2 = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_HE_V2), + AUDIO_FORMAT_AAC_ADTS_ELD = (AUDIO_FORMAT_AAC_ADTS | + AUDIO_FORMAT_AAC_SUB_ELD), + /*Offload PCM formats*/ + AUDIO_FORMAT_PCM_16_BIT_OFFLOAD = (AUDIO_FORMAT_PCM_OFFLOAD | + AUDIO_FORMAT_PCM_SUB_16_BIT), + AUDIO_FORMAT_PCM_24_BIT_OFFLOAD = (AUDIO_FORMAT_PCM_OFFLOAD | + AUDIO_FORMAT_PCM_SUB_8_24_BIT), } audio_format_t; /* For the channel mask for position assignment representation */ @@ -340,6 +380,9 @@ enum { 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_2POINT1 = (AUDIO_CHANNEL_OUT_FRONT_LEFT | + AUDIO_CHANNEL_OUT_FRONT_RIGHT | + AUDIO_CHANNEL_OUT_FRONT_CENTER), AUDIO_CHANNEL_OUT_QUAD = (AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT | AUDIO_CHANNEL_OUT_BACK_LEFT | @@ -350,6 +393,12 @@ enum { AUDIO_CHANNEL_OUT_FRONT_RIGHT | AUDIO_CHANNEL_OUT_SIDE_LEFT | AUDIO_CHANNEL_OUT_SIDE_RIGHT), + AUDIO_CHANNEL_OUT_SURROUND = (AUDIO_CHANNEL_OUT_FRONT_LEFT | + AUDIO_CHANNEL_OUT_FRONT_RIGHT | + AUDIO_CHANNEL_OUT_FRONT_CENTER | + AUDIO_CHANNEL_OUT_BACK_CENTER), + AUDIO_CHANNEL_OUT_PENTA = (AUDIO_CHANNEL_OUT_QUAD | + AUDIO_CHANNEL_OUT_FRONT_CENTER), AUDIO_CHANNEL_OUT_5POINT1 = (AUDIO_CHANNEL_OUT_FRONT_LEFT | AUDIO_CHANNEL_OUT_FRONT_RIGHT | AUDIO_CHANNEL_OUT_FRONT_CENTER | @@ -364,6 +413,13 @@ enum { AUDIO_CHANNEL_OUT_LOW_FREQUENCY | AUDIO_CHANNEL_OUT_SIDE_LEFT | AUDIO_CHANNEL_OUT_SIDE_RIGHT), + AUDIO_CHANNEL_OUT_6POINT1 = (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_BACK_CENTER), // 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 | @@ -415,6 +471,15 @@ enum { 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_5POINT1 = (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_VOICE_UPLINK_MONO = (AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_MONO), + AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO = (AUDIO_CHANNEL_IN_VOICE_DNLINK | AUDIO_CHANNEL_IN_MONO), + AUDIO_CHANNEL_IN_VOICE_CALL_MONO = (AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO | AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO), AUDIO_CHANNEL_IN_ALL = (AUDIO_CHANNEL_IN_LEFT | AUDIO_CHANNEL_IN_RIGHT | AUDIO_CHANNEL_IN_FRONT | @@ -616,6 +681,7 @@ enum { /* limited-output speaker device for acoustic safety */ AUDIO_DEVICE_OUT_SPEAKER_SAFE = 0x400000, AUDIO_DEVICE_OUT_IP = 0x800000, + AUDIO_DEVICE_OUT_PROXY = 0x1000000, AUDIO_DEVICE_OUT_DEFAULT = AUDIO_DEVICE_BIT_DEFAULT, AUDIO_DEVICE_OUT_ALL = (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | @@ -641,6 +707,7 @@ enum { AUDIO_DEVICE_OUT_AUX_LINE | AUDIO_DEVICE_OUT_SPEAKER_SAFE | AUDIO_DEVICE_OUT_IP | + AUDIO_DEVICE_OUT_PROXY | AUDIO_DEVICE_OUT_DEFAULT), AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | @@ -678,6 +745,7 @@ enum { 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_DEVICE_IN_PROXY = AUDIO_DEVICE_BIT_IN | 0x1000000, AUDIO_DEVICE_IN_DEFAULT = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT, AUDIO_DEVICE_IN_ALL = (AUDIO_DEVICE_IN_COMMUNICATION | @@ -699,6 +767,7 @@ enum { AUDIO_DEVICE_IN_SPDIF | AUDIO_DEVICE_IN_BLUETOOTH_A2DP | AUDIO_DEVICE_IN_LOOPBACK | + AUDIO_DEVICE_IN_PROXY | AUDIO_DEVICE_IN_IP | AUDIO_DEVICE_IN_DEFAULT), AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, @@ -741,6 +810,10 @@ typedef enum { AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO = 0x400, // Audio stream contains compressed audio in // SPDIF data bursts, not PCM. + AUDIO_OUTPUT_FLAG_VOIP_RX = 0x800, // use this flag in combination with DIRECT to + // start voip over voice path. + AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH = 0x1000, // flag for HDMI compressed passthrough + AUDIO_OUTPUT_FLAG_DIRECT_PCM = 0x2000, // flag for Direct PCM } audio_output_flags_t; /* The audio input flags are analogous to audio output flags. @@ -773,6 +846,9 @@ typedef struct { int64_t duration_us; // duration in microseconds, -1 if unknown bool has_video; // true if stream is tied to a video stream bool is_streaming; // true if streaming, false if local playback + uint32_t bit_width; + uint32_t offload_buffer_size; // offload fragment size + audio_usage_t usage; } audio_offload_info_t; #define AUDIO_MAKE_OFFLOAD_INFO_VERSION(maj,min) \ @@ -791,7 +867,10 @@ static const audio_offload_info_t AUDIO_INFO_INITIALIZER = { bit_rate: 0, duration_us: 0, has_video: false, - is_streaming: false + is_streaming: false, + bit_width: 16, + offload_buffer_size: 0, + usage: AUDIO_USAGE_UNKNOWN, }; /* common audio stream configuration parameters @@ -1357,6 +1436,7 @@ static inline bool audio_is_valid_format(audio_format_t format) case AUDIO_FORMAT_AMR_NB: case AUDIO_FORMAT_AMR_WB: case AUDIO_FORMAT_AAC: + case AUDIO_FORMAT_AAC_ADTS: case AUDIO_FORMAT_HE_AAC_V1: case AUDIO_FORMAT_HE_AAC_V2: case AUDIO_FORMAT_VORBIS: @@ -1365,6 +1445,25 @@ static inline bool audio_is_valid_format(audio_format_t format) case AUDIO_FORMAT_E_AC3: case AUDIO_FORMAT_DTS: case AUDIO_FORMAT_DTS_HD: + case AUDIO_FORMAT_QCELP: + case AUDIO_FORMAT_EVRC: + case AUDIO_FORMAT_EVRCB: + case AUDIO_FORMAT_EVRCWB: + case AUDIO_FORMAT_AAC_ADIF: + case AUDIO_FORMAT_AMR_WB_PLUS: + case AUDIO_FORMAT_MP2: + case AUDIO_FORMAT_EVRCNW: + case AUDIO_FORMAT_FLAC: + case AUDIO_FORMAT_ALAC: + case AUDIO_FORMAT_APE: + case AUDIO_FORMAT_WMA: + case AUDIO_FORMAT_WMA_PRO: + return true; + case AUDIO_FORMAT_PCM_OFFLOAD: + if (format != AUDIO_FORMAT_PCM_16_BIT_OFFLOAD && + format != AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) { + return false; + } return true; default: return false; @@ -1376,6 +1475,14 @@ static inline bool audio_is_linear_pcm(audio_format_t format) return ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM); } +static inline bool audio_is_offload_pcm(audio_format_t format) +{ +#ifdef QCOM_HARDWARE + return ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM_OFFLOAD); +#endif + return false; +} + static inline size_t audio_bytes_per_sample(audio_format_t format) { size_t size = 0; @@ -1383,12 +1490,14 @@ static inline size_t audio_bytes_per_sample(audio_format_t format) switch (format) { case AUDIO_FORMAT_PCM_32_BIT: case AUDIO_FORMAT_PCM_8_24_BIT: + case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD: size = sizeof(int32_t); break; case AUDIO_FORMAT_PCM_24_BIT_PACKED: size = sizeof(uint8_t) * 3; break; case AUDIO_FORMAT_PCM_16_BIT: + case AUDIO_FORMAT_PCM_16_BIT_OFFLOAD: size = sizeof(int16_t); break; case AUDIO_FORMAT_PCM_8_BIT: diff --git a/audio_effects/include/audio_effects/audio_effects_conf.h b/audio_effects/include/audio_effects/audio_effects_conf.h index d462c085..11d9019d 100755 --- a/audio_effects/include/audio_effects/audio_effects_conf.h +++ b/audio_effects/include/audio_effects/audio_effects_conf.h @@ -25,6 +25,11 @@ #define AUDIO_EFFECT_DEFAULT_CONFIG_FILE "/system/etc/audio_effects.conf" #define AUDIO_EFFECT_VENDOR_CONFIG_FILE "/vendor/etc/audio_effects.conf" + +// If the device ships a /vendor image which we can't modify but still want to +// change the effects configuration from the default, we can load one from here +#define AUDIO_EFFECT_VENDOR_CONFIG_FILE2 "/system/etc/audio_effects_vendor.conf" + #define LIBRARIES_TAG "libraries" #define PATH_TAG "path" diff --git a/audio_route/audio_route.c b/audio_route/audio_route.c index 029951c1..d24f7799 100644 --- a/audio_route/audio_route.c +++ b/audio_route/audio_route.c @@ -83,6 +83,7 @@ static bool is_supported_ctl_type(enum mixer_ctl_type type) case MIXER_CTL_TYPE_BOOL: case MIXER_CTL_TYPE_INT: case MIXER_CTL_TYPE_ENUM: + case MIXER_CTL_TYPE_BYTE: return true; default: return false; @@ -186,6 +187,40 @@ static int find_ctl_index_in_path(struct mixer_path *path, return -1; } +static int get_byte_array(struct mixer_ctl *ctl, + int *value, unsigned int num_values) +{ + unsigned int i; + char *data = (char *)malloc(num_values); + + if (!data) + return -1; + + mixer_ctl_get_array(ctl, data, num_values); + for(i = 0; i < num_values; i++) + value[i] = data[i]; + + free(data); + return 0; +} + +static int set_byte_array(struct mixer_ctl *ctl, + int *value, unsigned int num_values) +{ + unsigned int i; + char *data = (char *)malloc(num_values); + + if (!data) + return -1; + + for (i = 0; i < num_values; i++) + data[i] = value[i]; + + mixer_ctl_set_array(ctl, data, num_values); + free(data); + return 0; +} + static int alloc_path_setting(struct mixer_path *path) { struct mixer_setting *new_path_setting; @@ -412,6 +447,13 @@ static void start_tag(void *data, const XML_Char *tag_name, case MIXER_CTL_TYPE_INT: value = (int) strtol((char *)attr_value, NULL, 0); break; + case MIXER_CTL_TYPE_BYTE: + value = (int) strtol((char *)attr_value, NULL, 0); + if (value < 0 || value > 255) { + ALOGE("Control '%s' only supports byte values", attr_name); + goto done; + } + break; case MIXER_CTL_TYPE_ENUM: value = mixer_enum_string_to_value(ctl, (char *)attr_value); break; @@ -493,8 +535,12 @@ static int alloc_mixer_state(struct audio_route *ar) /* Skip unsupported types that are not supported yet in XML */ type = mixer_ctl_get_type(ctl); - if (!is_supported_ctl_type(type)) + if (!is_supported_ctl_type(type)) { + ar->mixer_state[i].old_value = NULL; + ar->mixer_state[i].new_value = NULL; + ar->mixer_state[i].reset_value = NULL; continue; + } ar->mixer_state[i].old_value = malloc(num_values * sizeof(int)); ar->mixer_state[i].new_value = malloc(num_values * sizeof(int)); @@ -502,6 +548,8 @@ static int alloc_mixer_state(struct audio_route *ar) if (type == MIXER_CTL_TYPE_ENUM) ar->mixer_state[i].old_value[0] = mixer_ctl_get_value(ctl, 0); + else if (type == MIXER_CTL_TYPE_BYTE) + get_byte_array(ctl, ar->mixer_state[i].old_value, num_values); else mixer_ctl_get_array(ctl, ar->mixer_state[i].old_value, num_values); memcpy(ar->mixer_state[i].new_value, ar->mixer_state[i].old_value, @@ -559,6 +607,8 @@ int audio_route_update_mixer(struct audio_route *ar) if (changed) { if (type == MIXER_CTL_TYPE_ENUM) mixer_ctl_set_value(ctl, 0, ar->mixer_state[i].new_value[0]); + else if (type == MIXER_CTL_TYPE_BYTE) + set_byte_array(ctl, ar->mixer_state[i].new_value, num_values); else mixer_ctl_set_array(ctl, ar->mixer_state[i].new_value, num_values); memcpy(ar->mixer_state[i].old_value, ar->mixer_state[i].new_value, @@ -678,6 +728,7 @@ static int audio_route_update_path(struct audio_route *ar, const char *name, boo type = mixer_ctl_get_type(ms->ctl); if (!is_supported_ctl_type(type)) { + i = reverse ? (i - 1) : (i + 1); continue; } @@ -686,6 +737,8 @@ static int audio_route_update_path(struct audio_route *ar, const char *name, boo if (ms->old_value[j] != ms->new_value[j]) { if (type == MIXER_CTL_TYPE_ENUM) mixer_ctl_set_value(ms->ctl, 0, ms->new_value[0]); + else if (type == MIXER_CTL_TYPE_BYTE) + set_byte_array(ms->ctl, ms->new_value, ms->num_values); else mixer_ctl_set_array(ms->ctl, ms->new_value, ms->num_values); memcpy(ms->old_value, ms->new_value, ms->num_values * sizeof(int)); diff --git a/audio_utils/format.c b/audio_utils/format.c index 66b0a6db..1aba6c85 100644 --- a/audio_utils/format.c +++ b/audio_utils/format.c @@ -134,6 +134,35 @@ void memcpy_by_audio_format(void *dst, audio_format_t dst_format, break; } break; + case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD: { + // pcm 24 bit with padding at LSB + // can assume LE? + size_t i; + uint8_t * src_ptr = (uint8_t *)src; + int32_t * dst_ptr = (int32_t *)dst; + switch (src_format) { + case AUDIO_FORMAT_PCM_24_BIT_PACKED: { + for (i = 0; i < count; i++) { + *dst_ptr++ = (int8_t)src_ptr[2] << 24 | src_ptr[1] << 16 | src_ptr[0] << 8; + src_ptr += 3; + } + return; + } + case AUDIO_FORMAT_PCM_8_24_BIT: { // padding is at MSB + for (i = 0; i < count; i++) { + *dst_ptr++ = (int8_t)src_ptr[2] << 24 | src_ptr[1] << 16 | src_ptr[0] << 8; + src_ptr += 4; + } + return; + } + case AUDIO_FORMAT_PCM_FLOAT: + memcpy_to_i32_from_float((int32_t*)dst, (float*)src, count); + return; + default: + break; + } + break; + } default: break; } |