diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 076a4692..2f8ce97e 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -312,6 +312,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_OUT_HDMI] = "hdmi", [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi", [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset", + [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb", /* Capture sound devices */ [SND_DEVICE_IN_EARPIECE_MIC] = "earpiece-mic", @@ -329,6 +330,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_IN_VOICE_HEADSET_MIC_WB] = "voice-headset-mic-wb", [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic", [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic", + [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb", [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic", [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "voice-rec-headset-mic", [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic", @@ -531,6 +533,8 @@ static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devic if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) { snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES; + } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) { + snd_device = SND_DEVICE_OUT_BT_SCO; } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) { snd_device = SND_DEVICE_OUT_VOICE_SPEAKER; } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) { @@ -541,6 +545,8 @@ static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devic if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) { snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES_WB; + } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) { + snd_device = SND_DEVICE_OUT_BT_SCO_WB; } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) { snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_WB; } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) { @@ -548,10 +554,6 @@ static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devic } } - if (devices & AUDIO_DEVICE_OUT_ALL_SCO) { - snd_device = SND_DEVICE_OUT_BT_SCO; - } - if (snd_device != SND_DEVICE_NONE) { goto exit; } @@ -660,7 +662,11 @@ static snd_device_t get_input_snd_device(struct audio_device *adev, audio_device snd_device = SND_DEVICE_IN_VOICE_MIC; if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) { - snd_device = SND_DEVICE_IN_BT_SCO_MIC; + if (voice_session_uses_wideband(adev->voice.session)) { + snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB; + } else { + snd_device = SND_DEVICE_IN_BT_SCO_MIC; + } } else if (voice_session_uses_twomic(adev->voice.session)) { snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC; } diff --git a/audio/audio_hw.h b/audio/audio_hw.h index ca90fef3..3bafff21 100644 --- a/audio/audio_hw.h +++ b/audio/audio_hw.h @@ -76,6 +76,7 @@ enum { SND_DEVICE_OUT_HDMI, SND_DEVICE_OUT_SPEAKER_AND_HDMI, SND_DEVICE_OUT_BT_SCO, + SND_DEVICE_OUT_BT_SCO_WB, SND_DEVICE_OUT_END, /* @@ -99,6 +100,7 @@ enum { SND_DEVICE_IN_VOICE_HEADSET_MIC_WB, SND_DEVICE_IN_HDMI_MIC, SND_DEVICE_IN_BT_SCO_MIC, + SND_DEVICE_IN_BT_SCO_MIC_WB, SND_DEVICE_IN_CAMCORDER_MIC, SND_DEVICE_IN_VOICE_REC_HEADSET_MIC, SND_DEVICE_IN_VOICE_REC_MIC, @@ -131,6 +133,7 @@ enum { #define SCO_PERIOD_COUNT 2 #define SCO_DEFAULT_CHANNEL_COUNT 2 #define SCO_DEFAULT_SAMPLING_RATE 8000 +#define SCO_WB_SAMPLING_RATE 16000 #define SCO_START_THRESHOLD 335 #define SCO_STOP_THRESHOLD 336 #define SCO_AVAILABLE_MIN 1 diff --git a/audio/mixer_paths_0.xml.template b/audio/mixer_paths_0.xml.template index 7753896c..4db95404 100644 --- a/audio/mixer_paths_0.xml.template +++ b/audio/mixer_paths_0.xml.template @@ -68,6 +68,10 @@ + + + + @@ -124,6 +128,10 @@ + + + + diff --git a/audio/voice.c b/audio/voice.c index 824724a0..ce981c5a 100644 --- a/audio/voice.c +++ b/audio/voice.c @@ -62,6 +62,15 @@ struct pcm_config pcm_config_voice_sco = { .format = PCM_FORMAT_S16_LE, }; +/* SCO WB and NB uses 8kHz for now, 16kHz it's on TO DO*/ +struct pcm_config pcm_config_voice_sco_wb = { + .channels = 1, + .rate = SCO_DEFAULT_SAMPLING_RATE, + .period_size = SCO_PERIOD_SIZE, + .period_count = SCO_PERIOD_COUNT, + .format = PCM_FORMAT_S16_LE, +}; + /* Prototypes */ int start_voice_call(struct audio_device *adev); int stop_voice_call(struct audio_device *adev); @@ -150,6 +159,8 @@ static void stop_voice_session_bt_sco(struct voice_session *session) { /* must be called with the hw device mutex locked, OK to hold other mutexes */ void start_voice_session_bt_sco(struct voice_session *session) { + struct pcm_config *voice_sco_config; + if (session->pcm_sco_rx != NULL || session->pcm_sco_tx != NULL) { ALOGW("%s: SCO PCMs already open!\n", __func__); return; @@ -157,12 +168,18 @@ void start_voice_session_bt_sco(struct voice_session *session) ALOGV("%s: Opening SCO PCMs", __func__); - /* TODO: Add wideband support */ + if (session->wb_amr_type >= 1) { + ALOGV("%s: pcm_config wideband", __func__); + voice_sco_config = &pcm_config_voice_sco_wb; + } else { + ALOGV("%s: pcm_config narrowband", __func__); + voice_sco_config = &pcm_config_voice_sco; + } session->pcm_sco_rx = pcm_open(SOUND_CARD, SOUND_PLAYBACK_SCO_DEVICE, PCM_OUT|PCM_MONOTONIC, - &pcm_config_voice_sco); + voice_sco_config); if (session->pcm_sco_rx != NULL && !pcm_is_ready(session->pcm_sco_rx)) { ALOGE("%s: cannot open PCM SCO RX stream: %s", __func__, pcm_get_error(session->pcm_sco_rx)); @@ -172,7 +189,7 @@ void start_voice_session_bt_sco(struct voice_session *session) session->pcm_sco_tx = pcm_open(SOUND_CARD, SOUND_CAPTURE_SCO_DEVICE, PCM_IN|PCM_MONOTONIC, - &pcm_config_voice_sco); + voice_sco_config); if (session->pcm_sco_tx && !pcm_is_ready(session->pcm_sco_tx)) { ALOGE("%s: cannot open PCM SCO TX stream: %s", __func__, pcm_get_error(session->pcm_sco_tx));