summaryrefslogtreecommitdiffstats
path: root/hal
diff options
context:
space:
mode:
Diffstat (limited to 'hal')
-rw-r--r--hal/Android.mk20
-rw-r--r--hal/audio_extn/audio_defs.h78
-rw-r--r--hal/audio_extn/audio_extn.c43
-rw-r--r--hal/audio_extn/audio_extn.h22
-rw-r--r--hal/audio_extn/hfp.c16
-rw-r--r--hal/audio_extn/sound_trigger_prop_intf.h61
-rw-r--r--hal/audio_extn/soundtrigger.c20
-rw-r--r--hal/audio_extn/spkr_protection.c1
-rw-r--r--hal/audio_hw.c298
-rw-r--r--hal/audio_hw.h8
-rw-r--r--hal/msm8960/platform.c8
-rw-r--r--hal/msm8974/platform.c291
-rw-r--r--hal/msm8974/platform.h22
-rw-r--r--hal/platform_api.h10
-rw-r--r--hal/voice.c3
15 files changed, 824 insertions, 77 deletions
diff --git a/hal/Android.mk b/hal/Android.mk
index 549d2f98..03696354 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -68,11 +68,18 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTI_VOICE_SESSIONS)),true)
LOCAL_SRC_FILES += voice_extn/voice_extn.c
endif
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HFP)),true)
LOCAL_CFLAGS += -DHFP_ENABLED
LOCAL_SRC_FILES += audio_extn/hfp.c
endif
+ifeq ($(strip $(AUDIO_FEATURE_SUPPORTED_EXTERNAL_BT)),true)
+ LOCAL_CFLAGS += -DEXTERNAL_BT_SUPPORTED
+endif
+
ifeq ($(strip $(AUDIO_FEATURE_NO_AUDIO_OUT)),true)
LOCAL_CFLAGS += -DNO_AUDIO_OUT
endif
@@ -101,6 +108,19 @@ ifneq ($(filter msm8992 msm8994,$(TARGET_BOARD_PLATFORM)),)
LOCAL_SRC_FILES += audio_extn/hwdep_cal.c
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PCM_OFFLOAD)),true)
+ LOCAL_CFLAGS += -DPCM_OFFLOAD_ENABLED
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FLAC_OFFLOAD)),true)
+ LOCAL_CFLAGS += -DFLAC_OFFLOAD_ENABLED
+ LOCAL_CFLAGS += -DPCM_OFFLOAD_ENABLED
+ LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
+endif
+
+LOCAL_COPY_HEADERS_TO := mm-audio
+LOCAL_COPY_HEADERS := audio_extn/audio_defs.h
+
LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE_RELATIVE_PATH := hw
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
new file mode 100644
index 00000000..335a6295
--- /dev/null
+++ b/hal/audio_extn/audio_defs.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AUDIO_DEFS_H
+#define AUDIO_DEFS_H
+
+
+/**
+ * extended audio codec parameters
+ */
+
+#define AUDIO_OFFLOAD_CODEC_WMA_FORMAT_TAG "music_offload_wma_format_tag"
+#define AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN "music_offload_wma_block_align"
+#define AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE "music_offload_wma_bit_per_sample"
+#define AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK "music_offload_wma_channel_mask"
+#define AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION "music_offload_wma_encode_option"
+#define AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1 "music_offload_wma_encode_option1"
+#define AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2 "music_offload_wma_encode_option2"
+#define AUDIO_OFFLOAD_CODEC_FORMAT "music_offload_codec_format"
+#define AUDIO_OFFLOAD_CODEC_FLAC_MIN_BLK_SIZE "music_offload_flac_min_blk_size"
+#define AUDIO_OFFLOAD_CODEC_FLAC_MAX_BLK_SIZE "music_offload_flac_max_blk_size"
+#define AUDIO_OFFLOAD_CODEC_FLAC_MIN_FRAME_SIZE "music_offload_flac_min_frame_size"
+#define AUDIO_OFFLOAD_CODEC_FLAC_MAX_FRAME_SIZE "music_offload_flac_max_frame_size"
+
+/* Query handle fm parameter*/
+#define AUDIO_PARAMETER_KEY_HANDLE_FM "handle_fm"
+
+/* Query fm volume */
+#define AUDIO_PARAMETER_KEY_FM_VOLUME "fm_volume"
+
+/* Query Fluence type */
+#define AUDIO_PARAMETER_KEY_FLUENCE "fluence"
+#define AUDIO_PARAMETER_VALUE_QUADMIC "quadmic"
+#define AUDIO_PARAMETER_VALUE_DUALMIC "dualmic"
+#define AUDIO_PARAMETER_KEY_NO_FLUENCE "none"
+
+/* Query if surround sound recording is supported */
+#define AUDIO_PARAMETER_KEY_SSR "ssr"
+
+/* Query if a2dp is supported */
+#define AUDIO_PARAMETER_KEY_HANDLE_A2DP_DEVICE "isA2dpDeviceSupported"
+
+/* Query ADSP Status */
+#define AUDIO_PARAMETER_KEY_ADSP_STATUS "ADSP_STATUS"
+
+/* Query Sound Card Status */
+#define AUDIO_PARAMETER_KEY_SND_CARD_STATUS "SND_CARD_STATUS"
+
+/* Query if Proxy can be Opend */
+#define AUDIO_PARAMETER_KEY_CAN_OPEN_PROXY "can_open_proxy"
+
+#endif /* AUDIO_DEFS_H */
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 7583f835..c9d805bf 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -29,7 +29,50 @@
#include "platform.h"
#include "platform_api.h"
+#include "sound/compress_params.h"
+#ifndef COMPRESS_METADATA_NEEDED
+#define audio_extn_parse_compress_metadata(out, parms) (0)
+#else
+int audio_extn_parse_compress_metadata(struct stream_out *out,
+ struct str_parms *parms)
+{
+ int ret = 0;
+ char value[32];
+
+#ifdef FLAC_OFFLOAD_ENABLED
+ if (out->format == AUDIO_FORMAT_FLAC) {
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MIN_BLK_SIZE, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.flac_dec.min_blk_size = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MAX_BLK_SIZE, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.flac_dec.max_blk_size = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MIN_FRAME_SIZE, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.flac_dec.min_frame_size = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MAX_FRAME_SIZE, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.flac_dec.max_frame_size = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ALOGV("FLAC metadata: min_blk_size %d, max_blk_size %d min_frame_size %d max_frame_size %d",
+ out->compr_config.codec->options.flac_dec.min_blk_size,
+ out->compr_config.codec->options.flac_dec.max_blk_size,
+ out->compr_config.codec->options.flac_dec.min_frame_size,
+ out->compr_config.codec->options.flac_dec.max_frame_size);
+ }
+#endif
+
+ return ret;
+}
+#endif
#ifdef KPI_OPTIMIZE_ENABLED
typedef int (*perf_lock_acquire_t)(int, int, int*, int);
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index c518faa7..3d3db003 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -25,6 +25,28 @@ void audio_extn_extspk_update(void* extn);
void audio_extn_extspk_set_mode(void* extn, audio_mode_t mode);
void audio_extn_extspk_set_voice_vol(void* extn, float vol);
+#ifndef PCM_OFFLOAD_ENABLED
+#define AUDIO_FORMAT_PCM_OFFLOAD 0x1A000000UL
+#define AUDIO_FORMAT_PCM_16_BIT_OFFLOAD (AUDIO_FORMAT_PCM_OFFLOAD | AUDIO_FORMAT_PCM_SUB_16_BIT)
+#define AUDIO_FORMAT_PCM_24_BIT_OFFLOAD (AUDIO_FORMAT_PCM_OFFLOAD | AUDIO_FORMAT_PCM_SUB_8_24_BIT)
+#define AUDIO_OFFLOAD_CODEC_FORMAT "music_offload_codec_format"
+#define audio_is_offload_pcm(format) (0)
+#endif
+
+#ifndef FLAC_OFFLOAD_ENABLED
+#define AUDIO_FORMAT_FLAC 0x1B000000UL
+#endif
+
+#ifndef COMPRESS_METADATA_NEEDED
+#define audio_extn_parse_compress_metadata(out, parms) (0)
+#else
+int audio_extn_parse_compress_metadata(struct stream_out *out,
+ struct str_parms *parms);
+#endif
+
+#define AUDIO_OUTPUT_BIT_WIDTH ((config->offload_info.bit_width == 32) ? 24\
+ :config->offload_info.bit_width)
+
#ifndef SPKR_PROT_ENABLED
#define audio_extn_spkr_prot_init(adev) (0)
#define audio_extn_spkr_prot_start_processing(snd_device) (-EINVAL)
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index a1087309..f3075cfa 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -71,7 +71,11 @@ static int32_t hfp_set_volume(struct audio_device *adev, float value)
{
int32_t vol, ret = 0;
struct mixer_ctl *ctl;
+#ifdef EXTERNAL_BT_SUPPORTED
+ const char *mixer_ctl_name = "PRI AUXPCM LOOPBACK Volume";
+#else
const char *mixer_ctl_name = "Internal HFP RX Volume";
+#endif
ALOGV("%s: entry", __func__);
ALOGD("%s: (%f)\n", __func__, value);
@@ -115,6 +119,8 @@ static int32_t start_hfp(struct audio_device *adev,
int32_t pcm_dev_rx_id, pcm_dev_tx_id, pcm_dev_asm_rx_id, pcm_dev_asm_tx_id;
ALOGD("%s: enter", __func__);
+ adev->enable_hfp = true;
+ platform_set_mic_mute(adev->platform, false);
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
uc_info->id = hfpmod.ucid;
@@ -238,6 +244,16 @@ static int32_t stop_hfp(struct audio_device *adev)
disable_snd_device(adev, uc_info->out_snd_device);
disable_snd_device(adev, uc_info->in_snd_device);
+ /* Disable the echo reference for HFP Tx */
+ platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
+
+ /* Set the unmute Tx mixer control */
+ if (voice_get_mic_mute(adev)) {
+ platform_set_mic_mute(adev->platform, false);
+ ALOGD("%s: unMute HFP Tx", __func__);
+ }
+ adev->enable_hfp = false;
+
list_remove(&uc_info->list);
free(uc_info);
diff --git a/hal/audio_extn/sound_trigger_prop_intf.h b/hal/audio_extn/sound_trigger_prop_intf.h
new file mode 100644
index 00000000..90a9aa97
--- /dev/null
+++ b/hal/audio_extn/sound_trigger_prop_intf.h
@@ -0,0 +1,61 @@
+/*
+ * Extrapolated / reversed header for Sound Trigger
+ */
+
+#ifndef SOUND_TRIGGER_PROP_INTF_H
+#define SOUND_TRIGGER_PROP_INTF_H
+
+struct sound_trigger_session_info {
+ int capture_handle;
+ struct pcm *pcm;
+ struct pcm_config config;
+};
+
+enum audio_event_type {
+ AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE,
+ AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE,
+ dummy1,
+ dummy2,
+ AUDIO_EVENT_STOP_LAB,
+ AUDIO_EVENT_SSR,
+ AUDIO_EVENT_NUM_ST_SESSIONS,
+ AUDIO_EVENT_READ_SAMPLES,
+};
+
+enum sound_trigger_event_type {
+ ST_EVENT_SESSION_REGISTER,
+ ST_EVENT_SESSION_DEREGISTER
+};
+typedef enum sound_trigger_event_type sound_trigger_event_type_t;
+
+enum ssr_event_status {
+ SND_CARD_STATUS_OFFLINE,
+ SND_CARD_STATUS_ONLINE,
+ CPE_STATUS_OFFLINE,
+ CPE_STATUS_ONLINE
+};
+
+struct sound_trigger_event_info {
+ struct sound_trigger_session_info st_ses;
+};
+typedef struct sound_trigger_event_info sound_trigger_event_info_t;
+
+struct audio_read_samples_info {
+ struct sound_trigger_session_info *ses_info;
+ void *buf;
+ size_t num_bytes;
+};
+
+struct audio_event_info {
+ union {
+ enum ssr_event_status status;
+ int value;
+ struct sound_trigger_session_info ses_info;
+ struct audio_read_samples_info aud_info;
+ }u;
+};
+typedef struct audio_event_info audio_event_info_t;
+
+typedef int (*sound_trigger_hw_call_back_t)(enum audio_event_type,
+ struct audio_event_info*);
+#endif
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index b5475a17..1630b2df 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
+ * Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +15,7 @@
* limitations under the License.
*/
#define LOG_TAG "soundtrigger"
-/* #define LOG_NDEBUG 0 */
+/*#define LOG_NDEBUG 0*/
#define LOG_NDDEBUG 0
#include <errno.h>
@@ -133,15 +134,17 @@ int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
if (in->standby)
in->standby = false;
+ ALOGD("audio_extn_sound_trigger_read");
+
pthread_mutex_lock(&st_dev->lock);
st_info = get_sound_trigger_info(in->capture_handle);
- pthread_mutex_unlock(&st_dev->lock);
if (st_info) {
event.u.aud_info.ses_info = &st_info->st_ses;
event.u.aud_info.buf = buffer;
event.u.aud_info.num_bytes = bytes;
ret = st_dev->st_callback(AUDIO_EVENT_READ_SAMPLES, &event);
}
+ pthread_mutex_unlock(&st_dev->lock);
exit:
if (ret) {
@@ -149,7 +152,7 @@ exit:
in->is_st_session_active = false;
memset(buffer, 0, bytes);
ALOGV("%s: read failed status %d - sleep", __func__, ret);
- usleep((bytes * 1000000) / (audio_stream_in_frame_size((struct audio_stream_in *)in) *
+ usleep(((int64_t)bytes * 1000000) / (audio_stream_in_frame_size((struct audio_stream_in *)in) *
in->config.rate));
}
return ret;
@@ -161,17 +164,20 @@ void audio_extn_sound_trigger_stop_lab(struct stream_in *in)
struct sound_trigger_info *st_ses_info = NULL;
audio_event_info_t event;
- if (!st_dev || !in)
+ if (!st_dev || !in || !in->is_st_session_active)
return;
+ ALOGD("audio_extn_sound_trigger_stop_lab");
+
pthread_mutex_lock(&st_dev->lock);
st_ses_info = get_sound_trigger_info(in->capture_handle);
- pthread_mutex_unlock(&st_dev->lock);
if (st_ses_info) {
event.u.ses_info = st_ses_info->st_ses;
ALOGV("%s: AUDIO_EVENT_STOP_LAB pcm %p", __func__, st_ses_info->st_ses.pcm);
st_dev->st_callback(AUDIO_EVENT_STOP_LAB, &event);
+ in->is_st_session_active = false;
}
+ pthread_mutex_unlock(&st_dev->lock);
}
void audio_extn_sound_trigger_check_and_get_session(struct stream_in *in)
{
@@ -225,6 +231,7 @@ void audio_extn_sound_trigger_update_device_status(snd_device_t snd_device,
ALOGI("%s: device 0x%x of type %d for Event %d",
__func__, snd_device, device_type, event);
if (device_type == PCM_CAPTURE) {
+ pthread_mutex_lock(&st_dev->lock);
switch(event) {
case ST_EVENT_SND_DEVICE_FREE:
st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE, NULL);
@@ -236,6 +243,7 @@ void audio_extn_sound_trigger_update_device_status(snd_device_t snd_device,
ALOGW("%s:invalid event %d for device 0x%x",
__func__, event, snd_device);
}
+ pthread_mutex_unlock(&st_dev->lock);
}/*Events for output device, if required can be placed here in else*/
}
@@ -251,6 +259,7 @@ void audio_extn_sound_trigger_set_parameters(struct audio_device *adev __unused,
return;
}
+ pthread_mutex_lock(&st_dev->lock);
ret = str_parms_get_str(params, "SND_CARD_STATUS", value,
sizeof(value));
if (ret > 0) {
@@ -285,6 +294,7 @@ void audio_extn_sound_trigger_set_parameters(struct audio_device *adev __unused,
event.u.value = val;
st_dev->st_callback(AUDIO_EVENT_NUM_ST_SESSIONS, &event);
}
+ pthread_mutex_unlock(&st_dev->lock);
}
int audio_extn_sound_trigger_init(struct audio_device *adev)
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 4d8b2337..3f9a654b 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -338,6 +338,7 @@ static int spkr_calibrate(int t0)
uc_info_rx->out_snd_device = SND_DEVICE_OUT_SPEAKER_PROTECTED;
disable_rx = true;
list_add_tail(&adev->usecase_list, &uc_info_rx->list);
+ platform_check_and_set_codec_backend_cfg(adev, uc_info_rx);
enable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED);
enable_audio_route(adev, uc_info_rx);
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 2e954d67..ada5ecec 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1,5 +1,8 @@
/*
- * Copyright (C) 2013-2014 The Android Open Source Project
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,12 +54,13 @@
#include "voice_extn.h"
#include "sound/compress_params.h"
+#include "sound/asound.h"
#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
// 2 buffers causes problems with high bitrate files
#define COMPRESS_OFFLOAD_NUM_FRAGMENTS 3
/* ToDo: Check and update a proper value in msec */
-#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
+#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 50
#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
#define PROXY_OPEN_RETRY_COUNT 100
@@ -222,15 +226,24 @@ bool audio_hw_send_gain_dep_calibration(int level) {
static bool is_supported_format(audio_format_t format)
{
- switch (format) {
- case AUDIO_FORMAT_MP3:
- case AUDIO_FORMAT_AAC_LC:
- case AUDIO_FORMAT_AAC_HE_V1:
- case AUDIO_FORMAT_AAC_HE_V2:
- return true;
- default:
- break;
- }
+ if (format == AUDIO_FORMAT_MP3 ||
+ format == AUDIO_FORMAT_AAC ||
+ format == AUDIO_FORMAT_AAC_LC ||
+ format == AUDIO_FORMAT_AAC_HE_V1 ||
+ format == AUDIO_FORMAT_AAC_HE_V2)
+ return true;
+
+#ifdef PCM_OFFLOAD_ENABLED
+ if (format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD ||
+ format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD)
+ return true;
+#endif
+
+#ifdef FLAC_OFFLOAD_ENABLED
+ if (format == AUDIO_FORMAT_FLAC)
+ return true;
+#endif
+
return false;
}
@@ -245,8 +258,19 @@ static int get_snd_codec_id(audio_format_t format)
case AUDIO_FORMAT_AAC:
id = SND_AUDIOCODEC_AAC;
break;
+#ifdef PCM_OFFLOAD_ENABLED
+ case AUDIO_FORMAT_PCM_16_BIT_OFFLOAD:
+ case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD:
+ id = SND_AUDIOCODEC_PCM;
+ break;
+#endif
+#ifdef FLAC_OFFLOAD_ENABLED
+ case AUDIO_FORMAT_FLAC:
+ id = SND_AUDIOCODEC_FLAC;
+ break;
+#endif
default:
- ALOGE("%s: Unsupported audio format", __func__);
+ ALOGE("%s: Unsupported audio format %x", __func__, format);
}
return id;
@@ -312,8 +336,6 @@ int enable_snd_device(struct audio_device *adev,
return -EINVAL;
}
- platform_send_audio_calibration(adev->platform, snd_device);
-
adev->snd_dev_ref_cnt[snd_device]++;
if (adev->snd_dev_ref_cnt[snd_device] > 1) {
ALOGV("%s: snd_device(%d: %s) is already active",
@@ -321,11 +343,6 @@ int enable_snd_device(struct audio_device *adev,
return 0;
}
- /* due to the possibility of calibration overwrite between listen
- and audio, notify sound trigger hal before audio calibration is sent */
- audio_extn_sound_trigger_update_device_status(snd_device,
- ST_EVENT_SND_DEVICE_BUSY);
-
if (audio_extn_spkr_prot_is_enabled())
audio_extn_spkr_prot_calib_cancel(adev);
@@ -335,12 +352,11 @@ int enable_snd_device(struct audio_device *adev,
snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
audio_extn_spkr_prot_is_enabled()) {
if (audio_extn_spkr_prot_get_acdb_id(snd_device) < 0) {
- adev->snd_dev_ref_cnt[snd_device]--;
- return -EINVAL;
+ goto out_error;
}
if (audio_extn_spkr_prot_start_processing(snd_device)) {
ALOGE("%s: spkr_start_processing failed", __func__);
- return -EINVAL;
+ goto out_error;
}
} else if (platform_can_split_snd_device(snd_device, &num_devices, new_snd_devices)) {
for (i = 0; i < num_devices; i++) {
@@ -349,11 +365,21 @@ int enable_snd_device(struct audio_device *adev,
platform_set_speaker_gain_in_combo(adev, snd_device, true);
} else {
const char * dev_path = platform_get_snd_device_name(snd_device);
- ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, dev_path);
+ audio_extn_sound_trigger_update_device_status(snd_device,
+ ST_EVENT_SND_DEVICE_BUSY);
+ /* due to the possibility of calibration overwrite between listen
+ and audio, notify sound trigger hal before audio calibration is sent */
+ ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, dev_path);
+ platform_send_audio_calibration(adev->platform, snd_device);
audio_route_apply_and_update_path(adev->audio_route, dev_path);
}
return 0;
+
+out_error:
+ adev->snd_dev_ref_cnt[snd_device]--;
+ audio_extn_sound_trigger_update_device_status(snd_device, ST_EVENT_SND_DEVICE_FREE);
+ return -EINVAL;
}
int disable_snd_device(struct audio_device *adev,
@@ -415,6 +441,15 @@ static void check_and_route_playback_usecases(struct audio_device *adev,
* because of the limitation that both the devices cannot be enabled
* at the same time as they share the same backend.
*/
+ /*
+ * This call is to check if we need to force routing for a particular stream
+ * If there is a backend configuration change for the device when a
+ * new stream starts, then ADM needs to be closed and re-opened with the new
+ * configuraion. This call check if we need to re-route all the streams
+ * associated with the backend. Touch tone + 24 bit playback.
+ */
+ bool force_routing = platform_check_and_set_codec_backend_cfg(adev, uc_info);
+
/* Disable all the usecases on the shared backend other than the
specified usecase */
for (i = 0; i < AUDIO_USECASE_MAX; i++)
@@ -424,7 +459,7 @@ static void check_and_route_playback_usecases(struct audio_device *adev,
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->type != PCM_CAPTURE &&
usecase != uc_info &&
- usecase->out_snd_device != snd_device &&
+ (usecase->out_snd_device != snd_device || force_routing) &&
usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND &&
platform_check_backends_match(snd_device, usecase->out_snd_device)) {
ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
@@ -845,7 +880,13 @@ int start_input_stream(struct stream_in *in)
}
ALOGV("%s: pcm_prepare start", __func__);
- pcm_prepare(in->pcm);
+ ret = pcm_prepare(in->pcm);
+ if (ret < 0) {
+ ALOGE("%s: pcm_prepare returned %d", __func__, ret);
+ pcm_close(in->pcm);
+ in->pcm = NULL;
+ goto error_open;
+ }
audio_extn_perf_lock_release();
@@ -909,6 +950,7 @@ static void *offload_thread_loop(void *context)
{
struct stream_out *out = (struct stream_out *) context;
struct listnode *item;
+ int ret = 0;
out->offload_state = OFFLOAD_STATE_IDLE;
out->playback_started = 0;
@@ -961,12 +1003,24 @@ static void *offload_thread_loop(void *context)
event = STREAM_CBK_EVENT_WRITE_READY;
break;
case OFFLOAD_CMD_PARTIAL_DRAIN:
- compress_next_track(out->compr);
- compress_partial_drain(out->compr);
+ ret = compress_next_track(out->compr);
+ if(ret == 0) {
+ ALOGD("copl(%p):calling compress_partial_drain", out);
+ compress_partial_drain(out->compr);
+ ALOGD("copl(%p):out of compress_partial_drain", out);
+ }
+ else if(ret == -ETIMEDOUT)
+ compress_drain(out->compr);
+ else
+ ALOGE("%s: Next track returned error %d",__func__, ret);
+
send_callback = true;
event = STREAM_CBK_EVENT_DRAIN_READY;
+ pthread_mutex_lock(&out->lock);
/* Resend the metadata for next iteration */
out->send_new_metadata = 1;
+ out->send_next_track_params = true;
+ pthread_mutex_unlock(&out->lock);
break;
case OFFLOAD_CMD_DRAIN:
compress_drain(out->compr);
@@ -980,7 +1034,7 @@ static void *offload_thread_loop(void *context)
lock_output_stream(out);
out->offload_thread_blocked = false;
pthread_cond_signal(&out->cond);
- if (send_callback) {
+ if (send_callback && out->offload_callback) {
ALOGVV("%s: sending offload_callback event %d", __func__, event);
out->offload_callback(event, NULL, out->offload_cookie);
}
@@ -1204,9 +1258,15 @@ int start_output_stream(struct stream_out *out)
break;
}
ALOGV("%s: pcm_prepare start", __func__);
- if (pcm_is_ready(out->pcm))
- pcm_prepare(out->pcm);
-
+ if (pcm_is_ready(out->pcm)) {
+ ret = pcm_prepare(out->pcm);
+ if (ret < 0) {
+ ALOGE("%s: pcm_prepare returned %d", __func__, ret);
+ pcm_close(out->pcm);
+ out->pcm = NULL;
+ goto error_open;
+ }
+ }
} else {
out->pcm = NULL;
out->compr = compress_open(adev->snd_card, out->pcm_device_id,
@@ -1218,6 +1278,9 @@ int start_output_stream(struct stream_out *out)
ret = -EIO;
goto error_open;
}
+ /* compress_open sends params of the track, so reset the flag here */
+ out->is_compr_metadata_avail = false;
+
if (out->offload_callback)
compress_nonblock(out->compr, out->non_blocking);
@@ -1362,6 +1425,8 @@ static int out_standby(struct audio_stream *stream)
}
} else {
stop_compressed_output_l(out);
+ out->send_next_track_params = false;
+ out->is_compr_metadata_avail = false;
out->gapless_mdata.encoder_delay = 0;
out->gapless_mdata.encoder_padding = 0;
if (out->compr != NULL) {
@@ -1386,28 +1451,23 @@ static int parse_compress_metadata(struct stream_out *out, struct str_parms *par
{
int ret = 0;
char value[32];
- struct compr_gapless_mdata tmp_mdata;
if (!out || !parms) {
+ ALOGE("%s: return invalid ",__func__);
return -EINVAL;
}
+ ret = audio_extn_parse_compress_metadata(out, parms);
+
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, value, sizeof(value));
if (ret >= 0) {
- tmp_mdata.encoder_delay = atoi(value); //whats a good limit check?
- } else {
- return -EINVAL;
+ out->gapless_mdata.encoder_delay = atoi(value); //whats a good limit check?
}
-
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES, value, sizeof(value));
if (ret >= 0) {
- tmp_mdata.encoder_padding = atoi(value);
- } else {
- return -EINVAL;
+ out->gapless_mdata.encoder_padding = atoi(value);
}
- out->gapless_mdata = tmp_mdata;
- out->send_new_metadata = 1;
ALOGV("%s new encoder delay %u and padding %u", __func__,
out->gapless_mdata.encoder_delay, out->gapless_mdata.encoder_padding);
@@ -1497,7 +1557,9 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
}
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ pthread_mutex_lock(&out->lock);
parse_compress_metadata(out, parms);
+ pthread_mutex_unlock(&out->lock);
}
str_parms_destroy(parms);
@@ -1547,12 +1609,17 @@ static char* out_get_parameters(const struct audio_stream *stream, const char *k
static uint32_t out_get_latency(const struct audio_stream_out *stream)
{
struct stream_out *out = (struct stream_out *)stream;
+ uint32_t latency = 0;
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
- return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
-
- return (out->config.period_count * out->config.period_size * 1000) /
+ if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ latency = COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
+ } else {
+ latency = (out->config.period_count * out->config.period_size * 1000) /
(out->config.rate);
+ }
+
+ ALOGV("%s: Latency %d", __func__, latency);
+ return latency;
}
static int out_set_volume(struct audio_stream_out *stream, float left,
@@ -1602,7 +1669,7 @@ static ssize_t out_write_for_no_output(struct audio_stream_out *stream,
* Sleep for the amount of buffer duration
*/
lock_output_stream(out);
- usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
+ usleep((uint64_t)bytes * 1000000 / audio_stream_out_frame_size(&out->stream.common) /
out_get_sample_rate(&out->stream.common));
pthread_mutex_unlock(&out->lock);
return bytes;
@@ -1632,14 +1699,22 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
}
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
- ALOGVV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
+ ALOGVV("copl(%p): writing buffer (%zu bytes) to compress device", out, bytes);
if (out->send_new_metadata) {
ALOGVV("send new gapless metadata");
compress_set_gapless_metadata(out->compr, &out->gapless_mdata);
out->send_new_metadata = 0;
+ if (out->send_next_track_params && out->is_compr_metadata_avail) {
+ ALOGD("copl(%p):send next track params in gapless", out);
+ compress_set_next_track_param(out->compr, &(out->compr_config.codec->options));
+ out->send_next_track_params = false;
+ out->is_compr_metadata_avail = false;
+ }
}
ret = compress_write(out->compr, buffer, bytes);
+ if (ret < 0)
+ ret = -errno;
ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret);
if (ret >= 0 && ret < (ssize_t)bytes) {
send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
@@ -1666,7 +1741,9 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
else
ret = pcm_write(out->pcm, (void *)buffer, bytes);
- if (ret == 0)
+ if (ret < 0)
+ ret = -errno;
+ else if (ret == 0)
out->written += bytes / (out->config.channels * sizeof(short));
if (adev->adm_abandon_focus)
@@ -1691,19 +1768,22 @@ static int out_get_render_position(const struct audio_stream_out *stream,
uint32_t *dsp_frames)
{
struct stream_out *out = (struct stream_out *)stream;
+ ssize_t ret = 0;
*dsp_frames = 0;
if ((out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) && (dsp_frames != NULL)) {
lock_output_stream(out);
if (out->compr != NULL) {
- compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
+ ret = compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
&out->sample_rate);
+ if (ret < 0)
+ ret = -errno;
ALOGVV("%s rendered frames %d sample_rate %d",
__func__, *dsp_frames, out->sample_rate);
}
pthread_mutex_unlock(&out->lock);
return 0;
- } else
- return -EINVAL;
+ }
+ return ret;
}
static int out_add_audio_effect(const struct audio_stream *stream __unused,
@@ -1935,11 +2015,13 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
parms = str_parms_create_str(kvpairs);
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
-
+ if (!parms)
+ goto error;
lock_input_stream(in);
-
pthread_mutex_lock(&adev->lock);
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
+
if (ret >= 0) {
val = atoi(value);
/* no audio source uses val == 0 */
@@ -1955,7 +2037,7 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
if (((int)in->device != val) && (val != 0)) {
in->device = val;
/* If recording is in progress, change the tx device to new device */
- if (!in->standby)
+ if (!in->standby && !in->is_st_session)
status = select_devices(adev, in->usecase);
}
}
@@ -1964,6 +2046,8 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
pthread_mutex_unlock(&in->lock);
str_parms_destroy(parms);
+
+error:
ALOGV("%s: exit: status(%d)", __func__, status);
return status;
}
@@ -1971,7 +2055,20 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
static char* in_get_parameters(const struct audio_stream *stream __unused,
const char *keys __unused)
{
- return strdup("");
+ struct str_parms *reply = str_parms_create_str(keys);
+ char *str;
+
+ if (!reply) {
+ ALOGE("in_get_parameters: failed to create query or reply");
+ return NULL;
+ }
+
+ ALOGV("%s: enter: keys - %s", __func__, keys);
+
+ str = str_parms_to_str(reply);
+ str_parms_destroy(reply);
+
+ return str;
}
static int in_set_gain(struct audio_stream_in *stream __unused, float gain __unused)
@@ -2014,8 +2111,13 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
if (in->pcm) {
if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) {
ret = pcm_mmap_read(in->pcm, buffer, bytes);
- } else
+ } else {
+ ALOGVV("%s: reading buffer (%d bytes) from pcm device (handle=%d)", __func__,
+ bytes, in->capture_handle);
ret = pcm_read(in->pcm, buffer, bytes);
+ }
+ if (ret < 0)
+ ret = -errno;
}
if (adev->adm_abandon_focus)
@@ -2033,9 +2135,10 @@ exit:
pthread_mutex_unlock(&in->lock);
if (ret != 0) {
+ memset(buffer, 0, bytes);
in_standby(&in->stream.common);
ALOGV("%s: read failed - sleeping for buffer duration", __func__);
- usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
+ usleep((uint64_t)bytes * 1000000 / audio_stream_in_frame_size(stream) /
in_get_sample_rate(&in->stream.common));
}
return bytes;
@@ -2117,13 +2220,23 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
{
struct audio_device *adev = (struct audio_device *)dev;
struct stream_out *out;
- int i, ret;
+ int i, ret = 0;
+ int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
__func__, config->sample_rate, config->channel_mask, devices, flags);
*stream_out = NULL;
out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
+ if (!out) {
+ return -ENOMEM;
+ }
+
+ pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
+ pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
+
+
if (devices == AUDIO_DEVICE_NONE)
devices = AUDIO_DEVICE_OUT_SPEAKER;
@@ -2135,6 +2248,9 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
out->handle = handle;
+ out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ out->non_blocking = 0;
+ out->use_small_bufs = false;
/* Init use case and pcm_config */
if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT &&
@@ -2177,8 +2293,10 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
if (config->offload_info.channel_mask)
out->channel_mask = config->offload_info.channel_mask;
- else if (config->channel_mask)
+ else if (config->channel_mask) {
out->channel_mask = config->channel_mask;
+ config->offload_info.channel_mask = config->channel_mask;
+ }
out->format = config->offload_info.format;
out->sample_rate = config->offload_info.sample_rate;
@@ -2187,10 +2305,18 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->stream.resume = out_resume;
out->stream.drain = out_drain;
out->stream.flush = out_flush;
+ out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
out->compr_config.codec->id =
get_snd_codec_id(config->offload_info.format);
- out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+#ifdef PCM_OFFLOAD_ENABLED
+ if ((config->offload_info.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM_OFFLOAD)
+ out->compr_config.fragment_size =
+ platform_get_pcm_offload_buffer_size(&config->offload_info);
+ else
+#endif
+ out->compr_config.fragment_size =
+ platform_get_compress_offload_buffer_size(&config->offload_info);
out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
out->compr_config.codec->bit_rate =
@@ -2198,11 +2324,35 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->compr_config.codec->ch_in =
audio_channel_count_from_out_mask(config->channel_mask);
out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
+ out->bit_width = AUDIO_OUTPUT_BIT_WIDTH;
+
+ if (config->offload_info.format == AUDIO_FORMAT_AAC)
+ out->compr_config.codec->format = SND_AUDIOSTREAMFORMAT_RAW;
+
+#ifdef PCM_OFFLOAD_ENABLED
+ if (config->offload_info.format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD)
+ out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE;
+ if(config->offload_info.format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD)
+ out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE;
+ if (out->bit_width == 24) {
+ out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE;
+ }
+#endif
+
+#ifdef FLAC_OFFLOAD_ENABLED
+ if (config->offload_info.format == AUDIO_FORMAT_FLAC)
+ out->compr_config.codec->options.flac_dec.sample_size = AUDIO_OUTPUT_BIT_WIDTH;
+#endif
if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
out->non_blocking = 1;
out->send_new_metadata = 1;
+ out->send_next_track_params = false;
+ out->is_compr_metadata_avail = false;
+ out->offload_state = OFFLOAD_STATE_IDLE;
+ out->playback_started = 0;
+
create_offload_callback_thread(out);
ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
__func__, config->offload_info.version,
@@ -2263,8 +2413,17 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
ALOGV("%s: Usecase(%s) config->format %#x out->config.format %#x\n",
__func__, use_case_table[out->usecase], config->format, out->config.format);
+ if ((24 == out->bit_width) &&
+ (devices == AUDIO_DEVICE_OUT_SPEAKER)) {
+ sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ ALOGI("%s 24-bit playback on Speaker is allowed ONLY at 48khz. Hence changing sample rate to: %d",
+ __func__, sample_rate);
+ } else {
+ sample_rate = out->sample_rate;
+ }
+
if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
- if (adev->primary_output == NULL)
+ if(adev->primary_output == NULL)
adev->primary_output = out;
else {
ALOGE("%s: Primary output is already opened", __func__);
@@ -2310,10 +2469,6 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
/* out->muted = false; by calloc() */
/* out->written = 0; by calloc() */
- pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
- pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
- pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
-
config->format = out->stream.common.get_format(&out->stream.common);
config->channel_mask = out->stream.common.get_channels(&out->stream.common);
config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
@@ -2419,6 +2574,8 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
}
audio_extn_hfp_set_parameters(adev, parms);
+ audio_extn_sound_trigger_set_parameters(adev, parms);
+
done:
str_parms_destroy(parms);
pthread_mutex_unlock(&adev->lock);
@@ -2643,9 +2800,16 @@ err_open:
static void adev_close_input_stream(struct audio_hw_device *dev __unused,
struct audio_stream_in *stream)
{
+ struct stream_in *in = (struct stream_in *)stream;
+
ALOGV("%s", __func__);
in_standby(&stream->common);
+
+ if (in->is_st_session) {
+ ALOGV("%s: sound trigger pcm stop lab", __func__);
+ audio_extn_sound_trigger_stop_lab(in);
+ }
free(stream);
return;
@@ -2891,6 +3055,8 @@ static int adev_open(const hw_module_t *module, const char *name,
adev->bluetooth_nrec = true;
adev->acdb_settings = TTY_MODE_OFF;
/* adev->cur_hdmi_channels = 0; by calloc() */
+ adev->cur_codec_backend_samplerate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ adev->cur_codec_backend_bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
voice_init(adev);
list_init(&adev->usecase_list);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index b82ee8b1..e5a94e62 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -25,6 +25,7 @@
#include <tinycompress/tinycompress.h>
#include <audio_route/audio_route.h>
+#include "audio_defs.h"
#include "voice.h"
#define VISUALIZER_LIBRARY_PATH "/system/lib/soundfx/libqcomvisualizer.so"
@@ -146,6 +147,7 @@ struct stream_out {
audio_io_handle_t handle;
int non_blocking;
+ bool use_small_bufs;
int playback_started;
int offload_state;
pthread_cond_t offload_cond;
@@ -157,6 +159,9 @@ struct stream_out {
void *offload_cookie;
struct compr_gapless_mdata gapless_mdata;
int send_new_metadata;
+ bool send_next_track_params;
+ bool is_compr_metadata_avail;
+ unsigned int bit_width;
struct audio_device *dev;
};
@@ -234,8 +239,11 @@ struct audio_device {
bool bt_wb_speech_enabled;
bool mic_muted;
bool enable_voicerx;
+ bool enable_hfp;
int snd_card;
+ unsigned int cur_codec_backend_samplerate;
+ unsigned int cur_codec_backend_bit_width;
void *platform;
void *extspk;
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 0ffe8a98..4988dbe5 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1087,3 +1087,11 @@ bool platform_check_backends_match(snd_device_t snd_device1 __unused,
{
return true;
}
+
+bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase) {
+ return false;
+}
+
+uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info) {
+ return 0;
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index c856bb0a..fbe70c29 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -27,13 +27,32 @@
#include "platform.h"
#include "audio_extn.h"
#include <linux/msm_audio.h>
+#include "sound/compress_params.h"
#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
+#define MIXER_XML_PATH_WCD9330 "/system/etc/mixer_paths_wcd9330.xml"
#define LIB_ACDB_LOADER "libacdbloader.so"
#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
#define CVD_VERSION_MIXER_CTL "CVD Version"
+#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
+#define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024)
+#define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024)
+#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
+
+/* Used in calculating fragment size for pcm offload */
+#define PCM_OFFLOAD_BUFFER_DURATION 40 /* 40 millisecs */
+
+/* MAX PCM fragment size cannot be increased further due
+ * to flinger's cblk size of 1mb,and it has to be a multiple of
+ * 24 - lcm of channels supported by DSP
+ */
+#define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024)
+#define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
+
+#define DIV_ROUND_UP(x, y) (((x) + (y) - 1)/(y))
+#define ALIGN(x, y) ((y) * DIV_ROUND_UP((x), (y)))
/*
* This file will have a maximum of 38 bytes:
*
@@ -201,6 +220,7 @@ static const char * const device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
[SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
+ [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = "voice-speaker-hfp",
/* Capture sound devices */
[SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
@@ -237,6 +257,7 @@ static const char * const device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
+ [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = "voice-speaker-mic-hfp",
[SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
[SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
[SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
@@ -286,6 +307,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_OUT_VOICE_TX] = 45,
[SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
+ [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = ACDB_ID_VOICE_SPEAKER,
[SND_DEVICE_IN_HANDSET_MIC] = 4,
[SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
@@ -320,6 +342,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_IN_VOICE_DMIC] = 41,
[SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
+ [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = 11,
[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
[SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
[SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
@@ -363,6 +386,7 @@ static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_HFP)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
@@ -411,6 +435,7 @@ static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
@@ -948,7 +973,15 @@ void *platform_init(struct audio_device *adev)
ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
- adev->audio_route = audio_route_init(snd_card_num, MIXER_XML_PATH);
+ if (!strncmp(snd_card_name, "msm8226-tomtom-snd-card",
+ sizeof("msm8226-tomtom-snd-card"))) {
+ ALOGD("%s: Call MIXER_XML_PATH_WCD9330", __func__);
+ adev->audio_route = audio_route_init(snd_card_num,
+ MIXER_XML_PATH_WCD9330);
+ } else {
+ adev->audio_route = audio_route_init(snd_card_num, MIXER_XML_PATH);
+ }
+
if (!adev->audio_route) {
ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
goto init_failed;
@@ -1592,9 +1625,13 @@ int platform_set_mic_mute(void *platform, bool state)
ALL_SESSION_VSID,
DEFAULT_MUTE_RAMP_DURATION_MS};
- if (adev->mode != AUDIO_MODE_IN_CALL)
+ if (adev->mode != AUDIO_MODE_IN_CALL &&
+ adev->mode != AUDIO_MODE_IN_COMMUNICATION)
return 0;
+ if (adev->enable_hfp)
+ mixer_ctl_name = "HFP Tx Mute";
+
set_values[0] = state;
ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
if (!ctl) {
@@ -1770,7 +1807,11 @@ snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devi
snd_device = SND_DEVICE_OUT_BT_SCO;
}
} else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
- snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
+ if (!adev->enable_hfp) {
+ snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
+ } else {
+ snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_HFP;
+ }
} else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
if(adev->voice.hac)
snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
@@ -1896,7 +1937,12 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d
//select default
if (snd_device == SND_DEVICE_NONE) {
- snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+ if (!adev->enable_hfp) {
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+ } else {
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
+ platform_set_echo_reference(adev, true, out_device);
+ }
}
} else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
snd_device = SND_DEVICE_IN_VOICE_RX;
@@ -2513,3 +2559,240 @@ int platform_swap_lr_channels(struct audio_device *adev, bool swap_channels)
}
return 0;
}
+
+/* Read offload buffer size from a property.
+ * If value is not power of 2 round it to
+ * power of 2.
+ */
+uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)
+{
+ char value[PROPERTY_VALUE_MAX] = {0};
+ uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ if((property_get("audio.offload.buffer.size.kb", value, "")) &&
+ atoi(value)) {
+ fragment_size = atoi(value) * 1024;
+ }
+
+#ifdef FLAC_OFFLOAD_ENABLED
+ // For FLAC use max size since it is loss less, and has sampling rates
+ // upto 192kHZ
+ if (info != NULL && !info->has_video &&
+ info->format == AUDIO_FORMAT_FLAC) {
+ fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ ALOGV("FLAC fragment size %d", fragment_size);
+ }
+#endif
+
+ if (info != NULL && info->has_video && info->is_streaming) {
+ fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
+ ALOGV("%s: offload fragment size reduced for AV streaming to %d",
+ __func__, fragment_size);
+ }
+
+ fragment_size = ALIGN( fragment_size, 1024);
+
+ if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ ALOGV("%s: fragment_size %d", __func__, fragment_size);
+ return fragment_size;
+}
+
+#ifdef PCM_OFFLOAD_ENABLED
+uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
+{
+ uint32_t fragment_size = 0;
+ uint32_t bits_per_sample = 16;
+ uint32_t pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION;
+
+ if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) {
+ bits_per_sample = 32;
+ }
+
+ //duration is set to 40 ms worth of stereo data at 48Khz
+ //with 16 bit per sample, modify this when the channel
+ //configuration is different
+ fragment_size = (pcm_offload_time
+ * info->sample_rate
+ * (bits_per_sample >> 3)
+ * popcount(info->channel_mask))/1000;
+ // To have same PCM samples for all channels, the buffer size requires to
+ // be multiple of (number of channels * bytes per sample)
+ // For writes to succeed, the buffer must be written at address which is multiple of 32
+ // Alignment of 96 satsfies both of the above requirements
+ fragment_size = ALIGN(fragment_size, 96);
+ if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
+ else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
+
+ ALOGI("PCM offload Fragment size to %d bytes", fragment_size);
+ return fragment_size;
+}
+#endif
+
+int platform_set_codec_backend_cfg(struct audio_device* adev,
+ unsigned int bit_width, unsigned int sample_rate)
+{
+ ALOGV("%s bit width: %d, sample rate: %d", __func__, bit_width, sample_rate);
+
+ int ret = 0;
+ if (bit_width != adev->cur_codec_backend_bit_width) {
+ const char * mixer_ctl_name = "SLIM_0_RX Format";
+ struct mixer_ctl *ctl;
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer command - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ if (bit_width == 24) {
+ mixer_ctl_set_enum_by_string(ctl, "S24_LE");
+ } else {
+ mixer_ctl_set_enum_by_string(ctl, "S16_LE");
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ }
+ adev->cur_codec_backend_bit_width = bit_width;
+ ALOGE("Backend bit width is set to %d ", bit_width);
+ }
+
+ /*
+ * Backend sample rate configuration follows:
+ * 16 bit playback - 48khz for streams at any valid sample rate
+ * 24 bit playback - 48khz for stream sample rate less than 48khz
+ * 24 bit playback - 96khz for sample rate range of 48khz to 96khz
+ * 24 bit playback - 192khz for sample rate range of 96khz to 192 khz
+ * Upper limit is inclusive in the sample rate range.
+ */
+ // TODO: This has to be more dynamic based on policy file
+ if (sample_rate != adev->cur_codec_backend_samplerate) {
+ char *rate_str = NULL;
+ const char * mixer_ctl_name = "SLIM_0_RX SampleRate";
+ struct mixer_ctl *ctl;
+
+ switch (sample_rate) {
+ case 8000:
+ case 11025:
+ case 16000:
+ case 22050:
+ case 32000:
+ case 44100:
+ case 48000:
+ rate_str = "KHZ_48";
+ break;
+ case 64000:
+ case 88200:
+ case 96000:
+ rate_str = "KHZ_96";
+ break;
+ case 176400:
+ case 192000:
+ rate_str = "KHZ_192";
+ break;
+ default:
+ rate_str = "KHZ_48";
+ break;
+ }
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if(!ctl) {
+ ALOGE("%s: Could not get ctl for mixer command - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ ALOGV("Set sample rate as rate_str = %s", rate_str);
+ mixer_ctl_set_enum_by_string(ctl, rate_str);
+ adev->cur_codec_backend_samplerate = sample_rate;
+ }
+
+ return ret;
+}
+
+bool platform_check_codec_backend_cfg(struct audio_device* adev,
+ struct audio_usecase* usecase,
+ unsigned int* new_bit_width,
+ unsigned int* new_sample_rate)
+{
+ bool backend_change = false;
+ struct listnode *node;
+ struct stream_out *out = NULL;
+ unsigned int bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ unsigned int sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+
+ // For voice calls use default configuration
+ // force routing is not required here, caller will do it anyway
+ if (voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
+ ALOGW("%s:Use default bw and sr for voice/voip calls ",__func__);
+ bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ } else {
+ /*
+ * The backend should be configured at highest bit width and/or
+ * sample rate amongst all playback usecases.
+ * If the selected sample rate and/or bit width differ with
+ * current backend sample rate and/or bit width, then, we set the
+ * backend re-configuration flag.
+ *
+ * Exception: 16 bit playbacks is allowed through 16 bit/48 khz backend only
+ */
+ list_for_each(node, &adev->usecase_list) {
+ struct audio_usecase *curr_usecase;
+ curr_usecase = node_to_item(node, struct audio_usecase, list);
+ if (curr_usecase->type == PCM_PLAYBACK) {
+ struct stream_out *out =
+ (struct stream_out*) curr_usecase->stream.out;
+ if (out != NULL ) {
+ ALOGV("Offload playback running bw %d sr %d",
+ out->bit_width, out->sample_rate);
+ if (bit_width < out->bit_width)
+ bit_width = out->bit_width;
+ if (sample_rate < out->sample_rate)
+ sample_rate = out->sample_rate;
+ }
+ }
+ }
+ }
+
+ // 24 bit playback on speakers and all 16 bit playbacks is allowed through
+ // 16 bit/48 khz backend only
+ if ((16 == bit_width) ||
+ ((24 == bit_width) &&
+ (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER))) {
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ }
+ // Force routing if the expected bitwdith or samplerate
+ // is not same as current backend comfiguration
+ if ((bit_width != adev->cur_codec_backend_bit_width) ||
+ (sample_rate != adev->cur_codec_backend_samplerate)) {
+ *new_bit_width = bit_width;
+ *new_sample_rate = sample_rate;
+ backend_change = true;
+ ALOGI("%s Codec backend needs to be updated. new bit width: %d new sample rate: %d",
+ __func__, *new_bit_width, *new_sample_rate);
+ }
+
+ return backend_change;
+}
+
+bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase)
+{
+ ALOGV("platform_check_and_set_codec_backend_cfg usecase = %d",usecase->id );
+
+ unsigned int new_bit_width, old_bit_width;
+ unsigned int new_sample_rate, old_sample_rate;
+
+ new_bit_width = old_bit_width = adev->cur_codec_backend_bit_width;
+ new_sample_rate = old_sample_rate = adev->cur_codec_backend_samplerate;
+
+ ALOGW("Codec backend bitwidth %d, samplerate %d", old_bit_width, old_sample_rate);
+ if (platform_check_codec_backend_cfg(adev, usecase,
+ &new_bit_width, &new_sample_rate)) {
+ platform_set_codec_backend_cfg(adev, new_bit_width, new_sample_rate);
+ return true;
+ }
+
+ return false;
+}
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 4b4332e0..dcd763a9 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -77,6 +77,7 @@ enum {
SND_DEVICE_OUT_VOICE_TX,
SND_DEVICE_OUT_SPEAKER_PROTECTED,
SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED,
+ SND_DEVICE_OUT_VOICE_SPEAKER_HFP,
SND_DEVICE_OUT_END,
/*
@@ -118,6 +119,7 @@ enum {
SND_DEVICE_IN_VOICE_DMIC,
SND_DEVICE_IN_VOICE_DMIC_TMUS,
SND_DEVICE_IN_VOICE_SPEAKER_MIC,
+ SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP,
SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
SND_DEVICE_IN_VOICE_HEADSET_MIC,
SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC,
@@ -204,18 +206,36 @@ enum {
#define LOWLATENCY_PCM_DEVICE 15
#define VOICE_VSID 0x10C01000
+#ifdef PLATFORM_MSM8x26
+#define VOICE_CALL_PCM_DEVICE 2
+#define VOICE2_CALL_PCM_DEVICE 14
+#define VOLTE_CALL_PCM_DEVICE 17
+#define QCHAT_CALL_PCM_DEVICE 18
+#define VOWLAN_CALL_PCM_DEVICE 30
+#elif PLATFORM_MSM8084
+#define VOICE_CALL_PCM_DEVICE 20
+#define VOICE2_CALL_PCM_DEVICE 25
+#define VOLTE_CALL_PCM_DEVICE 21
+#define QCHAT_CALL_PCM_DEVICE 33
+#define VOWLAN_CALL_PCM_DEVICE -1
+#else
#define VOICE_CALL_PCM_DEVICE 2
#define VOICE2_CALL_PCM_DEVICE 22
#define VOLTE_CALL_PCM_DEVICE 14
#define QCHAT_CALL_PCM_DEVICE 20
#define VOWLAN_CALL_PCM_DEVICE 36
+#endif
#define AFE_PROXY_PLAYBACK_PCM_DEVICE 7
#define AFE_PROXY_RECORD_PCM_DEVICE 8
#define HFP_PCM_RX 5
#ifdef PLATFORM_MSM8x26
-#define HFP_SCO_RX 28
+#ifdef EXTERNAL_BT_SUPPORTED
+#define HFP_SCO_RX 10 // AUXPCM Hostless
+#else
+#define HFP_SCO_RX 28 // INT_HFP_BT Hostless
+#endif
#define HFP_ASM_RX_TX 29
#else
#define HFP_SCO_RX 23
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 1e413587..c707db18 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -17,6 +17,9 @@
#ifndef AUDIO_PLATFORM_API_H
#define AUDIO_PLATFORM_API_H
+#define CODEC_BACKEND_DEFAULT_BIT_WIDTH 16
+#define CODEC_BACKEND_DEFAULT_SAMPLE_RATE 48000
+
void *platform_init(struct audio_device *adev);
void platform_deinit(void *platform);
const char *platform_get_snd_device_name(snd_device_t snd_device);
@@ -84,4 +87,11 @@ bool platform_check_backends_match(snd_device_t snd_device1, snd_device_t snd_de
int platform_set_parameters(void *platform, struct str_parms *parms);
+struct audio_offload_info_t;
+uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info);
+#ifdef PCM_OFFLOAD_ENABLED
+uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info);
+#endif
+
+bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase);
#endif // AUDIO_PLATFORM_API_H
diff --git a/hal/voice.c b/hal/voice.c
index a33305d3..d2215b61 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -350,7 +350,8 @@ int voice_set_mic_mute(struct audio_device *adev, bool state)
int err = 0;
adev->voice.mic_mute = state;
- if (adev->mode == AUDIO_MODE_IN_CALL)
+ if (adev->mode == AUDIO_MODE_IN_CALL ||
+ adev->mode == AUDIO_MODE_IN_COMMUNICATION)
err = platform_set_mic_mute(adev->platform, state);
return err;