diff options
author | Sangchul Lee <sc11.lee@samsung.com> | 2017-08-01 13:46:47 +0900 |
---|---|---|
committer | Sangchul Lee <sc11.lee@samsung.com> | 2017-08-02 15:45:33 +0900 |
commit | 29a0292e6d46b758703a53d96e406469e41491e6 (patch) | |
tree | 9c4f62b74d9faa7772d51155ad15d04dab16f834 | |
parent | e3024a012d89846c4dc8369ffb2f27f643524803 (diff) | |
download | audio-hal-wm1831-tw2-29a0292e6d46b758703a53d96e406469e41491e6.tar.gz audio-hal-wm1831-tw2-29a0292e6d46b758703a53d96e406469e41491e6.tar.bz2 audio-hal-wm1831-tw2-29a0292e6d46b758703a53d96e406469e41491e6.zip |
Support voice-recognition with BT SCO
Open/close hw:0,2 for this case.
Refer to bt_wideband to set param of samplerate(narrowband:8k, wideband:16k).
Remove unused codes.
[Version] 0.1.3
[Profile] Wearable
[Issue Type] New feature
Change-Id: Id7bca9b4e1ed01e8cb529323b3a01c6a16879b59
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
-rw-r--r-- | packaging/audio-hal-wm1831-tw2.spec | 2 | ||||
-rw-r--r-- | tizen-audio-impl-pcm.c | 188 | ||||
-rw-r--r-- | tizen-audio-impl.h | 8 | ||||
-rw-r--r-- | tizen-audio-internal.h | 20 | ||||
-rw-r--r-- | tizen-audio-pcm.c | 18 | ||||
-rw-r--r-- | tizen-audio-routing.c | 92 |
6 files changed, 230 insertions, 98 deletions
diff --git a/packaging/audio-hal-wm1831-tw2.spec b/packaging/audio-hal-wm1831-tw2.spec index 2fd151c..bdc00a7 100644 --- a/packaging/audio-hal-wm1831-tw2.spec +++ b/packaging/audio-hal-wm1831-tw2.spec @@ -1,6 +1,6 @@ Name: audio-hal-wm1831-tw2 Summary: TIZEN Audio HAL for WM1831(TW2) -Version: 0.1.2 +Version: 0.1.3 Release: 0 Group: System/Libraries License: Apache-2.0 diff --git a/tizen-audio-impl-pcm.c b/tizen-audio-impl-pcm.c index 908576e..9623af0 100644 --- a/tizen-audio-impl-pcm.c +++ b/tizen-audio-impl-pcm.c @@ -58,9 +58,6 @@ static const uint32_t g_format_convert_table[] = { }; #endif -#define VOICE_PCM_SAMPLERATE 48000 -#define VOICE_PCM_CHANNELS 2 - static uint32_t __convert_format(audio_sample_format_t format) { return g_format_convert_table[format]; @@ -68,7 +65,7 @@ static uint32_t __convert_format(audio_sample_format_t format) /* #define DEBUG_TIMING */ -static int __voice_pcm_set_params(audio_hal_t *ah, snd_pcm_t *pcm) +static int __pcm_device_set_params(audio_hal_t *ah, snd_pcm_t *pcm, uint32_t samplerate, uint32_t channels) { snd_pcm_hw_params_t *params = NULL; int err = 0; @@ -97,12 +94,12 @@ static int __voice_pcm_set_params(audio_hal_t *ah, snd_pcm_t *pcm) AUDIO_LOG_ERROR("snd_pcm_hw_params_set_access() : failed! - %s\n", snd_strerror(err)); goto error; } - err = snd_pcm_hw_params_set_rate(pcm, params, VOICE_PCM_SAMPLERATE, 0); + err = snd_pcm_hw_params_set_rate(pcm, params, samplerate, 0); if (err < 0) { AUDIO_LOG_ERROR("snd_pcm_hw_params_set_rate() : failed! - %s\n", snd_strerror(err)); goto error; } - err = snd_pcm_hw_params_set_channels(pcm, params, VOICE_PCM_CHANNELS); + err = snd_pcm_hw_params_set_channels(pcm, params, channels); if (err < 0) { AUDIO_LOG_ERROR("snd_pcm_hw_params_set_channels() : failed! - %s\n", snd_strerror(err)); goto error; @@ -192,7 +189,7 @@ static int __tinyalsa_pcm_recover(struct pcm *pcm, int err) } #endif -audio_return_t _voice_pcm_open(audio_hal_t *ah) +static audio_return_t __pcm_device_open(audio_hal_t *ah, audio_pcm_devices_t *pcm_devices, const char *device, uint32_t direction, uint32_t samplerate, uint32_t channels) { int err, ret = 0; @@ -202,62 +199,96 @@ audio_return_t _voice_pcm_open(audio_hal_t *ah) AUDIO_LOG_WARN("need implementation for tinyAlsa"); return AUDIO_ERR_NOT_IMPLEMENTED; #else - AUDIO_LOG_INFO("Setup Voice DAIs"); - - /* Voice Capture DAI */ - if ((err = snd_pcm_open((snd_pcm_t **)&ah->device.pcm_in, VOICE_PCM_DEVICE, SND_PCM_STREAM_CAPTURE, 0)) < 0) { - AUDIO_LOG_ERROR("snd_pcm_open for %s failed. %s", VOICE_PCM_DEVICE, snd_strerror(err)); - ret = AUDIO_ERR_IOCTL; - goto error; - } - ret = __voice_pcm_set_params(ah, ah->device.pcm_in); - if (ret != 0) { - AUDIO_LOG_ERROR("voice capture DAI(%s, %p) setparam failure", VOICE_PCM_DEVICE, ah->device.pcm_in); - ret = AUDIO_ERR_INTERNAL; - goto error; + AUDIO_LOG_INFO("Setup DAI PCM"); + + if (direction & AUDIO_DEVICE_DIRECTION_IN) { + /* Capture PCM */ + if ((err = snd_pcm_open((snd_pcm_t **)&pcm_devices->in, device, SND_PCM_STREAM_CAPTURE, 0)) < 0) { + AUDIO_LOG_ERROR("snd_pcm_open for %s failed. %s", device, snd_strerror(err)); + ret = AUDIO_ERR_IOCTL; + goto error; + } + ret = __pcm_device_set_params(ah, pcm_devices->in, samplerate, channels); + if (ret != 0) { + AUDIO_LOG_ERROR("capture DAI PCM(%s, %p) setparam failure", device, pcm_devices->in); + ret = AUDIO_ERR_INTERNAL; + goto error; + } + AUDIO_LOG_INFO("capture DAI PCM(%s, %p) open/setparam success", device, pcm_devices->in); } - AUDIO_LOG_INFO("voice capture DAI(%s, %p) open/setparam success", VOICE_PCM_DEVICE, ah->device.pcm_in); - /* Voice Playback DAI */ - if ((err = snd_pcm_open((snd_pcm_t **)&ah->device.pcm_out, VOICE_PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { - AUDIO_LOG_ERROR("snd_pcm_open for %s failed. %s", VOICE_PCM_DEVICE, snd_strerror(err)); - ret = AUDIO_ERR_IOCTL; - goto error; - } - ret = __voice_pcm_set_params(ah, ah->device.pcm_out); - if (ret != 0) { - AUDIO_LOG_ERROR("voice playback DAI(%s, %p) setparam failure", VOICE_PCM_DEVICE, ah->device.pcm_out); - ret = AUDIO_ERR_INTERNAL; - goto error; + if (direction & AUDIO_DEVICE_DIRECTION_OUT) { + /* Playback PCM */ + if ((err = snd_pcm_open((snd_pcm_t **)&pcm_devices->out, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { + AUDIO_LOG_ERROR("snd_pcm_open for %s failed. %s", device, snd_strerror(err)); + ret = AUDIO_ERR_IOCTL; + goto error; + } + ret = __pcm_device_set_params(ah, pcm_devices->out, samplerate, channels); + if (ret != 0) { + AUDIO_LOG_ERROR("playback DAI PCM(%s, %p) setparam failure", device, pcm_devices->out); + ret = AUDIO_ERR_INTERNAL; + goto error; + } + AUDIO_LOG_INFO("playback DAI PCM(%s, %p) open/setparam success", device, pcm_devices->out); } - AUDIO_LOG_INFO("voice playback DAI(%s, %p) open/setparam success", VOICE_PCM_DEVICE, ah->device.pcm_out); #endif return AUDIO_RET_OK; error: - if (ah->device.pcm_out) { - snd_pcm_close(ah->device.pcm_out); - ah->device.pcm_out = NULL; + if ((direction & AUDIO_DEVICE_DIRECTION_OUT) && pcm_devices->out) { + snd_pcm_close(pcm_devices->out); + pcm_devices->out = NULL; } - if (ah->device.pcm_in) { - snd_pcm_close(ah->device.pcm_in); - ah->device.pcm_in = NULL; + if ((direction & AUDIO_DEVICE_DIRECTION_IN) && pcm_devices->in) { + snd_pcm_close(pcm_devices->in); + pcm_devices->in = NULL; } return ret; } -bool _is_voice_pcm_opened(audio_hal_t *ah) +audio_return_t _voice_pcm_open(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + return __pcm_device_open(ah, &ah->device.voice_pcm, VOICE_PCM_DEVICE, + AUDIO_DEVICE_DIRECTION_IN | AUDIO_DEVICE_DIRECTION_OUT, 48000, 2); +} + +audio_return_t _bt_pcm_open(audio_hal_t *ah) +{ + uint32_t samplerate; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + samplerate = (ah->device.bt_wideband) ? 16000 : 8000; + + return __pcm_device_open(ah, &ah->device.bt_pcm, BT_PCM_DEVICE, + AUDIO_DEVICE_DIRECTION_IN | AUDIO_DEVICE_DIRECTION_OUT, samplerate, 1); +} + +bool _is_voice_pcm_opened_all(audio_hal_t *ah) +{ + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + if (ah->device.voice_pcm.in && ah->device.voice_pcm.out) + return true; + else + return false; +} + +bool _is_bt_pcm_opened_all(audio_hal_t *ah) { AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - if (ah->device.pcm_in && ah->device.pcm_out) + if (ah->device.bt_pcm.in && ah->device.bt_pcm.out) return true; else return false; } -audio_return_t _voice_pcm_close(audio_hal_t *ah, uint32_t direction) +audio_return_t _voice_pcm_close(audio_hal_t *ah) { audio_return_t audio_ret = AUDIO_RET_OK; @@ -265,18 +296,47 @@ audio_return_t _voice_pcm_close(audio_hal_t *ah, uint32_t direction) AUDIO_LOG_INFO("close voice pcm handles"); - if (ah->device.pcm_out && (direction == AUDIO_DIRECTION_OUT)) { - if ((audio_ret = _pcm_close(ah->device.pcm_out))) - AUDIO_LOG_ERROR("failed to _pcm_close() for pcm_out, ret(0x%x)", audio_ret); + if (ah->device.voice_pcm.out) { + if ((audio_ret = _pcm_close(ah->device.voice_pcm.out))) + AUDIO_LOG_ERROR("failed to _pcm_close() for voice pcm out, ret(0x%x)", audio_ret); else { - ah->device.pcm_out = NULL; + ah->device.voice_pcm.out = NULL; AUDIO_LOG_INFO("voice pcm_out handle close success"); } - } else if (ah->device.pcm_in && (direction == AUDIO_DIRECTION_IN)) { - if ((audio_ret = _pcm_close(ah->device.pcm_in))) - AUDIO_LOG_ERROR("failed to _pcm_close() for pcm_in, ret(0x%x)", audio_ret); + } + if (ah->device.voice_pcm.in) { + if ((audio_ret = _pcm_close(ah->device.voice_pcm.in))) + AUDIO_LOG_ERROR("failed to _pcm_close() for voice pcm in, ret(0x%x)", audio_ret); + else { + ah->device.voice_pcm.in = NULL; + AUDIO_LOG_INFO("voice pcm_in handle close success"); + } + } + + return audio_ret; +} + +audio_return_t _bt_pcm_close(audio_hal_t *ah) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + + AUDIO_LOG_INFO("close bt pcm handles"); + + if (ah->device.bt_pcm.out) { + if ((audio_ret = _pcm_close(ah->device.bt_pcm.out))) + AUDIO_LOG_ERROR("failed to _pcm_close() for bt pcm out, ret(0x%x)", audio_ret); + else { + ah->device.bt_pcm.out = NULL; + AUDIO_LOG_INFO("bt pcm_out handle close success"); + } + } + if (ah->device.bt_pcm.in) { + if ((audio_ret = _pcm_close(ah->device.bt_pcm.in))) + AUDIO_LOG_ERROR("failed to _pcm_close() for bt pcm in, ret(0x%x)", audio_ret); else { - ah->device.pcm_in = NULL; + ah->device.bt_pcm.in = NULL; AUDIO_LOG_INFO("voice pcm_in handle close success"); } } @@ -290,16 +350,28 @@ audio_return_t _reset_pcm_devices(audio_hal_t *ah) AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - if (ah->device.pcm_out) { - if (!(audio_ret = _pcm_close(ah->device.pcm_out))) { - ah->device.pcm_out = NULL; - AUDIO_LOG_INFO("pcm_out handle close success"); + if (ah->device.voice_pcm.out) { + if (!(audio_ret = _pcm_close(ah->device.voice_pcm.out))) { + ah->device.voice_pcm.out = NULL; + AUDIO_LOG_INFO("voice pcm out handle close success"); + } + } + if (ah->device.voice_pcm.in) { + if (!(audio_ret = _pcm_close(ah->device.voice_pcm.in))) { + ah->device.voice_pcm.in = NULL; + AUDIO_LOG_INFO("voice pcm in handle close success"); + } + } + if (ah->device.bt_pcm.out) { + if (!(audio_ret = _pcm_close(ah->device.bt_pcm.out))) { + ah->device.bt_pcm.out = NULL; + AUDIO_LOG_INFO("bt pcm out handle close success"); } } - if (ah->device.pcm_in) { - if (!(audio_ret = _pcm_close(ah->device.pcm_in))) { - ah->device.pcm_in = NULL; - AUDIO_LOG_INFO("pcm_in handle close success"); + if (ah->device.bt_pcm.in) { + if (!(audio_ret = _pcm_close(ah->device.bt_pcm.in))) { + ah->device.bt_pcm.in = NULL; + AUDIO_LOG_INFO("bt pcm in handle close success"); } } diff --git a/tizen-audio-impl.h b/tizen-audio-impl.h index 64daeaf..ee48fa9 100644 --- a/tizen-audio-impl.h +++ b/tizen-audio-impl.h @@ -20,9 +20,15 @@ * */ +#include <stdbool.h> + /* PCM */ audio_return_t _voice_pcm_open(audio_hal_t *ah); -audio_return_t _voice_pcm_close(audio_hal_t *ah, uint32_t direction); +audio_return_t _voice_pcm_close(audio_hal_t *ah); +audio_return_t _bt_pcm_open(audio_hal_t *ah); +audio_return_t _bt_pcm_close(audio_hal_t *ah); +bool _is_voice_pcm_opened_all(audio_hal_t *ah); +bool _is_bt_pcm_opened_all(audio_hal_t *ah); audio_return_t _reset_pcm_devices(audio_hal_t *ah); audio_return_t _pcm_open(void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods); audio_return_t _pcm_start(void *pcm_handle); diff --git a/tizen-audio-internal.h b/tizen-audio-internal.h index b2ab3b7..81ec92a 100644 --- a/tizen-audio-internal.h +++ b/tizen-audio-internal.h @@ -118,7 +118,10 @@ typedef struct device_type { #define ALSA_DEFAULT_CARD "universal7270la" #define PLAYBACK_PCM_DEVICE "hw:0,0" #define CAPTURE_PCM_DEVICE "hw:0,0" + +/* DAI PCM DEVICE */ #define VOICE_PCM_DEVICE "hw:0,1" +#define BT_PCM_DEVICE "hw:0,2" /* hw:0,0 */ #define PLAYBACK_CARD_ID 0 @@ -148,14 +151,18 @@ typedef enum audio_route_mode { VERB_VOIP, } audio_route_mode_t; +typedef struct { + snd_pcm_t *in; + snd_pcm_t *out; +} audio_pcm_devices_t; + typedef struct audio_hal_device { uint32_t active_in; uint32_t active_out; - snd_pcm_t *pcm_in; - snd_pcm_t *pcm_out; - pthread_mutex_t pcm_lock; - uint32_t pcm_count; + audio_pcm_devices_t voice_pcm; + audio_pcm_devices_t bt_pcm; audio_route_mode_t mode; + uint32_t bt_wideband; } audio_hal_device_t; /* Volume */ @@ -194,6 +201,11 @@ typedef struct audio_volume_value_table { } audio_volume_value_table_t; enum { + AUDIO_DEVICE_DIRECTION_IN = 0x01, + AUDIO_DEVICE_DIRECTION_OUT = 0x02 +}; + +enum { AUDIO_VOLUME_DEVICE_DEFAULT, AUDIO_VOLUME_DEVICE_MAX, }; diff --git a/tizen-audio-pcm.c b/tizen-audio-pcm.c index 0a09cba..89ca482 100644 --- a/tizen-audio-pcm.c +++ b/tizen-audio-pcm.c @@ -28,10 +28,10 @@ audio_return_t _audio_pcm_init(audio_hal_t *ah) { AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - ah->device.pcm_in = NULL; - ah->device.pcm_out = NULL; - pthread_mutex_init(&ah->device.pcm_lock, NULL); - ah->device.pcm_count = 0; + ah->device.voice_pcm.in = NULL; + ah->device.voice_pcm.out = NULL; + ah->device.bt_pcm.in = NULL; + ah->device.bt_pcm.out = NULL; return AUDIO_RET_OK; } @@ -40,15 +40,12 @@ audio_return_t _audio_pcm_deinit(audio_hal_t *ah) { AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - pthread_mutex_destroy(&ah->device.pcm_lock); - return AUDIO_RET_OK; } audio_return_t audio_pcm_open(void *audio_handle, void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods) { audio_return_t audio_ret = AUDIO_RET_OK; - audio_hal_t *ah = NULL; AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); @@ -59,8 +56,6 @@ audio_return_t audio_pcm_open(void *audio_handle, void **pcm_handle, uint32_t di if ((audio_ret = _pcm_open(pcm_handle, direction, sample_spec, period_size, periods))) return audio_ret; - ah = (audio_hal_t*)audio_handle; - ah->device.pcm_count++; AUDIO_LOG_INFO("Opening PCM handle 0x%x", *pcm_handle); return AUDIO_RET_OK; @@ -93,7 +88,6 @@ audio_return_t audio_pcm_stop(void *audio_handle, void *pcm_handle) audio_return_t audio_pcm_close(void *audio_handle, void *pcm_handle) { audio_return_t audio_ret = AUDIO_RET_OK; - audio_hal_t *ah = NULL; AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER); AUDIO_RETURN_VAL_IF_FAIL(pcm_handle, AUDIO_ERR_PARAMETER); @@ -102,10 +96,8 @@ audio_return_t audio_pcm_close(void *audio_handle, void *pcm_handle) return audio_ret; pcm_handle = NULL; - ah = (audio_hal_t*)audio_handle; - ah->device.pcm_count--; - AUDIO_LOG_INFO("PCM handle close success (count:%d)", ah->device.pcm_count); + AUDIO_LOG_INFO("PCM handle close success"); return audio_ret; } diff --git a/tizen-audio-routing.c b/tizen-audio-routing.c index ffa629d..fc1f794 100644 --- a/tizen-audio-routing.c +++ b/tizen-audio-routing.c @@ -161,17 +161,9 @@ static audio_return_t __update_route_ap_playback_capture(audio_hal_t *ah, audio_ AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); AUDIO_RETURN_VAL_IF_FAIL(route_info, AUDIO_ERR_PARAMETER); -#if 0 - if (ah->modem.is_connected) { - AUDIO_LOG_WARN("modem is connected, skip verb[%s]", verb); - return audio_ret; - } -#endif - if (ah->device.mode != VERB_NORMAL) { if (ah->device.mode == VERB_VOICECALL) { __reset_voice_devices_info(ah); -// COND_SIGNAL(ah->device.device_cond, "device_cond"); } _reset_pcm_devices(ah); ah->device.mode = VERB_NORMAL; @@ -196,15 +188,11 @@ static audio_return_t __update_route_voicecall(audio_hal_t *ah, device_info_t *d const char *verb = mode_to_verb_str[VERB_VOICECALL]; AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); - /* if both params are 0, return error for invalid state, - * this error would be used to tizen-audio-modem.c */ - AUDIO_RETURN_VAL_IF_FAIL((devices||num_of_devices), AUDIO_ERR_INVALID_STATE); AUDIO_RETURN_VAL_IF_FAIL(devices, AUDIO_ERR_PARAMETER); AUDIO_LOG_INFO("update_route_voicecall++"); - audio_ret = __set_devices(ah, verb, devices, num_of_devices); - if (audio_ret) { + if ((audio_ret = __set_devices(ah, verb, devices, num_of_devices))) { AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret); return audio_ret; } @@ -212,9 +200,16 @@ static audio_return_t __update_route_voicecall(audio_hal_t *ah, device_info_t *d if (ah->device.mode != VERB_VOICECALL) { ah->device.mode = VERB_VOICECALL; /* FIXME. Get network info and configure rate in pcm device */ + _reset_pcm_devices(ah); } else { - if (!_is_voice_pcm_opened(ah)) - _voice_pcm_open(ah); + if (_is_voice_pcm_opened_all(ah)) { + AUDIO_LOG_INFO("voice pcm device is already opened, skip it"); + return audio_ret; + } + if ((audio_ret = _voice_pcm_open(ah))) { + AUDIO_LOG_ERROR("Failed to open voice pcm device: error = 0x%x", audio_ret); + return audio_ret; + } } return audio_ret; @@ -230,8 +225,7 @@ static audio_return_t __update_route_voip(audio_hal_t *ah, device_info_t *device AUDIO_LOG_INFO("update_route_voip++"); - audio_ret = __set_devices(ah, verb, devices, num_of_devices); - if (audio_ret) { + if ((audio_ret = __set_devices(ah, verb, devices, num_of_devices))) { AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret); return audio_ret; } @@ -242,6 +236,42 @@ static audio_return_t __update_route_voip(audio_hal_t *ah, device_info_t *device return audio_ret; } +static audio_return_t __update_route_voice_recognition(audio_hal_t *ah, device_info_t *devices, int32_t num_of_devices) +{ + audio_return_t audio_ret = AUDIO_RET_OK; + const char *verb = mode_to_verb_str[VERB_NORMAL]; + + AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER); + AUDIO_RETURN_VAL_IF_FAIL(devices, AUDIO_ERR_PARAMETER); + + AUDIO_LOG_INFO("update_route_voice_recognition++"); + + if ((audio_ret = __set_devices(ah, verb, devices, num_of_devices))) { + AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret); + return audio_ret; + } + + if (ah->device.mode != VERB_NORMAL) { + ah->device.mode = VERB_NORMAL; + _reset_pcm_devices(ah); + } + + /* if this request is for BT SCO device */ + if (ah->device.active_in & AUDIO_DEVICE_IN_BT_SCO) { + if (_is_bt_pcm_opened_all(ah)) { + AUDIO_LOG_INFO("bt pcm device is already opened, skip it"); + return audio_ret; + } + + if ((audio_ret = _bt_pcm_open(ah))) { + AUDIO_LOG_ERROR("Failed to open bt pcm device: error = 0x%x", audio_ret); + return audio_ret; + } + } + + return audio_ret; +} + static audio_return_t __update_route_reset(audio_hal_t *ah, uint32_t direction) { audio_return_t audio_ret = AUDIO_RET_OK; @@ -275,13 +305,21 @@ static audio_return_t __update_route_reset(audio_hal_t *ah, uint32_t direction) } } } + if (ah->device.mode == VERB_VOICECALL) { - if ((audio_ret = _voice_pcm_close(ah, direction))) + if ((audio_ret = _bt_pcm_close(ah))) + AUDIO_LOG_ERROR("failed to _bt_pcm_close(), ret(0x%x)", audio_ret); + if ((audio_ret = _voice_pcm_close(ah))) AUDIO_LOG_ERROR("failed to _voice_pcm_close(), ret(0x%x)", audio_ret); if (!ah->device.active_in && !ah->device.active_out) ah->device.mode = VERB_NORMAL; __reset_voice_devices_info(ah); -// COND_SIGNAL(ah->device.device_cond, "device_cond"); + } else if (ah->device.mode == VERB_NORMAL) { + if (direction == AUDIO_DIRECTION_IN) { + /* voice-recognition case */ + if ((audio_ret = _bt_pcm_close(ah))) + AUDIO_LOG_ERROR("failed to _bt_pcm_close(), ret(0x%x)", audio_ret); + } } if (active_devices[0] == NULL) { @@ -346,17 +384,21 @@ audio_return_t audio_update_route(void *audio_handle, audio_route_info_t *info) if ((audio_ret = __update_route_voicecall(ah, devices, info->num_of_devices))) AUDIO_LOG_WARN("update voicecall route return 0x%x", audio_ret); -// COND_SIGNAL(ah->device.device_cond, "device_cond"); } else if (!strncmp("voip", info->role, MAX_NAME_LEN)) { if ((audio_ret = __update_route_voip(ah, devices, info->num_of_devices))) AUDIO_LOG_WARN("update voip route return 0x%x", audio_ret); + } else if (!strncmp("voice-recognition", info->role, MAX_NAME_LEN) || + !strncmp("voice-recognition-service", info->role, MAX_NAME_LEN)) { + if ((audio_ret = __update_route_voice_recognition(ah, devices, info->num_of_devices))) + AUDIO_LOG_WARN("update voice-recognition route return 0x%x", audio_ret); + } else if (!strncmp("reset", info->role, MAX_NAME_LEN)) { if ((audio_ret = __update_route_reset(ah, devices->direction))) AUDIO_LOG_WARN("update reset return 0x%x", audio_ret); } else { - /* need to prepare for "alarm","notification","emergency","voice-information","voice-recognition","ringtone" */ + /* need to prepare for "alarm","notification","emergency","voice-information","ringtone" */ if ((audio_ret = __update_route_ap_playback_capture(ah, info))) AUDIO_LOG_WARN("update playback route return 0x%x", audio_ret); } @@ -372,6 +414,14 @@ audio_return_t audio_update_route_option(void *audio_handle, audio_route_option_ AUDIO_RETURN_VAL_IF_FAIL(option, AUDIO_ERR_PARAMETER); AUDIO_LOG_INFO("role:%s, name:%s, value:%d", option->role, option->name, option->value); + if (!strncmp("voice-recognition", option->role, MAX_NAME_LEN)) { + if (!strncmp("bt-wideband", option->name, MAX_NAME_LEN)) { + if (option->value > 0) + ah->device.bt_wideband = 1; + else + ah->device.bt_wideband = 0; + } + } return audio_ret; } |