Merge "hal: add incall music delivery feature"
diff --git a/hal/Android.mk b/hal/Android.mk
index cc6b62e..be67ba0 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -43,6 +43,10 @@
LOCAL_CFLAGS += -DAFE_PROXY_ENABLED
endif
+ifneq ($(strip $(AUDIO_FEATURE_DISABLED_INCALL_MUSIC)),true)
+LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
+endif
+
ifneq ($(strip $(AUDIO_FEATURE_DISABLED_FM)),true)
LOCAL_CFLAGS += -DFM_ENABLED
LOCAL_SRC_FILES += audio_extn/fm.c
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 1bcb25a..aa7e6a6 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -114,6 +114,8 @@
[USECASE_INCALL_REC_UPLINK] = "incall-rec-uplink",
[USECASE_INCALL_REC_DOWNLINK] = "incall-rec-downlink",
[USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = "incall-rec-uplink-and-downlink",
+ [USECASE_INCALL_MUSIC_UPLINK] = "incall_music_uplink",
+ [USECASE_INCALL_MUSIC_UPLINK2] = "incall_music_uplink2",
};
@@ -1925,6 +1927,13 @@
ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
__func__, config->offload_info.version,
config->offload_info.bit_rate);
+ } else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) {
+ ret = voice_check_and_set_incall_music_usecase(adev, out);
+ if (ret != 0) {
+ ALOGE("%s: Incall music delivery usecase cannot be set error:%d",
+ __func__, ret);
+ goto error_open;
+ }
} else {
out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
out->config = pcm_config_low_latency;
@@ -2146,6 +2155,7 @@
struct audio_device *adev = (struct audio_device *)dev;
pthread_mutex_lock(&adev->lock);
if (adev->mode != mode) {
+ ALOGD("%s mode %d\n", __func__, mode);
adev->mode = mode;
}
pthread_mutex_unlock(&adev->lock);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index c43b557..965ac62 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -78,6 +78,9 @@
USECASE_INCALL_REC_DOWNLINK,
USECASE_INCALL_REC_UPLINK_AND_DOWNLINK,
+ USECASE_INCALL_MUSIC_UPLINK,
+ USECASE_INCALL_MUSIC_UPLINK2,
+
AUDIO_USECASE_MAX
} audio_usecase_t;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 134fdbb..1734ced 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -113,6 +113,10 @@
AUDIO_RECORD_PCM_DEVICE},
[USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
AUDIO_RECORD_PCM_DEVICE},
+ [USECASE_INCALL_MUSIC_UPLINK] = {INCALL_MUSIC_UPLINK_PCM_DEVICE,
+ INCALL_MUSIC_UPLINK_PCM_DEVICE},
+ [USECASE_INCALL_MUSIC_UPLINK2] = {INCALL_MUSIC_UPLINK2_PCM_DEVICE,
+ INCALL_MUSIC_UPLINK2_PCM_DEVICE},
};
/* Array to store sound devices */
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index fe55f1b..9212307 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -150,6 +150,8 @@
#define VOICE_CALL_PCM_DEVICE 2
#define FM_PLAYBACK_PCM_DEVICE 5
#define FM_CAPTURE_PCM_DEVICE 6
+#define INCALL_MUSIC_UPLINK_PCM_DEVICE 1
+#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 16
#ifdef PLATFORM_MSM8x26
#define VOICE2_CALL_PCM_DEVICE 14
diff --git a/hal/voice.c b/hal/voice.c
index 190df7c..39e2dd9 100755
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -249,6 +249,20 @@
return ret;
}
+int voice_check_and_set_incall_music_usecase(struct audio_device *adev,
+ struct stream_out *out)
+{
+ int ret = 0;
+
+ ret = voice_extn_check_and_set_incall_music_usecase(adev, out);
+ if (ret == -ENOSYS) {
+ /* Incall music delivery is used only for LCH call state */
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
int voice_set_mic_mute(struct audio_device *adev, bool state)
{
int err = 0;
diff --git a/hal/voice.h b/hal/voice.h
index d5e5a8d..7f8b25b 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -38,6 +38,7 @@
struct audio_device;
struct str_parms;
struct stream_in;
+struct stream_out;
struct call_state {
int current;
@@ -67,5 +68,7 @@
bool voice_get_mic_mute(struct audio_device *dev);
int voice_set_volume(struct audio_device *adev, float volume);
int voice_check_and_set_incall_rec_usecase(struct audio_device *adev,
- struct stream_in *in);
+ struct stream_in *in);
+int voice_check_and_set_incall_music_usecase(struct audio_device *adev,
+ struct stream_out *out);
#endif //VOICE_H
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 29f12d4..903d2aa 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -17,8 +17,6 @@
* limitations under the License.
*/
-#ifdef MULTI_VOICE_SESSION_ENABLED
-
#define LOG_TAG "voice_extn"
/*#define LOG_NDEBUG 0*/
#define LOG_NDDEBUG 0
@@ -52,6 +50,17 @@
#define CALL_HOLD (BASE_CALL_STATE + 2)
#define CALL_LOCAL_HOLD (BASE_CALL_STATE + 3)
+struct pcm_config pcm_config_incall_music = {
+ .channels = 1,
+ .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
+ .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE,
+ .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT,
+ .format = PCM_FORMAT_S16_LE,
+ .start_threshold = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
+ .stop_threshold = INT_MAX,
+ .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
+};
+
extern int start_call(struct audio_device *adev, audio_usecase_t usecase_id);
extern int stop_call(struct audio_device *adev, audio_usecase_t usecase_id);
int voice_extn_update_calls(struct audio_device *adev);
@@ -103,21 +112,28 @@
return usecase_id;
}
-int voice_extn_get_active_session_id(struct audio_device *adev,
- uint32_t *session_id)
+static uint32_t get_session_id_with_state(struct audio_device *adev,
+ int call_state)
{
struct voice_session *session = NULL;
int i = 0;
- *session_id = 0;
+ uint32_t session_id = 0;
for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
session = &adev->voice.session[i];
- if(session->state.current == CALL_ACTIVE){
- *session_id = session->vsid;
+ if(session->state.current == call_state){
+ session_id = session->vsid;
break;
}
}
+ return session_id;
+}
+
+int voice_extn_get_active_session_id(struct audio_device *adev,
+ uint32_t *session_id)
+{
+ *session_id = get_session_id_with_state(adev, CALL_ACTIVE);
return 0;
}
@@ -155,6 +171,7 @@
if (session) {
session->state.new = call_state;
voice_extn_is_in_call(adev, &is_in_call);
+ ALOGD("%s is_in_call:%d mode:%d\n", __func__, is_in_call, adev->mode);
if (is_in_call || adev->mode == AUDIO_MODE_IN_CALL) {
/* Device routing is not triggered for voice calls on the subsequent
* subs, Hence update the call states if voice call is already
@@ -224,7 +241,7 @@
for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
usecase_id = voice_extn_get_usecase_for_session_idx(i);
session = &adev->voice.session[i];
- ALOGV("%s: cur_state=%d new_state=%d vsid=%x",
+ ALOGD("%s: cur_state=%d new_state=%d vsid=%x",
__func__, session->state.current, session->state.new, session->vsid);
switch(session->state.new)
@@ -233,7 +250,7 @@
switch(session->state.current)
{
case CALL_INACTIVE:
- ALOGD("%s: INACTIVE ->ACTIVE vsid:%x", __func__, session->vsid);
+ ALOGD("%s: INACTIVE -> ACTIVE vsid:%x", __func__, session->vsid);
ret = start_call(adev, usecase_id);
if(ret < 0) {
ALOGE("%s: voice_start_call() failed for usecase: %d\n",
@@ -243,15 +260,15 @@
break;
case CALL_HOLD:
- ALOGD("%s: HOLD ->ACTIVE vsid:%x", __func__, session->vsid);
+ ALOGD("%s: HOLD -> ACTIVE vsid:%x", __func__, session->vsid);
session->state.current = session->state.new;
break;
case CALL_LOCAL_HOLD:
- ALOGD("%s: LOCAL_HOLD ->ACTIVE vsid:%x", __func__, session->vsid);
+ ALOGD("%s: LOCAL_HOLD -> ACTIVE vsid:%x", __func__, session->vsid);
lch_mode = VOICE_LCH_STOP;
if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) {
- ALOGE("LOCAL_HOLD ->ACTIVE failed");
+ ALOGE("LOCAL_HOLD -> ACTIVE failed");
} else {
session->state.current = session->state.new;
}
@@ -270,7 +287,7 @@
case CALL_ACTIVE:
case CALL_HOLD:
case CALL_LOCAL_HOLD:
- ALOGD("%s: ACTIVE/HOLD/LOCAL_HOLD ->INACTIVE vsid:%x", __func__, session->vsid);
+ ALOGD("%s: ACTIVE/HOLD/LOCAL_HOLD -> INACTIVE vsid:%x", __func__, session->vsid);
ret = stop_call(adev, usecase_id);
if(ret < 0) {
ALOGE("%s: voice_end_call() failed for usecase: %d\n",
@@ -290,15 +307,15 @@
switch(session->state.current)
{
case CALL_ACTIVE:
- ALOGD("%s: CALL_ACTIVE ->HOLD vsid:%x", __func__, session->vsid);
+ ALOGD("%s: CALL_ACTIVE -> HOLD vsid:%x", __func__, session->vsid);
session->state.current = session->state.new;
break;
case CALL_LOCAL_HOLD:
- ALOGD("%s: CALL_LOCAL_HOLD ->HOLD vsid:%x", __func__, session->vsid);
+ ALOGD("%s: CALL_LOCAL_HOLD -> HOLD vsid:%x", __func__, session->vsid);
lch_mode = VOICE_LCH_STOP;
if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) {
- ALOGE("LOCAL_HOLD ->HOLD failed");
+ ALOGE("LOCAL_HOLD -> HOLD failed");
} else {
session->state.current = session->state.new;
}
@@ -316,10 +333,11 @@
{
case CALL_ACTIVE:
case CALL_HOLD:
- ALOGD("%s: ACTIVE/CALL_HOLD ->LOCAL_HOLD vsid:%x", __func__, session->vsid);
+ ALOGD("%s: ACTIVE/CALL_HOLD -> LOCAL_HOLD vsid:%x", __func__,
+ session->vsid);
lch_mode = VOICE_LCH_START;
if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) {
- ALOGE("LOCAL_HOLD ->HOLD failed");
+ ALOGE("LOCAL_HOLD -> HOLD failed");
} else {
session->state.current = session->state.new;
}
@@ -382,4 +400,25 @@
return ret;
}
-#endif
+int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
+ struct stream_out *out)
+{
+ uint32_t session_id = 0;
+
+ session_id = get_session_id_with_state(adev, CALL_LOCAL_HOLD);
+ if (session_id == VOICE_VSID) {
+ out->usecase = USECASE_INCALL_MUSIC_UPLINK;
+ } else if (session_id == VOICE2_VSID) {
+ out->usecase = USECASE_INCALL_MUSIC_UPLINK2;
+ } else {
+ ALOGE("%s: Invalid session id %x", __func__, session_id);
+ return -EINVAL;
+ }
+
+ out->config = pcm_config_incall_music;
+ out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
+ out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
+
+ return 0;
+}
+
diff --git a/hal/voice_extn/voice_extn.h b/hal/voice_extn/voice_extn.h
index 568f716..a8efef1 100644
--- a/hal/voice_extn/voice_extn.h
+++ b/hal/voice_extn/voice_extn.h
@@ -20,6 +20,7 @@
#ifndef VOICE_EXTN_H
#define VOICE_EXTN_H
+#ifdef MULTI_VOICE_SESSION_ENABLED
int voice_extn_update_calls(struct audio_device *adev);
int voice_extn_get_session_from_use_case(struct audio_device *adev,
const audio_usecase_t usecase_id,
@@ -30,37 +31,48 @@
int voice_extn_is_in_call(struct audio_device *adev, bool *in_call);
int voice_extn_get_active_session_id(struct audio_device *adev,
uint32_t *session_id);
-
-#ifndef MULTI_VOICE_SESSION_ENABLED
-int voice_extn_update_calls(struct audio_device *adev)
+#else
+static int voice_extn_update_calls(struct audio_device *adev)
{
return -ENOSYS;
}
-int voice_extn_get_session_from_use_case(struct audio_device *adev,
- const audio_usecase_t usecase_id,
- struct voice_session **session)
+static int voice_extn_get_session_from_use_case(struct audio_device *adev,
+ const audio_usecase_t usecase_id,
+ struct voice_session **session)
{
return -ENOSYS;
}
-int voice_extn_init(struct audio_device *adev)
+static int voice_extn_init(struct audio_device *adev)
{
return -ENOSYS;
}
-int voice_extn_set_parameters(struct audio_device *adev,
- struct str_parms *parms)
+static int voice_extn_set_parameters(struct audio_device *adev,
+ struct str_parms *parms)
{
return -ENOSYS;
}
-int voice_extn_is_in_call(struct audio_device *adev, bool *in_call)
+static int voice_extn_is_in_call(struct audio_device *adev, bool *in_call)
{
return -ENOSYS;
}
-int voice_extn_get_active_session_id(struct audio_device *adev,
- uint32_t *session_id)
+
+static int voice_extn_get_active_session_id(struct audio_device *adev,
+ uint32_t *session_id)
+{
+ return -ENOSYS;
+}
+#endif
+
+#if defined INCALL_MUSIC_ENABLED && defined MULTI_VOICE_SESSION_ENABLED
+int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
+ struct stream_out *out);
+#else
+static int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
+ struct stream_out *out)
{
return -ENOSYS;
}