summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstenkinevgeniy <stenkinevgeniy@gmail.com>2018-07-09 11:20:36 +0000
committerSimon Shields <simon@lineageos.org>2018-07-25 09:40:56 +0200
commita14d5e7792fe98019da330d04d83117e0ae2ca87 (patch)
treef58a24cb15822ecdc4a261b42b5ae814eda35e69
parenta0d53a0fd60028b86723a81eb23a26d2b30157d3 (diff)
downloadandroid_hardware_samsung-a14d5e7792fe98019da330d04d83117e0ae2ca87.tar.gz
android_hardware_samsung-a14d5e7792fe98019da330d04d83117e0ae2ca87.tar.bz2
android_hardware_samsung-a14d5e7792fe98019da330d04d83117e0ae2ca87.zip
Audio: fix voip calls over bluetooth headset.
Current HAL start/stop bt_sco session only for incall mode - rewrite logic to start/stop bt session when system switch to one of the bluetooth devices. Move bt_sco_active and pcm_sco_rx/tx to main audio_device structure. Remove bt_sco_capture profile. Change-Id: I7bbe4273f759e255bb857f8292f2921df31d4b0b Signed-off-by: stenkinevgeniy <stenkinevgeniy@gmail.com>
-rw-r--r--audio/audio_hw.c55
-rw-r--r--audio/audio_hw.h4
-rw-r--r--audio/voice.c56
-rw-r--r--audio/voice.h6
4 files changed, 47 insertions, 74 deletions
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 395cb34..d28dc30 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -72,9 +72,7 @@ static struct pcm_device_profile pcm_device_playback = {
.id = SOUND_PLAYBACK_DEVICE,
.type = PCM_PLAYBACK,
.devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
- AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO|AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET|
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
+ AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_ALL_SCO,
};
static struct pcm_device_profile pcm_device_deep_buffer = {
@@ -92,9 +90,7 @@ static struct pcm_device_profile pcm_device_deep_buffer = {
.id = SOUND_DEEP_BUFFER_DEVICE,
.type = PCM_PLAYBACK,
.devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
- AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO|AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET|
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
+ AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_ALL_SCO,
};
static struct pcm_device_profile pcm_device_capture = {
@@ -112,7 +108,7 @@ static struct pcm_device_profile pcm_device_capture = {
.card = SOUND_CARD,
.id = SOUND_CAPTURE_DEVICE,
.type = PCM_CAPTURE,
- .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
+ .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
};
static struct pcm_device_profile pcm_device_capture_low_latency = {
@@ -130,32 +126,13 @@ static struct pcm_device_profile pcm_device_capture_low_latency = {
.card = SOUND_CARD,
.id = SOUND_CAPTURE_DEVICE,
.type = PCM_CAPTURE_LOW_LATENCY,
- .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
-};
-
-static struct pcm_device_profile pcm_device_capture_sco = {
- .config = {
- .channels = SCO_DEFAULT_CHANNEL_COUNT,
- .rate = SCO_DEFAULT_SAMPLING_RATE,
- .period_size = SCO_PERIOD_SIZE,
- .period_count = SCO_PERIOD_COUNT,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = CAPTURE_START_THRESHOLD,
- .stop_threshold = 0,
- .silence_threshold = 0,
- .avail_min = 0,
- },
- .card = SOUND_CARD,
- .id = SOUND_CAPTURE_SCO_DEVICE,
- .type = PCM_CAPTURE,
- .devices = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
+ .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
};
static struct pcm_device_profile * const pcm_devices[] = {
&pcm_device_playback,
&pcm_device_capture,
&pcm_device_capture_low_latency,
- &pcm_device_capture_sco,
NULL,
};
@@ -2669,11 +2646,6 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
}
#endif
if (val != SND_DEVICE_NONE) {
- bool bt_sco_active = false;
-
- if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
- bt_sco_active = true;
- }
out->devices = val;
if (!out->standby) {
@@ -2700,17 +2672,23 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
}
}
+ /* Turn on bluetooth sco if needed */
+ if ((adev->mode == AUDIO_MODE_IN_COMMUNICATION || adev->mode == AUDIO_MODE_IN_CALL) &&
+ (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !adev->bt_sco_active) {
+ adev->bt_sco_active = true;
+ start_voice_session_bt_sco(adev);
+ }
+ else if (!(out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && adev->bt_sco_active) {
+ adev->bt_sco_active = false;
+ stop_voice_session_bt_sco(adev);
+ }
+
if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
(out == adev->primary_output)) {
start_voice_call(adev);
} else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
adev->voice.in_call &&
(out == adev->primary_output)) {
- /* Turn on bluetooth if needed */
- if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
- select_devices(adev, USECASE_VOICE_CALL);
- start_voice_session_bt_sco(adev->voice.session);
- } else {
/*
* When we select different devices we need to restart the
* voice call. The modem closes the stream on its end and
@@ -2718,7 +2696,6 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
*/
stop_voice_call(adev);
start_voice_call(adev);
- }
}
}
@@ -4262,6 +4239,8 @@ static int adev_open(const hw_module_t *module, const char *name,
adev->voice.in_call = false;
adev->voice.bluetooth_wb = false;
+ adev->bt_sco_active = false;
+
/* adev->cur_hdmi_channels = 0; by calloc() */
adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
if (adev->snd_dev_ref_cnt == NULL) {
diff --git a/audio/audio_hw.h b/audio/audio_hw.h
index 871c04f..7143d55 100644
--- a/audio/audio_hw.h
+++ b/audio/audio_hw.h
@@ -381,6 +381,10 @@ struct audio_device {
bool mic_mute;
bool screen_off;
+ bool bt_sco_active;
+ struct pcm *pcm_sco_rx;
+ struct pcm *pcm_sco_tx;
+
struct voice_data voice;
int* snd_dev_ref_cnt;
diff --git a/audio/voice.c b/audio/voice.c
index a4cc03a..2219d9a 100644
--- a/audio/voice.c
+++ b/audio/voice.c
@@ -139,35 +139,35 @@ void prepare_voice_session(struct voice_session *session,
* This must be called with the hw device mutex locked, OK to hold other
* mutexes.
*/
-static void stop_voice_session_bt_sco(struct voice_session *session) {
+void stop_voice_session_bt_sco(struct audio_device *adev) {
ALOGV("%s: Closing SCO PCMs", __func__);
- if (session->pcm_sco_rx != NULL) {
- pcm_stop(session->pcm_sco_rx);
- pcm_close(session->pcm_sco_rx);
- session->pcm_sco_rx = NULL;
+ if (adev->pcm_sco_rx != NULL) {
+ pcm_stop(adev->pcm_sco_rx);
+ pcm_close(adev->pcm_sco_rx);
+ adev->pcm_sco_rx = NULL;
}
- if (session->pcm_sco_tx != NULL) {
- pcm_stop(session->pcm_sco_tx);
- pcm_close(session->pcm_sco_tx);
- session->pcm_sco_tx = NULL;
+ if (adev->pcm_sco_tx != NULL) {
+ pcm_stop(adev->pcm_sco_tx);
+ pcm_close(adev->pcm_sco_tx);
+ adev->pcm_sco_tx = NULL;
}
}
/* must be called with the hw device mutex locked, OK to hold other mutexes */
-void start_voice_session_bt_sco(struct voice_session *session)
+void start_voice_session_bt_sco(struct audio_device *adev)
{
struct pcm_config *voice_sco_config;
- if (session->pcm_sco_rx != NULL || session->pcm_sco_tx != NULL) {
+ if (adev->pcm_sco_rx != NULL || adev->pcm_sco_tx != NULL) {
ALOGW("%s: SCO PCMs already open!\n", __func__);
return;
}
ALOGV("%s: Opening SCO PCMs", __func__);
- if (session->vdata->bluetooth_wb) {
+ if (adev->voice.bluetooth_wb) {
ALOGV("%s: pcm_config wideband", __func__);
voice_sco_config = &pcm_config_voice_sco_wb;
} else {
@@ -175,37 +175,37 @@ void start_voice_session_bt_sco(struct voice_session *session)
voice_sco_config = &pcm_config_voice_sco;
}
- session->pcm_sco_rx = pcm_open(SOUND_CARD,
+ adev->pcm_sco_rx = pcm_open(SOUND_CARD,
SOUND_PLAYBACK_SCO_DEVICE,
PCM_OUT|PCM_MONOTONIC,
voice_sco_config);
- if (session->pcm_sco_rx != NULL && !pcm_is_ready(session->pcm_sco_rx)) {
+ if (adev->pcm_sco_rx != NULL && !pcm_is_ready(adev->pcm_sco_rx)) {
ALOGE("%s: cannot open PCM SCO RX stream: %s",
- __func__, pcm_get_error(session->pcm_sco_rx));
+ __func__, pcm_get_error(adev->pcm_sco_rx));
goto err_sco_rx;
}
- session->pcm_sco_tx = pcm_open(SOUND_CARD,
+ adev->pcm_sco_tx = pcm_open(SOUND_CARD,
SOUND_CAPTURE_SCO_DEVICE,
PCM_IN|PCM_MONOTONIC,
voice_sco_config);
- if (session->pcm_sco_tx && !pcm_is_ready(session->pcm_sco_tx)) {
+ if (adev->pcm_sco_tx && !pcm_is_ready(adev->pcm_sco_tx)) {
ALOGE("%s: cannot open PCM SCO TX stream: %s",
- __func__, pcm_get_error(session->pcm_sco_tx));
+ __func__, pcm_get_error(adev->pcm_sco_tx));
goto err_sco_tx;
}
- pcm_start(session->pcm_sco_rx);
- pcm_start(session->pcm_sco_tx);
+ pcm_start(adev->pcm_sco_rx);
+ pcm_start(adev->pcm_sco_tx);
return;
err_sco_tx:
- pcm_close(session->pcm_sco_tx);
- session->pcm_sco_tx = NULL;
+ pcm_close(adev->pcm_sco_tx);
+ adev->pcm_sco_tx = NULL;
err_sco_rx:
- pcm_close(session->pcm_sco_rx);
- session->pcm_sco_rx = NULL;
+ pcm_close(adev->pcm_sco_rx);
+ adev->pcm_sco_rx = NULL;
}
/*
* This function must be called with hw device mutex locked, OK to hold other
@@ -265,10 +265,6 @@ int start_voice_session(struct voice_session *session)
pcm_start(session->pcm_voice_rx);
pcm_start(session->pcm_voice_tx);
- if (session->out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
- start_voice_session_bt_sco(session);
- }
-
#ifdef AUDIENCE_EARSMART_IC
ALOGV("%s: Enabling Audience IC", __func__);
es_start_voice_session(session);
@@ -311,10 +307,6 @@ void stop_voice_session(struct voice_session *session)
status++;
}
- if (session->out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
- stop_voice_session_bt_sco(session);
- }
-
#ifdef AUDIENCE_EARSMART_IC
ALOGV("%s: Disabling Audience IC", __func__);
es_stop_voice_session();
diff --git a/audio/voice.h b/audio/voice.h
index 01c6aac..c5cc2f5 100644
--- a/audio/voice.h
+++ b/audio/voice.h
@@ -25,9 +25,6 @@ struct voice_session {
struct pcm *pcm_voice_rx;
struct pcm *pcm_voice_tx;
- struct pcm *pcm_sco_rx;
- struct pcm *pcm_sco_tx;
-
int wb_amr_type;
bool two_mic_control;
bool two_mic_disabled;
@@ -47,7 +44,8 @@ void set_voice_session_volume(struct voice_session *session, float volume);
void set_voice_session_audio_path(struct voice_session *session);
void set_voice_session_mic_mute(struct voice_session *session, bool state);
-void start_voice_session_bt_sco(struct voice_session *session);
+void start_voice_session_bt_sco(struct audio_device *adev);
+void stop_voice_session_bt_sco(struct audio_device *adev);
bool voice_session_uses_twomic(struct voice_session *session);
bool voice_session_uses_wideband(struct voice_session *session);