From d2dbaf991e3f6b730624b7dfc9ce3cda8101b8d7 Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Tue, 27 Sep 2011 13:39:53 -0700 Subject: audio: support wideband call audio Some networks support wideband AMR for voice calls. To support this, implement a callback that the RIL uses to set the wideband config. Change-Id: Ifa75ff189cc300728f560b77fd4fb3f1798e776d --- audio/audio_hw.c | 20 ++++++++++++++++++++ audio/ril_interface.c | 36 +++++++++++++++++++++++++++++++++++- audio/ril_interface.h | 5 +++++ 3 files changed, 60 insertions(+), 1 deletion(-) mode change 100644 => 100755 audio/audio_hw.c mode change 100644 => 100755 audio/ril_interface.c mode change 100644 => 100755 audio/ril_interface.h (limited to 'audio') diff --git a/audio/audio_hw.c b/audio/audio_hw.c old mode 100644 new mode 100755 index 40f5df3..48947cb --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -119,6 +119,8 @@ #define MM_FULL_POWER_SAMPLING_RATE 48000 /* sampling rate when using VX port for narrow band */ #define VX_NB_SAMPLING_RATE 8000 +/* sampling rate when using VX port for wide band */ +#define VX_WB_SAMPLING_RATE 16000 /* conversions from dB to ABE and codec gains */ #define DB_TO_ABE_GAIN(x) ((x) + MIXER_ABE_GAIN_0DB) @@ -445,6 +447,7 @@ struct tuna_audio_device { bool bluetooth_nrec; bool headphone_volume_europe; bool earpiece_volume_toro; + int wb_amr; /* RIL */ struct ril_handle ril; @@ -568,6 +571,8 @@ static int start_call(struct tuna_audio_device *adev) { LOGE("Opening modem PCMs"); + pcm_config_vx.rate = adev->wb_amr ? VX_WB_SAMPLING_RATE : VX_NB_SAMPLING_RATE; + /* Open modem PCM channels */ if (adev->pcm_modem_dl == NULL) { adev->pcm_modem_dl = pcm_open(0, PORT_MODEM, PCM_OUT, &pcm_config_vx); @@ -612,6 +617,18 @@ static void end_call(struct tuna_audio_device *adev) adev->pcm_modem_ul = NULL; } +void audio_set_wb_amr_callback(void *data, int enable) +{ + struct tuna_audio_device *adev = (struct tuna_audio_device *)data; + adev->wb_amr = enable; + + /* reopen the modem PCMs at the new rate */ + if (adev->in_call) { + end_call(adev); + start_call(adev); + } +} + static void set_incall_device(struct tuna_audio_device *adev) { int device_type; @@ -2407,10 +2424,13 @@ static int adev_open(const hw_module_t* module, const char* name, adev->headphone_volume_europe = is_product_yakju(); adev->earpiece_volume_toro = is_device_toro(); adev->bluetooth_nrec = true; + adev->wb_amr = 0; /* RIL */ ril_open(&adev->ril); pthread_mutex_unlock(&adev->lock); + /* register callback for wideband AMR setting */ + ril_register_set_wb_amr_callback(audio_set_wb_amr_callback, (void *)adev); *device = &adev->hw_device.common; diff --git a/audio/ril_interface.c b/audio/ril_interface.c old mode 100644 new mode 100755 index 8793fae..7d5d891 --- a/audio/ril_interface.c +++ b/audio/ril_interface.c @@ -37,6 +37,33 @@ int (*_ril_disconnect)(void *); int (*_ril_set_call_volume)(void *, enum ril_sound_type, int); int (*_ril_set_call_audio_path)(void *, enum ril_audio_path); int (*_ril_set_call_clock_sync)(void *, enum ril_clock_state); +int (*_ril_register_unsolicited_handler)(void *, int, void *); + +/* Audio WB AMR callback */ +void (*_audio_set_wb_amr_callback)(void *, int); +void *callback_data = NULL; + +void ril_register_set_wb_amr_callback(void *function, void *data) +{ + _audio_set_wb_amr_callback = function; + callback_data = data; +} + +/* This is the callback function that the RIL uses to +set the wideband AMR state */ +static int ril_set_wb_amr_callback(void *ril_client, + const void *data, + size_t datalen) +{ + int enable = ((int *)data)[0]; + + if (!callback_data || !_audio_set_wb_amr_callback) + return -1; + + _audio_set_wb_amr_callback(callback_data, enable); + + return 0; +} static int ril_connect_if_required(struct ril_handle *ril) { @@ -72,10 +99,13 @@ int ril_open(struct ril_handle *ril) _ril_set_call_volume = dlsym(ril->handle, "SetCallVolume"); _ril_set_call_audio_path = dlsym(ril->handle, "SetCallAudioPath"); _ril_set_call_clock_sync = dlsym(ril->handle, "SetCallClockSync"); + _ril_register_unsolicited_handler = dlsym(ril->handle, + "RegisterUnsolicitedHandler"); if (!_ril_open_client || !_ril_close_client || !_ril_connect || !_ril_is_connected || !_ril_disconnect || !_ril_set_call_volume || - !_ril_set_call_audio_path || !_ril_set_call_clock_sync) { + !_ril_set_call_audio_path || !_ril_set_call_clock_sync || + !_ril_register_unsolicited_handler) { LOGE("Cannot get symbols from '%s'", RIL_CLIENT_LIBPATH); dlclose(ril->handle); return -1; @@ -88,6 +118,10 @@ int ril_open(struct ril_handle *ril) return -1; } + /* register the wideband AMR callback */ + _ril_register_unsolicited_handler(ril->client, RIL_UNSOL_WB_AMR_STATE, + ril_set_wb_amr_callback); + property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT); ril->volume_steps_max = atoi(property); /* this catches the case where VOLUME_STEPS_PROPERTY does not contain diff --git a/audio/ril_interface.h b/audio/ril_interface.h old mode 100644 new mode 100755 index 4a7a839..676772c --- a/audio/ril_interface.h +++ b/audio/ril_interface.h @@ -28,6 +28,10 @@ #define RIL_CLIENT_ERR_RESOURCE 6 // Resource not available #define RIL_CLIENT_ERR_UNKNOWN 7 +#define RIL_OEM_UNSOL_RESPONSE_BASE 11000 // RIL response base index +#define RIL_UNSOL_WB_AMR_STATE \ + (RIL_OEM_UNSOL_RESPONSE_BASE + 17) // RIL AMR state index + struct ril_handle { void *handle; @@ -63,5 +67,6 @@ int ril_set_call_volume(struct ril_handle *ril, enum ril_sound_type sound_type, float volume); int ril_set_call_audio_path(struct ril_handle *ril, enum ril_audio_path path); int ril_set_call_clock_sync(struct ril_handle *ril, enum ril_clock_state state); +void ril_register_set_wb_amr_callback(void *function, void *data); #endif -- cgit v1.1