Snap for 5130385 from c4de160ac82905147883b15577091fa99c5530a4 to pi-qpr2-release
Change-Id: I605dd5369373b708036e708e0941a843a5e18e1c
diff --git a/hal/Android.mk b/hal/Android.mk
index b73038a..236ed11 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -207,6 +207,10 @@
LOCAL_SRC_FILES += audio_extn/maxxaudio.c
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_24BITS_CAMCORDER)), true)
+ LOCAL_CFLAGS += -DENABLED_24BITS_CAMCORDER
+endif
+
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_BG_CAL)),true)
LOCAL_CFLAGS += -DBG_CODEC_CAL
endif
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
index fc65332..2fd188d 100644
--- a/hal/audio_extn/maxxaudio.c
+++ b/hal/audio_extn/maxxaudio.c
@@ -41,29 +41,40 @@
#define CAL_PRESIST_STR "cal_persist"
#define CAL_SAMPLERATE_STR "cal_samplerate"
-#define MA_QDSP_PARAM_INIT "maxxaudio_qdsp_initialize"
-#define MA_QDSP_PARAM_DEINIT "maxxaudio_qdsp_uninitialize"
-#define MA_QDSP_SET_LR_SWAP "maxxaudio_qdsp_set_lr_swap"
-#define MA_QDSP_SET_MODE "maxxaudio_qdsp_set_sound_mode"
-#define MA_QDSP_SET_VOL "maxxaudio_qdsp_set_volume"
-#define MA_QDSP_SET_VOLT "maxxaudio_qdsp_set_volume_table"
+#define MA_QDSP_PARAM_INIT "maxxaudio_qdsp_initialize"
+#define MA_QDSP_PARAM_DEINIT "maxxaudio_qdsp_uninitialize"
+#define MA_QDSP_SET_LR_SWAP "maxxaudio_qdsp_set_lr_swap"
+#define MA_QDSP_SET_MODE "maxxaudio_qdsp_set_sound_mode"
+#define MA_QDSP_SET_VOL "maxxaudio_qdsp_set_volume"
+#define MA_QDSP_SET_VOLT "maxxaudio_qdsp_set_volume_table"
+#define MA_QDSP_SET_PARAM "maxxaudio_qdsp_set_parameter"
#define SUPPORT_DEV "Blackbird"
#define SUPPORTED_USB 0x01
-struct ma_audio_cal_settings {
- int app_type;
- audio_devices_t device;
-};
+typedef unsigned int effective_scope_flag_t;
+const effective_scope_flag_t EFFECTIVE_SCOPE_RTC = 1 << 0; /* RTC */
+const effective_scope_flag_t EFFECTIVE_SCOPE_ACDB = 1 << 1; /* ACDB */
+const effective_scope_flag_t EFFECTIVE_SCOPE_ALL = EFFECTIVE_SCOPE_RTC | EFFECTIVE_SCOPE_ACDB;
+const effective_scope_flag_t EFFECTIVE_SCOPE_NONE = 0;
+const effective_scope_flag_t EFFECTIVE_SCOPE_DEFAULT = EFFECTIVE_SCOPE_NONE;
-struct ma_state {
- float vol;
- bool active;
-};
+const unsigned int AUDIO_CAL_SETTINGS_VERSION_MAJOR = 2;
+const unsigned int AUDIO_CAL_SETTINGS_VERSION_MINOR = 0;
+const unsigned int AUDIO_CAL_SETTINGS_VERSION_MAJOR_DEFAULT = AUDIO_CAL_SETTINGS_VERSION_MAJOR;
+const unsigned int AUDIO_CAL_SETTINGS_VERSION_MINOR_DEFAULT = AUDIO_CAL_SETTINGS_VERSION_MINOR;
+
+const unsigned int VALUE_AUTO = 0xFFFFFFFF;
+const unsigned int APP_TYPE_AUTO = VALUE_AUTO;
+const unsigned int APP_TYPE_DEFAULT = APP_TYPE_AUTO;
+const unsigned int DEVICE_AUTO = VALUE_AUTO;
+const unsigned int DEVICE_DEFAULT = DEVICE_AUTO;
+
+const unsigned int MAAP_OUTPUT_GAIN = 27;
typedef enum MA_STREAM_TYPE {
- STREAM_MIN_STREAM_TYPES,
- STREAM_VOICE = STREAM_MIN_STREAM_TYPES,
+ STREAM_MIN_TYPES = 0,
+ STREAM_VOICE = STREAM_MIN_TYPES,
STREAM_SYSTEM,
STREAM_RING,
STREAM_MUSIC,
@@ -76,8 +87,31 @@
MA_CMD_VOL,
MA_CMD_SWAP_ENABLE,
MA_CMD_SWAP_DISABLE,
+ MA_CMD_SOFT_MUTE_ENABLE,
+ MA_CMD_SOFT_MUTE_DISABLE,
} ma_cmd_t;
+typedef struct ma_audio_cal_version {
+ unsigned int major;
+ unsigned int minor;
+} ma_audio_cal_version_t;
+
+typedef struct ma_audio_cal_common_settings {
+ unsigned int app_type;
+ unsigned int device;
+} ma_audio_cal_common_settings_t;
+
+struct ma_audio_cal_settings {
+ ma_audio_cal_version_t version;
+ ma_audio_cal_common_settings_t common;
+ effective_scope_flag_t effect_scope_flag;
+};
+
+struct ma_state {
+ float vol;
+ bool active;
+};
+
typedef void *ma_audio_cal_handle_t;
typedef int (*set_audio_cal_t)(const char *);
@@ -100,6 +134,10 @@
const struct ma_audio_cal_settings *,
size_t, struct ma_state *);
+typedef bool (*ma_set_param_t)(ma_audio_cal_handle_t,
+ const struct ma_audio_cal_settings *,
+ unsigned int, double);
+
struct ma_platform_data {
void *waves_handle;
void *platform;
@@ -110,6 +148,7 @@
ma_set_sound_mode_t ma_set_sound_mode;
ma_set_volume_t ma_set_volume;
ma_set_volume_table_t ma_set_volume_table;
+ ma_set_param_t ma_set_param;
};
ma_audio_cal_handle_t g_ma_audio_cal_handle = NULL;
@@ -155,6 +194,14 @@
volume_table);
}
+static bool ma_set_param_l(
+ const struct ma_audio_cal_settings *audio_cal_settings,
+ unsigned int index, double value)
+{
+ return my_data->ma_set_param(g_ma_audio_cal_handle,
+ audio_cal_settings, index, value);
+}
+
static inline bool valid_usecase(struct audio_usecase *usecase)
{
if ((usecase->type == PCM_PLAYBACK) &&
@@ -164,9 +211,8 @@
(usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD)) &&
/* support devices */
((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
- (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
- /* TODO: enable A2DP when it is ready */
- (usecase->devices & AUDIO_DEVICE_OUT_ALL_USB)))
+ (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE)))
+ /* TODO: enable A2DP/USB when it is ready */
return true;
@@ -182,13 +228,21 @@
ma_stream_type_t i = 0;
for (i = 0; i < STREAM_MAX_TYPES; i++)
- if (ma_cur_state_table[i].active &&
- (ma_cur_state_table[i].vol != 0))
+ if (ma_cur_state_table[i].active)
return true;
return false;
}
+static void ma_cal_init(struct ma_audio_cal_settings *ma_cal)
+{
+ ma_cal->version.major = AUDIO_CAL_SETTINGS_VERSION_MAJOR_DEFAULT;
+ ma_cal->version.minor = AUDIO_CAL_SETTINGS_VERSION_MINOR_DEFAULT;
+ ma_cal->common.app_type = APP_TYPE_DEFAULT;
+ ma_cal->common.device = DEVICE_DEFAULT;
+ ma_cal->effect_scope_flag = EFFECTIVE_SCOPE_ALL;
+}
+
static bool check_and_send_all_audio_cal(struct audio_device *adev, ma_cmd_t cmd)
{
int i = 0;
@@ -196,32 +250,27 @@
float vol = 0;
struct listnode *node;
struct audio_usecase *usecase;
- struct ma_audio_cal_settings *ma_cal = NULL;
+ struct ma_audio_cal_settings ma_cal;
- // alloct
- ma_cal = (struct ma_audio_cal_settings *)malloc(sizeof(struct ma_audio_cal_settings));
-
- if (ma_cal == NULL) {
- ALOGE("%s: ma_cal alloct fail", __func__);
- return ret;
- }
+ ma_cal_init(&ma_cal);
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (valid_usecase(usecase)) {
- ma_cal->app_type = usecase->stream.out->app_type_cfg.app_type;
- ma_cal->device = usecase->stream.out->devices;
+ ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
+ ma_cal.common.device = usecase->stream.out->devices;
ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
- __func__, usecase->id, ma_cal->app_type, ma_cal->device);
+ __func__, usecase->id, ma_cal.common.app_type,
+ ma_cal.common.device);
switch (cmd) {
case MA_CMD_VOL:
- ret = ma_set_volume_table_l(ma_cal, STREAM_MAX_TYPES,
+ ret = ma_set_volume_table_l(&ma_cal, STREAM_MAX_TYPES,
ma_cur_state_table);
if (ret)
- ALOGV("Waves: ma_set_volume_table_l success");
+ ALOGV("ma_set_volume_table_l success");
else
- ALOGE("Waves: ma_set_volume_table_l %f returned with error.", vol);
+ ALOGE("ma_set_volume_table_l returned with error.");
ALOGV("%s: send volume table === Start", __func__);
for (i = 0; i < STREAM_MAX_TYPES; i++)
@@ -230,26 +279,46 @@
ma_cur_state_table[i].active ? "T" : "F");
ALOGV("%s: send volume table === End", __func__);
break;
+
case MA_CMD_SWAP_ENABLE:
- ret = ma_set_lr_swap_l(ma_cal, true);
+ ret = ma_set_lr_swap_l(&ma_cal, true);
if (ret)
- ALOGV("Waves: ma_set_lr_swap_l enable returned with success.");
+ ALOGV("ma_set_lr_swap_l enable returned with success.");
else
- ALOGE("Waves: ma_set_lr_swap_l enable returned with error.");
+ ALOGE("ma_set_lr_swap_l enable returned with error.");
break;
+
case MA_CMD_SWAP_DISABLE:
- ret = ma_set_lr_swap_l(ma_cal, false);
+ ret = ma_set_lr_swap_l(&ma_cal, false);
if (ret)
- ALOGV("Waves: ma_set_lr_swap_l disable returned with success.");
+ ALOGV("ma_set_lr_swap_l disable returned with success.");
else
- ALOGE("Waves: ma_set_lr_swap_l disable returned with error.");
+ ALOGE("ma_set_lr_swap_l disable returned with error.");
break;
+
+ case MA_CMD_SOFT_MUTE_ENABLE:
+ if (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) break;
+
+ ma_cal.effect_scope_flag = EFFECTIVE_SCOPE_RTC;
+ ret = ma_set_param_l(&ma_cal, MAAP_OUTPUT_GAIN, -96);
+ if (!ret)
+ ALOGE("soft mute enable returned with error.");
+ break;
+
+ case MA_CMD_SOFT_MUTE_DISABLE:
+ if (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) break;
+
+ ma_cal.effect_scope_flag = EFFECTIVE_SCOPE_RTC;
+ ret = ma_set_param_l(&ma_cal, MAAP_OUTPUT_GAIN, 0);
+ if (!ret)
+ ALOGE("soft mute disable returned with error.");
+ break;
+
default:
ALOGE("%s: unsupported cmd %d", __func__, cmd);
}
}
}
- free(ma_cal);
return ret;
}
@@ -417,6 +486,13 @@
ALOGE("%s: dlsym error %s for ma_set_volume_table", __func__, dlerror());
goto error;
}
+
+ my_data->ma_set_param = (ma_set_param_t)dlsym(
+ my_data->waves_handle, MA_QDSP_SET_PARAM);
+ if (!my_data->ma_set_param) {
+ ALOGE("%s: dlsym error %s for ma_set_param", __func__, dlerror());
+ goto error;
+ }
}
/* get preset table */
@@ -509,27 +585,42 @@
float vol, bool active)
{
bool ret = false;
- ma_stream_type_t stype = (ma_stream_type_t)stream_type;
+ bool first_enable = false;
+ struct ma_state pr_mstate;
- ALOGV("%s: stream[%d] vol[%f] active[%s]",
- __func__, stream_type, vol, active ? "true" : "false");
+ if (stream_type >= STREAM_MAX_TYPES ||
+ stream_type < STREAM_MIN_TYPES) {
+ ALOGE("%s: stream_type %d out of range.", __func__, stream_type);
+ return ret;
+ }
if (!my_data) {
ALOGV("%s: maxxaudio isn't initialized.", __func__);
return ret;
}
- // update condition
- // 1. start track: active and volume isn't zero
- // 2. stop track: no tracks are active
- if ((active && vol != 0) ||
- (!active)) {
- pthread_mutex_lock(&my_data->lock);
+ ALOGV("%s: stream[%d] vol[%f] active[%s]",
+ __func__, stream_type, vol, active ? "true" : "false");
- ma_cur_state_table[stype].vol = vol;
- ma_cur_state_table[stype].active = active;
- if (is_active())
- ret = check_and_send_all_audio_cal(adev, MA_CMD_VOL);
+ pr_mstate.vol = ma_cur_state_table[(ma_stream_type_t)stream_type].vol;
+ pr_mstate.active = ma_cur_state_table[(ma_stream_type_t)stream_type].active;
+
+ // update condition: vol or active state changes
+ if (pr_mstate.vol != vol || pr_mstate.active != active) {
+
+ pthread_mutex_lock(&my_data->lock);
+ // get active state before updating
+ first_enable = (!is_active()) && active;
+
+ ma_cur_state_table[(ma_stream_type_t)stream_type].vol = vol;
+ ma_cur_state_table[(ma_stream_type_t)stream_type].active = active;
+
+ if (first_enable) //all F -> one of T
+ ret = check_and_send_all_audio_cal(adev, MA_CMD_SOFT_MUTE_DISABLE);
+ else if (!is_active()) // all F
+ ret = check_and_send_all_audio_cal(adev, MA_CMD_SOFT_MUTE_ENABLE);
+
+ ret = check_and_send_all_audio_cal(adev, MA_CMD_VOL);
pthread_mutex_unlock(&my_data->lock);
}
@@ -542,7 +633,7 @@
int i = 0;
int u_index = -1;
float vol = 0;
- struct ma_audio_cal_settings *ma_cal = NULL;
+ struct ma_audio_cal_settings ma_cal;
if (!my_data) {
ALOGV("%s: maxxaudio isn't initialized.", __func__);
@@ -554,38 +645,34 @@
return;
}
- ma_cal = (struct ma_audio_cal_settings *)malloc(sizeof(struct ma_audio_cal_settings));
+ ma_cal_init(&ma_cal);
/* update audio_cal and send it */
- if (ma_cal != NULL){
- ma_cal->app_type = usecase->stream.out->app_type_cfg.app_type;
- ma_cal->device = usecase->stream.out->devices;
- ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
- __func__, usecase->id, ma_cal->app_type, ma_cal->device);
+ ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
+ ma_cal.common.device = usecase->stream.out->devices;
+ ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
+ __func__, usecase->id, ma_cal.common.app_type,
+ ma_cal.common.device);
- pthread_mutex_lock(&my_data->lock);
+ pthread_mutex_lock(&my_data->lock);
- if (is_active()) {
- ALOGV("%s: send volume table === Start", __func__);
- for (i = 0; i < STREAM_MAX_TYPES; i++)
- ALOGV("%s: stream(%d) volume(%f) active(%s)", __func__, i,
- ma_cur_state_table[i].vol,
- ma_cur_state_table[i].active ? "T" : "F");
- ALOGV("%s: send volume table === End", __func__);
+ if (is_active()) {
+ ALOGV("%s: send volume table === Start", __func__);
+ for (i = 0; i < STREAM_MAX_TYPES; i++)
+ ALOGV("%s: stream(%d) volume(%f) active(%s)", __func__, i,
+ ma_cur_state_table[i].vol,
+ ma_cur_state_table[i].active ? "T" : "F");
+ ALOGV("%s: send volume table === End", __func__);
- if (!ma_set_volume_table_l(ma_cal,
- STREAM_MAX_TYPES,
- ma_cur_state_table))
- ALOGE("Waves: ma_set_volume_table_l %f returned with error.", vol);
- else
- ALOGV("Waves: ma_set_volume_table_l success");
+ if (!ma_set_volume_table_l(&ma_cal,
+ STREAM_MAX_TYPES,
+ ma_cur_state_table))
+ ALOGE("ma_set_volume_table_l returned with error.");
+ else
+ ALOGV("ma_set_volume_table_l success");
- }
- pthread_mutex_unlock(&my_data->lock);
- free(ma_cal);
- } else {
- ALOGE("%s: ma_cal alloct fail", __func__);
}
+ pthread_mutex_unlock(&my_data->lock);
}
void audio_extn_ma_set_parameters(struct audio_device *adev,
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 9559573..8e04bf8 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -540,6 +540,20 @@
return false;
}
+static bool is_supported_24bits_audiosource(audio_source_t source)
+{
+ switch (source) {
+ case AUDIO_SOURCE_UNPROCESSED:
+#ifdef ENABLED_24BITS_CAMCORDER
+ case AUDIO_SOURCE_CAMCORDER:
+#endif
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
static inline bool is_mmap_usecase(audio_usecase_t uc_id)
{
return (uc_id == USECASE_AUDIO_RECORD_AFE_PROXY) ||
@@ -4703,20 +4717,24 @@
adev->screen_off = true;
}
-#ifndef MAXXAUDIO_QDSP_ENABLED
ret = str_parms_get_int(parms, "rotation", &val);
if (ret >= 0) {
bool reverse_speakers = false;
+ int camera_rotation = CAMERA_ROTATION_LANDSCAPE;
switch (val) {
// FIXME: note that the code below assumes that the speakers are in the correct placement
// relative to the user when the device is rotated 90deg from its default rotation. This
// assumption is device-specific, not platform-specific like this code.
case 270:
reverse_speakers = true;
+ camera_rotation = CAMERA_ROTATION_INVERT_LANDSCAPE;
break;
case 0:
- case 90:
case 180:
+ camera_rotation = CAMERA_ROTATION_PORTRAIT;
+ break;
+ case 90:
+ camera_rotation = CAMERA_ROTATION_LANDSCAPE;
break;
default:
ALOGE("%s: unexpected rotation of %d", __func__, val);
@@ -4726,10 +4744,13 @@
// check and set swap
// - check if orientation changed and speaker active
// - set rotation and cache the rotation value
+ adev->camera_orientation =
+ (adev->camera_orientation & ~CAMERA_ROTATION_MASK) | camera_rotation;
+#ifndef MAXXAUDIO_QDSP_ENABLED
platform_check_and_set_swap_lr_channels(adev, reverse_speakers);
+#endif
}
}
-#endif
ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_SCO_WB, value, sizeof(value));
if (ret >= 0) {
@@ -4798,6 +4819,32 @@
}
}
+ //FIXME: to be replaced by proper video capture properties API
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_CAMERA_FACING, value, sizeof(value));
+ if (ret >= 0) {
+ int camera_facing = CAMERA_FACING_BACK;
+ if (strcmp(value, AUDIO_PARAMETER_VALUE_FRONT) == 0)
+ camera_facing = CAMERA_FACING_FRONT;
+ else if (strcmp(value, AUDIO_PARAMETER_VALUE_BACK) == 0)
+ camera_facing = CAMERA_FACING_BACK;
+ else {
+ ALOGW("%s: invalid camera facing value: %s", __func__, value);
+ goto done;
+ }
+ adev->camera_orientation =
+ (adev->camera_orientation & ~CAMERA_FACING_MASK) | camera_facing;
+ struct audio_usecase *usecase;
+ struct listnode *node;
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ struct stream_in *in = usecase->stream.in;
+ if (usecase->type == PCM_CAPTURE && in != NULL &&
+ in->source == AUDIO_SOURCE_CAMCORDER && !in->standby) {
+ select_devices(adev, in->usecase);
+ }
+ }
+ }
+
done:
str_parms_destroy(parms);
pthread_mutex_unlock(&adev->lock);
@@ -5083,7 +5130,7 @@
on error flinger will retry with supported format passed
*/
- if (source != AUDIO_SOURCE_UNPROCESSED) {
+ if (!is_supported_24bits_audiosource(source)) {
config->format = AUDIO_FORMAT_PCM_16_BIT;
ret_error = true;
} else if (config->format != AUDIO_FORMAT_PCM_8_24_BIT) {
@@ -5706,6 +5753,8 @@
adev->mic_break_enabled = property_get_bool("vendor.audio.mic_break", false);
+ adev->camera_orientation = CAMERA_DEFAULT;
+
// commented as full set of app type cfg is sent from platform
// audio_extn_utils_send_default_app_type_cfg(adev->platform, adev->mixer);
audio_device_ref_count++;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 6379844..0b3b028 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -159,6 +159,33 @@
OFFLOAD_CMD_ERROR, /* offload playback hit some error */
};
+/*
+ * Camera selection indicated via set_parameters "cameraFacing=front|back and
+ * "rotation=0|90|180|270""
+ */
+enum {
+ CAMERA_FACING_BACK = 0x0,
+ CAMERA_FACING_FRONT = 0x1,
+ CAMERA_FACING_MASK = 0x0F,
+ CAMERA_ROTATION_LANDSCAPE = 0x0,
+ CAMERA_ROTATION_INVERT_LANDSCAPE = 0x10,
+ CAMERA_ROTATION_PORTRAIT = 0x20,
+ CAMERA_ROTATION_MASK = 0xF0,
+ CAMERA_BACK_LANDSCAPE = (CAMERA_FACING_BACK|CAMERA_ROTATION_LANDSCAPE),
+ CAMERA_BACK_INVERT_LANDSCAPE = (CAMERA_FACING_BACK|CAMERA_ROTATION_INVERT_LANDSCAPE),
+ CAMERA_BACK_PORTRAIT = (CAMERA_FACING_BACK|CAMERA_ROTATION_PORTRAIT),
+ CAMERA_FRONT_LANDSCAPE = (CAMERA_FACING_FRONT|CAMERA_ROTATION_LANDSCAPE),
+ CAMERA_FRONT_INVERT_LANDSCAPE = (CAMERA_FACING_FRONT|CAMERA_ROTATION_INVERT_LANDSCAPE),
+ CAMERA_FRONT_PORTRAIT = (CAMERA_FACING_FRONT|CAMERA_ROTATION_PORTRAIT),
+
+ CAMERA_DEFAULT = CAMERA_BACK_LANDSCAPE,
+};
+
+//FIXME: to be replaced by proper video capture properties API
+#define AUDIO_PARAMETER_KEY_CAMERA_FACING "cameraFacing"
+#define AUDIO_PARAMETER_VALUE_FRONT "front"
+#define AUDIO_PARAMETER_VALUE_BACK "back"
+
enum {
OFFLOAD_STATE_IDLE,
OFFLOAD_STATE_PLAYING,
@@ -309,6 +336,7 @@
struct audio_device {
struct audio_hw_device device;
+
pthread_mutex_t lock; /* see note below on mutex acquisition order */
struct mixer *mixer;
audio_mode_t mode;
@@ -367,6 +395,7 @@
/* logging */
snd_device_t last_logged_snd_device[AUDIO_USECASE_MAX][2]; /* [out, in] */
+ int camera_orientation; /* CAMERA_BACK_LANDSCAPE ... CAMERA_FRONT_PORTRAIT */
};
int select_devices(struct audio_device *adev,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 7563689..5a36f0c 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -317,7 +317,7 @@
[SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
[SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
- [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
+ [SND_DEVICE_IN_CAMCORDER_LANDSCAPE] = "camcorder-mic",
[SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
[SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
@@ -359,6 +359,11 @@
[SND_DEVICE_IN_HANDSET_QMIC] = "quad-mic",
[SND_DEVICE_IN_HANDSET_TMIC_AEC] = "three-mic",
[SND_DEVICE_IN_HANDSET_QMIC_AEC] = "quad-mic",
+ [SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE] = "camcorder-mic",
+ [SND_DEVICE_IN_CAMCORDER_PORTRAIT] = "camcorder-mic",
+ [SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = "camcorder-mic",
+ [SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = "camcorder-mic",
+ [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = "camcorder-mic",
};
/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
@@ -436,7 +441,7 @@
[SND_DEVICE_IN_BT_SCO_MIC_NREC] = 21,
[SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 38,
- [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
+ [SND_DEVICE_IN_CAMCORDER_LANDSCAPE] = 61,
[SND_DEVICE_IN_VOICE_DMIC] = 41,
[SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
@@ -477,6 +482,11 @@
[SND_DEVICE_IN_HANDSET_QMIC] = 125,
[SND_DEVICE_IN_HANDSET_TMIC_AEC] = 125, /* override this for new target to 140 */
[SND_DEVICE_IN_HANDSET_QMIC_AEC] = 125, /* override this for new target to 140 */
+ [SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE] = 61,
+ [SND_DEVICE_IN_CAMCORDER_PORTRAIT] = 61,
+ [SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = 61,
+ [SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = 61,
+ [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = 61,
};
// Platform specific backend bit width table
@@ -565,7 +575,7 @@
{TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
{TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
{TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
- {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_LANDSCAPE)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
@@ -606,6 +616,13 @@
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC_AEC)},
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC_AEC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_PORTRAIT)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT)},
+ /* For legacy xml file parsing */
+ {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
};
static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -1296,7 +1313,7 @@
hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_HEADSET_MIC_AEC] = strdup("SLIMBUS_0_TX");
- hw_interface_table[SND_DEVICE_IN_CAMCORDER_MIC] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_CAMCORDER_LANDSCAPE] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_NS] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_AEC] = strdup("SLIMBUS_0_TX");
@@ -1338,6 +1355,11 @@
hw_interface_table[SND_DEVICE_IN_HANDSET_QMIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_HANDSET_TMIC_AEC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_HANDSET_QMIC_AEC] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_CAMCORDER_PORTRAIT] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = strdup("SLIMBUS_0_TX");
my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
}
@@ -2952,7 +2974,30 @@
} else if (source == AUDIO_SOURCE_CAMCORDER) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
+ switch (adev->camera_orientation) {
+ case CAMERA_BACK_LANDSCAPE:
+ snd_device = SND_DEVICE_IN_CAMCORDER_LANDSCAPE;
+ break;
+ case CAMERA_BACK_INVERT_LANDSCAPE:
+ snd_device = SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE;
+ break;
+ case CAMERA_BACK_PORTRAIT:
+ snd_device = SND_DEVICE_IN_CAMCORDER_PORTRAIT;
+ break;
+ case CAMERA_FRONT_LANDSCAPE:
+ snd_device = SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE;
+ break;
+ case CAMERA_FRONT_INVERT_LANDSCAPE:
+ snd_device = SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE;
+ break;
+ case CAMERA_FRONT_PORTRAIT:
+ snd_device = SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT;
+ break;
+ default:
+ ALOGW("%s: invalid camera orientation %08x", __func__, adev->camera_orientation);
+ snd_device = SND_DEVICE_IN_CAMCORDER_LANDSCAPE;
+ break;
+ }
}
} else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 2a9646c..f6c5a58 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -142,7 +142,7 @@
SND_DEVICE_IN_BT_SCO_MIC_NREC,
SND_DEVICE_IN_BT_SCO_MIC_WB,
SND_DEVICE_IN_BT_SCO_MIC_WB_NREC,
- SND_DEVICE_IN_CAMCORDER_MIC,
+ SND_DEVICE_IN_CAMCORDER_LANDSCAPE,
SND_DEVICE_IN_VOICE_DMIC,
SND_DEVICE_IN_VOICE_DMIC_TMUS,
@@ -185,10 +185,16 @@
SND_DEVICE_IN_HANDSET_QMIC,
SND_DEVICE_IN_HANDSET_TMIC_AEC,
SND_DEVICE_IN_HANDSET_QMIC_AEC,
+ SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE,
+ SND_DEVICE_IN_CAMCORDER_PORTRAIT,
+ SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE,
+ SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE,
+ SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT,
SND_DEVICE_IN_END,
SND_DEVICE_MAX = SND_DEVICE_IN_END,
-
+ /* For legacy xml file parsing */
+ SND_DEVICE_IN_CAMCORDER_MIC = SND_DEVICE_IN_CAMCORDER_LANDSCAPE,
};
#define DEFAULT_OUTPUT_SAMPLING_RATE 48000
#define OUTPUT_SAMPLING_RATE_44100 44100