Merge "policy_hal: Fix pop noise when MO call is started, while playing music"
diff --git a/hal/Android.mk b/hal/Android.mk
index 72042d1..e457b83 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -161,10 +161,6 @@
endif
endif
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTIPLE_TUNNEL)), true)
- LOCAL_CFLAGS += -DMULTIPLE_OFFLOAD_ENABLED
-endif
-
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
LOCAL_CFLAGS += -DFLAC_OFFLOAD_ENABLED
LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
index 9d80112..1c5da54 100644
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -101,4 +101,6 @@
/* Query if Proxy can be Opend */
#define AUDIO_PARAMETER_KEY_CAN_OPEN_PROXY "can_open_proxy"
+#define AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED "is_hw_dec_session_allowed"
+
#endif /* AUDIO_DEFS_H */
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 39ad4d1..ce8f965 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -874,9 +874,7 @@
static perf_lock_acquire_t perf_lock_acq;
static perf_lock_release_t perf_lock_rel;
-static int perf_lock_handle;
char opt_lib_path[512] = {0};
-int perf_lock_opts[1] = {0x20E};
int audio_extn_perf_lock_init(void)
{
@@ -914,19 +912,30 @@
return ret;
}
-void audio_extn_perf_lock_acquire(void)
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+ int *perf_lock_opts, int size)
{
- if (perf_lock_acq)
- perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, perf_lock_opts, 1);
- else
- ALOGE("%s: Perf lock acquire error \n", __func__);
+
+ if (!perf_lock_opts || !size || !perf_lock_acq || !handle)
+ return -EINVAL;
+ /*
+ * Acquire performance lock for 1 sec during device path bringup.
+ * Lock will be released either after 1 sec or when perf_lock_release
+ * function is executed.
+ */
+ *handle = perf_lock_acq(*handle, duration, perf_lock_opts, size);
+ if (*handle <= 0)
+ ALOGE("%s: Failed to acquire perf lock, err: %d\n",
+ __func__, *handle);
}
-void audio_extn_perf_lock_release(void)
+void audio_extn_perf_lock_release(int *handle)
{
- if (perf_lock_rel && perf_lock_handle)
- perf_lock_rel(perf_lock_handle);
- else
+ if (perf_lock_rel && handle && (*handle > 0)) {
+ perf_lock_rel(*handle);
+ *handle = 0;
+ } else {
ALOGE("%s: Perf lock release error \n", __func__);
+ }
}
#endif /* KPI_OPTIMIZE_ENABLED */
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 3645cdb..b4848a4 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -503,12 +503,14 @@
#ifndef KPI_OPTIMIZE_ENABLED
#define audio_extn_perf_lock_init() (0)
-#define audio_extn_perf_lock_acquire() (0)
-#define audio_extn_perf_lock_release() (0)
+#define audio_extn_perf_lock_acquire(handle, duration, opts, size) (0)
+#define audio_extn_perf_lock_release(handle) (0)
#else
int audio_extn_perf_lock_init(void);
-void audio_extn_perf_lock_acquire(void);
-void audio_extn_perf_lock_release(void);
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+ int *opts, int size);
+void audio_extn_perf_lock_release(int *handle);
+
#endif /* KPI_OPTIMIZE_ENABLED */
#ifndef AUDIO_EXTERNAL_HDMI_ENABLED
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index ed3776c..3e4b9ea 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -35,6 +35,7 @@
#define AUDIO_PARAMETER_KEY_HANDLE_FM "handle_fm"
#define AUDIO_PARAMETER_KEY_FM_VOLUME "fm_volume"
#define AUDIO_PARAMETER_KEY_REC_PLAY_CONC "rec_play_conc_on"
+#define FM_LOOPBACK_DRAIN_TIME_MS 2
static struct pcm_config pcm_config_fm = {
.channels = 2,
@@ -65,7 +66,7 @@
.scard_state = SND_CARD_STATE_ONLINE,
};
-static int32_t fm_set_volume(struct audio_device *adev, float value)
+static int32_t fm_set_volume(struct audio_device *adev, float value, bool persist)
{
int32_t vol, ret = 0;
struct mixer_ctl *ctl;
@@ -82,7 +83,8 @@
value = 1.0;
}
vol = lrint((value * 0x2000) + 0.5);
- fmmod.fm_volume = value;
+ if (persist)
+ fmmod.fm_volume = value;
if (!fmmod.is_fm_running) {
ALOGV("%s: FM not active, ignoring set_fm_volume call", __func__);
@@ -202,7 +204,7 @@
pcm_start(fmmod.fm_pcm_tx);
fmmod.is_fm_running = true;
- fm_set_volume(adev, fmmod.fm_volume);
+ fm_set_volume(adev, fmmod.fm_volume, false);
ALOGD("%s: exit: status(%d)", __func__, ret);
return 0;
@@ -263,8 +265,11 @@
adev->primary_output->devices = val & ~AUDIO_DEVICE_OUT_FM;
fm_start(adev);
} else if (!(val & AUDIO_DEVICE_OUT_FM)
- && fmmod.is_fm_running == true)
+ && fmmod.is_fm_running == true) {
+ fm_set_volume(adev, 0, false);
+ usleep(FM_LOOPBACK_DRAIN_TIME_MS*1000);
fm_stop(adev);
+ }
}
}
@@ -278,7 +283,7 @@
goto exit;
}
ALOGD("%s: set_fm_volume usecase", __func__);
- fm_set_volume(adev, vol);
+ fm_set_volume(adev, vol, true);
}
#ifdef RECORD_PLAY_CONCURRENCY
@@ -293,7 +298,7 @@
ALOGD("Record play concurrency OFF Forcing FM device reroute");
select_devices(adev, USECASE_AUDIO_PLAYBACK_FM);
- fm_set_volume(adev,fmmod.fm_volume);
+ fm_set_volume(adev, fmmod.fm_volume, false);
}
#endif
exit:
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index a73dfa1..3e09e55 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -47,6 +47,8 @@
#ifdef PLATFORM_MSM8994
#define HFP_RX_VOLUME "SEC AUXPCM LOOPBACK Volume"
+#elif defined PLATFORM_MSM8996
+#define HFP_RX_VOLUME "PRI AUXPCM LOOPBACK Volume"
#else
#define HFP_RX_VOLUME "Internal HFP RX Volume"
#endif
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 38dbb46..a114b30 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -587,14 +587,13 @@
} else if (usecase->type == PCM_PLAYBACK) {
if ((24 == usecase->stream.out->bit_width) &&
(usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
- sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
} else if ((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
(usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
- sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
- } else {
- sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
+ usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
}
+ sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
app_type_cfg[len++] = usecase->stream.out->app_type_cfg.app_type;
app_type_cfg[len++] = acdb_dev_id;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index b98d71b..e6fbc5f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -168,7 +168,7 @@
[USECASE_AUDIO_PLAYBACK_ULL] = "audio-ull-playback",
[USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback",
[USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
-#ifdef MULTIPLE_OFFLOAD_ENABLED
+ //Enabled for Direct_PCM
[USECASE_AUDIO_PLAYBACK_OFFLOAD2] = "compress-offload-playback2",
[USECASE_AUDIO_PLAYBACK_OFFLOAD3] = "compress-offload-playback3",
[USECASE_AUDIO_PLAYBACK_OFFLOAD4] = "compress-offload-playback4",
@@ -177,8 +177,6 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD7] = "compress-offload-playback7",
[USECASE_AUDIO_PLAYBACK_OFFLOAD8] = "compress-offload-playback8",
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] = "compress-offload-playback9",
-#endif
- [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] = "compress-offload-playback2",
[USECASE_AUDIO_RECORD] = "audio-record",
[USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
@@ -214,7 +212,6 @@
static const audio_usecase_t offload_usecases[] = {
USECASE_AUDIO_PLAYBACK_OFFLOAD,
-#ifdef MULTIPLE_OFFLOAD_ENABLED
USECASE_AUDIO_PLAYBACK_OFFLOAD2,
USECASE_AUDIO_PLAYBACK_OFFLOAD3,
USECASE_AUDIO_PLAYBACK_OFFLOAD4,
@@ -223,8 +220,6 @@
USECASE_AUDIO_PLAYBACK_OFFLOAD7,
USECASE_AUDIO_PLAYBACK_OFFLOAD8,
USECASE_AUDIO_PLAYBACK_OFFLOAD9,
-#endif
- USECASE_AUDIO_DIRECT_PCM_OFFLOAD,
};
#define STRING_TO_ENUM(string) { #string, string }
@@ -453,8 +448,8 @@
audio_extn_dolby_ds2_set_endpoint(adev);
audio_extn_sound_trigger_update_stream_status(usecase, ST_EVENT_STREAM_BUSY);
audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_BUSY);
- audio_extn_utils_send_audio_calibration(adev, usecase);
audio_extn_utils_send_app_type_cfg(adev, usecase);
+ audio_extn_utils_send_audio_calibration(adev, usecase);
strcpy(mixer_path, use_case_table[usecase->id]);
platform_add_backend_name(mixer_path, snd_device, usecase);
ALOGD("%s: apply mixer and update path: %s", __func__, mixer_path);
@@ -1129,7 +1124,9 @@
uc_info->out_snd_device = SND_DEVICE_NONE;
list_add_tail(&adev->usecase_list, &uc_info->list);
- audio_extn_perf_lock_acquire();
+ audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+ adev->perf_lock_opts,
+ adev->perf_lock_opts_size);
select_devices(adev, in->usecase);
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
@@ -1171,16 +1168,14 @@
goto error_open;
}
- audio_extn_perf_lock_release();
-
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
ALOGD("%s: exit", __func__);
return ret;
error_open:
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
stop_input_stream(in);
- audio_extn_perf_lock_release();
-
error_config:
adev->active_input = NULL;
/*
@@ -1249,35 +1244,50 @@
return false;
}
-static audio_usecase_t get_offload_usecase(struct audio_device *adev)
+static audio_usecase_t get_offload_usecase(struct audio_device *adev, bool is_direct_pcm)
{
- audio_usecase_t ret = USECASE_AUDIO_PLAYBACK_OFFLOAD;
- unsigned int i, num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
- char value[PROPERTY_VALUE_MAX] = {0};
+ audio_usecase_t ret_uc = USECASE_INVALID;
+ unsigned int offload_uc_index;
+ int num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
+ if (!adev->multi_offload_enable) {
+ if (is_direct_pcm)
+ ret_uc = USECASE_AUDIO_PLAYBACK_OFFLOAD2;
+ else
+ ret_uc = USECASE_AUDIO_PLAYBACK_OFFLOAD;
- property_get("audio.offload.multiple.enabled", value, NULL);
- if (!(atoi(value) || !strncmp("true", value, 4)))
- num_usecase = 1; /* If prop is not set, limit the num of offload usecases to 1 */
+ pthread_mutex_lock(&adev->lock);
+ if (get_usecase_from_list(adev, ret_uc) != NULL)
+ ret_uc = USECASE_INVALID;
+ pthread_mutex_unlock(&adev->lock);
+
+ return ret_uc;
+ }
ALOGV("%s: num_usecase: %d", __func__, num_usecase);
- for (i = 0; i < num_usecase; i++) {
- if (!(adev->offload_usecases_state & (0x1<<i))) {
- adev->offload_usecases_state |= 0x1 << i;
- ret = offload_usecases[i];
+ for (offload_uc_index = 0; offload_uc_index < num_usecase; offload_uc_index++) {
+ if (!(adev->offload_usecases_state & (0x1 << offload_uc_index))) {
+ adev->offload_usecases_state |= 0x1 << offload_uc_index;
+ ret_uc = offload_usecases[offload_uc_index];
break;
}
}
- ALOGV("%s: offload usecase is %d", __func__, ret);
- return ret;
+
+ ALOGV("%s: offload usecase is %d", __func__, ret_uc);
+ return ret_uc;
}
static void free_offload_usecase(struct audio_device *adev,
audio_usecase_t uc_id)
{
- unsigned int i;
- for (i = 0; i < sizeof(offload_usecases)/sizeof(offload_usecases[0]); i++) {
- if (offload_usecases[i] == uc_id) {
- adev->offload_usecases_state &= ~(0x1<<i);
+ unsigned int offload_uc_index;
+ int num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
+
+ if (!adev->multi_offload_enable)
+ return;
+
+ for (offload_uc_index = 0; offload_uc_index < num_usecase; offload_uc_index++) {
+ if (offload_usecases[offload_uc_index] == uc_id) {
+ adev->offload_usecases_state &= ~(0x1 << offload_uc_index);
break;
}
}
@@ -1634,6 +1644,9 @@
}
list_add_tail(&adev->usecase_list, &uc_info->list);
+ audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+ adev->perf_lock_opts,
+ adev->perf_lock_opts_size);
select_devices(adev, out->usecase);
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
@@ -1724,11 +1737,12 @@
audio_extn_check_and_set_dts_hpx_state(adev);
}
}
-
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
ALOGD("%s: exit", __func__);
return 0;
error_open:
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
stop_output_stream(out);
error_config:
/*
@@ -2207,7 +2221,7 @@
out->standby = true;
goto exit;
}
- if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD && adev->adm_register_output_stream)
+ if (!is_offload_usecase(out->usecase) && adev->adm_register_output_stream)
adev->adm_register_output_stream(adev->adm_data, out->handle, out->flags);
}
@@ -2974,18 +2988,24 @@
}
if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
- ALOGV("%s:: inserting DIRECT_PCM _USECASE", __func__);
- out->usecase = USECASE_AUDIO_DIRECT_PCM_OFFLOAD;
+ out->usecase = get_offload_usecase(adev, true);
+ ALOGV("DIRECT_PCM usecase ... usecase selected %d ", out->usecase);
} else {
- ALOGV("%s:: inserting OFFLOAD_USECASE", __func__);
- out->usecase = get_offload_usecase(adev);
-
out->stream.set_callback = out_set_callback;
out->stream.pause = out_pause;
out->stream.resume = out_resume;
out->stream.drain = out_drain;
out->stream.flush = out_flush;
+ out->usecase = get_offload_usecase(adev, false);
+ ALOGV("Compress Offload usecase .. usecase selected %d", out->usecase);
}
+
+ if (out->usecase == USECASE_INVALID) {
+ ALOGE("%s: Max allowed OFFLOAD usecase reached ... ");
+ ret = -EEXIST;
+ goto error_open;
+ }
+
if (config->offload_info.channel_mask)
out->channel_mask = config->offload_info.channel_mask;
else if (config->channel_mask) {
@@ -3645,7 +3665,6 @@
/* This stream could be for sound trigger lab,
get sound trigger pcm if present */
audio_extn_sound_trigger_check_and_get_session(in);
- audio_extn_perf_lock_init();
*stream_in = &in->stream;
ALOGV("%s: exit", __func__);
@@ -3806,6 +3825,9 @@
adev->cur_wfd_channels = 2;
adev->offload_usecases_state = 0;
adev->is_channel_status_set = false;
+ adev->perf_lock_opts[0] = 0x101;
+ adev->perf_lock_opts[1] = 0x20E;
+ adev->perf_lock_opts_size = 2;
pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL);
adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
@@ -3917,11 +3939,13 @@
}
}
+ adev->multi_offload_enable = property_get_bool("audio.offload.multiple.enabled", false);
pthread_mutex_unlock(&adev_init_lock);
if (adev->adm_init)
adev->adm_data = adev->adm_init();
+ audio_extn_perf_lock_init();
ALOGV("%s: exit", __func__);
return 0;
}
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index dc0970f..fd19211 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -74,6 +74,8 @@
#define SND_CARD_STATE_OFFLINE 0
#define SND_CARD_STATE_ONLINE 1
+#define MAX_PERF_LOCK_OPTS 20
+
/* These are the supported use cases by the hardware.
* Each usecase is mapped to a specific PCM device.
* Refer to pcm_device_table[].
@@ -85,7 +87,6 @@
USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
USECASE_AUDIO_PLAYBACK_MULTI_CH,
USECASE_AUDIO_PLAYBACK_OFFLOAD,
-#ifdef MULTIPLE_OFFLOAD_ENABLED
USECASE_AUDIO_PLAYBACK_OFFLOAD2,
USECASE_AUDIO_PLAYBACK_OFFLOAD3,
USECASE_AUDIO_PLAYBACK_OFFLOAD4,
@@ -94,11 +95,8 @@
USECASE_AUDIO_PLAYBACK_OFFLOAD7,
USECASE_AUDIO_PLAYBACK_OFFLOAD8,
USECASE_AUDIO_PLAYBACK_OFFLOAD9,
-#endif
USECASE_AUDIO_PLAYBACK_ULL,
- USECASE_AUDIO_DIRECT_PCM_OFFLOAD,
-
/* FM usecase */
USECASE_AUDIO_PLAYBACK_FM,
@@ -355,6 +353,11 @@
void (*offload_effects_get_parameters)(struct str_parms *,
struct str_parms *);
void (*offload_effects_set_parameters)(struct str_parms *);
+
+ bool multi_offload_enable;
+ int perf_lock_handle;
+ int perf_lock_opts[MAX_PERF_LOCK_OPTS];
+ int perf_lock_opts_size;
};
int select_devices(struct audio_device *adev,
diff --git a/hal/msm8916/hw_info.c b/hal/msm8916/hw_info.c
index 69c9341..6990f23 100644
--- a/hal/msm8916/hw_info.c
+++ b/hal/msm8916/hw_info.c
@@ -240,6 +240,18 @@
hw_info->snd_devices = NULL;
hw_info->num_snd_devices = 0;
strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
+ } else if (!strcmp(snd_card_name, "msm8952-sku1-snd-card")) {
+ strlcpy(hw_info->type, "", sizeof(hw_info->type));
+ strlcpy(hw_info->name, "msm8952", sizeof(hw_info->name));
+ hw_info->snd_devices = NULL;
+ hw_info->num_snd_devices = 0;
+ strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
+ } else if (!strcmp(snd_card_name, "msm8952-sku2-snd-card")) {
+ strlcpy(hw_info->type, "", sizeof(hw_info->type));
+ strlcpy(hw_info->name, "msm8952", sizeof(hw_info->name));
+ hw_info->snd_devices = NULL;
+ hw_info->num_snd_devices = 0;
+ strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
} else {
ALOGW("%s: Not an 8x16/8939/8909/8952 device", __func__);
}
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 03ae642..dbe51ff 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -51,6 +51,8 @@
#define MIXER_XML_PATH_SKUE "/system/etc/mixer_paths_skue.xml"
#define MIXER_XML_PATH_SKUL "/system/etc/mixer_paths_skul.xml"
#define MIXER_XML_PATH_SKUM "/system/etc/mixer_paths_qrd_skum.xml"
+#define MIXER_XML_PATH_SKU1 "/system/etc/mixer_paths_qrd_sku1.xml"
+#define MIXER_XML_PATH_SKU2 "/system/etc/mixer_paths_qrd_sku2.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
#define MIXER_XML_PATH_I2S "/system/etc/mixer_paths_i2s.xml"
@@ -138,6 +140,17 @@
#define AUDIO_PARAMETER_KEY_REC_PLAY_CONC "rec_play_conc_on"
+#define AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED "is_hw_dec_session_allowed"
+
+char * dsp_only_decoders_mime[] = {
+ "audio/x-ms-wma" /* wma*/ ,
+ "audio/x-ms-wma-lossless" /* wma lossless */ ,
+ "audio/x-ms-wma-pro" /* wma prop */ ,
+ "audio/amr-wb-plus" /* amr wb plus */ ,
+ "audio/alac" /*alac */ ,
+ "audio/x-ape" /*ape */,
+};
+
enum {
VOICE_FEATURE_SET_DEFAULT,
VOICE_FEATURE_SET_VOLUME_BOOST
@@ -257,7 +270,6 @@
MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD] =
{PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
/* Below entries are initialized with invalid values
* Valid values should be updated from fnc platform_info_init()
* based on pcm ids defined in audio_platform_info.xml.
@@ -270,9 +282,6 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD7] = {-1, -1},
[USECASE_AUDIO_PLAYBACK_OFFLOAD8] = {-1, -1},
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] = {-1, -1},
-#endif
- [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] =
- {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
[USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
[USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -648,7 +657,6 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD2)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD3)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD4)},
@@ -657,8 +665,6 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD7)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
-#endif
- {TO_NAME_INDEX(USECASE_AUDIO_DIRECT_PCM_OFFLOAD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_VOICE_CALL)},
@@ -898,6 +904,20 @@
msm_device_to_be_id = msm_device_to_be_id_external_codec;
msm_be_id_array_len =
sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
+ } else if (!strncmp(snd_card_name, "msm8952-sku1-snd-card",
+ sizeof("msm8952-sku1-snd-card"))) {
+ strlcpy(mixer_xml_path, MIXER_XML_PATH_SKU1,
+ sizeof(MIXER_XML_PATH_SKU1));
+ msm_device_to_be_id = msm_device_to_be_id_internal_codec;
+ msm_be_id_array_len =
+ sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
+ } else if (!strncmp(snd_card_name, "msm8952-sku2-snd-card",
+ sizeof("msm8952-sku2-snd-card"))) {
+ strlcpy(mixer_xml_path, MIXER_XML_PATH_SKU2,
+ sizeof(MIXER_XML_PATH_SKU2));
+ msm_device_to_be_id = msm_device_to_be_id_internal_codec;
+ msm_be_id_array_len =
+ sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
} else if (!strncmp(snd_card_name, "msm8952-skum-snd-card",
sizeof("msm8952-skum-snd-card"))) {
strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUM,
@@ -3435,6 +3455,8 @@
char value[512] = {0};
int ret;
char *kv_pairs = NULL;
+ char propValue[PROPERTY_VALUE_MAX]={0};
+ bool prop_playback_enabled = false;
ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
value, sizeof(value));
@@ -3463,6 +3485,37 @@
}
native_audio_get_params(query, reply, value, sizeof(value));
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED,
+ value, sizeof(value));
+ if (ret >= 0) {
+ int isallowed = 1; /*true*/
+
+ if (property_get("voice.playback.conc.disabled", propValue, NULL)) {
+ prop_playback_enabled = atoi(propValue) ||
+ !strncmp("true", propValue, 4);
+ }
+
+ if (prop_playback_enabled && (voice_is_in_call(my_data->adev) ||
+ (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev)))) {
+ char *decoder_mime_type = value;
+
+ //check if unsupported mime type or not
+ if(decoder_mime_type) {
+ int i = 0;
+ for (i = 0; i < sizeof(dsp_only_decoders_mime)/sizeof(dsp_only_decoders_mime[0]); i++) {
+ if (!strncmp(decoder_mime_type, dsp_only_decoders_mime[i],
+ strlen(dsp_only_decoders_mime[i]))) {
+ ALOGD("Rejecting request for DSP only session from HAL during voice call/SSR state");
+ isallowed = 0;
+ break;
+ }
+ }
+ }
+ }
+ str_parms_add_int(reply, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED, isallowed);
+ }
+
+
/* Handle audio calibration keys */
kv_pairs = str_parms_to_str(reply);
ALOGV("%s: exit: returns - %s", __func__, kv_pairs);
@@ -3513,7 +3566,6 @@
case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
case USECASE_AUDIO_PLAYBACK_MULTI_CH:
case USECASE_AUDIO_PLAYBACK_OFFLOAD:
- case USECASE_AUDIO_DIRECT_PCM_OFFLOAD:
needs_event = true;
break;
/* concurrent playback in low latency allowed */
@@ -3577,7 +3629,6 @@
case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
case USECASE_AUDIO_PLAYBACK_MULTI_CH:
case USECASE_AUDIO_PLAYBACK_OFFLOAD:
- case USECASE_AUDIO_DIRECT_PCM_OFFLOAD:
needs_event = true;
break;
/* concurrent playback in low latency allowed */
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index b72cae9..8d5004d 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -374,7 +374,7 @@
}
void platform_add_backend_name(char *mixer_path, snd_device_t snd_device,
- struct audio_usecase *usecase)
+ struct audio_usecase *usecase __unused)
{
if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
@@ -1172,3 +1172,8 @@
{
return 0;
}
+
+void platform_set_gsm_mode(void *platform __unused, bool enable __unused)
+{
+ ALOGE("%s: Not implemented", __func__);
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index d693aae..cc48b9e 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -118,6 +118,7 @@
#define AUDIO_PARAMETER_KEY_AUD_CALDATA "cal_data"
#define AUDIO_PARAMETER_KEY_AUD_CALRESULT "cal_result"
+#define AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS "perf_lock_opts"
/* Query external audio device connection status */
#define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
@@ -133,6 +134,18 @@
[WCD9XXX_VBAT_CAL] = "vbat_cal",
};
+#define AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED "is_hw_dec_session_allowed"
+
+char * dsp_only_decoders_mime[] = {
+ "audio/x-ms-wma" /* wma*/ ,
+ "audio/x-ms-wma-lossless" /* wma lossless */ ,
+ "audio/x-ms-wma-pro" /* wma prop */ ,
+ "audio/amr-wb-plus" /* amr wb plus */ ,
+ "audio/alac" /*alac */ ,
+ "audio/x-ape" /*ape */,
+};
+
+
enum {
VOICE_FEATURE_SET_DEFAULT,
VOICE_FEATURE_SET_VOLUME_BOOST
@@ -245,7 +258,6 @@
MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD] =
{PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
[USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
{PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
[USECASE_AUDIO_PLAYBACK_OFFLOAD3] =
@@ -262,10 +274,7 @@
{PLAYBACK_OFFLOAD_DEVICE8, PLAYBACK_OFFLOAD_DEVICE8},
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] =
{PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
-#endif
- [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] =
- {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
[USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
@@ -324,13 +333,16 @@
[SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
[SND_DEVICE_OUT_HEADPHONES] = "headphones",
[SND_DEVICE_OUT_HEADPHONES_44_1] = "headphones-44.1",
+ [SND_DEVICE_OUT_LINE] = "line",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
+ [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = "speaker-and-headphones-ext-1",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = "speaker-and-headphones-ext-2",
[SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
[SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = "voice-speaker-vbat",
[SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
+ [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
[SND_DEVICE_OUT_HDMI] = "hdmi",
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
[SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
@@ -424,15 +436,18 @@
[SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = 130,
[SND_DEVICE_OUT_SPEAKER_VBAT] = 14,
[SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
+ [SND_DEVICE_OUT_LINE] = 10,
[SND_DEVICE_OUT_HEADPHONES] = 10,
[SND_DEVICE_OUT_HEADPHONES_44_1] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
+ [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 130,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 130,
[SND_DEVICE_OUT_VOICE_HANDSET] = 7,
[SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = 14,
[SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
+ [SND_DEVICE_OUT_VOICE_LINE] = 10,
[SND_DEVICE_OUT_HDMI] = 18,
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
[SND_DEVICE_OUT_BT_SCO] = 22,
@@ -530,13 +545,16 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_44_1)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_VBAT)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
@@ -621,7 +639,6 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD2)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD3)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD4)},
@@ -630,8 +647,6 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD7)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
-#endif
- {TO_NAME_INDEX(USECASE_AUDIO_DIRECT_PCM_OFFLOAD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_VOICE_CALL)},
@@ -1148,7 +1163,7 @@
ret = 0;
- if((plat_data->is_vbat_speaker) && (WCD9XXX_VBAT_CAL == type)) {
+ if ((plat_data->is_vbat_speaker) && (WCD9XXX_VBAT_CAL == type)) {
ret = send_vbat_adc_data_to_acdb(plat_data, cal_name_info[type]);
if (ret < 0)
ALOGE("%s error in sending vbat adc data to acdb", __func__);
@@ -1255,7 +1270,7 @@
char value[PROPERTY_VALUE_MAX];
struct platform_data *my_data = NULL;
int retry_num = 0, snd_card_num = 0, key = 0;
- const char *snd_card_name;
+ const char *snd_card_name = NULL;
char *cvd_version = NULL;
char *snd_internal_name = NULL;
char *tmp = NULL;
@@ -1367,7 +1382,8 @@
if (snd_card_num >= MAX_SND_CARD) {
ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
free(my_data);
- free(snd_card_name);
+ if (snd_card_name)
+ free(snd_card_name);
return NULL;
}
@@ -1657,7 +1673,7 @@
return;
}
- if((snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT) &&
+ if ((snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT) &&
!(usecase->type == VOICE_CALL || usecase->type == VOIP_CALL)) {
ALOGI("%s: Not adding vbat speaker device to non voice use cases", __func__);
return;
@@ -2292,6 +2308,9 @@
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2;
else
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
+ } else if (devices == (AUDIO_DEVICE_OUT_LINE |
+ AUDIO_DEVICE_OUT_SPEAKER)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
} else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
@@ -2315,7 +2334,8 @@
if ((mode == AUDIO_MODE_IN_CALL) ||
voice_extn_compress_voip_is_active(adev)) {
if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+ devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ devices & AUDIO_DEVICE_OUT_LINE) {
if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
!voice_extn_compress_voip_is_active(adev)) {
switch (adev->voice.tty_mode) {
@@ -2332,6 +2352,8 @@
ALOGE("%s: Invalid TTY mode (%#x)",
__func__, adev->voice.tty_mode);
}
+ } else if (devices & AUDIO_DEVICE_OUT_LINE) {
+ snd_device = SND_DEVICE_OUT_VOICE_LINE;
} else if (audio_extn_get_anc_enabled()) {
if (audio_extn_should_use_fb_anc())
snd_device = SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET;
@@ -2381,6 +2403,8 @@
snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
else
snd_device = SND_DEVICE_OUT_HEADPHONES;
+ } else if (devices & AUDIO_DEVICE_OUT_LINE) {
+ snd_device = SND_DEVICE_OUT_LINE;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
if (my_data->external_spk_1)
snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_1;
@@ -2460,7 +2484,8 @@
if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
!voice_extn_compress_voip_is_active(adev)) {
if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ out_device & AUDIO_DEVICE_OUT_LINE) {
switch (adev->voice.tty_mode) {
case TTY_MODE_FULL:
snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
@@ -2478,7 +2503,8 @@
}
}
if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
- out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ out_device & AUDIO_DEVICE_OUT_LINE) {
if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
audio_extn_should_use_handset_anc(channel_count)) {
snd_device = SND_DEVICE_IN_AANC_HANDSET_MIC;
@@ -2694,7 +2720,8 @@
snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
else
snd_device = SND_DEVICE_IN_SPEAKER_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
+ } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ out_device & AUDIO_DEVICE_OUT_LINE) {
snd_device = SND_DEVICE_IN_HANDSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
if (adev->bt_wb_speech_enabled) {
@@ -2995,6 +3022,44 @@
free(dptr);
}
+static void perf_lock_set_params(struct platform_data *platform,
+ struct str_parms *parms,
+ char *value, int len)
+{
+ int err = 0, i = 0, num_opts = 0;
+ char *test_r = NULL;
+ char *opts = NULL;
+ char *opts_size = NULL;
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS,
+ value, len);
+ if (err >= 0) {
+ opts_size = strtok_r(value, ", ", &test_r);
+ if (opts_size == NULL) {
+ ALOGE("%s: incorrect perf lock opts\n", __func__);
+ return;
+ }
+ num_opts = atoi(opts_size);
+ if (num_opts > 0) {
+ if (num_opts > MAX_PERF_LOCK_OPTS) {
+ ALOGD("%s: num_opts %d exceeds max %d, setting to max\n",
+ __func__, num_opts, MAX_PERF_LOCK_OPTS);
+ num_opts = MAX_PERF_LOCK_OPTS;
+ }
+ for (i = 0; i < num_opts; i++) {
+ opts = strtok_r(NULL, ", ", &test_r);
+ if (opts == NULL) {
+ ALOGE("%s: incorrect perf lock opts\n", __func__);
+ break;
+ }
+ platform->adev->perf_lock_opts[i] = strtoul(opts, NULL, 16);
+ }
+ platform->adev->perf_lock_opts_size = i;
+ }
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS);
+ }
+}
+
int platform_set_parameters(void *platform, struct str_parms *parms)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -3088,6 +3153,7 @@
set_audiocal(platform, parms, value, len);
native_audio_set_params(platform, parms, value, len);
audio_extn_spkr_prot_set_parameters(parms, value, len);
+ perf_lock_set_params(platform, parms, value, len);
done:
ALOGV("%s: exit with code(%d)", __func__, ret);
if(kv_pairs != NULL)
@@ -3301,6 +3367,8 @@
char value[512] = {0};
int ret;
char *kv_pairs = NULL;
+ char propValue[PROPERTY_VALUE_MAX]={0};
+ bool prop_playback_enabled = false;
ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
value, sizeof(value));
@@ -3332,6 +3400,36 @@
get_audiocal(platform, query, reply);
native_audio_get_params(query, reply, value, sizeof(value));
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED,
+ value, sizeof(value));
+ if (ret >= 0) {
+ int isallowed = 1; /*true*/
+
+ if (property_get("voice.playback.conc.disabled", propValue, NULL)) {
+ prop_playback_enabled = atoi(propValue) ||
+ !strncmp("true", propValue, 4);
+ }
+
+ if (prop_playback_enabled && (voice_is_in_call(my_data->adev) ||
+ (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev)))) {
+ char *decoder_mime_type = value;
+
+ //check if unsupported mime type or not
+ if(decoder_mime_type) {
+ int i = 0;
+ for (i = 0; i < sizeof(dsp_only_decoders_mime)/sizeof(dsp_only_decoders_mime[0]); i++) {
+ if (!strncmp(decoder_mime_type, dsp_only_decoders_mime[i],
+ strlen(dsp_only_decoders_mime[i]))) {
+ ALOGD("Rejecting request for DSP only session from HAL during voice call/SSR state");
+ isallowed = 0;
+ break;
+ }
+ }
+ }
+ }
+ str_parms_add_int(reply, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED, isallowed);
+ }
+
done:
kv_pairs = str_parms_to_str(reply);
ALOGV_IF(kv_pairs != NULL, "%s: exit: returns - %s", __func__, kv_pairs);
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 54406b6..a2c6304 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -43,7 +43,8 @@
*/
#define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
(AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
- AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
+ AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE | \
+ AUDIO_DEVICE_OUT_LINE)
/*
* Below are the input devices for which back end is same, SLIMBUS_0_TX.
@@ -70,15 +71,18 @@
SND_DEVICE_OUT_SPEAKER_EXTERNAL_2,
SND_DEVICE_OUT_SPEAKER_REVERSE,
SND_DEVICE_OUT_SPEAKER_VBAT,
+ SND_DEVICE_OUT_LINE,
SND_DEVICE_OUT_HEADPHONES,
SND_DEVICE_OUT_HEADPHONES_44_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
+ SND_DEVICE_OUT_SPEAKER_AND_LINE,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2,
SND_DEVICE_OUT_VOICE_HANDSET,
SND_DEVICE_OUT_VOICE_SPEAKER,
SND_DEVICE_OUT_VOICE_SPEAKER_VBAT,
SND_DEVICE_OUT_VOICE_HEADPHONES,
+ SND_DEVICE_OUT_VOICE_LINE,
SND_DEVICE_OUT_HDMI,
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
@@ -248,9 +252,12 @@
#endif
#define PLAYBACK_OFFLOAD_DEVICE 9
-#ifdef MULTIPLE_OFFLOAD_ENABLED
-#ifdef PLATFORM_APQ8084
+// Direct_PCM
+#if defined (PLATFORM_MSM8994) || defined (PLATFORM_MSM8996) || defined (PLATFORM_APQ8084)
#define PLAYBACK_OFFLOAD_DEVICE2 17
+#endif
+
+#ifdef PLATFORM_APQ8084
#define PLAYBACK_OFFLOAD_DEVICE3 18
#define PLAYBACK_OFFLOAD_DEVICE4 34
#define PLAYBACK_OFFLOAD_DEVICE5 35
@@ -260,7 +267,6 @@
#define PLAYBACK_OFFLOAD_DEVICE9 39
#endif
#if defined (PLATFORM_MSM8994) || defined (PLATFORM_MSM8996)
-#define PLAYBACK_OFFLOAD_DEVICE2 17
#define PLAYBACK_OFFLOAD_DEVICE3 18
#define PLAYBACK_OFFLOAD_DEVICE4 37
#define PLAYBACK_OFFLOAD_DEVICE5 38
@@ -269,10 +275,6 @@
#define PLAYBACK_OFFLOAD_DEVICE8 41
#define PLAYBACK_OFFLOAD_DEVICE9 42
#endif
-#endif
-
-// for DIRECT_PCM
-#define PLAYBACK_OFFLOAD_DEVICE2 17
#define COMPRESS_VOIP_CALL_PCM_DEVICE 3
diff --git a/policy_hal/Android.mk b/policy_hal/Android.mk
index 52ed11d..70814d8 100644
--- a/policy_hal/Android.mk
+++ b/policy_hal/Android.mk
@@ -59,6 +59,10 @@
LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FM_POWER_OPT)),true)
+LOCAL_CFLAGS += -DFM_POWER_OPT
+endif
+
LOCAL_MODULE := libaudiopolicymanager
include $(BUILD_SHARED_LIBRARY)
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 64a877a..7876e5b 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -250,6 +250,23 @@
audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
updateCallRouting(newDevice);
}
+
+#ifdef FM_POWER_OPT
+ // handle FM device connection state to trigger FM AFE loopback
+ if(device == AUDIO_DEVICE_OUT_FM && hasPrimaryOutput()) {
+ audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
+ if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+ mPrimaryOutput->changeRefCount(AUDIO_STREAM_MUSIC, 1);
+ newDevice = newDevice | AUDIO_DEVICE_OUT_FM;
+ } else {
+ mPrimaryOutput->changeRefCount(AUDIO_STREAM_MUSIC, -1);
+ }
+ AudioParameter param = AudioParameter();
+ param.addInt(String8("handle_fm"), (int)newDevice);
+ mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString());
+ }
+#endif /* FM_POWER_OPT end */
+
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
@@ -393,6 +410,13 @@
return false;
}
+ // Check if offload has been disabled
+ bool offloadDisabled = property_get_bool("audio.offload.disable", false);
+ if (offloadDisabled) {
+ ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
+ return false;
+ }
+
char propValue[PROPERTY_VALUE_MAX];
bool pcmOffload = false;
#ifdef PCM_OFFLOAD_ENABLED
@@ -422,13 +446,13 @@
}
#endif
if (!pcmOffload) {
- // Check if offload has been disabled
- if (property_get("audio.offload.disable", propValue, "0")) {
- if (atoi(propValue) != 0) {
- ALOGV("offload disabled by audio.offload.disable=%s", propValue );
- return false;
- }
+
+ bool compressedOffloadDisabled = property_get_bool("audio.offload.compress.disable", false);
+ if (compressedOffloadDisabled) {
+ ALOGI("compressed offload disabled by audio.offload.compress.disable=%d", compressedOffloadDisabled);
+ return false;
}
+
//check if it's multi-channel AAC (includes sub formats) and FLAC format
if ((popcount(offloadInfo.channel_mask) > 2) &&
(((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
@@ -456,6 +480,14 @@
ALOGV("isOffloadSupported: has_video == true, returning false");
return false;
}
+
+ const bool allowOffloadStreamingWithVideo = property_get_bool("av.streaming.offload.enable",
+ false /*default value*/);
+ if(offloadInfo.has_video && offloadInfo.is_streaming && !allowOffloadStreamingWithVideo) {
+ ALOGW("offload disabled by av.streaming.offload.enable = %s ", propValue );
+ return false;
+ }
+
}
//If duration is less than minimum value defined in property, return false
@@ -947,18 +979,22 @@
}
-status_t AudioPolicyManagerCustom::stopSource(sp<SwAudioOutputDescriptor> outputDesc,
+status_t AudioPolicyManagerCustom::stopSource(sp<AudioOutputDescriptor> outputDesc,
audio_stream_type_t stream,
bool forceDeviceUpdate)
{
+ if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
+ ALOGW("stopSource() invalid stream %d", stream);
+ return INVALID_OPERATION;
+ }
// always handle stream stop, check which stream type is stopping
handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
// handle special case for sonification while in call
if (isInCall() && (outputDesc->mRefCount[stream] == 1)) {
if (outputDesc->isDuplicated()) {
- handleIncallSonification(stream, false, false, outputDesc->mOutput1->mIoHandle);
- handleIncallSonification(stream, false, false, outputDesc->mOutput2->mIoHandle);
+ handleIncallSonification(stream, false, false, outputDesc->subOutput1()->mIoHandle);
+ handleIncallSonification(stream, false, false, outputDesc->subOutput2()->mIoHandle);
}
handleIncallSonification(stream, false, false, outputDesc->mIoHandle);
}
@@ -993,7 +1029,7 @@
if (dev == prevDevice) {
delayMs = 0;
} else {
- delayMs = outputDesc->mLatency*2;
+ delayMs = outputDesc->latency()*2;
}
setOutputDevice(desc,
dev,
@@ -1010,7 +1046,7 @@
return INVALID_OPERATION;
}
}
-status_t AudioPolicyManagerCustom::startSource(sp<SwAudioOutputDescriptor> outputDesc,
+status_t AudioPolicyManagerCustom::startSource(sp<AudioOutputDescriptor> outputDesc,
audio_stream_type_t stream,
audio_devices_t device,
uint32_t *delayMs)
@@ -1018,6 +1054,11 @@
// cannot start playback of STREAM_TTS if any other output is being used
uint32_t beaconMuteLatency = 0;
+ if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
+ ALOGW("startSource() invalid stream %d", stream);
+ return INVALID_OPERATION;
+ }
+
*delayMs = 0;
if (stream == AUDIO_STREAM_TTS) {
ALOGV("\t found BEACON stream");
@@ -1161,10 +1202,14 @@
}
status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream,
int index,
- const sp<SwAudioOutputDescriptor>& outputDesc,
+ const sp<AudioOutputDescriptor>& outputDesc,
audio_devices_t device,
int delayMs, bool force)
{
+ if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
+ ALOGW("checkAndSetVolume() invalid stream %d", stream);
+ return INVALID_OPERATION;
+ }
// do not change actual stream volume if the stream is muted
if (outputDesc->mMuteCount[stream] != 0) {
ALOGVV("checkAndSetVolume() stream %d muted count %d",
@@ -1207,6 +1252,13 @@
mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
mLastVoiceVolume = voiceVolume;
}
+#ifdef FM_POWER_OPT
+ } else if (stream == AUDIO_STREAM_MUSIC && hasPrimaryOutput() &&
+ outputDesc == mPrimaryOutput) {
+ AudioParameter param = AudioParameter();
+ param.addFloat(String8("fm_volume"), Volume::DbToAmpl(volumeDb));
+ mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString(), delayMs);
+#endif /* FM_POWER_OPT end */
}
return NO_ERROR;
@@ -1236,7 +1288,17 @@
{
audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
- bool pcmOffloadEnabled = property_get_bool("audio.offload.track.enable", false);
+ bool offloadDisabled = property_get_bool("audio.offload.disable", false);
+ bool pcmOffloadEnabled = false;
+
+ if (offloadDisabled) {
+ ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
+ }
+
+ //read track offload property only if the global offload switch is off.
+ if (!offloadDisabled) {
+ pcmOffloadEnabled = property_get_bool("audio.offload.track.enable", false);
+ }
if (offloadInfo == NULL && pcmOffloadEnabled) {
tOffloadInfo.sample_rate = samplingRate;
@@ -1248,7 +1310,7 @@
ALOGV("found attribute .. setting usage %d ", attr->usage);
tOffloadInfo.usage = attr->usage;
} else {
- ALOGD("%s:: attribute is NULL .. no usage set", __func__);
+ ALOGI("%s:: attribute is NULL .. no usage set", __func__);
}
offloadInfo = &tOffloadInfo;
}
@@ -1559,23 +1621,29 @@
if (profile != 0) {
sp<SwAudioOutputDescriptor> outputDesc = NULL;
- for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- if (!desc->isDuplicated() && (profile == desc->mProfile)) {
- outputDesc = desc;
- // reuse direct output if currently open and configured with same parameters
- if ((samplingRate == outputDesc->mSamplingRate) &&
- (format == outputDesc->mFormat) &&
- (channelMask == outputDesc->mChannelMask)) {
- outputDesc->mDirectOpenCount++;
- ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
- return mOutputs.keyAt(i);
+ // if multiple concurrent offload decode is supported
+ // do no check for reuse and also don't close previous output if its offload
+ // previous output will be closed during track destruction
+ if (!(property_get_bool("audio.offload.multiple.enabled", false) &&
+ ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0))) {
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if (!desc->isDuplicated() && (profile == desc->mProfile)) {
+ outputDesc = desc;
+ // reuse direct output if currently open and configured with same parameters
+ if ((samplingRate == outputDesc->mSamplingRate) &&
+ (format == outputDesc->mFormat) &&
+ (channelMask == outputDesc->mChannelMask)) {
+ outputDesc->mDirectOpenCount++;
+ ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
+ return mOutputs.keyAt(i);
+ }
}
}
- }
- // close direct output if currently open and configured with different parameters
- if (outputDesc != NULL) {
- closeOutput(outputDesc->mIoHandle);
+ // close direct output if currently open and configured with different parameters
+ if (outputDesc != NULL) {
+ closeOutput(outputDesc->mIoHandle);
+ }
}
// if the selected profile is offloaded and no offload info was specified,
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index dfaad65..a7f88e4 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -79,7 +79,7 @@
status_t checkAndSetVolume(audio_stream_type_t stream,
int index,
- const sp<SwAudioOutputDescriptor>& outputDesc,
+ const sp<AudioOutputDescriptor>& outputDesc,
audio_devices_t device,
int delayMs = 0, bool force = false);
@@ -94,11 +94,11 @@
// if argument "device" is different from AUDIO_DEVICE_NONE, startSource() will force
// the re-evaluation of the output device.
- status_t startSource(sp<SwAudioOutputDescriptor> outputDesc,
+ status_t startSource(sp<AudioOutputDescriptor> outputDesc,
audio_stream_type_t stream,
audio_devices_t device,
uint32_t *delayMs);
- status_t stopSource(sp<SwAudioOutputDescriptor> outputDesc,
+ status_t stopSource(sp<AudioOutputDescriptor> outputDesc,
audio_stream_type_t stream,
bool forceDeviceUpdate);
// event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON
diff --git a/post_proc/volume_listener.c b/post_proc/volume_listener.c
index d4f418a..e1dd026 100644
--- a/post_proc/volume_listener.c
+++ b/post_proc/volume_listener.c
@@ -324,6 +324,13 @@
* Effect Control Interface Implementation
*/
+static inline int16_t clamp16(int32_t sample)
+{
+ if ((sample>>15) ^ (sample>>31))
+ sample = 0x7FFF ^ (sample>>31);
+ return sample;
+}
+
static int vol_effect_process(effect_handle_t self,
audio_buffer_t *in_buffer,
audio_buffer_t *out_buffer)
@@ -342,7 +349,14 @@
// calculation based on channel count 2
if (in_buffer->raw != out_buffer->raw) {
- memcpy(out_buffer->raw, in_buffer->raw, out_buffer->frameCount * 2 * sizeof(int16_t));
+ if (context->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+ size_t i;
+ for (i = 0; i < out_buffer->frameCount*2; i++) {
+ out_buffer->s16[i] = clamp16(out_buffer->s16[i] + in_buffer->s16[i]);
+ }
+ } else {
+ memcpy(out_buffer->raw, in_buffer->raw, out_buffer->frameCount * 2 * sizeof(int16_t));
+ }
} else {
ALOGV("%s: something wrong, didn't handle in_buffer and out_buffer same address case",
__func__);
@@ -386,6 +400,12 @@
case EFFECT_CMD_SET_CONFIG:
ALOGV("%s :: cmd called EFFECT_CMD_SET_CONFIG", __func__);
+ if (p_cmd_data == NULL || cmd_size != sizeof(effect_config_t)
+ || p_reply_data == NULL || reply_size == NULL || *reply_size != sizeof(int)) {
+ return -EINVAL;
+ }
+ context->config = *(effect_config_t *)p_cmd_data;
+ *(int *)p_reply_data = 0;
break;
case EFFECT_CMD_GET_CONFIG:
@@ -432,7 +452,7 @@
// After changing the state and if device is speaker
// recalculate gain dep cal level
- if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
check_and_set_gain_dep_cal();
}
@@ -459,7 +479,7 @@
// After changing the state and if device is speaker
// recalculate gain dep cal level
- if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
check_and_set_gain_dep_cal();
}
@@ -490,8 +510,8 @@
__func__, context->dev_id, new_device);
// check if old or new device is speaker
- if ((context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) ||
- (new_device & AUDIO_DEVICE_OUT_SPEAKER)) {
+ if ((context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) ||
+ (new_device == AUDIO_DEVICE_OUT_SPEAKER)) {
recompute_gain_dep_cal_Level = true;
}
@@ -516,7 +536,7 @@
goto exit;
}
- if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
recompute_gain_dep_cal_Level = true;
}
@@ -612,7 +632,7 @@
static int vol_prc_lib_create(const effect_uuid_t *uuid,
int32_t session_id,
- int32_t io_id,
+ int32_t io_id __unused,
effect_handle_t *p_handle)
{
int itt = 0;
@@ -696,7 +716,7 @@
&& (context->stream_type == recv_contex->stream_type)) {
ALOGV("--- Found something to remove ---");
PRINT_STREAM_TYPE(context->stream_type);
- if (context->dev_id && AUDIO_DEVICE_OUT_SPEAKER) {
+ if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
recompute_flag = true;
}
list_remove(&context->effect_list_node);