summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--alsa_utils/alsa_device_profile.c71
-rw-r--r--alsa_utils/alsa_device_proxy.c21
-rw-r--r--alsa_utils/include/alsa_device_profile.h4
-rw-r--r--alsa_utils/include/alsa_device_proxy.h19
-rw-r--r--audio/include/system/audio.h4
-rw-r--r--audio_route/audio_route.c15
-rw-r--r--audio_utils/format.c3
-rw-r--r--audio_utils/tests/Android.mk21
-rw-r--r--audio_utils/tests/primitives_tests.cpp33
-rw-r--r--camera/src/camera_metadata.c3
10 files changed, 173 insertions, 21 deletions
diff --git a/alsa_utils/alsa_device_profile.c b/alsa_utils/alsa_device_profile.c
index 0d9bd88..79ffcfc 100644
--- a/alsa_utils/alsa_device_profile.c
+++ b/alsa_utils/alsa_device_profile.c
@@ -192,6 +192,21 @@ unsigned profile_get_default_channel_count(alsa_device_profile* profile)
return profile_is_valid(profile) ? profile->channel_counts[0] : DEFAULT_CHANNEL_COUNT;
}
+unsigned profile_get_closest_channel_count(alsa_device_profile* profile, unsigned count)
+{
+ if (profile_is_valid(profile)) {
+ if (count < profile->min_channel_count) {
+ return profile->min_channel_count;
+ } else if (count > profile->max_channel_count) {
+ return profile->max_channel_count;
+ } else {
+ return count;
+ }
+ } else {
+ return 0;
+ }
+}
+
bool profile_is_channel_count_valid(alsa_device_profile* profile, unsigned count)
{
if (profile_is_initialized(profile)) {
@@ -566,3 +581,59 @@ char * profile_get_channel_count_strs(alsa_device_profile* profile)
return strdup(buffer);
}
+
+void profile_dump(const alsa_device_profile* profile, int fd)
+{
+ if (profile == NULL) {
+ dprintf(fd, " %s\n", "No USB Profile");
+ return; /* bail early */
+ }
+
+ if (!profile->is_valid) {
+ dprintf(fd, " Profile is INVALID");
+ }
+
+ /* card/device/direction */
+ dprintf(fd, " card:%d, device:%d - %s\n",
+ profile->card, profile->device, profile->direction == PCM_OUT ? "OUT" : "IN");
+
+ /* formats */
+ dprintf(fd, " Formats: ");
+ for (int fmtIndex = 0;
+ profile->formats[fmtIndex] != PCM_FORMAT_INVALID && fmtIndex < MAX_PROFILE_FORMATS;
+ fmtIndex++) {
+ dprintf(fd, "%d ", profile->formats[fmtIndex]);
+ }
+ dprintf(fd, "\n");
+
+ /* sample rates */
+ dprintf(fd, " Rates: ");
+ for (int rateIndex = 0;
+ profile->sample_rates[rateIndex] != 0 && rateIndex < MAX_PROFILE_SAMPLE_RATES;
+ rateIndex++) {
+ dprintf(fd, "%u ", profile->sample_rates[rateIndex]);
+ }
+ dprintf(fd, "\n");
+
+ // channel counts
+ dprintf(fd, " Channel Counts: ");
+ for (int cntIndex = 0;
+ profile->channel_counts[cntIndex] != 0 && cntIndex < MAX_PROFILE_CHANNEL_COUNTS;
+ cntIndex++) {
+ dprintf(fd, "%u ", profile->channel_counts[cntIndex]);
+ }
+ dprintf(fd, "\n");
+
+ dprintf(fd, " min/max period size [%u : %u]\n",
+ profile->min_period_size,profile-> max_period_size);
+ dprintf(fd, " min/max channel count [%u : %u]\n",
+ profile->min_channel_count, profile->max_channel_count);
+
+ // struct pcm_config default_config;
+ dprintf(fd, " Default Config:\n");
+ dprintf(fd, " channels: %d\n", profile->default_config.channels);
+ dprintf(fd, " rate: %d\n", profile->default_config.rate);
+ dprintf(fd, " period_size: %d\n", profile->default_config.period_size);
+ dprintf(fd, " period_count: %d\n", profile->default_config.period_count);
+ dprintf(fd, " format: %d\n", profile->default_config.format);
+}
diff --git a/alsa_utils/alsa_device_proxy.c b/alsa_utils/alsa_device_proxy.c
index ee92ed0..73e4375 100644
--- a/alsa_utils/alsa_device_proxy.c
+++ b/alsa_utils/alsa_device_proxy.c
@@ -69,10 +69,9 @@ void proxy_prepare(alsa_device_proxy * proxy, alsa_device_profile* profile,
if (config->channels != 0 && profile_is_channel_count_valid(profile, config->channels)) {
proxy->alsa_config.channels = config->channels;
} else {
- ALOGW("Invalid channel count %u - using default %u.",
- config->channels, profile->default_config.channels);
- proxy->alsa_config.channels = profile->default_config.channels;
-
+ proxy->alsa_config.channels = profile_get_closest_channel_count(profile, config->channels);
+ ALOGW("Invalid channel count %u - using closest %u.",
+ config->channels, proxy->alsa_config.channels);
}
proxy->alsa_config.period_count = profile->default_config.period_count;
@@ -218,3 +217,17 @@ int proxy_read(const alsa_device_proxy * proxy, void *data, unsigned int count)
{
return pcm_read(proxy->pcm, data, count);
}
+
+/*
+ * Debugging
+ */
+void proxy_dump(const alsa_device_proxy* proxy, int fd)
+{
+ if (proxy != NULL) {
+ dprintf(fd, " channels: %d\n", proxy->alsa_config.channels);
+ dprintf(fd, " rate: %d\n", proxy->alsa_config.rate);
+ dprintf(fd, " period_size: %d\n", proxy->alsa_config.period_size);
+ dprintf(fd, " period_count: %d\n", proxy->alsa_config.period_count);
+ dprintf(fd, " format: %d\n", proxy->alsa_config.format);
+ }
+}
diff --git a/alsa_utils/include/alsa_device_profile.h b/alsa_utils/include/alsa_device_profile.h
index 5520b8a..e056d70 100644
--- a/alsa_utils/include/alsa_device_profile.h
+++ b/alsa_utils/include/alsa_device_profile.h
@@ -81,10 +81,14 @@ bool profile_is_format_valid(alsa_device_profile* profile, enum pcm_format fmt);
/* Channel Methods */
unsigned profile_get_default_channel_count(alsa_device_profile* profile);
+unsigned profile_get_closest_channel_count(alsa_device_profile* profile, unsigned count);
bool profile_is_channel_count_valid(alsa_device_profile* profile, unsigned count);
/* Utility */
unsigned profile_calc_min_period_size(alsa_device_profile* profile, unsigned sample_rate);
unsigned int profile_get_period_size(alsa_device_profile* profile, unsigned sample_rate);
+/* Debugging */
+void profile_dump(const alsa_device_profile* profile, int fd);
+
#endif /* ANDROID_SYSTEM_MEDIA_ALSA_UTILS_ALSA_DEVICE_PROFILE_H */
diff --git a/alsa_utils/include/alsa_device_proxy.h b/alsa_utils/include/alsa_device_proxy.h
index e1ff8f5..0bc0731 100644
--- a/alsa_utils/include/alsa_device_proxy.h
+++ b/alsa_utils/include/alsa_device_proxy.h
@@ -32,24 +32,27 @@ typedef struct {
uint64_t transferred; /* the total frames transferred, not cleared on standby */
} alsa_device_proxy;
+
+/* State */
void proxy_prepare(alsa_device_proxy * proxy, alsa_device_profile * profile,
struct pcm_config * config);
+int proxy_open(alsa_device_proxy * proxy);
+void proxy_close(alsa_device_proxy * proxy);
+int proxy_get_presentation_position(const alsa_device_proxy * proxy,
+ uint64_t *frames, struct timespec *timestamp);
+/* Attributes */
unsigned proxy_get_sample_rate(const alsa_device_proxy * proxy);
enum pcm_format proxy_get_format(const alsa_device_proxy * proxy);
unsigned proxy_get_channel_count(const alsa_device_proxy * proxy);
-
unsigned int proxy_get_period_size(const alsa_device_proxy * proxy);
-
unsigned proxy_get_latency(const alsa_device_proxy * proxy);
-int proxy_get_presentation_position(const alsa_device_proxy * proxy,
- uint64_t *frames, struct timespec *timestamp);
-
-int proxy_open(alsa_device_proxy * proxy);
-void proxy_close(alsa_device_proxy * proxy);
-
+/* I/O */
int proxy_write(alsa_device_proxy * proxy, const void *data, unsigned int count);
int proxy_read(const alsa_device_proxy * proxy, void *data, unsigned int count);
+/* Debugging */
+void proxy_dump(const alsa_device_proxy * proxy, int fd);
+
#endif /* ANDROID_SYSTEM_MEDIA_ALSA_UTILS_ALSA_DEVICE_PROXY_H */
diff --git a/audio/include/system/audio.h b/audio/include/system/audio.h
index c5808aa..fa80a45 100644
--- a/audio/include/system/audio.h
+++ b/audio/include/system/audio.h
@@ -336,7 +336,8 @@ typedef enum {
AUDIO_FORMAT_APTX = 0x21000000UL,
AUDIO_FORMAT_APTX_HD = 0x22000000UL,
- AUDIO_FORMAT_MAIN_MASK = 0xFF000000UL,/* Deprecated. Use audio_get_main_format() */
+ AUDIO_FORMAT_DOLBY_TRUEHD = 0x0E000000UL,
+ AUDIO_FORMAT_MAIN_MASK = 0xFF000000UL, /* Deprecated. Use audio_get_main_format() */
AUDIO_FORMAT_SUB_MASK = 0x00FFFFFFUL,
/* Aliases */
@@ -1586,6 +1587,7 @@ static inline bool audio_is_valid_format(audio_format_t format)
format != AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) {
return false;
}
+ case AUDIO_FORMAT_DOLBY_TRUEHD:
return true;
default:
return false;
diff --git a/audio_route/audio_route.c b/audio_route/audio_route.c
index 90b114d..bd5c112 100644
--- a/audio_route/audio_route.c
+++ b/audio_route/audio_route.c
@@ -420,13 +420,24 @@ static int path_reset(struct audio_route *ar, struct mixer_path *path)
static int mixer_enum_string_to_value(struct mixer_ctl *ctl, const char *string)
{
unsigned int i;
+ unsigned int num_values = mixer_ctl_get_num_enums(ctl);
+
+ if (string == NULL) {
+ ALOGE("NULL enum value string passed to mixer_enum_string_to_value() for ctl %s",
+ mixer_ctl_get_name(ctl));
+ return 0;
+ }
/* Search the enum strings for a particular one */
- for (i = 0; i < mixer_ctl_get_num_enums(ctl); i++) {
+ for (i = 0; i < num_values; i++) {
if (strcmp(mixer_ctl_get_enum_string(ctl, i), string) == 0)
break;
}
-
+ if (i == num_values) {
+ ALOGE("unknown enum value string %s for ctl %s",
+ string, mixer_ctl_get_name(ctl));
+ return 0;
+ }
return i;
}
diff --git a/audio_utils/format.c b/audio_utils/format.c
index 4e61321..3eda484 100644
--- a/audio_utils/format.c
+++ b/audio_utils/format.c
@@ -120,6 +120,9 @@ void memcpy_by_audio_format(void *dst, audio_format_t dst_format,
case AUDIO_FORMAT_PCM_FLOAT:
memcpy_to_i32_from_float((int32_t*)dst, (float*)src, count);
return;
+ case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+ memcpy_to_i32_from_p24((int32_t*)dst, (uint8_t *)src, count);
+ return;
default:
break;
}
diff --git a/audio_utils/tests/Android.mk b/audio_utils/tests/Android.mk
index 0db09dc..cd76cf0 100644
--- a/audio_utils/tests/Android.mk
+++ b/audio_utils/tests/Android.mk
@@ -1,26 +1,37 @@
# Build the unit tests for audio_utils
LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
+include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
liblog \
libcutils \
libaudioutils
-
LOCAL_C_INCLUDES := \
$(call include-path-for, audio-utils)
-
LOCAL_SRC_FILES := \
primitives_tests.cpp
-
LOCAL_MODULE := primitives_tests
LOCAL_MODULE_TAGS := tests
-
LOCAL_CFLAGS := -Werror -Wall
include $(BUILD_NATIVE_TEST)
include $(CLEAR_VARS)
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils
+LOCAL_STATIC_LIBRARIES := \
+ libaudioutils
+LOCAL_C_INCLUDES := \
+ $(call include-path-for, audio-utils)
+LOCAL_SRC_FILES := \
+ primitives_tests.cpp
+LOCAL_MODULE := primitives_tests
+LOCAL_MODULE_TAGS := tests
+LOCAL_CFLAGS := -Werror -Wall
+include $(BUILD_HOST_NATIVE_TEST)
+
+include $(CLEAR_VARS)
LOCAL_SRC_FILES := fifo_tests.cpp
LOCAL_MODULE := fifo_tests
LOCAL_C_INCLUDES := $(call include-path-for, audio-utils)
diff --git a/audio_utils/tests/primitives_tests.cpp b/audio_utils/tests/primitives_tests.cpp
index 5b3cd2d..178490b 100644
--- a/audio_utils/tests/primitives_tests.cpp
+++ b/audio_utils/tests/primitives_tests.cpp
@@ -103,6 +103,14 @@ void checkMonotone(const T *ary, size_t size)
}
}
+void checkMonotonep24(uint8_t * pary, size_t size)
+{
+ size_t frames = size/3;
+ for (size_t i = 1; i < frames; ++i) {
+ EXPECT_LT(i32_from_p24(pary + 3*(i-1)), i32_from_p24(pary + 3*i));
+ }
+}
+
TEST(audio_utils_primitives, clamp_to_int) {
static const float testArray[] = {
-NAN, -INFINITY,
@@ -256,6 +264,31 @@ TEST(audio_utils_primitives, memcpy) {
memset(i32ary, 0, 65536 * sizeof(i32ary[0]));
checkMonotone(i16ary, 65536);
+ // do round-trip test i16 -> p24 -> i32 -> p24 -> q8_23 -> p24 -> i16
+ memcpy_to_p24_from_i16(pary, i16ary, 65536);
+ memset(i16ary, 0, 65536 * sizeof(i16ary[0]));
+ checkMonotonep24(pary, 65536 * 3);
+
+ memcpy_to_i32_from_p24(i32ary, pary, 65536);
+ memset(pary, 0, 65536 * 3 * sizeof(pary[0]));
+ checkMonotone(i32ary, 65536);
+
+ memcpy_to_p24_from_i32(pary, i32ary, 65536);
+ memset(i32ary, 0, 65536 * sizeof(i32ary[0]));
+ checkMonotonep24(pary, 65536 * 3);
+
+ memcpy_to_q8_23_from_p24(i32ary, pary, 65536);
+ memset(pary, 0, 65536 * 3 * sizeof(pary[0]));
+ checkMonotone(i32ary, 65536);
+
+ memcpy_to_p24_from_q8_23(pary, i32ary, 65536);
+ memset(i32ary, 0, 65536 * sizeof(i32ary[0]));
+ checkMonotonep24(pary, 65536 * 3);
+
+ memcpy_to_i16_from_p24(i16ary, pary, 65536);
+ memset(pary, 0, 65536 * 3 * sizeof(pary[0]));
+ checkMonotone(i16ary, 65536);
+
// do partial round-trip testing q4_27 to i16 and float
memcpy_to_float_from_i16(fary, i16ary, 65536);
//memset(i16ary, 0, 65536 * sizeof(i16ary[0])); // not cleared: we don't do full roundtrip
diff --git a/camera/src/camera_metadata.c b/camera/src/camera_metadata.c
index a6b6904..597129b 100644
--- a/camera/src/camera_metadata.c
+++ b/camera/src/camera_metadata.c
@@ -399,7 +399,8 @@ int validate_camera_metadata_structure(const camera_metadata_t *metadata,
return ERROR;
}
- const metadata_uptrdiff_t entries_end = metadata->entries_start + metadata->entry_capacity;
+ const metadata_uptrdiff_t entries_end =
+ metadata->entries_start + metadata->entry_capacity;
if (entries_end < metadata->entries_start || // overflow check
entries_end > metadata->data_start) {