diff --git a/Android.mk b/Android.mk index 4fb48d1..2dd66bb 100644 --- a/Android.mk +++ b/Android.mk @@ -1,5 +1,5 @@ ifeq ($(TARGET_QCOM_AUDIO_VARIANT),caf) -ifneq ($(filter msm8960 msm8660 msm8226 msm8x26 msm8610 msm8974 msm8x74 msm7x30 apq8084,$(TARGET_BOARD_PLATFORM)),) +ifneq ($(filter msm8960 msm8660 msm8226 msm8x26 msm8610 msm8974 msm8x74 apq8084,$(TARGET_BOARD_PLATFORM)),) MY_LOCAL_PATH := $(call my-dir) diff --git a/legacy/Android.mk b/legacy/Android.mk index f0379ba..b44bb88 100644 --- a/legacy/Android.mk +++ b/legacy/Android.mk @@ -7,10 +7,6 @@ ifeq ($(strip $(BOARD_USES_ALSA_AUDIO)),true) include $(AUDIO_HW_ROOT)/audiod/Android.mk endif -ifeq ($(TARGET_BOARD_PLATFORM),msm7x30) - include $(AUDIO_HW_ROOT)/msm7x30/Android.mk -endif - ifeq ($(TARGET_BOARD_PLATFORM),msm8660) include $(AUDIO_HW_ROOT)/msm8660/Android.mk include $(AUDIO_HW_ROOT)/mm-audio/Android.mk diff --git a/legacy/msm7x30/Android.mk b/legacy/msm7x30/Android.mk deleted file mode 100644 index 28d9507..0000000 --- a/legacy/msm7x30/Android.mk +++ /dev/null @@ -1,126 +0,0 @@ -#AUDIO_POLICY_TEST := true -#ENABLE_AUDIO_DUMP := true - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - AudioHardware.cpp \ - audio_hw_hal.cpp - -ifeq ($(BOARD_HAVE_BLUETOOTH),true) - LOCAL_CFLAGS += -DWITH_A2DP -endif - -ifeq ($(QCOM_FM_ENABLED),true) - LOCAL_CFLAGS += -DQCOM_FM_ENABLED -endif - -ifeq ($(BOARD_USES_QCOM_AUDIO_LPA),true) - LOCAL_CFLAGS += -DQCOM_TUNNEL_LPA_ENABLED -endif - -ifeq ($(BOARD_USES_QCOM_AUDIO_SPEECH),true) - LOCAL_CFLAGS += -DWITH_QCOM_SPEECH -endif - -ifeq ($(BOARD_USES_QCOM_AUDIO_VOIPMUTE),true) - LOCAL_CFLAGS += -DWITH_QCOM_VOIPMUTE -endif - -ifeq ($(BOARD_USES_QCOM_AUDIO_RESETALL),true) - LOCAL_CFLAGS += -DWITH_QCOM_RESETALL -endif - -ifeq ($(BOARD_USES_STEREO_HW_SPEAKER),true) - LOCAL_CFLAGS += -DWITH_STEREO_HW_SPEAKER -endif - -ifeq ($(BOARD_HAVE_HTC_AUDIO),true) - LOCAL_CFLAGS += -DHTC_AUDIO -endif - -ifeq ($(BOARD_HAVE_SAMSUNG_AUDIO),true) - LOCAL_CFLAGS += -DSAMSUNG_AUDIO -endif - -ifeq ($(BOARD_HAVE_BACK_MIC_CAMCORDER),true) - LOCAL_CFLAGS += -DBACK_MIC_CAMCORDER -endif - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libmedia \ - libaudioalsa - -# hack for prebuilt -$(shell mkdir -p $(OUT)/obj/SHARED_LIBRARIES/libaudioalsa_intermediates/) -$(shell touch $(OUT)/obj/SHARED_LIBRARIES/libaudioalsa_intermediates/export_includes) - -ifeq ($(BOARD_USES_QCOM_AUDIO_CALIBRATION),true) - LOCAL_SHARED_LIBRARIES += libaudcal - LOCAL_CFLAGS += -DWITH_QCOM_CALIBRATION -endif - -ifneq ($(TARGET_SIMULATOR),true) - LOCAL_SHARED_LIBRARIES += libdl -endif - -LOCAL_STATIC_LIBRARIES := \ - libmedia_helper \ - libaudiohw_legacy - -LOCAL_MODULE := audio.primary.msm7x30 -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw -LOCAL_MODULE_TAGS := optional - -LOCAL_CFLAGS += -fno-short-enums - -LOCAL_C_INCLUDES := $(TARGET_OUT_HEADERS)/mm-audio/audio-alsa -ifeq ($(BOARD_USES_QCOM_AUDIO_CALIBRATION),true) - LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audcal -endif -LOCAL_C_INCLUDES += hardware/libhardware/include -LOCAL_C_INCLUDES += hardware/libhardware_legacy/include -LOCAL_C_INCLUDES += frameworks/base/include -LOCAL_C_INCLUDES += system/core/include - -ifneq ($(TARGET_KERNEL_SOURCE),) - LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include - LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr -endif - -include $(BUILD_SHARED_LIBRARY) - -# The audio policy is implemented on top of legacy policy code -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - AudioPolicyManager.cpp \ - audio_policy_hal.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libmedia - -LOCAL_STATIC_LIBRARIES := \ - libmedia_helper \ - libaudiopolicy_legacy - -LOCAL_MODULE := audio_policy.msm7x30 -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw -LOCAL_MODULE_TAGS := optional - -ifeq ($(BOARD_HAVE_BLUETOOTH),true) - LOCAL_CFLAGS += -DWITH_A2DP -endif - -ifeq ($(BOARD_USES_QCOM_AUDIO_LPA),true) - LOCAL_CFLAGS += -DQCOM_TUNNEL_LPA_ENABLED -endif - -LOCAL_C_INCLUDES := hardware/libhardware_legacy/audio - -include $(BUILD_SHARED_LIBRARY) diff --git a/legacy/msm7x30/AudioHardware.cpp b/legacy/msm7x30/AudioHardware.cpp deleted file mode 100644 index 1f245d9..0000000 --- a/legacy/msm7x30/AudioHardware.cpp +++ /dev/null @@ -1,5183 +0,0 @@ -/* -** Copyright 2008, The Android Open-Source Project -** Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. -** Copyright (c) 2011-2013, The CyanogenMod Project -** Not a Contribution, Apache license notifications and license are retained -** for attribution purposes only. -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include - -#define LOG_TAG "AudioHardware7x30" -//#define LOG_NDDEBUG 0 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "control.h" -extern "C" { -#include "initialize_audcal7x30.h" -#ifdef HTC_AUDIO -#include -#include -#endif -} -// hardware specific functions - -#include "AudioHardware.h" -//#include -//#include -#ifdef WITH_QCOM_VOIP_OVER_MVS -#include -#endif - -#define LOG_SND_RPC 0 // Set to 1 to log sound RPC's - -#define ECHO_SUPRESSION "ec_supported" - -#define DUALMIC_KEY "dualmic_enabled" -#define TTY_MODE_KEY "tty_mode" -#define BTHEADSET_VGS "bt_headset_vgs" -#ifdef HTC_AUDIO -#define DSP_EFFECT_KEY "dolby_srs_eq" -#endif -#define AMRNB_DEVICE_IN "/dev/msm_amrnb_in" -#define EVRC_DEVICE_IN "/dev/msm_evrc_in" -#define QCELP_DEVICE_IN "/dev/msm_qcelp_in" -#define AAC_DEVICE_IN "/dev/msm_aac_in" -#ifdef QCOM_FM_ENABLED -#define FM_DEVICE "/dev/msm_fm" -#define FM_A2DP_REC 1 -#define FM_FILE_REC 2 -#endif - -#define MVS_DEVICE "/dev/msm_mvs" - -#define AMRNB_FRAME_SIZE 32 -#define EVRC_FRAME_SIZE 23 -#define QCELP_FRAME_SIZE 35 - - - -namespace android_audio_legacy { -//using android_audio_legacy::AudioSystem; -//using android_audio_legacy::AudioHardwareInterface; - -Mutex mDeviceSwitchLock; -#ifdef HTC_AUDIO -Mutex mAIC3254ConfigLock; -#endif -static int audpre_index, tx_iir_index; -static void * acoustic; -const uint32_t AudioHardware::inputSamplingRates[] = { - 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 -}; -static const uint32_t INVALID_DEVICE = 65535; -static const uint32_t SND_DEVICE_CURRENT =-1; -static const uint32_t SND_DEVICE_HANDSET = 0; -static const uint32_t SND_DEVICE_SPEAKER = 1; -static const uint32_t SND_DEVICE_HEADSET = 2; -static const uint32_t SND_DEVICE_FM_HANDSET = 3; -static const uint32_t SND_DEVICE_FM_SPEAKER = 4; -static const uint32_t SND_DEVICE_FM_HEADSET = 5; -static const uint32_t SND_DEVICE_BT = 6; -static const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER = 7; -static const uint32_t SND_DEVICE_NO_MIC_HEADSET = 8; -static const uint32_t SND_DEVICE_IN_S_SADC_OUT_HANDSET = 9; -static const uint32_t SND_DEVICE_IN_S_SADC_OUT_SPEAKER_PHONE = 10; -static const uint32_t SND_DEVICE_TTY_HEADSET = 11; -static const uint32_t SND_DEVICE_TTY_HCO = 12; -static const uint32_t SND_DEVICE_TTY_VCO = 13; -static const uint32_t SND_DEVICE_TTY_FULL = 14; -static const uint32_t SND_DEVICE_HDMI = 15; -static const uint32_t SND_DEVICE_FM_TX = 16; -static const uint32_t SND_DEVICE_FM_TX_AND_SPEAKER = 17; -static const uint32_t SND_DEVICE_HEADPHONE_AND_SPEAKER = 18; -static const uint32_t SND_DEVICE_BACK_MIC_CAMCORDER = 33; -#ifdef HTC_AUDIO -static const uint32_t SND_DEVICE_CARKIT = 19; -static const uint32_t SND_DEVICE_HANDSET_BACK_MIC = 20; -static const uint32_t SND_DEVICE_SPEAKER_BACK_MIC = 21; -static const uint32_t SND_DEVICE_NO_MIC_HEADSET_BACK_MIC = 28; -static const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC = 30; -static const uint32_t SND_DEVICE_I2S_SPEAKER = 32; -static const uint32_t SND_DEVICE_BT_EC_OFF = 45; -static const uint32_t SND_DEVICE_HAC = 252; -static const uint32_t SND_DEVICE_USB_HEADSET = 253; -#else -static const uint32_t SND_DEVICE_CARKIT = -1; -static const uint32_t SND_DEVICE_BT_EC_OFF = -1; -#endif -#ifdef SAMSUNG_AUDIO -static const uint32_t SND_DEVICE_VOIP_HANDSET = 50; -static const uint32_t SND_DEVICE_VOIP_SPEAKER = 51; -static const uint32_t SND_DEVICE_VOIP_HEADSET = 52; -static const uint32_t SND_DEVICE_CALL_HANDSET = 60; -static const uint32_t SND_DEVICE_CALL_SPEAKER = 61; -static const uint32_t SND_DEVICE_CALL_HEADSET = 62; -#endif - -static const uint32_t DEVICE_HANDSET_RX = 0; /* handset_rx */ -static const uint32_t DEVICE_HANDSET_TX = 1; /* handset_tx */ -static const uint32_t DEVICE_SPEAKER_RX = 2; /* caf: speaker_stereo_rx - htc: speaker_mono_rx - sam: speaker_rx */ -static const uint32_t DEVICE_SPEAKER_TX = 3; /* caf: speaker_mono_tx - sam: speaker_tx */ -static const uint32_t DEVICE_HEADSET_RX = 4; /* caf: headset_stereo_rx - sam: headset_rx */ -static const uint32_t DEVICE_HEADSET_TX = 5; /* caf: headset_mono_tx - sam: headset_tx */ -static const uint32_t DEVICE_FMRADIO_HANDSET_RX = 6; /* fmradio_handset_rx */ -static const uint32_t DEVICE_FMRADIO_HEADSET_RX = 7; /* fmradio_headset_rx */ -static const uint32_t DEVICE_FMRADIO_SPEAKER_RX = 8; /* fmradio_speaker_rx */ -static const uint32_t DEVICE_DUALMIC_HANDSET_TX = 9; /* handset_dual_mic_endfire_tx */ -static const uint32_t DEVICE_DUALMIC_SPEAKER_TX = 10; /* speaker_dual_mic_endfire_tx */ -static const uint32_t DEVICE_TTY_HEADSET_MONO_RX = 11; /* tty_headset_mono_rx */ -static const uint32_t DEVICE_TTY_HEADSET_MONO_TX = 12; /* tty_headset_mono_tx */ -static const uint32_t DEVICE_SPEAKER_HEADSET_RX = 13; /* caf: headset_stereo_speaker_stereo_rx - htc: headset_speaker_stereo_rx - sam: speaker_headset_rx */ -static const uint32_t DEVICE_FMRADIO_STEREO_TX = 14; -static const uint32_t DEVICE_HDMI_STERO_RX = 15; /* hdmi_stereo_rx */ -static const uint32_t DEVICE_FMRADIO_STEREO_RX = 16; -static const uint32_t DEVICE_BT_SCO_RX = 17; /* bt_sco_rx */ -static const uint32_t DEVICE_BT_SCO_TX = 18; /* bt_sco_tx */ -static const uint32_t DEVICE_CAMCORDER_TX = 105; /* caf: camcorder_tx - semc: speaker_secondary_mic_tx */ -#if defined(SAMSUNG_AUDIO) -static const uint32_t DEVICE_HANDSET_VOIP_RX = 40; /* handset_voip_rx */ -static const uint32_t DEVICE_HANDSET_VOIP_TX = 41; /* handset_voip_tx */ -static const uint32_t DEVICE_SPEAKER_VOIP_RX = 42; /* speaker_voip_rx */ -static const uint32_t DEVICE_SPEAKER_VOIP_TX = 43; /* speaker_voip_tx */ -static const uint32_t DEVICE_HEADSET_VOIP_RX = 44; /* headset_voip_rx */ -static const uint32_t DEVICE_HEADSET_VOIP_TX = 45; /* headset_voip_tx */ -static const uint32_t DEVICE_HANDSET_CALL_RX = 60; /* handset_call_rx */ -static const uint32_t DEVICE_HANDSET_CALL_TX = 61; /* handset_call_tx */ -static const uint32_t DEVICE_SPEAKER_CALL_RX = 62; /* speaker_call_rx */ -static const uint32_t DEVICE_SPEAKER_CALL_TX = 63; /* speaker_call_tx */ -static const uint32_t DEVICE_HEADSET_CALL_RX = 64; /* headset_call_rx */ -static const uint32_t DEVICE_HEADSET_CALL_TX = 65; /* headset_call_tx */ -static const uint32_t DEVICE_COUNT = DEVICE_HEADSET_CALL_TX +1; -#elif defined(HTC_AUDIO) -static const uint32_t DEVICE_USB_HEADSET_RX = 19; /* usb_headset_stereo_rx */ -static const uint32_t DEVICE_HAC_RX = 20; /* hac_mono_rx */ -static const uint32_t DEVICE_ALT_RX = 21; /* alt_mono_rx */ -static const uint32_t DEVICE_VR_HANDSET = 22; /* handset_vr_tx */ -static const uint32_t DEVICE_COUNT = DEVICE_VR_HANDSET +1; -#else -static const uint32_t DEVICE_COUNT = DEVICE_CAMCORDER_TX +1; -#endif - -#ifdef HTC_AUDIO -static bool support_aic3254 = true; -static bool aic3254_enabled = true; -int (*set_sound_effect)(const char* effect); -static bool support_tpa2051 = true; -static bool support_htc_backmic = true; -static bool fm_enabled = false; -static int alt_enable = 0; -static int hac_enable = 0; -static uint32_t cur_aic_tx = UPLINK_OFF; -static uint32_t cur_aic_rx = DOWNLINK_OFF; -static int cur_tpa_mode = 0; -#endif - -int dev_cnt = 0; -const char ** name = NULL; -int mixer_cnt = 0; -static uint32_t cur_tx = INVALID_DEVICE; -static uint32_t cur_rx = INVALID_DEVICE; -bool vMicMute = false; -typedef struct routing_table -{ - unsigned short dec_id; - int dev_id; - int dev_id_tx; - int stream_type; - bool active; - struct routing_table *next; -} Routing_table; -Routing_table* head; -Mutex mRoutingTableLock; - -typedef struct device_table -{ - int dev_id; - int class_id; - int capability; -}Device_table; -Device_table* device_list; - -static unsigned char build_id[20]; - -static void amr_transcode(unsigned char *src, unsigned char *dst); - -enum STREAM_TYPES { -PCM_PLAY=1, -PCM_REC, -#ifdef QCOM_TUNNEL_LPA_ENABLED -LPA_DECODE, -#endif -VOICE_CALL, -#ifdef QCOM_FM_ENABLED -FM_RADIO, -FM_REC, -FM_A2DP, -#endif -INVALID_STREAM -}; - -typedef struct ComboDeviceType -{ - uint32_t DeviceId; - STREAM_TYPES StreamType; -}CurrentComboDeviceStruct; -CurrentComboDeviceStruct CurrentComboDeviceData; -Mutex mComboDeviceLock; - -#ifdef QCOM_FM_ENABLED -enum FM_STATE { - FM_INVALID=1, - FM_OFF, - FM_ON -}; - -FM_STATE fmState = FM_INVALID; -#endif - -static uint32_t fmDevice = INVALID_DEVICE; - -#define DEV_ID(X) device_list[X].dev_id -void addToTable(int decoder_id,int device_id,int device_id_tx,int stream_type,bool active) { - Routing_table* temp_ptr; - Mutex::Autolock lock(mRoutingTableLock); - temp_ptr = (Routing_table* ) malloc(sizeof(Routing_table)); - temp_ptr->next = NULL; - temp_ptr->dec_id = decoder_id; - temp_ptr->dev_id = device_id; - temp_ptr->dev_id_tx = device_id_tx; - temp_ptr->stream_type = stream_type; - temp_ptr->active = active; - //add new Node to head. - temp_ptr->next =head->next; - head->next = temp_ptr; -} -bool isStreamOn(int Stream_type) { - Routing_table* temp_ptr; - Mutex::Autolock lock(mRoutingTableLock); - temp_ptr = head->next; - while(temp_ptr!=NULL) { - if(temp_ptr->stream_type == Stream_type) - return true; - temp_ptr=temp_ptr->next; - } - return false; -} -bool isStreamOnAndActive(int Stream_type) { - Routing_table* temp_ptr; - Mutex::Autolock lock(mRoutingTableLock); - temp_ptr = head->next; - while(temp_ptr!=NULL) { - if(temp_ptr->stream_type == Stream_type) { - if(temp_ptr->active == true) { - return true; - } - else { - return false; - } - } - temp_ptr=temp_ptr->next; - } - return false; -} -bool isStreamOnAndInactive(int Stream_type) { - Routing_table* temp_ptr; - Mutex::Autolock lock(mRoutingTableLock); - temp_ptr = head->next; - while(temp_ptr!=NULL) { - if(temp_ptr->stream_type == Stream_type) { - if(temp_ptr->active == false) { - return true; - } - else { - return false; - } - } - temp_ptr=temp_ptr->next; - } - return false; -} -Routing_table* getNodeByStreamType(int Stream_type) { - Routing_table* temp_ptr; - Mutex::Autolock lock(mRoutingTableLock); - temp_ptr = head->next; - while(temp_ptr!=NULL) { - if(temp_ptr->stream_type == Stream_type) { - return temp_ptr; - } - temp_ptr=temp_ptr->next; - } - return NULL; -} -void modifyActiveStateOfStream(int Stream_type, bool Active) { - Routing_table* temp_ptr; - Mutex::Autolock lock(mRoutingTableLock); - temp_ptr = head->next; - while(temp_ptr!=NULL) { - if(temp_ptr->stream_type == Stream_type) { - temp_ptr->active = Active; - return; - } - temp_ptr=temp_ptr->next; - } -} -void modifyActiveDeviceOfStream(int Stream_type,int Device_id,int Device_id_tx) { - Routing_table* temp_ptr; - temp_ptr = head->next; - while(temp_ptr!=NULL) { - if(temp_ptr->stream_type == Stream_type) { - temp_ptr->dev_id = Device_id; - temp_ptr->dev_id_tx = Device_id_tx; - return; - } - temp_ptr=temp_ptr->next; - } -} -void printTable() -{ - Routing_table * temp_ptr; - Mutex::Autolock lock(mRoutingTableLock); - temp_ptr = head->next; - while(temp_ptr!=NULL) { - printf("%d %d %d %d %d\n",temp_ptr->dec_id,temp_ptr->dev_id,temp_ptr->dev_id_tx,temp_ptr->stream_type,temp_ptr->active); - temp_ptr = temp_ptr->next; - } -} -void deleteFromTable(int Stream_type) { - Routing_table *temp_ptr,*temp1; - Mutex::Autolock lock(mRoutingTableLock); - temp_ptr = head; - while(temp_ptr->next!=NULL) { - if(temp_ptr->next->stream_type == Stream_type) { - temp1 = temp_ptr->next; - temp_ptr->next = temp_ptr->next->next; - free(temp1); - return; - } - temp_ptr=temp_ptr->next; - } - -} - -bool isDeviceListEmpty() { - if(head->next == NULL) - return true; - else - return false; -} - -int enableDevice(int device,short enable) { - ALOGV("value of device and enable is %d %d ALSA dev id:%d",device,enable,DEV_ID(device)); - if( msm_en_device(DEV_ID(device), enable)) { - ALOGE("msm_en_device(%d, %d) failed errno = %d",DEV_ID(device), enable, errno); - return -1; - } - return 0; -} - -#ifdef HTC_AUDIO -void updateACDB(uint32_t new_rx_device, uint32_t new_tx_device, - uint32_t new_rx_acdb, uint32_t new_tx_acdb) { - - ALOGD("updateACDB: (%d, %d, %d, %d) ", new_tx_device, new_rx_device, new_tx_acdb, new_rx_acdb); - - int rc = -1; - int (*update_acdb_id)(uint32_t, uint32_t, uint32_t, uint32_t); - - update_acdb_id = (int (*)(uint32_t, uint32_t, uint32_t, uint32_t))::dlsym(acoustic, "update_acdb_id"); - if ((*update_acdb_id) == 0) - ALOGE("Could not open update_acdb_id()"); - else { - rc = update_acdb_id(new_tx_device, new_rx_device, new_tx_acdb, new_rx_acdb); - if (rc < 0) - ALOGE("Could not set update_acdb_id: %d", rc); - } -} - -static status_t updateDeviceInfo(int rx_device,int tx_device, - uint32_t rx_acdb_id, uint32_t tx_acdb_id) { -#else -static status_t updateDeviceInfo(int rx_device,int tx_device) { -#endif - ALOGV("updateDeviceInfo: E rx_device %d and tx_device %d", rx_device, tx_device); - bool isRxDeviceEnabled = false,isTxDeviceEnabled = false; - Routing_table *temp_ptr,*temp_head; - int tx_dev_prev = INVALID_DEVICE; - temp_head = head; - Mutex::Autolock lock(mDeviceSwitchLock); - - if (!getNodeByStreamType(VOICE_CALL) && !getNodeByStreamType(PCM_PLAY) -#ifdef QCOM_FM_ENABLED - && !getNodeByStreamType(FM_RADIO) -#endif -#ifdef QCOM_TUNNEL_LPA_ENABLED - && !getNodeByStreamType(LPA_DECODE) -#endif - ) { - ALOGV("No active voicecall/playback, disabling cur_rx %d", cur_rx); - if(cur_rx != INVALID_DEVICE && enableDevice(cur_rx, 0)) { - ALOGE("Disabling device failed for cur_rx %d", cur_rx); - } - cur_rx = rx_device; - } - - if(!getNodeByStreamType(VOICE_CALL) && !getNodeByStreamType(PCM_REC)) { - ALOGV("No active voicecall/recording, disabling cur_tx %d", cur_tx); - if(cur_tx != INVALID_DEVICE && enableDevice(cur_tx, 0)) { - ALOGE("Disabling device failed for cur_tx %d", cur_tx); - } - cur_tx = tx_device; - } - Mutex::Autolock lock_1(mRoutingTableLock); - - while(temp_head->next != NULL) { - temp_ptr = temp_head->next; - switch(temp_ptr->stream_type) { - case PCM_PLAY: -#ifdef QCOM_TUNNEL_LPA_ENABLED - case LPA_DECODE: -#endif -#ifdef QCOM_FM_ENABLED - case FM_RADIO: -#endif - ALOGD("The node type is %d and cur device %d new device %d ", temp_ptr->stream_type, temp_ptr->dev_id, rx_device); - if(rx_device == INVALID_DEVICE) - return -1; - if(rx_device == temp_ptr->dev_id) - break; - ALOGV("rx_device = %d,temp_ptr->dev_id = %d",rx_device,temp_ptr->dev_id); - if(isRxDeviceEnabled == false) { - enableDevice(temp_ptr->dev_id,0); - enableDevice(rx_device,1); - isRxDeviceEnabled = true; - } - if(msm_route_stream(PCM_PLAY,temp_ptr->dec_id,DEV_ID(temp_ptr->dev_id),0)) { - ALOGE("msm_route_stream(PCM_PLAY,%d,%d,0) failed",temp_ptr->dec_id,DEV_ID(temp_ptr->dev_id)); - } - if(msm_route_stream(PCM_PLAY,temp_ptr->dec_id,DEV_ID(rx_device),1)) { - ALOGE("msm_route_stream(PCM_PLAY,%d,%d,1) failed",temp_ptr->dec_id,DEV_ID(rx_device)); - } - modifyActiveDeviceOfStream(temp_ptr->stream_type,rx_device,INVALID_DEVICE); - cur_tx = tx_device ; - cur_rx = rx_device ; - break; - case PCM_REC: - - ALOGD("case PCM_REC"); - if(tx_device == INVALID_DEVICE) - return -1; - if(tx_device == temp_ptr->dev_id) - break; - - if(isTxDeviceEnabled == false) { - enableDevice(temp_ptr->dev_id,0); - enableDevice(tx_device,1); - isTxDeviceEnabled = true; - } - if(msm_route_stream(PCM_REC,temp_ptr->dec_id,DEV_ID(temp_ptr->dev_id),0)) { - ALOGE("msm_route_stream(PCM_REC,%d,%d,0) failed",temp_ptr->dec_id,DEV_ID(temp_ptr->dev_id)); - } - if(msm_route_stream(PCM_REC,temp_ptr->dec_id,DEV_ID(tx_device),1)) { - ALOGE("msm_route_stream(PCM_REC,%d,%d,1) failed",temp_ptr->dec_id,DEV_ID(tx_device)); - } - modifyActiveDeviceOfStream(PCM_REC,tx_device,INVALID_DEVICE); - tx_dev_prev = cur_tx; - cur_tx = tx_device ; - cur_rx = rx_device ; -#ifdef WITH_QCOM_VOIPMUTE - if((vMicMute == true) && (tx_dev_prev != cur_tx)) { - ALOGD("REC:device switch with mute enabled :tx_dev_prev %d cur_tx: %d",tx_dev_prev, cur_tx); - msm_device_mute(DEV_ID(cur_tx), true); - } -#endif - break; - case VOICE_CALL: - - ALOGD("case VOICE_CALL"); - if(rx_device == INVALID_DEVICE || tx_device == INVALID_DEVICE) - return -1; - if(rx_device == temp_ptr->dev_id && tx_device == temp_ptr->dev_id_tx) - break; - -#ifdef HTC_AUDIO - updateACDB(rx_device, tx_device, rx_acdb_id, tx_acdb_id); -#endif - - msm_route_voice(DEV_ID(rx_device),DEV_ID(tx_device),1); - - // Temporary work around for Speaker mode. The driver is not - // supporting Speaker Rx and Handset Tx combo - if(isRxDeviceEnabled == false) { - if (rx_device != temp_ptr->dev_id) - { - enableDevice(temp_ptr->dev_id,0); - } - isRxDeviceEnabled = true; - } - if(isTxDeviceEnabled == false) { - if (tx_device != temp_ptr->dev_id_tx) - { - enableDevice(temp_ptr->dev_id_tx,0); - } - isTxDeviceEnabled = true; - } - - if (rx_device != temp_ptr->dev_id) - { - enableDevice(rx_device,1); - } - - if (tx_device != temp_ptr->dev_id_tx) - { - enableDevice(tx_device,1); - } - - cur_rx = rx_device; - cur_tx = tx_device; - modifyActiveDeviceOfStream(VOICE_CALL,cur_rx,cur_tx); - break; - default: - break; - } - temp_head = temp_head->next; - } - - ALOGV("updateDeviceInfo: X cur_rx %d cur_tx %d", cur_rx, cur_tx); - return NO_ERROR; -} - -void freeMemory() { - Routing_table *temp; - while(head != NULL) { - temp = head->next; - free(head); - head = temp; - } -free(device_list); -} - -// -// ---------------------------------------------------------------------------- - -AudioHardware::AudioHardware() : - mInit(false), mMicMute(true), mFmFd(-1), mBluetoothNrec(true), - mBluetoothVGS(false), mBluetoothId(0), mVoiceVolume(1), mOutput(0), - mCurSndDevice(SND_DEVICE_CURRENT), mDualMicEnabled(false), mTtyMode(TTY_OFF) -#ifdef HTC_AUDIO - , mHACSetting(false), mBluetoothIdTx(0), mBluetoothIdRx(0), - mRecordState(false), mEffectEnabled(false) -#endif -#ifdef WITH_QCOM_VOIP_OVER_MVS - , mVoipFd(-1), mVoipInActive(false), mVoipOutActive(false), mDirectOutput(0) -#endif -{ -#ifdef HTC_AUDIO - int (*snd_get_num)(); - int (*snd_get_bt_endpoint)(msm_bt_endpoint *); - int (*set_acoustic_parameters)(); - int (*set_tpa2051_parameters)(); - int (*set_aic3254_parameters)(); - int (*support_back_mic)(); - - struct msm_bt_endpoint *ept; -#endif - - int control; - int i = 0,index = 0; - - head = (Routing_table* ) malloc(sizeof(Routing_table)); - head->next = NULL; - -#ifdef HTC_AUDIO - acoustic =:: dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW); - if (acoustic == NULL ) { - ALOGD("Could not open libhtc_acoustic.so"); - /* this is not really an error on non-htc devices... */ - mNumBTEndpoints = 0; - support_aic3254 = false; - support_tpa2051 = false; - support_htc_backmic = false; - } -#endif - - ALOGD("msm_mixer_open: Opening the device"); - control = msm_mixer_open("/dev/snd/controlC0", 0); - if(control< 0) - ALOGE("ERROR opening the device"); - - if((fp = fopen("/sys/devices/system/soc/soc0/build_id","r")) == NULL) { - ALOGE("Cannot open build_id file."); - } - else { - (void)fgets((char *)build_id,sizeof(build_id),fp); - } - -#ifdef WITH_QCOM_RESETALL - if(msm_reset_all_device() < 0) - ALOGE("msm_reset_all_device() failed"); -#endif - - mixer_cnt = msm_mixer_count(); - ALOGD("msm_mixer_count:mixer_cnt =%d",mixer_cnt); - - dev_cnt = msm_get_device_count(); - ALOGV("got device_count %d",dev_cnt); - if (dev_cnt <= 0) { - ALOGE("NO devices registered\n"); - return; - } - name = msm_get_device_list(); - device_list = (Device_table* )malloc(sizeof(Device_table)*DEVICE_COUNT); - if(device_list == NULL) { - ALOGE("malloc failed for device list"); - return; - } - for(i = 0;i= 0) { - ALOGV("Found device: %s:index = %d,dev_id: %d",( char* )name[i], index,device_list[index].dev_id); - } - device_list[index].class_id = msm_get_device_class(device_list[index].dev_id); - device_list[index].capability = msm_get_device_capability(device_list[index].dev_id); - ALOGV("class ID = %d,capablity = %d for device %d",device_list[index].class_id,device_list[index].capability,device_list[index].dev_id); - } -#ifdef WITH_QCOM_CALIBRATION - audcal_initialize(); -#endif - - CurrentComboDeviceData.DeviceId = INVALID_DEVICE; - CurrentComboDeviceData.StreamType = INVALID_STREAM; - -#ifdef HTC_AUDIO - // HTC specific functions - set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters"); - if ((*set_acoustic_parameters) == 0 ) { - ALOGE("Could not open set_acoustic_parameters()"); - return; - } - - int rc = set_acoustic_parameters(); - if (rc < 0) { - ALOGD("Could not set acoustic parameters to share memory: %d", rc); - } - - char value[PROPERTY_VALUE_MAX]; - /* Check the system property for enable or not the ALT function */ - property_get("htc.audio.alt.enable", value, "0"); - alt_enable = atoi(value); - ALOGV("Enable ALT function: %d", alt_enable); - - /* Check the system property for enable or not the HAC function */ - property_get("htc.audio.hac.enable", value, "0"); - hac_enable = atoi(value); - ALOGV("Enable HAC function: %d", hac_enable); - - set_tpa2051_parameters = (int (*)(void))::dlsym(acoustic, "set_tpa2051_parameters"); - if ((*set_tpa2051_parameters) == 0) { - ALOGI("set_tpa2051_parameters() not present"); - support_tpa2051 = false; - } - - if (support_tpa2051) { - if (set_tpa2051_parameters() < 0) { - ALOGI("Speaker amplifies tpa2051 is not supported"); - support_tpa2051 = false; - } - } - - set_aic3254_parameters = (int (*)(void))::dlsym(acoustic, "set_aic3254_parameters"); - if ((*set_aic3254_parameters) == 0 ) { - ALOGI("set_aic3254_parameters() not present"); - support_aic3254 = false; - } - - if (support_aic3254) { - if (set_aic3254_parameters() < 0) { - ALOGI("AIC3254 DSP is not supported"); - support_aic3254 = false; - } - } - - if (support_aic3254) { - set_sound_effect = (int (*)(const char*))::dlsym(acoustic, "set_sound_effect"); - if ((*set_sound_effect) == 0 ) { - ALOGI("set_sound_effect() not present"); - ALOGI("AIC3254 DSP is not supported"); - support_aic3254 = false; - } else - strcpy(mEffect, "\0"); - } - - support_back_mic = (int (*)(void))::dlsym(acoustic, "support_back_mic"); - if ((*support_back_mic) == 0 ) { - ALOGI("support_back_mic() not present"); - support_htc_backmic = false; - } - - if (support_htc_backmic) { - if (support_back_mic() != 1) { - ALOGI("HTC DualMic is not supported"); - support_htc_backmic = false; - } - } - - snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num"); - if ((*snd_get_num) == 0 ) { - ALOGD("Could not open snd_get_num()"); - } - - mNumBTEndpoints = snd_get_num(); - ALOGV("mNumBTEndpoints = %d", mNumBTEndpoints); - mBTEndpoints = new msm_bt_endpoint[mNumBTEndpoints]; - ALOGV("constructed %d SND endpoints)", mNumBTEndpoints); - ept = mBTEndpoints; - snd_get_bt_endpoint = (int (*)(msm_bt_endpoint *))::dlsym(acoustic, "snd_get_bt_endpoint"); - if ((*snd_get_bt_endpoint) == 0 ) { - mInit = true; - ALOGE("Could not open snd_get_bt_endpoint()"); - return; - } - snd_get_bt_endpoint(mBTEndpoints); - - for (int i = 0; i < mNumBTEndpoints; i++) { - ALOGV("BT name %s (tx,rx)=(%d,%d)", mBTEndpoints[i].name, mBTEndpoints[i].tx, mBTEndpoints[i].rx); - } -#endif - - mInit = true; -} - -AudioHardware::~AudioHardware() -{ - for (size_t index = 0; index < mInputs.size(); index++) { - closeInputStream((AudioStreamIn*)mInputs[index]); - } - mInputs.clear(); - closeOutputStream((AudioStreamOut*)mOutput); - if (acoustic) { - ::dlclose(acoustic); - acoustic = 0; - } - msm_mixer_close(); -#ifdef WITH_QCOM_CALIBRATION - audcal_deinitialize(); -#endif - freeMemory(); - fclose(fp); - mInit = false; -} - -status_t AudioHardware::initCheck() -{ - return mInit ? NO_ERROR : NO_INIT; -} - -AudioStreamOut* AudioHardware::openOutputStream( - uint32_t devices, int *format, uint32_t *channels, - uint32_t *sampleRate, status_t *status) - -{ - ALOGD("AudioHardware::openOutputStream devices %x format %d channels %d samplerate %d", - devices, *format, *channels, *sampleRate); - - audio_output_flags_t flags = static_cast (*status); - - - { // scope for the lock - Mutex::Autolock lock(mLock); - - // only one output stream allowed -#ifdef WITH_QCOM_VOIP_OVER_MVS - if (mOutput && !(flags & AUDIO_OUTPUT_FLAG_DIRECT) ) { -#else - if (mOutput) { -#endif - if (status) { - *status = INVALID_OPERATION; - } - ALOGE(" AudioHardware::openOutputStream Only one output stream allowed \n"); - return 0; - } -#ifdef WITH_QCOM_VOIP_OVER_MVS - status_t lStatus; - if(flags & AUDIO_OUTPUT_FLAG_DIRECT) { - if(mDirectOutput == 0) { - // open direct output stream - ALOGV(" AudioHardware::openOutputStream Direct output stream \n"); - AudioStreamOutDirect* out = new AudioStreamOutDirect(); - status_t lStatus = out->set(this, devices, format, channels, sampleRate); - if (status) { - *status = lStatus; - } - if (lStatus == NO_ERROR) { - mDirectOutput = out; - ALOGV(" \n set sucessful for AudioStreamOutDirect"); - } else { - ALOGE(" \n set Failed for AudioStreamOutDirect"); - delete out; - } - } - else - ALOGE(" \n AudioHardware::AudioStreamOutDirect is already open"); - return mDirectOutput; - } - else - { - ALOGV(" AudioHardware::openOutputStream AudioStreamOutMSM72xx output stream \n"); - // only one output stream allowed - if (mOutput) { - if (status) { - *status = INVALID_OPERATION; - } - ALOGE(" AudioHardware::openOutputStream Only one output stream allowed \n"); - return 0; - } - - // create new output stream - AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); - lStatus = out->set(this, devices, format, channels, sampleRate); - if (status) { - *status = lStatus; - } - if (lStatus == NO_ERROR) { - mOutput = out; - } else { - delete out; - } - return mOutput; - } - } -#else - // create new output stream - AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); - status_t lStatus = out->set(this, devices, format, channels, sampleRate); - if (status) { - *status = lStatus; - } - if (lStatus == NO_ERROR) { - mOutput = out; - } else { - delete out; - } - } - return mOutput; -#endif -} - -#ifdef QCOM_TUNNEL_LPA_ENABLED -AudioStreamOut* AudioHardware::openOutputSession( - uint32_t devices, int *format, status_t *status, int sessionId, - uint32_t samplingRate, uint32_t channels) -{ - AudioSessionOutMSM7xxx* out; - { // scope for the lock - Mutex::Autolock lock(mLock); - - // create new output stream - out = new AudioSessionOutMSM7xxx(); - status_t lStatus = out->set(this, devices, format, sessionId); - if (status) { - *status = lStatus; - } - if (lStatus != NO_ERROR) { - delete out; - out = NULL; - } - } - return out; -} -#endif /* QCOM_TUNNEL_LPA_ENABLED */ - -void AudioHardware::closeOutputStream(AudioStreamOut* out) { - Mutex::Autolock lock(mLock); -#ifdef WITH_QCOM_VOIP_OVER_MVS - if ((mOutput == 0 && mDirectOutput == 0) || ((mOutput != out) && (mDirectOutput != out))){ -#else - if (mOutput == 0 || mOutput != out) { -#endif - ALOGW("Attempt to close invalid output stream"); - } -#ifdef WITH_QCOM_VOIP_OVER_MVS - else if (mOutput == out) { -#else - else { -#endif - delete mOutput; - mOutput = 0; - } -#ifdef WITH_QCOM_VOIP_OVER_MVS - else if (mDirectOutput == out){ - ALOGV(" deleting mDirectOutput \n"); - delete mDirectOutput; - mDirectOutput = 0; - } -#endif -} - -AudioStreamIn* AudioHardware::openInputStream( - uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status, - AudioSystem::audio_in_acoustics acoustic_flags) -{ - // check for valid input source - ALOGD("AudioHardware::openInputStream devices %x format %d channels %d samplerate %d", - devices, *format, *channels, *sampleRate); - - if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) { - return 0; - } - - mLock.lock(); - -#ifdef WITH_QCOM_VOIP_OVER_MVS - AudioStreamIn *in; - if((devices == AudioSystem::DEVICE_IN_COMMUNICATION)&& (*sampleRate == 8000)) { - ALOGV("Create Audio stream Voip \n"); - AudioStreamInVoip* inVoip = new AudioStreamInVoip(); - status_t lStatus = NO_ERROR; - lStatus = inVoip->set(this, devices, format, channels, sampleRate, acoustic_flags); - if (status) { - *status = lStatus; - } - if (lStatus != NO_ERROR) { - ALOGE(" Error creating voip input \n"); - mLock.unlock(); - delete inVoip; - return 0; - } - mVoipInputs.add(inVoip); -#else - AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); - status_t lStatus = in->set(this, devices, format, channels, sampleRate, acoustic_flags); - if (status) { - *status = lStatus; - } - if (lStatus != NO_ERROR) { -#endif - mLock.unlock(); -#ifndef WITH_QCOM_VOIP_OVER_MVS - delete in; - return 0; -#else - return inVoip; - } else { - AudioStreamInMSM72xx* in72xx = new AudioStreamInMSM72xx(); - status_t lStatus = in72xx->set(this, devices, format, channels, sampleRate, acoustic_flags); - if (status) { - *status = lStatus; - } - if (lStatus != NO_ERROR) { - ALOGE("Error creating Audio stream AudioStreamInMSM72xx \n"); - mLock.unlock(); - delete in72xx; - return 0; - } - mInputs.add(in72xx); - mLock.unlock(); - return in72xx; -#endif - } -#ifndef WITH_QCOM_VOIP_OVER_MVS - mInputs.add(in); - mLock.unlock(); - - return in; -#endif -} - -void AudioHardware::closeInputStream(AudioStreamIn* in) { - Mutex::Autolock lock(mLock); - -#ifdef WITH_QCOM_VOIP_OVER_MVS - ssize_t index = -1; - if((index = mInputs.indexOf((AudioStreamInMSM72xx *)in)) >= 0) { - ALOGV("closeInputStream AudioStreamInMSM72xx"); -#else - ssize_t index = mInputs.indexOf((AudioStreamInMSM72xx *)in); - if (index < 0) { - ALOGW("Attempt to close invalid input stream"); - } else { -#endif - mLock.unlock(); - delete mInputs[index]; - mLock.lock(); - mInputs.removeAt(index); -#ifdef WITH_QCOM_VOIP_OVER_MVS - } else if ((index = mVoipInputs.indexOf((AudioStreamInVoip *)in)) >= 0) { - ALOGV("closeInputStream mVoipInputs"); - mLock.unlock(); - delete mVoipInputs[index]; - mLock.lock(); - mVoipInputs.removeAt(index); - } else { - ALOGE("Attempt to close invalid input stream"); -#endif - } -} - -status_t AudioHardware::setMode(int mode) -{ - status_t status = AudioHardwareBase::setMode(mode); - if (status == NO_ERROR) { - // make sure that doAudioRouteOrMute() is called by doRouting() - // even if the new device selected is the same as current one. - clearCurDevice(); - } - return status; -} - -bool AudioHardware::checkOutputStandby() -{ - if (mOutput) - if (!mOutput->checkStandby()) - return false; - - return true; -} - -status_t AudioHardware::setMicMute(bool state) -{ - Mutex::Autolock lock(mLock); - return setMicMute_nosync(state); -} - -// always call with mutex held -status_t AudioHardware::setMicMute_nosync(bool state) -{ - if (mMicMute != state) { - mMicMute = state; - ALOGD("setMicMute_nosync calling voice mute with the mMicMute %d", mMicMute); -#ifdef WITH_QCOM_VOIPMUTE - if (isStreamOnAndActive(PCM_REC) && (mMode == AudioSystem::MODE_IN_COMMUNICATION)) { - vMicMute = state; - ALOGD("VOIP Active: vMicMute %d\n", vMicMute); - msm_device_mute(DEV_ID(cur_tx), vMicMute); - } else { -#endif - ALOGD("setMicMute_nosync:voice_mute\n"); - msm_set_voice_tx_mute(mMicMute); -#ifdef WITH_QCOM_VOIPMUTE - } -#endif - } - return NO_ERROR; -} - -status_t AudioHardware::getMicMute(bool* state) -{ - *state = mMicMute; - return NO_ERROR; -} - -status_t AudioHardware::setParameters(const String8& keyValuePairs) -{ - AudioParameter param = AudioParameter(keyValuePairs); - String8 value; - String8 key; - const char BT_NREC_KEY[] = "bt_headset_nrec"; - const char BT_NAME_KEY[] = "bt_headset_name"; - const char BT_NREC_VALUE_ON[] = "on"; -#ifdef QCOM_FM_ENABLED - const char FM_NAME_KEY[] = "FMRadioOn"; - const char FM_VALUE_HANDSET[] = "handset"; - const char FM_VALUE_SPEAKER[] = "speaker"; - const char FM_VALUE_HEADSET[] = "headset"; - const char FM_VALUE_FALSE[] = "false"; -#endif -#ifdef HTC_AUDIO - const char ACTIVE_AP[] = "active_ap"; - const char EFFECT_ENABLED[] = "sound_effect_enable"; -#endif - - ALOGV("setParameters() %s", keyValuePairs.string()); - - if (keyValuePairs.length() == 0) return BAD_VALUE; - - key = String8(BT_NREC_KEY); - if (param.get(key, value) == NO_ERROR) { - if (value == BT_NREC_VALUE_ON) { - mBluetoothNrec = true; - } else { - mBluetoothNrec = false; - ALOGI("Turning noise reduction and echo cancellation off for BT " - "headset"); - } - } - - key = String8(BTHEADSET_VGS); - if (param.get(key, value) == NO_ERROR) { - if (value == BT_NREC_VALUE_ON) { - mBluetoothVGS = true; - } else { - mBluetoothVGS = false; - } - } - - key = String8(BT_NAME_KEY); - if (param.get(key, value) == NO_ERROR) { -#ifdef HTC_AUDIO - mBluetoothIdTx = 0; - mBluetoothIdRx = 0; - for (int i = 0; i < mNumBTEndpoints; i++) { - if (!strcasecmp(value.string(), mBTEndpoints[i].name)) { - mBluetoothIdTx = mBTEndpoints[i].tx; - mBluetoothIdRx = mBTEndpoints[i].rx; - ALOGD("Using custom acoustic parameters for %s", value.string()); - break; - } - } - if (mBluetoothIdTx == 0) { - ALOGD("Using default acoustic parameters " - "(%s not in acoustic database)", value.string()); - } -#endif - doRouting(NULL); - } - - key = String8(DUALMIC_KEY); - if (param.get(key, value) == NO_ERROR) { - if (value == "true") { - mDualMicEnabled = true; - ALOGI("DualMike feature Enabled"); - } else { - mDualMicEnabled = false; - ALOGI("DualMike feature Disabled"); - } - doRouting(NULL); - } - - key = String8(TTY_MODE_KEY); - if (param.get(key, value) == NO_ERROR) { - if (value == "full" || value == "tty_full") { - mTtyMode = TTY_FULL; - } else if (value == "hco" || value == "tty_hco") { - mTtyMode = TTY_HCO; - } else if (value == "vco" || value == "tty_vco") { - mTtyMode = TTY_VCO; - } else { - mTtyMode = TTY_OFF; - } - if(mMode != AudioSystem::MODE_IN_CALL){ - return NO_ERROR; - } - ALOGI("Changed TTY Mode=%s", value.string()); - if((mMode == AudioSystem::MODE_IN_CALL) && - (cur_rx == DEVICE_HEADSET_RX) && - (cur_tx == DEVICE_HEADSET_TX)) - doRouting(NULL); - } - -#ifdef HTC_AUDIO - key = String8(ACTIVE_AP); - if (param.get(key, value) == NO_ERROR) { - const char* active_ap = value.string(); - ALOGD("Active AP = %s", active_ap); - strcpy(mActiveAP, active_ap); - - const char* dsp_effect = "\0"; - key = String8(DSP_EFFECT_KEY); - if (param.get(key, value) == NO_ERROR) { - ALOGD("DSP Effect = %s", value.string()); - dsp_effect = value.string(); - strcpy(mEffect, dsp_effect); - } - - key = String8(EFFECT_ENABLED); - if (param.get(key, value) == NO_ERROR) { - const char* sound_effect_enable = value.string(); - ALOGD("Sound Effect Enabled = %s", sound_effect_enable); - if (value == "on") { - mEffectEnabled = true; - if (support_aic3254) - aic3254_config(get_snd_dev()); - } else { - strcpy(mEffect, "\0"); - mEffectEnabled = false; - } - } - } -#endif - - return NO_ERROR; -} - -String8 AudioHardware::getParameters(const String8& keys) -{ - AudioParameter param = AudioParameter(keys); - String8 value; - - String8 key = String8(DUALMIC_KEY); - if (param.get(key, value) == NO_ERROR) { - value = String8(mDualMicEnabled ? "true" : "false"); - param.add(key, value); - } - key = String8(BTHEADSET_VGS); - if (param.get(key, value) == NO_ERROR) { - if(mBluetoothVGS) - param.addInt(String8("isVGS"), true); - } -#ifdef WITH_QCOM_SPEECH - key = String8("tunneled-input-formats"); - if ( param.get(key,value) == NO_ERROR ) { - param.addInt(String8("AMR"), true ); - if (build_id[17] != '1') { - param.addInt(String8("EVRC"), true ); - param.addInt(String8("QCELP"), true ); - } - } -#endif - -#ifdef QCOM_FM_ENABLED - key = String8("Fm-radio"); - if ( param.get(key,value) == NO_ERROR ) { - if ( getNodeByStreamType(FM_RADIO) ) { - param.addInt(String8("isFMON"), true ); - } - } -#endif - -#ifdef HTC_AUDIO - key = String8(DSP_EFFECT_KEY); - if (param.get(key, value) == NO_ERROR) { - value = String8(mCurDspProfile); - param.add(key, value); - } -#endif - - ALOGV("AudioHardware::getParameters() %s", param.toString().string()); - return param.toString(); -} - - -static unsigned calculate_audpre_table_index(unsigned index) -{ - switch (index) { - case 48000: return SAMP_RATE_INDX_48000; - case 44100: return SAMP_RATE_INDX_44100; - case 32000: return SAMP_RATE_INDX_32000; - case 24000: return SAMP_RATE_INDX_24000; - case 22050: return SAMP_RATE_INDX_22050; - case 16000: return SAMP_RATE_INDX_16000; - case 12000: return SAMP_RATE_INDX_12000; - case 11025: return SAMP_RATE_INDX_11025; - case 8000: return SAMP_RATE_INDX_8000; - default: return -1; - } -} -size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) -{ - if ((format != AudioSystem::PCM_16_BIT) && -#ifdef WITH_QCOM_SPEECH - (format != AudioSystem::AMR_NB) && - (format != AudioSystem::EVRC) && - (format != AudioSystem::QCELP) && -#endif - (format != AudioSystem::AAC)){ - ALOGW("getInputBufferSize bad format: %d", format); - return 0; - } - if (channelCount < 1 || channelCount > 2) { - ALOGW("getInputBufferSize bad channel count: %d", channelCount); - return 0; - } - - if (format == AudioSystem::AAC) - return 2048; -#ifdef WITH_QCOM_SPEECH - else if (format == AudioSystem::AMR_NB) - return 320*channelCount; - else if (format == AudioSystem::EVRC) - return 230*channelCount; - else if (format == AudioSystem::QCELP) - return 350*channelCount; -#endif -#ifdef WITH_QCOM_VOIP_OVER_MVS - else if (sampleRate == AUDIO_HW_VOIP_SAMPLERATE_8K) - return 320*channelCount; - else if (sampleRate == AUDIO_HW_VOIP_SAMPLERATE_16K) - return 640*channelCount; -#endif - else - { - if (build_id[17] == '1') { - /* - Return pcm record buffer size based on the sampling rate: - If sampling rate >= 44.1 Khz, use 512 samples/channel pcm recording and - If sampling rate < 44.1 Khz, use 256 samples/channel pcm recording - */ - if(sampleRate>=44100) - return 1024*channelCount; - else - return 512*channelCount; - } - else { - return 2048*channelCount; - } - } -} -static status_t set_volume_rpc(uint32_t device, - uint32_t method, - uint32_t volume) -{ - ALOGV("set_volume_rpc(%d, %d, %d)\n", device, method, volume); - - if (device == -1UL) return NO_ERROR; - return NO_ERROR; -} - -status_t AudioHardware::setVoiceVolume(float v) -{ - if (v < 0.0) { - ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); - v = 0.0; - } else if (v > 1.0) { - ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); - v = 1.0; - } - - mVoiceVolume = v; - - int vol = lrint(v * 100.0); - ALOGD("setVoiceVolume(%f)\n", v); - ALOGI("Setting in-call volume to %d (available range is 0 to 100)\n", vol); - - if(msm_set_voice_rx_vol(vol)) { - ALOGE("msm_set_voice_rx_vol(%d) failed errno = %d",vol,errno); - return -1; - } - ALOGV("msm_set_voice_rx_vol(%d) succeeded",vol); - -#ifdef HTC_AUDIO - if (mMode == AudioSystem::MODE_IN_CALL && - mCurSndDevice != SND_DEVICE_BT && - mCurSndDevice != SND_DEVICE_CARKIT && - mCurSndDevice != SND_DEVICE_BT_EC_OFF) - { - uint32_t new_tx_acdb = getACDB(MOD_TX, mCurSndDevice); - uint32_t new_rx_acdb = getACDB(MOD_RX, mCurSndDevice); - - int (*update_voice_acdb)(uint32_t, uint32_t); - - update_voice_acdb = (int (*)(uint32_t, uint32_t))::dlsym(acoustic, "update_voice_acdb"); - if ((*update_voice_acdb) == 0 ) { - ALOGE("Could not open update_voice_acdb()"); - } - - int rc = update_voice_acdb(new_tx_acdb, new_rx_acdb); - if (rc < 0) - ALOGE("Could not set update_voice_acdb: %d", rc); - else - ALOGI("update_voice_acdb(%d, %d) succeeded", new_tx_acdb, new_rx_acdb); - } -#endif - - return NO_ERROR; -} -#ifdef QCOM_FM_ENABLED -status_t AudioHardware::setFmVolume(float v) -{ - int vol = android::AudioSystem::logToLinear( v ); - if ( vol > 100 ) { - vol = 100; - } - else if ( vol < 0 ) { - vol = 0; - } - ALOGV("setFmVolume(%f)\n", v); - Routing_table* temp = NULL; - temp = getNodeByStreamType(FM_RADIO); - if(temp == NULL){ - ALOGV("No Active FM stream is running"); - return NO_ERROR; - } - if(msm_set_volume(temp->dec_id, vol)) { - ALOGE("msm_set_volume(%d) failed for FM errno = %d",vol,errno); - return -1; - } - ALOGV("msm_set_volume(%d) for FM succeeded",vol); - return NO_ERROR; -} -#endif - -status_t AudioHardware::setMasterVolume(float v) -{ - Mutex::Autolock lock(mLock); - int vol = ceil(v * 7.0); - ALOGI("Set master volume to %d.\n", vol); - - set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol); - set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol); - set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol); - set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol); - //TBD - does HDMI require this handling - - // We return an error code here to let the audioflinger do in-software - // volume on top of the maximum volume that we set through the SND API. - // return error - software mixer will handle it - return -1; -} - -#ifdef HTC_AUDIO -status_t get_batt_temp(int *batt_temp) { - ALOGD("Enable ALT for speaker"); - - int i, fd, len; - char get_batt_temp[6] = { 0 }; - const char *fn[] = { - "/sys/devices/platform/rs30100001:00000000.0/power_supply/battery/batt_temp", - "/sys/devices/platform/rs30100001:00000000/power_supply/battery/batt_temp" }; - - for (i = 0; i < 2; i++) { - if ((fd = open(fn[i], O_RDONLY)) >= 0) - break; - } - if (fd <= 0) { - ALOGE("Couldn't open sysfs file batt_temp"); - return UNKNOWN_ERROR; - } - - if ((len = read(fd, get_batt_temp, sizeof(get_batt_temp))) <= 1) { - ALOGE("read battery temp fail: %s", strerror(errno)); - close(fd); - return BAD_VALUE; - } - - *batt_temp = strtol(get_batt_temp, NULL, 10); - ALOGD("ALT batt_temp = %d", *batt_temp); - - close(fd); - return NO_ERROR; -} - -status_t do_tpa2051_control(int mode) -{ - int fd, rc; - int tpa_mode = 0; - int batt_temp = 0; - - if (mode) { - if (cur_rx == DEVICE_HEADSET_RX) - tpa_mode = TPA2051_MODE_VOICECALL_HEADSET; - else if (cur_rx == DEVICE_SPEAKER_RX) - tpa_mode = TPA2051_MODE_VOICECALL_SPKR; - } else { - switch (cur_rx) { - case DEVICE_FMRADIO_HEADSET_RX: - tpa_mode = TPA2051_MODE_FM_HEADSET; - break; - case DEVICE_FMRADIO_SPEAKER_RX: - tpa_mode = TPA2051_MODE_FM_SPKR; - break; - case DEVICE_SPEAKER_HEADSET_RX: - tpa_mode = TPA2051_MODE_RING; - break; - case DEVICE_HEADSET_RX: - tpa_mode = TPA2051_MODE_PLAYBACK_HEADSET; - break; - case DEVICE_SPEAKER_RX: - tpa_mode = TPA2051_MODE_PLAYBACK_SPKR; - break; - default: - break; - } - } - - fd = open("/dev/tpa2051d3", O_RDWR); - if (fd < 0) { - ALOGE("can't open /dev/tpa2051d3 %d", fd); - return -1; - } - - if (tpa_mode != cur_tpa_mode) { - cur_tpa_mode = tpa_mode; - rc = ioctl(fd, TPA2051_SET_MODE, &tpa_mode); - if (rc < 0) - ALOGE("ioctl TPA2051_SET_MODE failed: %s", strerror(errno)); - else - ALOGD("update TPA2051_SET_MODE to mode %d success", tpa_mode); - } - - if (alt_enable && cur_rx == DEVICE_SPEAKER_RX) { - if (get_batt_temp(&batt_temp) == NO_ERROR) { - if (batt_temp < 50) { - tpa_mode = 629276672; - rc = ioctl(fd, TPA2051_SET_CONFIG, &tpa_mode); - if (rc < 0) - ALOGE("ioctl TPA2051_SET_CONFIG failed: %s", strerror(errno)); - else - ALOGD("update TPA2051_SET_CONFIG to mode %d success", tpa_mode); - } - } - } - - close(fd); - return 0; -} - -static status_t do_route_audio_rpc(uint32_t device, - bool ear_mute, bool mic_mute, - uint32_t rx_acdb_id, uint32_t tx_acdb_id) -#else -static status_t do_route_audio_rpc(uint32_t device, - bool ear_mute, bool mic_mute) -#endif -{ - if(device == -1) - return 0; - - int new_rx_device = INVALID_DEVICE,new_tx_device = INVALID_DEVICE,fm_device = INVALID_DEVICE; - Routing_table* temp = NULL; - ALOGV("do_route_audio_rpc(%d, %d, %d)", device, ear_mute, mic_mute); - - if(device == SND_DEVICE_HANDSET) { - new_rx_device = DEVICE_HANDSET_RX; - new_tx_device = DEVICE_HANDSET_TX; - ALOGV("In HANDSET"); - } - else if(device == SND_DEVICE_SPEAKER) { - new_rx_device = DEVICE_SPEAKER_RX; - new_tx_device = DEVICE_SPEAKER_TX; - ALOGV("In SPEAKER"); - } - else if(device == SND_DEVICE_HEADSET) { - new_rx_device = DEVICE_HEADSET_RX; - new_tx_device = DEVICE_HEADSET_TX; - ALOGV("In HEADSET"); - } - else if(device == SND_DEVICE_NO_MIC_HEADSET) { - new_rx_device = DEVICE_HEADSET_RX; - new_tx_device = DEVICE_HANDSET_TX; - ALOGV("In NO MIC HEADSET"); - } -#ifdef QCOM_FM_ENABLED - else if (device == SND_DEVICE_FM_HANDSET) { - fm_device = DEVICE_FMRADIO_HANDSET_RX; - ALOGV("In FM HANDSET"); - } - else if(device == SND_DEVICE_FM_SPEAKER) { - fm_device = DEVICE_FMRADIO_SPEAKER_RX; - ALOGV("In FM SPEAKER"); - } - else if(device == SND_DEVICE_FM_HEADSET) { - fm_device = DEVICE_FMRADIO_HEADSET_RX; - ALOGV("In FM HEADSET"); - } -#endif - else if(device == SND_DEVICE_IN_S_SADC_OUT_HANDSET) { - new_rx_device = DEVICE_HANDSET_RX; - new_tx_device = DEVICE_DUALMIC_HANDSET_TX; - ALOGV("In DUALMIC_HANDSET"); - } - else if(device == SND_DEVICE_IN_S_SADC_OUT_SPEAKER_PHONE) { - new_rx_device = DEVICE_SPEAKER_RX; - new_tx_device = DEVICE_DUALMIC_SPEAKER_TX; - ALOGV("In DUALMIC_SPEAKER"); - } - else if(device == SND_DEVICE_TTY_FULL) { - new_rx_device = DEVICE_TTY_HEADSET_MONO_RX; - new_tx_device = DEVICE_TTY_HEADSET_MONO_TX; - ALOGV("In TTY_FULL"); - } - else if(device == SND_DEVICE_TTY_VCO) { - new_rx_device = DEVICE_TTY_HEADSET_MONO_RX; - new_tx_device = DEVICE_HANDSET_TX; - ALOGV("In TTY_VCO"); - } - else if(device == SND_DEVICE_TTY_HCO) { - new_rx_device = DEVICE_HANDSET_RX; - new_tx_device = DEVICE_TTY_HEADSET_MONO_TX; - ALOGV("In TTY_HCO"); - } -#ifdef HTC_AUDIO - else if((device == SND_DEVICE_BT) || - (device == SND_DEVICE_BT_EC_OFF)) { -#else - else if(device == SND_DEVICE_BT) { -#endif - new_rx_device = DEVICE_BT_SCO_RX; - new_tx_device = DEVICE_BT_SCO_TX; - ALOGV("In BT_HCO"); - } - else if(device == SND_DEVICE_HEADSET_AND_SPEAKER) { - new_rx_device = DEVICE_SPEAKER_HEADSET_RX; - new_tx_device = DEVICE_HEADSET_TX; - ALOGV("In DEVICE_SPEAKER_HEADSET_RX and DEVICE_HEADSET_TX"); - } - else if(device == SND_DEVICE_HEADPHONE_AND_SPEAKER) { - new_rx_device = DEVICE_SPEAKER_HEADSET_RX; - new_tx_device = DEVICE_HANDSET_TX; - ALOGV("In DEVICE_SPEAKER_HEADSET_RX and DEVICE_HANDSET_TX"); - } - else if (device == SND_DEVICE_HDMI) { - new_rx_device = DEVICE_HDMI_STERO_RX; - new_tx_device = cur_tx; - ALOGV("In DEVICE_HDMI_STERO_RX and cur_tx"); - } -#ifdef QCOM_FM_ENABLED - else if (device == SND_DEVICE_FM_TX) { - new_rx_device = DEVICE_FMRADIO_STEREO_RX; - new_tx_device = cur_tx; - ALOGV("In DEVICE_FMRADIO_STEREO_RX and cur_tx"); - } -#endif -#ifdef SAMSUNG_AUDIO - else if (device == SND_DEVICE_VOIP_HANDSET) { - new_rx_device = DEVICE_HANDSET_VOIP_RX; - new_tx_device = DEVICE_HANDSET_VOIP_TX; - ALOGV("In VOIP HANDSET"); - } - else if (device == SND_DEVICE_VOIP_SPEAKER) { - new_rx_device = DEVICE_SPEAKER_VOIP_RX; - new_tx_device = DEVICE_SPEAKER_VOIP_TX; - ALOGV("In VOIP SPEAKER"); - } - else if (device == SND_DEVICE_VOIP_HEADSET) { - new_rx_device = DEVICE_HEADSET_VOIP_RX; - new_tx_device = DEVICE_HEADSET_VOIP_TX; - ALOGV("In VOIP HEADSET"); - } - else if (device == SND_DEVICE_CALL_HANDSET) { - new_rx_device = DEVICE_HANDSET_CALL_RX; - new_tx_device = DEVICE_HANDSET_CALL_TX; - ALOGV("In CALL HANDSET"); - } - else if (device == SND_DEVICE_CALL_SPEAKER) { - new_rx_device = DEVICE_SPEAKER_CALL_RX; - new_tx_device = DEVICE_SPEAKER_CALL_TX; - ALOGV("In CALL SPEAKER"); - } - else if (device == SND_DEVICE_CALL_HEADSET) { - new_rx_device = DEVICE_HEADSET_CALL_RX; - new_tx_device = DEVICE_HEADSET_CALL_TX; - ALOGV("In CALL HEADSET"); - } -#endif -#ifdef BACK_MIC_CAMCORDER - else if (device == SND_DEVICE_BACK_MIC_CAMCORDER) { - new_rx_device = cur_rx; - new_tx_device = DEVICE_CAMCORDER_TX; - ALOGV("In BACK_MIC_CAMCORDER"); - } -#endif - - if(new_rx_device != INVALID_DEVICE) - ALOGD("new_rx = %d", DEV_ID(new_rx_device)); - if(new_tx_device != INVALID_DEVICE) - ALOGD("new_tx = %d", DEV_ID(new_tx_device)); - - if (ear_mute == false && !isStreamOn(VOICE_CALL)) { - ALOGV("Going to enable RX/TX device for voice stream"); - // Routing Voice - if ( (new_rx_device != INVALID_DEVICE) && (new_tx_device != INVALID_DEVICE)) - { - ALOGD("Starting voice on Rx %d and Tx %d device", DEV_ID(new_rx_device), DEV_ID(new_tx_device)); - -#ifdef HTC_AUDIO - updateACDB(new_rx_device, new_tx_device, rx_acdb_id, tx_acdb_id); -#endif - - msm_route_voice(DEV_ID(new_rx_device),DEV_ID(new_tx_device), 1); - } - else - { - return -1; - } - - if(cur_rx == INVALID_DEVICE || new_rx_device == INVALID_DEVICE) - return -1; - - if(cur_tx == INVALID_DEVICE || new_tx_device == INVALID_DEVICE) - return -1; - - //Enable RX device - if(new_rx_device != cur_rx) { - enableDevice(cur_rx,0); - } - enableDevice(new_rx_device,1); - - //Enable TX device - if(new_tx_device != cur_tx) { - enableDevice(cur_tx,0); - } - enableDevice(new_tx_device,1); - - // start Voice call - ALOGD("Starting voice call and UnMuting the call"); - msm_start_voice(); - msm_set_voice_tx_mute(0); - cur_rx = new_rx_device; - cur_tx = new_tx_device; - addToTable(0,cur_rx,cur_tx,VOICE_CALL,true); -#ifdef HTC_AUDIO - updateDeviceInfo(new_rx_device,new_tx_device, rx_acdb_id, tx_acdb_id); -#else - updateDeviceInfo(new_rx_device,new_tx_device); -#endif - } - else if (ear_mute == true && isStreamOnAndActive(VOICE_CALL)) { - ALOGV("Going to disable RX/TX device during end of voice call"); - temp = getNodeByStreamType(VOICE_CALL); - if(temp == NULL) - return 0; - - // Ending voice call - ALOGD("Ending Voice call"); - msm_end_voice(); - deleteFromTable(VOICE_CALL); -#ifdef HTC_AUDIO - updateDeviceInfo(new_rx_device,new_tx_device, 0, 0); -#else - updateDeviceInfo(new_rx_device,new_tx_device); -#endif - if(new_rx_device != INVALID_DEVICE && new_tx_device != INVALID_DEVICE) { - cur_rx = new_rx_device; - cur_tx = new_tx_device; - } - } - else { -#ifdef HTC_AUDIO - updateDeviceInfo(new_rx_device,new_tx_device, rx_acdb_id, tx_acdb_id); - } - - if (support_tpa2051) - do_tpa2051_control(ear_mute ^1); -#else - updateDeviceInfo(new_rx_device,new_tx_device); - } -#endif - - return NO_ERROR; -} - -#ifdef HTC_AUDIO -status_t AudioHardware::doAudioRouteOrMuteHTC(uint32_t device) -{ - uint32_t rx_acdb_id = 0; - uint32_t tx_acdb_id = 0; - - if (device == SND_DEVICE_BT) { - if (!mBluetoothNrec) - device = SND_DEVICE_BT_EC_OFF; - } - - if (support_aic3254) { - aic3254_config(device); - do_aic3254_control(device); - } - - if (device == SND_DEVICE_BT) { - if (mBluetoothIdTx != 0) { - rx_acdb_id = mBluetoothIdRx; - tx_acdb_id = mBluetoothIdTx; - } else { - /* use default BT entry defined in AudioBTID.csv */ - rx_acdb_id = mBTEndpoints[0].rx; - tx_acdb_id = mBTEndpoints[0].tx; - ALOGD("Update ACDB ID to default BT setting"); - } - } else if (device == SND_DEVICE_CARKIT || - device == SND_DEVICE_BT_EC_OFF) { - if (mBluetoothIdTx != 0) { - rx_acdb_id = mBluetoothIdRx; - tx_acdb_id = mBluetoothIdTx; - } else { - /* use default carkit entry defined in AudioBTID.csv */ - rx_acdb_id = mBTEndpoints[1].rx; - tx_acdb_id = mBTEndpoints[1].tx; - ALOGD("Update ACDB ID to default carkit setting"); - } - } else if (isInCall() && hac_enable && mHACSetting && - device == SND_DEVICE_HANDSET) { - ALOGD("Update acdb id to hac profile."); - rx_acdb_id = ACDB_ID_HAC_HANDSET_SPKR; - tx_acdb_id = ACDB_ID_HAC_HANDSET_MIC; - } else { - if (isInCall()) { - rx_acdb_id = getACDB(MOD_RX, device); - tx_acdb_id = getACDB(MOD_TX, device); - } else { - if (!checkOutputStandby()) - rx_acdb_id = getACDB(MOD_PLAY, device); - - if (mRecordState) - tx_acdb_id = getACDB(MOD_REC, device); - } - } - - ALOGV("doAudioRouteOrMuteHTC: rx acdb %d, tx acdb %d", rx_acdb_id, tx_acdb_id); - ALOGV("doAudioRouteOrMuteHTC() device %x, mMode %d, mMicMute %d", device, mMode, mMicMute); -#ifdef WITH_QCOM_VOIP_OVER_MVS - int earMute = (mMode != AudioSystem::MODE_IN_CALL) && (mMode != AudioSystem::MODE_IN_COMMUNICATION); - return do_route_audio_rpc(device,earMute, mMicMute, rx_acdb_id, tx_acdb_id); -#else - return do_route_audio_rpc(device, !isInCall(), mMicMute, rx_acdb_id, tx_acdb_id); -#endif -} -#endif - -// always call with mutex held -status_t AudioHardware::doAudioRouteOrMute(uint32_t device) -{ -// BT acoustics is not supported. This might be used by OEMs. Hence commenting -// the code and not removing it. -#if 0 - if (device == (uint32_t)SND_DEVICE_BT || device == (uint32_t)SND_DEVICE_CARKIT) { - if (mBluetoothId) { - device = mBluetoothId; - } else if (!mBluetoothNrec) { - device = SND_DEVICE_BT_EC_OFF; - } - } -#endif - - status_t ret = NO_ERROR; - -#ifdef HTC_AUDIO - ret = doAudioRouteOrMuteHTC(device); -#else - ALOGV("doAudioRouteOrMute() device %d, mMode %d, mMicMute %d", device, mMode, mMicMute); -#ifdef WITH_QCOM_VOIP_OVER_MVS - int earMute = (mMode != AudioSystem::MODE_IN_CALL) && (mMode != AudioSystem::MODE_IN_COMMUNICATION); - ret = do_route_audio_rpc(device, earMute, mMicMute); -#else - ret = do_route_audio_rpc(device, !isInCall(), mMicMute); -#endif -#endif - - if (isStreamOnAndActive(VOICE_CALL) && mMicMute == false) - msm_set_voice_tx_mute(0); - - if (isInCall()) - setVoiceVolume(mVoiceVolume); - - return ret; -} - - -#ifdef HTC_AUDIO -status_t AudioHardware::get_mMode(void) { - return mMode; -} - -status_t AudioHardware::set_mRecordState(bool onoff) { - mRecordState = onoff; - return 0; -} - -status_t AudioHardware::get_mRecordState(void) { - return mRecordState; -} - -status_t AudioHardware::get_snd_dev(void) { - return mCurSndDevice; -} - -uint32_t AudioHardware::getACDB(int mode, uint32_t device) { - - uint32_t acdb_id = 0; - int batt_temp = 0; - int vol = lrint(mVoiceVolume * 100.0); - - if (mMode == AudioSystem::MODE_IN_CALL && - device <= SND_DEVICE_NO_MIC_HEADSET) { - if (mode == MOD_RX) { - switch (device) { - case SND_DEVICE_HANDSET: - acdb_id = vol / 20 + 201; - break; - case SND_DEVICE_HEADSET: - case SND_DEVICE_NO_MIC_HEADSET: - acdb_id = vol / 20 + 401; - break; - case SND_DEVICE_SPEAKER: - acdb_id = vol / 20 + 601; - break; - default: - break; - } - } else if (mode == MOD_TX) { - switch (device) { - case SND_DEVICE_HANDSET: - acdb_id = vol / 20 + 101; - break; - case SND_DEVICE_HEADSET: - case SND_DEVICE_NO_MIC_HEADSET: - acdb_id = vol / 20 + 301; - break; - case SND_DEVICE_SPEAKER: - acdb_id = vol / 20 + 501; - break; - default: - break; - } - } - } else { - if (mode == MOD_PLAY) { - switch (device) { - case SND_DEVICE_HEADSET: - case SND_DEVICE_NO_MIC_HEADSET: - case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: - case SND_DEVICE_FM_HEADSET: - acdb_id = ACDB_ID_HEADSET_PLAYBACK; - break; - case SND_DEVICE_SPEAKER: - case SND_DEVICE_FM_SPEAKER: - case SND_DEVICE_SPEAKER_BACK_MIC: - acdb_id = ACDB_ID_SPKR_PLAYBACK; - if (alt_enable) { - if (get_batt_temp(&batt_temp) == NO_ERROR) { - if (batt_temp < 50) - acdb_id = ACDB_ID_ALT_SPKR_PLAYBACK; - } - } - break; - case SND_DEVICE_HEADSET_AND_SPEAKER: - case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: - case SND_DEVICE_HEADPHONE_AND_SPEAKER: - acdb_id = ACDB_ID_HEADSET_RINGTONE_PLAYBACK; - break; - default: - break; - } - } else if (mode == MOD_REC) { - switch (device) { - case SND_DEVICE_HEADSET: - case SND_DEVICE_FM_HEADSET: - case SND_DEVICE_FM_SPEAKER: - case SND_DEVICE_HEADSET_AND_SPEAKER: - acdb_id = ACDB_ID_EXT_MIC_REC; - break; - case SND_DEVICE_HANDSET: - case SND_DEVICE_NO_MIC_HEADSET: - case SND_DEVICE_SPEAKER: - acdb_id = ACDB_ID_INT_MIC_REC; - break; - case SND_DEVICE_SPEAKER_BACK_MIC: - case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: - case SND_DEVICE_HANDSET_BACK_MIC: - case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: - acdb_id = ACDB_ID_CAMCORDER; - break; - default: - break; - } - } - } - ALOGV("getACDB, return ID %d", acdb_id); - return acdb_id; -} - -status_t AudioHardware::do_aic3254_control(uint32_t device) { - ALOGD("do_aic3254_control device: %d mode: %d record: %d", device, mMode, mRecordState); - - uint32_t new_aic_txmode = UPLINK_OFF; - uint32_t new_aic_rxmode = DOWNLINK_OFF; - - Mutex::Autolock lock(mAIC3254ConfigLock); - - if (mMode == AudioSystem::MODE_IN_CALL) { - switch (device ) { - case SND_DEVICE_HEADSET: - new_aic_rxmode = CALL_DOWNLINK_EMIC_HEADSET; - new_aic_txmode = CALL_UPLINK_EMIC_HEADSET; - break; - case SND_DEVICE_SPEAKER: - case SND_DEVICE_SPEAKER_BACK_MIC: - new_aic_rxmode = CALL_DOWNLINK_IMIC_SPEAKER; - new_aic_txmode = CALL_UPLINK_IMIC_SPEAKER; - break; - case SND_DEVICE_HEADSET_AND_SPEAKER: - case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: - new_aic_rxmode = RING_HEADSET_SPEAKER; - break; - case SND_DEVICE_NO_MIC_HEADSET: - case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: - new_aic_rxmode = CALL_DOWNLINK_IMIC_HEADSET; - new_aic_txmode = CALL_UPLINK_IMIC_HEADSET; - break; - case SND_DEVICE_HANDSET: - case SND_DEVICE_HANDSET_BACK_MIC: - new_aic_rxmode = CALL_DOWNLINK_IMIC_RECEIVER; - new_aic_txmode = CALL_UPLINK_IMIC_RECEIVER; - break; - default: - break; - } - } else { - if (checkOutputStandby()) { - if (device == SND_DEVICE_FM_HEADSET) { - new_aic_rxmode = FM_OUT_HEADSET; - new_aic_txmode = FM_IN_HEADSET; - } else if (device == SND_DEVICE_FM_SPEAKER) { - new_aic_rxmode = FM_OUT_SPEAKER; - new_aic_txmode = FM_IN_SPEAKER; - } - } else { - switch (device) { - case SND_DEVICE_HEADSET_AND_SPEAKER: - case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: - case SND_DEVICE_HEADPHONE_AND_SPEAKER: - new_aic_rxmode = RING_HEADSET_SPEAKER; - break; - case SND_DEVICE_SPEAKER: - case SND_DEVICE_SPEAKER_BACK_MIC: - new_aic_rxmode = PLAYBACK_SPEAKER; - break; - case SND_DEVICE_HANDSET: - case SND_DEVICE_HANDSET_BACK_MIC: - new_aic_rxmode = PLAYBACK_RECEIVER; - break; - case SND_DEVICE_HEADSET: - case SND_DEVICE_NO_MIC_HEADSET: - case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: - new_aic_rxmode = PLAYBACK_HEADSET; - break; - default: - break; - } - } - - if (mRecordState) { - switch (device) { - case SND_DEVICE_HEADSET: - new_aic_txmode = VOICERECORD_EMIC; - break; - case SND_DEVICE_HANDSET_BACK_MIC: - case SND_DEVICE_SPEAKER_BACK_MIC: - case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: - case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: - new_aic_txmode = VIDEORECORD_IMIC; - break; - case SND_DEVICE_HANDSET: - case SND_DEVICE_SPEAKER: - case SND_DEVICE_NO_MIC_HEADSET: - case SND_DEVICE_HEADSET_AND_SPEAKER: - new_aic_txmode = VOICERECORD_IMIC; - break; - default: - break; - } - } - } - ALOGD("aic3254_ioctl: new_aic_rxmode %d cur_aic_rx %d", new_aic_rxmode, cur_aic_rx); - if (new_aic_rxmode != cur_aic_rx) - if (aic3254_ioctl(AIC3254_CONFIG_RX, new_aic_rxmode) >= 0) - cur_aic_rx = new_aic_rxmode; - - ALOGD("aic3254_ioctl: new_aic_txmode %d cur_aic_tx %d", new_aic_txmode, cur_aic_tx); - if (new_aic_txmode != cur_aic_tx) - if (aic3254_ioctl(AIC3254_CONFIG_TX, new_aic_txmode) >= 0) - cur_aic_tx = new_aic_txmode; - - if (cur_aic_tx == UPLINK_OFF && cur_aic_rx == DOWNLINK_OFF && aic3254_enabled) { - strcpy(mCurDspProfile, "\0"); - aic3254_enabled = false; - aic3254_powerdown(); - } else if (cur_aic_tx != UPLINK_OFF || cur_aic_rx != DOWNLINK_OFF) - aic3254_enabled = true; - - return NO_ERROR; -} - -bool AudioHardware::isAic3254Device(uint32_t device) { - switch(device) { - case SND_DEVICE_HANDSET: - case SND_DEVICE_SPEAKER: - case SND_DEVICE_HEADSET: - case SND_DEVICE_NO_MIC_HEADSET: - case SND_DEVICE_FM_HEADSET: - case SND_DEVICE_HEADSET_AND_SPEAKER: - case SND_DEVICE_FM_SPEAKER: - case SND_DEVICE_HEADPHONE_AND_SPEAKER: - case SND_DEVICE_HANDSET_BACK_MIC: - case SND_DEVICE_SPEAKER_BACK_MIC: - case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: - case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: - return true; - break; - default: - return false; - break; - } -} - -status_t AudioHardware::aic3254_config(uint32_t device) { - ALOGD("aic3254_config: device %d enabled %d", device, aic3254_enabled); - char name[22] = "\0"; - char aap[9] = "\0"; - - if ((!isAic3254Device(device) || - !aic3254_enabled) && - strlen(mCurDspProfile) != 0) - return NO_ERROR; - - Mutex::Autolock lock(mAIC3254ConfigLock); - - if (mMode == AudioSystem::MODE_IN_CALL) { -#ifdef WITH_SPADE_DSP_PROFILE - if (support_htc_backmic) { - strcpy(name, "DualMic_Phone"); - switch (device) { - case SND_DEVICE_HANDSET: - case SND_DEVICE_HANDSET_BACK_MIC: - case SND_DEVICE_HEADSET: - case SND_DEVICE_HEADSET_AND_SPEAKER: - case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: - case SND_DEVICE_NO_MIC_HEADSET: - strcat(name, "_EP"); - break; - case SND_DEVICE_SPEAKER: - strcat(name, "_SPK"); - break; - default: - break; - } - } else { - strcpy(name, "Original_Phone"); - } -#else - strcpy(name, "Original_Phone"); - switch (device) { - case SND_DEVICE_HANDSET: - case SND_DEVICE_HANDSET_BACK_MIC: - strcat(name, "_REC"); - break; - case SND_DEVICE_HEADSET: - case SND_DEVICE_HEADSET_AND_SPEAKER: - case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: - case SND_DEVICE_NO_MIC_HEADSET: - strcat(name, "_HP"); - break; - case SND_DEVICE_SPEAKER: - strcat(name, "_SPK"); - break; - default: - break; - } -#endif - } else { -#ifdef WITH_SPADE_DSP_PROFILE - if (mRecordState) { -#else - if ((strcasecmp(mActiveAP, "Camcorder") == 0)) { - if (strlen(mEffect) != 0) { - strcpy(name, "Recording_"); - strcat(name, mEffect); - } else - strcpy(name, "Original"); - } else if (mRecordState) { -#endif -#ifdef WITH_SPADE_DSP_PROFILE - strcpy(name, "Original"); -#else - strcpy(name, "Original_Recording"); -#endif - } else if (strlen(mEffect) == 0 && !mEffectEnabled) - strcpy(name, "Original"); - else { - if (mEffectEnabled) - strcpy(name, mEffect); - - if ((strcasecmp(name, "Srs") == 0) || - (strcasecmp(name, "Dolby") == 0)) { - strcpy(mEffect, name); - if (strcasecmp(mActiveAP, "Music") == 0) - strcat(name, "_a"); - else if (strcasecmp(mActiveAP, "Video") == 0) - strcat(name, "_v"); - if (device == SND_DEVICE_SPEAKER) - strcat(name, "_spk"); - else - strcat(name, "_hp"); - } - } - } - - if (strcasecmp(mCurDspProfile, name)) { - ALOGD("aic3254_config: loading effect %s", name); - strcpy(mCurDspProfile, name); - } else { - ALOGD("aic3254_config: effect %s already loaded", name); - return NO_ERROR; - } - - int rc = set_sound_effect(name); - if (rc < 0) { - ALOGE("Could not set sound effect %s: %d", name, rc); - return rc; - } - - return NO_ERROR; -} - -int AudioHardware::aic3254_ioctl(int cmd, const int argc) { - int rc = -1; - int (*set_aic3254_ioctl)(int, const int*); - - ALOGD("aic3254_ioctl()"); - - set_aic3254_ioctl = (int (*)(int, const int*))::dlsym(acoustic, "set_aic3254_ioctl"); - if ((*set_aic3254_ioctl) == 0) { - ALOGE("Could not open set_aic3254_ioctl()"); - return rc; - } - - ALOGD("aic3254_ioctl: try ioctl 0x%x with arg %d", cmd, argc); - rc = set_aic3254_ioctl(cmd, &argc); - if (rc < 0) - ALOGE("aic3254_ioctl failed"); - - return rc; -} - -void AudioHardware::aic3254_powerdown() { - ALOGD("aic3254_powerdown"); - int rc = aic3254_ioctl(AIC3254_POWERDOWN, 0); - if (rc < 0) - ALOGE("aic3254_powerdown failed"); -} - -int AudioHardware::aic3254_set_volume(int volume) { - ALOGD("aic3254_set_volume = %d", volume); - - if (aic3254_ioctl(AIC3254_CONFIG_VOLUME_L, volume) < 0) - ALOGE("aic3254_set_volume: could not set aic3254 LEFT volume %d", volume); - - int rc = aic3254_ioctl(AIC3254_CONFIG_VOLUME_R, volume); - if (rc < 0) - ALOGE("aic3254_set_volume: could not set aic3254 RIGHT volume %d", volume); - return rc; -} -#endif - -status_t AudioHardware::doRouting(AudioStreamInMSM72xx *input) -{ - Mutex::Autolock lock(mLock); - uint32_t outputDevices = mOutput->devices(); - status_t ret = NO_ERROR; - int audProcess = (ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); - int sndDevice = -1; - - - - if (input != NULL) { - uint32_t inputDevice = input->devices(); - ALOGI("do input routing device %x\n", inputDevice); - // ignore routing device information when we start a recording in voice - // call - // Recording will happen through currently active tx device - if((inputDevice == AudioSystem::DEVICE_IN_VOICE_CALL) -#ifdef QCOM_FM_ENABLED - || (inputDevice == AudioSystem::DEVICE_IN_FM_RX) - || (inputDevice == AudioSystem::DEVICE_IN_FM_RX_A2DP) -#endif - ) - return NO_ERROR; - if (inputDevice != 0) { - if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { - ALOGI("Routing audio to Bluetooth PCM\n"); - sndDevice = SND_DEVICE_BT; -#ifdef BACK_MIC_CAMCORDER - } else if (inputDevice & AudioSystem::DEVICE_IN_BACK_MIC) { - ALOGI("Routing audio to back mic (camcorder)"); - sndDevice = SND_DEVICE_BACK_MIC_CAMCORDER; -#endif - } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) { - if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && - (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { - ALOGI("Routing audio to Wired Headset and Speaker\n"); - sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; - audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE | MBADRC_ENABLE); - } else { - ALOGI("Routing audio to Wired Headset\n"); - sndDevice = SND_DEVICE_HEADSET; - } - } else { - if (outputDevices & AudioSystem::DEVICE_OUT_EARPIECE) { - ALOGI("Routing audio to Handset\n"); - sndDevice = SND_DEVICE_HANDSET; - } else if (outputDevices == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { - ALOGI("Routing audio to Speakerphone\n"); - sndDevice = SND_DEVICE_NO_MIC_HEADSET; - } else { - ALOGI("Routing audio to Speakerphone\n"); - sndDevice = SND_DEVICE_SPEAKER; - } - } - } - // if inputDevice == 0, restore output routing - } - - if (sndDevice == -1) { - if (outputDevices & (outputDevices - 1)) { - if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) { - ALOGW("Hardware does not support requested route combination (%#X)," - " picking closest possible route...", outputDevices); - } - } - if ((mTtyMode != TTY_OFF) && (mMode == AudioSystem::MODE_IN_CALL) && - (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET)) { - if (mTtyMode == TTY_FULL) { - ALOGI("Routing audio to TTY FULL Mode\n"); - sndDevice = SND_DEVICE_TTY_FULL; - } else if (mTtyMode == TTY_VCO) { - ALOGI("Routing audio to TTY VCO Mode\n"); - sndDevice = SND_DEVICE_TTY_VCO; - } else if (mTtyMode == TTY_HCO) { - ALOGI("Routing audio to TTY HCO Mode\n"); - sndDevice = SND_DEVICE_TTY_HCO; - } - } else if (outputDevices & - (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { - ALOGI("Routing audio to Bluetooth PCM\n"); - sndDevice = SND_DEVICE_BT; - } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { - ALOGI("Routing audio to Bluetooth PCM\n"); - sndDevice = SND_DEVICE_CARKIT; - } else if (outputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) { - ALOGI("Routing audio to HDMI\n"); - sndDevice = SND_DEVICE_HDMI; - } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && - (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { - ALOGI("Routing audio to Wired Headset and Speaker\n"); - sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; - audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE | MBADRC_ENABLE); - } -#ifdef QCOM_FM_ENABLED - else if ((outputDevices & AudioSystem::DEVICE_OUT_FM_TX) && - (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { - ALOGI("Routing audio to FM Tx and Speaker\n"); - sndDevice = SND_DEVICE_FM_TX_AND_SPEAKER; - enableComboDevice(sndDevice,1); - audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE | MBADRC_ENABLE); - } -#endif - else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { - if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { - ALOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); - sndDevice = SND_DEVICE_HEADPHONE_AND_SPEAKER; - audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE | MBADRC_ENABLE); - } else { - ALOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); - sndDevice = SND_DEVICE_NO_MIC_HEADSET; - } - } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { - ALOGI("Routing audio to Wired Headset\n"); - sndDevice = SND_DEVICE_HEADSET; - audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE | MBADRC_ENABLE); - } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { - ALOGI("Routing audio to Speakerphone\n"); - sndDevice = SND_DEVICE_SPEAKER; - audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE | MBADRC_ENABLE); - } else if(outputDevices & AudioSystem::DEVICE_OUT_EARPIECE){ - ALOGI("Routing audio to Handset\n"); - sndDevice = SND_DEVICE_HANDSET; - audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE | MBADRC_ENABLE); - } -#ifdef QCOM_FM_ENABLED - else if(outputDevices & AudioSystem::DEVICE_OUT_FM_TX){ - ALOGI("Routing audio to FM Tx Device\n"); - sndDevice = SND_DEVICE_FM_TX; - audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE | MBADRC_ENABLE); - } -#endif - } - - if (mDualMicEnabled && mMode == AudioSystem::MODE_IN_CALL) { - if (sndDevice == SND_DEVICE_HANDSET) { - ALOGI("Routing audio to handset with DualMike enabled\n"); - sndDevice = SND_DEVICE_IN_S_SADC_OUT_HANDSET; - } else if (sndDevice == SND_DEVICE_SPEAKER) { - ALOGI("Routing audio to speakerphone with DualMike enabled\n"); - sndDevice = SND_DEVICE_IN_S_SADC_OUT_SPEAKER_PHONE; - } - } - -#ifdef SAMSUNG_AUDIO - if (mMode == AudioSystem::MODE_IN_CALL) { - if (sndDevice == SND_DEVICE_HANDSET) { - ALOGI("Routing audio to Call Handset\n"); - sndDevice = SND_DEVICE_CALL_HANDSET; - } else if (sndDevice == SND_DEVICE_SPEAKER) { - ALOGI("Routing audio to Call Speaker\n"); - sndDevice = SND_DEVICE_CALL_SPEAKER; - } else if (sndDevice == SND_DEVICE_HEADSET) { - ALOGI("Routing audio to Call Headset\n"); - sndDevice = SND_DEVICE_CALL_HEADSET; - } - } else if (mMode == AudioSystem::MODE_IN_COMMUNICATION) { - if (sndDevice == SND_DEVICE_HANDSET) { - ALOGI("Routing audio to VOIP handset\n"); - sndDevice = SND_DEVICE_VOIP_HANDSET; - } else if (sndDevice == SND_DEVICE_SPEAKER) { - ALOGI("Routing audio to VOIP speaker\n"); - sndDevice = SND_DEVICE_VOIP_SPEAKER; - } else if (sndDevice == SND_DEVICE_HEADSET) { - ALOGI("Routing audio to VOIP headset\n"); - sndDevice = SND_DEVICE_VOIP_HEADSET; - } - } -#endif - -#ifdef QCOM_FM_ENABLED - if ((outputDevices & AudioSystem::DEVICE_OUT_FM) && (mFmFd == -1)){ - enableFM(sndDevice); - } - if ((mFmFd != -1) && !(outputDevices & AudioSystem::DEVICE_OUT_FM)){ - disableFM(); - } - if ((CurrentComboDeviceData.DeviceId == INVALID_DEVICE) && - (sndDevice == SND_DEVICE_FM_TX_AND_SPEAKER )){ - /* speaker rx is already enabled change snd device to the fm tx - * device and let the flow take the regular route to - * updatedeviceinfo(). - */ - Mutex::Autolock lock_1(mComboDeviceLock); - - CurrentComboDeviceData.DeviceId = SND_DEVICE_FM_TX_AND_SPEAKER; - sndDevice = DEVICE_FMRADIO_STEREO_RX; - } - else if(CurrentComboDeviceData.DeviceId != INVALID_DEVICE){ - /* time to disable the combo device */ - enableComboDevice(CurrentComboDeviceData.DeviceId,0); - Mutex::Autolock lock_2(mComboDeviceLock); - CurrentComboDeviceData.DeviceId = INVALID_DEVICE; - CurrentComboDeviceData.StreamType = INVALID_STREAM; - } -#endif - - if (sndDevice != -1 && sndDevice != mCurSndDevice) { - ret = doAudioRouteOrMute(sndDevice); - mCurSndDevice = sndDevice; - } - - return ret; -} -#ifdef QCOM_FM_ENABLED -status_t AudioHardware::enableComboDevice(uint32_t sndDevice, bool enableOrDisable) -{ - ALOGD("enableComboDevice %u",enableOrDisable); - status_t status = NO_ERROR; -#ifdef QCOM_TUNNEL_LPA_ENABLED - Routing_table *LpaNode = getNodeByStreamType(LPA_DECODE); -#endif - Routing_table *PcmNode = getNodeByStreamType(PCM_PLAY); - - - if(SND_DEVICE_FM_TX_AND_SPEAKER == sndDevice){ - - if(getNodeByStreamType(VOICE_CALL) || getNodeByStreamType(FM_RADIO) || - getNodeByStreamType(FM_A2DP)){ - ALOGE("voicecall/FM radio active bailing out"); - return NO_ERROR; - } - - if( -#ifdef QCOM_TUNNEL_LPA_ENABLED - !LpaNode && -#endif - !PcmNode) { - ALOGE("No active playback session active bailing out "); - return NO_ERROR; - } - - Mutex::Autolock lock_1(mComboDeviceLock); - - Routing_table* temp = NULL; - - if (enableOrDisable == 1) { - - if(enableDevice(DEVICE_SPEAKER_RX, 1)) { - ALOGE("enableDevice failed for device %d", DEVICE_SPEAKER_RX); - return -1; - } - - - if(CurrentComboDeviceData.StreamType == INVALID_STREAM){ - if (PcmNode){ - temp = PcmNode; - CurrentComboDeviceData.StreamType = PCM_PLAY; - ALOGD("PCM_PLAY session Active "); -#ifdef QCOM_TUNNEL_LPA_ENABLED - }else if(LpaNode){ - temp = LpaNode; - CurrentComboDeviceData.StreamType = LPA_DECODE; - ALOGD("LPA_DECODE session Active "); -#endif - } else { - ALOGE("no PLAYback session Active "); - return -1; - } - }else - temp = getNodeByStreamType(CurrentComboDeviceData.StreamType); - - if(temp == NULL){ - ALOGE("null check:fatal error:temp cannot be null"); - return -1; - } - - ALOGD("combo:msm_route_stream(%d,%d,1)",temp->dec_id, - DEV_ID(DEVICE_SPEAKER_RX)); - if(msm_route_stream(PCM_PLAY, temp->dec_id, DEV_ID(DEVICE_SPEAKER_RX), - 1)) { - ALOGE("msm_route_stream failed"); - return -1; - } - - }else if(enableOrDisable == 0) { - temp = getNodeByStreamType(CurrentComboDeviceData.StreamType); - - - if(temp == NULL){ - ALOGE("null check:fatal error:temp cannot be null"); - return -1; - } - - ALOGD("combo:de-route msm_route_stream(%d,%d,0)",temp->dec_id, - DEV_ID(DEVICE_SPEAKER_RX)); - if(msm_route_stream(PCM_PLAY, temp->dec_id, - DEV_ID(DEVICE_SPEAKER_RX), 0)) { - ALOGE("msm_route_stream failed"); - return -1; - } - - if(enableDevice(DEVICE_SPEAKER_RX, 0)) { - ALOGE("enableDevice failed for device %d", DEVICE_SPEAKER_RX); - return -1; - } - } - - } - - return status; -} - -status_t AudioHardware::enableFM(int sndDevice) -{ - ALOGD("enableFM"); - status_t status = NO_INIT; - unsigned short session_id = INVALID_DEVICE; - status = ::open(FM_DEVICE, O_RDWR); - if (status < 0) { - ALOGE("Cannot open FM_DEVICE errno: %d", errno); - goto Error; - } - mFmFd = status; - if(ioctl(mFmFd, AUDIO_GET_SESSION_ID, &session_id)) { - ALOGE("AUDIO_GET_SESSION_ID failed*********"); - goto Error; - } - - if(enableDevice(DEVICE_FMRADIO_STEREO_TX, 1)) { - ALOGE("enableDevice failed for device %d", DEVICE_FMRADIO_STEREO_TX); - goto Error; - } - if(msm_route_stream(PCM_PLAY, session_id, DEV_ID(DEVICE_FMRADIO_STEREO_TX), 1)) { - ALOGE("msm_route_stream failed"); - goto Error; - } - addToTable(session_id,cur_rx,INVALID_DEVICE,FM_RADIO,true); - if(sndDevice == mCurSndDevice || mCurSndDevice == -1) { - enableDevice(cur_rx, 1); - msm_route_stream(PCM_PLAY,session_id,DEV_ID(cur_rx),1); - } - status = ioctl(mFmFd, AUDIO_START, 0); - if (status < 0) { - ALOGE("Cannot do AUDIO_START"); - goto Error; - } - return NO_ERROR; - Error: - if (mFmFd >= 0) { - ::close(mFmFd); - mFmFd = -1; - } - return NO_ERROR; -} - -status_t AudioHardware::disableFM() -{ - ALOGD("disableFM"); - Routing_table* temp = NULL; - temp = getNodeByStreamType(FM_RADIO); - if(temp == NULL) - return 0; - if (mFmFd >= 0) { - ::close(mFmFd); - mFmFd = -1; - } - if(msm_route_stream(PCM_PLAY, temp->dec_id, DEV_ID(DEVICE_FMRADIO_STEREO_TX), 0)) { - ALOGE("msm_route_stream failed"); - return 0; - } - if(!getNodeByStreamType(FM_A2DP)){ - if(enableDevice(DEVICE_FMRADIO_STEREO_TX, 0)) { - ALOGE("Disabling device failed for device %d", DEVICE_FMRADIO_STEREO_TX); - } - } - deleteFromTable(FM_RADIO); -#ifdef HTC_AUDIO - updateDeviceInfo(cur_rx, cur_tx, 0, 0); -#else - updateDeviceInfo(cur_rx, cur_tx); -#endif - return NO_ERROR; -} -#endif - -status_t AudioHardware::checkMicMute() -{ - Mutex::Autolock lock(mLock); - if (mMode != AudioSystem::MODE_IN_CALL) { - setMicMute_nosync(true); - } - - return NO_ERROR; -} - -status_t AudioHardware::dumpInternals(int fd, const Vector& args) -{ - const size_t SIZE = 256; - char buffer[SIZE]; - String8 result; - result.append("AudioHardware::dumpInternals\n"); - snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); - result.append(buffer); - snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); - result.append(buffer); - snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); - result.append(buffer); - snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); - result.append(buffer); - ::write(fd, result.string(), result.size()); - return NO_ERROR; -} - -status_t AudioHardware::dump(int fd, const Vector& args) -{ - dumpInternals(fd, args); - for (size_t index = 0; index < mInputs.size(); index++) { - mInputs[index]->dump(fd, args); - } - - if (mOutput) { - mOutput->dump(fd, args); - } - return NO_ERROR; -} - -uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) -{ - uint32_t i; - uint32_t prevDelta; - uint32_t delta; - - for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { - delta = abs(sampleRate - inputSamplingRates[i]); - if (delta > prevDelta) break; - } - // i is always > 0 here - return inputSamplingRates[i-1]; -} - - -// ---------------------------------------------------------------------------- -#ifdef QCOM_TUNNEL_LPA_ENABLED -AudioHardware::AudioSessionOutMSM7xxx::AudioSessionOutMSM7xxx() : - mHardware(0), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0), mSessionId(-1) -{ -} - -status_t AudioHardware::AudioSessionOutMSM7xxx::set( - AudioHardware* hw, uint32_t devices, int *pFormat, int32_t sessionId) -{ - int lFormat = pFormat ? *pFormat : 0; - - mHardware = hw; - mDevices = devices; - - if(sessionId >= 0) { - ALOGD("AudioSessionOutMSM7xxx::set() Adding LPA_DECODE Node to Table"); - - Mutex::Autolock lock(mDeviceSwitchLock); - - addToTable(sessionId,cur_rx,INVALID_DEVICE,LPA_DECODE,true); - - if(enableDevice(cur_rx, 1)) { - ALOGE("enableDevice failed for device cur_rx %d", cur_rx); - return 0; - } - - ALOGV("msm_route_stream(PCM_PLAY,%d,%d,0)",sessionId,DEV_ID(cur_rx)); - if(msm_route_stream(PCM_PLAY,sessionId,DEV_ID(cur_rx),1)) { - ALOGE("msm_route_stream(PCM_PLAY,%d,%d,1) failed",sessionId,DEV_ID(cur_rx)); - } - - Mutex::Autolock lock_1(mComboDeviceLock); - - if(CurrentComboDeviceData.DeviceId == SND_DEVICE_FM_TX_AND_SPEAKER){ - ALOGD("Routing LPA steam to speaker for combo device"); - ALOGD("combo:msm_route_stream(LPA_DECODE,session id:%d,dev id:%d,1)",sessionId, - DEV_ID(DEVICE_SPEAKER_RX)); - /* music session is already routed to speaker in - * enableComboDevice(), but at this point it can - * be said that it was done with incorrect session id, - * so re-routing with correct session id here. - */ - if(msm_route_stream(PCM_PLAY, sessionId, DEV_ID(DEVICE_SPEAKER_RX), - 1)) { - ALOGE("msm_route_stream failed"); - return -1; - } - CurrentComboDeviceData.StreamType = LPA_DECODE; - } - - mSessionId = sessionId; - } - return NO_ERROR; -} - -AudioHardware::AudioSessionOutMSM7xxx::~AudioSessionOutMSM7xxx() -{ -} - -status_t AudioHardware::AudioSessionOutMSM7xxx::standby() -{ - Routing_table* temp = NULL; - ALOGD("AudioSessionOutMSM7xxx::standby()"); - status_t status = NO_ERROR; - - temp = getNodeByStreamType(LPA_DECODE); - - if(temp == NULL) - return NO_ERROR; - - ALOGD("Deroute lpa playback stream"); - if(msm_route_stream(PCM_PLAY, temp->dec_id,DEV_ID(temp->dev_id), 0)) { - ALOGE("could not set stream routing\n"); - deleteFromTable(LPA_DECODE); - return -1; - } - deleteFromTable(LPA_DECODE); - updateDeviceInfo(cur_rx, cur_tx); - mStandby = true; - return status; -} - -bool AudioHardware::AudioSessionOutMSM7xxx::checkStandby() -{ - return mStandby; -} - - -status_t AudioHardware::AudioSessionOutMSM7xxx::setParameters(const String8& keyValuePairs) -{ - AudioParameter param = AudioParameter(keyValuePairs); - String8 key = String8(AudioParameter::keyRouting); - status_t status = NO_ERROR; - int device; - ALOGV("AudioSessionOutMSM7xxx::setParameters() %s", keyValuePairs.string()); - - if (param.getInt(key, device) == NO_ERROR) { - mDevices = device; - ALOGV("set output routing %x", mDevices); - status = mHardware->doRouting(NULL); - param.remove(key); - } - - if (param.size()) { - status = BAD_VALUE; - } - return status; -} - -String8 AudioHardware::AudioSessionOutMSM7xxx::getParameters(const String8& keys) -{ - AudioParameter param = AudioParameter(keys); - String8 value; - String8 key = String8(AudioParameter::keyRouting); - - if (param.get(key, value) == NO_ERROR) { - ALOGV("get routing %x", mDevices); - param.addInt(key, (int)mDevices); - } - - ALOGV("AudioSessionOutMSM7xxx::getParameters() %s", param.toString().string()); - return param.toString(); -} - -status_t AudioHardware::AudioSessionOutMSM7xxx::getRenderPosition(uint32_t *dspFrames) -{ - //TODO: enable when supported by driver - return INVALID_OPERATION; -} - -status_t AudioHardware::AudioSessionOutMSM7xxx::setVolume(float left, float right) -{ - float v = (left + right) / 2; - if (v < 0.0) { - ALOGW("AudioSessionOutMSM7xxx::setVolume(%f) under 0.0, assuming 0.0\n", v); - v = 0.0; - } else if (v > 1.0) { - ALOGW("AudioSessionOutMSM7xxx::setVolume(%f) over 1.0, assuming 1.0\n", v); - v = 1.0; - } - - // Ensure to convert the log volume back to linear for LPA - float vol = v * 100; - ALOGV("AudioSessionOutMSM7xxx::setVolume(%f)\n", v); - ALOGV("Setting session volume to %f (available range is 0 to 100)\n", vol); - - if(msm_set_volume(mSessionId, vol)) { - ALOGE("msm_set_volume(%d %f) failed errno = %d",mSessionId, vol,errno); - return -1; - } - ALOGV("msm_set_volume(%f) succeeded",vol); - return NO_ERROR; -} - -#endif /* QCOM_TUNNEL_LPA_ENABLED */ -// ---------------------------------------------------------------------------- - -AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : - mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0) -{ -} - -status_t AudioHardware::AudioStreamOutMSM72xx::set( - AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) -{ - int lFormat = pFormat ? *pFormat : 0; - uint32_t lChannels = pChannels ? *pChannels : 0; - uint32_t lRate = pRate ? *pRate : 0; - - mHardware = hw; - - // fix up defaults - if (lFormat == 0) lFormat = format(); - if (lChannels == 0) lChannels = channels(); - if (lRate == 0) lRate = sampleRate(); - - // check values - if ((lFormat != format()) || - (lChannels != channels()) || - (lRate != sampleRate())) { - if (pFormat) *pFormat = format(); - if (pChannels) *pChannels = channels(); - if (pRate) *pRate = sampleRate(); - return BAD_VALUE; - } - - if (pFormat) *pFormat = lFormat; - if (pChannels) *pChannels = lChannels; - if (pRate) *pRate = lRate; - - mDevices = devices; - - return NO_ERROR; -} - -AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() -{ - if (mFd >= 0) close(mFd); -} - -ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) -{ - // ALOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); - status_t status = NO_INIT; - size_t count = bytes; - const uint8_t* p = static_cast(buffer); - unsigned short dec_id = INVALID_DEVICE; - - if (mStandby) { - - // open driver - ALOGV("open driver"); - status = ::open("/dev/msm_pcm_out", O_WRONLY/*O_RDWR*/); - if (status < 0) { - ALOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); - goto Error; - } - mFd = status; - - // configuration - ALOGV("get config"); - struct msm_audio_config config; - status = ioctl(mFd, AUDIO_GET_CONFIG, &config); - if (status < 0) { - ALOGE("Cannot read config"); - goto Error; - } - - ALOGV("set config"); - config.channel_count = AudioSystem::popCount(channels()); - config.sample_rate = sampleRate(); - config.buffer_size = bufferSize(); - config.buffer_count = AUDIO_HW_NUM_OUT_BUF; - config.type = CODEC_TYPE_PCM; - - status = ioctl(mFd, AUDIO_SET_CONFIG, &config); - if (status < 0) { - ALOGE("Cannot set config"); - goto Error; - } - - ALOGV("buffer_size: %u", config.buffer_size); - ALOGV("buffer_count: %u", config.buffer_count); - ALOGV("channel_count: %u", config.channel_count); - ALOGV("sample_rate: %u", config.sample_rate); - - // fill 2 buffers before AUDIO_START - mStartCount = AUDIO_HW_NUM_OUT_BUF; - mStandby = false; - -#ifdef HTC_AUDIO - if (support_tpa2051) - do_tpa2051_control(0); -#endif - } - - while (count) { - ssize_t written = ::write(mFd, p, count); - if (written >= 0) { - count -= written; - p += written; - } else { - if (errno != EAGAIN) return written; - mRetryCount++; - ALOGW("EAGAIN - retry"); - } - } - - // start audio after we fill 2 buffers - if (mStartCount) { - if (--mStartCount == 0) { - if(ioctl(mFd, AUDIO_GET_SESSION_ID, &dec_id)) { - ALOGE("AUDIO_GET_SESSION_ID failed*********"); - return 0; - } - ALOGV("dec_id = %d\n",dec_id); - if(cur_rx == INVALID_DEVICE) - return 0; - - Mutex::Autolock lock(mDeviceSwitchLock); - -#ifdef HTC_AUDIO - int snd_dev = mHardware->get_snd_dev(); - if (support_aic3254) - mHardware->do_aic3254_control(snd_dev); -#endif - - ALOGV("cur_rx for pcm playback = %d",cur_rx); - if (enableDevice(cur_rx, 1)) { - ALOGE("enableDevice failed for device cur_rx %d", cur_rx); - return 0; - } - -#ifdef HTC_AUDIO - uint32_t rx_acdb_id = mHardware->getACDB(MOD_PLAY, snd_dev); - updateACDB(cur_rx, cur_tx, rx_acdb_id, 0); -#endif - - ALOGV("msm_route_stream(PCM_PLAY,%d,%d,1)",dec_id,DEV_ID(cur_rx)); - if(msm_route_stream(PCM_PLAY, dec_id, DEV_ID(cur_rx), 1)) { - ALOGE("msm_route_stream failed"); - return 0; - } -#ifdef QCOM_FM_ENABLED - Mutex::Autolock lock_1(mComboDeviceLock); - - if(CurrentComboDeviceData.DeviceId == SND_DEVICE_FM_TX_AND_SPEAKER){ -#ifdef QCOM_TUNNEL_LPA_ENABLED - Routing_table *LpaNode = getNodeByStreamType(LPA_DECODE); - - /* This de-routes the LPA being routed on to speaker, which is done in - * enablecombo() - */ - if(LpaNode == NULL){ - ALOGE("null check:fatal error:LpaNode cannot be null"); - return -1; - } - ALOGD("combo:de-route:msm_route_stream(%d,%d,0)",LpaNode ->dec_id, - DEV_ID(DEVICE_SPEAKER_RX)); - if(msm_route_stream(PCM_PLAY, LpaNode ->dec_id, DEV_ID(DEVICE_SPEAKER_RX), - 0)) { - ALOGE("msm_route_stream failed"); - return -1; - } -#endif - - ALOGD("Routing PCM stream to speaker for combo device"); - ALOGD("combo:msm_route_stream(PCM_PLAY,session id:%d,dev id:%d,1)",dec_id, - DEV_ID(DEVICE_SPEAKER_RX)); - - if(msm_route_stream(PCM_PLAY, dec_id, DEV_ID(DEVICE_SPEAKER_RX), - 1)) { - ALOGE("msm_route_stream failed"); - return -1; - } - CurrentComboDeviceData.StreamType = PCM_PLAY; - } -#endif - addToTable(dec_id,cur_rx,INVALID_DEVICE,PCM_PLAY,true); - ioctl(mFd, AUDIO_START, 0); - } - } - return bytes; - -Error: - if (mFd >= 0) { - ::close(mFd); - mFd = -1; - } - // Simulate audio output timing in case of error - usleep(bytes * 1000000 / frameSize() / sampleRate()); - - return status; -} - -status_t AudioHardware::AudioStreamOutMSM72xx::standby() -{ - Routing_table* temp = NULL; - ALOGV("AudioStreamOutMSM72xx::standby()"); - status_t status = NO_ERROR; - - temp = getNodeByStreamType(PCM_PLAY); - - if(temp == NULL) - return NO_ERROR; - - ALOGV("Deroute pcm out stream"); - if(msm_route_stream(PCM_PLAY, temp->dec_id,DEV_ID(temp->dev_id), 0)) { - ALOGE("could not set stream routing\n"); - deleteFromTable(PCM_PLAY); - return -1; - } - deleteFromTable(PCM_PLAY); -#ifdef HTC_AUDIO - updateDeviceInfo(cur_rx, cur_tx, 0, 0); -#else - updateDeviceInfo(cur_rx, cur_tx); -#endif - - if (!mStandby && mFd >= 0) { - ::close(mFd); - mFd = -1; - } - - mStandby = true; - -#ifdef HTC_AUDIO - if (support_aic3254) - mHardware->do_aic3254_control(mHardware->get_snd_dev()); -#endif - - return status; -} - -status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector& args) -{ - const size_t SIZE = 256; - char buffer[SIZE]; - String8 result; - result.append("AudioStreamOutMSM72xx::dump\n"); - snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); - result.append(buffer); - snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); - result.append(buffer); - snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); - result.append(buffer); - snprintf(buffer, SIZE, "\tformat: %d\n", format()); - result.append(buffer); - snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); - result.append(buffer); - snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); - result.append(buffer); - snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); - result.append(buffer); - snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); - result.append(buffer); - snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); - result.append(buffer); - ::write(fd, result.string(), result.size()); - return NO_ERROR; -} - -bool AudioHardware::AudioStreamOutMSM72xx::checkStandby() -{ - return mStandby; -} - - -status_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) -{ - AudioParameter param = AudioParameter(keyValuePairs); - String8 key = String8(AudioParameter::keyRouting); - status_t status = NO_ERROR; - int device; - ALOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); - - if (param.getInt(key, device) == NO_ERROR) { - mDevices = device; - ALOGV("set output routing %x", mDevices); - status = mHardware->doRouting(NULL); - param.remove(key); - } - - if (param.size()) { - status = BAD_VALUE; - } - return status; -} - -String8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) -{ - AudioParameter param = AudioParameter(keys); - String8 value; - String8 key = String8(AudioParameter::keyRouting); - - if (param.get(key, value) == NO_ERROR) { - ALOGV("get routing %x", mDevices); - param.addInt(key, (int)mDevices); - } - - ALOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); - return param.toString(); -} - -status_t AudioHardware::AudioStreamOutMSM72xx::getRenderPosition(uint32_t *dspFrames) -{ - //TODO: enable when supported by driver - return INVALID_OPERATION; -} - -#ifdef WITH_QCOM_VOIP_OVER_MVS -AudioHardware::AudioStreamOutDirect::AudioStreamOutDirect() : - mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0),mChannels(AudioSystem::CHANNEL_OUT_MONO), - mSampleRate(AUDIO_HW_VOIP_SAMPLERATE_8K), mBufferSize(AUDIO_HW_VOIP_BUFFERSIZE_8K) -{ -} - -status_t AudioHardware::AudioStreamOutDirect::set( - AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) -{ - int lFormat = pFormat ? *pFormat : 0; - uint32_t lChannels = pChannels ? *pChannels : 0; - uint32_t lRate = pRate ? *pRate : 0; - - ALOGV("AudioStreamOutDirect::set lFormat = %d lChannels= %u lRate = %u\n", lFormat, lChannels, lRate ); - mHardware = hw; - - // fix up defaults - if (lFormat == 0) lFormat = format(); - if (lChannels == 0) lChannels = channels(); - if (lRate == 0) lRate = sampleRate(); - - // check values - if ((lFormat != format()) || - (lChannels != channels()) || - (lRate != sampleRate())) { - if (pFormat) *pFormat = format(); - if (pChannels) *pChannels = channels(); - if (pRate) *pRate = sampleRate(); - ALOGE(" AudioStreamOutDirect::set return bad values\n"); - return BAD_VALUE; - } - - if (pFormat) *pFormat = lFormat; - if (pChannels) *pChannels = lChannels; - if (pRate) *pRate = lRate; - - mDevices = devices; - mChannels = lChannels; - mSampleRate = lRate; - - if(mSampleRate == AUDIO_HW_VOIP_SAMPLERATE_8K) { - mBufferSize = AUDIO_HW_VOIP_BUFFERSIZE_8K; - } else if(mSampleRate == AUDIO_HW_VOIP_SAMPLERATE_16K) { - mBufferSize = AUDIO_HW_VOIP_BUFFERSIZE_16K; - } else { - ALOGE(" AudioStreamOutDirect::set return bad values\n"); - return BAD_VALUE; - } - - mHardware->mVoipOutActive = true; - - if (mHardware->mVoipInActive) - mHardware->setupDeviceforVoipCall(true); - - return NO_ERROR; -} - -AudioHardware::AudioStreamOutDirect::~AudioStreamOutDirect() -{ - ALOGV("AudioStreamOutDirect destructor"); - mHardware->mVoipOutActive = false; - standby(); -} - -ssize_t AudioHardware::AudioStreamOutDirect::write(const void* buffer, size_t bytes) -{ - status_t status = NO_INIT; - size_t count = bytes; - const uint8_t* p = static_cast(buffer); - unsigned short dec_id = INVALID_DEVICE; - ALOGV("AudioStreamOutDirect::write(%p, %ld)", buffer, bytes); - - if (mStandby) { - if(mHardware->mVoipFd >= 0) { - mFd = mHardware->mVoipFd; - - mHardware->mVoipOutActive = true; - if (mHardware->mVoipInActive) - mHardware->setupDeviceforVoipCall(true); - - mStandby = false; - } else { - //Routing Voice - if ( (cur_rx != INVALID_DEVICE) && (cur_tx != INVALID_DEVICE)) - { - ALOGV("Starting voice on Rx %d and Tx %d device", DEV_ID(cur_rx), DEV_ID(cur_tx)); - msm_route_voice(DEV_ID(cur_rx),DEV_ID(cur_tx), 1); - } - else - { - return -1; - } - - //Enable RX device - if(cur_rx != INVALID_DEVICE && (enableDevice(cur_rx,1) == -1)) - { - return -1; - } - - //Enable TX device - if(cur_tx != INVALID_DEVICE&&(enableDevice(cur_tx,1) == -1)) - { - return -1; - } - - // start Voice call - ALOGD("Starting voice call and UnMuting the call"); - msm_start_voice(); - msm_set_voice_tx_mute(0); - addToTable(0,cur_rx,cur_tx,VOICE_CALL,true); - - - // open driver - ALOGV("open mvs driver"); - status = ::open(MVS_DEVICE, /*O_WRONLY*/ O_RDWR); - if (status < 0) { - ALOGE("Cannot open %s errno: %d",MVS_DEVICE, errno); - goto Error; - } - mFd = status; - mHardware->mVoipFd = mFd; - // configuration - ALOGV("get mvs config"); - struct msm_audio_mvs_config mvs_config; - status = ioctl(mFd, AUDIO_GET_MVS_CONFIG, &mvs_config); - if (status < 0) { - ALOGE("Cannot read mvs config"); - goto Error; - } - - ALOGV("set mvs config"); - mvs_config.mvs_mode = MVS_MODE_PCM; - status = ioctl(mFd, AUDIO_SET_MVS_CONFIG, &mvs_config); - if (status < 0) { - ALOGE("Cannot set mvs config"); - goto Error; - } - - ALOGV("start mvs config"); - status = ioctl(mFd, AUDIO_START, 0); - if (status < 0) { - ALOGE("Cannot start mvs driver"); - goto Error; - } - - mHardware->mVoipOutActive = true; - if (mHardware->mVoipInActive) - mHardware->setupDeviceforVoipCall(true); - - // fill 2 buffers before AUDIO_START - mStartCount = AUDIO_HW_NUM_OUT_BUF; - mStandby = false; - } - } - struct q5v2_msm_audio_mvs_frame audio_mvs_frame; - audio_mvs_frame.frame_type = 0; - while (count) { - audio_mvs_frame.len = mBufferSize; - memcpy(&audio_mvs_frame.voc_pkt, p, mBufferSize); - size_t written = ::write(mFd, &audio_mvs_frame, sizeof(audio_mvs_frame)); - ALOGV(" mvs bytes count = %d written : %d \n", count, written); - if (written == 0) { - count -= mBufferSize; - p += mBufferSize; - } else { - if (errno != EAGAIN) return written; - mRetryCount++; - ALOGW("EAGAIN - retry"); - } - } - - // start audio after we fill 2 buffers - if (mStartCount) { - if (--mStartCount == 0) { - if(ioctl(mFd, AUDIO_GET_SESSION_ID, &dec_id)) { - ALOGE("AUDIO_GET_SESSION_ID failed*********"); - return 0; - } - ALOGD("write(): dec_id = %d cur_rx = %d\n",dec_id,cur_rx); - if(cur_rx == INVALID_DEVICE) { - //return 0; //temporary fix until team upmerges code to froyo tip - cur_rx = 0; - cur_tx = 1; - } - } - } - bytes = sizeof(audio_mvs_frame.voc_pkt); - return bytes; - -Error: -ALOGE(" write Error \n"); - // mHardware->mLock.unlock(); - if (mFd >= 0) { - ::close(mFd); - mFd = -1; - mHardware->mVoipFd = -1; - } - // Simulate audio output timing in case of error - usleep(bytes * 1000000 / frameSize() / sampleRate()); - - return status; -} - -status_t AudioHardware::AudioStreamOutDirect::standby() -{ - Routing_table* temp = NULL; - ALOGD("AudioStreamOutDirect::standby()"); - Mutex::Autolock lock(mHardware->mVoipLock); - status_t status = NO_ERROR; - - ALOGD("Voipin %d driver fd %d", mHardware->mVoipInActive, mHardware->mVoipFd); - mHardware->mVoipOutActive = false; - if (mHardware->mVoipFd >= 0 && !mHardware->mVoipInActive) { - ALOGE("mute and disbale device ***\n"); - //Mute and disable the device. - int ret = msm_set_voice_rx_vol(0); - if (ret <0) - ALOGE("Error %d setting volume\n", ret); - - ret = msm_set_voice_tx_mute(1); - if (ret < 0) - ALOGE("Error %d setting mute\n", ret); - - ret = msm_end_voice(); - if (ret < 0) - ALOGE("Error %d ending voice\n", ret); - - if (mHardware->mVoipFd >= 0) { - ret = ioctl(mHardware->mVoipFd, AUDIO_STOP, NULL); - ALOGE("MVS stop returned %d \n", ret); - ::close(mFd); - mFd = mHardware->mVoipFd = -1; - mHardware->setupDeviceforVoipCall(false); - ALOGD("MVS driver closed %d mFd %d", __LINE__, mHardware->mVoipFd); - } - //mHardware->checkMicMute(); - } - else - ALOGE("Not closing MVS driver"); - mStandby = true; - return status; -} - -status_t AudioHardware::AudioStreamOutDirect::dump(int fd, const Vector& args) -{ - const size_t SIZE = 256; - char buffer[SIZE]; - String8 result; - result.append("AudioStreamOutDirect::dump\n"); - snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); - result.append(buffer); - snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); - result.append(buffer); - snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); - result.append(buffer); - snprintf(buffer, SIZE, "\tformat: %d\n", format()); - result.append(buffer); - snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); - result.append(buffer); - snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); - result.append(buffer); - snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); - result.append(buffer); - snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); - result.append(buffer); - snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); - result.append(buffer); - ::write(fd, result.string(), result.size()); - return NO_ERROR; -} - -bool AudioHardware::AudioStreamOutDirect::checkStandby() -{ - return mStandby; -} - - -status_t AudioHardware::AudioStreamOutDirect::setParameters(const String8& keyValuePairs) -{ - AudioParameter param = AudioParameter(keyValuePairs); - String8 key = String8(AudioParameter::keyRouting); - status_t status = NO_ERROR; - int device; - ALOGV("AudioStreamOutDirect::setParameters() %s", keyValuePairs.string()); - - if (param.getInt(key, device) == NO_ERROR) { - mDevices = device; - ALOGV("set output routing %x", mDevices); - status = mHardware->doRouting(NULL); - param.remove(key); - } - - if (param.size()) { - status = BAD_VALUE; - } - return status; -} - -String8 AudioHardware::AudioStreamOutDirect::getParameters(const String8& keys) -{ - AudioParameter param = AudioParameter(keys); - String8 value; - String8 key = String8(AudioParameter::keyRouting); - - if (param.get(key, value) == NO_ERROR) { - ALOGV("get routing %x", mDevices); - param.addInt(key, (int)mDevices); - } - - ALOGV("AudioStreamOutDirect::getParameters() %s", param.toString().string()); - return param.toString(); -} - -status_t AudioHardware::AudioStreamOutDirect::getRenderPosition(uint32_t *dspFrames) -{ - //TODO: enable when supported by driver - return INVALID_OPERATION; -} -#endif - -// ---------------------------------------------------------------------------- - -AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : - mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), - mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), - mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE), - mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) -{ -} - -status_t AudioHardware::AudioStreamInMSM72xx::set( - AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, - AudioSystem::audio_in_acoustics acoustic_flags) -{ - if ((pFormat == 0) || - ((*pFormat != AUDIO_HW_IN_FORMAT) && -#ifdef WITH_QCOM_SPEECH - (*pFormat != AudioSystem::AMR_NB) && - (*pFormat != AudioSystem::EVRC) && - (*pFormat != AudioSystem::QCELP) && -#endif - (*pFormat != AudioSystem::AAC))) - { - *pFormat = AUDIO_HW_IN_FORMAT; - return BAD_VALUE; - } - - if((*pFormat == AudioSystem::AAC) && (*pChannels & (AudioSystem::CHANNEL_IN_VOICE_DNLINK | AudioSystem::CHANNEL_IN_VOICE_UPLINK))) { - ALOGE("voice call recording in AAC format does not support"); - return BAD_VALUE; - } - - if (pRate == 0) { - return BAD_VALUE; - } - uint32_t rate = hw->getInputSampleRate(*pRate); - if (rate != *pRate) { - *pRate = rate; - return BAD_VALUE; - } - - if (pChannels == 0 || (*pChannels & (AudioSystem::CHANNEL_IN_MONO | AudioSystem::CHANNEL_IN_STEREO)) == 0) { - *pChannels = AUDIO_HW_IN_CHANNELS; - return BAD_VALUE; - } - - mHardware = hw; - - ALOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); - if (mFd >= 0) { - ALOGE("Audio record already open"); - return -EPERM; - } - status_t status =0; - struct msm_voicerec_mode voc_rec_cfg; -#ifdef QCOM_FM_ENABLED - if(devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) { - status = ::open("/dev/msm_a2dp_in", O_RDONLY); - if (status < 0) { - ALOGE("Cannot open /dev/msm_a2dp_in errno: %d", errno); - goto Error; - } - mFd = status; - // configuration - ALOGV("get config"); - struct msm_audio_config config; - status = ioctl(mFd, AUDIO_GET_CONFIG, &config); - if (status < 0) { - ALOGE("Cannot read config"); - goto Error; - } - - ALOGV("set config"); - config.channel_count = AudioSystem::popCount((*pChannels) & (AudioSystem::CHANNEL_IN_STEREO | AudioSystem::CHANNEL_IN_MONO)); - config.sample_rate = *pRate; - config.buffer_size = bufferSize(); - config.buffer_count = 2; - config.type = CODEC_TYPE_PCM; - status = ioctl(mFd, AUDIO_SET_CONFIG, &config); - if (status < 0) { - ALOGE("Cannot set config"); - if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) { - if (config.channel_count == 1) { - *pChannels = AudioSystem::CHANNEL_IN_MONO; - } else { - *pChannels = AudioSystem::CHANNEL_IN_STEREO; - } - *pRate = config.sample_rate; - } - goto Error; - } - - ALOGV("confirm config"); - status = ioctl(mFd, AUDIO_GET_CONFIG, &config); - if (status < 0) { - ALOGE("Cannot read config"); - goto Error; - } - ALOGV("buffer_size: %u", config.buffer_size); - ALOGV("buffer_count: %u", config.buffer_count); - ALOGV("channel_count: %u", config.channel_count); - ALOGV("sample_rate: %u", config.sample_rate); - - mDevices = devices; - mFormat = AUDIO_HW_IN_FORMAT; - mChannels = *pChannels; - mSampleRate = config.sample_rate; - mBufferSize = config.buffer_size; - } - else -#endif - if(*pFormat == AUDIO_HW_IN_FORMAT) - { - // open audio input device - status = ::open("/dev/msm_pcm_in", O_RDONLY); - if (status < 0) { - ALOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); - goto Error; - } - mFd = status; - - // configuration - ALOGV("get config"); - struct msm_audio_config config; - status = ioctl(mFd, AUDIO_GET_CONFIG, &config); - if (status < 0) { - ALOGE("Cannot read config"); - goto Error; - } - - ALOGV("set config"); - config.channel_count = AudioSystem::popCount((*pChannels) & (AudioSystem::CHANNEL_IN_STEREO | AudioSystem::CHANNEL_IN_MONO)); - config.sample_rate = *pRate; - config.buffer_size = bufferSize(); - config.buffer_count = 2; - config.type = CODEC_TYPE_PCM; - if (build_id[17] == '1') {//build 4.1 - /* - Configure pcm record buffer size based on the sampling rate: - If sampling rate >= 44.1 Khz, use 512 samples/channel pcm recording and - If sampling rate < 44.1 Khz, use 256 samples/channel pcm recording - */ - if(*pRate>=44100) - config.buffer_size = 1024 * config.channel_count; - else - config.buffer_size = 512 * config.channel_count; - } - status = ioctl(mFd, AUDIO_SET_CONFIG, &config); - if (status < 0) { - ALOGE("Cannot set config"); - if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) { - if (config.channel_count == 1) { - *pChannels = AudioSystem::CHANNEL_IN_MONO; - } else { - *pChannels = AudioSystem::CHANNEL_IN_STEREO; - } - *pRate = config.sample_rate; - } - goto Error; - } - - ALOGV("confirm config"); - status = ioctl(mFd, AUDIO_GET_CONFIG, &config); - if (status < 0) { - ALOGE("Cannot read config"); - goto Error; - } - ALOGV("buffer_size: %u", config.buffer_size); - ALOGV("buffer_count: %u", config.buffer_count); - ALOGV("channel_count: %u", config.channel_count); - ALOGV("sample_rate: %u", config.sample_rate); - - mDevices = devices; - mFormat = AUDIO_HW_IN_FORMAT; - mChannels = *pChannels; - if (mDevices == AudioSystem::DEVICE_IN_VOICE_CALL) - { - if ((mChannels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) && - (mChannels & AudioSystem::CHANNEL_IN_VOICE_UPLINK)) { - ALOGI("Recording Source: Voice Call Both Uplink and Downlink"); - voc_rec_cfg.rec_mode = VOC_REC_BOTH; - } else if (mChannels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { - ALOGI("Recording Source: Voice Call DownLink"); - voc_rec_cfg.rec_mode = VOC_REC_DOWNLINK; - } else if (mChannels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) { - ALOGI("Recording Source: Voice Call UpLink"); - voc_rec_cfg.rec_mode = VOC_REC_UPLINK; - } - if (ioctl(mFd, AUDIO_SET_INCALL, &voc_rec_cfg)) - { - ALOGE("Error: AUDIO_SET_INCALL failed\n"); - goto Error; - } - } - mSampleRate = config.sample_rate; - mBufferSize = config.buffer_size; - } -#ifdef WITH_QCOM_SPEECH - else if (*pFormat == AudioSystem::EVRC) - { - ALOGI("Recording format: EVRC"); - // open evrc input device - status = ::open(EVRC_DEVICE_IN, O_RDONLY); - if (status < 0) { - ALOGE("Cannot open evrc device for read"); - goto Error; - } - mFd = status; - mDevices = devices; - mChannels = *pChannels; - - if (mDevices == AudioSystem::DEVICE_IN_VOICE_CALL) - { - if ((mChannels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) && - (mChannels & AudioSystem::CHANNEL_IN_VOICE_UPLINK)) { - ALOGI("Recording Source: Voice Call Both Uplink and Downlink"); - voc_rec_cfg.rec_mode = VOC_REC_BOTH; - } else if (mChannels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { - ALOGI("Recording Source: Voice Call DownLink"); - voc_rec_cfg.rec_mode = VOC_REC_DOWNLINK; - } else if (mChannels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) { - ALOGI("Recording Source: Voice Call UpLink"); - voc_rec_cfg.rec_mode = VOC_REC_UPLINK; - } - - if (ioctl(mFd, AUDIO_SET_INCALL, &voc_rec_cfg)) - { - ALOGE("Error: AUDIO_SET_INCALL failed\n"); - goto Error; - } - } - - /* Config param */ - struct msm_audio_stream_config config; - if(ioctl(mFd, AUDIO_GET_STREAM_CONFIG, &config)) - { - ALOGE(" Error getting buf config param AUDIO_GET_STREAM_CONFIG \n"); - goto Error; - } - - ALOGV("The Config buffer size is %d", config.buffer_size); - ALOGV("The Config buffer count is %d", config.buffer_count); - - mSampleRate =8000; - mFormat = *pFormat; - mBufferSize = 230; - struct msm_audio_evrc_enc_config evrc_enc_cfg; - - if (ioctl(mFd, AUDIO_GET_EVRC_ENC_CONFIG, &evrc_enc_cfg)) - { - ALOGE("Error: AUDIO_GET_EVRC_ENC_CONFIG failed\n"); - goto Error; - } - - ALOGV("The Config cdma_rate is %d", evrc_enc_cfg.cdma_rate); - ALOGV("The Config min_bit_rate is %d", evrc_enc_cfg.min_bit_rate); - ALOGV("The Config max_bit_rate is %d", evrc_enc_cfg.max_bit_rate); - - evrc_enc_cfg.min_bit_rate = 4; - evrc_enc_cfg.max_bit_rate = 4; - - if (ioctl(mFd, AUDIO_SET_EVRC_ENC_CONFIG, &evrc_enc_cfg)) - { - ALOGE("Error: AUDIO_SET_EVRC_ENC_CONFIG failed\n"); - goto Error; - } - } - else if (*pFormat == AudioSystem::QCELP) - { - ALOGI("Recording format: QCELP"); - // open qcelp input device - status = ::open(QCELP_DEVICE_IN, O_RDONLY); - if (status < 0) { - ALOGE("Cannot open qcelp device for read"); - goto Error; - } - mFd = status; - mDevices = devices; - mChannels = *pChannels; - - if (mDevices == AudioSystem::DEVICE_IN_VOICE_CALL) - { - if ((mChannels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) && - (mChannels & AudioSystem::CHANNEL_IN_VOICE_UPLINK)) { - ALOGI("Recording Source: Voice Call Both Uplink and Downlink"); - voc_rec_cfg.rec_mode = VOC_REC_BOTH; - } else if (mChannels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { - ALOGI("Recording Source: Voice Call DownLink"); - voc_rec_cfg.rec_mode = VOC_REC_DOWNLINK; - } else if (mChannels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) { - ALOGI("Recording Source: Voice Call UpLink"); - voc_rec_cfg.rec_mode = VOC_REC_UPLINK; - } - - if (ioctl(mFd, AUDIO_SET_INCALL, &voc_rec_cfg)) - { - ALOGE("Error: AUDIO_SET_INCALL failed\n"); - goto Error; - } - } - - /* Config param */ - struct msm_audio_stream_config config; - if(ioctl(mFd, AUDIO_GET_STREAM_CONFIG, &config)) - { - ALOGE(" Error getting buf config param AUDIO_GET_STREAM_CONFIG \n"); - goto Error; - } - - ALOGV("The Config buffer size is %d", config.buffer_size); - ALOGV("The Config buffer count is %d", config.buffer_count); - - mSampleRate =8000; - mFormat = *pFormat; - mBufferSize = 350; - - struct msm_audio_qcelp_enc_config qcelp_enc_cfg; - - if (ioctl(mFd, AUDIO_GET_QCELP_ENC_CONFIG, &qcelp_enc_cfg)) - { - ALOGE("Error: AUDIO_GET_QCELP_ENC_CONFIG failed\n"); - goto Error; - } - - ALOGV("The Config cdma_rate is %d", qcelp_enc_cfg.cdma_rate); - ALOGV("The Config min_bit_rate is %d", qcelp_enc_cfg.min_bit_rate); - ALOGV("The Config max_bit_rate is %d", qcelp_enc_cfg.max_bit_rate); - - qcelp_enc_cfg.min_bit_rate = 4; - qcelp_enc_cfg.max_bit_rate = 4; - - if (ioctl(mFd, AUDIO_SET_QCELP_ENC_CONFIG, &qcelp_enc_cfg)) - { - ALOGE("Error: AUDIO_SET_QCELP_ENC_CONFIG failed\n"); - goto Error; - } - } - else if (*pFormat == AudioSystem::AMR_NB) - { - ALOGI("Recording format: AMR_NB"); - // open amr_nb input device - status = ::open(AMRNB_DEVICE_IN, O_RDONLY); - if (status < 0) { - ALOGE("Cannot open amr_nb device for read"); - goto Error; - } - mFd = status; - mDevices = devices; - mChannels = *pChannels; - - if (mDevices == AudioSystem::DEVICE_IN_VOICE_CALL) - { - if ((mChannels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) && - (mChannels & AudioSystem::CHANNEL_IN_VOICE_UPLINK)) { - ALOGI("Recording Source: Voice Call Both Uplink and Downlink"); - voc_rec_cfg.rec_mode = VOC_REC_BOTH; - } else if (mChannels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { - ALOGI("Recording Source: Voice Call DownLink"); - voc_rec_cfg.rec_mode = VOC_REC_DOWNLINK; - } else if (mChannels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) { - ALOGI("Recording Source: Voice Call UpLink"); - voc_rec_cfg.rec_mode = VOC_REC_UPLINK; - } - - if (ioctl(mFd, AUDIO_SET_INCALL, &voc_rec_cfg)) - { - ALOGE("Error: AUDIO_SET_INCALL failed\n"); - goto Error; - } - } - - /* Config param */ - struct msm_audio_stream_config config; - if(ioctl(mFd, AUDIO_GET_STREAM_CONFIG, &config)) - { - ALOGE(" Error getting buf config param AUDIO_GET_STREAM_CONFIG \n"); - goto Error; - } - - ALOGV("The Config buffer size is %d", config.buffer_size); - ALOGV("The Config buffer count is %d", config.buffer_count); - - mSampleRate =8000; - mFormat = *pFormat; - mBufferSize = 320; - struct msm_audio_amrnb_enc_config_v2 amr_nb_cfg; - - if (ioctl(mFd, AUDIO_GET_AMRNB_ENC_CONFIG_V2, &amr_nb_cfg)) - { - ALOGE("Error: AUDIO_GET_AMRNB_ENC_CONFIG_V2 failed\n"); - goto Error; - } - - ALOGV("The Config band_mode is %d", amr_nb_cfg.band_mode); - ALOGV("The Config dtx_enable is %d", amr_nb_cfg.dtx_enable); - ALOGV("The Config frame_format is %d", amr_nb_cfg.frame_format); - - amr_nb_cfg.band_mode = 7; /* Bit Rate 12.2 kbps MR122 */ - amr_nb_cfg.dtx_enable= 0; - amr_nb_cfg.frame_format = 0; /* IF1 */ - - if (ioctl(mFd, AUDIO_SET_AMRNB_ENC_CONFIG_V2, &amr_nb_cfg)) - { - ALOGE("Error: AUDIO_SET_AMRNB_ENC_CONFIG_V2 failed\n"); - goto Error; - } - } -#endif - else if (*pFormat == AudioSystem::AAC) - { - ALOGI("Recording format: AAC"); - // open aac input device - status = ::open(AAC_DEVICE_IN, O_RDWR); - if (status < 0) { - ALOGE("Cannot open aac device for read"); - goto Error; - } - mFd = status; - - struct msm_audio_stream_config config; - if(ioctl(mFd, AUDIO_GET_STREAM_CONFIG, &config)) - { - ALOGE(" Error getting buf config param AUDIO_GET_STREAM_CONFIG \n"); - goto Error; - } - - ALOGE("The Config buffer size is %d", config.buffer_size); - ALOGE("The Config buffer count is %d", config.buffer_count); - - - struct msm_audio_aac_enc_config aac_enc_cfg; - if (ioctl(mFd, AUDIO_GET_AAC_ENC_CONFIG, &aac_enc_cfg)) - { - ALOGE("Error: AUDIO_GET_AAC_ENC_CONFIG failed\n"); - goto Error; - } - - ALOGV("The Config channels is %d", aac_enc_cfg.channels); - ALOGV("The Config sample_rate is %d", aac_enc_cfg.sample_rate); - ALOGV("The Config bit_rate is %d", aac_enc_cfg.bit_rate); - ALOGV("The Config stream_format is %d", aac_enc_cfg.stream_format); - - mDevices = devices; - mChannels = *pChannels; - aac_enc_cfg.sample_rate = mSampleRate = *pRate; - mFormat = *pFormat; - mBufferSize = 2048; - if (*pChannels & (AudioSystem::CHANNEL_IN_MONO)) - aac_enc_cfg.channels = 1; - else if (*pChannels & (AudioSystem::CHANNEL_IN_STEREO)) - aac_enc_cfg.channels = 2; - aac_enc_cfg.bit_rate = 128000; - - ALOGV("Setting the Config channels is %d", aac_enc_cfg.channels); - ALOGV("Setting the Config sample_rate is %d", aac_enc_cfg.sample_rate); - ALOGV("Setting the Config bit_rate is %d", aac_enc_cfg.bit_rate); - ALOGV("Setting the Config stream_format is %d", aac_enc_cfg.stream_format); - - if (ioctl(mFd, AUDIO_SET_AAC_ENC_CONFIG, &aac_enc_cfg)) - { - ALOGE("Error: AUDIO_SET_AAC_ENC_CONFIG failed\n"); - goto Error; - } - } - //mHardware->setMicMute_nosync(false); - mState = AUDIO_INPUT_OPENED; -#ifdef HTC_AUDIO - mHardware->set_mRecordState(true); -#endif - - if (!acoustic) - return NO_ERROR; - - int (*msm72xx_set_audpre_params)(int, int); - msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params"); - if ((*msm72xx_set_audpre_params) == 0) { - ALOGI("msm72xx_set_audpre_params not present"); - return NO_ERROR; - } - - int (*msm72xx_enable_audpre)(int, int, int); - msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre"); - if ((*msm72xx_enable_audpre) == 0) { - ALOGI("msm72xx_enable_audpre not present"); - return NO_ERROR; - } - - audpre_index = calculate_audpre_table_index(mSampleRate); - tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1); - ALOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index); - - /** - * If audio-preprocessing failed, we should not block record. - */ - status = msm72xx_set_audpre_params(audpre_index, tx_iir_index); - if (status < 0) - ALOGE("Cannot set audpre parameters"); - - mAcoustics = acoustic_flags; - status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index); - if (status < 0) - ALOGE("Cannot enable audpre"); - - return NO_ERROR; - -Error: - if (mFd >= 0) { - ::close(mFd); - mFd = -1; - } - return status; -} - -AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() -{ - ALOGV("AudioStreamInMSM72xx destructor"); - standby(); -} - -ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) -{ - unsigned short dec_id = INVALID_DEVICE; - ALOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); - if (!mHardware) return -1; - - size_t count = bytes; - size_t aac_framesize= bytes; - uint8_t* p = static_cast(buffer); - uint32_t* recogPtr = (uint32_t *)p; - uint16_t* frameCountPtr; - uint16_t* frameSizePtr; - - if (mState < AUDIO_INPUT_OPENED) { - AudioHardware *hw = mHardware; - hw->mLock.lock(); - status_t status = set(hw, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics); - if (status != NO_ERROR) { - hw->mLock.unlock(); - return -1; - } -#ifdef QCOM_FM_ENABLED - if((mDevices == AudioSystem::DEVICE_IN_FM_RX) || (mDevices == AudioSystem::DEVICE_IN_FM_RX_A2DP) ){ - if(ioctl(mFd, AUDIO_GET_SESSION_ID, &dec_id)) { - ALOGE("AUDIO_GET_SESSION_ID failed*********"); - hw->mLock.unlock(); - return -1; - } - - if(enableDevice(DEVICE_FMRADIO_STEREO_TX, 1)) { - ALOGE("enableDevice failed for device %d",DEVICE_FMRADIO_STEREO_TX); - hw->mLock.unlock(); - return -1; - } - - if(msm_route_stream(PCM_REC, dec_id, DEV_ID(DEVICE_FMRADIO_STEREO_TX), 1)) { - ALOGE("msm_route_stream failed"); - hw->mLock.unlock(); - return -1; - } - mFirstread = false; - if (mDevices == AudioSystem::DEVICE_IN_FM_RX_A2DP) { - addToTable(dec_id,cur_tx,INVALID_DEVICE,FM_A2DP,true); - mFmRec = FM_A2DP_REC; - } - else { - addToTable(dec_id,cur_tx,INVALID_DEVICE,FM_REC,true); - mFmRec = FM_FILE_REC; - } - hw->mLock.unlock(); - } - else -#endif - { - hw->mLock.unlock(); - if(ioctl(mFd, AUDIO_GET_SESSION_ID, &dec_id)) { - ALOGE("AUDIO_GET_SESSION_ID failed*********"); - return -1; - } - ALOGV("dec_id = %d,cur_tx= %d",dec_id,cur_tx); - if(cur_tx == INVALID_DEVICE) - cur_tx = DEVICE_HANDSET_TX; - - Mutex::Autolock lock(mDeviceSwitchLock); - - if(enableDevice(cur_tx, 1)) { - ALOGE("enableDevice failed, device %d",cur_tx); - return -1; - } - if(msm_route_stream(PCM_REC, dec_id, DEV_ID(cur_tx), 1)) { - ALOGE("msm_route_stream failed"); - return -1; - } - addToTable(dec_id,cur_tx,INVALID_DEVICE,PCM_REC,true); - mFirstread = false; - } - } - - - if (mState < AUDIO_INPUT_STARTED) { - // force routing to input device - mHardware->clearCurDevice(); - mHardware->doRouting(this); -#ifdef HTC_AUDIO - if (support_aic3254) { - int snd_dev = mHardware->get_snd_dev(); - mHardware->aic3254_config(snd_dev); - mHardware->do_aic3254_control(snd_dev); - } -#endif - if (ioctl(mFd, AUDIO_START, 0)) { - ALOGE("Error starting record"); - standby(); - return -1; - } - mState = AUDIO_INPUT_STARTED; - } - - bytes = 0; - if(mFormat == AUDIO_HW_IN_FORMAT) - { - while (count) { - ssize_t bytesRead = ::read(mFd, buffer, count); - if (bytesRead >= 0) { - count -= bytesRead; - p += bytesRead; - bytes += bytesRead; - if(!mFirstread) - { - mFirstread = true; - break; - } - } else { - if (errno != EAGAIN) return bytesRead; - mRetryCount++; - ALOGW("EAGAIN - retrying"); - } - } - } -#ifdef WITH_QCOM_SPEECH - else if ((mFormat == AudioSystem::EVRC) || (mFormat == AudioSystem::QCELP) || (mFormat == AudioSystem::AMR_NB)) - { - uint8_t readBuf[36]; - uint8_t *dataPtr; - while (count) { - dataPtr = readBuf; - ssize_t bytesRead = ::read(mFd, readBuf, 36); - if (bytesRead >= 0) { - if (mFormat == AudioSystem::AMR_NB){ - amr_transcode(dataPtr,p); - p += AMRNB_FRAME_SIZE; - count -= AMRNB_FRAME_SIZE; - bytes += AMRNB_FRAME_SIZE; - if(!mFirstread) - { - mFirstread = true; - break; - } - } - else { - dataPtr++; - if (mFormat == AudioSystem::EVRC){ - memcpy(p, dataPtr, EVRC_FRAME_SIZE); - p += EVRC_FRAME_SIZE; - count -= EVRC_FRAME_SIZE; - bytes += EVRC_FRAME_SIZE; - if(!mFirstread) - { - mFirstread = true; - break; - } - } - else if (mFormat == AudioSystem::QCELP){ - memcpy(p, dataPtr, QCELP_FRAME_SIZE); - p += QCELP_FRAME_SIZE; - count -= QCELP_FRAME_SIZE; - bytes += QCELP_FRAME_SIZE; - if(!mFirstread) - { - mFirstread = true; - break; - } - } - } - - } else { - if (errno != EAGAIN) return bytesRead; - mRetryCount++; - ALOGW("EAGAIN - retrying"); - } - } - } -#endif - else if (mFormat == AudioSystem::AAC) - { - *((uint32_t*)recogPtr) = 0x51434F4D ;// ('Q','C','O', 'M') Number to identify format as AAC by higher layers - recogPtr++; - frameCountPtr = (uint16_t*)recogPtr; - *frameCountPtr = 0; - p += 3*sizeof(uint16_t); - count -= 3*sizeof(uint16_t); - - while (count > 0) { - frameSizePtr = (uint16_t *)p; - p += sizeof(uint16_t); - if(!(count > 2)) break; - count -= sizeof(uint16_t); - - ssize_t bytesRead = ::read(mFd, p, count); - if (bytesRead > 0) { - ALOGV("Number of Bytes read = %d", bytesRead); - count -= bytesRead; - p += bytesRead; - bytes += bytesRead; - ALOGV("Total Number of Bytes read = %d", bytes); - - *frameSizePtr = bytesRead; - (*frameCountPtr)++; - if(!mFirstread) - { - mFirstread = true; - break; - } - /*Typical frame size for AAC is around 250 bytes. So we have - * taken the minimum buffer size as twice of this size i.e. - * 512 to avoid short reads from driver */ - if(count < 512) - { - ALOGI("buffer passed to driver %d, is less than the min 512 bytes", count); - break; - } - } - else if(bytesRead == 0) - { - ALOGI("Bytes Read = %d ,Buffer no longer sufficient",bytesRead); - break; - } else { - if (errno != EAGAIN) return bytesRead; - mRetryCount++; - ALOGW("EAGAIN - retrying"); - } - } - } - - if (mFormat == AudioSystem::AAC) - return aac_framesize; - - return bytes; -} - -status_t AudioHardware::AudioStreamInMSM72xx::standby() -{ - bool isDriverClosed = false; - ALOGD("AudioStreamInMSM72xx::standby()"); - Routing_table* temp = NULL; - if (!mHardware) return -1; - -#ifdef HTC_AUDIO - mHardware->set_mRecordState(false); - if (support_aic3254) { - int snd_dev = mHardware->get_snd_dev(); - mHardware->aic3254_config(snd_dev); - mHardware->do_aic3254_control(snd_dev); - } -#endif - - if (mState > AUDIO_INPUT_CLOSED) { - if (mFd >= 0) { - ::close(mFd); - mFd = -1; - ALOGV("driver closed"); - isDriverClosed = true; - } - //mHardware->checkMicMute(); - mState = AUDIO_INPUT_CLOSED; - } -#ifdef QCOM_FM_ENABLED - if (mFmRec == FM_A2DP_REC) { - //A2DP Recording - temp = getNodeByStreamType(FM_A2DP); - if(temp == NULL) - return NO_ERROR; - if(msm_route_stream(PCM_PLAY, temp->dec_id, DEV_ID(DEVICE_FMRADIO_STEREO_TX), 0)) { - ALOGE("msm_route_stream failed"); - return 0; - } - deleteFromTable(FM_A2DP); - if(enableDevice(DEVICE_FMRADIO_STEREO_TX, 0)) { - ALOGE("Disabling device failed for device %d", DEVICE_FMRADIO_STEREO_TX); - } - } - if (mFmRec == FM_FILE_REC) { - //FM Recording - temp = getNodeByStreamType(FM_REC); - if(temp == NULL) - return NO_ERROR; - if(msm_route_stream(PCM_PLAY, temp->dec_id, DEV_ID(DEVICE_FMRADIO_STEREO_TX), 0)) { - ALOGE("msm_route_stream failed"); - return 0; - } - deleteFromTable(FM_REC); - } -#endif - temp = getNodeByStreamType(PCM_REC); - if(temp == NULL) - return NO_ERROR; - - if(isDriverClosed){ - ALOGD("Deroute pcm in stream"); - if(msm_route_stream(PCM_REC, temp->dec_id,DEV_ID(temp->dev_id), 0)) { - ALOGE("could not set stream routing\n"); - deleteFromTable(PCM_REC); - return -1; - } - ALOGV("Disable device"); - deleteFromTable(PCM_REC); -#ifdef HTC_AUDIO - updateDeviceInfo(cur_rx, cur_tx, 0, 0); -#else - updateDeviceInfo(cur_rx, cur_tx); -#endif - }//mRecordingSession condition. - // restore output routing if necessary - mHardware->clearCurDevice(); - mHardware->doRouting(this); - return NO_ERROR; -} - -status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector& args) -{ - const size_t SIZE = 256; - char buffer[SIZE]; - String8 result; - result.append("AudioStreamInMSM72xx::dump\n"); - snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); - result.append(buffer); - snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); - result.append(buffer); - snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); - result.append(buffer); - snprintf(buffer, SIZE, "\tformat: %d\n", format()); - result.append(buffer); - snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); - result.append(buffer); - snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); - result.append(buffer); - snprintf(buffer, SIZE, "\tmState: %d\n", mState); - result.append(buffer); - snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); - result.append(buffer); - ::write(fd, result.string(), result.size()); - return NO_ERROR; -} - -status_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs) -{ - AudioParameter param = AudioParameter(keyValuePairs); - String8 key = String8(AudioParameter::keyRouting); - status_t status = NO_ERROR; - int device; - ALOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string()); - - if (param.getInt(key, device) == NO_ERROR) { - ALOGV("set input routing %x", device); - if (device & (device - 1)) { - status = BAD_VALUE; - } else { - mDevices = device; - status = mHardware->doRouting(this); - } - param.remove(key); - } - - if (param.size()) { - status = BAD_VALUE; - } - return status; -} - -String8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys) -{ - AudioParameter param = AudioParameter(keys); - String8 value; - String8 key = String8(AudioParameter::keyRouting); - - if (param.get(key, value) == NO_ERROR) { - ALOGV("get routing %x", mDevices); - param.addInt(key, (int)mDevices); - } - - ALOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string()); - return param.toString(); -} - -// getActiveInput_l() must be called with mLock held -AudioHardware::AudioStreamInMSM72xx *AudioHardware::getActiveInput_l() -{ - for (size_t i = 0; i < mInputs.size(); i++) { - // return first input found not being in standby mode - // as only one input can be in this state - if (mInputs[i]->state() > AudioStreamInMSM72xx::AUDIO_INPUT_CLOSED) { - return mInputs[i]; - } - } - - return NULL; -} - -#ifdef WITH_QCOM_VOIP_OVER_MVS -status_t AudioHardware::setupDeviceforVoipCall(bool value) -{ - - int mode = (value ? AudioSystem::MODE_IN_COMMUNICATION : AudioSystem::MODE_NORMAL); - if (setMode(mode) != NO_ERROR) { - ALOGV("setMode fails"); - return UNKNOWN_ERROR; - } - - if (setMicMute(!value) != NO_ERROR) { - ALOGV("MicMute fails"); - return UNKNOWN_ERROR; - } - - ALOGD("Device setup sucess for VOIP call"); - - return NO_ERROR; -} - -AudioHardware::AudioStreamInVoip::AudioStreamInVoip() : - mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), - mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), - mSampleRate(AUDIO_HW_VOIP_SAMPLERATE_8K), mBufferSize(AUDIO_HW_VOIP_BUFFERSIZE_8K), - mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) -{ -} - -status_t AudioHardware::AudioStreamInVoip::set( - AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, - AudioSystem::audio_in_acoustics acoustic_flags) -{ - ALOGV(" AudioHardware::AudioStreamInVoip::set devices = %u format = %d pChannels = %u Rate = %u \n", - devices, *pFormat, *pChannels, *pRate); - ALOGV("AudioStreamInVoip cur_rx %d, cur_tx %d" ,cur_rx,cur_tx); - if (pFormat == 0 ||*pFormat != AUDIO_HW_IN_FORMAT) - { - *pFormat = AUDIO_HW_IN_FORMAT; - return BAD_VALUE; - } - - if (pRate == 0) { - return BAD_VALUE; - } - - uint32_t rate = hw->getInputSampleRate(*pRate); - if (rate != *pRate) { - *pRate = rate; - ALOGE(" sample rate does not match\n"); - return BAD_VALUE; - } - - if (pChannels == 0 || (*pChannels & (AudioSystem::CHANNEL_IN_MONO)) == 0) { - *pChannels = AUDIO_HW_IN_CHANNELS; - ALOGE(" Channle count does not match\n"); - return BAD_VALUE; - } - - mHardware = hw; - - ALOGV("AudioStreamInVoip::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); - if (mFd >= 0) { - ALOGE("Audio record already open"); - return -EPERM; - } - - status_t status = NO_INIT; - // open driver - ALOGV("Check if driver is open"); - if(mHardware->mVoipFd >= 0) { - mFd = mHardware->mVoipFd; - } - else { - - ALOGV("Going to enable RX/TX device for voice stream"); - // Routing Voice - if ( (cur_rx != INVALID_DEVICE) && (cur_tx != INVALID_DEVICE)) - { - ALOGV("Starting voice on Rx %d and Tx %d device", DEV_ID(cur_rx), DEV_ID(cur_tx)); - msm_route_voice(DEV_ID(cur_rx),DEV_ID(cur_tx), 1); - } - else - { - return -1; - } - - if(cur_rx != INVALID_DEVICE && (enableDevice(cur_rx,1) == -1)) - { - ALOGI(" Enable device for cur_rx failed \n"); - return -1; - } - - if(cur_tx != INVALID_DEVICE&&(enableDevice(cur_tx,1) == -1)) - { - ALOGE(" Enable device for cur_tx failed \n"); - return -1; - } - - // start Voice call - ALOGD("Starting voice call and UnMuting the call"); - msm_start_voice(); - msm_set_voice_tx_mute(0); - addToTable(0,cur_rx,cur_tx,VOICE_CALL,true); - - ALOGE("open mvs driver"); - status = ::open(MVS_DEVICE, /*O_WRONLY*/ O_RDWR); - if (status < 0) { - ALOGE("Cannot open %s errno: %d",MVS_DEVICE, errno); - goto Error; - } - - mFd = status; - ALOGE("VOPIstreamin : Save the fd \n"); - - // configuration - ALOGV("get mvs config"); - struct msm_audio_mvs_config mvs_config; - status = ioctl(mFd, AUDIO_GET_MVS_CONFIG, &mvs_config); - if (status < 0) { - ALOGE("Cannot read mvs config"); - goto Error; - } - - ALOGV("set mvs config"); - mvs_config.mvs_mode = MVS_MODE_PCM; - status = ioctl(mFd, AUDIO_SET_MVS_CONFIG, &mvs_config); - if (status < 0) { - ALOGE("Cannot set mvs config"); - goto Error; - } - - ALOGV("start mvs"); - status = ioctl(mFd, AUDIO_START, 0); - if (status < 0) { - ALOGE("Cannot start mvs driver"); - goto Error; - } - } - mFormat = *pFormat; - mChannels = *pChannels; - mSampleRate = *pRate; - if(mSampleRate == AUDIO_HW_VOIP_SAMPLERATE_8K) { - mBufferSize = AUDIO_HW_VOIP_BUFFERSIZE_8K; - } else if(mSampleRate == AUDIO_HW_VOIP_SAMPLERATE_16K) { - mBufferSize = AUDIO_HW_VOIP_BUFFERSIZE_16K; - } else { - ALOGE("AudioStreamInVoip::set return bad values\n"); - return BAD_VALUE; - } - - ALOGV(" AudioHardware::AudioStreamInVoip::set after configuring devices = %u format = %d pChannels = %u Rate = %u \n", - devices, mFormat, mChannels, mSampleRate); - - ALOGV(" Set state AUDIO_INPUT_OPENED\n"); - mState = AUDIO_INPUT_OPENED; - - ALOGV(" Set mVoipFd now\n"); - mHardware->mVoipFd = mFd; - mHardware->mVoipInActive = true; - - if (mHardware->mVoipOutActive) - mHardware->setupDeviceforVoipCall(true); - - if (!acoustic) - return NO_ERROR; - - return NO_ERROR; - -Error: - if (mFd >= 0) { - ::close(mFd); - mFd = -1; - mHardware->mVoipFd = -1; - } - ALOGE("Error : ret status \n"); - return status; -} - -AudioHardware::AudioStreamInVoip::~AudioStreamInVoip() -{ - ALOGV("AudioStreamInVoip destructor"); - mHardware->mVoipInActive = false; - standby(); -} - -ssize_t AudioHardware::AudioStreamInVoip::read( void* buffer, ssize_t bytes) -{ - unsigned short dec_id = INVALID_DEVICE; - ALOGV("AudioStreamInVoip::read(%p, %ld)", buffer, bytes); - if (!mHardware) return -1; - - size_t count = bytes; - size_t totalBytesRead = 0; - - if (mState < AUDIO_INPUT_OPENED) { - ALOGE(" reopen the device \n"); - AudioHardware *hw = mHardware; - hw->mLock.lock(); - status_t status = set(hw, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics); - if (status != NO_ERROR) { - hw->mLock.unlock(); - return -1; - } - hw->mLock.unlock(); - mState = AUDIO_INPUT_STARTED; - bytes = 0; - }else - ALOGV("AudioStreamInVoip::read : device is already open \n"); - - - if(mFormat == AUDIO_HW_IN_FORMAT) - { - if(count < mBufferSize) { - ALOGE("read:: read size requested is less than min input buffer size"); - return 0; - } - - struct q5v2_msm_audio_mvs_frame audio_mvs_frame; - audio_mvs_frame.frame_type = 0; - while (count >= mBufferSize) { - audio_mvs_frame.len = mBufferSize; - ALOGV("Calling read count = %u mBufferSize = %u\n",count, mBufferSize ); - int bytesRead = ::read(mFd, &audio_mvs_frame, sizeof(audio_mvs_frame)); - ALOGV("read_bytes = %d mvs bytes \n", bytesRead); - if (bytesRead > 0) { - memcpy(buffer+totalBytesRead,&audio_mvs_frame.voc_pkt, mBufferSize); - count -= mBufferSize; - totalBytesRead += mBufferSize; - if(!mFirstread){ - mFirstread = true; - break; - } - } else { - ALOGE("retry read count = %d buffersize = %d\n", count, mBufferSize); - if (errno != EAGAIN) return bytesRead; - mRetryCount++; - ALOGW("EAGAIN - retrying"); - } - } - } - return totalBytesRead; -} - -status_t AudioHardware::AudioStreamInVoip::standby() -{ - Routing_table* temp = NULL; - ALOGD("AudioStreamInVoip::standby"); - Mutex::Autolock lock(mHardware->mVoipLock); - if (!mHardware) return -1; - ALOGE("VoipOut %d driver fd %d", mHardware->mVoipOutActive, mHardware->mVoipFd); - mHardware->mVoipInActive = false; - if (mState > AUDIO_INPUT_CLOSED && !mHardware->mVoipOutActive) { - ALOGE(" closing mvs driver\n"); - //Mute and disable the device. - int ret = msm_set_voice_rx_vol(0); - if (ret <0) - ALOGE("Error %d setting volume\n", ret); - ret = msm_set_voice_tx_mute(1); - if (ret < 0) - ALOGE("Error %d setting mute\n", ret); - ret = msm_end_voice(); - if (ret < 0) - ALOGE("Error %d ending voice\n", ret); - if (ret < 0) - ALOGE("Error %d closing mixer\n", ret); - if (mHardware->mVoipFd >= 0) { - ret = ioctl(mHardware->mVoipFd, AUDIO_STOP, NULL); - ALOGD("MVS stop returned %d %d %d\n", ret, __LINE__, mHardware->mVoipFd); - ::close(mFd); - mFd = mHardware->mVoipFd = -1; - mHardware->setupDeviceforVoipCall(false); - ALOGD("MVS driver closed %d mFd %d", __LINE__, mHardware->mVoipFd); - } - mState = AUDIO_INPUT_CLOSED; - } - else - ALOGE("Not closing MVS driver"); - return NO_ERROR; -} - -status_t AudioHardware::AudioStreamInVoip::dump(int fd, const Vector& args) -{ - const size_t SIZE = 256; - char buffer[SIZE]; - String8 result; - result.append("AudioStreamInVoip::dump\n"); - snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); - result.append(buffer); - snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); - result.append(buffer); - snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); - result.append(buffer); - snprintf(buffer, SIZE, "\tformat: %d\n", format()); - result.append(buffer); - snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); - result.append(buffer); - snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); - result.append(buffer); - snprintf(buffer, SIZE, "\tmState: %d\n", mState); - result.append(buffer); - snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); - result.append(buffer); - ::write(fd, result.string(), result.size()); - return NO_ERROR; -} - -status_t AudioHardware::AudioStreamInVoip::setParameters(const String8& keyValuePairs) -{ - AudioParameter param = AudioParameter(keyValuePairs); - String8 key = String8(AudioParameter::keyRouting); - status_t status = NO_ERROR; - int device; - ALOGV("AudioStreamInVoip::setParameters() %s", keyValuePairs.string()); - - if (param.getInt(key, device) == NO_ERROR) { - ALOGV("set input routing %x", device); - if (device & (device - 1)) { - ALOGV(" return BAD_VALUE "); - status = BAD_VALUE; - } else { - mDevices = device; - status = mHardware->doRouting(this); - } - param.remove(key); - } - - if (param.size()) { - status = BAD_VALUE; - } - - return status; -} - -String8 AudioHardware::AudioStreamInVoip::getParameters(const String8& keys) -{ - AudioParameter param = AudioParameter(keys); - String8 value; - String8 key = String8(AudioParameter::keyRouting); - - if (param.get(key, value) == NO_ERROR) { - ALOGV("get routing %x", mDevices); - param.addInt(key, (int)mDevices); - } - - ALOGV("AudioStreamInVoip::getParameters() %s", param.toString().string()); - return param.toString(); -} - -// getActiveInput_l() must be called with mLock held -AudioHardware::AudioStreamInVoip*AudioHardware::getActiveVoipInput_l() -{ - for (size_t i = 0; i < mVoipInputs.size(); i++) { - // return first input found not being in standby mode - // as only one input can be in this state - if (mVoipInputs[i]->state() > AudioStreamInVoip::AUDIO_INPUT_CLOSED) { - return mVoipInputs[i]; - } - } - - return NULL; -} -#endif - -// ---------------------------------------------------------------------------- - -extern "C" AudioHardwareInterface* createAudioHardware(void) { - return new AudioHardware(); -} - -#ifdef WITH_QCOM_SPEECH -/*=========================================================================== - -FUNCTION amrsup_frame_len - -DESCRIPTION - This function will determine number of bytes of AMR vocoder frame length -based on the frame type and frame rate. - -DEPENDENCIES - None. - -RETURN VALUE - number of bytes of AMR frame - -SIDE EFFECTS - None. - -===========================================================================*/ -int amrsup_frame_len_bits( - amrsup_frame_type frame_type, - amrsup_mode_type amr_mode -) -{ - int frame_len=0; - - - switch (frame_type) - { - case AMRSUP_SPEECH_GOOD : - case AMRSUP_SPEECH_DEGRADED : - case AMRSUP_ONSET : - case AMRSUP_SPEECH_BAD : - if (amr_mode >= AMRSUP_MODE_MAX) - { - frame_len = 0; - } - else - { - frame_len = amrsup_122_framing.len_a - + amrsup_122_framing.len_b - + amrsup_122_framing.len_c; - } - break; - - case AMRSUP_SID_FIRST : - case AMRSUP_SID_UPDATE : - case AMRSUP_SID_BAD : - frame_len = AMR_CLASS_A_BITS_SID; - break; - - case AMRSUP_NO_DATA : - case AMRSUP_SPEECH_LOST : - default : - frame_len = 0; - } - - return frame_len; -} - -/*=========================================================================== - -FUNCTION amrsup_frame_len - -DESCRIPTION - This function will determine number of bytes of AMR vocoder frame length -based on the frame type and frame rate. - -DEPENDENCIES - None. - -RETURN VALUE - number of bytes of AMR frame - -SIDE EFFECTS - None. - -===========================================================================*/ -int amrsup_frame_len( - amrsup_frame_type frame_type, - amrsup_mode_type amr_mode -) -{ - int frame_len = amrsup_frame_len_bits(frame_type, amr_mode); - - frame_len = (frame_len + 7) / 8; - return frame_len; -} - -/*=========================================================================== - -FUNCTION amrsup_tx_order - -DESCRIPTION - Use a bit ordering table to order bits from their original sequence. - -DEPENDENCIES - None. - -RETURN VALUE - None. - -SIDE EFFECTS - None. - -===========================================================================*/ -void amrsup_tx_order( - unsigned char *dst_frame, - int *dst_bit_index, - unsigned char *src, - int num_bits, - const unsigned short *order -) -{ - unsigned long dst_mask = 0x00000080 >> ((*dst_bit_index) & 0x7); - unsigned char *dst = &dst_frame[((unsigned int) *dst_bit_index) >> 3]; - unsigned long src_bit, src_mask; - - /* Prepare to process all bits - */ - *dst_bit_index += num_bits; - num_bits++; - - while(--num_bits) { - /* Get the location of the bit in the input buffer */ - src_bit = (unsigned long ) *order++; - src_mask = 0x00000080 >> (src_bit & 0x7); - - /* Set the value of the output bit equal to the input bit */ - if (src[src_bit >> 3] & src_mask) { - *dst |= (unsigned char ) dst_mask; - } - - /* Set the destination bit mask and increment pointer if necessary */ - dst_mask >>= 1; - if (dst_mask == 0) { - dst_mask = 0x00000080; - dst++; - } - } -} /* amrsup_tx_order */ - -/*=========================================================================== - -FUNCTION amrsup_if1_framing - -DESCRIPTION - Performs the transmit side framing function. Generates AMR IF1 ordered data - from the vocoder packet and frame type. - -DEPENDENCIES - None. - -RETURN VALUE - number of bytes of encoded frame. - if1_frame : IF1-encoded frame. - if1_frame_info : holds frame information of IF1-encoded frame. - -SIDE EFFECTS - None. - -===========================================================================*/ -static int amrsup_if1_framing( - unsigned char *vocoder_packet, - amrsup_frame_type frame_type, - amrsup_mode_type amr_mode, - unsigned char *if1_frame, - amrsup_if1_frame_info_type *if1_frame_info -) -{ - amrsup_frame_order_type *ordering_table; - int frame_len = 0; - int i; - - if(amr_mode >= AMRSUP_MODE_MAX) - { - ALOGE("Invalid AMR_Mode : %d",amr_mode); - return 0; - } - - /* Initialize IF1 frame data and info */ - if1_frame_info->fqi = true; - - if1_frame_info->amr_type = AMRSUP_CODEC_AMR_NB; - - memset(if1_frame, 0, - amrsup_frame_len(AMRSUP_SPEECH_GOOD, AMRSUP_MODE_1220)); - - - switch (frame_type) - { - case AMRSUP_SID_BAD: - if1_frame_info->fqi = false; - /* fall thru */ - - case AMRSUP_SID_FIRST: - case AMRSUP_SID_UPDATE: - /* Set frame type index */ - if1_frame_info->frame_type_index - = AMRSUP_FRAME_TYPE_INDEX_AMR_SID; - - - /* ===== Encoding SID frame ===== */ - /* copy the sid frame to class_a data */ - for (i=0; i<5; i++) - { - if1_frame[i] = vocoder_packet[i]; - } - - /* Set the SID type : SID_FIRST: Bit 35 = 0, SID_UPDATE : Bit 35 = 1 */ - if (frame_type == AMRSUP_SID_FIRST) - { - if1_frame[4] &= ~0x10; - } - - if (frame_type == AMRSUP_SID_UPDATE) - { - if1_frame[4] |= 0x10; - } - else - { - /* Set the mode (Bit 36 - 38 = amr_mode with bits swapped) - */ - if1_frame[4] |= (((unsigned char)amr_mode << 3) & 0x08) - | (((unsigned char)amr_mode << 1) & 0x04) | (((unsigned char)amr_mode >> 1) & 0x02); - - frame_len = AMR_CLASS_A_BITS_SID; - } - - break; - - - case AMRSUP_SPEECH_BAD: - if1_frame_info->fqi = false; - /* fall thru */ - - case AMRSUP_SPEECH_GOOD: - /* Set frame type index */ - - if1_frame_info->frame_type_index - = (amrsup_frame_type_index_type)(amr_mode); - - /* ===== Encoding Speech frame ===== */ - /* Clear num bits in frame */ - frame_len = 0; - - /* Select ordering table */ - ordering_table = - (amrsup_frame_order_type*)&amrsup_122_framing; - - amrsup_tx_order( - if1_frame, - &frame_len, - vocoder_packet, - ordering_table->len_a, - ordering_table->class_a - ); - - amrsup_tx_order( - if1_frame, - &frame_len, - vocoder_packet, - ordering_table->len_b, - ordering_table->class_b - ); - - amrsup_tx_order( - if1_frame, - &frame_len, - vocoder_packet, - ordering_table->len_c, - ordering_table->class_c - ); - - - /* frame_len already updated with correct number of bits */ - break; - - - - default: - ALOGE("Unsupported frame type %d", frame_type); - /* fall thru */ - - case AMRSUP_NO_DATA: - /* Set frame type index */ - if1_frame_info->frame_type_index = AMRSUP_FRAME_TYPE_INDEX_NO_DATA; - - frame_len = 0; - - break; - } /* end switch */ - - - /* convert bit length to byte length */ - frame_len = (frame_len + 7) / 8; - - return frame_len; -} - -static void amr_transcode(unsigned char *src, unsigned char *dst) -{ - amrsup_frame_type frame_type_in = (amrsup_frame_type) *(src++); - amrsup_mode_type frame_rate_in = (amrsup_mode_type) *(src++); - amrsup_if1_frame_info_type frame_info_out; - unsigned char frameheader; - - amrsup_if1_framing(src, frame_type_in, frame_rate_in, dst+1, &frame_info_out); - frameheader = (frame_info_out.frame_type_index << 3) + (frame_info_out.fqi << 2); - *dst = frameheader; - - return; -} -#endif - -}; // namespace android diff --git a/legacy/msm7x30/AudioHardware.h b/legacy/msm7x30/AudioHardware.h deleted file mode 100644 index 9a5b7f5..0000000 --- a/legacy/msm7x30/AudioHardware.h +++ /dev/null @@ -1,664 +0,0 @@ -/* -** Copyright 2008, The Android Open-Source Project -** Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. -** Copyright (c) 2011-2013, The CyanogenMod Project -** Not a Contribution, Apache license notifications and license are retained -** for attribution purposes only. -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef ANDROID_AUDIO_HARDWARE_H -#define ANDROID_AUDIO_HARDWARE_H - -#include -#include - -#include -#include - -#include - -extern "C" { -#include -#include -#ifdef WITH_QCOM_SPEECH -#include -#include -#endif -} - -namespace android_audio_legacy { -using android::SortedVector; -using android::Mutex; - -// ---------------------------------------------------------------------------- -// Kernel driver interface -// - -#define SAMP_RATE_INDX_8000 0 -#define SAMP_RATE_INDX_11025 1 -#define SAMP_RATE_INDX_12000 2 -#define SAMP_RATE_INDX_16000 3 -#define SAMP_RATE_INDX_22050 4 -#define SAMP_RATE_INDX_24000 5 -#define SAMP_RATE_INDX_32000 6 -#define SAMP_RATE_INDX_44100 7 -#define SAMP_RATE_INDX_48000 8 - -#define EQ_MAX_BAND_NUM 12 - -#define ADRC_ENABLE 0x0001 -#define ADRC_DISABLE 0x0000 -#define EQ_ENABLE 0x0002 -#define EQ_DISABLE 0x0000 -#define RX_IIR_ENABLE 0x0004 -#define RX_IIR_DISABLE 0x0000 - -#ifdef HTC_AUDIO -#define MOD_PLAY 1 -#define MOD_REC 2 -#define MOD_TX 3 -#define MOD_RX 4 - -#define VOICE_VOLUME_MAX 100 /* Maximum voice volume */ - -#define ACDB_ID_HAC_HANDSET_MIC 107 -#define ACDB_ID_HAC_HANDSET_SPKR 207 -#define ACDB_ID_EXT_MIC_REC 307 -#define ACDB_ID_HEADSET_PLAYBACK 407 -#define ACDB_ID_HEADSET_RINGTONE_PLAYBACK 408 -#define ACDB_ID_INT_MIC_REC 507 -#define ACDB_ID_CAMCORDER 508 -#define ACDB_ID_INT_MIC_VR 509 -#define ACDB_ID_SPKR_PLAYBACK 607 -#define ACDB_ID_ALT_SPKR_PLAYBACK 608 -#endif - -struct eq_filter_type { - int16_t gain; - uint16_t freq; - uint16_t type; - uint16_t qf; -}; - -struct eqalizer { - uint16_t bands; - uint16_t params[132]; -}; - -struct rx_iir_filter { - uint16_t num_bands; - uint16_t iir_params[48]; -}; - -struct msm_audio_stats { - uint32_t out_bytes; - uint32_t unused[3]; -}; - -#ifdef WITH_QCOM_SPEECH -/* AMR frame type definitions */ -typedef enum { - AMRSUP_SPEECH_GOOD, /* Good speech frame */ - AMRSUP_SPEECH_DEGRADED, /* Speech degraded */ - AMRSUP_ONSET, /* onset */ - AMRSUP_SPEECH_BAD, /* Corrupt speech frame (bad CRC) */ - AMRSUP_SID_FIRST, /* First silence descriptor */ - AMRSUP_SID_UPDATE, /* Comfort noise frame */ - AMRSUP_SID_BAD, /* Corrupt SID frame (bad CRC) */ - AMRSUP_NO_DATA, /* Nothing to transmit */ - AMRSUP_SPEECH_LOST, /* Lost speech in downlink */ - AMRSUP_FRAME_TYPE_MAX -} amrsup_frame_type; - -/* AMR frame mode (frame rate) definitions */ -typedef enum { - AMRSUP_MODE_0475, /* 4.75 kbit /s */ - AMRSUP_MODE_0515, /* 5.15 kbit /s */ - AMRSUP_MODE_0590, /* 5.90 kbit /s */ - AMRSUP_MODE_0670, /* 6.70 kbit /s */ - AMRSUP_MODE_0740, /* 7.40 kbit /s */ - AMRSUP_MODE_0795, /* 7.95 kbit /s */ - AMRSUP_MODE_1020, /* 10.2 kbit /s */ - AMRSUP_MODE_1220, /* 12.2 kbit /s */ - AMRSUP_MODE_MAX -} amrsup_mode_type; - -/* The AMR classes -*/ -typedef enum { - AMRSUP_CLASS_A, - AMRSUP_CLASS_B, - AMRSUP_CLASS_C -} amrsup_class_type; - -/* The maximum number of bits in each class */ -#define AMRSUP_CLASS_A_MAX 81 -#define AMRSUP_CLASS_B_MAX 405 -#define AMRSUP_CLASS_C_MAX 60 - -/* The size of the buffer required to hold the vocoder frame */ -#define AMRSUP_VOC_FRAME_BYTES \ - ((AMRSUP_CLASS_A_MAX + AMRSUP_CLASS_B_MAX + AMRSUP_CLASS_C_MAX + 7) / 8) - -/* Size of each AMR class to hold one frame of AMR data */ -#define AMRSUP_CLASS_A_BYTES ((AMRSUP_CLASS_A_MAX + 7) / 8) -#define AMRSUP_CLASS_B_BYTES ((AMRSUP_CLASS_B_MAX + 7) / 8) -#define AMRSUP_CLASS_C_BYTES ((AMRSUP_CLASS_C_MAX + 7) / 8) - - -/* Number of bytes for an AMR IF2 frame */ -#define AMRSUP_IF2_FRAME_BYTES 32 - -/* Frame types for 4-bit frame type as in 3GPP TS 26.101 v3.2.0, Sec.4.1.1 */ -typedef enum { - AMRSUP_FRAME_TYPE_INDEX_0475 = 0, /* 4.75 kbit /s */ - AMRSUP_FRAME_TYPE_INDEX_0515 = 1, /* 5.15 kbit /s */ - AMRSUP_FRAME_TYPE_INDEX_0590 = 2, /* 5.90 kbit /s */ - AMRSUP_FRAME_TYPE_INDEX_0670 = 3, /* 6.70 kbit /s */ - AMRSUP_FRAME_TYPE_INDEX_0740 = 4, /* 7.40 kbit /s */ - AMRSUP_FRAME_TYPE_INDEX_0795 = 5, /* 7.95 kbit /s */ - AMRSUP_FRAME_TYPE_INDEX_1020 = 6, /* 10.2 kbit /s */ - AMRSUP_FRAME_TYPE_INDEX_1220 = 7, /* 12.2 kbit /s */ - AMRSUP_FRAME_TYPE_INDEX_AMR_SID = 8, /* SID frame */ -/* Frame types 9-11 are not supported */ - AMRSUP_FRAME_TYPE_INDEX_NO_DATA = 15, /* No data */ - AMRSUP_FRAME_TYPE_INDEX_MAX, - AMRSUP_FRAME_TYPE_INDEX_UNDEF = AMRSUP_FRAME_TYPE_INDEX_MAX -} amrsup_frame_type_index_type; - -#define AMRSUP_FRAME_TYPE_INDEX_MASK 0x0F /* All frame types */ -#define AMRSUP_FRAME_TYPE_INDEX_SPEECH_MASK 0x07 /* Speech frame */ - -typedef enum { - AMRSUP_CODEC_AMR_NB, - AMRSUP_CODEC_AMR_WB, - AMRSUP_CODEC_MAX -} amrsup_codec_type; - -/* IF1-encoded frame info */ -typedef struct { - amrsup_frame_type_index_type frame_type_index; - unsigned char fqi; /* frame quality indicator: TRUE: good frame, FALSE: bad */ - amrsup_codec_type amr_type; /* AMR-NB or AMR-WB */ -} amrsup_if1_frame_info_type; - -#define AUDFADEC_AMR_FRAME_TYPE_MASK 0x78 -#define AUDFADEC_AMR_FRAME_TYPE_SHIFT 3 -#define AUDFADEC_AMR_FRAME_QUALITY_MASK 0x04 - -#define AMR_CLASS_A_BITS_BAD 0 - -#define AMR_CLASS_A_BITS_SID 39 - -#define AMR_CLASS_A_BITS_122 81 -#define AMR_CLASS_B_BITS_122 103 -#define AMR_CLASS_C_BITS_122 60 - -typedef struct { - int len_a; - unsigned short *class_a; - int len_b; - unsigned short *class_b; - int len_c; - unsigned short *class_c; -} amrsup_frame_order_type; -#endif - -#ifdef HTC_AUDIO -struct msm_bt_endpoint { - int tx; - int rx; - char name[64]; -}; -#endif - -enum tty_modes { - TTY_OFF = 0, - TTY_VCO = 1, - TTY_HCO = 2, - TTY_FULL = 3 -}; - -#define CODEC_TYPE_PCM 0 -#define AUDIO_HW_NUM_OUT_BUF 2 // Number of buffers in audio driver for output -// TODO: determine actual audio DSP and hardware latency -#define AUDIO_HW_OUT_LATENCY_MS 0 // Additionnal latency introduced by audio DSP and hardware in ms - -#define AUDIO_HW_IN_SAMPLERATE 8000 // Default audio input sample rate -#define AUDIO_HW_IN_CHANNELS (AudioSystem::CHANNEL_IN_MONO) // Default audio input channel mask -#define AUDIO_HW_IN_BUFFERSIZE 2048 // Default audio input buffer size -#define AUDIO_HW_IN_FORMAT (AudioSystem::PCM_16_BIT) // Default audio input sample format -#define AUDIO_HW_VOIP_BUFFERSIZE_8K 320 -#define AUDIO_HW_VOIP_BUFFERSIZE_16K 640 -#define AUDIO_HW_VOIP_SAMPLERATE_8K 8000 -#define AUDIO_HW_VOIP_SAMPLERATE_16K 16000 - -#ifdef WITH_QCOM_SPEECH -/* ======================== 12.2 kbps mode ========================== */ -const unsigned short amrsup_bit_order_122_a[AMR_CLASS_A_BITS_122] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 23, 15, 16, 17, 18, - 19, 20, 21, 22, 24, 25, 26, 27, 28, 38, - 141, 39, 142, 40, 143, 41, 144, 42, 145, 43, - 146, 44, 147, 45, 148, 46, 149, 47, 97, 150, - 200, 48, 98, 151, 201, 49, 99, 152, 202, 86, - 136, 189, 239, 87, 137, 190, 240, 88, 138, 191, - 241, 91, 194, 92, 195, 93, 196, 94, 197, 95, - 198 -}; - -const unsigned short amrsup_bit_order_122_b[AMR_CLASS_B_BITS_122] = { - /**/ 29, 30, 31, 32, 33, 34, 35, 50, 100, - 153, 203, 89, 139, 192, 242, 51, 101, 154, 204, - 55, 105, 158, 208, 90, 140, 193, 243, 59, 109, - 162, 212, 63, 113, 166, 216, 67, 117, 170, 220, - 36, 37, 54, 53, 52, 58, 57, 56, 62, 61, - 60, 66, 65, 64, 70, 69, 68, 104, 103, 102, - 108, 107, 106, 112, 111, 110, 116, 115, 114, 120, - 119, 118, 157, 156, 155, 161, 160, 159, 165, 164, - 163, 169, 168, 167, 173, 172, 171, 207, 206, 205, - 211, 210, 209, 215, 214, 213, 219, 218, 217, 223, - 222, 221, 73, 72 -}; - - -const unsigned short amrsup_bit_order_122_c[AMR_CLASS_C_BITS_122] = { - /* ------------- */ 71, 76, 75, 74, 79, 78, - 77, 82, 81, 80, 85, 84, 83, 123, 122, 121, - 126, 125, 124, 129, 128, 127, 132, 131, 130, 135, - 134, 133, 176, 175, 174, 179, 178, 177, 182, 181, - 180, 185, 184, 183, 188, 187, 186, 226, 225, 224, - 229, 228, 227, 232, 231, 230, 235, 234, 233, 238, - 237, 236, 96, 199 -}; - - -const amrsup_frame_order_type amrsup_122_framing = { - AMR_CLASS_A_BITS_122, - (unsigned short *) amrsup_bit_order_122_a, - AMR_CLASS_B_BITS_122, - (unsigned short *) amrsup_bit_order_122_b, - AMR_CLASS_C_BITS_122, - (unsigned short *) amrsup_bit_order_122_c -}; -#endif - -// ---------------------------------------------------------------------------- - -using android_audio_legacy::AudioHardwareBase; -using android_audio_legacy::AudioStreamOut; -using android_audio_legacy::AudioStreamIn; -using android_audio_legacy::AudioSystem; -using android_audio_legacy::AudioHardwareInterface; - -class AudioHardware : public AudioHardwareBase -{ - class AudioStreamOutMSM72xx; -#ifdef QCOM_TUNNEL_LPA_ENABLED - class AudioSessionOutMSM7xxx; -#endif /* QCOM_TUNNEL_LPA_ENABLED */ - class AudioStreamInMSM72xx; -#ifdef WITH_QCOM_VOIP_OVER_MVS - class AudioStreamOutDirect; - class AudioStreamInVoip; -#endif - -public: - AudioHardware(); - virtual ~AudioHardware(); - virtual status_t initCheck(); - - virtual status_t setVoiceVolume(float volume); - virtual status_t setMasterVolume(float volume); -#ifdef QCOM_FM_ENABLED - virtual status_t setFmVolume(float volume); -#endif - virtual status_t setMode(int mode); - - // mic mute - virtual status_t setMicMute(bool state); - virtual status_t getMicMute(bool* state); - - virtual status_t setParameters(const String8& keyValuePairs); - virtual String8 getParameters(const String8& keys); - - // create I/O streams - virtual AudioStreamOut* openOutputStream( - uint32_t devices, - // audio_output_flags_t flags, - int *format=0, - uint32_t *channels=0, - uint32_t *sampleRate=0, - status_t *status=0); -#ifdef QCOM_TUNNEL_LPA_ENABLED - virtual AudioStreamOut* openOutputSession( - uint32_t devices, - int *format=0, - status_t *status=0, - int sessionId=-1, - uint32_t samplingRate=0, - uint32_t channels=0); -#endif /* QCOM_TUNNEL_LPA_ENABLED */ - - virtual AudioStreamIn* openInputStream( - - uint32_t devices, - int *format, - uint32_t *channels, - uint32_t *sampleRate, - status_t *status, - AudioSystem::audio_in_acoustics acoustics); - - virtual void closeOutputStream(AudioStreamOut* out); - virtual void closeInputStream(AudioStreamIn* in); - - virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount); - void clearCurDevice() { mCurSndDevice = -1; } - -protected: - virtual status_t dump(int fd, const Vector& args); - status_t setupDeviceforVoipCall(bool value); - -private: - -#ifdef HTC_AUDIO - status_t doAudioRouteOrMuteHTC(uint32_t device); -#endif - status_t doAudioRouteOrMute(uint32_t device); - status_t setMicMute_nosync(bool state); - status_t checkMicMute(); - status_t dumpInternals(int fd, const Vector& args); - uint32_t getInputSampleRate(uint32_t sampleRate); - bool checkOutputStandby(); - status_t doRouting(AudioStreamInMSM72xx *input); -#ifdef QCOM_FM_ENABLED - status_t enableFM(int sndDevice); -#endif - status_t enableComboDevice(uint32_t sndDevice, bool enableOrDisable); -#ifdef QCOM_FM_ENABLED - status_t disableFM(); -#endif -#ifdef HTC_AUDIO - status_t get_mMode(); - status_t set_mRecordState(bool onoff); - status_t get_mRecordState(); - status_t get_snd_dev(); - uint32_t getACDB(int mode, uint32_t device); - status_t do_aic3254_control(uint32_t device); - bool isAic3254Device(uint32_t device); - status_t aic3254_config(uint32_t device); - int aic3254_ioctl(int cmd, const int argc); - void aic3254_powerdown(); - int aic3254_set_volume(int volume); -#endif - AudioStreamInMSM72xx* getActiveInput_l(); -#ifdef WITH_QCOM_VOIP_OVER_MVS - AudioStreamInVoip* getActiveVoipInput_l(); -#endif - FILE *fp; - - class AudioStreamOutMSM72xx : public AudioStreamOut { - public: - AudioStreamOutMSM72xx(); - virtual ~AudioStreamOutMSM72xx(); - status_t set(AudioHardware* mHardware, - uint32_t devices, - int *pFormat, - uint32_t *pChannels, - uint32_t *pRate); - virtual uint32_t sampleRate() const { return 44100; } - // must be 32-bit aligned - driver only seems to like 4800 - virtual size_t bufferSize() const { return 4800; } - virtual uint32_t channels() const { return AudioSystem::CHANNEL_OUT_STEREO; } - virtual int format() const { return AudioSystem::PCM_16_BIT; } - virtual uint32_t latency() const { return (1000*AUDIO_HW_NUM_OUT_BUF*(bufferSize()/frameSize()))/sampleRate()+AUDIO_HW_OUT_LATENCY_MS; } - virtual status_t setVolume(float left, float right) { return INVALID_OPERATION; } - virtual ssize_t write(const void* buffer, size_t bytes); - virtual status_t standby(); - virtual status_t dump(int fd, const Vector& args); - bool checkStandby(); - virtual status_t setParameters(const String8& keyValuePairs); - virtual String8 getParameters(const String8& keys); - uint32_t devices() { return mDevices; } - virtual status_t getRenderPosition(uint32_t *dspFrames); - - private: - AudioHardware* mHardware; - int mFd; - int mStartCount; - int mRetryCount; - bool mStandby; - uint32_t mDevices; - }; -#ifdef WITH_QCOM_VOIP_OVER_MVS - class AudioStreamOutDirect : public AudioStreamOut { - public: - AudioStreamOutDirect(); - virtual ~AudioStreamOutDirect(); - status_t set(AudioHardware* mHardware, - uint32_t devices, - int *pFormat, - uint32_t *pChannels, - uint32_t *pRate); - virtual uint32_t sampleRate() const { ALOGE(" AudioStreamOutDirect: sampleRate\n"); return 8000; } - // must be 32-bit aligned - driver only seems to like 4800 - virtual size_t bufferSize() const { ALOGE(" AudioStreamOutDirect: bufferSize\n"); return 320; } - virtual uint32_t channels() const {ALOGD(" AudioStreamOutDirect: channels\n"); return mChannels; } - virtual int format() const {ALOGE(" AudioStreamOutDirect: format\n"); return AudioSystem::PCM_16_BIT; } - virtual uint32_t latency() const { return (1000*AUDIO_HW_NUM_OUT_BUF*(bufferSize()/frameSize()))/sampleRate()+AUDIO_HW_OUT_LATENCY_MS; } - virtual status_t setVolume(float left, float right) { return INVALID_OPERATION; } - virtual ssize_t write(const void* buffer, size_t bytes); - virtual status_t standby(); - virtual status_t dump(int fd, const Vector& args); - bool checkStandby(); - virtual status_t setParameters(const String8& keyValuePairs); - virtual String8 getParameters(const String8& keys); - uint32_t devices() { return mDevices; } - virtual status_t getRenderPosition(uint32_t *dspFrames); - - private: - AudioHardware* mHardware; - int mFd; - int mStartCount; - int mRetryCount; - bool mStandby; - uint32_t mDevices; - int mSessionId; - uint32_t mChannels; - uint32_t mSampleRate; - size_t mBufferSize; - int mFormat; - - }; -#endif -#ifdef QCOM_TUNNEL_LPA_ENABLED - class AudioSessionOutMSM7xxx : public AudioStreamOut { - public: - AudioSessionOutMSM7xxx(); - virtual ~AudioSessionOutMSM7xxx(); - status_t set(AudioHardware* mHardware, - uint32_t devices, - int *pFormat, - int32_t sessionId); - virtual uint32_t sampleRate() const { return 44100; } - // must be 32-bit aligned - driver only seems to like 4800 - virtual size_t bufferSize() const { return 4800; } - virtual uint32_t channels() const { return AudioSystem::CHANNEL_OUT_STEREO; } - virtual int format() const { return AudioSystem::MP3; } - virtual uint32_t latency() const { return 0; } - virtual status_t setVolume(float left, float right); - virtual ssize_t write(const void* buffer, size_t bytes) {return 0;}; - virtual status_t standby(); - virtual status_t dump(int fd, const Vector& args) {return 0;}; - bool checkStandby(); - virtual status_t setParameters(const String8& keyValuePairs); - virtual String8 getParameters(const String8& keys); - uint32_t devices() { return mDevices; } - virtual status_t getRenderPosition(uint32_t *dspFrames); - - private: - AudioHardware* mHardware; - int mStartCount; - int mRetryCount; - bool mStandby; - uint32_t mDevices; - int mSessionId; - }; -#endif /* QCOM_TUNNEL_LPA_ENABLED */ - - class AudioStreamInMSM72xx : public AudioStreamIn { - public: - enum input_state { - AUDIO_INPUT_CLOSED, - AUDIO_INPUT_OPENED, - AUDIO_INPUT_STARTED - }; - - AudioStreamInMSM72xx(); - virtual ~AudioStreamInMSM72xx(); - status_t set(AudioHardware* mHardware, - uint32_t devices, - int *pFormat, - uint32_t *pChannels, - uint32_t *pRate, - AudioSystem::audio_in_acoustics acoustics); - virtual size_t bufferSize() const { return mBufferSize; } - virtual uint32_t channels() const { return mChannels; } - virtual int format() const { return mFormat; } - virtual uint32_t sampleRate() const { return mSampleRate; } - virtual status_t setGain(float gain) { return INVALID_OPERATION; } - virtual ssize_t read(void* buffer, ssize_t bytes); - virtual status_t dump(int fd, const Vector& args); - virtual status_t standby(); - virtual status_t setParameters(const String8& keyValuePairs); - virtual String8 getParameters(const String8& keys); - virtual unsigned int getInputFramesLost() const { return 0; } - uint32_t devices() { return mDevices; } - int state() const { return mState; } - virtual status_t addAudioEffect(effect_interface_s**) { return 0;} - virtual status_t removeAudioEffect(effect_interface_s**) { return 0;} - - private: - AudioHardware* mHardware; - int mFd; - int mState; - int mRetryCount; - int mFormat; - uint32_t mChannels; - uint32_t mSampleRate; - size_t mBufferSize; - AudioSystem::audio_in_acoustics mAcoustics; - uint32_t mDevices; - bool mFirstread; - uint32_t mFmRec; - }; - -#ifdef WITH_QCOM_VOIP_OVER_MVS - class AudioStreamInVoip : public AudioStreamInMSM72xx { //*/ AudioStreamIn { - public: - enum input_state { - AUDIO_INPUT_CLOSED, - AUDIO_INPUT_OPENED, - AUDIO_INPUT_STARTED - }; - - AudioStreamInVoip(); - virtual ~AudioStreamInVoip(); - status_t set(AudioHardware* mHardware, - uint32_t devices, - int *pFormat, - uint32_t *pChannels, - uint32_t *pRate, - AudioSystem::audio_in_acoustics acoustics); - virtual size_t bufferSize() const { ALOGE("\n AudioStreamInVoip mBufferSize %d ",mBufferSize); return mBufferSize; } //320; } - virtual uint32_t channels() const {ALOGD(" AudioStreamInVoip: channels %d \n",mChannels); return mChannels; } - virtual int format() const { ALOGE("\n AudioStreamInVoip mFormat %d",mFormat); return mFormat; }//AUDIO_HW_IN_FORMAT; } - virtual uint32_t sampleRate() const { ALOGE("\n AudioStreamInVoip mSampleRate %d ",mSampleRate); return mSampleRate;} //8000; } - virtual status_t setGain(float gain) { return INVALID_OPERATION; } - virtual ssize_t read(void* buffer, ssize_t bytes); - virtual status_t dump(int fd, const Vector& args); - virtual status_t standby(); - virtual status_t setParameters(const String8& keyValuePairs); - virtual String8 getParameters(const String8& keys); - virtual unsigned int getInputFramesLost() const { return 0; } - uint32_t devices() { return mDevices; } - int state() const { return mState; } - - private: - AudioHardware* mHardware; - int mFd; - int mState; - int mRetryCount; - int mFormat; - uint32_t mChannels; - uint32_t mSampleRate; - size_t mBufferSize; - AudioSystem::audio_in_acoustics mAcoustics; - uint32_t mDevices; - bool mFirstread; - uint32_t mFmRec; - int mSessionId; - }; -#endif - static const uint32_t inputSamplingRates[]; - bool mInit; - bool mMicMute; - int mFmFd; - bool mBluetoothNrec; - bool mBluetoothVGS; - uint32_t mBluetoothId; - float mVoiceVolume; -#ifdef HTC_AUDIO - bool mHACSetting; - uint32_t mBluetoothIdTx; - uint32_t mBluetoothIdRx; - msm_bt_endpoint *mBTEndpoints; - int mNumBTEndpoints; - int mNoiseSuppressionState; - bool mRecordState; - char mCurDspProfile[22]; - bool mEffectEnabled; - char mActiveAP[10]; - char mEffect[10]; -#endif - AudioStreamOutMSM72xx* mOutput; - SortedVector mInputs; -#ifdef WITH_QCOM_VOIP_OVER_MVS - AudioStreamOutDirect* mDirectOutput; -#endif - int mCurSndDevice; - int m7xsnddriverfd; - bool mDualMicEnabled; - int mTtyMode; -#ifdef WITH_QCOM_VOIP_OVER_MVS - SortedVector mVoipInputs; -#endif - - friend class AudioStreamInMSM72xx; - Mutex mLock; -#ifdef WITH_QCOM_VOIP_OVER_MVS - int mVoipFd; - bool mVoipInActive; - bool mVoipOutActive; - Mutex mVoipLock; - int mVoipSession; -#endif -}; - -// ---------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_AUDIO_HARDWARE_MSM72XX_H diff --git a/legacy/msm7x30/AudioPolicyManager.cpp b/legacy/msm7x30/AudioPolicyManager.cpp deleted file mode 100644 index 429f2ad..0000000 --- a/legacy/msm7x30/AudioPolicyManager.cpp +++ /dev/null @@ -1,2224 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. - * Not a Contribution. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "AudioPolicyManager" -//#define LOG_NDEBUG 0 -//#define LOG_NDDEBUG 0 - -//#define VERY_VERBOSE_LOGGING -#ifdef VERY_VERBOSE_LOGGING -#define ALOGVV ALOGV -#else -#define ALOGVV(a...) do { } while(0) -#endif - -// A device mask for all audio input devices that are considered "virtual" when evaluating -// active inputs in getActiveInput() -#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX - -#include - -#include "AudioPolicyManager.h" -#include -#include -#include -#include -#include -#include -#include - -namespace android_audio_legacy { - -// ---------------------------------------------------------------------------- -// AudioPolicyManager -// ---------------------------------------------------------------------------- - -AudioParameter param; - -void AudioPolicyManager::setStrategyMute(routing_strategy strategy, - bool on, - audio_io_handle_t output, - int delayMs, - audio_devices_t device) -{ - ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); - for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { - if (getStrategy((AudioSystem::stream_type)stream) == strategy) { - setStreamMute(stream, on, output, delayMs, device); - } - } -} - -void AudioPolicyManager::releaseOutput(audio_io_handle_t output) -{ - ALOGV("releaseOutput() %d", output); - ssize_t index = mOutputs.indexOfKey(output); - if (index < 0) { - ALOGW("releaseOutput() releasing unknown output %d", output); - return; - } - -#ifdef AUDIO_POLICY_TEST - int testIndex = testOutputIndex(output); - if (testIndex != 0) { - AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); - if (outputDesc->isActive()) { - mpClientInterface->closeOutput(output); - delete mOutputs.valueAt(index); - mOutputs.removeItem(output); - mTestOutputs[testIndex] = 0; - } - return; - } -#endif //AUDIO_POLICY_TEST - - AudioOutputDescriptor *desc = mOutputs.valueAt(index); - if (desc->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { - if ((desc->mDirectOpenCount <= 0) && !(desc->mFlags & AUDIO_OUTPUT_FLAG_LPA || desc->mFlags & AUDIO_OUTPUT_FLAG_TUNNEL || - desc->mFlags & AUDIO_OUTPUT_FLAG_VOIP_RX)) { - ALOGW("releaseOutput() invalid open count %d for output %d", - desc->mDirectOpenCount, output); - return; - } - if ((--desc->mDirectOpenCount == 0) || ((desc->mFlags & AUDIO_OUTPUT_FLAG_LPA || desc->mFlags & AUDIO_OUTPUT_FLAG_TUNNEL || - desc->mFlags & AUDIO_OUTPUT_FLAG_VOIP_RX))) { - ALOGV("releaseOutput() closing output"); - closeOutput(output); - } - } - -} - -uint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, - audio_devices_t prevDevice, - uint32_t delayMs) -{ - // mute/unmute strategies using an incompatible device combination - // if muting, wait for the audio in pcm buffer to be drained before proceeding - // if unmuting, unmute only after the specified delay - if (outputDesc->isDuplicated()) { - return 0; - } - - uint32_t muteWaitMs = 0; - audio_devices_t device = outputDesc->device(); - bool shouldMute = (outputDesc->isActive()) && - (AudioSystem::popCount(device) >= 2); - // temporary mute output if device selection changes to avoid volume bursts due to - // different per device volumes - bool tempMute = (outputDesc->isActive()) && (device != prevDevice); - - for (size_t i = 0; i < NUM_STRATEGIES; i++) { - audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); - bool mute = shouldMute && (curDevice & device) && (curDevice != device); - bool doMute = false; - - if (mute && !outputDesc->mStrategyMutedByDevice[i]) { - doMute = true; - outputDesc->mStrategyMutedByDevice[i] = true; - } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){ - doMute = true; - outputDesc->mStrategyMutedByDevice[i] = false; - } - if (doMute || tempMute) { - for (size_t j = 0; j < mOutputs.size(); j++) { - AudioOutputDescriptor *desc = mOutputs.valueAt(j); - // skip output if it does not share any device with current output - if ((desc->supportedDevices() & outputDesc->supportedDevices()) - == AUDIO_DEVICE_NONE) { - continue; - } - audio_io_handle_t curOutput = mOutputs.keyAt(j); - ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", - mute ? "muting" : "unmuting", i, curDevice, curOutput); - setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); - if (desc->isStrategyActive((routing_strategy)i)) { - // do tempMute only for current output - if (tempMute && (desc == outputDesc)) { - setStrategyMute((routing_strategy)i, true, curOutput); - setStrategyMute((routing_strategy)i, false, curOutput, - desc->latency() * ((desc->mFlags & AUDIO_OUTPUT_FLAG_LPA) ? 4 : 2), - device); - } - if ((tempMute && (desc == outputDesc)) || mute) { - if (muteWaitMs < desc->latency()) { - muteWaitMs = desc->latency(); - } - } - } - } - } - } - - // FIXME: should not need to double latency if volume could be applied immediately by the - // audioflinger mixer. We must account for the delay between now and the next time - // the audioflinger thread for this output will process a buffer (which corresponds to - // one buffer size, usually 1/2 or 1/4 of the latency). - muteWaitMs *= 2; - // wait for the PCM output buffers to empty before proceeding with the rest of the command - if (muteWaitMs > delayMs) { - muteWaitMs -= delayMs; - usleep(muteWaitMs * 1000); - return muteWaitMs; - } - return 0; -} - -void AudioPolicyManager::setStreamMute(int stream, - bool on, - audio_io_handle_t output, - int delayMs, - audio_devices_t device) -{ - StreamDescriptor &streamDesc = mStreams[stream]; - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); - if (device == AUDIO_DEVICE_NONE) { - device = outputDesc->device(); - } - - ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x", - stream, on, output, outputDesc->mMuteCount[stream], device); - - if (on) { - if (outputDesc->mMuteCount[stream] > 0) { - ALOGV("setStreamMute() muting already muted stream!"); - return; - } - if (outputDesc->mMuteCount[stream] == 0) { - if (streamDesc.mCanBeMuted && - ((stream != AudioSystem::ENFORCED_AUDIBLE) || - (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) { - checkAndSetVolume(stream, 0, output, device, delayMs); - } - } - // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored - outputDesc->mMuteCount[stream]++; - } else { - if (outputDesc->mMuteCount[stream] == 0) { - ALOGV("setStreamMute() unmuting non muted stream!"); - return; - } - if (--outputDesc->mMuteCount[stream] == 0) { - checkAndSetVolume(stream, - streamDesc.getVolumeIndex(device), - output, - device, - delayMs); - } - } -} - - -status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, - AudioSystem::device_connection_state state, - const char *device_address) -{ - SortedVector outputs; - - ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); - - // connect/disconnect only 1 device at a time - if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; - - if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { - ALOGE("setDeviceConnectionState() invalid address: %s", device_address); - return BAD_VALUE; - } - - // handle output devices - if (audio_is_output_device(device)) { - - //Use QCOM's a2dp and usb audio solution, no need to check here - /*if (!mHasA2dp && audio_is_a2dp_device(device)) { - ALOGE("setDeviceConnectionState() invalid A2DP device: %x", device); - return BAD_VALUE; - } - if (!mHasUsb && audio_is_usb_device(device)) { - ALOGE("setDeviceConnectionState() invalid USB audio device: %x", device); - return BAD_VALUE; - }*/ - if (!mHasRemoteSubmix && audio_is_remote_submix_device((audio_devices_t)device)) { - ALOGE("setDeviceConnectionState() invalid remote submix audio device: %x", device); - return BAD_VALUE; - } - - // save a copy of the opened output descriptors before any output is opened or closed - // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() - mPreviousOutputs = mOutputs; - switch (state) - { - // handle output device connection - case AudioSystem::DEVICE_STATE_AVAILABLE: - if (mAvailableOutputDevices & device) { - ALOGW("setDeviceConnectionState() device already connected: %x", device); - return INVALID_OPERATION; - } - ALOGV("setDeviceConnectionState() connecting device %x", device); - - if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) { - return INVALID_OPERATION; - } - ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %d outputs", - outputs.size()); - // register new device as available - mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device); - - if (audio_is_a2dp_device(device)) { - AudioParameter param; - param.add(String8("a2dp_connected"), String8("true")); - mpClientInterface->setParameters(0, param.toString()); - } - if ( audio_is_usb_device(device)) { - AudioParameter param; - param.add(String8("usb_connected"), String8("true")); - mpClientInterface->setParameters(0, param.toString()); - } - if (!outputs.isEmpty()) { - String8 paramStr; - if (audio_is_a2dp_device(device)) { - // handle A2DP device connection - AudioParameter param; - param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address)); - paramStr = param.toString(); - mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); - mA2dpSuspended = false; - } else if (audio_is_bluetooth_sco_device(device)) { - // handle SCO device connection - mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); - } else if (audio_is_usb_device(device)) { - // handle USB device connection - mUsbCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN); - paramStr = mUsbCardAndDevice; - } - // not currently handling multiple simultaneous submixes: ignoring remote submix - // case and address - if (!paramStr.isEmpty()) { - for (size_t i = 0; i < outputs.size(); i++) { - mpClientInterface->setParameters(outputs[i], paramStr); - } - } - } - break; - // handle output device disconnection - case AudioSystem::DEVICE_STATE_UNAVAILABLE: { - if (!(mAvailableOutputDevices & device)) { - ALOGW("setDeviceConnectionState() device not connected: %x", device); - return INVALID_OPERATION; - } - - ALOGV("setDeviceConnectionState() disconnecting device %x", device); - // remove device from available output devices - mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); - - checkOutputsForDevice(device, state, outputs); - if (audio_is_a2dp_device(device)) { - // handle A2DP device disconnection - mA2dpDeviceAddress = ""; - mA2dpSuspended = false; - - AudioParameter param; - param.add(String8("a2dp_connected"), String8("false")); - mpClientInterface->setParameters(0, param.toString()); - - } else if (audio_is_bluetooth_sco_device(device)) { - // handle SCO device disconnection - mScoDeviceAddress = ""; - } else if (audio_is_usb_device(device)) { - // handle USB device disconnection - mUsbCardAndDevice = ""; - - AudioParameter param; - param.add(String8("usb_connected"), String8("false")); - mpClientInterface->setParameters(0, param.toString()); - } - // not currently handling multiple simultaneous submixes: ignoring remote submix - // case and address - } break; - - default: - ALOGE("setDeviceConnectionState() invalid state: %x", state); - return BAD_VALUE; - } - - checkA2dpSuspend(); - checkOutputForAllStrategies(); - // outputs must be closed after checkOutputForAllStrategies() is executed - if (!outputs.isEmpty()) { - for (size_t i = 0; i < outputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); - // close unused outputs after device disconnection or direct outputs that have been - // opened by checkOutputsForDevice() to query dynamic parameters - if ((state == AudioSystem::DEVICE_STATE_UNAVAILABLE) || - (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && - (desc->mDirectOpenCount == 0))) { - closeOutput(outputs[i]); - } - } - } - - updateDevicesAndOutputs(); -#ifdef QCOM_PROXY_DEVICE_ENABLED - if (state == AudioSystem::DEVICE_STATE_AVAILABLE && - audio_is_a2dp_device(device) && - (mAvailableOutputDevices & AUDIO_DEVICE_OUT_PROXY)) { - ALOGV("Delay the proxy device open"); - return NO_ERROR; - } -#endif - - audio_devices_t newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); -#ifdef QCOM_FM_ENABLED - if(device == AUDIO_DEVICE_OUT_FM) { - if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { - ALOGV("setDeviceConnectionState() changeRefCount Inc"); - mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AudioSystem::FM, 1); - newDevice = (audio_devices_t)(AudioPolicyManagerBase::getNewDevice(mPrimaryOutput, false) | AUDIO_DEVICE_OUT_FM); - } - else { - ALOGV("setDeviceConnectionState() changeRefCount Dec"); - mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AudioSystem::FM, -1); - } - - AudioParameter param = AudioParameter(); - param.addInt(String8(AudioParameter::keyHandleFm), (int)newDevice); - ALOGV("setDeviceConnectionState() setParameters handle_fm"); - mpClientInterface->setParameters(mPrimaryOutput, param.toString()); - } -#endif - for (int i = mOutputs.size() -1; i >= 0; i--) { - audio_devices_t newDevice = getNewDevice(mOutputs.keyAt(i), true /*fromCache*/); -#ifdef QCOM_ANC_HEADSET_ENABLED - if(device == AUDIO_DEVICE_OUT_ANC_HEADPHONE || - device == AUDIO_DEVICE_OUT_ANC_HEADSET) { - if(newDevice == 0){ - newDevice = getDeviceForStrategy(STRATEGY_MEDIA, false); - } - } -#endif - setOutputDevice(mOutputs.keyAt(i), - getNewDevice(mOutputs.keyAt(i), true /*fromCache*/), - true, - 0); - } - - if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) { - device = AUDIO_DEVICE_IN_WIRED_HEADSET; - } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO || - device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET || - device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { - device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; - } else if(device == AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET){ - device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET; -#ifdef QCOM_ANC_HEADSET_ENABLED - } else if(device == AUDIO_DEVICE_OUT_ANC_HEADSET){ - device = AUDIO_DEVICE_IN_ANC_HEADSET; //wait for actual ANC device -#endif - } else { - return NO_ERROR; - } - } - // handle input devices - if (audio_is_input_device(device)) { - - switch (state) - { - // handle input device connection - case AudioSystem::DEVICE_STATE_AVAILABLE: { - if (mAvailableInputDevices & device) { - ALOGW("setDeviceConnectionState() device already connected: %d", device); - return INVALID_OPERATION; - } - mAvailableInputDevices = mAvailableInputDevices | (device & ~AUDIO_DEVICE_BIT_IN); - } - break; - - // handle input device disconnection - case AudioSystem::DEVICE_STATE_UNAVAILABLE: { - if (!(mAvailableInputDevices & device)) { - ALOGW("setDeviceConnectionState() device not connected: %d", device); - return INVALID_OPERATION; - } - mAvailableInputDevices = (audio_devices_t) (mAvailableInputDevices & ~device); - } break; - - default: - ALOGE("setDeviceConnectionState() invalid state: %x", state); - return BAD_VALUE; - } - - audio_io_handle_t activeInput = getActiveInput(); - if (activeInput != 0) { - AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); - audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); - if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { - ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d", - inputDesc->mDevice, newDevice, activeInput); - inputDesc->mDevice = newDevice; - AudioParameter param = AudioParameter(); - param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); - mpClientInterface->setParameters(activeInput, param.toString()); - } - } - - return NO_ERROR; - } - - ALOGW("setDeviceConnectionState() invalid device: %x", device); - return BAD_VALUE; -} - -AudioSystem::device_connection_state AudioPolicyManager::getDeviceConnectionState(audio_devices_t device, - const char *device_address) -{ - AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; - String8 address = String8(device_address); - if (audio_is_output_device(device)) { - if (device & mAvailableOutputDevices) { - if (audio_is_a2dp_device(device) && - ((address != "" && mA2dpDeviceAddress != address))) { - return state; - } - if (audio_is_bluetooth_sco_device(device) && - address != "" && mScoDeviceAddress != address) { - return state; - } - if (audio_is_usb_device(device) && - ((address != "" && mUsbCardAndDevice != address))) { - ALOGE("getDeviceConnectionState() invalid device: %x", device); - return state; - } - if (audio_is_remote_submix_device((audio_devices_t)device) && !mHasRemoteSubmix) { - return state; - } - state = AudioSystem::DEVICE_STATE_AVAILABLE; - } - } else if (audio_is_input_device(device)) { - if (device & mAvailableInputDevices) { - state = AudioSystem::DEVICE_STATE_AVAILABLE; - } - } - - return state; -} - -void AudioPolicyManager::setPhoneState(int state) -{ - ALOGV("setPhoneState() state %d", state); - audio_devices_t newDevice = AUDIO_DEVICE_NONE; - if (state < 0 || state >= AudioSystem::NUM_MODES) { - ALOGW("setPhoneState() invalid state %d", state); - return; - } - - if (state == mPhoneState ) { - ALOGW("setPhoneState() setting same state %d", state); - return; - } - - // if leaving call state, handle special case of active streams - // pertaining to sonification strategy see handleIncallSonification() - if (isInCall()) { - ALOGV("setPhoneState() in call state management: new state is %d", state); - for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { - handleIncallSonification(stream, false, true); - } - } - - // store previous phone state for management of sonification strategy below - int oldState = mPhoneState; - mPhoneState = state; - bool force = false; - - // are we entering or starting a call - if (!isStateInCall(oldState) && isStateInCall(state)) { - ALOGV(" Entering call in setPhoneState()"); - // force routing command to audio hardware when starting a call - // even if no device change is needed - force = true; - } else if (isStateInCall(oldState) && !isStateInCall(state)) { - ALOGV(" Exiting call in setPhoneState()"); - // force routing command to audio hardware when exiting a call - // even if no device change is needed - force = true; - } else if (isStateInCall(state) && (state != oldState)) { - ALOGV(" Switching between telephony and VoIP in setPhoneState()"); - // force routing command to audio hardware when switching between telephony and VoIP - // even if no device change is needed - force = true; - } - - // check for device and output changes triggered by new phone state - // Need to update A2DP suspend first then getNewDevice(from cache) - checkA2dpSuspend(); - checkOutputForAllStrategies(); - updateDevicesAndOutputs(); - newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); - - AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); - - // force routing command to audio hardware when ending call - // even if no device change is needed - if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) { - newDevice = hwOutputDesc->device(); - } - - int delayMs = 0; - if (state == AUDIO_MODE_IN_CALL && -#ifdef QCOM_CSDCLIENT_ENABLED - platform_is_Fusion3() && -#endif - oldState == AUDIO_MODE_RINGTONE) { - delayMs = 40; - } - - if (isStateInCall(state)) { - nsecs_t sysTime = systemTime(); - for (size_t i = 0; i < mOutputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueAt(i); - // mute media and sonification strategies and delay device switch by the largest - // latency of any output where either strategy is active. - // This avoid sending the ring tone or music tail into the earpiece or headset. - if ((desc->isStrategyActive(STRATEGY_MEDIA, - SONIFICATION_HEADSET_MUSIC_DELAY, - sysTime) || - desc->isStrategyActive(STRATEGY_SONIFICATION, - SONIFICATION_HEADSET_MUSIC_DELAY, - sysTime)) && - (delayMs < (int)desc->mLatency*2)) { - delayMs = desc->mLatency*2; - } - setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); - setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, - getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); - setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); - setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, - getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); - } - } - - // change routing is necessary - setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); - - //update device for all non-primary outputs - for (size_t i = 0; i < mOutputs.size(); i++) { - audio_io_handle_t output = mOutputs.keyAt(i); - if (output != mPrimaryOutput) { - newDevice = getNewDevice(output, false /*fromCache*/); - setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); - } - } - - // if entering in call state, handle special case of active streams - // pertaining to sonification strategy see handleIncallSonification() - if (isStateInCall(state)) { - ALOGV("setPhoneState() in call state management: new state is %d", state); - for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { - handleIncallSonification(stream, true, true); - } - } - - // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE - if (state == AudioSystem::MODE_RINGTONE && - isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { - mLimitRingtoneVolume = true; - } else { - mLimitRingtoneVolume = false; - } -} - -void AudioPolicyManager::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) -{ - ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); - - bool forceVolumeReeval = false; - switch(usage) { - case AudioSystem::FOR_COMMUNICATION: - if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO && - config != AudioSystem::FORCE_NONE) { - ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); - return; - } - forceVolumeReeval = true; - mForceUse[usage] = config; - break; - case AudioSystem::FOR_MEDIA: - if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && - config != AudioSystem::FORCE_WIRED_ACCESSORY && - config != AudioSystem::FORCE_ANALOG_DOCK && - config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE && - config != AudioSystem::FORCE_NO_BT_A2DP && config != AudioSystem::FORCE_SPEAKER) { - ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); - return; - } - mForceUse[usage] = config; - break; - case AudioSystem::FOR_RECORD: - if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY && - config != AudioSystem::FORCE_NONE) { - ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); - return; - } - mForceUse[usage] = config; - break; - case AudioSystem::FOR_DOCK: - if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && - config != AudioSystem::FORCE_BT_DESK_DOCK && - config != AudioSystem::FORCE_WIRED_ACCESSORY && - config != AudioSystem::FORCE_ANALOG_DOCK && - config != AudioSystem::FORCE_DIGITAL_DOCK) { - ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); - } - forceVolumeReeval = true; - mForceUse[usage] = config; - break; - case AudioSystem::FOR_SYSTEM: - if (config != AudioSystem::FORCE_NONE && - config != AudioSystem::FORCE_SYSTEM_ENFORCED) { - ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); - } - forceVolumeReeval = true; - mForceUse[usage] = config; - break; - default: - ALOGW("setForceUse() invalid usage %d", usage); - break; - } - - // check for device and output changes triggered by new force usage - checkA2dpSuspend(); - checkOutputForAllStrategies(); - updateDevicesAndOutputs(); - for (int i = mOutputs.size() -1; i >= 0; i--) { - audio_io_handle_t output = mOutputs.keyAt(i); - audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/); - setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); - if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { - applyStreamVolumes(output, newDevice, 0, true); - } - } - - audio_io_handle_t activeInput = getActiveInput(); - if (activeInput != 0) { - AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); - audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); - if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { - ALOGV("setForceUse() changing device from %x to %x for input %d", - inputDesc->mDevice, newDevice, activeInput); - inputDesc->mDevice = newDevice; - AudioParameter param = AudioParameter(); - param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); - mpClientInterface->setParameters(activeInput, param.toString()); - } - } - -} - -audio_io_handle_t AudioPolicyManager::getOutput(AudioSystem::stream_type stream, - uint32_t samplingRate, - uint32_t format, - uint32_t channelMask, - AudioSystem::output_flags flags, - const audio_offload_info_t *offloadInfo) -{ - audio_io_handle_t output = 0; - uint32_t latency = 0; - routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); - audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); - ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x", - device, stream, samplingRate, format, channelMask, flags); - -#ifdef AUDIO_POLICY_TEST - if (mCurOutput != 0) { - ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", - mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); - - if (mTestOutputs[mCurOutput] == 0) { - ALOGV("getOutput() opening test output"); - AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); - outputDesc->mDevice = mTestDevice; - outputDesc->mSamplingRate = mTestSamplingRate; - outputDesc->mFormat = mTestFormat; - outputDesc->mChannelMask = mTestChannels; - outputDesc->mLatency = mTestLatencyMs; - outputDesc->mFlags = (audio_output_flags_t)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0); - outputDesc->mRefCount[stream] = 0; - mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, - &outputDesc->mSamplingRate, - &outputDesc->mFormat, - &outputDesc->mChannelMask, - &outputDesc->mLatency, - outputDesc->mFlags, - offloadInfo); - if (mTestOutputs[mCurOutput]) { - AudioParameter outputCmd = AudioParameter(); - outputCmd.addInt(String8("set_id"),mCurOutput); - mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); - addOutput(mTestOutputs[mCurOutput], outputDesc); - } - } - return mTestOutputs[mCurOutput]; - } -#endif //AUDIO_POLICY_TEST - - // open a direct output if required by specified parameters - //force direct flag if offload flag is set: offloading implies a direct output stream - // and all common behaviors are driven by checking only the direct flag - // this should normally be set appropriately in the policy configuration file - if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { - flags = (AudioSystem::output_flags)(flags | AUDIO_OUTPUT_FLAG_DIRECT); - } - - IOProfile *profile = getProfileForDirectOutput(device, - samplingRate, - format, - channelMask, - (audio_output_flags_t)flags); - - if (profile != NULL) { - AudioOutputDescriptor *outputDesc = NULL; - - for (size_t i = 0; i < mOutputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueAt(i); - if (!desc->isDuplicated() && (profile == desc->mProfile)) { - outputDesc = desc; - // reuse direct output if currently open and configured with same parameters - if ((samplingRate == outputDesc->mSamplingRate) && - (format == outputDesc->mFormat) && - (channelMask == outputDesc->mChannelMask)) { - outputDesc->mDirectOpenCount++; - ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); - return mOutputs.keyAt(i); - } - } - } - - // close direct output if currently open and configured with different parameters - if (outputDesc != NULL) { - closeOutput(outputDesc->mId); - } - outputDesc = new AudioOutputDescriptor(profile); - outputDesc->mDevice = device; - outputDesc->mSamplingRate = samplingRate; - outputDesc->mFormat = (audio_format_t)format; - outputDesc->mChannelMask = (audio_channel_mask_t)channelMask; - outputDesc->mLatency = 0; - outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); - outputDesc->mRefCount[stream] = 0; - outputDesc->mStopTime[stream] = 0; - outputDesc->mDirectOpenCount = 1; - output = mpClientInterface->openOutput(profile->mModule->mHandle, - &outputDesc->mDevice, - &outputDesc->mSamplingRate, - &outputDesc->mFormat, - &outputDesc->mChannelMask, - &outputDesc->mLatency, - outputDesc->mFlags, - offloadInfo); - - // only accept an output with the requested parameters - if (output == 0 || - (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || - (format != 0 && format != outputDesc->mFormat) || - (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { - ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," - "format %d %d, channelMask %04x %04x", output, samplingRate, - outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, - outputDesc->mChannelMask); - if (output != 0) { - mpClientInterface->closeOutput(output); - } - delete outputDesc; - return 0; - } - addOutput(output, outputDesc); - mPreviousOutputs = mOutputs; - ALOGV("getOutput() returns new direct output %d", output); - return output; - } - - // ignoring channel mask due to downmix capability in mixer - - // open a non direct output - - // for non direct outputs, only PCM is supported - if (audio_is_linear_pcm((audio_format_t)format)) { - // get which output is suitable for the specified stream. The actual - // routing change will happen when startOutput() will be called - SortedVector outputs = getOutputsForDevice(device, mOutputs); - - output = selectOutput(outputs, flags); - } - ALOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d," - "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); - - ALOGV("getOutput() returns output %d", output); - - return output; -} -status_t AudioPolicyManager::startOutput(audio_io_handle_t output, - AudioSystem::stream_type stream, - int session) -{ - ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); - ssize_t index = mOutputs.indexOfKey(output); - if (index < 0) { - ALOGW("startOutput() unknow output %d", output); - return BAD_VALUE; - } - - AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); - - // increment usage count for this stream on the requested output: - // NOTE that the usage count is the same for duplicated output and hardware output which is - // necessary for a correct control of hardware output routing by startOutput() and stopOutput() - outputDesc->changeRefCount(stream, 1); - - if (outputDesc->mRefCount[stream] == 1) { - audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); - routing_strategy strategy = getStrategy(stream); - bool shouldWait = (strategy == STRATEGY_SONIFICATION) || - (strategy == STRATEGY_SONIFICATION_RESPECTFUL); - uint32_t waitMs = 0; - uint32_t muteWaitMs = 0; - bool force = false; - for (size_t i = 0; i < mOutputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueAt(i); - if (desc != outputDesc) { - // force a device change if any other output is managed by the same hw - // module and has a current device selection that differs from selected device. - // In this case, the audio HAL must receive the new device selection so that it can - // change the device currently selected by the other active output. - if (outputDesc->sharesHwModuleWith(desc) && - desc->device() != newDevice) { - force = true; - } - // wait for audio on other active outputs to be presented when starting - // a notification so that audio focus effect can propagate. - uint32_t latency = desc->latency(); - if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { - waitMs = latency; - } - } - } - -#ifdef QCOM_FM_ENABLED - if(stream == AudioSystem::FM && output == getA2dpOutput()) { - muteWaitMs = setOutputDevice(output, newDevice, true); - } else -#endif - { - muteWaitMs = setOutputDevice(output, newDevice, force); - } - - // handle special case for sonification while in call - if (isInCall()) { - handleIncallSonification(stream, true, false); - } - - // apply volume rules for current stream and device if necessary - checkAndSetVolume(stream, - mStreams[stream].getVolumeIndex(newDevice), - output, - newDevice); - - // update the outputs if starting an output with a stream that can affect notification - // routing - handleNotificationRoutingForStream(stream); - if (waitMs > muteWaitMs) { - usleep((waitMs - muteWaitMs) * 2 * 1000); - } - } else { - // handle special case for sonification while in call - if (isInCall()) { - handleIncallSonification(stream, true, false); - } - } - return NO_ERROR; -} - -status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, - AudioSystem::stream_type stream, - int session) -{ - ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); - ssize_t index = mOutputs.indexOfKey(output); - if (index < 0) { - ALOGW("stopOutput() unknow output %d", output); - return BAD_VALUE; - } - - AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); - - // handle special case for sonification while in call - if (isInCall()) { - handleIncallSonification(stream, false, false); - } - - if (outputDesc->mRefCount[stream] > 0) { - // decrement usage count of this stream on the output - outputDesc->changeRefCount(stream, -1); - // store time at which the stream was stopped - see isStreamActive() - if (outputDesc->mRefCount[stream] == 0) { - outputDesc->mStopTime[stream] = systemTime(); - - if ((outputDesc->mRefCount[AUDIO_STREAM_RING]!= 0) && (stream == AUDIO_STREAM_VOICE_CALL)) { - // When AUDIO_STREAM_RING is present, Send Mute on RING - // if it gets stopOutput on AUDIO_STREAM_VOICE_CALL - setStreamMute(AudioSystem::RING, true, mPrimaryOutput); - } - - audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); - // delay the device switch by twice the latency because stopOutput() is executed when - // the track stop() command is received and at that time the audio track buffer can - // still contain data that needs to be drained. The latency only covers the audio HAL - // and kernel buffers. Also the latency does not always include additional delay in the - // audio path (audio DSP, CODEC ...) - setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); - - // force restoring the device selection on other active outputs if it differs from the - // one being selected for this output - for (size_t i = 0; i < mOutputs.size(); i++) { - audio_io_handle_t curOutput = mOutputs.keyAt(i); - AudioOutputDescriptor *desc = mOutputs.valueAt(i); - if (curOutput != output && - desc->isActive() && - outputDesc->sharesHwModuleWith(desc) && - (newDevice != desc->device())) { - setOutputDevice(curOutput, - getNewDevice(curOutput, false /*fromCache*/), - true, - outputDesc->mLatency*2); - } - } - // update the outputs if stopping one with a stream that can affect notification routing - handleNotificationRoutingForStream(stream); - } - return NO_ERROR; - } else { - ALOGW("stopOutput() refcount is already 0 for output %d", output); - return INVALID_OPERATION; - } -} - - -audio_io_handle_t AudioPolicyManager::getInput(int inputSource, - uint32_t samplingRate, - uint32_t format, - uint32_t channelMask, - AudioSystem::audio_in_acoustics acoustics) -{ - audio_io_handle_t input = 0; - audio_devices_t device = getDeviceForInputSource(inputSource); - - ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", - inputSource, samplingRate, format, channelMask, acoustics); - - if (device == AUDIO_DEVICE_NONE) { - ALOGW("getInput() could not find device for inputSource %d", inputSource); - return 0; - } - - // adapt channel selection to input source - switch(inputSource) { - case AUDIO_SOURCE_VOICE_UPLINK: - channelMask |= AudioSystem::CHANNEL_IN_VOICE_UPLINK; - break; - case AUDIO_SOURCE_VOICE_DOWNLINK: - channelMask |= AudioSystem::CHANNEL_IN_VOICE_DNLINK; - break; - case AUDIO_SOURCE_VOICE_CALL: - channelMask |= (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK); - break; - default: - break; - } - - IOProfile *profile = getInputProfile(device, - samplingRate, - format, - channelMask); - if (profile == NULL) { - ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d," - "channelMask %04x", - device, samplingRate, format, channelMask); - return 0; - } - - if (profile->mModule->mHandle == 0) { - ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); - return 0; - } - - AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); - - inputDesc->mInputSource = inputSource; - inputDesc->mDevice = device; - inputDesc->mSamplingRate = samplingRate; - inputDesc->mFormat = (audio_format_t)format; - inputDesc->mChannelMask = (audio_channel_mask_t)channelMask; - inputDesc->mRefCount = 0; - input = mpClientInterface->openInput(profile->mModule->mHandle, - &inputDesc->mDevice, - &inputDesc->mSamplingRate, - &inputDesc->mFormat, - &inputDesc->mChannelMask); - - // only accept input with the exact requested set of parameters - if (input == 0 || - (samplingRate != inputDesc->mSamplingRate) || - (format != inputDesc->mFormat) || - (channelMask != inputDesc->mChannelMask)) { - ALOGV("getInput() failed opening input: samplingRate %d, format %d, channelMask %d", - samplingRate, format, channelMask); - if (input != 0) { - mpClientInterface->closeInput(input); - } - delete inputDesc; - return 0; - } - mInputs.add(input, inputDesc); - return input; -} - -/* -Overwriting this function from base class to allow 2 acitve AudioRecord clients in case of FM. -One for FM A2DP playbck and other for FM recording. -*/ -status_t AudioPolicyManager::startInput(audio_io_handle_t input) -{ - ALOGV("startInput() input %d", input); - ssize_t index = mInputs.indexOfKey(input); - if (index < 0) { - ALOGW("startInput() unknow input %d", input); - return BAD_VALUE; - } - AudioInputDescriptor *inputDesc = mInputs.valueAt(index); - -/* -#ifdef AUDIO_POLICY_TEST - if (mTestInput == 0) -#endif //AUDIO_POLICY_TEST - { - // refuse 2 active AudioRecord clients at the same time except if the active input - // uses AUDIO_SOURCE_HOTWORD in which case it is closed. - audio_io_handle_t activeInput = getActiveInput(); - if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) { - AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput); - if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { - ALOGW("startInput() preempting already started low-priority input %d", activeInput); - stopInput(activeInput); - releaseInput(activeInput); - } else { - ALOGW("startInput() input %d failed: other input already started..", input); - return INVALID_OPERATION; - } - } - } -*/ - audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); - if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { - inputDesc->mDevice = newDevice; - } - // automatically enable the remote submix output when input is started - if (audio_is_remote_submix_device(inputDesc->mDevice)) { - setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, - AudioSystem::DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); - } - AudioParameter param = AudioParameter(); - param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); - - int aliasSource = (inputDesc->mInputSource == AUDIO_SOURCE_HOTWORD) ? - AUDIO_SOURCE_VOICE_RECOGNITION : inputDesc->mInputSource; - - param.addInt(String8(AudioParameter::keyInputSource), aliasSource); - ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource); - - //to pass on if camcorder mode is enabled to HAL - int camcorder_enabled = inputDesc->mInputSource == AUDIO_SOURCE_CAMCORDER ? 1 : 0; - param.addInt(String8("camcorder_mode"), camcorder_enabled); - - mpClientInterface->setParameters(input, param.toString()); - - inputDesc->mRefCount = 1; - return NO_ERROR; -} - -status_t AudioPolicyManager::stopInput(audio_io_handle_t input) -{ - ALOGV("stopInput() input %d", input); - ssize_t index = mInputs.indexOfKey(input); - if (index < 0) { - ALOGW("stopInput() unknow input %d", input); - return BAD_VALUE; - } - AudioInputDescriptor *inputDesc = mInputs.valueAt(index); - - if (inputDesc->mRefCount == 0) { - ALOGW("stopInput() input %d already stopped", input); - return INVALID_OPERATION; - } else { - // automatically disable the remote submix output when input is stopped - if (audio_is_remote_submix_device(inputDesc->mDevice)) { - setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, - AudioSystem::DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); - } - - AudioParameter param = AudioParameter(); - param.addInt(String8(AudioParameter::keyRouting), 0); - mpClientInterface->setParameters(input, param.toString()); - setOutputDevice(mPrimaryOutput, getNewDevice(mPrimaryOutput, true), true); - inputDesc->mRefCount = 0; - return NO_ERROR; - } -} - - -status_t AudioPolicyManager::setStreamVolumeIndex(AudioSystem::stream_type stream, - int index, - audio_devices_t device) -{ - - if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { - return BAD_VALUE; - } - if (!audio_is_output_device(device)) { - return BAD_VALUE; - } - - // Force max volume if stream cannot be muted - if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; - - ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d", - stream, device, index); - - // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and - // clear all device specific values - if ((device == AUDIO_DEVICE_OUT_DEFAULT) && (AUDIO_DEVICE_OUT_DEFAULT != AUDIO_DEVICE_OUT_SPEAKER)) { - mStreams[stream].mIndexCur.clear(); - } - mStreams[stream].mIndexCur.add(device, index); - - // compute and apply stream volume on all outputs according to connected device - status_t status = NO_ERROR; - for (size_t i = 0; i < mOutputs.size(); i++) { - audio_devices_t curDevice = - getDeviceForVolume(mOutputs.valueAt(i)->device()); - if (device == curDevice) { - status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); - if (volStatus != NO_ERROR) { - status = volStatus; - } - } - } - return status; -} - - -status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, - AudioSystem::device_connection_state state, - SortedVector& outputs) -{ - AudioOutputDescriptor *desc; - - if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { - // first list already open outputs that can be routed to this device - for (size_t i = 0; i < mOutputs.size(); i++) { - desc = mOutputs.valueAt(i); - if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices & device)) { - ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); - outputs.add(mOutputs.keyAt(i)); - } - } - // then look for output profiles that can be routed to this device - SortedVector profiles; - for (size_t i = 0; i < mHwModules.size(); i++) - { - if (mHwModules[i]->mHandle == 0) { - continue; - } - for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) - { - if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices & device) { - ALOGV("checkOutputsForDevice(): adding profile %d from module %d", j, i); - profiles.add(mHwModules[i]->mOutputProfiles[j]); - } - } - } - - if (profiles.isEmpty() && outputs.isEmpty()) { - ALOGW("checkOutputsForDevice(): No output available for device %04x", device); - return BAD_VALUE; - } - - // open outputs for matching profiles if needed. Direct outputs are also opened to - // query for dynamic parameters and will be closed later by setDeviceConnectionState() - for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) { - IOProfile *profile = profiles[profile_index]; - - // nothing to do if one output is already opened for this profile - size_t j; - for (j = 0; j < mOutputs.size(); j++) { - desc = mOutputs.valueAt(j); - if (!desc->isDuplicated() && desc->mProfile == profile) { - break; - } - } - if (j != mOutputs.size()) { - continue; - } - - ALOGV("opening output for device %08x", device); - desc = new AudioOutputDescriptor(profile); - desc->mDevice = device; - audio_io_handle_t output = 0; - if (!(desc->mFlags & AUDIO_OUTPUT_FLAG_LPA || desc->mFlags & AUDIO_OUTPUT_FLAG_TUNNEL || - desc->mFlags & AUDIO_OUTPUT_FLAG_VOIP_RX)) { - output = mpClientInterface->openOutput(profile->mModule->mHandle, - &desc->mDevice, - &desc->mSamplingRate, - &desc->mFormat, - &desc->mChannelMask, - &desc->mLatency, - desc->mFlags); - } - if (output != 0) { - if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { - String8 reply; - char *value; - if (profile->mSamplingRates[0] == 0) { - reply = mpClientInterface->getParameters(output, - String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); - ALOGV("checkOutputsForDevice() direct output sup sampling rates %s", - reply.string()); - value = strpbrk((char *)reply.string(), "="); - if (value != NULL) { - loadSamplingRates(value, profile); - } - } - if (profile->mFormats[0] == 0) { - reply = mpClientInterface->getParameters(output, - String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); - ALOGV("checkOutputsForDevice() direct output sup formats %s", - reply.string()); - value = strpbrk((char *)reply.string(), "="); - if (value != NULL) { - loadFormats(value, profile); - } - } - if (profile->mChannelMasks[0] == 0) { - reply = mpClientInterface->getParameters(output, - String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); - ALOGV("checkOutputsForDevice() direct output sup channel masks %s", - reply.string()); - value = strpbrk((char *)reply.string(), "="); - if (value != NULL) { - loadOutChannels(value + 1, profile); - } - } - if (((profile->mSamplingRates[0] == 0) && - (profile->mSamplingRates.size() < 2)) || - ((profile->mFormats[0] == 0) && - (profile->mFormats.size() < 2)) || - ((profile->mFormats[0] == 0) && - (profile->mChannelMasks.size() < 2))) { - ALOGW("checkOutputsForDevice() direct output missing param"); - mpClientInterface->closeOutput(output); - output = 0; - } else { - addOutput(output, desc); - } - } else { - audio_io_handle_t duplicatedOutput = 0; - // add output descriptor - addOutput(output, desc); - // set initial stream volume for device - applyStreamVolumes(output, device, 0, true); - - //TODO: configure audio effect output stage here - - // open a duplicating output thread for the new output and the primary output - duplicatedOutput = mpClientInterface->openDuplicateOutput(output, - mPrimaryOutput); - if (duplicatedOutput != 0) { - // add duplicated output descriptor - AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); - dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); - dupOutputDesc->mOutput2 = mOutputs.valueFor(output); - dupOutputDesc->mSamplingRate = desc->mSamplingRate; - dupOutputDesc->mFormat = desc->mFormat; - dupOutputDesc->mChannelMask = desc->mChannelMask; - dupOutputDesc->mLatency = desc->mLatency; - addOutput(duplicatedOutput, dupOutputDesc); - applyStreamVolumes(duplicatedOutput, device, 0, true); - } else { - ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", - mPrimaryOutput, output); - mpClientInterface->closeOutput(output); - mOutputs.removeItem(output); - output = 0; - } - } - } - if (output == 0) { - ALOGW("checkOutputsForDevice() could not open output for device %x", device); - delete desc; - profiles.removeAt(profile_index); - profile_index--; - } else { - outputs.add(output); - ALOGV("checkOutputsForDevice(): adding output %d", output); - } - } - - if (profiles.isEmpty()) { - ALOGW("checkOutputsForDevice(): No output available for device %04x", device); - return BAD_VALUE; - } - } else { - // check if one opened output is not needed any more after disconnecting one device - for (size_t i = 0; i < mOutputs.size(); i++) { - desc = mOutputs.valueAt(i); - if (!desc->isDuplicated() && - !(desc->mProfile->mSupportedDevices & mAvailableOutputDevices)) { - ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i)); - outputs.add(mOutputs.keyAt(i)); - } - } - for (size_t i = 0; i < mHwModules.size(); i++) - { - if (mHwModules[i]->mHandle == 0) { - continue; - } - for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) - { - IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; - if ((profile->mSupportedDevices & device) && - (profile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) { - ALOGV("checkOutputsForDevice(): clearing direct output profile %d on module %d", - j, i); - if (profile->mSamplingRates[0] == 0) { - profile->mSamplingRates.clear(); - profile->mSamplingRates.add(0); - } - if (profile->mFormats[0] == 0) { - profile->mFormats.clear(); - profile->mFormats.add((audio_format_t)0); - } - if (profile->mChannelMasks[0] == 0) { - profile->mChannelMasks.clear(); - profile->mChannelMasks.add((audio_channel_mask_t)0); - } - } - } - } - } - return NO_ERROR; -} - -audio_devices_t AudioPolicyManager::getNewDevice(audio_io_handle_t output, bool fromCache) -{ - audio_devices_t device = AUDIO_DEVICE_NONE; - - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); - AudioOutputDescriptor *primaryOutputDesc = mOutputs.valueFor(mPrimaryOutput); - // check the following by order of priority to request a routing change if necessary: - // 1: the strategy enforced audible is active on the output: - // use device for strategy enforced audible - // 2: we are in call or the strategy phone is active on the output: - // use device for strategy phone - // 3: the strategy sonification is active on the output: - // use device for strategy sonification - // 4: the strategy "respectful" sonification is active on the output: - // use device for strategy "respectful" sonification - // 5: the strategy media is active on the output: - // use device for strategy media - // 6: the strategy DTMF is active on the output: - // use device for strategy DTMF - if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { - device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); - } else if (isInCall() || - outputDesc->isStrategyActive(STRATEGY_PHONE)) { - device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); - } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { - device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); - } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { - device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); - } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { - device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); - } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { - device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); - } - - ALOGV("getNewDevice() selected device %x", device); - return device; -} - -AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy( - AudioSystem::stream_type stream) { - // stream to strategy mapping - switch (stream) { - case AudioSystem::VOICE_CALL: - case AudioSystem::BLUETOOTH_SCO: - return STRATEGY_PHONE; - case AudioSystem::RING: - case AudioSystem::ALARM: - return STRATEGY_SONIFICATION; - case AudioSystem::NOTIFICATION: - return STRATEGY_SONIFICATION_RESPECTFUL; - case AudioSystem::DTMF: - return STRATEGY_DTMF; - default: - ALOGE("unknown stream type"); - case AudioSystem::SYSTEM: - // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs - // while key clicks are played produces a poor result - case AudioSystem::TTS: - case AudioSystem::MUSIC: -#ifdef QCOM_FM_ENABLED - case AudioSystem::FM: -#endif - return STRATEGY_MEDIA; - case AudioSystem::ENFORCED_AUDIBLE: - return STRATEGY_ENFORCED_AUDIBLE; - } -} -audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, - bool fromCache) -{ - uint32_t device = AUDIO_DEVICE_NONE; - - if (fromCache) { - ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", - strategy, mDeviceForStrategy[strategy]); - return mDeviceForStrategy[strategy]; - } - - switch (strategy) { - - case STRATEGY_SONIFICATION_RESPECTFUL: - if (isInCall()) { - device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); - } else if (isStreamActiveRemotely(AudioSystem::MUSIC, - SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { - // while media is playing on a remote device, use the the sonification behavior. - // Note that we test this usecase before testing if media is playing because - // the isStreamActive() method only informs about the activity of a stream, not - // if it's for local playback. Note also that we use the same delay between both tests - device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); - } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { - // while media is playing (or has recently played), use the same device - device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); - } else { - // when media is not playing anymore, fall back on the sonification behavior - device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); - } - - break; - - case STRATEGY_DTMF: - if (!isInCall()) { - // when off call, DTMF strategy follows the same rules as MEDIA strategy - device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); - break; - } - // when in call, DTMF and PHONE strategies follow the same rules - // FALL THROUGH - - case STRATEGY_PHONE: - // for phone strategy, we first consider the forced use and then the available devices by order - // of priority - switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { - case AudioSystem::FORCE_BT_SCO: - if (!isInCall() || strategy != STRATEGY_DTMF) { - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; - if (device) break; - } - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; - if (device) break; - // if SCO device is requested but no SCO device is available, fall back to default case - // FALL THROUGH - - default: // FORCE_NONE - // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP - if (!isInCall()) - { - if ((mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && - !mA2dpSuspended) { - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; - if (device) break; - } - } - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; - if (device) break; -#ifdef QCOM_ANC_HEADSET_ENABLED - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANC_HEADPHONE; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANC_HEADSET; - if (device) break; -#endif - if (mPhoneState != AudioSystem::MODE_IN_CALL) { - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; - if (device) break; - } - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_EARPIECE; - if (device) break; - device = mDefaultOutputDevice; - if (device == AUDIO_DEVICE_NONE) { - ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); - } - break; - - case AudioSystem::FORCE_SPEAKER: - // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to - // A2DP speaker when forcing to speaker output - if (!isInCall() && - (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && - !mA2dpSuspended) { - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; - if (device) break; - } - if (mPhoneState != AudioSystem::MODE_IN_CALL) { - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; - if (device) break; - } - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; - if (device) break; - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; - if (device) break; - device = mDefaultOutputDevice; - if (device == AUDIO_DEVICE_NONE) { - ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); - } - break; - } -#ifdef QCOM_FM_ENABLED - if (mAvailableOutputDevices & AUDIO_DEVICE_OUT_FM) { - if (mForceUse[AudioSystem::FOR_MEDIA] == AudioSystem::FORCE_SPEAKER) { - device &= ~(AUDIO_DEVICE_OUT_WIRED_HEADSET); - device &= ~(AUDIO_DEVICE_OUT_WIRED_HEADPHONE); - device &= ~(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET); - device |= AUDIO_DEVICE_OUT_SPEAKER; - } - } -#endif - break; - - case STRATEGY_SONIFICATION: - - // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by - // handleIncallSonification(). - if (isInCall()) { - device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); - break; - } - // FALL THROUGH - - case STRATEGY_ENFORCED_AUDIBLE: - // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION - // except: - // - when in call where it doesn't default to STRATEGY_PHONE behavior - // - in countries where not enforced in which case it follows STRATEGY_MEDIA - - if ((strategy == STRATEGY_SONIFICATION) || - (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)) { - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; - if (device == AUDIO_DEVICE_NONE) { - ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); - } - } - // The second device used for sonification is the same as the device used by media strategy - // FALL THROUGH - - case STRATEGY_MEDIA: { - uint32_t device2 = AUDIO_DEVICE_NONE; - if (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_SPEAKER) { - if (strategy != STRATEGY_SONIFICATION) { - // no sonification on remote submix (e.g. WFD) - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; - } - if ((device2 == AUDIO_DEVICE_NONE) && - (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && - !mA2dpSuspended) { - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; - } - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; - } -#ifdef QCOM_ANC_HEADSET_ENABLED - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANC_HEADPHONE; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANC_HEADSET; - } -#endif - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; - } - if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { - // no sonification on aux digital (e.g. HDMI) - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; - } -#ifdef QCOM_FM_ENABLED - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_FM_TX; - } -#endif -#ifdef QCOM_PROXY_DEVICE_ENABLED - if ((strategy != STRATEGY_SONIFICATION) && (device2 == AUDIO_DEVICE_NONE)) { - // no sonification on WFD sink - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_PROXY; - } -#endif - if (device2 == AUDIO_DEVICE_NONE) { - device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; - } - - // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or - // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise - device |= device2; - if (!device) { - device = mDefaultOutputDevice; - } - if (device == AUDIO_DEVICE_NONE) { - ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); - } - - } else { - //AudioSystem::FORCE_SPEAKER for STRATEGY_MEDIA - device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; - } - - if (isInCall()) { - // when in call, get the device for Phone strategy - device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/); - } - - } break; - - default: - ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); - break; - } - - ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); - return device; -} - -uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, - audio_devices_t device, - bool force, - int delayMs) - -{ - ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); - AudioParameter param; - uint32_t muteWaitMs = 0; - - if (outputDesc->isDuplicated()) { - muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); - muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); - return muteWaitMs; - } - // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current - // output profile - if ((device != AUDIO_DEVICE_NONE) && - ((device & outputDesc->mProfile->mSupportedDevices) == 0)) { - return 0; - } - - // filter devices according to output selected - device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); - - audio_devices_t prevDevice = outputDesc->mDevice; - - ALOGV("setOutputDevice() prevDevice %04x", prevDevice); - - if (device != AUDIO_DEVICE_NONE) { - outputDesc->mDevice = device; - } - muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); - - // Do not change the routing if: - // - the requested device is AUDIO_DEVICE_NONE - // - the requested device is the same as current device and force is not specified. - // Doing this check here allows the caller to call setOutputDevice() without conditions - if ((device == AUDIO_DEVICE_NONE) || ((device == prevDevice) && !force)) { - ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); - return muteWaitMs; - } - if (device == prevDevice) { - ALOGV("setOutputDevice() Call routing with same device with zero delay "); - delayMs = 0; - } - ALOGV("setOutputDevice() changing device:%x",device); - // do the routing - param.addInt(String8(AudioParameter::keyRouting), (int)device); - mpClientInterface->setParameters(output, param.toString(), delayMs); - - // update stream volumes according to new device - applyStreamVolumes(output, device, delayMs); - - - return muteWaitMs; -} - -audio_devices_t AudioPolicyManager::getDeviceForInputSource(int inputSource) -{ - uint32_t device = AUDIO_DEVICE_NONE; - - switch (inputSource) { - case AUDIO_SOURCE_VOICE_UPLINK: - if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { - device = AUDIO_DEVICE_IN_VOICE_CALL; - break; - } - // FALL THROUGH - - case AUDIO_SOURCE_DEFAULT: - case AUDIO_SOURCE_MIC: - case AUDIO_SOURCE_VOICE_RECOGNITION: - case AUDIO_SOURCE_HOTWORD: - if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && - mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { - device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; - } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) { - device = AUDIO_DEVICE_IN_WIRED_HEADSET; -#ifdef QCOM_ANC_HEADSET_ENABLED - } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_ANC_HEADSET) { - device = AUDIO_DEVICE_IN_ANC_HEADSET; -#endif - } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET) { - device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET; - } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { - device = AUDIO_DEVICE_IN_BUILTIN_MIC; - } - break; - case AUDIO_SOURCE_VOICE_COMMUNICATION: - device = AUDIO_DEVICE_IN_COMMUNICATION; - break; - case AUDIO_SOURCE_CAMCORDER: - if (mAvailableInputDevices & AUDIO_DEVICE_IN_BACK_MIC) { - device = AUDIO_DEVICE_IN_BACK_MIC; - } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { - device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; - } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) { - device = AUDIO_DEVICE_IN_WIRED_HEADSET; - } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_AUX_DIGITAL) { - device = AUDIO_DEVICE_IN_AUX_DIGITAL; - } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { - device = AUDIO_DEVICE_IN_BUILTIN_MIC; - } - break; - case AUDIO_SOURCE_VOICE_DOWNLINK: - case AUDIO_SOURCE_VOICE_CALL: - if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { - device = AUDIO_DEVICE_IN_VOICE_CALL; - } - break; - case AUDIO_SOURCE_REMOTE_SUBMIX: - if (mAvailableInputDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { - device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; - } - break; -#ifdef QCOM_FM_ENABLED - case AUDIO_SOURCE_FM_RX: - device = AUDIO_DEVICE_IN_FM_RX; - break; - case AUDIO_SOURCE_FM_RX_A2DP: - device = AUDIO_DEVICE_IN_FM_RX_A2DP; - break; -#endif - default: - ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); - break; - } - ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); - return device; -} - - - - -audio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device) -{ - if (device == AUDIO_DEVICE_NONE) { - // this happens when forcing a route update and no track is active on an output. - // In this case the returned category is not important. - device = AUDIO_DEVICE_OUT_SPEAKER; - } else if (AudioSystem::popCount(device) > 1) { - // Multiple device selection is either: - // - speaker + one other device: give priority to speaker in this case. - // - one A2DP device + another device: happens with duplicated output. In this case - // retain the device on the A2DP output as the other must not correspond to an active - // selection if not the speaker. - if (device & AUDIO_DEVICE_OUT_SPEAKER) { - device = AUDIO_DEVICE_OUT_SPEAKER; - } else if ((device & AUDIO_DEVICE_OUT_WIRED_HEADSET) != 0) { - device = AUDIO_DEVICE_OUT_WIRED_HEADSET; - } else if ((device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) != 0) { - device = AUDIO_DEVICE_OUT_WIRED_HEADPHONE; - } else { - device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); - } - } - - ALOGW_IF(AudioSystem::popCount(device) != 1, - "getDeviceForVolume() invalid device combination: %08x", - device); - - return device; -} - -AudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device) -{ - switch(getDeviceForVolume(device)) { - case AUDIO_DEVICE_OUT_EARPIECE: - return DEVICE_CATEGORY_EARPIECE; - case AUDIO_DEVICE_OUT_WIRED_HEADSET: - case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: -#ifdef QCOM_ANC_HEADSET_ENABLED - case AUDIO_DEVICE_OUT_ANC_HEADSET: - case AUDIO_DEVICE_OUT_ANC_HEADPHONE: -#endif - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: -#ifdef QCOM_FM_ENABLED - case AUDIO_DEVICE_OUT_FM: -#endif - return DEVICE_CATEGORY_HEADSET; - case AUDIO_DEVICE_OUT_SPEAKER: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: - case AUDIO_DEVICE_OUT_AUX_DIGITAL: - case AUDIO_DEVICE_OUT_USB_ACCESSORY: - case AUDIO_DEVICE_OUT_USB_DEVICE: - case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: -#ifdef QCOM_PROXY_DEVICE_ENABLED - case AUDIO_DEVICE_OUT_PROXY: -#endif - default: - return DEVICE_CATEGORY_SPEAKER; - } -} - -bool AudioPolicyManager::isDirectOutput(audio_io_handle_t output) { - for (size_t i = 0; i < mOutputs.size(); i++) { - audio_io_handle_t curOutput = mOutputs.keyAt(i); - AudioOutputDescriptor *desc = mOutputs.valueAt(i); - if ((curOutput == output) && (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) { - return true; - } - } - return false; -} - -status_t AudioPolicyManager::checkAndSetVolume(int stream, - int index, - audio_io_handle_t output, - audio_devices_t device, - int delayMs, - bool force) -{ - // do not change actual stream volume if the stream is muted - if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { - ALOGVV("checkAndSetVolume() stream %d muted count %d", - stream, mOutputs.valueFor(output)->mMuteCount[stream]); - return NO_ERROR; - } - - // do not change in call volume if bluetooth is connected and vice versa - if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || - (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) { - ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", - stream, mForceUse[AudioSystem::FOR_COMMUNICATION]); - return INVALID_OPERATION; - } - - float volume = computeVolume(stream, index, output, device); - // We actually change the volume if: - // - the float value returned by computeVolume() changed - // - the force flag is set - if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || -#ifdef QCOM_FM_ENABLED - (stream == AudioSystem::FM) || -#endif - force) { - mOutputs.valueFor(output)->mCurVolume[stream] = volume; - ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); - // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is - // enabled - if (stream == AudioSystem::BLUETOOTH_SCO) { - mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs); -#ifdef QCOM_FM_ENABLED - } else if (stream == AudioSystem::FM) { - float fmVolume = -1.0; - fmVolume = computeVolume(stream, index, output, device); - if (fmVolume >= 0) { - if(output == mPrimaryOutput) - mpClientInterface->setFmVolume(fmVolume, delayMs); - else if(mHasA2dp && output == getA2dpOutput()) - mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); - } - return NO_ERROR; -#endif - } - mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); - } - - if (stream == AudioSystem::VOICE_CALL || - stream == AudioSystem::BLUETOOTH_SCO) { - float voiceVolume; - // Force voice volume to max for bluetooth SCO as volume is managed by the headset - if (stream == AudioSystem::VOICE_CALL) { - voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; - } else { - voiceVolume = 1.0; - } - - voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; - - // Force voice volume to max when Vgs is set for bluetooth SCO as volume is managed by the headset - if (stream == AudioSystem::BLUETOOTH_SCO) { - String8 key ("bt_headset_vgs"); - mpClientInterface->getParameters(output,key); - AudioParameter result(mpClientInterface->getParameters(0,key)); - int value; - if (result.getInt(String8("isVGS"),value) == NO_ERROR) { - ALOGV("Use BT-SCO Voice Volume"); - voiceVolume = 1.0; - } - } - - if (voiceVolume != mLastVoiceVolume && (output == mPrimaryOutput || - isDirectOutput(output))) { - mpClientInterface->setVoiceVolume(voiceVolume, delayMs); - mLastVoiceVolume = voiceVolume; - } - } - - return NO_ERROR; -} - - -void AudioPolicyManager::checkA2dpSuspend() -{ - - // suspend A2DP output if: - // (NOT already suspended) && - // ((SCO device is connected && - // (forced usage for communication || for record is SCO))) || - // (phone state is ringing || in call) - // - // restore A2DP output if: - // (Already suspended) && - // ((SCO device is NOT connected || - // (forced usage NOT for communication && NOT for record is SCO))) && - // (phone state is NOT ringing && NOT in call) - // - if (mA2dpSuspended) { - if (((mScoDeviceAddress == "") || - ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) && - (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) || - ((mPhoneState != AudioSystem::MODE_IN_CALL) && - (mPhoneState != AudioSystem::MODE_RINGTONE))) { - - mA2dpSuspended = false; - } - } else { - if (((mScoDeviceAddress != "") && - ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || - (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) && - ((mPhoneState == AudioSystem::MODE_IN_CALL) || - (mPhoneState == AudioSystem::MODE_RINGTONE))) { - - mA2dpSuspended = true; - } - } -} - -audio_io_handle_t AudioPolicyManager::getA2dpOutput() -{ - return 0; -} - -//private function, no changes from AudioPolicyManagerBase -void AudioPolicyManager::handleNotificationRoutingForStream(AudioSystem::stream_type stream) { - switch(stream) { - case AudioSystem::MUSIC: - checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); - updateDevicesAndOutputs(); - break; - default: - break; - } -} - - -AudioPolicyManagerBase::IOProfile *AudioPolicyManager::getProfileForDirectOutput( - audio_devices_t device, - uint32_t samplingRate, - uint32_t format, - uint32_t channelMask, - audio_output_flags_t flags) -{ - if( !((flags & AUDIO_OUTPUT_FLAG_LPA) || - (flags & AUDIO_OUTPUT_FLAG_TUNNEL)|| - (flags & AUDIO_OUTPUT_FLAG_VOIP_RX)) ) - flags = AUDIO_OUTPUT_FLAG_DIRECT; - - for (size_t i = 0; i < mHwModules.size(); i++) { - if (mHwModules[i]->mHandle == 0) { - continue; - } - for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { - AudioPolicyManagerBase::IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; - if (isCompatibleProfile(profile, device, samplingRate, format, - channelMask, - flags)) { - if (mAvailableOutputDevices & profile->mSupportedDevices) { - return mHwModules[i]->mOutputProfiles[j]; - } - } - } - } - return 0; -} - -bool AudioPolicyManager::isCompatibleProfile(AudioPolicyManagerBase::IOProfile *profile, - audio_devices_t device, - uint32_t samplingRate, - uint32_t format, - uint32_t channelMask, - audio_output_flags_t flags) -{ - if ((profile->mSupportedDevices & device) != device) { - return false; - } - if (profile->mFlags != flags) { - return false; - } - if (samplingRate != 0) { - size_t i; - for (i = 0; i < profile->mSamplingRates.size(); i++) - { - if (profile->mSamplingRates[i] == samplingRate) { - break; - } - } - if (i == profile->mSamplingRates.size()) { - return false; - } - } - if (format != 0) { - size_t i; - for (i = 0; i < profile->mFormats.size(); i++) - { - if (profile->mFormats[i] == format) { - break; - } - } - if (i == profile->mFormats.size()) { - return false; - } - } - if (channelMask != 0) { - size_t i; - for (i = 0; i < profile->mChannelMasks.size(); i++) - { - if (profile->mChannelMasks[i] == channelMask) { - break; - } - } - if (i == profile->mChannelMasks.size()) { - return false; - } - } - ALOGD(" profile found: device %x, flags %x, samplingrate %d,\ - format %x, channelMask %d", - device, flags, samplingRate, format, channelMask); - return true; -} - -bool AudioPolicyManager::platform_is_Fusion3() -{ - char platform[128], baseband[128], baseband_arch[128]; - property_get("ro.board.platform", platform, ""); - property_get("ro.baseband", baseband, ""); - property_get("ro.baseband.arch", baseband_arch, ""); - if (!strcmp("msm8960", platform) && (!strcmp("mdm", baseband) || !strcmp("mdm", baseband_arch))) - return true; - else - return false; -} - -extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface) -{ - return new AudioPolicyManager(clientInterface); -} - -extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface) -{ - delete interface; -} - - -}; // namespace android diff --git a/legacy/msm7x30/AudioPolicyManager.h b/legacy/msm7x30/AudioPolicyManager.h deleted file mode 100644 index 4767b24..0000000 --- a/legacy/msm7x30/AudioPolicyManager.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. - * Not a Contribution. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include -#include -#include -#include -#include -#include - - -namespace android_audio_legacy { - -// ---------------------------------------------------------------------------- - -class AudioPolicyManager: public AudioPolicyManagerBase -{ - -public: - AudioPolicyManager(AudioPolicyClientInterface *clientInterface) - : AudioPolicyManagerBase(clientInterface) {} - - virtual ~AudioPolicyManager() {} - - // AudioPolicyInterface - virtual status_t setDeviceConnectionState(audio_devices_t device, - AudioSystem::device_connection_state state, - const char *device_address); - uint32_t checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, - audio_devices_t prevDevice, - uint32_t delayMs); - - void setStrategyMute(routing_strategy strategy, - bool on, - audio_io_handle_t output, - int delayMs = 0, - audio_devices_t device = (audio_devices_t)0); - void setStreamMute(int stream, bool on, audio_io_handle_t output, - int delayMs = 0, - audio_devices_t device = (audio_devices_t)0); - - virtual AudioSystem::device_connection_state getDeviceConnectionState(audio_devices_t device, - const char *device_address); - virtual void setPhoneState(int state); - virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config); - virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream, - uint32_t samplingRate = 0, - uint32_t format = AudioSystem::FORMAT_DEFAULT, - uint32_t channels = 0, - AudioSystem::output_flags flags = - AudioSystem::OUTPUT_FLAG_INDIRECT, const audio_offload_info_t *offloadInfo = NULL); - virtual status_t startOutput(audio_io_handle_t output, - AudioSystem::stream_type stream, - int session = 0); - virtual status_t stopOutput(audio_io_handle_t output, - AudioSystem::stream_type stream, - int session = 0); - virtual void releaseOutput(audio_io_handle_t output); - virtual audio_io_handle_t getInput(int inputSource, - uint32_t samplingRate, - uint32_t format, - uint32_t channels, - AudioSystem::audio_in_acoustics acoustics); - - // indicates to the audio policy manager that the input starts being used. - virtual status_t startInput(audio_io_handle_t input); - - // indicates to the audio policy manager that the input stops being used. - virtual status_t stopInput(audio_io_handle_t input); - virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, - int index, - audio_devices_t device); -protected: - // return the strategy corresponding to a given stream type - static routing_strategy getStrategy(AudioSystem::stream_type stream); - - // return appropriate device for streams handled by the specified strategy according to current - // phone state, connected devices... - // if fromCache is true, the device is returned from mDeviceForStrategy[], - // otherwise it is determine by current state - // (device connected,phone state, force use, a2dp output...) - // This allows to: - // 1 speed up process when the state is stable (when starting or stopping an output) - // 2 access to either current device selection (fromCache == true) or - // "future" device selection (fromCache == false) when called from a context - // where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND - // before updateDevicesAndOutputs() is called. - virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy, - bool fromCache = true); - - // change the route of the specified output. Returns the number of ms we have slept to - // allow new routing to take effect in certain cases. - uint32_t setOutputDevice(audio_io_handle_t output, - audio_devices_t device, - bool force = false, - int delayMs = 0); - - // select input device corresponding to requested audio source - virtual audio_devices_t getDeviceForInputSource(int inputSource); - - // check that volume change is permitted, compute and send new volume to audio hardware - status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false); - - - // when a device is connected, checks if an open output can be routed - // to this device. If none is open, tries to open one of the available outputs. - // Returns an output suitable to this device or 0. - // when a device is disconnected, checks if an output is not used any more and - // returns its handle if any. - // transfers the audio tracks and effects from one output thread to another accordingly. - status_t checkOutputsForDevice(audio_devices_t device, - AudioSystem::device_connection_state state, - SortedVector& outputs); - // manages A2DP output suspend/restore according to phone state and BT SCO usage - void checkA2dpSuspend(); - - // returns the A2DP output handle if it is open or 0 otherwise - audio_io_handle_t getA2dpOutput(); - - // returns true if give output is direct output - bool isDirectOutput(audio_io_handle_t output); - virtual AudioPolicyManagerBase::IOProfile* getProfileForDirectOutput( - audio_devices_t device, - uint32_t samplingRate, - uint32_t format, - uint32_t channelMask, - audio_output_flags_t flags); - bool isCompatibleProfile(AudioPolicyManagerBase::IOProfile *profile, - audio_devices_t device, - uint32_t samplingRate, - uint32_t format, - uint32_t channelMask, - audio_output_flags_t flags); - // selects the most appropriate device on output for current state - // must be called every time a condition that affects the device choice for a given output is - // changed: connected device, phone state, force use, output start, output stop.. - // see getDeviceForStrategy() for the use of fromCache parameter - - audio_devices_t getNewDevice(audio_io_handle_t output, bool fromCache); - - - // returns the category the device belongs to with regard to volume curve management - static device_category getDeviceCategory(audio_devices_t device); - - // extract one device relevant for volume control from multiple device selection - static audio_devices_t getDeviceForVolume(audio_devices_t device); - // true is current platform implements a back microphone - virtual bool hasBackMicrophone() const { return false; } - // true is current platform supports suplication of notifications and ringtones over A2DP output - virtual bool a2dpUsedForSonification() const { return true; } - -private: - - void handleNotificationRoutingForStream(AudioSystem::stream_type stream); - bool platform_is_Fusion3(); -}; -}; diff --git a/legacy/msm7x30/audio_hw_hal.cpp b/legacy/msm7x30/audio_hw_hal.cpp deleted file mode 100644 index c849eb7..0000000 --- a/legacy/msm7x30/audio_hw_hal.cpp +++ /dev/null @@ -1,759 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * Copyright (c) 2012, The Linux Foundation. All rights reserved. - * Copyright (c) 2012-2013, The CyanogenMod Project - * Not a Contribution, Apache license notifications and license are retained - * for attribution purposes only. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "audio.primary.msm7x30" -//#define LOG_NDEBUG 0 - -#include - -#include -#include -#include - -#include -#include - -namespace android_audio_legacy { - -extern "C" { - -struct qcom_audio_module { - struct audio_module module; -}; - -struct qcom_audio_device { - struct audio_hw_device device; - - struct AudioHardwareInterface *hwif; -}; - -struct qcom_stream_out { - struct audio_stream_out stream; - - AudioStreamOut *qcom_out; -}; - -struct qcom_stream_in { - struct audio_stream_in stream; - - AudioStreamIn *qcom_in; -}; - -enum { - HAL_API_REV_1_0, - HAL_API_REV_2_0, - HAL_API_REV_NUM -} hal_api_rev; -static uint32_t audio_device_conv_table[][HAL_API_REV_NUM] = -{ - /* output devices */ - { AudioSystem::DEVICE_OUT_EARPIECE, AUDIO_DEVICE_OUT_EARPIECE }, - { AudioSystem::DEVICE_OUT_SPEAKER, AUDIO_DEVICE_OUT_SPEAKER }, - { AudioSystem::DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET }, - { AudioSystem::DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADPHONE }, - { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, AUDIO_DEVICE_OUT_BLUETOOTH_SCO }, - { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET }, - { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT }, - { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP }, - { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES }, - { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER }, - { AudioSystem::DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_AUX_DIGITAL }, - { AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET }, - { AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET }, - { AudioSystem::DEVICE_OUT_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT }, - /* input devices */ - { AudioSystem::DEVICE_IN_COMMUNICATION, AUDIO_DEVICE_IN_COMMUNICATION }, - { AudioSystem::DEVICE_IN_AMBIENT, AUDIO_DEVICE_IN_AMBIENT }, - { AudioSystem::DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC }, - { AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET }, - { AudioSystem::DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET }, - { AudioSystem::DEVICE_IN_AUX_DIGITAL, AUDIO_DEVICE_IN_AUX_DIGITAL }, - { AudioSystem::DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_VOICE_CALL }, - { AudioSystem::DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BACK_MIC }, - { AudioSystem::DEVICE_IN_DEFAULT, AUDIO_DEVICE_IN_DEFAULT }, -}; - -static uint32_t convert_audio_device(uint32_t from_device, int from_rev, int to_rev) -{ - const uint32_t k_num_devices = sizeof(audio_device_conv_table)/sizeof(uint32_t)/HAL_API_REV_NUM; - uint32_t to_device = AUDIO_DEVICE_NONE; - uint32_t in_bit = 0; - - if (from_rev != HAL_API_REV_1_0) { - in_bit = from_device & AUDIO_DEVICE_BIT_IN; - from_device &= ~AUDIO_DEVICE_BIT_IN; - } - - while (from_device) { - uint32_t i = 31 - __builtin_clz(from_device); - uint32_t cur_device = (1 << i) | in_bit; - - for (i = 0; i < k_num_devices; i++) { - if (audio_device_conv_table[i][from_rev] == cur_device) { - to_device |= audio_device_conv_table[i][to_rev]; - break; - } - } - from_device &= ~cur_device; - } - return to_device; -} - -/** audio_stream_out implementation **/ -static uint32_t out_get_sample_rate(const struct audio_stream *stream) -{ - const struct qcom_stream_out *out = - reinterpret_cast(stream); - return out->qcom_out->sampleRate(); -} - -static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - struct qcom_stream_out *out = - reinterpret_cast(stream); - - ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); - /* TODO: implement this */ - return 0; -} - -static size_t out_get_buffer_size(const struct audio_stream *stream) -{ - const struct qcom_stream_out *out = - reinterpret_cast(stream); - return out->qcom_out->bufferSize(); -} - -static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) -{ - const struct qcom_stream_out *out = - reinterpret_cast(stream); - return (audio_channel_mask_t) out->qcom_out->channels(); -} - -static audio_format_t out_get_format(const struct audio_stream *stream) -{ - const struct qcom_stream_out *out = - reinterpret_cast(stream); - return (audio_format_t)out->qcom_out->format(); -} - -static int out_set_format(struct audio_stream *stream, audio_format_t format) -{ - struct qcom_stream_out *out = - reinterpret_cast(stream); - ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); - /* TODO: implement me */ - return 0; -} - -static int out_standby(struct audio_stream *stream) -{ - struct qcom_stream_out *out = - reinterpret_cast(stream); - return out->qcom_out->standby(); -} - -static int out_dump(const struct audio_stream *stream, int fd) -{ - const struct qcom_stream_out *out = - reinterpret_cast(stream); - Vector args; - return out->qcom_out->dump(fd, args); -} - -static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - struct qcom_stream_out *out = - reinterpret_cast(stream); - int val; - String8 s8 = String8(kvpairs); - AudioParameter parms = AudioParameter(String8(kvpairs)); - - if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { - val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0); - parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); - parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); - s8 = parms.toString(); - } - - return out->qcom_out->setParameters(s8); -} - -static char * out_get_parameters(const struct audio_stream *stream, const char *keys) -{ - const struct qcom_stream_out *out = - reinterpret_cast(stream); - String8 s8; - int val; - - s8 = out->qcom_out->getParameters(String8(keys)); - - AudioParameter parms = AudioParameter(s8); - if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { - val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0); - parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); - parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); - s8 = parms.toString(); - } - - return strdup(s8.string()); -} - -static uint32_t out_get_latency(const struct audio_stream_out *stream) -{ - const struct qcom_stream_out *out = - reinterpret_cast(stream); - return out->qcom_out->latency(); -} - -static int out_set_volume(struct audio_stream_out *stream, float left, - float right) -{ - struct qcom_stream_out *out = - reinterpret_cast(stream); - return out->qcom_out->setVolume(left, right); -} - -static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, - size_t bytes) -{ - struct qcom_stream_out *out = - reinterpret_cast(stream); - usleep(5); - return out->qcom_out->write(buffer, bytes); -} - -static int out_get_render_position(const struct audio_stream_out *stream, - uint32_t *dsp_frames) -{ - const struct qcom_stream_out *out = - reinterpret_cast(stream); - return out->qcom_out->getRenderPosition(dsp_frames); -} - -static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - return 0; -} - -static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - return 0; -} - -static int out_get_next_write_timestamp(const struct audio_stream_out *stream, - int64_t *timestamp) -{ - return -EINVAL; -} - -/** audio_stream_in implementation **/ -static uint32_t in_get_sample_rate(const struct audio_stream *stream) -{ - const struct qcom_stream_in *in = - reinterpret_cast(stream); - return in->qcom_in->sampleRate(); -} - -static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - struct qcom_stream_in *in = - reinterpret_cast(stream); - - ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); - /* TODO: implement this */ - return 0; -} - -static size_t in_get_buffer_size(const struct audio_stream *stream) -{ - const struct qcom_stream_in *in = - reinterpret_cast(stream); - return in->qcom_in->bufferSize(); -} - -static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) -{ - const struct qcom_stream_in *in = - reinterpret_cast(stream); - return (audio_channel_mask_t) in->qcom_in->channels(); -} - -static audio_format_t in_get_format(const struct audio_stream *stream) -{ - const struct qcom_stream_in *in = - reinterpret_cast(stream); - return (audio_format_t)in->qcom_in->format(); -} - -static int in_set_format(struct audio_stream *stream, audio_format_t format) -{ - struct qcom_stream_in *in = - reinterpret_cast(stream); - ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); - /* TODO: implement me */ - return 0; -} - -static int in_standby(struct audio_stream *stream) -{ - struct qcom_stream_in *in = reinterpret_cast(stream); - return in->qcom_in->standby(); -} - -static int in_dump(const struct audio_stream *stream, int fd) -{ - const struct qcom_stream_in *in = - reinterpret_cast(stream); - Vector args; - return in->qcom_in->dump(fd, args); -} - -static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - struct qcom_stream_in *in = - reinterpret_cast(stream); - int val; - AudioParameter parms = AudioParameter(String8(kvpairs)); - String8 s8 = String8(kvpairs); - - if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { - val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0); - parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); - parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); - s8 = parms.toString(); - } - - return in->qcom_in->setParameters(s8); -} - -static char * in_get_parameters(const struct audio_stream *stream, - const char *keys) -{ - const struct qcom_stream_in *in = - reinterpret_cast(stream); - String8 s8; - int val; - - s8 = in->qcom_in->getParameters(String8(keys)); - - AudioParameter parms = AudioParameter(s8); - if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { - val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0); - parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); - parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); - s8 = parms.toString(); - } - - return strdup(s8.string()); -} - -static int in_set_gain(struct audio_stream_in *stream, float gain) -{ - struct qcom_stream_in *in = - reinterpret_cast(stream); - return in->qcom_in->setGain(gain); -} - -static ssize_t in_read(struct audio_stream_in *stream, void* buffer, - size_t bytes) -{ - struct qcom_stream_in *in = - reinterpret_cast(stream); - return in->qcom_in->read(buffer, bytes); -} - -static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) -{ - struct qcom_stream_in *in = - reinterpret_cast(stream); - return in->qcom_in->getInputFramesLost(); -} - -static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - const struct qcom_stream_in *in = - reinterpret_cast(stream); - return in->qcom_in->addAudioEffect(effect); -} - -static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - const struct qcom_stream_in *in = - reinterpret_cast(stream); - return in->qcom_in->removeAudioEffect(effect); -} - -/** audio_hw_device implementation **/ -static inline struct qcom_audio_device * to_ladev(struct audio_hw_device *dev) -{ - return reinterpret_cast(dev); -} - -static inline const struct qcom_audio_device * to_cladev(const struct audio_hw_device *dev) -{ - return reinterpret_cast(dev); -} - - -static int adev_init_check(const struct audio_hw_device *dev) -{ - const struct qcom_audio_device *qadev = to_cladev(dev); - - return qadev->hwif->initCheck(); -} - -static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - return qadev->hwif->setVoiceVolume(volume); -} - -static int adev_set_master_volume(struct audio_hw_device *dev, float volume) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - return qadev->hwif->setMasterVolume(volume); -} -static int adev_get_master_volume(struct audio_hw_device *dev, float *volume) { - - struct qcom_audio_device *qadev = to_ladev(dev); - return qadev->hwif->getMasterVolume(volume); -} - -#ifdef QCOM_FM_ENABLED -static int adev_set_fm_volume(struct audio_hw_device *dev, float volume) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - return qadev->hwif->setFmVolume(volume); -} -#endif -static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - return qadev->hwif->setMode((int)mode); -} - -static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - return qadev->hwif->setMicMute(state); -} - -static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) -{ - const struct qcom_audio_device *qadev = to_cladev(dev); - return qadev->hwif->getMicMute(state); -} - -static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - return qadev->hwif->setParameters(String8(kvpairs)); -} - -static char * adev_get_parameters(const struct audio_hw_device *dev, - const char *keys) -{ - const struct qcom_audio_device *qadev = to_cladev(dev); - String8 s8; - - s8 = qadev->hwif->getParameters(String8(keys)); - return strdup(s8.string()); -} - -static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, - const struct audio_config *config) -{ - const struct qcom_audio_device *qadev = to_cladev(dev); - uint8_t channelCount = popcount(config->channel_mask); - return qadev->hwif->getInputBufferSize(config->sample_rate,config->format,channelCount); -} - -#ifdef QCOM_TUNNEL_LPA_ENABLED -static int adev_open_output_session(struct audio_hw_device *dev, - uint32_t devices, - int *format, - int sessionId, - uint32_t samplingRate, - uint32_t channels, - struct audio_stream_out **stream_out) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - status_t status; - struct qcom_stream_out *out; - int ret; - - out = (struct qcom_stream_out *)calloc(1, sizeof(*out)); - if (!out) - return -ENOMEM; - - devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); - status = static_cast (flags); - - out->qcom_out = qadev->hwif->openOutputSession(devices, format,&status,sessionId,samplingRate,channels); - if (!out->qcom_out) { - ret = status; - goto err_open; - } - - out->stream.common.standby = out_standby; - out->stream.common.set_parameters = out_set_parameters; - out->stream.set_volume = out_set_volume; - - *stream_out = &out->stream; - return 0; - -err_open: - free(out); - *stream_out = NULL; - return ret; -} -#endif /* QCOM_TUNNEL_LPA_ENABLED */ -static int adev_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - status_t status; - struct qcom_stream_out *out; - int ret; - - out = (struct qcom_stream_out *)calloc(1, sizeof(*out)); - if (!out) - return -ENOMEM; - - devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); - status = static_cast (flags); - - out->qcom_out = qadev->hwif->openOutputStream(devices, (int *) &config->format, - &config->channel_mask, - &config->sample_rate, - &status); - if (!out->qcom_out) { - ret = status; - goto err_open; - } - - out->stream.common.get_sample_rate = out_get_sample_rate; - out->stream.common.set_sample_rate = out_set_sample_rate; - out->stream.common.get_buffer_size = out_get_buffer_size; - out->stream.common.get_channels = out_get_channels; - out->stream.common.get_format = out_get_format; - out->stream.common.set_format = out_set_format; - out->stream.common.standby = out_standby; - out->stream.common.dump = out_dump; - out->stream.common.set_parameters = out_set_parameters; - out->stream.common.get_parameters = out_get_parameters; - out->stream.common.add_audio_effect = out_add_audio_effect; - out->stream.common.remove_audio_effect = out_remove_audio_effect; - out->stream.get_latency = out_get_latency; - out->stream.set_volume = out_set_volume; - out->stream.write = out_write; - out->stream.get_render_position = out_get_render_position; - out->stream.get_next_write_timestamp = out_get_next_write_timestamp; - - *stream_out = &out->stream; - return 0; - -err_open: - free(out); - *stream_out = NULL; - return ret; -} - -static void adev_close_output_stream(struct audio_hw_device *dev, - struct audio_stream_out* stream) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - struct qcom_stream_out *out = reinterpret_cast(stream); - - qadev->hwif->closeOutputStream(out->qcom_out); - free(out); -} - -/** This method creates and opens the audio hardware input stream */ -static int adev_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - status_t status; - struct qcom_stream_in *in; - int ret; - - in = (struct qcom_stream_in *)calloc(1, sizeof(*in)); - if (!in) - return -ENOMEM; - - devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); - in->qcom_in = qadev->hwif->openInputStream(devices, (int *)&config->format, - &config->channel_mask, - &config->sample_rate, - &status, - (AudioSystem::audio_in_acoustics)0); - if (!in->qcom_in) { - ret = status; - goto err_open; - } - - in->stream.common.get_sample_rate = in_get_sample_rate; - in->stream.common.set_sample_rate = in_set_sample_rate; - in->stream.common.get_buffer_size = in_get_buffer_size; - in->stream.common.get_channels = in_get_channels; - in->stream.common.get_format = in_get_format; - in->stream.common.set_format = in_set_format; - in->stream.common.standby = in_standby; - in->stream.common.dump = in_dump; - in->stream.common.set_parameters = in_set_parameters; - in->stream.common.get_parameters = in_get_parameters; - in->stream.common.add_audio_effect = in_add_audio_effect; - in->stream.common.remove_audio_effect = in_remove_audio_effect; - in->stream.set_gain = in_set_gain; - in->stream.read = in_read; - in->stream.get_input_frames_lost = in_get_input_frames_lost; - - *stream_in = &in->stream; - return 0; - -err_open: - free(in); - *stream_in = NULL; - return ret; -} - -static void adev_close_input_stream(struct audio_hw_device *dev, - struct audio_stream_in *stream) -{ - struct qcom_audio_device *qadev = to_ladev(dev); - struct qcom_stream_in *in = - reinterpret_cast(stream); - - qadev->hwif->closeInputStream(in->qcom_in); - free(in); -} - -static int adev_dump(const struct audio_hw_device *dev, int fd) -{ - const struct qcom_audio_device *qadev = to_cladev(dev); - Vector args; - - return qadev->hwif->dumpState(fd, args); -} - -static int qcom_adev_close(hw_device_t* device) -{ - struct audio_hw_device *hwdev = - reinterpret_cast(device); - struct qcom_audio_device *qadev = to_ladev(hwdev); - - if (!qadev) - return 0; - - if (qadev->hwif) - delete qadev->hwif; - - free(qadev); - return 0; -} - -static int qcom_adev_open(const hw_module_t* module, const char* name, - hw_device_t** device) -{ - struct qcom_audio_device *qadev; - int ret; - - if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) - return -EINVAL; - - qadev = (struct qcom_audio_device *)calloc(1, sizeof(*qadev)); - if (!qadev) - return -ENOMEM; - - qadev->device.common.tag = HARDWARE_DEVICE_TAG; - qadev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; - qadev->device.common.module = const_cast(module); - qadev->device.common.close = qcom_adev_close; - - qadev->device.init_check = adev_init_check; - qadev->device.set_voice_volume = adev_set_voice_volume; - qadev->device.set_master_volume = adev_set_master_volume; - qadev->device.get_master_volume = adev_get_master_volume; -#ifdef QCOM_FM_ENABLED - qadev->device.set_fm_volume = adev_set_fm_volume; -#endif - qadev->device.set_mode = adev_set_mode; - qadev->device.set_mic_mute = adev_set_mic_mute; - qadev->device.get_mic_mute = adev_get_mic_mute; - qadev->device.set_parameters = adev_set_parameters; - qadev->device.get_parameters = adev_get_parameters; - qadev->device.get_input_buffer_size = adev_get_input_buffer_size; - qadev->device.open_output_stream = adev_open_output_stream; -#ifdef QCOM_TUNNEL_LPA_ENABLED - qadev->device.open_output_session = adev_open_output_session; -#endif /* QCOM_TUNNEL_LPA_ENABLED */ - qadev->device.close_output_stream = adev_close_output_stream; - qadev->device.open_input_stream = adev_open_input_stream; - qadev->device.close_input_stream = adev_close_input_stream; - qadev->device.dump = adev_dump; - - qadev->hwif = createAudioHardware(); - if (!qadev->hwif) { - ret = -EIO; - goto err_create_audio_hw; - } - - *device = &qadev->device.common; - - return 0; - -err_create_audio_hw: - free(qadev); - return ret; -} - -static struct hw_module_methods_t qcom_audio_module_methods = { - open: qcom_adev_open -}; - -struct qcom_audio_module HAL_MODULE_INFO_SYM = { - module: { - common: { - tag: HARDWARE_MODULE_TAG, - module_api_version: AUDIO_DEVICE_API_VERSION_1_0, - hal_api_version: HARDWARE_HAL_API_VERSION, - id: AUDIO_HARDWARE_MODULE_ID, - name: "QCOM Audio HW HAL", - author: "Code Aurora Forum", - methods: &qcom_audio_module_methods, - dso : NULL, - reserved : {0}, - }, - }, -}; - -}; // extern "C" - -}; // namespace android_audio_legacy diff --git a/legacy/msm7x30/audio_policy_hal.cpp b/legacy/msm7x30/audio_policy_hal.cpp deleted file mode 100644 index a41b453..0000000 --- a/legacy/msm7x30/audio_policy_hal.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - * Not a Contribution. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "qcom_audio_policy_hal" -//#define LOG_NDEBUG 0 - -#include - -#include -#include -#include -#include - -#include -#include - -#include "AudioPolicyCompatClient.h" - -namespace android_audio_legacy { - -extern "C" { - -struct qcom_ap_module { - struct audio_policy_module module; -}; - -struct qcom_ap_device { - struct audio_policy_device device; -}; - -struct qcom_audio_policy { - struct audio_policy policy; - - void *service; - struct audio_policy_service_ops *aps_ops; - AudioPolicyCompatClient *service_client; - AudioPolicyInterface *apm; -}; - -static inline struct qcom_audio_policy * to_qap(struct audio_policy *pol) -{ - return reinterpret_cast(pol); -} - -static inline const struct qcom_audio_policy * to_cqap(const struct audio_policy *pol) -{ - return reinterpret_cast(pol); -} - - -static int ap_set_device_connection_state(struct audio_policy *pol, - audio_devices_t device, - audio_policy_dev_state_t state, - const char *device_address) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->setDeviceConnectionState( - (AudioSystem::audio_devices)device, - (AudioSystem::device_connection_state)state, - device_address); -} - -static audio_policy_dev_state_t ap_get_device_connection_state( - const struct audio_policy *pol, - audio_devices_t device, - const char *device_address) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return (audio_policy_dev_state_t)qap->apm->getDeviceConnectionState( - (AudioSystem::audio_devices)device, - device_address); -} - -static void ap_set_phone_state(struct audio_policy *pol, audio_mode_t state) -{ - struct qcom_audio_policy *qap = to_qap(pol); - // as this is the legacy API, don't change it to use audio_mode_t instead of int - qap->apm->setPhoneState((int) state); -} - - /* indicate a change in ringer mode */ -static void ap_set_ringer_mode(struct audio_policy *pol, uint32_t mode, - uint32_t mask) -{ - // deprecated, never called -} - - /* force using a specific device category for the specified usage */ -static void ap_set_force_use(struct audio_policy *pol, - audio_policy_force_use_t usage, - audio_policy_forced_cfg_t config) -{ - struct qcom_audio_policy *qap = to_qap(pol); - qap->apm->setForceUse((AudioSystem::force_use)usage, - (AudioSystem::forced_config)config); -} - - /* retreive current device category forced for a given usage */ -static audio_policy_forced_cfg_t ap_get_force_use( - const struct audio_policy *pol, - audio_policy_force_use_t usage) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return (audio_policy_forced_cfg_t)qap->apm->getForceUse( - (AudioSystem::force_use)usage); -} - -/* if can_mute is true, then audio streams that are marked ENFORCED_AUDIBLE - * can still be muted. */ -static void ap_set_can_mute_enforced_audible(struct audio_policy *pol, - bool can_mute) -{ - struct qcom_audio_policy *qap = to_qap(pol); - qap->apm->setSystemProperty("ro.camera.sound.forced", can_mute ? "0" : "1"); -} - -static int ap_init_check(const struct audio_policy *pol) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->initCheck(); -} - -static audio_io_handle_t ap_get_output(struct audio_policy *pol, - audio_stream_type_t stream, - uint32_t sampling_rate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo) -{ - struct qcom_audio_policy *qap = to_qap(pol); - - ALOGV("%s: tid %d", __func__, gettid()); - return qap->apm->getOutput((AudioSystem::stream_type)stream, - sampling_rate, (int) format, channelMask, - (AudioSystem::output_flags)flags, - offloadInfo); -} - -static int ap_start_output(struct audio_policy *pol, audio_io_handle_t output, - audio_stream_type_t stream, int session) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->startOutput(output, (AudioSystem::stream_type)stream, - session); -} - -static int ap_stop_output(struct audio_policy *pol, audio_io_handle_t output, - audio_stream_type_t stream, int session) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->stopOutput(output, (AudioSystem::stream_type)stream, - session); -} - -static void ap_release_output(struct audio_policy *pol, - audio_io_handle_t output) -{ - struct qcom_audio_policy *qap = to_qap(pol); - qap->apm->releaseOutput(output); -} - -static audio_io_handle_t ap_get_input(struct audio_policy *pol, audio_source_t inputSource, - uint32_t sampling_rate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_in_acoustics_t acoustics) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->getInput((int) inputSource, sampling_rate, (int) format, channelMask, - (AudioSystem::audio_in_acoustics)acoustics); -} - -static int ap_start_input(struct audio_policy *pol, audio_io_handle_t input) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->startInput(input); -} - -static int ap_stop_input(struct audio_policy *pol, audio_io_handle_t input) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->stopInput(input); -} - -static void ap_release_input(struct audio_policy *pol, audio_io_handle_t input) -{ - struct qcom_audio_policy *qap = to_qap(pol); - qap->apm->releaseInput(input); -} - -static void ap_init_stream_volume(struct audio_policy *pol, - audio_stream_type_t stream, int index_min, - int index_max) -{ - struct qcom_audio_policy *qap = to_qap(pol); - qap->apm->initStreamVolume((AudioSystem::stream_type)stream, index_min, - index_max); -} - -static int ap_set_stream_volume_index(struct audio_policy *pol, - audio_stream_type_t stream, - int index) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream, - index, - AUDIO_DEVICE_OUT_DEFAULT); -} - -static int ap_get_stream_volume_index(const struct audio_policy *pol, - audio_stream_type_t stream, - int *index) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream, - index, - AUDIO_DEVICE_OUT_DEFAULT); -} - -static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol, - audio_stream_type_t stream) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->getStrategyForStream((AudioSystem::stream_type)stream); -} - -static int ap_set_stream_volume_index_for_device(struct audio_policy *pol, - audio_stream_type_t stream, - int index, - audio_devices_t device) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream, - index, - device); -} - -static int ap_get_stream_volume_index_for_device(const struct audio_policy *pol, - audio_stream_type_t stream, - int *index, - audio_devices_t device) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream, - index, - device); -} - -static audio_devices_t ap_get_devices_for_stream(const struct audio_policy *pol, - audio_stream_type_t stream) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->getDevicesForStream((AudioSystem::stream_type)stream); -} - -static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol, - const struct effect_descriptor_s *desc) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->getOutputForEffect(desc); -} - -static int ap_register_effect(struct audio_policy *pol, - const struct effect_descriptor_s *desc, - audio_io_handle_t io, - uint32_t strategy, - int session, - int id) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->registerEffect(desc, io, strategy, session, id); -} - -static int ap_unregister_effect(struct audio_policy *pol, int id) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->unregisterEffect(id); -} - -static int ap_set_effect_enabled(struct audio_policy *pol, int id, bool enabled) -{ - struct qcom_audio_policy *qap = to_qap(pol); - return qap->apm->setEffectEnabled(id, enabled); -} - -static bool ap_is_stream_active(const struct audio_policy *pol, - audio_stream_type_t stream, - uint32_t in_past_ms) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->isStreamActive((int) stream, in_past_ms); -} - -static bool ap_is_stream_active_remotely(const struct audio_policy *pol, - audio_stream_type_t stream, uint32_t in_past_ms) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->isStreamActiveRemotely((int) stream, in_past_ms); -} - -static bool ap_is_source_active(const struct audio_policy *pol, audio_source_t source) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->isSourceActive(source); -} - -static int ap_dump(const struct audio_policy *pol, int fd) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->dump(fd); -} - -static bool ap_is_offload_supported(const struct audio_policy *pol, - const audio_offload_info_t *info) -{ - const struct qcom_audio_policy *qap = to_cqap(pol); - return qap->apm->isOffloadSupported(*info); -} - -static int create_qcom_ap(const struct audio_policy_device *device, - struct audio_policy_service_ops *aps_ops, - void *service, - struct audio_policy **ap) -{ - struct qcom_audio_policy *qap; - int ret; - - if (!service || !aps_ops) - return -EINVAL; - - qap = (struct qcom_audio_policy *)calloc(1, sizeof(*qap)); - if (!qap) - return -ENOMEM; - - qap->policy.set_device_connection_state = ap_set_device_connection_state; - qap->policy.get_device_connection_state = ap_get_device_connection_state; - qap->policy.set_phone_state = ap_set_phone_state; - qap->policy.set_ringer_mode = ap_set_ringer_mode; - qap->policy.set_force_use = ap_set_force_use; - qap->policy.get_force_use = ap_get_force_use; - qap->policy.set_can_mute_enforced_audible = - ap_set_can_mute_enforced_audible; - qap->policy.init_check = ap_init_check; - qap->policy.get_output = ap_get_output; - qap->policy.start_output = ap_start_output; - qap->policy.stop_output = ap_stop_output; - qap->policy.release_output = ap_release_output; - qap->policy.get_input = ap_get_input; - qap->policy.start_input = ap_start_input; - qap->policy.stop_input = ap_stop_input; - qap->policy.release_input = ap_release_input; - qap->policy.init_stream_volume = ap_init_stream_volume; - qap->policy.set_stream_volume_index = ap_set_stream_volume_index; - qap->policy.get_stream_volume_index = ap_get_stream_volume_index; - qap->policy.set_stream_volume_index_for_device = ap_set_stream_volume_index_for_device; - qap->policy.get_stream_volume_index_for_device = ap_get_stream_volume_index_for_device; - qap->policy.get_strategy_for_stream = ap_get_strategy_for_stream; - qap->policy.get_devices_for_stream = ap_get_devices_for_stream; - qap->policy.get_output_for_effect = ap_get_output_for_effect; - qap->policy.register_effect = ap_register_effect; - qap->policy.unregister_effect = ap_unregister_effect; - qap->policy.set_effect_enabled = ap_set_effect_enabled; - qap->policy.is_stream_active = ap_is_stream_active; - qap->policy.is_stream_active_remotely = ap_is_stream_active_remotely; - qap->policy.is_source_active = ap_is_source_active; - qap->policy.dump = ap_dump; - qap->policy.is_offload_supported = ap_is_offload_supported; - - qap->service = service; - qap->aps_ops = aps_ops; - qap->service_client = - new AudioPolicyCompatClient(aps_ops, service); - if (!qap->service_client) { - ret = -ENOMEM; - goto err_new_compat_client; - } - - qap->apm = createAudioPolicyManager(qap->service_client); - if (!qap->apm) { - ret = -ENOMEM; - goto err_create_apm; - } - - *ap = &qap->policy; - return 0; - -err_create_apm: - delete qap->service_client; -err_new_compat_client: - free(qap); - *ap = NULL; - return ret; -} - -static int destroy_qcom_ap(const struct audio_policy_device *ap_dev, - struct audio_policy *ap) -{ - struct qcom_audio_policy *qap = to_qap(ap); - - if (!qap) - return 0; - - if (qap->apm) - destroyAudioPolicyManager(qap->apm); - if (qap->service_client) - delete qap->service_client; - free(qap); - return 0; -} - -static int qcom_ap_dev_close(hw_device_t* device) -{ - if (device) - free(device); - return 0; -} - -static int qcom_ap_dev_open(const hw_module_t* module, const char* name, - hw_device_t** device) -{ - struct qcom_ap_device *dev; - - if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0) - return -EINVAL; - - dev = (struct qcom_ap_device *)calloc(1, sizeof(*dev)); - if (!dev) - return -ENOMEM; - - dev->device.common.tag = HARDWARE_DEVICE_TAG; - dev->device.common.version = 0; - dev->device.common.module = const_cast(module); - dev->device.common.close = qcom_ap_dev_close; - dev->device.create_audio_policy = create_qcom_ap; - dev->device.destroy_audio_policy = destroy_qcom_ap; - - *device = &dev->device.common; - - return 0; -} - -static struct hw_module_methods_t qcom_ap_module_methods = { - open: qcom_ap_dev_open -}; - -struct qcom_ap_module HAL_MODULE_INFO_SYM = { - module: { - common: { - tag: HARDWARE_MODULE_TAG, - version_major: 1, - version_minor: 0, - id: AUDIO_POLICY_HARDWARE_MODULE_ID, - name: "QCOM Audio Policy HAL", - author: "The Linux Foundation", - methods: &qcom_ap_module_methods, - dso : NULL, - reserved : {0}, - }, - }, -}; - -}; // extern "C" - -}; // namespace android_audio_legacy diff --git a/legacy/msm7x30/control.h b/legacy/msm7x30/control.h deleted file mode 100644 index 3eb69fd..0000000 --- a/legacy/msm7x30/control.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2009, The Android Open-Source Project - * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. - * Copyright (c) 2011-2013, The CyanogenMod Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MSM_AUDIO_ALSA_CONTROL -#define __MSM_AUDIO_ALSA_CONTROL - -#include - -__BEGIN_DECLS - -extern const char **msm_get_device_list(void); -extern int msm_mixer_count(void); -extern int msm_mixer_open(const char *name, int id); -extern void msm_mixer_close(void); -extern int msm_get_device(const char *name); -extern int msm_en_device(int device, short enable); -extern int msm_route_stream(int dir, int dec_id, int dev_id, int set); -extern int msm_route_voice(int tx, int rx, int set); -extern int msm_set_volume(int dec_id, float vol); -extern int msm_get_device_class(int dev_id); -extern int msm_get_device_capability(int dev_id); -extern int msm_get_device_count(void); -extern void msm_start_voice(void); -extern int msm_end_voice(void); -extern int msm_set_voice_tx_mute(int mute); -extern int msm_set_voice_rx_vol(int volume); -extern void msm_set_device_volume(int dev_id, int volume); -extern void msm_device_mute(int dev_id, int mute); -extern int msm_reset_all_device(void); - -__END_DECLS - -#endif diff --git a/legacy/msm7x30/initialize_audcal7x30.h b/legacy/msm7x30/initialize_audcal7x30.h deleted file mode 100644 index bf547ff..0000000 --- a/legacy/msm7x30/initialize_audcal7x30.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2009, The Android Open-Source Project - * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. - * Copyright (c) 2011-2013, The CyanogenMod Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MSM_AUDIO_CALIBRATION -#define __MSM_AUDIO_CALIBRATION - -#include - -__BEGIN_DECLS - -extern void audcal_initialize(void); -extern void audcal_deinitialize(void); - -__END_DECLS - -#endif