Revert "audio: Initial bring up of QCOM added audio feature."
This reverts commit bbd94add9f826cc02a5cbb6813af38110c767a88.
diff --git a/alsa_sound/ALSAControl.cpp b/alsa_sound/ALSAControl.cpp
new file mode 100644
index 0000000..2d610a1
--- /dev/null
+++ b/alsa_sound/ALSAControl.cpp
@@ -0,0 +1,131 @@
+/* ALSAControl.cpp
+ **
+ ** Copyright 2008-2009 Wind River Systems
+ ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ **
+ ** 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 <errno.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dlfcn.h>
+
+#define LOG_TAG "ALSAControl"
+//#define LOG_NDEBUG 0
+#define LOG_NDDEBUG 0
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <cutils/properties.h>
+#include <media/AudioRecord.h>
+#include <hardware_legacy/power.h>
+
+#include "AudioHardwareALSA.h"
+
+namespace android_audio_legacy
+{
+
+ALSAControl::ALSAControl(const char *device)
+{
+ ALOGD("ALSAControl: ctor device %s", device);
+ mHandle = mixer_open(device);
+ ALOGV("ALSAControl: ctor mixer %p", mHandle);
+}
+
+ALSAControl::~ALSAControl()
+{
+ if (mHandle) mixer_close(mHandle);
+}
+
+status_t ALSAControl::get(const char *name, unsigned int &value, int index)
+{
+ struct mixer_ctl *ctl;
+
+ if (!mHandle) {
+ ALOGE("Control not initialized");
+ return NO_INIT;
+ }
+
+ ctl = mixer_get_control(mHandle, name, index);
+ if (!ctl)
+ return BAD_VALUE;
+
+ mixer_ctl_get(ctl, &value);
+ return NO_ERROR;
+}
+
+status_t ALSAControl::set(const char *name, unsigned int value, int index)
+{
+ struct mixer_ctl *ctl;
+ int ret = 0;
+ ALOGD("set:: name %s value %d index %d", name, value, index);
+ if (!mHandle) {
+ ALOGE("Control not initialized");
+ return NO_INIT;
+ }
+
+ // ToDo: Do we need to send index here? Right now it works with 0
+ ctl = mixer_get_control(mHandle, name, 0);
+ if(ctl == NULL) {
+ ALOGE("Could not get the mixer control");
+ return BAD_VALUE;
+ }
+ ret = mixer_ctl_set(ctl, value);
+ return (ret < 0) ? BAD_VALUE : NO_ERROR;
+}
+
+status_t ALSAControl::set(const char *name, const char *value)
+{
+ struct mixer_ctl *ctl;
+ int ret = 0;
+ ALOGD("set:: name %s value %s", name, value);
+
+ if (!mHandle) {
+ ALOGE("Control not initialized");
+ return NO_INIT;
+ }
+
+ ctl = mixer_get_control(mHandle, name, 0);
+ if(ctl == NULL) {
+ ALOGE("Could not get the mixer control");
+ return BAD_VALUE;
+ }
+ ret = mixer_ctl_select(ctl, value);
+ return (ret < 0) ? BAD_VALUE : NO_ERROR;
+}
+
+status_t ALSAControl::setext(const char *name, int count, char **setValues)
+{
+ struct mixer_ctl *ctl;
+ int ret = 0;
+ ALOGD("setext:: name %s count %d", name, count);
+ if (!mHandle) {
+ ALOGE("Control not initialized");
+ return NO_INIT;
+ }
+
+ // ToDo: Do we need to send index here? Right now it works with 0
+ ctl = mixer_get_control(mHandle, name, 0);
+ if(ctl == NULL) {
+ ALOGE("Could not get the mixer control");
+ return BAD_VALUE;
+ }
+ ret = mixer_ctl_set_value(ctl, count, setValues);
+ return (ret < 0) ? BAD_VALUE : NO_ERROR;
+}
+
+}; // namespace android
diff --git a/alsa_sound/ALSADevice.cpp b/alsa_sound/ALSADevice.cpp
deleted file mode 100644
index cd5b92d..0000000
--- a/alsa_sound/ALSADevice.cpp
+++ /dev/null
@@ -1,2408 +0,0 @@
-/* ALSADevice.cpp
- **
- ** Copyright 2009 Wind River Systems
- ** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- **
- ** 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 "ALSADevice"
-#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-#include <cutils/properties.h>
-#include <linux/ioctl.h>
-#include "AudioUtil.h"
-#include "AudioHardwareALSA.h"
-#include <media/AudioRecord.h>
-#include <dlfcn.h>
-#ifdef QCOM_CSDCLIENT_ENABLED
-extern "C" {
-static int (*csd_disable_device)();
-static int (*csd_enable_device)(int, int, uint32_t);
-static int (*csd_volume)(int);
-static int (*csd_mic_mute)(int);
-static int (*csd_wide_voice)(uint8_t);
-static int (*csd_slow_talk)(uint8_t);
-static int (*csd_fens)(uint8_t);
-static int (*csd_start_voice)();
-static int (*csd_stop_voice)();
-static int (*csd_client_volume)(int);
-static int (*csd_client_mic_mute)(int);
-}
-#endif
-
-#define SAMPLE_RATE_8KHZ 8000
-
-
-#define BTSCO_RATE_16KHZ 16000
-#define USECASE_TYPE_RX 1
-#define USECASE_TYPE_TX 2
-#define MAX_HDMI_CHANNEL_CNT 6
-
-#define AFE_PROXY_PERIOD_SIZE 3072
-#define KILL_A2DP_THREAD 1
-#define SIGNAL_A2DP_THREAD 2
-#define PROXY_CAPTURE_DEVICE_NAME (const char *)("hw:0,8")
-namespace sys_close {
- ssize_t lib_close(int fd) {
- return close(fd);
- }
-};
-
-namespace android_audio_legacy
-{
-
-ALSADevice::ALSADevice() {
-#ifdef USES_FLUENCE_INCALL
- mDevSettingsFlag = TTY_OFF | DMIC_FLAG;
-#else
- mDevSettingsFlag = TTY_OFF;
-#endif
- mBtscoSamplerate = 8000;
- mCallMode = AUDIO_MODE_NORMAL;
- mInChannels = 0;
- char value[128], platform[128], baseband[128];
-
- property_get("persist.audio.handset.mic",value,"0");
- strlcpy(mMicType, value, sizeof(mMicType));
- property_get("persist.audio.fluence.mode",value,"0");
- if (!strcmp("broadside", value)) {
- mFluenceMode = FLUENCE_MODE_BROADSIDE;
- } else {
- mFluenceMode = FLUENCE_MODE_ENDFIRE;
- }
- property_get("ro.board.platform", platform, "");
- property_get("ro.baseband", baseband, "");
- if (!strcmp("msm8960", platform) && !strcmp("sglte", baseband)) {
- mIsSglte = true;
- }
- else {
- mIsSglte = false;
- }
- strlcpy(mCurRxUCMDevice, "None", sizeof(mCurRxUCMDevice));
- strlcpy(mCurTxUCMDevice, "None", sizeof(mCurTxUCMDevice));
-
- mMixer = mixer_open("/dev/snd/controlC0");
-
- mProxyParams.mExitRead = false;
- resetProxyVariables();
- mProxyParams.mCaptureBufferSize = AFE_PROXY_PERIOD_SIZE;
- mProxyParams.mCaptureBuffer = NULL;
- mProxyParams.mProxyState = proxy_params::EProxyClosed;
- mProxyParams.mProxyPcmHandle = NULL;
-
- ALOGD("ALSA module opened");
-}
-
-//static int s_device_close(hw_device_t* device)
-ALSADevice::~ALSADevice()
-{
- if (mMixer) mixer_close(mMixer);
- if(mProxyParams.mCaptureBuffer != NULL) {
- free(mProxyParams.mCaptureBuffer);
- mProxyParams.mCaptureBuffer = NULL;
- }
- mProxyParams.mProxyState = proxy_params::EProxyClosed;
-
-}
-
-bool ALSADevice::platform_is_Fusion3()
-{
- char platform[128], baseband[128];
- property_get("ro.board.platform", platform, "");
- property_get("ro.baseband", baseband, "");
- if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband))
- return true;
- else
- return false;
-}
-
-int ALSADevice::deviceName(alsa_handle_t *handle, unsigned flags, char **value)
-{
- int ret = 0;
- char ident[70];
-
- if (flags & PCM_IN) {
- strlcpy(ident, "CapturePCM/", sizeof(ident));
- } else {
- strlcpy(ident, "PlaybackPCM/", sizeof(ident));
- }
- strlcat(ident, handle->useCase, sizeof(ident));
- ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value);
- ALOGD("Device value returned is %s", (*value));
- return ret;
-}
-
-status_t ALSADevice::setHDMIChannelCount()
-{
- status_t err = NO_ERROR;
- int channel_count = 0;
- const char *channel_cnt_str = NULL;
- EDID_AUDIO_INFO info = { 0 };
-
- if (AudioUtil::getHDMIAudioSinkCaps(&info)) {
- for (int i = 0; i < info.nAudioBlocks && i < MAX_EDID_BLOCKS; i++) {
- if (info.AudioBlocksArray[i].nChannels > channel_count &&
- info.AudioBlocksArray[i].nChannels <= MAX_HDMI_CHANNEL_CNT) {
- channel_count = info.AudioBlocksArray[i].nChannels;
- }
- }
- }
-
- switch (channel_count) {
- case 6: channel_cnt_str = "Six"; break;
- case 5: channel_cnt_str = "Five"; break;
- case 4: channel_cnt_str = "Four"; break;
- case 3: channel_cnt_str = "Three"; break;
- default: channel_cnt_str = "Two"; break;
- }
- ALOGD("HDMI channel count: %s", channel_cnt_str);
- setMixerControl("HDMI_RX Channels", channel_cnt_str);
-
- return err;
-}
-
-status_t ALSADevice::setHardwareParams(alsa_handle_t *handle)
-{
- struct snd_pcm_hw_params *params;
- unsigned long bufferSize, reqBuffSize;
- unsigned int periodTime, bufferTime;
- unsigned int requestedRate = handle->sampleRate;
- int status = 0;
- int channels = handle->channels;
- status_t err;
- snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE;
- struct snd_compr_caps compr_cap;
- struct snd_compr_params compr_params;
- uint32_t codec_id = 0;
-
- ALOGD("handle->format: 0x%x", handle->format);
- if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL))) {
- ALOGV("Tunnel mode detected...");
- //get the list of codec supported by hardware
- if (ioctl(handle->handle->fd, SNDRV_COMPRESS_GET_CAPS, &compr_cap)) {
- ALOGE("SNDRV_COMPRESS_GET_CAPS, failed Error no %d \n", errno);
- err = -errno;
- return err;
- }
- if( handle->format == AUDIO_FORMAT_AAC ) {
- codec_id = get_compressed_format("AAC");
- ALOGV("### AAC CODEC codec_id %d",codec_id);
- }
- else if (handle->format == AUDIO_FORMAT_AMR_WB) {
- codec_id = get_compressed_format("AMR_WB");
- if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL))) {
- compr_params.codec.options.generic.reserved[0] = 8; /*band mode - 23.85 kbps*/
- compr_params.codec.options.generic.reserved[1] = 0; /*dtx mode - disable*/
- }
- ALOGV("### AMR WB CODEC codec_id %d",codec_id);
- }
-#ifdef QCOM_AUDIO_FORMAT_ENABLED
- else if (handle->format == AUDIO_FORMAT_AMR_WB_PLUS) {
- codec_id = get_compressed_format("AMR_WB_PLUS");
- ALOGV("### AMR WB+ CODEC codec_id %d",codec_id);
- }
-#endif
- else if (handle->format == AUDIO_FORMAT_MP3) {
- codec_id = get_compressed_format("MP3");
- ALOGV("### MP3 CODEC codec_id %d",codec_id);
- }
- else {
- return UNKNOWN_ERROR;
- }
- //find if codec_id matches with any of h/w supported codecs.
- for (int i = 0; i < compr_cap.num_codecs; i++) {
- if (compr_cap.codecs[i] == codec_id) {
- ALOGV("### MatchedFcodec_id %u", codec_id);
- compr_params.codec.id = codec_id;
- break;
- }
- }
- if (!compr_params.codec.id) {
- ALOGE("### Codec %u not supported",codec_id);
- return UNKNOWN_ERROR;
- }
-
- if (ioctl(handle->handle->fd, SNDRV_COMPRESS_SET_PARAMS, &compr_params)) {
- ALOGE("SNDRV_COMPRESS_SET_PARAMS,failed Error no %d \n", errno);
- err = -errno;
- return err;
- }
- }
-
- params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
- if (!params) {
- ALOGE("Failed to allocate ALSA hardware parameters!");
- return NO_INIT;
- }
-
- reqBuffSize = handle->bufferSize;
- ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d",
- (int) reqBuffSize, handle->channels, handle->sampleRate);
-
-#ifdef QCOM_SSR_ENABLED
- if (channels == 6) {
- if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, strlen(SND_USE_CASE_VERB_HIFI_REC_COMPRESSED))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
- ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
- channels = 4;
- }
- }
-#endif
-
- param_init(params);
- if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
- param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
- SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
- }
- else {
- param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
- SNDRV_PCM_ACCESS_RW_INTERLEAVED);
- }
-
- if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
- if (handle->format == AUDIO_FORMAT_AMR_NB
- || handle->format == AUDIO_FORMAT_AMR_WB
-#ifdef QCOM_AUDIO_FORMAT_ENABLED
- || handle->format == AUDIO_FORMAT_EVRC
- || handle->format == AUDIO_FORMAT_EVRCB
- || handle->format == AUDIO_FORMAT_EVRCWB
-#endif
- ) {
- if ((strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) &&
- (strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL)) &&
- (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)) &&
- (strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL)) &&
- (strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL)) &&
- (strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL)) &&
- (strcmp(handle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL)) &&
- (strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
- format = SNDRV_PCM_FORMAT_SPECIAL;
- ALOGW("setting format to SNDRV_PCM_FORMAT_SPECIAL");
- }
- }
- }
- //TODO: Add format setting for tunnel mode using the usecase.
- param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
- format);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
- SNDRV_PCM_SUBFORMAT_STD);
- param_set_int(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
- param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- channels * 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
- channels);
- param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
- param_set_hw_refine(handle->handle, params);
-
- if (param_set_hw_params(handle->handle, params)) {
- ALOGE("cannot set hw params");
- return NO_INIT;
- }
- param_dump(params);
-
- handle->handle->buffer_size = pcm_buffer_size(params);
- handle->handle->period_size = pcm_period_size(params);
- handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
- ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
- handle->handle->buffer_size, handle->handle->period_size,
- handle->handle->period_cnt);
- handle->handle->rate = handle->sampleRate;
- handle->handle->channels = handle->channels;
- handle->periodSize = handle->handle->period_size;
- if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
- strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED) &&
- strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
- strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED) &&
- (6 != handle->channels)) {
- //Do not update buffersize for 5.1 recording
- if (handle->format == AUDIO_FORMAT_AMR_WB &&
- format != SNDRV_PCM_FORMAT_SPECIAL) {
- ALOGV("### format AMWB, set bufsize to 61");
- handle->bufferSize = 61;
- } else {
- handle->bufferSize = handle->handle->period_size;
- }
- }
-
- return NO_ERROR;
-}
-
-status_t ALSADevice::setSoftwareParams(alsa_handle_t *handle)
-{
- struct snd_pcm_sw_params* params;
- struct pcm* pcm = handle->handle;
-
- unsigned long periodSize = pcm->period_size;
- int channels = handle->channels;
-
- params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
- if (!params) {
- LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
- return NO_INIT;
- }
-
-#ifdef QCOM_SSR_ENABLED
- if (channels == 6) {
- if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, strlen(SND_USE_CASE_VERB_HIFI_REC_COMPRESSED))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
- ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
- channels = 4;
- }
- }
-#endif
-
- // Get the current software parameters
- params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
- params->period_step = 1;
- if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
- (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
- ALOGV("setparam: start & stop threshold for Voip ");
- params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
- params->start_threshold = periodSize/2;
- params->stop_threshold = INT_MAX;
- } else {
- params->avail_min = periodSize/(channels * 2);
- params->start_threshold = periodSize/(channels * 2);
- params->stop_threshold = INT_MAX;
- }
- params->silence_threshold = 0;
- params->silence_size = 0;
-
- if (param_set_sw_params(handle->handle, params)) {
- ALOGE("cannot set sw params");
- return NO_INIT;
- }
- return NO_ERROR;
-}
-
-void ALSADevice::switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
-{
- const char **mods_list;
- use_case_t useCaseNode;
- unsigned usecase_type = 0;
- bool inCallDevSwitch = false;
- char *rxDevice, *txDevice, ident[70], *use_case = NULL;
- int err = 0, index, mods_size;
- int rx_dev_id, tx_dev_id;
- ALOGV("%s: device %#x mode:%d", __FUNCTION__, devices, mode);
-
- if ((mode == AUDIO_MODE_IN_CALL) || (mode == AUDIO_MODE_IN_COMMUNICATION)) {
- if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
- (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
- devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
- AudioSystem::DEVICE_IN_WIRED_HEADSET);
- } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
- devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
- AudioSystem::DEVICE_IN_BUILTIN_MIC);
- } else if ((devices & AudioSystem::DEVICE_OUT_EARPIECE) ||
- (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC)) {
- devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
- AudioSystem::DEVICE_OUT_EARPIECE);
- } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
- devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
- AudioSystem::DEVICE_OUT_SPEAKER);
- } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
- (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
- (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
- devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET |
- AudioSystem::DEVICE_OUT_BLUETOOTH_SCO);
-#ifdef QCOM_ANC_HEADSET_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
- (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
- devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET |
- AudioSystem::DEVICE_IN_ANC_HEADSET);
- } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) {
- devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE |
- AudioSystem::DEVICE_IN_BUILTIN_MIC);
-#endif
-#ifdef QCOM_USBAUDIO_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET ) ||
- (devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET )) {
- devices = devices | (AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET |
- AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET);
-#endif
- } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
- devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
- AudioSystem::DEVICE_IN_AUX_DIGITAL);
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
- (devices & AudioSystem::DEVICE_IN_PROXY)) {
- devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
- AudioSystem::DEVICE_IN_PROXY);
- } else if (devices & AudioSystem::DEVICE_OUT_ALL_A2DP) {
- devices = devices | (AudioSystem::DEVICE_IN_PROXY);
-#endif
- }
- }
-#ifdef QCOM_SSR_ENABLED
- if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
- if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, strlen(SND_USE_CASE_VERB_HIFI_REC_COMPRESSED))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
- ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
- setFlags(SSRQMIC_FLAG);
- }
- }
-#endif
-
- rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
- ALOGV("%s: rxDevice %s devices:0x%x", __FUNCTION__, rxDevice,devices);
- txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
- ALOGV("%s: txDevice:%s devices:0x%x", __FUNCTION__, txDevice,devices);
-
- if ((rxDevice != NULL) && (txDevice != NULL)) {
- if (((strncmp(rxDevice, mCurRxUCMDevice, MAX_STR_LEN)) ||
- (strncmp(txDevice, mCurTxUCMDevice, MAX_STR_LEN))) &&
- ((mode == AUDIO_MODE_IN_CALL) ||
- (mode == AUDIO_MODE_IN_COMMUNICATION)))
- inCallDevSwitch = true;
- }
-
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
- if (csd_disable_device == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
- } else {
- err = csd_disable_device();
- if (err < 0)
- {
- ALOGE("csd_client_disable_device, failed, error %d", err);
- }
- }
- }
-#endif
-
- snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
- mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
- if (rxDevice != NULL) {
- if ((strncmp(mCurRxUCMDevice, "None", 4)) &&
- ((strncmp(rxDevice, mCurRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
- if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE)))) {
- usecase_type = getUseCaseType(use_case);
- if (usecase_type & USECASE_TYPE_RX) {
- ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
- strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
- snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
- mUseCaseList.push_front(useCaseNode);
- }
- }
- if (mods_size) {
- for(index = 0; index < mods_size; index++) {
- usecase_type = getUseCaseType(mods_list[index]);
- if (usecase_type & USECASE_TYPE_RX) {
- ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
- strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
- snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
- mUseCaseList.push_back(useCaseNode);
- }
- }
- }
- snd_use_case_set(handle->ucMgr, "_disdev", mCurRxUCMDevice);
- }
- }
- if (txDevice != NULL) {
- if ((strncmp(mCurTxUCMDevice, "None", 4)) &&
- ((strncmp(txDevice, mCurTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
- if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE)))) {
- usecase_type = getUseCaseType(use_case);
- if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
- ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
- strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
- snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
- mUseCaseList.push_front(useCaseNode);
- }
- }
- if (mods_size) {
- for(index = 0; index < mods_size; index++) {
- usecase_type = getUseCaseType(mods_list[index]);
- if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
- ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
- strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
- snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
- mUseCaseList.push_back(useCaseNode);
- }
- }
- }
- snd_use_case_set(handle->ucMgr, "_disdev", mCurTxUCMDevice);
- }
- }
-
- ALOGV("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, mCurRxUCMDevice, mCurTxUCMDevice);
-
- if (rxDevice != NULL) {
- snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
- strlcpy(mCurRxUCMDevice, rxDevice, sizeof(mCurRxUCMDevice));
- }
- if (txDevice != NULL) {
- snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
- strlcpy(mCurTxUCMDevice, txDevice, sizeof(mCurTxUCMDevice));
- }
- for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
- ALOGD("Route use case %s\n", it->useCase);
- if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
- snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
- } else {
- snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
- }
- }
- if (!mUseCaseList.empty())
- mUseCaseList.clear();
- if (use_case != NULL) {
- free(use_case);
- use_case = NULL;
- }
-#ifdef QCOM_FM_ENABLED
- if (rxDevice != NULL) {
- if (devices & AudioSystem::DEVICE_OUT_FM)
- setFmVolume(mFmVolume);
- }
-#endif
- ALOGD("switchDevice: mCurTxUCMDevivce %s mCurRxDevDevice %s", mCurTxUCMDevice, mCurRxUCMDevice);
- if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
-
- /* get tx acdb id */
- memset(&ident,0,sizeof(ident));
- strlcpy(ident, "ACDBID/", sizeof(ident));
- strlcat(ident, mCurTxUCMDevice, sizeof(ident));
- tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
-
- /* get rx acdb id */
- memset(&ident,0,sizeof(ident));
- strlcpy(ident, "ACDBID/", sizeof(ident));
- strlcat(ident, mCurRxUCMDevice, sizeof(ident));
- rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
-
- if (rx_dev_id == DEVICE_SPEAKER_RX_ACDB_ID && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
- tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
- }
-
-#ifdef QCOM_CSDCLIENT_ENABLED
- ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
- if (csd_enable_device == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_enable_device", dlerror());
- } else {
- err = csd_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag);
- if (err < 0)
- {
- ALOGE("csd_client_disable_device failed, error %d", err);
- }
- }
-#endif
- }
-
- if (rxDevice != NULL) {
- free(rxDevice);
- rxDevice = NULL;
- }
- if (txDevice != NULL) {
- free(txDevice);
- txDevice = NULL;
- }
-}
-
-// ----------------------------------------------------------------------------
-/*
-status_t ALSADevice::init(alsa_device_t *module, ALSAHandleList &list)
-{
- ALOGD("s_init: Initializing devices for ALSA module");
-
- list.clear();
-
- return NO_ERROR;
-}
-*/
-status_t ALSADevice::open(alsa_handle_t *handle)
-{
- char *devName = NULL;
- unsigned flags = 0;
- int err = NO_ERROR;
-
- if(handle->devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
- err = setHDMIChannelCount();
- if(err != OK) {
- ALOGE("setHDMIChannelCount err = %d", err);
- return err;
- }
- }
- close(handle);
-
- ALOGD("open: handle %p, format 0x%x", handle, handle->format);
-
- // ASoC multicomponent requires a valid path (frontend/backend) for
- // the device to be opened
-
- // The PCM stream is opened in blocking mode, per ALSA defaults. The
- // AudioFlinger seems to assume blocking mode too, so asynchronous mode
- // should not be used.
- if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
- ALOGV("LPA/tunnel use case");
- flags |= PCM_MMAP;
- flags |= DEBUG_ON;
- } else if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI2)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) {
- ALOGV("Music case");
- flags = PCM_OUT;
- } else {
- flags = PCM_IN;
- }
-
- if (handle->channels == 1) {
- flags |= PCM_MONO;
- }
-#ifdef QCOM_SSR_ENABLED
- else if (handle->channels == 4 ) {
- flags |= PCM_QUAD;
- } else if (handle->channels == 6 ) {
- if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, strlen(SND_USE_CASE_VERB_HIFI_REC_COMPRESSED))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
- flags |= PCM_QUAD;
- } else {
- flags |= PCM_5POINT1;
- }
- }
-#endif
- else {
- flags |= PCM_STEREO;
- }
-
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node: %s", devName);
- return NO_INIT;
- }
- if (devName != NULL) {
- ALOGV("flags %x, devName %s",flags,devName);
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- ALOGV("pcm_open returned fd %d", handle->handle->fd);
-
- if (!handle->handle || (handle->handle->fd < 0)) {
- ALOGE("open: Failed to initialize ALSA device '%s'", devName);
- if (devName) {
- free(devName);
- devName = NULL;
- }
- return NO_INIT;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
-
- if (err == NO_ERROR) {
- err = setSoftwareParams(handle);
- }
-
- if(err != NO_ERROR) {
- ALOGE("Set HW/SW params failed: Closing the pcm stream");
- standby(handle);
- free(devName);
- devName = NULL;
- return err;
- }
-
- if (devName) {
- free(devName);
- devName = NULL;
- }
- return NO_ERROR;
-}
-
-status_t ALSADevice::startVoipCall(alsa_handle_t *handle)
-{
-
- char* devName = NULL;
- unsigned flags = 0;
- int err = NO_ERROR;
- uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE];
-
- close(handle);
- flags = PCM_OUT;
- flags |= PCM_MONO;
- ALOGV("startVoipCall handle %p", handle);
-
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
-
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
-
- if (!handle->handle || (handle->handle->fd < 0)) {
- if (devName) {
- free(devName);
- devName = NULL;
- }
- ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
- return NO_INIT;
- }
-
- if (!pcm_ready(handle->handle)) {
- ALOGE(" pcm ready failed");
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
-
- if (err == NO_ERROR) {
- err = setSoftwareParams(handle);
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("startVoipCall: pcm_prepare failed");
- }
-
- /* first write required start dsp */
- memset(&voc_pkt,0,sizeof(voc_pkt));
- pcm_write(handle->handle,&voc_pkt,handle->handle->period_size);
- handle->rxHandle = handle->handle;
- if (devName) {
- free(devName);
- devName = NULL;
- }
- ALOGV("s_open: DEVICE_IN_COMMUNICATION ");
- flags = PCM_IN;
- flags |= PCM_MONO;
- handle->handle = 0;
-
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
-
- if (!handle->handle) {
- if (devName) {
- free(devName);
- devName = NULL;
- }
- ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
- return NO_INIT;
- }
-
- if (!pcm_ready(handle->handle)) {
- ALOGE(" pcm ready in failed");
- }
-
- handle->handle->flags = flags;
-
- err = setHardwareParams(handle);
-
- if (err == NO_ERROR) {
- err = setSoftwareParams(handle);
- }
-
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed");
- }
-
- /* first read required start dsp */
- memset(&voc_pkt,0,sizeof(voc_pkt));
- pcm_read(handle->handle,&voc_pkt,handle->handle->period_size);
- if (devName) {
- free(devName);
- devName = NULL;
- }
- return NO_ERROR;
-}
-
-status_t ALSADevice::startVoiceCall(alsa_handle_t *handle)
-{
- char* devName = NULL;
- unsigned flags = 0;
- int err = NO_ERROR;
-
- ALOGD("startVoiceCall: handle %p", handle);
- // ASoC multicomponent requires a valid path (frontend/backend) for
- // the device to be opened
-
- flags = PCM_OUT | PCM_MONO;
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
-
- if (!handle->handle || (handle->handle->fd < 0)) {
- ALOGE("startVoiceCall: could not open PCM device");
- goto Error;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("startVoiceCall: setHardwareParams failed");
- goto Error;
- }
-
- err = setSoftwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("startVoiceCall: setSoftwareParams failed");
- goto Error;
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("startVoiceCall: pcm_prepare failed");
- goto Error;
- }
-
- if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("startVoiceCall:SNDRV_PCM_IOCTL_START failed\n");
- goto Error;
- }
-
- // Store the PCM playback device pointer in rxHandle
- handle->rxHandle = handle->handle;
- if (devName) {
- free(devName);
- devName = NULL;
- }
-
- // Open PCM capture device
- flags = PCM_IN | PCM_MONO;
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- goto Error;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (!handle->handle || (handle->handle->fd < 0)) {
- free(devName);
- goto Error;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("startVoiceCall: setHardwareParams failed");
- goto Error;
- }
-
- err = setSoftwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("startVoiceCall: setSoftwareParams failed");
- goto Error;
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("startVoiceCall: pcm_prepare failed");
- goto Error;
- }
-
- if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("startVoiceCall:SNDRV_PCM_IOCTL_START failed\n");
- goto Error;
- }
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_start_voice == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_start_voice", dlerror());
- } else {
- err = csd_start_voice();
- if (err < 0){
- ALOGE("s_start_voice_call: csd_client error %d\n", err);
- goto Error;
- }
- }
-#endif
- }
-
- if (devName) {
- free(devName);
- devName = NULL;
- }
- return NO_ERROR;
-
-Error:
- ALOGE("startVoiceCall: Failed to initialize ALSA device '%s'", devName);
- if (devName) {
- free(devName);
- devName = NULL;
- }
- close(handle);
- return NO_INIT;
-}
-
-status_t ALSADevice::startFm(alsa_handle_t *handle)
-{
- char *devName = NULL;
- unsigned flags = 0;
- int err = NO_ERROR;
-
- ALOGV("startFm: handle %p", handle);
-
- // ASoC multicomponent requires a valid path (frontend/backend) for
- // the device to be opened
-
- flags = PCM_OUT | PCM_STEREO;
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- goto Error;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (!handle->handle || (handle->handle->fd < 0)) {
- ALOGE("startFm: could not open PCM device");
- goto Error;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("startFm: setHardwareParams failed");
- goto Error;
- }
-
- err = setSoftwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("startFm: setSoftwareParams failed");
- goto Error;
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("startFm: setSoftwareParams failed");
- goto Error;
- }
-
- if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("startFm: SNDRV_PCM_IOCTL_START failed\n");
- goto Error;
- }
-
- // Store the PCM playback device pointer in rxHandle
- handle->rxHandle = handle->handle;
- if (devName) {
- free(devName);
- devName = NULL;
- }
-
- // Open PCM capture device
- flags = PCM_IN | PCM_STEREO;
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- goto Error;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (!handle->handle) {
- goto Error;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("startFm: setHardwareParams failed");
- goto Error;
- }
-
- err = setSoftwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("startFm: setSoftwareParams failed");
- goto Error;
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("startFm: pcm_prepare failed");
- goto Error;
- }
-
- if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("startFm: SNDRV_PCM_IOCTL_START failed\n");
- goto Error;
- }
-
-
- setFmVolume(mFmVolume);
- if (devName) {
- free(devName);
- devName = NULL;
- }
- return NO_ERROR;
-
-Error:
- if (devName) {
- free(devName);
- devName = NULL;
- }
- close(handle);
- return NO_INIT;
-}
-
-status_t ALSADevice::setFmVolume(int value)
-{
- status_t err = NO_ERROR;
-
- setMixerControl("Internal FM RX Volume",value,0);
- mFmVolume = value;
-
- return err;
-}
-
-status_t ALSADevice::setLpaVolume(int value)
-{
- status_t err = NO_ERROR;
-
- setMixerControl("LPA RX Volume",value,0);
-
- return err;
-}
-
-status_t ALSADevice::start(alsa_handle_t *handle)
-{
- status_t err = NO_ERROR;
-
- if(!handle->handle) {
- ALOGE("No active PCM driver to start");
- return err;
- }
-
- err = pcm_prepare(handle->handle);
-
- return err;
-}
-
-status_t ALSADevice::close(alsa_handle_t *handle)
-{
- int ret;
- status_t err = NO_ERROR;
- struct pcm *h = handle->rxHandle;
-
- handle->rxHandle = 0;
- ALOGD("close: handle %p h %p", handle, h);
- if (h) {
- if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) ||
- !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) &&
- platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_stop_voice == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
- } else {
- err = csd_stop_voice();
- if (err < 0) {
- ALOGE("s_close: csd_client error %d\n", err);
- }
- }
-#endif
- }
- ALOGV("close rxHandle\n");
- err = pcm_close(h);
- if(err != NO_ERROR) {
- ALOGE("close: pcm_close failed for rxHandle with err %d", err);
- }
- }
-
- h = handle->handle;
- handle->handle = 0;
-
- if (h) {
- ALOGV("close handle h %p\n", h);
- err = pcm_close(h);
- if(err != NO_ERROR) {
- ALOGE("close: pcm_close failed for handle with err %d", err);
- }
- disableDevice(handle);
- }
-
- return err;
-}
-
-/*
- this is same as s_close, but don't discard
- the device/mode info. This way we can still
- close the device, hit idle and power-save, reopen the pcm
- for the same device/mode after resuming
-*/
-status_t ALSADevice::standby(alsa_handle_t *handle)
-{
- int ret;
- status_t err = NO_ERROR;
- struct pcm *h = handle->rxHandle;
- handle->rxHandle = 0;
- ALOGD("standby: handle %p h %p", handle, h);
- if (h) {
- ALOGV("standby rxHandle\n");
- err = pcm_close(h);
- if(err != NO_ERROR) {
- ALOGE("standby: pcm_close failed for rxHandle with err %d", err);
- }
- }
-
- h = handle->handle;
- handle->handle = 0;
-
- if (h) {
- ALOGV("standby handle h %p\n", h);
- err = pcm_close(h);
- if(err != NO_ERROR) {
- ALOGE("standby: pcm_close failed for handle with err %d", err);
- }
- disableDevice(handle);
- }
-
- return err;
-}
-
-status_t ALSADevice::route(alsa_handle_t *handle, uint32_t devices, int mode)
-{
- status_t status = NO_ERROR;
-
- ALOGD("route: devices 0x%x in mode %d", devices, mode);
- mCallMode = mode;
- switchDevice(handle, devices, mode);
- return status;
-}
-
-int ALSADevice::getUseCaseType(const char *useCase)
-{
- ALOGV("use case is %s\n", useCase);
- if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
- MAX_LEN(useCase, SND_USE_CASE_VERB_HIFI2)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI2)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
- MAX_LEN(useCase,SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
- MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LPA)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_FM))) {
- return USECASE_TYPE_RX;
- } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED,
- MAX_LEN(useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_FM_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_FM_A2DP_REC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_FM)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
- MAX_LEN(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED,
- MAX_LEN(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
- return USECASE_TYPE_TX;
- } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_VOICECALL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_IP_VOICECALL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_DL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_UL_DL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_INCALL_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_INCALL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOICE)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
- MAX_LEN(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_SGLTECALL,
- MAX_LEN(useCase, SND_USE_CASE_VERB_SGLTECALL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_SGLTE,
- MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_SGLTE)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
- MAX_LEN(useCase,SND_USE_CASE_VERB_VOLTE)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
- MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_VOLTE))) {
- return (USECASE_TYPE_RX | USECASE_TYPE_TX);
- } else {
- ALOGV("unknown use case %s\n", useCase);
- return 0;
- }
-}
-
-void ALSADevice::disableDevice(alsa_handle_t *handle)
-{
- unsigned usecase_type = 0;
- int i, mods_size;
- char *useCase;
- const char **mods_list;
-
- snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
- if (useCase != NULL) {
- if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
- snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
- } else {
- snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
- }
- free(useCase);
- snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
- if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE)))
- usecase_type |= getUseCaseType(useCase);
- mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
- ALOGV("Number of modifiers %d\n", mods_size);
- if (mods_size) {
- for(i = 0; i < mods_size; i++) {
- ALOGV("index %d modifier %s\n", i, mods_list[i]);
- usecase_type |= getUseCaseType(mods_list[i]);
- }
- }
- ALOGV("usecase_type is %d\n", usecase_type);
- if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(mCurTxUCMDevice, "None", 4)))
- snd_use_case_set(handle->ucMgr, "_disdev", mCurTxUCMDevice);
- if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(mCurRxUCMDevice, "None", 4)))
- snd_use_case_set(handle->ucMgr, "_disdev", mCurRxUCMDevice);
- } else {
- ALOGE("Invalid state, no valid use case found to disable");
- }
- free(useCase);
-}
-
-char *ALSADevice::getUCMDeviceFromAcdbId(int acdb_id)
-{
- switch(acdb_id) {
- case DEVICE_HANDSET_RX_ACDB_ID:
- return strdup(SND_USE_CASE_DEV_HANDSET);
- case DEVICE_SPEAKER_RX_ACDB_ID:
- return strdup(SND_USE_CASE_DEV_SPEAKER);
- case DEVICE_HEADSET_RX_ACDB_ID:
- return strdup(SND_USE_CASE_DEV_HEADPHONES);
- case DEVICE_TTY_HEADSET_MONO_RX_ACDB_ID:
- return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
- case DEVICE_ANC_HEADSET_STEREO_RX_ACDB_ID:
- return strdup(SND_USE_CASE_DEV_ANC_HEADSET);
- default:
- return NULL;
- }
-}
-
-char* ALSADevice::getUCMDevice(uint32_t devices, int input, char *rxDevice)
-{
- if (!input) {
- ALOGV("getUCMDevice for output device: devices:%x is input device:%d",devices,input);
- if (!(mDevSettingsFlag & TTY_OFF) &&
- (mCallMode == AUDIO_MODE_IN_CALL) &&
- ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET)
- || (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)
-#ifdef QCOM_ANC_HEADSET_ENABLED
- || (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET)
- || (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)
-#endif
- )) {
- if (mDevSettingsFlag & TTY_VCO) {
- return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
- } else if (mDevSettingsFlag & TTY_FULL) {
- return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
- } else if (mDevSettingsFlag & TTY_HCO) {
- return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
- }
- } else if (devices & AudioSystem::DEVICE_OUT_ALL_A2DP &&
- devices & AudioSystem::DEVICE_OUT_SPEAKER) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER);
- } else if (devices & AudioSystem::DEVICE_OUT_ALL_A2DP) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX);
- } else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET ||
- devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET) &&
- devices & AudioSystem::DEVICE_OUT_SPEAKER) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER); /* PROXY RX */
- } else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) {
- return strdup(SND_USE_CASE_DEV_USB_PROXY_RX); /* PROXY RX */
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- } else if( (devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- (devices & AudioSystem::DEVICE_OUT_PROXY) &&
- ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) ) ) {
- if (mDevSettingsFlag & ANC_FLAG) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER_ANC_HEADSET);
- } else {
- return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER_HEADSET);
- }
-#endif
- } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
- if (mDevSettingsFlag & ANC_FLAG) {
- return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
- } else {
- return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
- }
- } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- ((devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL))) {
- return strdup(SND_USE_CASE_DEV_HDMI_SPEAKER);
-#ifdef QCOM_ANC_HEADSET_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) &&
- ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET)||
- (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) ) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX_ANC_HEADSET);
- } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
- return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
-#endif
-#ifdef QCOM_FM_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
- return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
-#endif
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- (devices & AudioSystem::DEVICE_OUT_PROXY)) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX_SPEAKER); /* COMBO SPEAKER + PROXY RX */
- } else if ((devices & AudioSystem::DEVICE_OUT_EARPIECE) &&
- (devices & AudioSystem::DEVICE_OUT_PROXY)) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX_HANDSET); /* COMBO EARPIECE + PROXY RX */
-#endif
- } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
- if (mCallMode == AUDIO_MODE_IN_CALL ||
- mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
- return strdup(SND_USE_CASE_DEV_VOC_EARPIECE); /* Voice HANDSET RX */
- } else {
- return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
- }
- } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
- return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
- } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
- if (mDevSettingsFlag & ANC_FLAG) {
- if (mCallMode == AUDIO_MODE_IN_CALL ||
- mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
- return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
- } else {
- return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
- }
- } else {
- if (mCallMode == AUDIO_MODE_IN_CALL ||
- mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
- return strdup(SND_USE_CASE_DEV_VOC_HEADPHONE); /* Voice HEADSET RX */
- } else {
- return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */
- }
- }
-#ifdef QCOM_ANC_HEADSET_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) &&
- ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
- if (mDevSettingsFlag & ANC_FLAG) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX_ANC_HEADSET);
- } else {
- return strdup(SND_USE_CASE_DEV_PROXY_RX_HEADSET);
- }
- } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
- if (mCallMode == AUDIO_MODE_IN_CALL ||
- mCallMode == AUDIO_MODE_IN_COMMUNICATION) {
- return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
- } else {
- return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
- }
-#endif
- } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
- (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
- if (mBtscoSamplerate == BTSCO_RATE_16KHZ)
- return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
- else
- return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
- } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
- return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
-#endif
-#ifdef QCOM_FM_TX_ENABLED
- } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
- return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
-#endif
- } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
- return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
- } else {
- ALOGD("No valid output device: %u", devices);
- }
- } else {
- ALOGV("getUCMDevice for input device: devices:%x is input device:%d",devices,input);
- if (!(mDevSettingsFlag & TTY_OFF) &&
- (mCallMode == AUDIO_MODE_IN_CALL) &&
- ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)
-#ifdef QCOM_ANC_HEADSET_ENABLED
- || (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)
-#endif
- )) {
- if (mDevSettingsFlag & TTY_HCO) {
- return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
- } else if (mDevSettingsFlag & TTY_FULL) {
- return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
- } else if (mDevSettingsFlag & TTY_VCO) {
- if (!strncmp(mMicType, "analog", 6)) {
- return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
- } else {
- return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
- }
- }
- } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
- if (!strncmp(mMicType, "analog", 6)) {
- return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
- } else {
- if ((mDevSettingsFlag & DMIC_FLAG) && (mInChannels == 1)) {
-#ifdef USES_FLUENCE_INCALL
- if(callMode == AUDIO_MODE_IN_CALL) {
- if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
- } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
- } else {
- return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
- }
- }
-#else
- if (((rxDevice != NULL) &&
- !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
- (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
- ((rxDevice == NULL) &&
- !strncmp(mCurRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
- (strlen(SND_USE_CASE_DEV_SPEAKER)+1)))) {
- if (mFluenceMode == FLUENCE_MODE_ENDFIRE) {
- if (mIsSglte == false) {
- return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
- }
- else {
- return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE_SGLTE); /* DUALMIC EF TX */
- }
- } else if (mFluenceMode == FLUENCE_MODE_BROADSIDE) {
- return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
- }
- } else {
- if (mFluenceMode == FLUENCE_MODE_ENDFIRE) {
- if (mIsSglte == false) {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
- }
- else {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE_SGLTE); /* DUALMIC EF TX */
- }
- } else if (mFluenceMode == FLUENCE_MODE_BROADSIDE) {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
- }
- }
-#endif
- } else if ((mDevSettingsFlag & DMIC_FLAG) && (mInChannels > 1)) {
- if (((rxDevice != NULL) &&
- !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
- (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
- ((rxDevice == NULL) &&
- !strncmp(mCurRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
- (strlen(SND_USE_CASE_DEV_SPEAKER)+1)))) {
- if (mIsSglte == false) {
- return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_STEREO); /* DUALMIC EF TX */
- }
- else {
- return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_STEREO_SGLTE); /* DUALMIC EF TX */
- }
- } else {
- if (mIsSglte == false) {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_HANDSET_STEREO); /* DUALMIC EF TX */
- }
- else {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_HANDSET_STEREO_SGLTE); /* DUALMIC EF TX */
- }
- }
- } else if ((mDevSettingsFlag & QMIC_FLAG) && (mInChannels == 1)) {
- if (((rxDevice != NULL) &&
- !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
- (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
- ((rxDevice == NULL) &&
- !strncmp(mCurRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
- (strlen(SND_USE_CASE_DEV_SPEAKER)+1)))) {
- return strdup(SND_USE_CASE_DEV_QUAD_MIC); /* QUADMIC TX */
- } else {
- return strdup(SND_USE_CASE_DEV_LINE);
- }
- }
-#ifdef QCOM_SSR_ENABLED
- else if ((mDevSettingsFlag & QMIC_FLAG) && (mInChannels > 1)) {
- return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC);
- } else if ((mDevSettingsFlag & SSRQMIC_FLAG) && (mInChannels > 1)){
- ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
- // Mapping for quad mic input device.
- return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
- }
-#endif
-#ifdef SEPERATED_AUDIO_INPUT
- if(mInput_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
- return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */
- }
-#endif
- else {
- return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
- }
- }
- } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
- return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
- } else if ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
- return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
-#ifdef QCOM_ANC_HEADSET_ENABLED
- } else if (devices & AudioSystem::DEVICE_IN_ANC_HEADSET) {
- return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
-#endif
- } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
- if (mBtscoSamplerate == BTSCO_RATE_16KHZ)
- return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
- else
- return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
-#ifdef QCOM_USBAUDIO_ENABLED
- } else if (devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) {
- if ((mCallMode == AUDIO_MODE_IN_CALL) ||
- (mCallMode == AUDIO_MODE_IN_COMMUNICATION)) {
- if ((rxDevice != NULL) &&
- (!strncmp(rxDevice, SND_USE_CASE_DEV_USB_PROXY_RX,
- (strlen(SND_USE_CASE_DEV_USB_PROXY_RX)+1)))) {
- return strdup(SND_USE_CASE_DEV_USB_PROXY_TX); /* USB PROXY TX */
- } else if ((rxDevice != NULL) &&
- (!strncmp(rxDevice, SND_USE_CASE_DEV_PROXY_RX,
- (strlen(SND_USE_CASE_DEV_PROXY_RX)+1)))) {
- return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
- } else {
- return strdup(SND_USE_CASE_DEV_USB_PROXY_TX); /* USB PROXY TX */
- }
- } else {
- return strdup(SND_USE_CASE_DEV_USB_PROXY_TX); /* USB PROXY TX */
- }
-#endif
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- } else if (devices & AudioSystem::DEVICE_IN_PROXY) {
- return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
-#endif
- } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
- (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
- /* Nothing to be done, use current active device */
- if (strncmp(mCurTxUCMDevice, "None", 4)) {
- return strdup(mCurTxUCMDevice);
- }
-#ifdef QCOM_FM_ENABLED
- } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
- (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
- /* Nothing to be done, use current tx device or set dummy device */
- if (strncmp(mCurTxUCMDevice, "None", 4)) {
- return strdup(mCurTxUCMDevice);
- } else {
- return strdup(SND_USE_CASE_DEV_DUMMY_TX);
- }
-#endif
- } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
- (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
- ALOGI("No proper mapping found with UCM device list, setting default");
- if (!strncmp(mMicType, "analog", 6)) {
- return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
- } else {
-#ifdef SEPERATED_AUDIO_INPUT
- if (callMode == AUDIO_MODE_IN_CALL) {
- return strdup(SND_USE_CASE_DEV_VOC_LINE); /* Voice BUILTIN-MIC TX */
- } else if(mInput_source == AUDIO_SOURCE_CAMCORDER) {
- return strdup(SND_USE_CASE_DEV_CAMCORDER_TX ); /* CAMCORDER TX */
- } else
-#endif
- return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
- }
- } else {
- ALOGD("No valid input device: %u", devices);
- }
- }
- return NULL;
-}
-
-void ALSADevice::setVoiceVolume(int vol)
-{
- int err = 0;
- ALOGD("setVoiceVolume: volume %d", vol);
- setMixerControl("Voice Rx Volume", vol, 0);
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_volume == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_volume", dlerror());
- } else {
- err = csd_volume(vol);
- if (err < 0) {
- ALOGE("s_set_voice_volume: csd_client error %d", err);
- }
- }
-#endif
- }
-}
-
-void ALSADevice::setSGLTEVolume(int vol)
-{
- int err = 0;
- ALOGD("setSGLTEVolume: volume %d", vol);
- setMixerControl("SGLTE Rx Volume", vol, 0);
-
- if (platform_is_Fusion3()) {
- err = csd_client_volume(vol);
- if (err < 0) {
- ALOGE("setSGLTEVolume: csd_client error %d", err);
- }
- }
-}
-
-void ALSADevice::setVoLTEVolume(int vol)
-{
- ALOGD("setVoLTEVolume: volume %d", vol);
- setMixerControl("VoLTE Rx Volume", vol, 0);
-}
-
-
-void ALSADevice::setVoipVolume(int vol)
-{
- ALOGD("setVoipVolume: volume %d", vol);
- setMixerControl("Voip Rx Volume", vol, 0);
-}
-
-void ALSADevice::setMicMute(int state)
-{
- int err = 0;
- ALOGD("setMicMute: state %d", state);
- setMixerControl("Voice Tx Mute", state, 0);
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_mic_mute == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_mic_mute", dlerror());
- } else {
- err=csd_mic_mute(state);
- if (err < 0) {
- ALOGE("s_set_mic_mute: csd_client error %d", err);
- }
- }
-#endif
- }
-}
-
-void ALSADevice::setSGLTEMicMute(int state)
-{
- int err = 0;
- ALOGD("setSGLTEMicMute: state %d", state);
- setMixerControl("SGLTE Tx Mute", state, 0);
-
- if (platform_is_Fusion3()) {
- err = csd_client_mic_mute(state);
- if (err < 0) {
- ALOGE("setSGLTEMicMute: csd_client error %d", err);
- }
- }
-}
-
-void ALSADevice::setVoLTEMicMute(int state)
-{
- ALOGD("setVolteMicMute: state %d", state);
- setMixerControl("VoLTE Tx Mute", state, 0);
-}
-
-void ALSADevice::setVoipMicMute(int state)
-{
- ALOGD("setVoipMicMute: state %d", state);
- setMixerControl("Voip Tx Mute", state, 0);
-}
-
-void ALSADevice::setVoipConfig(int mode, int rate)
-{
- ALOGD("setVoipConfig: mode %d,rate %d", mode, rate);
- char** setValues;
- setValues = (char**)malloc(2*sizeof(char*));
- if (setValues == NULL) {
- return;
- }
- setValues[0] = (char*)malloc(4*sizeof(char));
- if (setValues[0] == NULL) {
- free(setValues);
- return;
- }
-
- setValues[1] = (char*)malloc(8*sizeof(char));
- if (setValues[1] == NULL) {
- free(setValues);
- free(setValues[0]);
- return;
- }
-
- sprintf(setValues[0], "%d",mode);
- sprintf(setValues[1], "%d",rate);
-
- setMixerControlExt("Voip Mode Rate Config", 2, setValues);
- free(setValues[1]);
- free(setValues[0]);
- free(setValues);
- return;
-}
-
-void ALSADevice::setBtscoRate(int rate)
-{
- mBtscoSamplerate = rate;
-}
-
-void ALSADevice::enableWideVoice(bool flag)
-{
- int err = 0;
-
- ALOGD("enableWideVoice: flag %d", flag);
- if(flag == true) {
- setMixerControl("Widevoice Enable", 1, 0);
- } else {
- setMixerControl("Widevoice Enable", 0, 0);
- }
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_wide_voice == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_wide_voice", dlerror());
- } else {
- err = csd_wide_voice(flag);
- if (err < 0) {
- ALOGE("enableWideVoice: csd_client_wide_voice error %d", err);
- }
- }
-#endif
- }
-}
-
-void ALSADevice::setVocRecMode(uint8_t mode)
-{
- ALOGD("setVocRecMode: mode %d", mode);
- setMixerControl("Incall Rec Mode", mode, 0);
-}
-
-void ALSADevice::enableFENS(bool flag)
-{
- int err = 0;
-
- ALOGD("enableFENS: flag %d", flag);
- if(flag == true) {
- setMixerControl("FENS Enable", 1, 0);
- } else {
- setMixerControl("FENS Enable", 0, 0);
- }
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_fens == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_fens", dlerror());
- } else {
- err = csd_fens(flag);
- if (err < 0) {
- ALOGE("s_enable_fens: csd_client error %d", err);
- }
- }
-#endif
- }
-}
-
-void ALSADevice::enableSlowTalk(bool flag)
-{
- int err = 0;
-
- ALOGD("enableSlowTalk: flag %d", flag);
- if(flag == true) {
- setMixerControl("Slowtalk Enable", 1, 0);
- } else {
- setMixerControl("Slowtalk Enable", 0, 0);
- }
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_slow_talk == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_slow_talk", dlerror());
- } else {
- err = csd_slow_talk(flag);
- if (err < 0) {
- ALOGE("s_enable_slow_talk: csd_client error %d", err);
- }
- }
-#endif
- }
-}
-
-void ALSADevice::setFlags(uint32_t flags)
-{
- ALOGV("setFlags: flags %d", flags);
- mDevSettingsFlag = flags;
-}
-
-status_t ALSADevice::setCompressedVolume(int value)
-{
- status_t err = NO_ERROR;
-
- setMixerControl("COMPRESSED RX Volume",value,0);
-
- return err;
-}
-
-status_t ALSADevice::getMixerControl(const char *name, unsigned int &value, int index)
-{
- struct mixer_ctl *ctl;
-
- if (!mMixer) {
- ALOGE("Control not initialized");
- return NO_INIT;
- }
-
- ctl = mixer_get_control(mMixer, name, index);
- if (!ctl)
- return BAD_VALUE;
-
- mixer_ctl_get(ctl, &value);
- return NO_ERROR;
-}
-
-status_t ALSADevice::setMixerControl(const char *name, unsigned int value, int index)
-{
- struct mixer_ctl *ctl;
- int ret = 0;
- ALOGD("setMixerControl:: name %s value %d index %d", name, value, index);
- if (!mMixer) {
- ALOGE("Control not initialized");
- return NO_INIT;
- }
-
- // ToDo: Do we need to send index here? Right now it works with 0
- ctl = mixer_get_control(mMixer, name, 0);
- if(ctl == NULL) {
- ALOGE("Could not get the mixer control");
- return BAD_VALUE;
- }
- ret = mixer_ctl_set(ctl, value);
- return (ret < 0) ? BAD_VALUE : NO_ERROR;
-}
-
-status_t ALSADevice::setMixerControl(const char *name, const char *value)
-{
- struct mixer_ctl *ctl;
- int ret = 0;
- ALOGD("setMixerControl:: name %s value %s", name, value);
-
- if (!mMixer) {
- ALOGE("Control not initialized");
- return NO_INIT;
- }
-
- ctl = mixer_get_control(mMixer, name, 0);
- if(ctl == NULL) {
- ALOGE("Could not get the mixer control");
- return BAD_VALUE;
- }
- ret = mixer_ctl_select(ctl, value);
- return (ret < 0) ? BAD_VALUE : NO_ERROR;
-}
-
-status_t ALSADevice::setMixerControlExt(const char *name, int count, char **setValues)
-{
- struct mixer_ctl *ctl;
- int ret = 0;
- ALOGD("setMixerControl:: name %s count %d", name, count);
- if (!mMixer) {
- ALOGE("Control not initialized");
- return NO_INIT;
- }
-
- // ToDo: Do we need to send index here? Right now it works with 0
- ctl = mixer_get_control(mMixer, name, 0);
- if(ctl == NULL) {
- ALOGE("Could not get the mixer control");
- return BAD_VALUE;
- }
- ret = mixer_ctl_set_value(ctl, count, setValues);
- return (ret < 0) ? BAD_VALUE : NO_ERROR;
-}
-
-status_t ALSADevice::setEcrxDevice(char *device)
-{
- status_t err = NO_ERROR;
- setMixerControl("EC_REF_RX", device);
- return err;
-}
-
-void ALSADevice::setInChannels(int channels)
-{
- mInChannels = channels;
- ALOGV("mInChannels:%d", mInChannels);
-}
-
-status_t ALSADevice::exitReadFromProxy()
-{
- ALOGV("exitReadFromProxy");
- mProxyParams.mExitRead = true;
- if(mProxyParams.mPfdProxy[1].fd != -1) {
- uint64_t writeValue = KILL_A2DP_THREAD;
- ALOGD("Writing to mPfdProxy[1].fd %d",mProxyParams.mPfdProxy[1].fd);
- write(mProxyParams.mPfdProxy[1].fd, &writeValue, sizeof(uint64_t));
- }
- return NO_ERROR;
-}
-
-void ALSADevice::resetProxyVariables() {
-
- mProxyParams.mAvail = 0;
- mProxyParams.mFrames = 0;
- mProxyParams.mX.frames = 0;
- if(mProxyParams.mPfdProxy[1].fd != -1) {
- sys_close::lib_close(mProxyParams.mPfdProxy[1].fd);
- mProxyParams.mPfdProxy[1].fd = -1;
- }
-}
-
-ssize_t ALSADevice::readFromProxy(void **captureBuffer , ssize_t *bufferSize) {
-
- status_t err = NO_ERROR;
- int err_poll = 0;
- initProxyParams();
- err = startProxy();
- if(err) {
- ALOGE("ReadFromProxy-startProxy returned err = %d", err);
- *captureBuffer = NULL;
- *bufferSize = 0;
- return err;
- }
- struct pcm * capture_handle = (struct pcm *)mProxyParams.mProxyPcmHandle;
-
- while(!mProxyParams.mExitRead) {
- ALOGV("Calling sync_ptr(proxy");
- err = sync_ptr(capture_handle);
- if(err == EPIPE) {
- ALOGE("Failed in sync_ptr \n");
- /* we failed to make our window -- try to restart */
- capture_handle->underruns++;
- capture_handle->running = 0;
- capture_handle->start = 0;
- continue;
- } else if (err != NO_ERROR) {
- ALOGE("Error: Sync ptr returned %d", err);
- break;
- }
-
- mProxyParams.mAvail = pcm_avail(capture_handle);
- ALOGV("avail is = %d frames = %ld, avai_min = %d\n",\
- mProxyParams.mAvail, mProxyParams.mFrames,(int)capture_handle->sw_p->avail_min);
- if (mProxyParams.mAvail < capture_handle->sw_p->avail_min) {
- err_poll = poll(mProxyParams.mPfdProxy, NUM_FDS, TIMEOUT_INFINITE);
- if (mProxyParams.mPfdProxy[1].revents & POLLIN) {
- ALOGV("Event on userspace fd");
- }
- if ((mProxyParams.mPfdProxy[1].revents & POLLERR) ||
- (mProxyParams.mPfdProxy[1].revents & POLLNVAL)) {
- ALOGV("POLLERR or INVALID POLL");
- err = BAD_VALUE;
- break;
- }
- if((mProxyParams.mPfdProxy[0].revents & POLLERR) ||
- (mProxyParams.mPfdProxy[0].revents & POLLNVAL)) {
- ALOGV("POLLERR or INVALID POLL on zero");
- err = BAD_VALUE;
- break;
- }
- if (mProxyParams.mPfdProxy[0].revents & POLLIN) {
- ALOGV("POLLIN on zero");
- }
- ALOGV("err_poll = %d",err_poll);
- continue;
- }
- break;
- }
- if(err != NO_ERROR) {
- ALOGE("Reading from proxy failed = err = %d", err);
- *captureBuffer = NULL;
- *bufferSize = 0;
- return err;
- }
- if (mProxyParams.mX.frames > mProxyParams.mAvail)
- mProxyParams.mFrames = mProxyParams.mAvail;
- void *data = dst_address(capture_handle);
- //TODO: Return a pointer to AudioHardware
- if(mProxyParams.mCaptureBuffer == NULL)
- mProxyParams.mCaptureBuffer = malloc(mProxyParams.mCaptureBufferSize);
- memcpy(mProxyParams.mCaptureBuffer, (char *)data,
- mProxyParams.mCaptureBufferSize);
- mProxyParams.mX.frames -= mProxyParams.mFrames;
- capture_handle->sync_ptr->c.control.appl_ptr += mProxyParams.mFrames;
- capture_handle->sync_ptr->flags = 0;
- ALOGV("Calling sync_ptr for proxy after sync");
- err = sync_ptr(capture_handle);
- if(err == EPIPE) {
- ALOGV("Failed in sync_ptr \n");
- capture_handle->running = 0;
- err = sync_ptr(capture_handle);
- }
- if(err != NO_ERROR ) {
- ALOGE("Error: Sync ptr end returned %d", err);
- *captureBuffer = NULL;
- *bufferSize = 0;
- return err;
- }
- *captureBuffer = mProxyParams.mCaptureBuffer;
- *bufferSize = mProxyParams.mCaptureBufferSize;
- return err;
-}
-
-void ALSADevice::initProxyParams() {
- if(mProxyParams.mPfdProxy[1].fd == -1) {
- ALOGV("Allocating A2Dp poll fd");
- mProxyParams.mPfdProxy[0].fd = mProxyParams.mProxyPcmHandle->fd;
- mProxyParams.mPfdProxy[0].events = (POLLIN | POLLERR | POLLNVAL);
- ALOGV("Allocated A2DP poll fd");
- mProxyParams.mPfdProxy[1].fd = eventfd(0,0);
- mProxyParams.mPfdProxy[1].events = (POLLIN | POLLERR | POLLNVAL);
- mProxyParams.mFrames = (mProxyParams.mProxyPcmHandle->flags & PCM_MONO) ?
- (mProxyParams.mProxyPcmHandle->period_size / 2) :
- (mProxyParams.mProxyPcmHandle->period_size / 4);
- mProxyParams.mX.frames = (mProxyParams.mProxyPcmHandle->flags & PCM_MONO) ?
- (mProxyParams.mProxyPcmHandle->period_size / 2) :
- (mProxyParams.mProxyPcmHandle->period_size / 4);
- }
-}
-
-status_t ALSADevice::startProxy() {
-
- status_t err = NO_ERROR;
- struct pcm * capture_handle = (struct pcm *)mProxyParams.mProxyPcmHandle;
- while(1) {
- if (!capture_handle->start) {
- if(ioctl(capture_handle->fd, SNDRV_PCM_IOCTL_START)) {
- err = -errno;
- if (errno == EPIPE) {
- ALOGV("Failed in SNDRV_PCM_IOCTL_START\n");
- /* we failed to make our window -- try to restart */
- capture_handle->underruns++;
- capture_handle->running = 0;
- capture_handle->start = 0;
- continue;
- } else {
- ALOGE("IGNORE - IOCTL_START failed for proxy err: %d \n", errno);
- err = NO_ERROR;
- break;
- }
- } else {
- ALOGD(" Proxy Driver started(IOCTL_START Success)\n");
- break;
- }
- }
- else {
- ALOGV("Proxy Already started break out of condition");
- break;
- }
- }
- ALOGV("startProxy - Proxy started");
- capture_handle->start = 1;
- capture_handle->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL |
- SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
- return err;
-}
-
-status_t ALSADevice::openProxyDevice()
-{
- struct snd_pcm_hw_params *params = NULL;
- struct snd_pcm_sw_params *sparams = NULL;
- int flags = (DEBUG_ON | PCM_MMAP| PCM_STEREO | PCM_IN);
-
- ALOGV("openProxyDevice");
- mProxyParams.mProxyPcmHandle = pcm_open(flags, PROXY_CAPTURE_DEVICE_NAME);
- if (!pcm_ready(mProxyParams.mProxyPcmHandle)) {
- ALOGE("Opening proxy device failed");
- goto bail;
- }
- ALOGV("Proxy device opened successfully: mProxyPcmHandle %p", mProxyParams.mProxyPcmHandle);
- mProxyParams.mProxyPcmHandle->channels = AFE_PROXY_CHANNEL_COUNT;
- mProxyParams.mProxyPcmHandle->rate = AFE_PROXY_SAMPLE_RATE;
- mProxyParams.mProxyPcmHandle->flags = flags;
- mProxyParams.mProxyPcmHandle->period_size = AFE_PROXY_PERIOD_SIZE;
-
- params = (struct snd_pcm_hw_params*) calloc(1,sizeof(struct snd_pcm_hw_params));
- if (!params) {
- goto bail;
- }
-
- param_init(params);
-
- param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
- (mProxyParams.mProxyPcmHandle->flags & PCM_MMAP)?
- SNDRV_PCM_ACCESS_MMAP_INTERLEAVED
- : SNDRV_PCM_ACCESS_RW_INTERLEAVED);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_FORMAT_S16_LE);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
- SNDRV_PCM_SUBFORMAT_STD);
- param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- mProxyParams.mProxyPcmHandle->period_size);
- param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- mProxyParams.mProxyPcmHandle->channels - 1 ? 32 : 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
- mProxyParams.mProxyPcmHandle->channels);
- param_set_int(params, SNDRV_PCM_HW_PARAM_RATE,
- mProxyParams.mProxyPcmHandle->rate);
-
- param_set_hw_refine(mProxyParams.mProxyPcmHandle, params);
-
- if (param_set_hw_params(mProxyParams.mProxyPcmHandle, params)) {
- ALOGE("Failed to set hardware params on Proxy device");
- goto bail;
- }
-
- mProxyParams.mProxyPcmHandle->buffer_size = pcm_buffer_size(params);
- mProxyParams.mProxyPcmHandle->period_size = pcm_period_size(params);
- mProxyParams.mProxyPcmHandle->period_cnt =
- mProxyParams.mProxyPcmHandle->buffer_size /
- mProxyParams.mProxyPcmHandle->period_size;
- ALOGV("Capture - period_size (%d)",\
- mProxyParams.mProxyPcmHandle->period_size);
- ALOGV("Capture - buffer_size (%d)",\
- mProxyParams.mProxyPcmHandle->buffer_size);
- ALOGV("Capture - period_cnt (%d)\n",\
- mProxyParams.mProxyPcmHandle->period_cnt);
- sparams = (struct snd_pcm_sw_params*) calloc(1,sizeof(struct snd_pcm_sw_params));
- if (!sparams) {
- ALOGE("Failed to allocated software params for Proxy device");
- goto bail;
- }
-
- sparams->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
- sparams->period_step = 1;
- sparams->avail_min = (mProxyParams.mProxyPcmHandle->flags & PCM_MONO) ?
- mProxyParams.mProxyPcmHandle->period_size/2
- : mProxyParams.mProxyPcmHandle->period_size/4;
- sparams->start_threshold = 1;
- sparams->stop_threshold = mProxyParams.mProxyPcmHandle->buffer_size;
- sparams->xfer_align = (mProxyParams.mProxyPcmHandle->flags & PCM_MONO) ?
- mProxyParams.mProxyPcmHandle->period_size/2
- : mProxyParams.mProxyPcmHandle->period_size/4; /* needed for old kernels */
- sparams->silence_size = 0;
- sparams->silence_threshold = 0;
-
- if (param_set_sw_params(mProxyParams.mProxyPcmHandle, sparams)) {
- ALOGE("Failed to set software params on Proxy device");
- goto bail;
- }
- mmap_buffer(mProxyParams.mProxyPcmHandle);
-
- if (pcm_prepare(mProxyParams.mProxyPcmHandle)) {
- ALOGE("Failed to pcm_prepare on Proxy device");
- goto bail;
- }
- mProxyParams.mProxyState = proxy_params::EProxySuspended;
- return NO_ERROR;
-
-bail:
- if(mProxyParams.mProxyPcmHandle) {
- pcm_close(mProxyParams.mProxyPcmHandle);
- mProxyParams.mProxyPcmHandle = NULL;
- }
- mProxyParams.mProxyState = proxy_params::EProxyClosed;
- return NO_INIT;
-}
-
-status_t ALSADevice::closeProxyDevice() {
- status_t err = NO_ERROR;
- if(mProxyParams.mProxyPcmHandle) {
- pcm_close(mProxyParams.mProxyPcmHandle);
- mProxyParams.mProxyPcmHandle = NULL;
- }
- resetProxyVariables();
- mProxyParams.mProxyState = proxy_params::EProxyClosed;
- mProxyParams.mExitRead = false;
- return err;
-}
-
-bool ALSADevice::isProxyDeviceOpened() {
-
- //TODO : Add some intelligence to return appropriate value
- if(mProxyParams.mProxyState == proxy_params::EProxyOpened ||
- mProxyParams.mProxyState == proxy_params::EProxyCapture ||
- mProxyParams.mProxyState == proxy_params::EProxySuspended)
- return true;
- return false;
-}
-
-bool ALSADevice::isProxyDeviceSuspended() {
-
- if(mProxyParams.mProxyState == proxy_params::EProxySuspended)
- return true;
- return false;
-}
-
-bool ALSADevice::suspendProxy() {
-
- status_t err = NO_ERROR;
- if(mProxyParams.mProxyState == proxy_params::EProxyOpened ||
- mProxyParams.mProxyState == proxy_params::EProxyCapture) {
- mProxyParams.mProxyState = proxy_params::EProxySuspended;
- }
- else {
- ALOGE("Proxy already suspend or closed, in state = %d",\
- mProxyParams.mProxyState);
- }
- return err;
-}
-
-bool ALSADevice::resumeProxy() {
-
- status_t err = NO_ERROR;
- struct pcm *capture_handle= mProxyParams.mProxyPcmHandle;
- ALOGD("resumeProxy mProxyParams.mProxyState = %d, capture_handle =%p",\
- mProxyParams.mProxyState, capture_handle);
- if((mProxyParams.mProxyState == proxy_params::EProxyOpened ||
- mProxyParams.mProxyState == proxy_params::EProxySuspended) &&
- capture_handle != NULL) {
- ALOGV("pcm_prepare from Resume");
- capture_handle->start = 0;
- err = pcm_prepare(capture_handle);
- if(err != OK) {
- ALOGE("IGNORE: PCM Prepare - capture failed err = %d", err);
- }
- err = startProxy();
- if(err) {
- ALOGE("IGNORE:startProxy returned error = %d", err);
- }
- mProxyParams.mProxyState = proxy_params::EProxyCapture;
- err = sync_ptr(capture_handle);
- if (err) {
- ALOGE("IGNORE: sync ptr from resumeProxy returned error = %d", err);
- }
- ALOGV("appl_ptr= %d", (int)capture_handle->sync_ptr->c.control.appl_ptr);
- }
- else {
- ALOGV("resume Proxy ignored in invalid state - ignore");
- if(mProxyParams.mProxyState == proxy_params::EProxyClosed ||
- capture_handle == NULL) {
- ALOGE("resumeProxy = BAD_VALUE");
- err = BAD_VALUE;
- return err;
- }
- }
- return NO_ERROR;
-}
-
-#ifdef SEPERATED_AUDIO_INPUT
-void s_setInput(int input)
-{
- mInput_source = input;
- ALOGD("s_setInput() : input_source = %d",input_source);
-}
-#endif
-
-#ifdef QCOM_CSDCLIENT_ENABLED
-void ALSADevice::setCsdHandle(void* handle)
-{
- mcsd_handle = static_cast<void*>(handle);
- ALOGI("%s csd_handle: %p", __func__, mcsd_handle);
-
- csd_disable_device = (int (*)())::dlsym(mcsd_handle,"csd_client_disable_device");
- csd_enable_device = (int (*)(int,int,uint32_t))::dlsym(mcsd_handle,"csd_client_enable_device");
- csd_start_voice = (int (*)())::dlsym(mcsd_handle,"csd_client_start_voice");
- csd_stop_voice = (int (*)())::dlsym(mcsd_handle,"csd_client_stop_voice");
- csd_volume = (int (*)(int))::dlsym(mcsd_handle,"csd_client_volume");
- csd_mic_mute = (int (*)(int))::dlsym(mcsd_handle,"csd_client_mic_mute");
- csd_wide_voice = (int (*)(uint8_t))::dlsym(mcsd_handle,"csd_client_wide_voice");
- csd_fens = (int (*)(uint8_t))::dlsym(mcsd_handle,"csd_client_fens");
- csd_slow_talk = (int (*)(uint8_t))::dlsym(mcsd_handle,"csd_client_slow_talk");
- csd_client_volume = (int (*)(int))::dlsym(mcsd_handle,"csd_client_volume");
- csd_client_mic_mute = (int (*)(int))::dlsym(mcsd_handle,"csd_client_mic_mute");
-}
-#endif
-
-}
diff --git a/alsa_sound/ALSAMixer.cpp b/alsa_sound/ALSAMixer.cpp
index 0875a57..d1383cf 100644
--- a/alsa_sound/ALSAMixer.cpp
+++ b/alsa_sound/ALSAMixer.cpp
@@ -1,7 +1,6 @@
/* ALSAMixer.cpp
**
** Copyright 2008-2010 Wind River Systems
- ** Copyright (c) 2012, The Linux Foundation. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
diff --git a/alsa_sound/ALSAStreamOps.cpp b/alsa_sound/ALSAStreamOps.cpp
index a8c5bad..4e534fd 100644
--- a/alsa_sound/ALSAStreamOps.cpp
+++ b/alsa_sound/ALSAStreamOps.cpp
@@ -1,7 +1,7 @@
/* ALSAStreamOps.cpp
**
** Copyright 2008-2009 Wind River Systems
- ** Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ ** Copyright (c) 2011, Code Aurora Forum. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -65,7 +65,6 @@
}
}
mParent->mVoipStreamCount = 0;
- mParent->mVoipMicMute = 0;
mParent->mVoipBitRate = 0;
}
close();
@@ -111,15 +110,15 @@
break;
// Do not fall through
case 4:
- *channels |= AUDIO_CHANNEL_OUT_BACK_LEFT;
- *channels |= AUDIO_CHANNEL_OUT_BACK_RIGHT;
+ *channels |= AudioSystem::CHANNEL_OUT_BACK_LEFT;
+ *channels |= AudioSystem::CHANNEL_OUT_BACK_RIGHT;
// Fall through...
default:
case 2:
- *channels |= AUDIO_CHANNEL_OUT_FRONT_RIGHT;
+ *channels |= AudioSystem::CHANNEL_OUT_FRONT_RIGHT;
// Fall through...
case 1:
- *channels |= AUDIO_CHANNEL_OUT_FRONT_LEFT;
+ *channels |= AudioSystem::CHANNEL_OUT_FRONT_LEFT;
break;
}
} else {
@@ -127,16 +126,16 @@
#ifdef QCOM_SSR_ENABLED
// For 5.1 recording
case 6 :
- *channels |= AUDIO_CHANNEL_IN_5POINT1;
+ *channels |= AudioSystem::CHANNEL_IN_5POINT1;
break;
#endif
// Do not fall through...
default:
case 2:
- *channels |= AUDIO_CHANNEL_IN_RIGHT;
+ *channels |= AudioSystem::CHANNEL_IN_RIGHT;
// Fall through...
case 1:
- *channels |= AUDIO_CHANNEL_IN_LEFT;
+ *channels |= AudioSystem::CHANNEL_IN_LEFT;
break;
}
}
@@ -153,23 +152,23 @@
if (format) {
switch(*format) {
- case AUDIO_FORMAT_DEFAULT:
+ case AudioSystem::FORMAT_DEFAULT:
break;
- case AUDIO_FORMAT_PCM_16_BIT:
+ case AudioSystem::PCM_16_BIT:
iformat = SNDRV_PCM_FORMAT_S16_LE;
break;
- case AUDIO_FORMAT_AMR_NB:
- case AUDIO_FORMAT_AMR_WB:
-#ifdef QCOM_AUDIO_FORMAT_ENABLED
- case AUDIO_FORMAT_EVRC:
- case AUDIO_FORMAT_EVRCB:
- case AUDIO_FORMAT_EVRCWB:
+ case AudioSystem::AMR_NB:
+ case AudioSystem::AMR_WB:
+#ifdef QCOM_QCHAT_ENABLED
+ case AudioSystem::EVRC:
+ case AudioSystem::EVRCB:
+ case AudioSystem::EVRCWB:
#endif
iformat = *format;
break;
- case AUDIO_FORMAT_PCM_8_BIT:
+ case AudioSystem::PCM_8_BIT:
iformat = SNDRV_PCM_FORMAT_S8;
break;
@@ -183,10 +182,10 @@
switch(iformat) {
case SNDRV_PCM_FORMAT_S16_LE:
- *format = AUDIO_FORMAT_PCM_16_BIT;
+ *format = AudioSystem::PCM_16_BIT;
break;
case SNDRV_PCM_FORMAT_S8:
- *format = AUDIO_FORMAT_PCM_8_BIT;
+ *format = AudioSystem::PCM_8_BIT;
break;
default:
break;
@@ -199,9 +198,8 @@
status_t ALSAStreamOps::setParameters(const String8& keyValuePairs)
{
AudioParameter param = AudioParameter(keyValuePairs);
- String8 key = String8(AudioParameter::keyRouting),value;
+ String8 key = String8(AudioParameter::keyRouting);
int device;
- status_t err = NO_ERROR;
#ifdef SEPERATED_AUDIO_INPUT
String8 key_input = String8(AudioParameter::keyInputSource);
@@ -221,21 +219,13 @@
if ((device == 0) && (mDevices == AudioSystem::DEVICE_OUT_AUX_DIGITAL)) {
device = AudioSystem::DEVICE_OUT_SPEAKER;
}
+ if (device)
+ mDevices = device;
+ else
+ ALOGV("must not change mDevices to 0");
+
if(device) {
- ALOGD("setParameters(): keyRouting with device %#x", device);
- if(device & AudioSystem::DEVICE_OUT_ALL_A2DP) {
- mParent->mRouteAudioToA2dp = true;
- ALOGD("setParameters(): A2DP device %#x", device);
- }
- err = mParent->doRouting(device);
- if(err) {
- ALOGE("doRouting failed = %d",err);
- }
- else {
- mDevices = device;
- }
- } else {
- ALOGE("must not change mDevices to 0");
+ mParent->doRouting(device);
}
param.remove(key);
}
@@ -243,9 +233,9 @@
else {
key = String8(AudioParameter::keyHandleFm);
if (param.getInt(key, device) == NO_ERROR) {
- ALOGD("setParameters(): handleFm with device %d", device);
+ ALOGD("setParameters(): handleFm with device %d", device);
+ mDevices = device;
if(device) {
- mDevices = device;
mParent->handleFm(device);
}
param.remove(key);
@@ -253,7 +243,7 @@
}
#endif
- return err;
+ return NO_ERROR;
}
String8 ALSAStreamOps::getParameters(const String8& keys)
@@ -267,7 +257,7 @@
}
else {
#ifdef QCOM_VOIP_ENABLED
- key = String8(VOIPCHECK_KEY);
+ key = String8(AudioParameter::keyVoipCheck);
if (param.get(key, value) == NO_ERROR) {
if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
(!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP))))
@@ -334,25 +324,25 @@
switch(ALSAFormat) {
case SNDRV_PCM_FORMAT_S8:
- audioSystemFormat = AUDIO_FORMAT_PCM_8_BIT;
+ audioSystemFormat = AudioSystem::PCM_8_BIT;
break;
- case AUDIO_FORMAT_AMR_NB:
- case AUDIO_FORMAT_AMR_WB:
-#ifdef QCOM_AUDIO_FORMAT_ENABLED
- case AUDIO_FORMAT_EVRC:
- case AUDIO_FORMAT_EVRCB:
- case AUDIO_FORMAT_EVRCWB:
+ case AudioSystem::AMR_NB:
+ case AudioSystem::AMR_WB:
+#ifdef QCOM_QCHAT_ENABLED
+ case AudioSystem::EVRC:
+ case AudioSystem::EVRCB:
+ case AudioSystem::EVRCWB:
#endif
audioSystemFormat = mHandle->format;
break;
case SNDRV_PCM_FORMAT_S16_LE:
- audioSystemFormat = AUDIO_FORMAT_PCM_16_BIT;
+ audioSystemFormat = AudioSystem::PCM_16_BIT;
break;
default:
LOG_FATAL("Unknown AudioSystem bit width %d!", audioSystemFormat);
- audioSystemFormat = AUDIO_FORMAT_PCM_16_BIT;
+ audioSystemFormat = AudioSystem::PCM_16_BIT;
break;
}
@@ -373,15 +363,15 @@
break;
// Do not fall through
case 4:
- channels |= AUDIO_CHANNEL_OUT_BACK_LEFT;
- channels |= AUDIO_CHANNEL_OUT_BACK_RIGHT;
+ channels |= AudioSystem::CHANNEL_OUT_BACK_LEFT;
+ channels |= AudioSystem::CHANNEL_OUT_BACK_RIGHT;
// Fall through...
default:
case 2:
- channels |= AUDIO_CHANNEL_OUT_FRONT_RIGHT;
+ channels |= AudioSystem::CHANNEL_OUT_FRONT_RIGHT;
// Fall through...
case 1:
- channels |= AUDIO_CHANNEL_OUT_FRONT_LEFT;
+ channels |= AudioSystem::CHANNEL_OUT_FRONT_LEFT;
break;
}
else
@@ -389,16 +379,16 @@
#ifdef QCOM_SSR_ENABLED
// For 5.1 recording
case 6 :
- channels |= AUDIO_CHANNEL_IN_5POINT1;
+ channels |= AudioSystem::CHANNEL_IN_5POINT1;
break;
// Do not fall through...
#endif
default:
case 2:
- channels |= AUDIO_CHANNEL_IN_RIGHT;
+ channels |= AudioSystem::CHANNEL_IN_RIGHT;
// Fall through...
case 1:
- channels |= AUDIO_CHANNEL_IN_LEFT;
+ channels |= AudioSystem::CHANNEL_IN_LEFT;
break;
}
@@ -410,7 +400,6 @@
ALOGD("close");
if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
(!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
- mParent->mVoipMicMute = false;
mParent->mVoipBitRate = 0;
mParent->mVoipStreamCount = 0;
}
diff --git a/alsa_sound/Android.mk b/alsa_sound/Android.mk
index 9139af9..738b969 100644
--- a/alsa_sound/Android.mk
+++ b/alsa_sound/Android.mk
@@ -11,53 +11,25 @@
LOCAL_ARM_MODE := arm
LOCAL_CFLAGS := -D_POSIX_SOURCE
-LOCAL_CFLAGS += -DQCOM_ACDB_ENABLED
-LOCAL_CFLAGS += -DQCOM_ANC_HEADSET_ENABLED
-LOCAL_CFLAGS += -DQCOM_AUDIO_FORMAT_ENABLED
LOCAL_CFLAGS += -DQCOM_CSDCLIENT_ENABLED
-#LOCAL_CFLAGS += -DQCOM_FM_ENABLED
-#LOCAL_CFLAGS += -DQCOM_FM_TX_ENABLED
-#LOCAL_CFLAGS += -DQCOM_OUTPUT_FLAGS_ENABLED
-LOCAL_CFLAGS += -DQCOM_PROXY_DEVICE_ENABLED
-#LOCAL_CFLAGS += -DQCOM_SSR_ENABLED
-LOCAL_CFLAGS += -DQCOM_USBAUDIO_ENABLED
-LOCAL_CFLAGS += -DQCOM_VOIP_ENABLED
+LOCAL_CFLAGS += -DQCOM_ACDB_ENABLED
-ifeq ($(call is-board-platform,msm8974),true)
- LOCAL_CFLAGS += -DTARGET_8974
+ifeq ($(strip $(BOARD_USES_FLUENCE_INCALL)),true)
+LOCAL_CFLAGS += -DUSES_FLUENCE_INCALL
endif
-ifneq ($(ALSA_DEFAULT_SAMPLE_RATE),)
- LOCAL_CFLAGS += -DALSA_DEFAULT_SAMPLE_RATE=$(ALSA_DEFAULT_SAMPLE_RATE)
+ifeq ($(strip $(BOARD_USES_SEPERATED_AUDIO_INPUT)),true)
+LOCAL_CFLAGS += -DSEPERATED_AUDIO_INPUT
endif
-#Do not use Dual MIC scenario in call feature
-#Dual MIC solution(Fluence) feature in Built-in MIC used scenarioes.
-# 1. Handset
-# 2. 3-Pole Headphones
-#ifeq ($(strip $(BOARD_USES_FLUENCE_INCALL)),true)
-#LOCAL_CFLAGS += -DUSES_FLUENCE_INCALL
-#endif
-
-#Do not use separate audio Input path feature
-#Separate audio input path can be set using input source of audio parameter
-# 1. Voice Recognition
-# 2. Camcording
-# 3. etc.
-#ifeq ($(strip $(BOARD_USES_SEPERATED_AUDIO_INPUT)),true)
-#LOCAL_CFLAGS += -DSEPERATED_AUDIO_INPUT
-#endif
-
LOCAL_SRC_FILES := \
- AudioHardwareALSA.cpp \
- AudioStreamOutALSA.cpp \
- AudioStreamInALSA.cpp \
- ALSAStreamOps.cpp \
- audio_hw_hal.cpp \
- AudioUsbALSA.cpp \
- AudioUtil.cpp \
- AudioSessionOut.cpp \
- ALSADevice.cpp
+ AudioHardwareALSA.cpp \
+ AudioStreamOutALSA.cpp \
+ AudioStreamInALSA.cpp \
+ ALSAStreamOps.cpp \
+ audio_hw_hal.cpp \
+ AudioUsbALSA.cpp \
+ AudioUtil.cpp
LOCAL_STATIC_LIBRARIES := \
libmedia_helper \
@@ -87,37 +59,20 @@
LOCAL_C_INCLUDES += frameworks/base/include
LOCAL_C_INCLUDES += system/core/include
-LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-ifeq ($(call is-board-platform,msm8974),true)
- LOCAL_MODULE := audio.primary.msm8974
-endif
-
-ifeq ($(call is-board-platform,msm8960),true)
- LOCAL_MODULE := audio.primary.msm8960
-endif
-
+LOCAL_MODULE := audio.primary.msm8960
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
+ifeq (1,0) # use default audio policy manager
+# This is the ALSA audio policy manager
+
include $(CLEAR_VARS)
LOCAL_CFLAGS := -D_POSIX_SOURCE
LOCAL_CFLAGS += -DQCOM_ACDB_ENABLED
-LOCAL_CFLAGS += -DQCOM_ANC_HEADSET_ENABLED
-LOCAL_CFLAGS += -DQCOM_AUDIO_FORMAT_ENABLED
-LOCAL_CFLAGS += -DQCOM_CSDCLIENT_ENABLED
-#LOCAL_CFLAGS += -DQCOM_FM_ENABLED
-#LOCAL_CFLAGS += -DQCOM_FM_TX_ENABLED
-#LOCAL_CFLAGS += -DQCOM_OUTPUT_FLAGS_ENABLED
-LOCAL_CFLAGS += -DQCOM_PROXY_DEVICE_ENABLED
-#LOCAL_CFLAGS += -DQCOM_SSR_ENABLED
-LOCAL_CFLAGS += -DQCOM_USBAUDIO_ENABLED
-LOCAL_CFLAGS += -DQCOM_VOIP_ENABLED
-
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_CFLAGS += -DWITH_A2DP
@@ -127,15 +82,7 @@
audio_policy_hal.cpp \
AudioPolicyManagerALSA.cpp
-
-ifeq ($(call is-board-platform,msm8974),true)
- LOCAL_MODULE := audio_policy.msm8974
-endif
-
-ifeq ($(call is-board-platform,msm8960),true)
- LOCAL_MODULE := audio_policy.msm8960
-endif
-
+LOCAL_MODULE := audio_policy.msm8960
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_MODULE_TAGS := optional
@@ -152,5 +99,51 @@
LOCAL_C_INCLUDES += hardware/libhardware_legacy/audio
include $(BUILD_SHARED_LIBRARY)
+endif
+# This is the ALSA module which behaves closely like the original
+
+include $(CLEAR_VARS)
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+
+LOCAL_CFLAGS := -D_POSIX_SOURCE -Wno-multichar
+LOCAL_CFLAGS += -DQCOM_ACDB_ENABLED
+
+ifeq ($(strip $(BOARD_USES_FLUENCE_INCALL)),true)
+LOCAL_CFLAGS += -DUSES_FLUENCE_INCALL
+endif
+
+ifeq ($(strip $(BOARD_USES_SEPERATED_AUDIO_INPUT)),true)
+LOCAL_CFLAGS += -DSEPERATED_AUDIO_INPUT
+endif
+
+ifneq ($(ALSA_DEFAULT_SAMPLE_RATE),)
+ LOCAL_CFLAGS += -DALSA_DEFAULT_SAMPLE_RATE=$(ALSA_DEFAULT_SAMPLE_RATE)
+endif
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/libalsa-intf
+
+LOCAL_SRC_FILES:= \
+ alsa_default.cpp \
+ ALSAControl.cpp \
+ AudioUtil.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ liblog \
+ libalsa-intf
+
+ifeq ($(TARGET_SIMULATOR),true)
+ LOCAL_LDLIBS += -ldl
+else
+ LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+LOCAL_MODULE:= alsa.msm8960
+LOCAL_MODULE_TAGS := optional
+
+ include $(BUILD_SHARED_LIBRARY)
endif
diff --git a/alsa_sound/AudioHardwareALSA.cpp b/alsa_sound/AudioHardwareALSA.cpp
index 6cf142f..a53f161 100644
--- a/alsa_sound/AudioHardwareALSA.cpp
+++ b/alsa_sound/AudioHardwareALSA.cpp
@@ -1,7 +1,7 @@
/* AudioHardwareALSA.cpp
**
** Copyright 2008-2010 Wind River Systems
- ** Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
#include <math.h>
#define LOG_TAG "AudioHardwareALSA"
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#define LOG_NDDEBUG 0
#include <utils/Log.h>
#include <utils/String8.h>
@@ -37,7 +37,6 @@
#include <cutils/properties.h>
#include <media/AudioRecord.h>
#include <hardware_legacy/power.h>
-#include <pthread.h>
#include "AudioHardwareALSA.h"
#ifdef QCOM_USBAUDIO_ENABLED
@@ -45,13 +44,6 @@
#endif
#include "AudioUtil.h"
-//#define OUTPUT_BUFFER_LOG
-#ifdef OUTPUT_BUFFER_LOG
- FILE *outputBufferFile1;
- char outputfilename [50] = "/data/output_proxy";
- static int number = 0;
-#endif
-
extern "C"
{
//
@@ -80,35 +72,39 @@
}
AudioHardwareALSA::AudioHardwareALSA() :
- mALSADevice(0),mVoipStreamCount(0),mVoipMicMute(false),mVoipBitRate(0)
+ mALSADevice(0),mVoipStreamCount(0),mVoipBitRate(0)
,mCallState(0),mAcdbHandle(NULL),mCsdHandle(NULL),mMicMute(0)
{
FILE *fp;
char soundCardInfo[200];
- char platform[128], baseband[128], audio_init[128], platformVer[128];
- int codec_rev = 2, verNum = 0;
- mALSADevice = new ALSADevice();
- mDeviceList.clear();
- mCSCallActive = 0;
- mVolteCallActive = 0;
- mSGLTECallActive = 0;
- mIsFmActive = 0;
- mDevSettingsFlag = 0;
- bool audio_init_done = false;
- int sleep_retry = 0;
+ hw_module_t *module;
+ char platform[128], baseband[128];
+ int err = hw_get_module(ALSA_HARDWARE_MODULE_ID,
+ (hw_module_t const**)&module);
+ int codec_rev = 2;
+ ALOGD("hw_get_module(ALSA_HARDWARE_MODULE_ID) returned err %d", err);
+ if (err == 0) {
+ hw_device_t* device;
+ err = module->methods->open(module, ALSA_HARDWARE_NAME, &device);
+ if (err == 0) {
+ mALSADevice = (alsa_device_t *)device;
+ mALSADevice->init(mALSADevice, mDeviceList);
+ mCSCallActive = 0;
+ mVolteCallActive = 0;
+ mIsFmActive = 0;
+ mDevSettingsFlag = 0;
#ifdef QCOM_USBAUDIO_ENABLED
- mAudioUsbALSA = new AudioUsbALSA();
- musbPlaybackState = 0;
- musbRecordingState = 0;
+ mAudioUsbALSA = new AudioUsbALSA();
+ musbPlaybackState = 0;
+ musbRecordingState = 0;
#endif
#ifdef USES_FLUENCE_INCALL
- mDevSettingsFlag |= TTY_OFF | DMIC_FLAG;
+ mDevSettingsFlag |= TTY_OFF | DMIC_FLAG;
#else
- mDevSettingsFlag |= TTY_OFF;
+ mDevSettingsFlag |= TTY_OFF;
#endif
- mBluetoothVGS = false;
- mFusion3Platform = false;
- mIsVoicePathActive = false;
+ mBluetoothVGS = false;
+ mFusion3Platform = false;
#ifdef QCOM_ACDB_ENABLED
mAcdbHandle = ::dlopen("/system/lib/libacdbloader.so", RTLD_NOW);
@@ -137,141 +133,61 @@
}
mALSADevice->setCsdHandle(mCsdHandle);
#endif
- if((fp = fopen("/proc/asound/cards","r")) == NULL) {
- ALOGE("Cannot open /proc/asound/cards file to get sound card info");
- } else {
- while((fgets(soundCardInfo, sizeof(soundCardInfo), fp) != NULL)) {
- ALOGV("SoundCardInfo %s", soundCardInfo);
- if (strstr(soundCardInfo, "msm8960-tabla1x-snd-card")) {
- codec_rev = 1;
- break;
- } else if (strstr(soundCardInfo, "msm-snd-card")) {
- codec_rev = 2;
- break;
- } else if (strstr(soundCardInfo, "msm8930-sitar-snd-card")) {
- codec_rev = 3;
- break;
- } else if (strstr(soundCardInfo, "msm8974-taiko-mtp-snd-card")) {
- codec_rev = 40;
- break;
- } else if (strstr(soundCardInfo, "msm8974-taiko-cdp-snd-card")) {
- codec_rev = 41;
- break;
- } else if (strstr(soundCardInfo, "msm8974-taiko-fluid-snd-card")) {
- codec_rev = 42;
- break;
- } else if (strstr(soundCardInfo, "msm8974-taiko-liquid-snd-card")) {
- codec_rev = 43;
- break;
- }
- }
- fclose(fp);
- }
-
- while (audio_init_done == false && sleep_retry < MAX_SLEEP_RETRY) {
- property_get("qcom.audio.init", audio_init, NULL);
- ALOGD("qcom.audio.init is set to %s\n",audio_init);
- if(!strncmp(audio_init, "complete", sizeof("complete"))) {
- audio_init_done = true;
- } else {
- ALOGD("Sleeping for 50 ms");
- usleep(AUDIO_INIT_SLEEP_WAIT*1000);
- sleep_retry++;
- }
- }
-
- if (codec_rev == 1) {
- ALOGV("Detected tabla 1.x sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm");
- } else if (codec_rev == 3) {
- ALOGV("Detected sitar 1.x sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Sitar");
- } else if (codec_rev == 40) {
- ALOGV("Detected taiko sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Taiko");
- } else if (codec_rev == 41) {
- ALOGV("Detected taiko sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Taiko_CDP");
- } else if (codec_rev == 42) {
- ALOGV("Detected taiko sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Taiko_Fluid");
- } else if (codec_rev == 43) {
- ALOGV("Detected taiko liquid sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Taiko_liquid");
- } else {
- property_get("ro.board.platform", platform, "");
- property_get("ro.baseband", baseband, "");
- if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) {
- ALOGV("Detected Fusion tabla 2.x");
- mFusion3Platform = true;
- if((fp = fopen("/sys/devices/system/soc/soc0/platform_version","r")) == NULL) {
- ALOGE("Cannot open /sys/devices/system/soc/soc0/platform_version file");
-
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x_Fusion3");
+ if((fp = fopen("/proc/asound/cards","r")) == NULL) {
+ ALOGE("Cannot open /proc/asound/cards file to get sound card info");
} else {
- while((fgets(platformVer, sizeof(platformVer), fp) != NULL)) {
- ALOGV("platformVer %s", platformVer);
-
- verNum = atoi(platformVer);
- if (verNum == 0x10001) {
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_I2SFusion");
+ while((fgets(soundCardInfo, sizeof(soundCardInfo), fp) != NULL)) {
+ ALOGV("SoundCardInfo %s", soundCardInfo);
+ if (strstr(soundCardInfo, "msm8960-tabla1x-snd-card")) {
+ codec_rev = 1;
break;
- } else {
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x_Fusion3");
+ } else if (strstr(soundCardInfo, "msm-snd-card")) {
+ codec_rev = 2;
+ break;
+ } else if (strstr(soundCardInfo, "msm8930-sitar-snd-card")) {
+ codec_rev = 3;
break;
}
}
+ fclose(fp);
}
- fclose(fp);
+
+ if (codec_rev == 1) {
+ ALOGV("Detected tabla 1.x sound card");
+ snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm");
+ } else if (codec_rev == 3) {
+ ALOGV("Detected sitar 1.x sound card");
+ snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Sitar");
+ } else {
+ property_get("ro.board.platform", platform, "");
+ property_get("ro.baseband", baseband, "");
+ if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) {
+ ALOGV("Detected Fusion tabla 2.x");
+ mFusion3Platform = true;
+ snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x_Fusion3");
+ } else {
+ ALOGV("Detected tabla 2.x sound card");
+ snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x");
+ }
+ }
+
+ if (mUcMgr < 0) {
+ ALOGE("Failed to open ucm instance: %d", errno);
+ } else {
+ ALOGI("ucm instance opened: %u", (unsigned)mUcMgr);
+ mUcMgr->acdb_handle = NULL;
+#ifdef QCOM_ACDB_ENABLED
+ if (mAcdbHandle) {
+ mUcMgr->acdb_handle = static_cast<void*> (mAcdbHandle);
+ }
+#endif
+ }
} else {
- ALOGV("Detected tabla 2.x sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x");
+ ALOGE("ALSA Module could not be opened!!!");
}
- }
-
- if (mUcMgr < 0) {
- ALOGE("Failed to open ucm instance: %d", errno);
} else {
- ALOGI("ucm instance opened: %u", (unsigned)mUcMgr);
+ ALOGE("ALSA Module not found!!!");
}
-
- //set default AudioParameters
- AudioParameter param;
- String8 key;
- String8 value;
-
- //Set default AudioParameter for fluencetype
- key = String8(FLUENCE_KEY);
- char fluence_key[20] = "none";
- property_get("ro.qc.sdk.audio.fluencetype",fluence_key,"0");
- if (0 == strncmp("fluencepro", fluence_key, sizeof("fluencepro"))) {
- mDevSettingsFlag |= QMIC_FLAG;
- mDevSettingsFlag &= (~DMIC_FLAG);
- value = String8("fluencepro");
- ALOGD("FluencePro quadMic feature Enabled");
- } else if (0 == strncmp("fluence", fluence_key, sizeof("fluence"))) {
- mDevSettingsFlag |= DMIC_FLAG;
- mDevSettingsFlag &= (~QMIC_FLAG);
- value = String8("fluence");
- ALOGD("Fluence dualmic feature Enabled");
- } else if (0 == strncmp("none", fluence_key, sizeof("none"))) {
- mDevSettingsFlag &= (~DMIC_FLAG);
- mDevSettingsFlag &= (~QMIC_FLAG);
- value = String8("none");
- ALOGD("Fluence feature Disabled");
- }
- param.add(key, value);
- mALSADevice->setFlags(mDevSettingsFlag);
-
- //mALSADevice->setDeviceList(&mDeviceList);
- mRouteAudioToA2dp = false;
- mA2dpDevice = NULL;
- mA2dpStream = NULL;
- mA2DPActiveUseCases = USECASE_NONE;
- mIsA2DPEnabled = false;
- mKillA2DPThread = false;
- mA2dpThreadAlive = false;
- mA2dpThread = NULL;
}
AudioHardwareALSA::~AudioHardwareALSA()
@@ -281,7 +197,7 @@
snd_use_case_mgr_close(mUcMgr);
}
if (mALSADevice) {
- delete mALSADevice;
+ mALSADevice->common.close(&mALSADevice->common);
}
for(ALSAHandleList::iterator it = mDeviceList.begin();
it != mDeviceList.end(); ++it) {
@@ -340,13 +256,11 @@
vol = 100 - vol;
if (mALSADevice) {
- if(newMode == AUDIO_MODE_IN_COMMUNICATION) {
+ if(newMode == AudioSystem::MODE_IN_COMMUNICATION) {
mALSADevice->setVoipVolume(vol);
- } else if (newMode == AUDIO_MODE_IN_CALL){
+ } else if (newMode == AudioSystem::MODE_IN_CALL){
if (mCSCallActive == CS_ACTIVE)
mALSADevice->setVoiceVolume(vol);
- else if (mSGLTECallActive == CS_ACTIVE_SESSION2)
- mALSADevice->setSGLTEVolume(vol);
if (mVolteCallActive == IMS_ACTIVE)
mALSADevice->setVoLTEVolume(vol);
}
@@ -358,7 +272,6 @@
#ifdef QCOM_FM_ENABLED
status_t AudioHardwareALSA::setFmVolume(float value)
{
- Mutex::Autolock autoLock(mLock);
status_t status = NO_ERROR;
int vol;
@@ -393,10 +306,10 @@
if (mode != mMode) {
status = AudioHardwareBase::setMode(mode);
}
- if (mode == AUDIO_MODE_IN_CALL) {
- if (mCallState == CS_INACTIVE)
- mCallState = CS_ACTIVE;
- }else if (mode == AUDIO_MODE_NORMAL) {
+
+ if (mode == AudioSystem::MODE_IN_CALL) {
+ mCallState = CS_ACTIVE;
+ }else if (mode == AudioSystem::MODE_NORMAL) {
mCallState = 0;
}
@@ -417,18 +330,18 @@
key = String8(TTY_MODE_KEY);
if (param.get(key, value) == NO_ERROR) {
mDevSettingsFlag &= TTY_CLEAR;
- if (value == "full") {
+ if (value == "tty_full") {
mDevSettingsFlag |= TTY_FULL;
- } else if (value == "hco") {
+ } else if (value == "tty_hco") {
mDevSettingsFlag |= TTY_HCO;
- } else if (value == "vco") {
+ } else if (value == "tty_vco") {
mDevSettingsFlag |= TTY_VCO;
} else {
mDevSettingsFlag |= TTY_OFF;
}
ALOGI("Changed TTY Mode=%s", value.string());
mALSADevice->setFlags(mDevSettingsFlag);
- if(mMode != AUDIO_MODE_IN_CALL){
+ if(mMode != AudioSystem::MODE_IN_CALL){
return NO_ERROR;
}
doRouting(0);
@@ -525,43 +438,6 @@
param.remove(key);
}
- key = String8("a2dp_connected");
- if (param.get(key, value) == NO_ERROR) {
- if (value == "true") {
- status_t err = openA2dpOutput();
- if(err) {
- ALOGE("openA2DPOutput failed = %d",err);
- return err;
- }
- } else {
- uint32_t activeUsecase = getA2DPActiveUseCases_l();
- stopA2dpPlayback(activeUsecase);
- status_t err = closeA2dpOutput();
- if(err) {
- ALOGE("closeA2dpOutput = %d" ,err);
- }
- }
- param.remove(key);
- }
-
- key = String8("A2dpSuspended");
- if (param.get(key, value) == NO_ERROR) {
- if (value == "true") {
- if (mA2dpDevice != NULL) {
- mA2dpDevice->set_parameters(mA2dpDevice,keyValuePairs);
- }
- }
- param.remove(key);
- }
-
- key = String8("a2dp_sink_address");
- if (param.get(key, value) == NO_ERROR) {
- if (mA2dpStream != NULL) {
- mA2dpStream->common.set_parameters(&mA2dpStream->common,keyValuePairs);
- }
- param.remove(key);
- }
-
key = String8(VOIPRATE_KEY);
if (param.get(key, value) == NO_ERROR) {
mVoipBitRate = atoi(value);
@@ -620,7 +496,6 @@
{
AudioParameter param = AudioParameter(keys);
String8 value;
- int device;
String8 key = String8(DUALMIC_KEY);
if (param.get(key, value) == NO_ERROR) {
@@ -643,12 +518,6 @@
}
#ifdef QCOM_FM_ENABLED
-
- key = String8(AudioParameter::keyHandleA2dpDevice);
- if ( param.get(key,value) == NO_ERROR ) {
- param.add(key, String8("true"));
- }
-
key = String8("Fm-radio");
if ( param.get(key,value) == NO_ERROR ) {
if ( mIsFmActive ) {
@@ -662,57 +531,6 @@
if(mBluetoothVGS)
param.addInt(String8("isVGS"), true);
}
-#ifdef QCOM_SSR_ENABLED
- key = String8(AudioParameter::keySSR);
- if (param.get(key, value) == NO_ERROR) {
- char ssr_enabled[6] = "false";
- property_get("ro.qc.sdk.audio.ssr",ssr_enabled,"0");
- if (!strncmp("true", ssr_enabled, 4)) {
- value = String8("true");
- }
- param.add(key, value);
- }
-#endif
-
- key = String8("A2dpSuspended");
- if (param.get(key, value) == NO_ERROR) {
- if (mA2dpDevice != NULL) {
- value = mA2dpDevice->get_parameters(mA2dpDevice,key);
- }
- param.add(key, value);
- }
-
- key = String8("a2dp_sink_address");
- if (param.get(key, value) == NO_ERROR) {
- if (mA2dpStream != NULL) {
- value = mA2dpStream->common.get_parameters(&mA2dpStream->common,key);
- }
- param.add(key, value);
- }
-
- key = String8(VOICE_PATH_ACTIVE);
- if (param.get(key, value) == NO_ERROR) {
- if (mIsVoicePathActive) {
- value = String8("true");
- } else {
- value = String8("false");
- }
- param.add(key, value);
-
- ALOGV("AudioHardwareALSA::getParameters() mIsVoicePathActive %d",
- mIsVoicePathActive);
- }
-
- key = String8("tunneled-input-formats");
- if ( param.get(key,value) == NO_ERROR ) {
- ALOGD("Add tunnel AWB to audio parameter");
- param.addInt(String8("AWB"), true );
- }
-
- key = String8(AudioParameter::keyRouting);
- if (param.getInt(key, device) == NO_ERROR) {
- param.addInt(key, mCurDevice);
- }
ALOGV("AudioHardwareALSA::getParameters() %s", param.toString().string());
return param.toString();
@@ -765,7 +583,7 @@
}
#endif
-status_t AudioHardwareALSA::doRouting(int device)
+void AudioHardwareALSA::doRouting(int device)
{
Mutex::Autolock autoLock(mLock);
int newMode = mode();
@@ -774,34 +592,38 @@
if ((device == AudioSystem::DEVICE_IN_VOICE_CALL)
#ifdef QCOM_FM_ENABLED
|| (device == AudioSystem::DEVICE_IN_FM_RX)
+ || (device == AudioSystem::DEVICE_OUT_DIRECTOUTPUT)
|| (device == AudioSystem::DEVICE_IN_FM_RX_A2DP)
#endif
|| (device == AudioSystem::DEVICE_IN_COMMUNICATION)
) {
ALOGV("Ignoring routing for FM/INCALL/VOIP recording");
- return NO_ERROR;
+ return;
}
- ALOGV("device = 0x%x,mCurDevice 0x%x", device, mCurDevice);
if (device == 0)
device = mCurDevice;
- ALOGV("doRouting: device %#x newMode %d mCSCallActive %d mVolteCallActive %d"
- "mSGLTECallActive %d mIsFmActive %d", device, newMode, mCSCallActive,
- mVolteCallActive, mSGLTECallActive, mIsFmActive);
+ ALOGV("doRouting: device %d newMode %d mCSCallActive %d mVolteCallActive %d"
+ "mIsFmActive %d", device, newMode, mCSCallActive, mVolteCallActive,
+ mIsFmActive);
+
isRouted = routeVoLTECall(device, newMode);
isRouted |= routeVoiceCall(device, newMode);
- isRouted |= routeSGLTECall(device, newMode);
if(!isRouted) {
#ifdef QCOM_USBAUDIO_ENABLED
if(!(device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) &&
!(device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET) &&
!(device & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) &&
- (musbPlaybackState || musbRecordingState)){
+ (musbPlaybackState)){
//USB unplugged
+ device &= ~ AudioSystem::DEVICE_OUT_PROXY;
+ device &= ~ AudioSystem::DEVICE_IN_PROXY;
ALSAHandleList::iterator it = mDeviceList.end();
it--;
mALSADevice->route(&(*it), (uint32_t)device, newMode);
ALOGD("USB UNPLUGGED, setting musbPlaybackState to 0");
+ musbPlaybackState = 0;
+ musbRecordingState = 0;
closeUSBRecording();
closeUSBPlayback();
} else if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
@@ -809,11 +631,8 @@
ALOGD("Routing everything to prox now");
ALSAHandleList::iterator it = mDeviceList.end();
it--;
- if (device != mCurDevice) {
- if(musbPlaybackState)
- closeUSBPlayback();
- }
- mALSADevice->route(&(*it), device, newMode);
+ mALSADevice->route(&(*it), AudioSystem::DEVICE_OUT_PROXY,
+ newMode);
for(it = mDeviceList.begin(); it != mDeviceList.end(); ++it) {
if((!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
(!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_LPA))) {
@@ -821,12 +640,6 @@
startUsbPlaybackIfNotStarted();
musbPlaybackState |= USBPLAYBACKBIT_LPA;
break;
- } else if((!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
- ALOGD("doRouting: Tunnel Player device switch to proxy");
- startUsbPlaybackIfNotStarted();
- musbPlaybackState |= USBPLAYBACKBIT_TUNNEL;
- break;
} else if((!strcmp(it->useCase, SND_USE_CASE_VERB_VOICECALL)) ||
(!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOICE))) {
ALOGV("doRouting: VOICE device switch to proxy");
@@ -845,134 +658,41 @@
}
} else
#endif
- if (device & AudioSystem::DEVICE_OUT_ALL_A2DP &&
- mRouteAudioToA2dp == true ) {
- ALOGV(" A2DP Enabled - Routing everything to proxy now");
- if (device != mCurDevice) {
- pauseIfUseCaseTunnelOrLPA();
- }
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- status_t err = NO_ERROR;
- uint32_t activeUsecase = useCaseStringToEnum(it->useCase);
- ALOGD("doRouting-startA2dpPlayback_l-A2DPHardwareOutput-enable");
- if ((activeUsecase == USECASE_HIFI_LOW_POWER) ||
- (activeUsecase == USECASE_HIFI_TUNNEL)) {
- if (device != mCurDevice) {
- if((mCurDevice & AudioSystem::DEVICE_OUT_ALL_A2DP) &&
- (device & AudioSystem::DEVICE_OUT_ALL_A2DP)) {
- activeUsecase = getA2DPActiveUseCases_l();
- stopA2dpPlayback_l(activeUsecase);
- mRouteAudioToA2dp = true;
- }
- mALSADevice->route(&(*it),(uint32_t)device, newMode);
- }
- err = startA2dpPlayback_l(activeUsecase);
- if(err) {
- ALOGW("startA2dpPlayback_l for hardware output failed err = %d", err);
- stopA2dpPlayback_l(activeUsecase);
- }
- } else {
- //WHY NO check for prev device here?
- if (device != mCurDevice) {
- if((mCurDevice & AudioSystem::DEVICE_OUT_ALL_A2DP) &&
- (device & AudioSystem::DEVICE_OUT_ALL_A2DP)) {
- activeUsecase = getA2DPActiveUseCases_l();
- stopA2dpPlayback_l(activeUsecase);
- mALSADevice->route(&(*it),(uint32_t)device, newMode);
- mRouteAudioToA2dp = true;
- startA2dpPlayback_l(activeUsecase);
- } else {
- mALSADevice->route(&(*it),(uint32_t)device, newMode);
- }
- }
- if (activeUsecase == USECASE_FM){
- err = startA2dpPlayback_l(activeUsecase);
- if(err) {
- ALOGW("startA2dpPlayback_l for hardware output failed err = %d", err);
- stopA2dpPlayback_l(activeUsecase);
- }
- }
- }
- if (device != mCurDevice) {
- resumeIfUseCaseTunnelOrLPA();
- }
- if(err) {
- mRouteAudioToA2dp = false;
- mALSADevice->route(&(*it),(uint32_t)mCurDevice, newMode);
- return err;
- }
- } else if(device & AudioSystem::DEVICE_OUT_ALL &&
- !(device & AudioSystem::DEVICE_OUT_ALL_A2DP) &&
- mRouteAudioToA2dp == true ) {
- ALOGV(" A2DP Disable on hardware output");
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- status_t err;
- uint32_t activeUsecase = getA2DPActiveUseCases_l();
- err = stopA2dpPlayback_l(activeUsecase);
- if(err) {
- ALOGW("stop A2dp playback for hardware output failed = %d", err);
- return err;
- }
- if (device != mCurDevice) {
- mALSADevice->route(&(*it),(uint32_t)device, newMode);
- }
- } else {
- setInChannels(device);
+ {
ALSAHandleList::iterator it = mDeviceList.end();
it--;
mALSADevice->route(&(*it), (uint32_t)device, newMode);
}
}
mCurDevice = device;
- return NO_ERROR;
-}
-
-void AudioHardwareALSA::setInChannels(int device)
-{
- ALSAHandleList::iterator it;
-
- if (device & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
- for(it = mDeviceList.begin(); it != mDeviceList.end(); ++it) {
- if (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC,
- strlen(SND_USE_CASE_VERB_HIFI_REC)) ||
- !strncmp(it->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
- strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
- mALSADevice->setInChannels(it->channels);
- return;
- }
- }
- }
-
- mALSADevice->setInChannels(1);
}
uint32_t AudioHardwareALSA::getVoipMode(int format)
{
switch(format) {
- case AUDIO_FORMAT_PCM_16_BIT:
+ case AudioSystem::PCM_16_BIT:
return MODE_PCM;
break;
- case AUDIO_FORMAT_AMR_NB:
+ case AudioSystem::AMR_NB:
return MODE_AMR;
break;
- case AUDIO_FORMAT_AMR_WB:
+ case AudioSystem::AMR_WB:
return MODE_AMR_WB;
break;
-#ifdef QCOM_AUDIO_FORMAT_ENABLED
- case AUDIO_FORMAT_EVRC:
+#ifdef QCOM_QCHAT_ENABLED
+ case AudioSystem::EVRC:
return MODE_IS127;
break;
- case AUDIO_FORMAT_EVRCB:
+ case AudioSystem::EVRCB:
return MODE_4GV_NB;
break;
- case AUDIO_FORMAT_EVRCWB:
+ case AudioSystem::EVRCWB:
return MODE_4GV_WB;
break;
#endif
+
default:
return MODE_PCM;
}
@@ -980,9 +700,6 @@
AudioStreamOut *
AudioHardwareALSA::openOutputStream(uint32_t devices,
-#ifdef QCOM_OUTPUT_FLAGS_ENABLED
- audio_output_flags_t flags,
-#endif
int *format,
uint32_t *channels,
uint32_t *sampleRate,
@@ -995,30 +712,7 @@
audio_output_flags_t flag = static_cast<audio_output_flags_t> (*status);
status_t err = BAD_VALUE;
-#ifdef QCOM_OUTPUT_FLAGS_ENABLED
- if (flags & AUDIO_OUTPUT_FLAG_LPA) {
- AudioSessionOutALSA *out = new AudioSessionOutALSA(this, devices, *format, *channels,
- *sampleRate, 0, &err);
- if(err != NO_ERROR) {
- delete out;
- out = NULL;
- }
- if (status) *status = err;
- return out;
- }
-
- if (flags & AUDIO_OUTPUT_FLAG_TUNNEL) {
- AudioSessionOutALSA *out = new AudioSessionOutALSA(this, devices, *format, *channels,
- *sampleRate, 1, &err);
- if(err != NO_ERROR) {
- delete out;
- out = NULL;
- }
- if (status) *status = err;
- return out;
- }
-#endif
-
+ *status = NO_ERROR;
AudioStreamOutALSA *out = 0;
ALSAHandleList::iterator it;
@@ -1028,14 +722,9 @@
return out;
}
- if(devices & AudioSystem::DEVICE_OUT_ALL_A2DP) {
- ALOGV("Set Capture from proxy true");
- mRouteAudioToA2dp = true;
- }
-
-#ifdef QCOM_OUTPUT_FLAGS_ENABLED
- if((flags & AUDIO_OUTPUT_FLAG_DIRECT) && (flags & AUDIO_OUTPUT_FLAG_VOIP_RX)&&
+# if 0
+ if((devices == AudioSystem::DEVICE_OUT_DIRECTOUTPUT) &&
((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) {
bool voipstream_active = false;
for(it = mDeviceList.begin();
@@ -1049,7 +738,6 @@
}
if(voipstream_active == false) {
mVoipStreamCount = 0;
- mVoipMicMute = false;
alsa_handle_t alsa_handle;
unsigned long bufferSize;
if(*sampleRate == VOIP_SAMPLING_RATE_8K) {
@@ -1067,7 +755,7 @@
alsa_handle.bufferSize = bufferSize;
alsa_handle.devices = devices;
alsa_handle.handle = 0;
- if(*format == AUDIO_FORMAT_PCM_16_BIT)
+ if(*format == AudioSystem::PCM_16_BIT)
alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
else
alsa_handle.format = *format;
@@ -1093,17 +781,17 @@
(mCurDevice & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
(mCurDevice & AudioSystem::DEVICE_OUT_PROXY)){
ALOGD("Routing to proxy for normal voip call in openOutputStream");
- mALSADevice->route(&(*it), mCurDevice, AUDIO_MODE_IN_COMMUNICATION);
-#ifdef QCOM_USBAUDIO_ENABLED
- ALOGD("enabling VOIP in openoutputstream, musbPlaybackState: %d", musbPlaybackState);
+ mCurDevice |= AudioSystem::DEVICE_OUT_PROXY;
+ alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY;
+ mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
+ ALOGD("enabling VOIP in openoutputstream, musbPlaybackState: %d", musbPlaybackState);
startUsbPlaybackIfNotStarted();
musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState);
startUsbRecordingIfNotStarted();
musbRecordingState |= USBRECBIT_VOIPCALL;
-#endif
- } else{
- mALSADevice->route(&(*it), mCurDevice, AUDIO_MODE_IN_COMMUNICATION);
+ } else{
+ mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
}
if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL);
@@ -1196,6 +884,7 @@
if (status) *status = err;
return out;
} else {
+
alsa_handle_t alsa_handle;
unsigned long bufferSize = DEFAULT_BUFFER_SIZE;
@@ -1212,52 +901,54 @@
alsa_handle.latency = PLAYBACK_LATENCY;
alsa_handle.rxHandle = 0;
alsa_handle.ucMgr = mUcMgr;
- alsa_handle.session = NULL;
- alsa_handle.isFastOutput = false;
+ alsa_handle.isDeepbufferOutput = false;
char *use_case;
snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
-#ifdef QCOM_OUTPUT_FLAGS_ENABLED
- if (flags & AUDIO_OUTPUT_FLAG_FAST) {
- alsa_handle.bufferSize = PLAYBACK_LOW_LATENCY_BUFFER_SIZE;
- alsa_handle.latency = PLAYBACK_LOW_LATENCY;
- alsa_handle.isFastOutput = true;
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
- }
- } else
-#endif
- {
+ if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
+ ALOGD("openOutputStream: DeepBuffer Output");
+ alsa_handle.isDeepbufferOutput = true;
if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI, sizeof(alsa_handle.useCase));
} else {
strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC, sizeof(alsa_handle.useCase));
}
+ } else {
+ ALOGD("openOutputStream: Lowlatency Output");
+ alsa_handle.bufferSize = PLAYBACK_LOW_LATENCY_BUFFER_SIZE;
+ alsa_handle.latency = PLAYBACK_LOW_LATENCY_MEASURED;
+ if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
+ } else {
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
+ }
}
free(use_case);
mDeviceList.push_back(alsa_handle);
ALSAHandleList::iterator it = mDeviceList.end();
it--;
- ALOGD("useCase %s", it->useCase);
- mALSADevice->route(&(*it), devices, mode());
-#ifdef QCOM_OUTPUT_FLAGS_ENABLED
- if (flags & AUDIO_OUTPUT_FLAG_FAST) {
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) {
- snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC);
- }
- } else
+ ALOGV("useCase %s", it->useCase);
+#ifdef QCOM_USBAUDIO_ENABLED
+ if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
+ (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
+ ALOGD("Routing to proxy for normal playback in openOutputStream");
+ devices |= AudioSystem::DEVICE_OUT_PROXY;
+ }
#endif
- {
+ mALSADevice->route(&(*it), devices, mode());
+ if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI)) {
snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI);
} else {
snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC);
}
+ } else {
+ if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) {
+ snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC);
+ } else {
+ snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC);
+ }
}
err = mALSADevice->open(&(*it));
if (err) {
@@ -1278,6 +969,100 @@
delete out;
}
+#ifdef QCOM_TUNNEL_LPA_ENABLED
+AudioStreamOut *
+AudioHardwareALSA::openOutputSession(uint32_t devices,
+ int *format,
+ status_t *status,
+ int sessionId,
+ uint32_t samplingRate,
+ uint32_t channels)
+{
+ Mutex::Autolock autoLock(mLock);
+ ALOGD("openOutputSession = %d" ,sessionId);
+ AudioStreamOutALSA *out = 0;
+ status_t err = BAD_VALUE;
+
+ alsa_handle_t alsa_handle;
+ unsigned long bufferSize = DEFAULT_BUFFER_SIZE;
+
+ for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
+ bufferSize &= ~b;
+
+ alsa_handle.module = mALSADevice;
+ alsa_handle.bufferSize = bufferSize;
+ alsa_handle.devices = devices;
+ alsa_handle.handle = 0;
+ alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
+ alsa_handle.channels = DEFAULT_CHANNEL_MODE;
+ alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
+ alsa_handle.latency = VOICE_LATENCY;
+ alsa_handle.rxHandle = 0;
+ alsa_handle.ucMgr = mUcMgr;
+
+ char *use_case;
+ if(sessionId == TUNNEL_SESSION_ID) {
+ snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
+ if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_TUNNEL, sizeof(alsa_handle.useCase));
+ } else {
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_TUNNEL, sizeof(alsa_handle.useCase));
+ }
+ } else {
+ snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
+ if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER, sizeof(alsa_handle.useCase));
+ } else {
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LPA, sizeof(alsa_handle.useCase));
+ }
+ }
+ free(use_case);
+ mDeviceList.push_back(alsa_handle);
+ ALSAHandleList::iterator it = mDeviceList.end();
+ it--;
+ ALOGD("useCase %s", it->useCase);
+#ifdef QCOM_USBAUDIO_ENABLED
+ if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
+ (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
+ ALOGD("Routing to proxy for LPA in openOutputSession");
+ devices |= AudioSystem::DEVICE_OUT_PROXY;
+ mALSADevice->route(&(*it), devices, mode());
+ devices = AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET;
+ ALOGD("Starting USBPlayback for LPA");
+ startUsbPlaybackIfNotStarted();
+ musbPlaybackState |= USBPLAYBACKBIT_LPA;
+ } else
+#endif
+ {
+ mALSADevice->route(&(*it), devices, mode());
+ }
+ if(sessionId == TUNNEL_SESSION_ID) {
+ if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) {
+ snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_TUNNEL);
+ } else {
+ snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_TUNNEL);
+ }
+ }
+ else {
+ if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) {
+ snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOW_POWER);
+ } else {
+ snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LPA);
+ }
+ }
+ err = mALSADevice->open(&(*it));
+ out = new AudioStreamOutALSA(this, &(*it));
+
+ if (status) *status = err;
+ return out;
+}
+
+void
+AudioHardwareALSA::closeOutputSession(AudioStreamOut* out)
+{
+ delete out;
+}
+#endif
AudioStreamIn *
AudioHardwareALSA::openInputStream(uint32_t devices,
@@ -1296,10 +1081,9 @@
AudioStreamInALSA *in = 0;
ALSAHandleList::iterator it;
- ALOGD("openInputStream: devices 0x%x format 0x%x channels %d sampleRate %d", devices, *format, *channels, *sampleRate);
+ ALOGD("openInputStream: devices 0x%x channels %d sampleRate %d", devices, *channels, *sampleRate);
if (devices & (devices - 1)) {
if (status) *status = err;
- ALOGE("openInputStream failed error:0x%x devices:%x",err,devices);
return in;
}
@@ -1317,7 +1101,6 @@
}
if(voipstream_active == false) {
mVoipStreamCount = 0;
- mVoipMicMute = false;
alsa_handle_t alsa_handle;
unsigned long bufferSize;
if(*sampleRate == VOIP_SAMPLING_RATE_8K) {
@@ -1335,7 +1118,7 @@
alsa_handle.bufferSize = bufferSize;
alsa_handle.devices = devices;
alsa_handle.handle = 0;
- if(*format == AUDIO_FORMAT_PCM_16_BIT)
+ if(*format == AudioSystem::PCM_16_BIT)
alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
else
alsa_handle.format = *format;
@@ -1360,7 +1143,7 @@
if((mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
(mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
ALOGD("Routing everything from proxy for voipcall");
- mALSADevice->route(&(*it), AudioSystem::DEVICE_IN_PROXY, AUDIO_MODE_IN_COMMUNICATION);
+ mALSADevice->route(&(*it), AudioSystem::DEVICE_IN_PROXY, AudioSystem::MODE_IN_COMMUNICATION);
ALOGD("enabling VOIP in openInputstream, musbPlaybackState: %d", musbPlaybackState);
startUsbPlaybackIfNotStarted();
musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
@@ -1370,7 +1153,7 @@
} else
#endif
{
- mALSADevice->route(&(*it),mCurDevice, AUDIO_MODE_IN_COMMUNICATION);
+ mALSADevice->route(&(*it),mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
}
if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL);
@@ -1380,10 +1163,8 @@
if(sampleRate) {
it->sampleRate = *sampleRate;
}
- if(channels) {
+ if(channels)
it->channels = AudioSystem::popCount(*channels);
- setInChannels(devices);
- }
err = mALSADevice->startVoipCall(&(*it));
if (err) {
ALOGE("Error opening pcm input device");
@@ -1407,10 +1188,7 @@
alsa_handle.bufferSize = bufferSize;
alsa_handle.devices = devices;
alsa_handle.handle = 0;
- if(*format == AUDIO_FORMAT_PCM_16_BIT)
- alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
- else
- alsa_handle.format = *format;
+ alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
alsa_handle.channels = VOICE_CHANNEL_MODE;
alsa_handle.sampleRate = android::AudioRecord::DEFAULT_SAMPLE_RATE;
alsa_handle.latency = RECORD_LATENCY;
@@ -1419,37 +1197,27 @@
snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
- (newMode == AUDIO_MODE_IN_CALL)) {
+ (newMode == AudioSystem::MODE_IN_CALL)) {
ALOGD("openInputStream: into incall recording, channels %d", *channels);
mIncallMode = *channels;
- if ((*channels & AUDIO_CHANNEL_IN_VOICE_UPLINK) &&
- (*channels & AUDIO_CHANNEL_IN_VOICE_DNLINK)) {
+ if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
+ (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
if (mFusion3Platform) {
mALSADevice->setVocRecMode(INCALL_REC_STEREO);
strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
sizeof(alsa_handle.useCase));
} else {
- if (*format == AUDIO_FORMAT_AMR_WB) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL,
- sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
- sizeof(alsa_handle.useCase));
- }
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
+ sizeof(alsa_handle.useCase));
}
- } else if (*channels & AUDIO_CHANNEL_IN_VOICE_DNLINK) {
+ } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
if (mFusion3Platform) {
mALSADevice->setVocRecMode(INCALL_REC_MONO);
strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
sizeof(alsa_handle.useCase));
} else {
- if (*format == AUDIO_FORMAT_AMR_WB) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL,
- sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
- sizeof(alsa_handle.useCase));
- }
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
+ sizeof(alsa_handle.useCase));
}
}
#ifdef QCOM_FM_ENABLED
@@ -1459,50 +1227,37 @@
strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, sizeof(alsa_handle.useCase));
#endif
} else {
- char value[128];
- property_get("persist.audio.lowlatency.rec",value,"0");
+ char value[128];
+ property_get("persist.audio.lowlatency.rec",value,"0");
if (!strcmp("true", value)) {
strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
- } else if (*format == AUDIO_FORMAT_AMR_WB) {
- ALOGV("Format AMR_WB, open compressed capture");
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, sizeof(alsa_handle.useCase));
} else {
strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(alsa_handle.useCase));
}
}
} else {
if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
- (newMode == AUDIO_MODE_IN_CALL)) {
+ (newMode == AudioSystem::MODE_IN_CALL)) {
ALOGD("openInputStream: incall recording, channels %d", *channels);
mIncallMode = *channels;
- if ((*channels & AUDIO_CHANNEL_IN_VOICE_UPLINK) &&
- (*channels & AUDIO_CHANNEL_IN_VOICE_DNLINK)) {
+ if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
+ (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
if (mFusion3Platform) {
mALSADevice->setVocRecMode(INCALL_REC_STEREO);
strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC,
sizeof(alsa_handle.useCase));
} else {
- if (*format == AUDIO_FORMAT_AMR_WB) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL,
- sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_UL_DL_REC,
- sizeof(alsa_handle.useCase));
- }
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_UL_DL_REC,
+ sizeof(alsa_handle.useCase));
}
- } else if (*channels & AUDIO_CHANNEL_IN_VOICE_DNLINK) {
+ } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
if (mFusion3Platform) {
mALSADevice->setVocRecMode(INCALL_REC_MONO);
strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC,
sizeof(alsa_handle.useCase));
} else {
- if (*format == AUDIO_FORMAT_AMR_WB) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL,
- sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DL_REC,
- sizeof(alsa_handle.useCase));
- }
+ strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DL_REC,
+ sizeof(alsa_handle.useCase));
}
}
#ifdef QCOM_FM_ENABLED
@@ -1516,8 +1271,6 @@
property_get("persist.audio.lowlatency.rec",value,"0");
if (!strcmp("true", value)) {
strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(alsa_handle.useCase));
- } else if (*format == AUDIO_FORMAT_AMR_WB) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, sizeof(alsa_handle.useCase));
} else {
strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(alsa_handle.useCase));
}
@@ -1530,14 +1283,13 @@
//update channel info before do routing
if(channels) {
it->channels = AudioSystem::popCount((*channels) &
- (AUDIO_CHANNEL_IN_STEREO
- | AUDIO_CHANNEL_IN_MONO
+ (AudioSystem::CHANNEL_IN_STEREO
+ | AudioSystem::CHANNEL_IN_MONO
#ifdef QCOM_SSR_ENABLED
- | AUDIO_CHANNEL_IN_5POINT1
+ | AudioSystem::CHANNEL_IN_5POINT1
#endif
));
ALOGV("updated channel info: channels=%d", it->channels);
- setInChannels(devices);
}
if (devices == AudioSystem::DEVICE_IN_VOICE_CALL){
/* Add current devices info to devices to do route */
@@ -1568,15 +1320,12 @@
if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC) ||
!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) ||
- !strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED) ||
#ifdef QCOM_FM_ENABLED
!strcmp(it->useCase, SND_USE_CASE_VERB_FM_REC) ||
!strcmp(it->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) ||
#endif
!strcmp(it->useCase, SND_USE_CASE_VERB_DL_REC) ||
!strcmp(it->useCase, SND_USE_CASE_VERB_UL_DL_REC) ||
- !strcmp(it->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL) ||
- !strcmp(it->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL) ||
!strcmp(it->useCase, SND_USE_CASE_VERB_INCALL_REC)) {
snd_use_case_set(mUcMgr, "_verb", it->useCase);
} else {
@@ -1587,25 +1336,10 @@
}
if (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
|| !strncmp(it->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
- ALOGV("OpenInoutStream: getInputBufferSize sampleRate:%d format:%d, channels:%d", it->sampleRate,*format,it->channels);
+ ALOGV("OpenInoutStream: Use larger buffer size for 5.1(%s) recording ", it->useCase);
it->bufferSize = getInputBufferSize(it->sampleRate,*format,it->channels);
}
-
-#ifdef QCOM_SSR_ENABLED
- //Check if SSR is supported by reading system property
- char ssr_enabled[6] = "false";
- property_get("ro.qc.sdk.audio.ssr",ssr_enabled,"0");
- if (strncmp("true", ssr_enabled, 4)) {
- if (status) *status = err;
- ALOGE("openInputStream: FAILED:%d. Surround sound recording is not supported",*status);
- return in;
- }
-#endif
err = mALSADevice->open(&(*it));
- if (*format == AUDIO_FORMAT_AMR_WB) {
- ALOGV("### Setting bufsize to 61");
- it->bufferSize = 61;
- }
if (err) {
ALOGE("Error opening pcm input device");
} else {
@@ -1625,28 +1359,11 @@
status_t AudioHardwareALSA::setMicMute(bool state)
{
- int newMode = mode();
- ALOGD("setMicMute newMode %d state:%d",newMode,state);
- if(newMode == AUDIO_MODE_IN_COMMUNICATION) {
- if (mVoipMicMute != state) {
- mVoipMicMute = state;
- ALOGD("setMicMute: mVoipMicMute %d", mVoipMicMute);
- if(mALSADevice) {
- mALSADevice->setVoipMicMute(state);
- }
- }
- } else {
- if (mMicMute != state) {
- mMicMute = state;
- ALOGD("setMicMute: mMicMute %d", mMicMute);
- if(mALSADevice) {
- if(mCSCallActive == CS_ACTIVE)
- mALSADevice->setMicMute(state);
- else if(mSGLTECallActive == CS_ACTIVE_SESSION2)
- mALSADevice->setSGLTEMicMute(state);
- if(mVolteCallActive == IMS_ACTIVE)
- mALSADevice->setVoLTEMicMute(state);
- }
+ if (mMicMute != state) {
+ mMicMute = state;
+ ALOGD("setMicMute: mMicMute %d", mMicMute);
+ if(mALSADevice) {
+ mALSADevice->setMicMute(state);
}
}
return NO_ERROR;
@@ -1654,12 +1371,7 @@
status_t AudioHardwareALSA::getMicMute(bool *state)
{
- int newMode = mode();
- if(newMode == AUDIO_MODE_IN_COMMUNICATION) {
- *state = mVoipMicMute;
- } else {
- *state = mMicMute;
- }
+ *state = mMicMute;
return NO_ERROR;
}
@@ -1671,7 +1383,7 @@
size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
{
size_t bufferSize = 0;
- if (format == AUDIO_FORMAT_PCM_16_BIT) {
+ if (format == AudioSystem::PCM_16_BIT) {
if(sampleRate == 8000 || sampleRate == 16000 || sampleRate == 32000) {
bufferSize = (sampleRate * channelCount * 20 * sizeof(int16_t)) / 1000;
} else if (sampleRate == 11025 || sampleRate == 12000) {
@@ -1690,9 +1402,7 @@
#ifdef QCOM_FM_ENABLED
void AudioHardwareALSA::handleFm(int device)
{
- int newMode = mode();
- uint32_t activeUsecase = USECASE_NONE;
-
+int newMode = mode();
if(device & AudioSystem::DEVICE_OUT_FM && mIsFmActive == 0) {
// Start FM Radio on current active device
unsigned long bufferSize = FM_BUFFER_SIZE;
@@ -1723,6 +1433,12 @@
mDeviceList.push_back(alsa_handle);
ALSAHandleList::iterator it = mDeviceList.end();
it--;
+ if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
+ (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
+ device |= AudioSystem::DEVICE_OUT_PROXY;
+ alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY;
+ ALOGD("Routing to proxy for FM case");
+ }
mALSADevice->route(&(*it), (uint32_t)device, newMode);
if(!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) {
snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_DIGITAL_RADIO);
@@ -1730,25 +1446,12 @@
snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_FM);
}
mALSADevice->startFm(&(*it));
- activeUsecase = useCaseStringToEnum(it->useCase);
-#ifdef QCOM_USBAUDIO_ENABLED
if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
(device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
ALOGD("Starting FM, musbPlaybackState %d", musbPlaybackState);
startUsbPlaybackIfNotStarted();
musbPlaybackState |= USBPLAYBACKBIT_FM;
}
-#endif
- if(device & AudioSystem::DEVICE_OUT_ALL_A2DP) {
- status_t err = NO_ERROR;
- mRouteAudioToA2dp = true;
- err = startA2dpPlayback_l(activeUsecase);
- if(err) {
- ALOGE("startA2dpPlayback_l for hardware output failed err = %d", err);
- stopA2dpPlayback_l(activeUsecase);
- }
- }
-
} else if (!(device & AudioSystem::DEVICE_OUT_FM) && mIsFmActive == 1) {
//i Stop FM Radio
ALOGV("Stop FM");
@@ -1757,27 +1460,17 @@
if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
(!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) {
mALSADevice->close(&(*it));
- activeUsecase = useCaseStringToEnum(it->useCase);
//mALSADevice->route(&(*it), (uint32_t)device, newMode);
mDeviceList.erase(it);
break;
}
}
mIsFmActive = 0;
-#ifdef QCOM_USBAUDIO_ENABLED
musbPlaybackState &= ~USBPLAYBACKBIT_FM;
if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
(device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
closeUsbPlaybackIfNothingActive();
}
-#endif
- if(mRouteAudioToA2dp == true) {
- status_t err = NO_ERROR;
- err = stopA2dpPlayback_l(activeUsecase);
- if(err)
- ALOGE("stopA2dpPlayback_l for hardware output failed err = %d", err);
- }
-
}
}
#endif
@@ -1795,8 +1488,6 @@
break;
}
}
- mIsVoicePathActive = false;
-
#ifdef QCOM_USBAUDIO_ENABLED
if(musbPlaybackState & USBPLAYBACKBIT_VOICECALL) {
ALOGD("Voice call ended on USB");
@@ -1836,7 +1527,13 @@
mDeviceList.push_back(alsa_handle);
ALSAHandleList::iterator it = mDeviceList.end();
it--;
- setInChannels(device);
+#ifdef QCOM_USBAUDIO_ENABLED
+ if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
+ (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
+ device |= AudioSystem::DEVICE_OUT_PROXY;
+ alsa_handle.devices = device;
+ }
+#endif
mALSADevice->route(&(*it), (uint32_t)device, mode);
if (!strcmp(it->useCase, verb)) {
snd_use_case_set(mUcMgr, "_verb", verb);
@@ -1844,8 +1541,6 @@
snd_use_case_set(mUcMgr, "_enamod", modifier);
}
mALSADevice->startVoiceCall(&(*it));
- mIsVoicePathActive = true;
-
#ifdef QCOM_USBAUDIO_ENABLED
if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
(device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
@@ -1918,70 +1613,6 @@
}
return isRouted;
}
-
-bool AudioHardwareALSA::routeSGLTECall(int device, int newMode)
-{
-int SGLTECallState = mCallState&0xF00;
- bool isRouted = false;
- switch (SGLTECallState) {
- case CS_INACTIVE_SESSION2:
- if (mSGLTECallActive != CS_INACTIVE_SESSION2) {
- ALOGV("doRouting: Disabling voice call session2");
- disableVoiceCall((char *)SND_USE_CASE_VERB_SGLTECALL,
- (char *)SND_USE_CASE_MOD_PLAY_SGLTE, newMode, device);
- isRouted = true;
- mSGLTECallActive = CS_INACTIVE_SESSION2;
- }
- break;
- case CS_ACTIVE_SESSION2:
- if (mSGLTECallActive == CS_INACTIVE_SESSION2) {
- ALOGV("doRouting: Enabling CS voice call session2 ");
- enableVoiceCall((char *)SND_USE_CASE_VERB_SGLTECALL,
- (char *)SND_USE_CASE_MOD_PLAY_SGLTE, newMode, device);
- isRouted = true;
- mSGLTECallActive = CS_ACTIVE_SESSION2;
- } else if (mSGLTECallActive == CS_HOLD_SESSION2) {
- ALOGV("doRouting: Resume voice call session2 from hold state");
- ALSAHandleList::iterator vt_it;
- for(vt_it = mDeviceList.begin();
- vt_it != mDeviceList.end(); ++vt_it) {
- if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_SGLTECALL,
- strlen(SND_USE_CASE_VERB_SGLTECALL))) ||
- (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_SGLTE,
- strlen(SND_USE_CASE_MOD_PLAY_SGLTE)))) {
- alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
- mSGLTECallActive = CS_ACTIVE_SESSION2;
- if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0)
- ALOGE("SGLTE resume failed");
- break;
- }
- }
- }
- break;
- case CS_HOLD_SESSION2:
- if (mSGLTECallActive == CS_ACTIVE_SESSION2) {
- ALOGV("doRouting: Voice call session2 going to Hold");
- ALSAHandleList::iterator vt_it;
- for(vt_it = mDeviceList.begin();
- vt_it != mDeviceList.end(); ++vt_it) {
- if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_SGLTECALL,
- strlen(SND_USE_CASE_VERB_SGLTECALL))) ||
- (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_SGLTE,
- strlen(SND_USE_CASE_MOD_PLAY_SGLTE)))) {
- mSGLTECallActive = CS_HOLD_SESSION2;
- alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
- if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0)
- ALOGE("Voice session2 pause failed");
- break;
- }
- }
- }
- break;
- }
- return isRouted;
-}
-
-
bool AudioHardwareALSA::routeVoLTECall(int device, int newMode)
{
int volteCallState = mCallState&0xF0;
@@ -2044,378 +1675,4 @@
return isRouted;
}
-void AudioHardwareALSA::pauseIfUseCaseTunnelOrLPA() {
- for (ALSAHandleList::iterator it = mDeviceList.begin();
- it != mDeviceList.end(); it++) {
- if((!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
- strlen(SND_USE_CASE_VERB_HIFI_TUNNEL))) ||
- (!strncmp(it->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
- strlen(SND_USE_CASE_MOD_PLAY_TUNNEL))) ||
- (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
- strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER))) ||
- (!strncmp(it->useCase, SND_USE_CASE_MOD_PLAY_LPA,
- strlen(SND_USE_CASE_MOD_PLAY_LPA)))) {
- it->session->pause_l();
- }
- }
-}
-
-void AudioHardwareALSA::resumeIfUseCaseTunnelOrLPA() {
- for (ALSAHandleList::iterator it = mDeviceList.begin();
- it != mDeviceList.end(); it++) {
- if((!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
- strlen(SND_USE_CASE_VERB_HIFI_TUNNEL))) ||
- (!strncmp(it->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
- strlen(SND_USE_CASE_MOD_PLAY_TUNNEL))) ||
- (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
- strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER))) ||
- (!strncmp(it->useCase, SND_USE_CASE_MOD_PLAY_LPA,
- strlen(SND_USE_CASE_MOD_PLAY_LPA)))) {
- it->session->resume_l();
- }
- }
-}
-
-status_t AudioHardwareALSA::startA2dpPlayback(uint32_t activeUsecase) {
-
- Mutex::Autolock autoLock(mLock);
- status_t err = startA2dpPlayback_l(activeUsecase);
- if(err) {
- ALOGE("startA2dpPlayback_l = %d", err);
- }
- return err;
-}
-status_t AudioHardwareALSA::startA2dpPlayback_l(uint32_t activeUsecase) {
-
- ALOGV("startA2dpPlayback_l::usecase = %d ", activeUsecase);
- status_t err = NO_ERROR;
-
- if (activeUsecase != USECASE_NONE && !mIsA2DPEnabled) {
- //setA2DPActiveUseCases_l(activeUsecase);
- Mutex::Autolock autolock1(mA2dpMutex);
- err = mALSADevice->openProxyDevice();
- if(err) {
- ALOGE("openProxyDevice failed = %d", err);
- }
-
- err = openA2dpOutput();
- if(err) {
- ALOGE("openA2DPOutput failed = %d",err);
- return err;
- }
-
- mKillA2DPThread = false;
- err = pthread_create(&mA2dpThread, (const pthread_attr_t *) NULL,
- a2dpThreadWrapper,
- this);
- if(err) {
- ALOGE("thread create failed = %d", err);
- return err;
- }
- mA2dpThreadAlive = true;
- mIsA2DPEnabled = true;
-
-#ifdef OUTPUT_BUFFER_LOG
- sprintf(outputfilename, "%s%d%s", outputfilename, number,".pcm");
- outputBufferFile1 = fopen (outputfilename, "ab");
- number++;
-#endif
- }
-
- setA2DPActiveUseCases_l(activeUsecase);
- mALSADevice->resumeProxy();
-
- ALOGV("A2DP signal");
- mA2dpCv.signal();
- return err;
-}
-
-status_t AudioHardwareALSA::stopA2dpPlayback(uint32_t activeUsecase) {
- Mutex::Autolock autoLock(mLock);
- status_t err = stopA2dpPlayback_l(activeUsecase);
- if(err) {
- ALOGE("stopA2dpPlayback = %d", err);
- }
- return err;
-}
-
-status_t AudioHardwareALSA::stopA2dpPlayback_l(uint32_t activeUsecase) {
-
- ALOGV("stopA2dpPlayback = %d", activeUsecase);
- status_t err = NO_ERROR;
- suspendA2dpPlayback_l(activeUsecase);
- {
- Mutex::Autolock autolock1(mA2dpMutex);
- ALOGV("stopA2dpPlayback getA2DPActiveUseCases_l = %d",
- getA2DPActiveUseCases_l());
-
- if(!getA2DPActiveUseCases_l()) {
- mIsA2DPEnabled = false;
-
- mA2dpMutex.unlock();
- err = stopA2dpThread();
- mA2dpMutex.lock();
-
- if(err) {
- ALOGE("stopA2dpOutput = %d" ,err);
- }
-
- err = closeA2dpOutput();
- if(err) {
- ALOGE("closeA2dpOutput = %d" ,err);
- }
-
- err = mALSADevice->closeProxyDevice();
- if(err) {
- ALOGE("closeProxyDevice failed = %d", err);
- }
-
- mA2DPActiveUseCases = 0x0;
- mRouteAudioToA2dp = false;
-
-#ifdef OUTPUT_BUFFER_LOG
- ALOGV("close file output");
- fclose (outputBufferFile1);
-#endif
- }
- }
- return err;
-}
-
-status_t AudioHardwareALSA::openA2dpOutput()
-{
- hw_module_t *mod;
- int format = AUDIO_FORMAT_PCM_16_BIT;
- uint32_t channels = AUDIO_CHANNEL_OUT_STEREO;
- uint32_t sampleRate = AFE_PROXY_SAMPLE_RATE;
- status_t status;
- ALOGV("openA2dpOutput");
- struct audio_config config;
- config.sample_rate = AFE_PROXY_SAMPLE_RATE;
- config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- config.format = AUDIO_FORMAT_PCM_16_BIT;
-
- //TODO : Confirm AUDIO_HARDWARE_MODULE_ID_A2DP ???
- int rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID/*_A2DP*/, (const char*)"a2dp",
- (const hw_module_t**)&mod);
- if (rc) {
- ALOGE("Could not get a2dp hardware module");
- return NO_INIT;
- }
-
- rc = audio_hw_device_open(mod, &mA2dpDevice);
- if(rc) {
- ALOGE("couldn't open a2dp audio hw device");
- return NO_INIT;
- }
- //TODO: unique id 0?
- status = mA2dpDevice->open_output_stream(mA2dpDevice, 0,((audio_devices_t)(AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP)),
- (audio_output_flags_t)AUDIO_OUTPUT_FLAG_NONE, &config, &mA2dpStream);
- if(status != NO_ERROR) {
- ALOGE("Failed to open output stream for a2dp: status %d", status);
- }
- return status;
-}
-
-status_t AudioHardwareALSA::closeA2dpOutput()
-{
- ALOGV("closeA2dpOutput");
- if(!mA2dpDevice){
- ALOGE("No Aactive A2dp output found");
- return NO_ERROR;
- }
-
- mA2dpDevice->close_output_stream(mA2dpDevice, mA2dpStream);
- mA2dpStream = NULL;
-
- audio_hw_device_close(mA2dpDevice);
- mA2dpDevice = NULL;
- return NO_ERROR;
-}
-
-status_t AudioHardwareALSA::stopA2dpThread()
-{
- ALOGV("stopA2dpThread");
- status_t err = NO_ERROR;
- if (!mA2dpThreadAlive) {
- ALOGD("Return - thread not live");
- return NO_ERROR;
- }
- mKillA2DPThread = true;
- err = mALSADevice->exitReadFromProxy();
- if(err) {
- ALOGE("exitReadFromProxy failed = %d", err);
- }
- mA2dpCv.signal();
- int ret = pthread_join(mA2dpThread,NULL);
- ALOGD("a2dp thread killed = %d", ret);
- return err;
-}
-
-void *AudioHardwareALSA::a2dpThreadWrapper(void *me) {
- static_cast<AudioHardwareALSA *>(me)->a2dpThreadFunc();
- return NULL;
-}
-
-void AudioHardwareALSA::a2dpThreadFunc() {
- if(!mA2dpStream) {
- ALOGE("No valid a2dp output stream found");
- return;
- }
- if(!mALSADevice->isProxyDeviceOpened()) {
- ALOGE("No valid mProxyPcmHandle found");
- return;
- }
-
- pid_t tid = gettid();
- androidSetThreadPriority(tid, ANDROID_PRIORITY_AUDIO);
- prctl(PR_SET_NAME, (unsigned long)"A2DPThread", 0, 0, 0);
-
- int ionBufCount = 0;
- uint32_t bytesWritten = 0;
- uint32_t numBytesRemaining = 0;
- uint32_t bytesAvailInBuffer = 0;
- void *data;
- int err = NO_ERROR;
- ssize_t size = 0;
-
- mALSADevice->resetProxyVariables();
-
- ALOGV("mKillA2DPThread = %d", mKillA2DPThread);
- while(!mKillA2DPThread) {
-
- {
- Mutex::Autolock autolock1(mA2dpMutex);
- if (!mA2dpStream || !mIsA2DPEnabled ||
- !mALSADevice->isProxyDeviceOpened() ||
- (mALSADevice->isProxyDeviceSuspended()) ||
- (err != NO_ERROR)) {
- ALOGD("A2DPThreadEntry:: proxy opened = %d,\
- proxy suspended = %d,err =%d,\
- mA2dpStream = %p",\
- mALSADevice->isProxyDeviceOpened(),\
- mALSADevice->isProxyDeviceSuspended(),err,mA2dpStream);
- ALOGD("A2DPThreadEntry:: Waiting on mA2DPCv");
- mA2dpCv.wait(mA2dpMutex);
- ALOGD("A2DPThreadEntry:: received signal to wake up");
- mA2dpMutex.unlock();
- continue;
- }
- }
- err = mALSADevice->readFromProxy(&data, &size);
- if(err < 0) {
- ALOGE("ALSADevice readFromProxy returned err = %d,data = %p,\
- size = %ld", err, data, size);
- continue;
- }
-
-#ifdef OUTPUT_BUFFER_LOG
- if (outputBufferFile1)
- {
- fwrite (data,1,size,outputBufferFile1);
- }
-#endif
- void *copyBuffer = data;
- numBytesRemaining = size;
- while (err == OK && (numBytesRemaining > 0) && !mKillA2DPThread
- && mIsA2DPEnabled ) {
- {
- Mutex::Autolock autolock1(mA2dpMutex);
- bytesAvailInBuffer = mA2dpStream->common.get_buffer_size(&mA2dpStream->common);
- }
- uint32_t writeLen = bytesAvailInBuffer > numBytesRemaining ?
- numBytesRemaining : bytesAvailInBuffer;
- ALOGV("Writing %d bytes to A2DP ", writeLen);
- {
- Mutex::Autolock autolock1(mA2dpMutex);
- bytesWritten = mA2dpStream->write(mA2dpStream,copyBuffer, writeLen);
- }
- ALOGV("bytesWritten = %d",bytesWritten);
- //Need to check warning here - void used in arithmetic
- copyBuffer = (char *)copyBuffer + bytesWritten;
- numBytesRemaining -= bytesWritten;
- ALOGV("@_@bytes To write2:%d",numBytesRemaining);
- }
- }
-
- mALSADevice->resetProxyVariables();
- mA2dpThreadAlive = false;
- ALOGD("A2DP Thread is dying");
-}
-
-void AudioHardwareALSA::setA2DPActiveUseCases_l(uint32_t activeUsecase)
-{
- mA2DPActiveUseCases |= activeUsecase;
- ALOGD("mA2DPActiveUseCases = %u, activeUsecase = %u", mA2DPActiveUseCases, activeUsecase);
-}
-
-uint32_t AudioHardwareALSA::getA2DPActiveUseCases_l()
-{
- ALOGD("getA2DPActiveUseCases_l: mA2DPActiveUseCases = %u", mA2DPActiveUseCases);
- return mA2DPActiveUseCases;
-}
-
-void AudioHardwareALSA::clearA2DPActiveUseCases_l(uint32_t activeUsecase) {
-
- mA2DPActiveUseCases &= ~activeUsecase;
- ALOGD("clear - mA2DPActiveUseCases = %u, activeUsecase = %u", mA2DPActiveUseCases, activeUsecase);
-
-}
-
-uint32_t AudioHardwareALSA::useCaseStringToEnum(const char *usecase)
-{
- ALOGV("useCaseStringToEnum usecase:%s",usecase);
- uint32_t activeUsecase = USECASE_NONE;
-
- if ((!strncmp(usecase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
- strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER))) ||
- (!strncmp(usecase, SND_USE_CASE_MOD_PLAY_LPA,
- strlen(SND_USE_CASE_MOD_PLAY_LPA)))) {
- activeUsecase = USECASE_HIFI_LOW_POWER;
- } else if ((!strncmp(usecase, SND_USE_CASE_VERB_HIFI_TUNNEL,
- strlen(SND_USE_CASE_VERB_HIFI_TUNNEL))) ||
- (!strncmp(usecase, SND_USE_CASE_MOD_PLAY_TUNNEL,
- strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)))) {
- activeUsecase = USECASE_HIFI_TUNNEL;
- } else if ((!strncmp(usecase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
- strlen(SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC )))||
- (!strncmp(usecase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
- strlen(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)))) {
- activeUsecase = USECASE_HIFI_LOWLATENCY;
- } else if ((!strncmp(usecase, SND_USE_CASE_VERB_DIGITAL_RADIO,
- strlen(SND_USE_CASE_VERB_DIGITAL_RADIO))) ||
- (!strncmp(usecase, SND_USE_CASE_MOD_PLAY_FM,
- strlen(SND_USE_CASE_MOD_PLAY_FM)))||
- (!strncmp(usecase, SND_USE_CASE_VERB_FM_REC,
- strlen(SND_USE_CASE_VERB_FM_REC)))||
- (!strncmp(usecase, SND_USE_CASE_MOD_CAPTURE_FM,
- strlen(SND_USE_CASE_MOD_CAPTURE_FM)))){
- activeUsecase = USECASE_FM;
- } else if ((!strncmp(usecase, SND_USE_CASE_VERB_HIFI,
- strlen(SND_USE_CASE_VERB_HIFI)))||
- (!strncmp(usecase, SND_USE_CASE_MOD_PLAY_MUSIC,
- strlen(SND_USE_CASE_MOD_PLAY_MUSIC)))) {
- activeUsecase = USECASE_HIFI;
- }
- return activeUsecase;
-}
-
-bool AudioHardwareALSA::suspendA2dpPlayback(uint32_t activeUsecase) {
-
- Mutex::Autolock autoLock(mLock);
- suspendA2dpPlayback_l(activeUsecase);
- return NO_ERROR;
-}
-
-bool AudioHardwareALSA::suspendA2dpPlayback_l(uint32_t activeUsecase) {
-
- Mutex::Autolock autolock1(mA2dpMutex);
- ALOGD("suspendA2dpPlayback_l activeUsecase = %d, mRouteAudioToA2dp = %d",\
- activeUsecase, mRouteAudioToA2dp);
- clearA2DPActiveUseCases_l(activeUsecase);
- if((!getA2DPActiveUseCases_l()) && mIsA2DPEnabled )
- return mALSADevice->suspendProxy();
- return NO_ERROR;
-}
-
} // namespace android_audio_legacy
diff --git a/alsa_sound/AudioHardwareALSA.h b/alsa_sound/AudioHardwareALSA.h
index 22b2082..932b18f 100644
--- a/alsa_sound/AudioHardwareALSA.h
+++ b/alsa_sound/AudioHardwareALSA.h
@@ -1,7 +1,7 @@
/* AudioHardwareALSA.h
**
** Copyright 2008-2010, Wind River Systems
- ** Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@
#ifndef ANDROID_AUDIO_HARDWARE_ALSA_H
#define ANDROID_AUDIO_HARDWARE_ALSA_H
+#define QCOM_CSDCLIENT_ENABLED 1
+
#include <utils/List.h>
#include <hardware_legacy/AudioHardwareBase.h>
@@ -28,18 +30,15 @@
#include <hardware/audio.h>
#include <utils/threads.h>
#include <dlfcn.h>
+
#ifdef QCOM_USBAUDIO_ENABLED
#include <AudioUsbALSA.h>
#endif
-#include <sys/poll.h>
-#include <sys/eventfd.h>
extern "C" {
- #include <sound/asound.h>
- #include <sound/compress_params.h>
- #include <sound/compress_offload.h>
- #include "alsa_audio.h"
- #include "msm8960_use_cases.h"
+ #include <sound/asound.h>
+ #include "alsa_audio.h"
+ #include "msm8960_use_cases.h"
}
#include <hardware/hardware.h>
@@ -48,7 +47,6 @@
{
using android::List;
using android::Mutex;
-using android::Condition;
class AudioHardwareALSA;
/**
@@ -71,11 +69,7 @@
#define PLAYBACK_LOW_LATENCY_BUFFER_SIZE 1024
#define PLAYBACK_LOW_LATENCY 22000
#define PLAYBACK_LOW_LATENCY_MEASURED 42000
-#ifdef TARGET_8974
-#define DEFAULT_IN_BUFFER_SIZE 512
-#else
#define DEFAULT_IN_BUFFER_SIZE 320
-#endif
#define MIN_CAPTURE_BUFFER_SIZE_PER_CH 320
#define MAX_CAPTURE_BUFFER_SIZE_PER_CH 2048
#define FM_BUFFER_SIZE 1024
@@ -98,7 +92,6 @@
#define DUALMIC_KEY "dualmic_enabled"
#define FLUENCE_KEY "fluence"
-#define VOIPCHECK_KEY "voip_flag"
#define ANC_KEY "anc_enabled"
#define TTY_MODE_KEY "tty_mode"
#define BT_SAMPLERATE_KEY "bt_samplerate"
@@ -108,7 +101,6 @@
#define FENS_KEY "fens_enable"
#define ST_KEY "st_enable"
#define INCALLMUSIC_KEY "incall_music_enabled"
-#define VOICE_PATH_ACTIVE "voice_path_active"
#define ANC_FLAG 0x00000001
#define DMIC_FLAG 0x00000002
@@ -131,7 +123,6 @@
static int USBPLAYBACKBIT_VOIPCALL = (1 << 2);
static int USBPLAYBACKBIT_FM = (1 << 3);
static int USBPLAYBACKBIT_LPA = (1 << 4);
-static int USBPLAYBACKBIT_TUNNEL = (1 << 5);
static int USBRECBIT_REC = (1 << 0);
static int USBRECBIT_VOICECALL = (1 << 1);
@@ -152,20 +143,10 @@
#endif
#define MODE_CALL_KEY "CALL_KEY"
-#ifndef ALSA_DEFAULT_SAMPLE_RATE
-#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
-#endif
-#define NUM_FDS 2
-#define AFE_PROXY_SAMPLE_RATE 48000
-#define AFE_PROXY_CHANNEL_COUNT 2
-
-#define MAX_SLEEP_RETRY 100 /* Will check 100 times before continuing */
-#define AUDIO_INIT_SLEEP_WAIT 50 /* 50 ms */
-
+struct alsa_device_t;
static uint32_t FLUENCE_MODE_ENDFIRE = 0;
static uint32_t FLUENCE_MODE_BROADSIDE = 1;
-class ALSADevice;
enum {
INCALL_REC_MONO,
@@ -176,60 +157,28 @@
CS_INACTIVE = 0x0,
CS_ACTIVE = 0x1,
CS_HOLD = 0x2,
- CS_INACTIVE_SESSION2 = 0x0,
- CS_ACTIVE_SESSION2 = 0x100,
- CS_HOLD_SESSION2 = 0x200,
IMS_INACTIVE = 0x0,
IMS_ACTIVE = 0x10,
IMS_HOLD = 0x20
};
-class AudioSessionOutALSA;
+
struct alsa_handle_t {
- ALSADevice* module;
+ alsa_device_t * module;
uint32_t devices;
char useCase[MAX_STR_LEN];
struct pcm * handle;
snd_pcm_format_t format;
uint32_t channels;
uint32_t sampleRate;
- int mode;
unsigned int latency; // Delay in usec
unsigned int bufferSize; // Size of sample buffer
unsigned int periodSize;
- bool isFastOutput;
+ bool isDeepbufferOutput;
struct pcm * rxHandle;
snd_use_case_mgr_t *ucMgr;
- AudioSessionOutALSA *session;
};
-struct output_metadata_handle_t {
- uint32_t metadataLength;
- uint32_t bufferLength;
- uint64_t timestamp;
- uint32_t reserved[12];
-};
-typedef struct buf_info;
-
-/** Structure to save buffer information for applying effects for
- * LPA buffers */
-struct buf_info {
- int bufsize;
- int nBufs;
- int **buffers;
-};
-
-#ifdef __cplusplus
-/**
- *Observer class to post the Events from HAL to Flinger
-*/
-class AudioEventObserver {
-public:
- virtual ~AudioEventObserver() {}
- virtual void postEOS(int64_t delayUs) = 0;
-};
-#endif
-
typedef List < alsa_handle_t > ALSAHandleList;
struct use_case_t {
@@ -238,119 +187,39 @@
typedef List < use_case_t > ALSAUseCaseList;
-class ALSADevice
-{
+struct alsa_device_t {
+ hw_device_t common;
-public:
-
- ALSADevice();
- virtual ~ALSADevice();
-// status_t init(alsa_device_t *module, ALSAHandleList &list);
- status_t open(alsa_handle_t *handle);
- status_t close(alsa_handle_t *handle);
- status_t standby(alsa_handle_t *handle);
- status_t route(alsa_handle_t *handle, uint32_t devices, int mode);
- status_t startVoiceCall(alsa_handle_t *handle);
- status_t startVoipCall(alsa_handle_t *handle);
- status_t startFm(alsa_handle_t *handle);
- void setVoiceVolume(int volume);
- void setVoipVolume(int volume);
- void setMicMute(int state);
- void setVoipMicMute(int state);
- void setVoipConfig(int mode, int rate);
- status_t setFmVolume(int vol);
- void setBtscoRate(int rate);
- status_t setLpaVolume(int vol);
- void enableWideVoice(bool flag);
- void enableFENS(bool flag);
- void setFlags(uint32_t flag);
- status_t setCompressedVolume(int vol);
- void enableSlowTalk(bool flag);
- void setVocRecMode(uint8_t mode);
- void setVoLTEMicMute(int state);
- void setVoLTEVolume(int vol);
- void setSGLTEMicMute(int state);
- void setSGLTEVolume(int vol);
- status_t setEcrxDevice(char *device);
- void setInChannels(int);
- //TODO:check if this needs to be public
- void disableDevice(alsa_handle_t *handle);
- char *getUCMDeviceFromAcdbId(int acdb_id);
+ status_t (*init)(alsa_device_t *, ALSAHandleList &);
+ status_t (*open)(alsa_handle_t *);
+ status_t (*close)(alsa_handle_t *);
+ status_t (*standby)(alsa_handle_t *);
+ status_t (*route)(alsa_handle_t *, uint32_t, int);
+ status_t (*startVoiceCall)(alsa_handle_t *);
+ status_t (*startVoipCall)(alsa_handle_t *);
+ status_t (*startFm)(alsa_handle_t *);
+ void (*setVoiceVolume)(int);
+ void (*setVoipVolume)(int);
+ void (*setMicMute)(int);
+ void (*setVoipMicMute)(int);
+ void (*setVoipConfig)(int, int);
+ status_t (*setFmVolume)(int);
+ void (*setBtscoRate)(int);
+ status_t (*setLpaVolume)(int);
+ void (*enableWideVoice)(bool);
+ void (*enableFENS)(bool);
+ void (*setFlags)(uint32_t);
+ status_t (*setCompressedVolume)(int);
+ void (*enableSlowTalk)(bool);
+ void (*setVocRecMode)(uint8_t);
+ void (*setVoLTEMicMute)(int);
+ void (*setVoLTEVolume)(int);
#ifdef SEPERATED_AUDIO_INPUT
- void setInput(int);
+ void (*setInput)(int);
#endif
#ifdef QCOM_CSDCLIENT_ENABLED
- void setCsdHandle(void*);
+ void (*setCsdHandle)(void*);
#endif
-
-protected:
- friend class AudioHardwareALSA;
-private:
- void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode);
- int getUseCaseType(const char *useCase);
- status_t setHDMIChannelCount();
- status_t setHardwareParams(alsa_handle_t *handle);
- int deviceName(alsa_handle_t *handle, unsigned flags, char **value);
- status_t setSoftwareParams(alsa_handle_t *handle);
- bool platform_is_Fusion3();
- status_t getMixerControl(const char *name, unsigned int &value, int index = 0);
- status_t setMixerControl(const char *name, unsigned int value, int index = -1);
- status_t setMixerControl(const char *name, const char *);
- status_t setMixerControlExt(const char *name, int count, char **setValues);
- char * getUCMDevice(uint32_t devices, int input, char *rxDevice);
- status_t start(alsa_handle_t *handle);
-
- status_t openProxyDevice();
- status_t closeProxyDevice();
- bool isProxyDeviceOpened();
- bool isProxyDeviceSuspended();
- bool suspendProxy();
- bool resumeProxy();
- void resetProxyVariables();
- ssize_t readFromProxy(void **captureBuffer , ssize_t *bufferSize);
- status_t exitReadFromProxy();
- void initProxyParams();
- status_t startProxy();
-
-private:
- char mMicType[25];
- char mCurRxUCMDevice[50];
- char mCurTxUCMDevice[50];
- uint32_t mFluenceMode;
- int mFmVolume;
- uint32_t mDevSettingsFlag;
- int mBtscoSamplerate;
- ALSAUseCaseList mUseCaseList;
- void *mcsd_handle;
- int mCallMode;
- struct mixer* mMixer;
- int mInChannels;
- bool mIsSglte;
-#ifdef SEPERATED_AUDIO_INPUT
- int mInput_source
-#endif
-// ALSAHandleList *mDeviceList;
-
- struct proxy_params {
- bool mExitRead;
- struct pcm *mProxyPcmHandle;
- uint32_t mCaptureBufferSize;
- void *mCaptureBuffer;
- enum {
- EProxyClosed = 0,
- EProxyOpened = 1,
- EProxySuspended = 2,
- EProxyCapture = 3,
- };
-
- uint32_t mProxyState;
- struct snd_xferi mX;
- unsigned mAvail;
- struct pollfd mPfdProxy[NUM_FDS];
- long mFrames;
- };
- struct proxy_params mProxyParams;
-
};
// ----------------------------------------------------------------------------
@@ -375,6 +244,21 @@
};
+class ALSAControl
+{
+public:
+ ALSAControl(const char *device = "/dev/snd/controlC0");
+ virtual ~ALSAControl();
+
+ status_t get(const char *name, unsigned int &value, int index = 0);
+ status_t set(const char *name, unsigned int value, int index = -1);
+ status_t set(const char *name, const char *);
+ status_t setext(const char *name, int count, char **setValues);
+
+private:
+ struct mixer* mHandle;
+};
+
class ALSAStreamOps
{
public:
@@ -453,155 +337,11 @@
private:
uint32_t mFrameCount;
- uint32_t mUseCase;
protected:
AudioHardwareALSA * mParent;
};
-// ----------------------------------------------------------------------------
-
-class AudioSessionOutALSA : public AudioStreamOut
-{
-public:
- AudioSessionOutALSA(AudioHardwareALSA *parent,
- uint32_t devices,
- int format,
- uint32_t channels,
- uint32_t samplingRate,
- int type,
- status_t *status);
- virtual ~AudioSessionOutALSA();
-
- virtual uint32_t sampleRate() const
- {
- return mSampleRate;
- }
-
- virtual size_t bufferSize() const
- {
- return mBufferSize;
- }
-
- virtual uint32_t channels() const
- {
- return mChannels;
- }
-
- virtual int format() const
- {
- return mFormat;
- }
-
- virtual uint32_t latency() const;
-
- virtual ssize_t write(const void *buffer, size_t bytes);
-
- virtual status_t start();
- virtual status_t pause();
- virtual status_t flush();
- virtual status_t stop();
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- status_t setVolume(float left, float right);
-
- virtual status_t standby();
-
- virtual status_t setParameters(const String8& keyValuePairs);
-
- virtual String8 getParameters(const String8& keys);
-
-
- // return the number of audio frames written by the audio dsp to DAC since
- // the output has exited standby
- virtual status_t getRenderPosition(uint32_t *dspFrames);
-
- virtual status_t getNextWriteTimestamp(int64_t *timestamp);
-
- virtual status_t setObserver(void *observer);
-
- virtual status_t getBufferInfo(buf_info **buf);
- virtual status_t isBufferAvailable(int *isAvail);
- status_t pause_l();
- status_t resume_l();
-
- void updateMetaData(size_t bytes);
-
-private:
- Mutex mLock;
- uint32_t mFrameCount;
- uint32_t mSampleRate;
- uint32_t mChannels;
- size_t mBufferSize;
- int mFormat;
- uint32_t mStreamVol;
-
- bool mPaused;
- bool mSeeking;
- bool mReachedEOS;
- bool mSkipWrite;
- bool mEosEventReceived;
- AudioHardwareALSA *mParent;
- alsa_handle_t * mAlsaHandle;
- ALSADevice * mAlsaDevice;
- snd_use_case_mgr_t *mUcMgr;
- AudioEventObserver *mObserver;
- output_metadata_handle_t mOutputMetadataTunnel;
- uint32_t mOutputMetadataLength;
- uint32_t mUseCase;
- status_t openDevice(char *pUseCase, bool bIsUseCase, int devices);
-
- status_t closeDevice(alsa_handle_t *pDevice);
- void createEventThread();
- void bufferAlloc(alsa_handle_t *handle);
- void bufferDeAlloc();
- bool isReadyToPostEOS(int errPoll, void *fd);
- status_t drain();
- status_t openAudioSessionDevice(int type, int devices);
- // make sure the event thread also exited
- void requestAndWaitForEventThreadExit();
- int32_t writeToDriver(char *buffer, int bytes);
- static void * eventThreadWrapper(void *me);
- void eventThreadEntry();
- void reset();
-
- //Structure to hold mem buffer information
- class BuffersAllocated {
- public:
- BuffersAllocated(void *buf1, int32_t nSize) :
- memBuf(buf1), memBufsize(nSize), bytesToWrite(0)
- {}
- void* memBuf;
- int32_t memBufsize;
- uint32_t bytesToWrite;
- };
- List<BuffersAllocated> mEmptyQueue;
- List<BuffersAllocated> mFilledQueue;
- List<BuffersAllocated> mBufPool;
-
- //Declare all the threads
- pthread_t mEventThread;
-
- //Declare the condition Variables and Mutex
- Mutex mEmptyQueueMutex;
- Mutex mFilledQueueMutex;
-
- Condition mWriteCv;
- Condition mEventCv;
- bool mKillEventThread;
- bool mEventThreadAlive;
- int mInputBufferSize;
- int mInputBufferCount;
-
- //event fd to signal the EOS and Kill from the userspace
- int mEfd;
-
-public:
- bool mRouteAudioToA2dp;
-};
-
-
class AudioStreamInALSA : public AudioStreamIn, public ALSAStreamOps
{
public:
@@ -674,14 +414,14 @@
private:
void resetFramesLost();
+#ifdef QCOM_CSDCLIENT_ENABLED
+ int start_csd_record(int);
+ int stop_csd_record(void);
+#endif
+
unsigned int mFramesLost;
AudioSystem::audio_in_acoustics mAcoustics;
-#ifdef QCOM_CSDCLIENT_ENABLED
- int start_csd_record(int param);
- int stop_csd_record();
-#endif
-
#ifdef QCOM_SSR_ENABLED
// Function to read coefficients from files.
status_t readCoeffsFromFile();
@@ -745,12 +485,22 @@
// parameters is not supported
virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channels);
+#ifdef QCOM_TUNNEL_LPA_ENABLED
+ /** This method creates and opens the audio hardware output
+ * session for LPA */
+ virtual AudioStreamOut* openOutputSession(
+ uint32_t devices,
+ int *format,
+ status_t *status,
+ int sessionId,
+ uint32_t samplingRate=0,
+ uint32_t channels=0);
+ virtual void closeOutputSession(AudioStreamOut* out);
+#endif
+
/** This method creates and opens the audio hardware output stream */
virtual AudioStreamOut* openOutputStream(
uint32_t devices,
-#ifdef QCOM_OUTPUT_FLAGS_ENABLED
- audio_output_flags_t flags,
-#endif
int *format=0,
uint32_t *channels=0,
uint32_t *sampleRate=0,
@@ -767,14 +517,6 @@
AudioSystem::audio_in_acoustics acoustics);
virtual void closeInputStream(AudioStreamIn* in);
- status_t startA2dpPlayback(uint32_t activeUsecase);
- status_t stopA2dpPlayback(uint32_t activeUsecase);
- bool suspendA2dpPlayback(uint32_t activeUsecase);
-
- status_t startA2dpPlayback_l(uint32_t activeUsecase);
- status_t stopA2dpPlayback_l(uint32_t activeUsecase);
- bool suspendA2dpPlayback_l(uint32_t activeUsecase);
-
/**This method dumps the state of the audio hardware */
//virtual status_t dumpState(int fd, const Vector<String16>& args);
@@ -785,24 +527,10 @@
return mMode;
}
- void pauseIfUseCaseTunnelOrLPA();
- void resumeIfUseCaseTunnelOrLPA();
-
-private:
- status_t openA2dpOutput();
- status_t closeA2dpOutput();
- status_t stopA2dpThread();
- void a2dpThreadFunc();
- static void* a2dpThreadWrapper(void *context);
- void setA2DPActiveUseCases_l(uint32_t activeUsecase);
- uint32_t getA2DPActiveUseCases_l();
- void clearA2DPActiveUseCases_l(uint32_t activeUsecase);
- uint32_t useCaseStringToEnum(const char *usecase);
-
protected:
virtual status_t dump(int fd, const Vector<String16>& args);
virtual uint32_t getVoipMode(int format);
- status_t doRouting(int device);
+ void doRouting(int device);
#ifdef QCOM_FM_ENABLED
void handleFm(int device);
#endif
@@ -814,19 +542,16 @@
void startUsbPlaybackIfNotStarted();
void startUsbRecordingIfNotStarted();
#endif
- void setInChannels(int device);
void disableVoiceCall(char* verb, char* modifier, int mode, int device);
void enableVoiceCall(char* verb, char* modifier, int mode, int device);
bool routeVoiceCall(int device, int newMode);
bool routeVoLTECall(int device, int newMode);
- bool routeSGLTECall(int device, int newMode);
- friend class AudioSessionOutALSA;
friend class AudioStreamOutALSA;
friend class AudioStreamInALSA;
friend class ALSAStreamOps;
- ALSADevice* mALSADevice;
+ alsa_device_t * mALSADevice;
ALSAHandleList mDeviceList;
@@ -838,19 +563,17 @@
snd_use_case_mgr_t *mUcMgr;
- int32_t mCurDevice;
+ uint32_t mCurDevice;
/* The flag holds all the audio related device settings from
* Settings and Qualcomm Settings applications */
uint32_t mDevSettingsFlag;
uint32_t mVoipStreamCount;
- bool mVoipMicMute;
uint32_t mVoipBitRate;
uint32_t mIncallMode;
bool mMicMute;
int mCSCallActive;
int mVolteCallActive;
- int mSGLTECallActive;
int mCallState;
int mIsFmActive;
bool mBluetoothVGS;
@@ -859,33 +582,8 @@
int musbPlaybackState;
int musbRecordingState;
#endif
- bool mIsVoicePathActive;
-
void *mAcdbHandle;
void *mCsdHandle;
- //A2DP variables
- audio_stream_out *mA2dpStream;
- audio_hw_device_t *mA2dpDevice;
-
- bool mKillA2DPThread;
- bool mA2dpThreadAlive;
- pthread_t mA2dpThread;
- Mutex mA2dpMutex;
- Condition mA2dpCv;
- volatile bool mIsA2DPEnabled;
-
- enum {
- USECASE_NONE = 0x0,
- USECASE_HIFI = 0x1,
- USECASE_HIFI_LOWLATENCY = 0x2,
- USECASE_HIFI_LOW_POWER = 0x4,
- USECASE_HIFI_TUNNEL = 0x8,
- USECASE_FM = 0x10,
- };
- uint32_t mA2DPActiveUseCases;
-
-public:
- bool mRouteAudioToA2dp;
};
// ----------------------------------------------------------------------------
diff --git a/alsa_sound/AudioPolicyManagerALSA.cpp b/alsa_sound/AudioPolicyManagerALSA.cpp
old mode 100755
new mode 100644
index 3345cb9..98f8203
--- a/alsa_sound/AudioPolicyManagerALSA.cpp
+++ b/alsa_sound/AudioPolicyManagerALSA.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 The Android Open Source Project
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,29 +17,11 @@
#define LOG_TAG "AudioPolicyManagerALSA"
//#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
-
+#define LOG_NDDEBUG 0
#include <utils/Log.h>
-#include "AudioPolicyManagerALSA.h"
-#include <hardware/audio_effect.h>
-#include <hardware/audio.h>
-#include <hardware_legacy/audio_policy_conf.h>
-#include <math.h>
-#include <media/mediarecorder.h>
-#include <stdio.h>
-#define MAX_POLL_VOICE_SETUP 20
+#include "AudioPolicyManagerALSA.h"
+#include <media/mediarecorder.h>
namespace android_audio_legacy {
@@ -47,1201 +29,11 @@
// AudioPolicyManagerALSA
// ----------------------------------------------------------------------------
-AudioParameter param;
+//Compiling error seen (only) on mako-pdk project if AudioParamer doesn't exist in this file
+//No issue is seen on QCOM jb-mailine if remvong this line
+//AudioParameter param;
-status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
- AudioSystem::device_connection_state state,
- const char *device_address)
-{
- SortedVector <audio_io_handle_t> 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 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 (!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 (mHasUsb && 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 (mHasUsb && audio_is_usb_device(device)) {
- // handle USB device disconnection
- mUsbCardAndDevice = "";
- }
- // 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++) {
- // 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) ||
- (mOutputs.valueFor(outputs[i])->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
- closeOutput(outputs[i]);
- }
- }
- }
-
- updateDevicesAndOutputs();
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- if (state == AudioSystem::DEVICE_STATE_AVAILABLE &&
- (mAvailableOutputDevices & AUDIO_DEVICE_OUT_PROXY) &&
- audio_is_a2dp_device(device) ) {
- ALOGV("Delay the proxy device open");
- return NO_ERROR;
- }
-#endif
-
-#ifdef QCOM_FM_ENABLED
- audio_devices_t newDevice = AudioPolicyManagerBase::getNewDevice(mPrimaryOutput, false /*fromCache*/);
- if(device == AUDIO_DEVICE_OUT_FM) {
- if (state == AudioSystem::DEVICE_STATE_AVAILABLE) {
- ALOGV("setDeviceConnectionState() changeRefCount Inc");
- mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AudioSystem::FM, 1);
- }
- else {
- ALOGV("setDeviceConnectionState() changeRefCount Dec");
- mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AudioSystem::FM, -1);
- }
- if(newDevice == 0){
- newDevice = getDeviceForStrategy(STRATEGY_MEDIA, false);
- }
- AudioParameter param = AudioParameter();
- param.addInt(String8(AudioParameter::keyHandleFm), (int)newDevice);
- ALOGV("setDeviceConnectionState() setParameters handle_fm");
- mpClientInterface->setParameters(mPrimaryOutput, param.toString());
- }
-#endif
- for (size_t i = 0; i < mOutputs.size(); i++) {
-#ifdef QCOM_ANC_HEADSET_ENABLED
- audio_devices_t newDevice = getNewDevice(mOutputs.keyAt(i), true /*fromCache*/);
- 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) &&
- (!mHasUsb || (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();
- }
-
- // when changing from ring tone to in call mode, mute the ringing tone
- // immediately and delay the route change to avoid sending the ring tone
- // tail into the earpiece or headset.
- int delayMs = 0;
- if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) {
- // delay the device change command by twice the output latency to have some margin
- // and be sure that audio buffers not yet affected by the mute are out when
- // we actually apply the route change
- delayMs = hwOutputDesc->mLatency*2;
- setStreamMute(AudioSystem::RING, true, mPrimaryOutput);
- }
-
- if (isStateInCall(state)) {
-
- if(!isStateInCall(oldState)) {
- audio_io_handle_t activeInput = getActiveInput();
-
- /* Block the policy manager until voice path is setup. This is
- * done to prevent telephony from signaling call connect before the
- * entire voice path is established.
- */
- for (int i = 0; i < MAX_POLL_VOICE_SETUP; i++) {
- usleep(100000);
- String8 voiceActive = mpClientInterface->getParameters(activeInput,
- String8("voice_path_active"));
-
- if (!voiceActive.compare(String8("voice_path_active=true"))) {
- ALOGV("setPhoneState: Voice path is active");
- break;
- } else {
- ALOGV("setPhoneState: voice path is not active");
- }
- }
- }
-
- for (size_t i = 0; i < mOutputs.size(); i++) {
- AudioOutputDescriptor *desc = mOutputs.valueAt(i);
- //take the biggest latency for all outputs
- if (delayMs < desc->mLatency*2) {
- delayMs = desc->mLatency*2;
- }
- //mute STRATEGY_MEDIA on all outputs
- if (desc->strategyRefCount(STRATEGY_MEDIA) != 0) {
- setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
- setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
- getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
- }
- }
- }
-
- // change routing is necessary
- setOutputDevice(mPrimaryOutput, newDevice, force, delayMs);
-
- // 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);
- // unmute the ringing tone after a sufficient delay if it was muted before
- // setting output device above
- if (oldState == AudioSystem::MODE_RINGTONE) {
- setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS);
- }
- 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 (size_t i = 0; i < mOutputs.size(); 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());
- }
- }
-
-}
-
-
-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.
- if (shouldWait && (desc->refCount() != 0) && (waitMs < desc->latency())) {
- waitMs = desc->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);
- }
- }
- 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();
- 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->refCount() != 0 &&
- 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;
- }
-}
-
-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
- if (getActiveInput() != 0) {
- ALOGW("startInput() input %d failed: other input already started", input);
- return INVALID_OPERATION;
- }
- }
-
- AudioParameter param = AudioParameter();
- param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
-
- param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource);
-
- // use Voice Recognition mode or not for this input based on input source
- int vr_enabled = inputDesc->mInputSource == AUDIO_SOURCE_VOICE_RECOGNITION ? 1 : 0;
- param.addInt(String8("vr_mode"), vr_enabled);
- ALOGV("AudioPolicyManager::startInput(%d), setting vr_mode to %d", inputDesc->mInputSource, vr_enabled);
-
- mpClientInterface->setParameters(input, param.toString());
-
- inputDesc->mRefCount = 1;
- return NO_ERROR;
-}
-
-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 (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() &&
- (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) {
- device |= 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;
- }
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- //handle proxy device begin
- if ((device2 == AUDIO_DEVICE_NONE) ||
- (device2 == AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_PROXY;
- if(device2 != 0) {
- ALOGV("getDeviceForStrategy() STRATEGY_MEDIA use DEVICE_OUT_PROXY:%x",device2);
- // No combo device allowed with proxy device
- device = 0;
- }
- }
-#endif
- if ((device2 == AUDIO_DEVICE_NONE) &&
- (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
- !mA2dpSuspended) {
- 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) &&
- (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_ANALOG_DOCK)) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
- }
- if (device2 == AUDIO_DEVICE_NONE) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
- }
-#ifdef QCOM_FM_ENABLED
- if (device2 == AUDIO_DEVICE_NONE) {
- device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_FM_TX;
- }
-#endif
-
- // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
- // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
- device |= device2;
- if (device) break;
- 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;
- }
-
-#ifdef QCOM_FM_ENABLED
- if (mAvailableOutputDevices & AUDIO_DEVICE_OUT_FM) {
- device |= AUDIO_DEVICE_OUT_FM;
- }
-#endif
-
- } 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;
- }
- // 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;
- }
-
- 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);
-
-#ifdef QCOM_FM_ENABLED
- //if changing from a combined headset + speaker + FM route, unmute media streams
- if (mAvailableOutputDevices & AUDIO_DEVICE_OUT_FM)
- muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
-#endif
-
- return muteWaitMs;
-}
-
-audio_devices_t AudioPolicyManager::getDeviceForInputSource(int inputSource)
-{
- uint32_t device = AUDIO_DEVICE_NONE;
-
- switch(inputSource) {
- case AUDIO_SOURCE_DEFAULT:
- case AUDIO_SOURCE_MIC:
- case AUDIO_SOURCE_VOICE_RECOGNITION:
- case AUDIO_SOURCE_VOICE_COMMUNICATION:
- 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_CAMCORDER:
- if (mAvailableInputDevices & AUDIO_DEVICE_IN_BACK_MIC) {
- device = AUDIO_DEVICE_IN_BACK_MIC;
- } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- device = AUDIO_DEVICE_IN_BUILTIN_MIC;
- }
- break;
- case AUDIO_SOURCE_VOICE_UPLINK:
- 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;
-}
-
-
-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) {
- 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;
- }
-}
-
+// --- class factory
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
@@ -1254,5 +46,4 @@
delete interface;
}
-
-}; // namespace android
+}; // namespace androidi_audio_legacy
diff --git a/alsa_sound/AudioPolicyManagerALSA.h b/alsa_sound/AudioPolicyManagerALSA.h
index af3cef6..2a7dfdb 100644
--- a/alsa_sound/AudioPolicyManagerALSA.h
+++ b/alsa_sound/AudioPolicyManagerALSA.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 The Android Open Source Project
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,65 +37,5 @@
virtual ~AudioPolicyManager() {}
- // AudioPolicyInterface
- virtual status_t setDeviceConnectionState(audio_devices_t device,
- AudioSystem::device_connection_state state,
- const char *device_address);
- 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 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);
-
- // indicates to the audio policy manager that the input starts being used.
- virtual status_t startInput(audio_io_handle_t input);
- // 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);
-
- // 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();
-
-protected:
-
- // 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);
};
};
diff --git a/alsa_sound/AudioSessionOut.cpp b/alsa_sound/AudioSessionOut.cpp
deleted file mode 100644
index b37f7a0..0000000
--- a/alsa_sound/AudioSessionOut.cpp
+++ /dev/null
@@ -1,895 +0,0 @@
-/* AudioSessionOutALSA.cpp
- **
- ** Copyright 2008-2009 Wind River Systems
- ** Copyright (c) 2012, The Linux Foundation. All rights reserved.
- **
- ** 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 <errno.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <math.h>
-
-#define LOG_TAG "AudioSessionOutALSA"
-#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <cutils/properties.h>
-#include <media/AudioRecord.h>
-#include <hardware_legacy/power.h>
-
-#include <linux/ioctl.h>
-#include <sys/prctl.h>
-#include <sys/resource.h>
-#include <pthread.h>
-#include <sys/poll.h>
-#include <sys/eventfd.h>
-#include <linux/unistd.h>
-
-#include "AudioHardwareALSA.h"
-
-namespace sys_write {
- ssize_t lib_write(int fd, const void *buf, size_t count) {
- return write(fd, buf, count);
- }
-};
-namespace android_audio_legacy
-{
-#define LPA_MODE 0
-#define TUNNEL_MODE 1
-#define NUM_FDS 2
-#define KILL_EVENT_THREAD 1
-#define BUFFER_COUNT 4
-#define LPA_BUFFER_SIZE 256*1024
-#define TUNNEL_BUFFER_SIZE 600*1024
-#define MONO_CHANNEL_MODE 1
-// ----------------------------------------------------------------------------
-
-AudioSessionOutALSA::AudioSessionOutALSA(AudioHardwareALSA *parent,
- uint32_t devices,
- int format,
- uint32_t channels,
- uint32_t samplingRate,
- int type,
- status_t *status)
-{
-
- alsa_handle_t alsa_handle;
- char *use_case;
- bool bIsUseCaseSet = false;
-
- Mutex::Autolock autoLock(mLock);
- // Default initilization
- mParent = parent;
- mAlsaDevice = mParent->mALSADevice;
- mUcMgr = mParent->mUcMgr;
- mFormat = format;
- mSampleRate = samplingRate;
- mChannels = channels;
-
-
- mBufferSize = 0;
- *status = BAD_VALUE;
-
- mPaused = false;
- mSeeking = false;
- mReachedEOS = false;
- mSkipWrite = false;
-
- mAlsaHandle = NULL;
- mUseCase = AudioHardwareALSA::USECASE_NONE;
-
- mInputBufferSize = type ? TUNNEL_BUFFER_SIZE : LPA_BUFFER_SIZE;
- mInputBufferCount = BUFFER_COUNT;
- mEfd = -1;
- mEosEventReceived = false;
- mEventThread = NULL;
- mEventThreadAlive = false;
- mKillEventThread = false;
- mObserver = NULL;
- mOutputMetadataLength = 0;
-
- if(devices == 0) {
- ALOGE("No output device specified");
- return;
- }
- if((format == AUDIO_FORMAT_PCM_16_BIT) && (channels == 0 || channels > 6)) {
- ALOGE("Invalid number of channels %d", channels);
- return;
- }
-
- if(devices & AudioSystem::DEVICE_OUT_ALL_A2DP) {
- ALOGV("Set Capture from proxy true");
- mParent->mRouteAudioToA2dp = true;
- }
-
- //open device based on the type (LPA or Tunnel) and devices
- //TODO: Check format type for linear vs non-linear to determine LPA/Tunnel
- openAudioSessionDevice(type, devices);
-
- //Creates the event thread to poll events from LPA/Compress Driver
- createEventThread();
-
- ALOGV("mParent->mRouteAudioToA2dp = %d", mParent->mRouteAudioToA2dp);
- if (mParent->mRouteAudioToA2dp) {
- status_t err = NO_ERROR;
- mUseCase = mParent->useCaseStringToEnum(mAlsaHandle->useCase);
- err = mParent->startA2dpPlayback_l(mUseCase);
- *status = err;
- }
-
- *status = NO_ERROR;
-}
-
-AudioSessionOutALSA::~AudioSessionOutALSA()
-{
- ALOGD("~AudioSessionOutALSA");
-
- mSkipWrite = true;
- mWriteCv.signal();
- if (mParent->mRouteAudioToA2dp) {
- status_t err = mParent->stopA2dpPlayback(mUseCase);
- if(err){
- ALOGE("stopA2dpPlayback return err %d", err);
- }
- }
- //TODO: This might need to be Locked using Parent lock
- reset();
-}
-
-status_t AudioSessionOutALSA::setVolume(float left, float right)
-{
- Mutex::Autolock autoLock(mLock);
- float volume;
- status_t status = NO_ERROR;
-
- volume = (left + right) / 2;
- if (volume < 0.0) {
- ALOGW("AudioSessionOutALSA::setVolume(%f) under 0.0, assuming 0.0\n", volume);
- volume = 0.0;
- } else if (volume > 1.0) {
- ALOGW("AudioSessionOutALSA::setVolume(%f) over 1.0, assuming 1.0\n", volume);
- volume = 1.0;
- }
- mStreamVol = lrint((volume * 0x2000)+0.5);
-
- ALOGV("Setting stream volume to %d (available range is 0 to 0x2000)\n", mStreamVol);
- if(mAlsaHandle) {
- if(!strcmp(mAlsaHandle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER) ||
- !strcmp(mAlsaHandle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) {
- ALOGD("setLpaVolume(%u)\n", mStreamVol);
- ALOGD("Setting LPA volume to %d (available range is 0 to 100)\n", mStreamVol);
- mAlsaHandle->module->setLpaVolume(mStreamVol);
- return status;
- }
- else if(!strcmp(mAlsaHandle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL) ||
- !strcmp(mAlsaHandle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL)) {
- ALOGD("setCompressedVolume(%u)\n", mStreamVol);
- ALOGD("Setting Compressed volume to %d (available range is 0 to 100)\n", mStreamVol);
- mAlsaHandle->module->setCompressedVolume(mStreamVol);
- return status;
- }
- }
- return INVALID_OPERATION;
-}
-
-
-status_t AudioSessionOutALSA::openAudioSessionDevice(int type, int devices)
-{
- char* use_case;
- status_t status = NO_ERROR;
- //1.) Based on the current device and session type (LPA/Tunnel), open a device
- // with verb or modifier
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
- if (type == LPA_MODE) {
- if ((use_case == NULL) || (!strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE)))) {
- status = openDevice(SND_USE_CASE_VERB_HIFI_LOW_POWER, true, devices);
- } else {
- status = openDevice(SND_USE_CASE_MOD_PLAY_LPA, false, devices);
- }
- } else if (type == TUNNEL_MODE) {
- if ((use_case == NULL) || (!strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE)))) {
- status = openDevice(SND_USE_CASE_VERB_HIFI_TUNNEL, true, devices);
- } else {
- status = openDevice(SND_USE_CASE_MOD_PLAY_TUNNEL, false, devices);
- }
- mOutputMetadataLength = sizeof(output_metadata_handle_t);
- ALOGD("openAudioSessionDevice - mOutputMetadataLength = %d", mOutputMetadataLength);
- }
- if(use_case) {
- free(use_case);
- use_case = NULL;
- }
- if(status != NO_ERROR) {
- return status;
- }
-
- //2.) Get the device handle
- ALSAHandleList::iterator it = mParent->mDeviceList.end();
- it--;
-
- mAlsaHandle = &(*it);
- ALOGV("mAlsaHandle %p, mAlsaHandle->useCase %s",mAlsaHandle, mAlsaHandle->useCase);
-
- //3.) mmap the buffers for playback
- status_t err = mmap_buffer(mAlsaHandle->handle);
- if(err) {
- ALOGE("MMAP buffer failed - playback err = %d", err);
- return err;
- }
- ALOGV("buffer pointer %p ", mAlsaHandle->handle->addr);
-
- //4.) prepare the driver for playback and allocate the buffers
- status = pcm_prepare(mAlsaHandle->handle);
- if (status) {
- ALOGE("PCM Prepare failed - playback err = %d", err);
- return status;
- }
- bufferAlloc(mAlsaHandle);
- mBufferSize = mAlsaHandle->periodSize;
- return NO_ERROR;
-}
-
-ssize_t AudioSessionOutALSA::write(const void *buffer, size_t bytes)
-{
- Mutex::Autolock autoLock(mLock);
- int err;
- ALOGV("write Empty Queue size() = %d, Filled Queue size() = %d ",
- mEmptyQueue.size(),mFilledQueue.size());
-
- if(mFilledQueue.empty() && !bytes) {
- mReachedEOS = true;
- mEosEventReceived = true;
- ALOGV("mObserver: posting EOS");
- mObserver->postEOS(0);
- }
-
- //1.) Dequeue the buffer from empty buffer queue. Copy the data to be
- // written into the buffer. Then Enqueue the buffer to the filled
- // buffer queue
- mEmptyQueueMutex.lock();
- List<BuffersAllocated>::iterator it = mEmptyQueue.begin();
- BuffersAllocated buf = *it;
- if(bytes)
- mEmptyQueue.erase(it);
- mEmptyQueueMutex.unlock();
-
- memset(buf.memBuf, 0, mAlsaHandle->handle->period_size);
- if((!strncmp(mAlsaHandle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
- strlen(SND_USE_CASE_VERB_HIFI_TUNNEL))) ||
- (!strncmp(mAlsaHandle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
- strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)))) {
- updateMetaData(bytes);
-
- memcpy(buf.memBuf, &mOutputMetadataTunnel, mOutputMetadataLength);
- ALOGD("Copy Metadata = %d, bytes = %d", mOutputMetadataLength, bytes);
-
- if(bytes == 0) {
- err = pcm_write(mAlsaHandle->handle, buf.memBuf, mAlsaHandle->handle->period_size);
- buf.bytesToWrite = bytes;
- return err;
- }
- }
- memcpy((buf.memBuf + mOutputMetadataLength), buffer, bytes);
- buf.bytesToWrite = bytes;
-
- //2.) Write the buffer to the Driver
- ALOGV("PCM write start");
- err = pcm_write(mAlsaHandle->handle, buf.memBuf, mAlsaHandle->handle->period_size);
- ALOGV("PCM write complete");
- if (bytes < (mAlsaHandle->handle->period_size - mOutputMetadataLength)) {
- ALOGV("Last buffer case");
- if ( ioctl(mAlsaHandle->handle->fd, SNDRV_PCM_IOCTL_START) < 0 ) {
- ALOGE("Audio Start failed");
- } else {
- mAlsaHandle->handle->start = 1;
- }
- mReachedEOS = true;
- }
-
- mFilledQueueMutex.lock();
- mFilledQueue.push_back(buf);
- mFilledQueueMutex.unlock();
- return err;
-}
-
-void AudioSessionOutALSA::bufferAlloc(alsa_handle_t *handle) {
- void *mem_buf = NULL;
- int i = 0;
-
- int32_t nSize = mAlsaHandle->handle->period_size;
- ALOGV("number of input buffers = %d", mInputBufferCount);
- ALOGV("memBufferAlloc calling with required size %d", nSize);
- for (i = 0; i < mInputBufferCount; i++) {
- mem_buf = (int32_t *)mAlsaHandle->handle->addr + (nSize * i/sizeof(int));
- ALOGV("Buffer pointer %p ", mem_buf);
- BuffersAllocated buf(mem_buf, nSize);
- memset(buf.memBuf, 0x0, nSize);
- mEmptyQueue.push_back(buf);
- mBufPool.push_back(buf);
- ALOGV("The MEM that is allocated - buffer is %x",\
- (unsigned int)mem_buf);
- }
-}
-
-void AudioSessionOutALSA::bufferDeAlloc() {
- while (!mBufPool.empty()) {
- List<BuffersAllocated>::iterator it = mBufPool.begin();
- ALOGV("Removing input buffer from Buffer Pool ");
- mBufPool.erase(it);
- }
-}
-
-void AudioSessionOutALSA::requestAndWaitForEventThreadExit() {
- if (!mEventThreadAlive)
- return;
- mKillEventThread = true;
- if(mEfd != -1) {
- ALOGE("Writing to mEfd %d",mEfd);
- uint64_t writeValue = KILL_EVENT_THREAD;
- sys_write::lib_write(mEfd, &writeValue, sizeof(uint64_t));
- }
- pthread_join(mEventThread,NULL);
- ALOGV("event thread killed");
-}
-
-void * AudioSessionOutALSA::eventThreadWrapper(void *me) {
- static_cast<AudioSessionOutALSA *>(me)->eventThreadEntry();
- return NULL;
-}
-
-void AudioSessionOutALSA::eventThreadEntry() {
- //1.) Initialize the variables required for polling events
- int rc = 0;
- int err_poll = 0;
- int avail = 0;
- int i = 0;
- struct pollfd pfd[NUM_FDS];
- int timeout = -1;
-
- //2.) Set the priority for the event thread
- pid_t tid = gettid();
- androidSetThreadPriority(tid, ANDROID_PRIORITY_AUDIO);
- prctl(PR_SET_NAME, (unsigned long)"HAL Audio EventThread", 0, 0, 0);
-
- //3.) Allocate two FDs for polling.
- // 1st FD: Polling on the Driver's timer_fd. This is used for getting write done
- // events from the driver
- // 2nd FD: Polling on a local fd so we can interrup the event thread locally
- // when playback is stopped from Apps
- // The event thread will when a write is performed on one of these FDs
- ALOGV("Allocating poll fd");
- if(!mKillEventThread) {
- pfd[0].fd = mAlsaHandle->handle->timer_fd;
- pfd[0].events = (POLLIN | POLLERR | POLLNVAL);
- mEfd = eventfd(0,0);
- pfd[1].fd = mEfd;
- pfd[1].events = (POLLIN | POLLERR | POLLNVAL);
- }
-
- //4.) Start a poll for write done events from driver.
- while(!mKillEventThread && ((err_poll = poll(pfd, NUM_FDS, timeout)) >=0)) {
- ALOGV("pfd[0].revents =%d ", pfd[0].revents);
- ALOGV("pfd[1].revents =%d ", pfd[1].revents);
- // Handle Poll errors
- if (err_poll == EINTR)
- ALOGE("Timer is intrrupted");
- if ((pfd[1].revents & POLLERR) || (pfd[1].revents & POLLNVAL)) {
- pfd[1].revents = 0;
- ALOGE("POLLERR or INVALID POLL");
- }
-
- //POLLIN event on 2nd FD. Kill from event thread
- if (pfd[1].revents & POLLIN) {
- uint64_t u;
- read(mEfd, &u, sizeof(uint64_t));
- ALOGV("POLLIN event occured on the event fd, value written to %llu",
- (unsigned long long)u);
- pfd[1].revents = 0;
- if (u == KILL_EVENT_THREAD) {
- continue;
- }
- }
-
- //Poll error on Driver's timer fd
- if((pfd[0].revents & POLLERR) || (pfd[0].revents & POLLNVAL)) {
- pfd[0].revents = 0;
- continue;
- }
-
- //Pollin event on Driver's timer fd
- if (pfd[0].revents & POLLIN && !mKillEventThread) {
- struct snd_timer_tread rbuf[4];
- read(mAlsaHandle->handle->timer_fd, rbuf, sizeof(struct snd_timer_tread) * 4 );
- pfd[0].revents = 0;
- if (mPaused)
- continue;
- ALOGV("After an event occurs");
-
- mFilledQueueMutex.lock();
- if (mFilledQueue.empty()) {
- ALOGV("Filled queue is empty");
- mFilledQueueMutex.unlock();
- continue;
- }
- // Transfer a buffer that was consumed by the driver from filled queue
- // to empty queue
-
- BuffersAllocated buf = *(mFilledQueue.begin());
- mFilledQueue.erase(mFilledQueue.begin());
- ALOGV("mFilledQueue %d", mFilledQueue.size());
-
- //Post EOS in case the filled queue is empty and EOS is reached.
- if (mFilledQueue.empty() && mReachedEOS) {
- mFilledQueueMutex.unlock();
- if (mObserver != NULL) {
- if((!strncmp(mAlsaHandle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
- strlen(SND_USE_CASE_VERB_HIFI_TUNNEL))) ||
- (!strncmp(mAlsaHandle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
- strlen(SND_USE_CASE_MOD_PLAY_TUNNEL)))) {
- ALOGD("Audio Drain DONE ++");
- if ( ioctl(mAlsaHandle->handle->fd, SNDRV_COMPRESS_DRAIN) < 0 ) {
- ALOGE("Audio Drain failed");
- }
- ALOGD("Audio Drain DONE --");
- }
- ALOGV("Posting the EOS to the observer player %p", mObserver);
- mEosEventReceived = true;
- if(mReachedEOS) {
- ALOGV("mObserver: posting EOS");
- mObserver->postEOS(0);
- }
- }
- }
- mFilledQueueMutex.unlock();
-
- mEmptyQueueMutex.lock();
- mEmptyQueue.push_back(buf);
- mEmptyQueueMutex.unlock();
- mWriteCv.signal();
- }
- }
-
- //5.) Close mEfd that was created
- mEventThreadAlive = false;
- if (mEfd != -1) {
- close(mEfd);
- mEfd = -1;
- }
- ALOGV("Event Thread is dying.");
- return;
-
-}
-
-void AudioSessionOutALSA::createEventThread() {
- ALOGV("Creating Event Thread");
- mKillEventThread = false;
- mEventThreadAlive = true;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
- pthread_create(&mEventThread, &attr, eventThreadWrapper, this);
- ALOGV("Event Thread created");
-}
-
-status_t AudioSessionOutALSA::start()
-{
- Mutex::Autolock autoLock(mLock);
- if (mPaused) {
- status_t err = NO_ERROR;
- if (mSeeking) {
- drain();
- mSeeking = false;
- } else if (ioctl(mAlsaHandle->handle->fd, SNDRV_PCM_IOCTL_PAUSE,0) < 0) {
- ALOGE("Resume failed on use case %s", mAlsaHandle->useCase);
- return UNKNOWN_ERROR;
- }
- mPaused = false;
- if (mParent->mRouteAudioToA2dp) {
- err = mParent->startA2dpPlayback_l(mUseCase);
- if(err != NO_ERROR) {
- ALOGE("start Proxy from start returned error = %d",err);
- return err;
- }
- }
- }
- else {
- //Signal the driver to start rendering data
- if (ioctl(mAlsaHandle->handle->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("start:SNDRV_PCM_IOCTL_START failed\n");
- return UNKNOWN_ERROR;
- }
- }
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::pause()
-{
- Mutex::Autolock autoLock(mLock);
- status_t err = NO_ERROR;
- ALOGD("Pausing the driver");
- //Signal the driver to pause rendering data
- if (ioctl(mAlsaHandle->handle->fd, SNDRV_PCM_IOCTL_PAUSE,1) < 0) {
- ALOGE("PAUSE failed on use case %s", mAlsaHandle->useCase);
- return UNKNOWN_ERROR;
- }
- mPaused = true;
-
- if(err) {
- ALOGE("pause returned error");
- return err;
- }
- if (mParent->mRouteAudioToA2dp) {
- err = mParent->suspendA2dpPlayback(mUseCase);
- if(err != NO_ERROR) {
- ALOGE("Suspend Proxy from Pause returned error = %d",err);
- return err;
- }
- }
- return err;
-
-}
-
-status_t AudioSessionOutALSA::pause_l()
-{
- if (!mPaused) {
- if (ioctl(mAlsaHandle->handle->fd, SNDRV_PCM_IOCTL_PAUSE,1) < 0) {
- ALOGE("PAUSE failed on use case %s", mAlsaHandle->useCase);
- return UNKNOWN_ERROR;
- }
- }
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::resume_l()
-{
- status_t err = NO_ERROR;
- if (!mPaused) {
- if (ioctl(mAlsaHandle->handle->fd, SNDRV_PCM_IOCTL_PAUSE,0) < 0) {
- ALOGE("Resume failed on use case %s", mAlsaHandle->useCase);
- return UNKNOWN_ERROR;
- }
- }
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::drain()
-{
- mAlsaHandle->handle->start = 0;
- int err = pcm_prepare(mAlsaHandle->handle);
- if(err != OK) {
- ALOGE("pcm_prepare -seek = %d",err);
- //Posting EOS
- if (mObserver)
- mObserver->postEOS(0);
- return UNKNOWN_ERROR;
- }
-
- ALOGV("drain Empty Queue size() = %d, Filled Queue size() = %d ",
- mEmptyQueue.size(), mFilledQueue.size());
-
- mAlsaHandle->handle->sync_ptr->flags =
- SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
- sync_ptr(mAlsaHandle->handle);
- ALOGV("appl_ptr=%d",(int)mAlsaHandle->handle->sync_ptr->c.control.appl_ptr);
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::flush()
-{
- Mutex::Autolock autoLock(mLock);
- ALOGV("AudioSessionOutALSA flush");
- int err;
- {
- Mutex::Autolock autoLockEmptyQueue(mEmptyQueueMutex);
- Mutex::Autolock autoLockFilledQueue(mFilledQueueMutex);
- // 1.) Clear the Empty and Filled buffer queue
- mEmptyQueue.clear();
- mFilledQueue.clear();
-
- // 2.) Add all the available buffers to Request Queue (Maintain order)
- List<BuffersAllocated>::iterator it = mBufPool.begin();
- for (; it!=mBufPool.end(); ++it) {
- memset(it->memBuf, 0x0, (*it).memBufsize);
- mEmptyQueue.push_back(*it);
- }
- }
-
- ALOGV("Transferred all the buffers from Filled queue to "
- "Empty queue to handle seek");
- mReachedEOS = false;
- // 3.) If its in start state,
- // Pause and flush the driver and Resume it again
- // If its in paused state,
- // Set the seek flag, Resume will take care of flushing the
- // driver
- if (!mPaused && !mEosEventReceived) {
- if ((err = ioctl(mAlsaHandle->handle->fd, SNDRV_PCM_IOCTL_PAUSE,1)) < 0) {
- ALOGE("Audio Pause failed");
- return UNKNOWN_ERROR;
- }
- //mReachedEOS = false;
- if ((err = drain()) != OK)
- return err;
- } else {
- mSeeking = true;
- }
-
- //4.) Skip the current write from the decoder and signal to the Write get
- // the next set of data from the decoder
- mSkipWrite = true;
- mWriteCv.signal();
-
- ALOGV("AudioSessionOutALSA::flush completed");
- return NO_ERROR;
-}
-
-
-
-status_t AudioSessionOutALSA::stop()
-{
- Mutex::Autolock autoLock(mLock);
- ALOGV("AudioSessionOutALSA- stop");
- // close all the existing PCM devices
- mSkipWrite = true;
- mWriteCv.signal();
-
- if (mParent->mRouteAudioToA2dp) {
- status_t err = mParent->suspendA2dpPlayback(mUseCase);
- if(err) {
- ALOGE("stop-suspendA2dpPlayback- return err = %d", err);
- return err;
- }
- }
-
- ALOGV("stop -");
-
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::standby()
-{
- Mutex::Autolock autoLock(mParent->mLock);
- status_t err = NO_ERROR;
- if (mParent->mRouteAudioToA2dp) {
- ALOGD("Standby - stopA2dpPlayback_l - mUseCase = %d",mUseCase);
- err = mParent->stopA2dpPlayback_l(mUseCase);
- if(err){
- ALOGE("stopA2dpPlayback return err %d", err);
- }
- }
- return err;
-}
-
-#define USEC_TO_MSEC(x) ((x + 999) / 1000)
-
-uint32_t AudioSessionOutALSA::latency() const
-{
- // Android wants latency in milliseconds.
- return USEC_TO_MSEC (mAlsaHandle->latency);
-}
-
-status_t AudioSessionOutALSA::setObserver(void *observer)
-{
- ALOGV("Registering the callback \n");
- mObserver = reinterpret_cast<AudioEventObserver *>(observer);
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::dump(int fd, const Vector<String16>& args)
-{
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::getNextWriteTimestamp(int64_t *timestamp)
-{
- struct snd_compr_tstamp tstamp;
- tstamp.timestamp = -1;
- if (ioctl(mAlsaHandle->handle->fd, SNDRV_COMPRESS_TSTAMP, &tstamp)){
- ALOGE("Failed SNDRV_COMPRESS_TSTAMP\n");
- return UNKNOWN_ERROR;
- } else {
- ALOGV("Timestamp returned = %lld\n", tstamp.timestamp);
- *timestamp = tstamp.timestamp;
- return NO_ERROR;
- }
- return NO_ERROR;
-}
-
-// return the number of audio frames written by the audio dsp to DAC since
-// the output has exited standby
-status_t AudioSessionOutALSA::getRenderPosition(uint32_t *dspFrames)
-{
- Mutex::Autolock autoLock(mLock);
- *dspFrames = mFrameCount;
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::getBufferInfo(buf_info **buf) {
- if (!mAlsaHandle) {
- return NO_ERROR;
- }
- buf_info *tempbuf = (buf_info *)malloc(sizeof(buf_info) + mInputBufferCount*sizeof(int *));
- ALOGV("Get buffer info");
- tempbuf->bufsize = mAlsaHandle->handle->period_size;
- tempbuf->nBufs = mInputBufferCount;
- tempbuf->buffers = (int **)((char*)tempbuf + sizeof(buf_info));
- List<BuffersAllocated>::iterator it = mBufPool.begin();
- for (int i = 0; i < mInputBufferCount; i++) {
- tempbuf->buffers[i] = (int *)it->memBuf;
- it++;
- }
- *buf = tempbuf;
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::isBufferAvailable(int *isAvail) {
-
- Mutex::Autolock autoLock(mLock);
- ALOGV("isBufferAvailable Empty Queue size() = %d, Filled Queue size() = %d ",
- mEmptyQueue.size(),mFilledQueue.size());
- *isAvail = false;
- // 1.) Wait till a empty buffer is available in the Empty buffer queue
- mEmptyQueueMutex.lock();
- if (mEmptyQueue.empty()) {
- ALOGV("Write: waiting on mWriteCv");
- mLock.unlock();
- mWriteCv.wait(mEmptyQueueMutex);
- mLock.lock();
- if (mSkipWrite) {
- ALOGV("Write: Flushing the previous write buffer");
- mSkipWrite = false;
- mEmptyQueueMutex.unlock();
- return NO_ERROR;
- }
- ALOGV("isBufferAvailable: received a signal to wake up");
- }
- mEmptyQueueMutex.unlock();
-
- *isAvail = true;
- return NO_ERROR;
-}
-
-status_t AudioSessionOutALSA::openDevice(char *useCase, bool bIsUseCase, int devices)
-{
- alsa_handle_t alsa_handle;
- status_t status = NO_ERROR;
- ALOGV("openDevice: E usecase %s", useCase);
- alsa_handle.module = mAlsaDevice;
- alsa_handle.bufferSize = mInputBufferSize;
- alsa_handle.devices = devices;
- alsa_handle.handle = 0;
- alsa_handle.format = (mFormat == AUDIO_FORMAT_PCM_16_BIT ? SNDRV_PCM_FORMAT_S16_LE : mFormat);
- //ToDo: Add conversion from channel Mask to channel count.
- if (mChannels == AUDIO_CHANNEL_OUT_MONO)
- alsa_handle.channels = MONO_CHANNEL_MODE;
- else
- alsa_handle.channels = DEFAULT_CHANNEL_MODE;
- alsa_handle.sampleRate = mSampleRate;
- alsa_handle.latency = PLAYBACK_LATENCY;
- alsa_handle.rxHandle = 0;
- alsa_handle.ucMgr = mUcMgr;
- alsa_handle.session = this;
- strlcpy(alsa_handle.useCase, useCase, sizeof(alsa_handle.useCase));
-
- mAlsaDevice->route(&alsa_handle, devices, mParent->mode());
- if (bIsUseCase) {
- snd_use_case_set(mUcMgr, "_verb", useCase);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", useCase);
- }
-
- status = mAlsaDevice->open(&alsa_handle);
- if(status != NO_ERROR) {
- ALOGE("Could not open the ALSA device for use case %s", alsa_handle.useCase);
- mAlsaDevice->close(&alsa_handle);
- } else{
- mParent->mDeviceList.push_back(alsa_handle);
- }
- return status;
-}
-
-status_t AudioSessionOutALSA::closeDevice(alsa_handle_t *pHandle)
-{
- status_t status = NO_ERROR;
- ALOGV("closeDevice: useCase %s", pHandle->useCase);
- //TODO: remove from mDeviceList
- if(pHandle) {
- status = mAlsaDevice->close(pHandle);
- }
- return status;
-}
-
-status_t AudioSessionOutALSA::setParameters(const String8& keyValuePairs)
-{
- Mutex::Autolock autoLock(mLock);
- AudioParameter param = AudioParameter(keyValuePairs);
- String8 key = String8(AudioParameter::keyRouting);
- int device;
- if (param.getInt(key, device) == NO_ERROR) {
- // Ignore routing if device is 0.
- if(device) {
- ALOGV("setParameters(): keyRouting with device %#x", device);
- if(device & AudioSystem::DEVICE_OUT_ALL_A2DP) {
- mParent->mRouteAudioToA2dp = true;
- ALOGD("setParameters(): A2DP device %#x", device);
- }
- mParent->doRouting(device);
- }
- param.remove(key);
- }
- return NO_ERROR;
-}
-
-String8 AudioSessionOutALSA::getParameters(const String8& keys)
-{
- Mutex::Autolock autoLock(mLock);
- AudioParameter param = AudioParameter(keys);
- String8 value;
- String8 key = String8(AudioParameter::keyRouting);
-
- if (param.get(key, value) == NO_ERROR) {
- param.addInt(key, (int)mAlsaHandle->devices);
- }
-
- ALOGV("getParameters() %s", param.toString().string());
- return param.toString();
-}
-
-void AudioSessionOutALSA::reset() {
- mParent->mLock.lock();
- requestAndWaitForEventThreadExit();
-
- if(mAlsaHandle) {
- ALOGV("closeDevice mAlsaHandle");
- closeDevice(mAlsaHandle);
- mAlsaHandle = NULL;
- }
- ALOGV("Erase device list");
- for(ALSAHandleList::iterator it = mParent->mDeviceList.begin();
- it != mParent->mDeviceList.end(); ++it) {
- if((!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
- strlen(SND_USE_CASE_VERB_HIFI_TUNNEL))) ||
- (!strncmp(it->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
- strlen(SND_USE_CASE_MOD_PLAY_TUNNEL))) ||
- (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
- strlen(SND_USE_CASE_VERB_HIFI_LOW_POWER))) ||
- (!strncmp(it->useCase, SND_USE_CASE_MOD_PLAY_LPA,
- strlen(SND_USE_CASE_MOD_PLAY_LPA)))) {
- mParent->mDeviceList.erase(it);
- break;
- }
- }
- mParent->mLock.unlock();
-}
-void AudioSessionOutALSA::updateMetaData(size_t bytes) {
- mOutputMetadataTunnel.metadataLength = sizeof(mOutputMetadataTunnel);
- mOutputMetadataTunnel.timestamp = 0;
- mOutputMetadataTunnel.bufferLength = bytes;
- ALOGD("bytes = %d , mAlsaHandle->handle->period_size = %d ",
- bytes, mAlsaHandle->handle->period_size);
-}
-
-} // namespace android_audio_legacy
diff --git a/alsa_sound/AudioStreamInALSA.cpp b/alsa_sound/AudioStreamInALSA.cpp
index 86fb532..3b66c24 100644
--- a/alsa_sound/AudioStreamInALSA.cpp
+++ b/alsa_sound/AudioStreamInALSA.cpp
@@ -1,7 +1,7 @@
/* AudioStreamInALSA.cpp
**
** Copyright 2008-2009 Wind River Systems
- ** Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@
static int (*csd_start_record)(int);
static int (*csd_stop_record)(void);
#endif
+
#ifdef QCOM_SSR_ENABLED
#include "surround_filters_interface.h"
#endif
@@ -68,8 +69,8 @@
AudioSystem::audio_in_acoustics audio_acoustics) :
ALSAStreamOps(parent, handle),
mFramesLost(0),
- mParent(parent),
- mAcoustics(audio_acoustics)
+ mAcoustics(audio_acoustics),
+ mParent(parent)
#ifdef QCOM_SSR_ENABLED
, mFp_4ch(NULL),
mFp_6ch(NULL),
@@ -89,9 +90,7 @@
// Call surround sound library init if device is Surround Sound
if ( handle->channels == 6) {
if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, strlen(SND_USE_CASE_VERB_HIFI_REC_COMPRESSED))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED))) {
+ || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
err = initSurroundSoundLibrary(handle->bufferSize);
if ( NO_ERROR != err) {
@@ -126,13 +125,13 @@
ssize_t AudioStreamInALSA::read(void *buffer, ssize_t bytes)
{
- unsigned int period_size;
+ int period_size;
ALOGV("read:: buffer %p, bytes %d", buffer, bytes);
int n;
status_t err;
- size_t read = 0;
+ ssize_t read = 0;
char *use_case;
int newMode = mParent->mode();
@@ -143,10 +142,10 @@
snd_use_case_get(mHandle->ucMgr, "_verb", (const char **)&use_case);
if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
if ((mHandle->devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
- (newMode == AUDIO_MODE_IN_CALL)) {
+ (newMode == AudioSystem::MODE_IN_CALL)) {
ALOGD("read:: mParent->mIncallMode=%d", mParent->mIncallMode);
- if ((mParent->mIncallMode & AUDIO_CHANNEL_IN_VOICE_UPLINK) &&
- (mParent->mIncallMode & AUDIO_CHANNEL_IN_VOICE_DNLINK)) {
+ if ((mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
+ (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
#ifdef QCOM_CSDCLIENT_ENABLED
if (mParent->mFusion3Platform) {
mParent->mALSADevice->setVocRecMode(INCALL_REC_STEREO);
@@ -156,15 +155,10 @@
} else
#endif
{
- if (mHandle->format == AUDIO_FORMAT_AMR_WB) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL,
- sizeof(mHandle->useCase));
- } else {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
- sizeof(mHandle->useCase));
- }
+ strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
+ sizeof(mHandle->useCase));
}
- } else if (mParent->mIncallMode & AUDIO_CHANNEL_IN_VOICE_DNLINK) {
+ } else if (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
#ifdef QCOM_CSDCLIENT_ENABLED
if (mParent->mFusion3Platform) {
mParent->mALSADevice->setVocRecMode(INCALL_REC_MONO);
@@ -174,13 +168,8 @@
} else
#endif
{
- if (mHandle->format == AUDIO_FORMAT_AMR_WB) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL,
- sizeof(mHandle->useCase));
- } else {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
- sizeof(mHandle->useCase));
- }
+ strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
+ sizeof(mHandle->useCase));
}
}
#ifdef QCOM_FM_ENABLED
@@ -192,22 +181,20 @@
} else if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(mHandle->useCase));
} else {
- char value[128];
- property_get("persist.audio.lowlatency.rec",value,"0");
- if (!strcmp("true", value)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(mHandle->useCase));
- } else if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED, sizeof(mHandle->useCase));
- } else {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(mHandle->useCase));
- }
+ char value[128];
+ property_get("persist.audio.lowlatency.rec",value,"0");
+ if (!strcmp("true", value)) {
+ strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(mHandle->useCase));
+ } else {
+ strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(mHandle->useCase));
+ }
}
} else {
if ((mHandle->devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
- (newMode == AUDIO_MODE_IN_CALL)) {
+ (newMode == AudioSystem::MODE_IN_CALL)) {
ALOGD("read:: ---- mParent->mIncallMode=%d", mParent->mIncallMode);
- if ((mParent->mIncallMode & AUDIO_CHANNEL_IN_VOICE_UPLINK) &&
- (mParent->mIncallMode & AUDIO_CHANNEL_IN_VOICE_DNLINK)) {
+ if ((mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
+ (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
#ifdef QCOM_CSDCLIENT_ENABLED
if (mParent->mFusion3Platform) {
mParent->mALSADevice->setVocRecMode(INCALL_REC_STEREO);
@@ -217,15 +204,10 @@
} else
#endif
{
- if (mHandle->format == AUDIO_FORMAT_AMR_WB) {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL,
- sizeof(mHandle->useCase));
- } else {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_UL_DL_REC,
- sizeof(mHandle->useCase));
- }
+ strlcpy(mHandle->useCase, SND_USE_CASE_VERB_UL_DL_REC,
+ sizeof(mHandle->useCase));
}
- } else if (mParent->mIncallMode & AUDIO_CHANNEL_IN_VOICE_DNLINK) {
+ } else if (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
#ifdef QCOM_CSDCLIENT_ENABLED
if (mParent->mFusion3Platform) {
mParent->mALSADevice->setVocRecMode(INCALL_REC_MONO);
@@ -235,14 +217,8 @@
} else
#endif
{
- if (mHandle->format == AUDIO_FORMAT_AMR_WB) {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL,
- sizeof(mHandle->useCase));
- }
- else {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_DL_REC,
- sizeof(mHandle->useCase));
- }
+ strlcpy(mHandle->useCase, SND_USE_CASE_VERB_DL_REC,
+ sizeof(mHandle->useCase));
}
}
#ifdef QCOM_FM_ENABLED
@@ -253,16 +229,14 @@
#endif
} else if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)){
strlcpy(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(mHandle->useCase));
- } else if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)){
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED, sizeof(mHandle->useCase));
} else {
- char value[128];
- property_get("persist.audio.lowlatency.rec",value,"0");
- if (!strcmp("true", value)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(mHandle->useCase));
- } else {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(mHandle->useCase));
- }
+ char value[128];
+ property_get("persist.audio.lowlatency.rec",value,"0");
+ if (!strcmp("true", value)) {
+ strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(mHandle->useCase));
+ } else {
+ strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(mHandle->useCase));
+ }
}
}
free(use_case);
@@ -271,11 +245,11 @@
#ifdef QCOM_USBAUDIO_ENABLED
if((mDevices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
(mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)) {
- mHandle->module->route(mHandle, (mDevices | AudioSystem::DEVICE_IN_PROXY) , AUDIO_MODE_IN_COMMUNICATION);
+ mHandle->module->route(mHandle, (mDevices | AudioSystem::DEVICE_IN_PROXY) , AudioSystem::MODE_IN_COMMUNICATION);
}else
#endif
{
- mHandle->module->route(mHandle, mDevices , AUDIO_MODE_IN_COMMUNICATION);
+ mHandle->module->route(mHandle, mDevices , AudioSystem::MODE_IN_COMMUNICATION);
}
} else {
#ifdef QCOM_USBAUDIO_ENABLED
@@ -291,7 +265,6 @@
}
if (!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC) ||
!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED) ||
!strcmp(mHandle->useCase, SND_USE_CASE_VERB_FM_REC) ||
!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL) ||
!strcmp(mHandle->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) ||
@@ -439,39 +412,6 @@
buffer = buffer_start;
} else
#endif
- if (mHandle->format == AUDIO_FORMAT_AMR_WB &&
- (strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) &&
- (strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
- ALOGV("AUDIO_FORMAT_AMR_WB");
- do {
- if (read_pending < 61) {
- read_pending = 61;
- }
- //We should pcm_read period_size to get complete data from driver
- n = pcm_read(mHandle->handle, buffer, period_size);
- if (n < 0) {
- ALOGE("pcm_read() returned failure: %d", n);
- return 0;
- } else {
- struct snd_compr_audio_info *header = (struct snd_compr_audio_info *) buffer;
- if (header->frame_size > 0) {
- if (sizeof(*header) + header->reserved[0] + header->frame_size > period_size) {
- ALOGE("AMR WB read buffer overflow. Assign bigger buffer size");
- header->frame_size = period_size - sizeof(*header) - header->reserved[0];
- }
- read += header->frame_size;
- read_pending -= header->frame_size;
- ALOGV("buffer: %p, data offset: %p, header size: %u, reserved[0]: %u",
- buffer, ((uint8_t*)buffer) + sizeof(*header) + header->reserved[0],
- sizeof(*header), header->reserved[0]);
- memmove(buffer, ((uint8_t*)buffer) + sizeof(*header) + header->reserved[0], header->frame_size);
- buffer += header->frame_size;
- } else {
- ALOGW("pcm_read() with zero frame size");
- }
- }
- } while (mHandle->handle && read < bytes);
- } else
{
do {
@@ -484,24 +424,24 @@
ALOGV("pcm_read() returned n = %d", n);
if (n && (n == -EIO || n == -EAGAIN || n == -EPIPE || n == -EBADFD)) {
mParent->mLock.lock();
- if (mHandle->handle != NULL) {
- ALOGW("pcm_read() returned error n %d, Recovering from error\n", n);
- pcm_close(mHandle->handle);
- mHandle->handle = NULL;
- if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
- (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
- pcm_close(mHandle->rxHandle);
- mHandle->rxHandle = NULL;
- mHandle->module->startVoipCall(mHandle);
- }
- else
- mHandle->module->open(mHandle);
- if(mHandle->handle == NULL) {
- ALOGE("read:: PCM device re-open failed");
- mParent->mLock.unlock();
- return 0;
- }
+ ALOGW("pcm_read() returned error n %d, Recovering from error\n", n);
+ pcm_close(mHandle->handle);
+ mHandle->handle = NULL;
+ if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
+ (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
+ pcm_close(mHandle->rxHandle);
+ mHandle->rxHandle = NULL;
+ mHandle->module->startVoipCall(mHandle);
}
+ else
+ mHandle->module->open(mHandle);
+
+ if(mHandle->handle == NULL) {
+ ALOGE("read:: PCM device re-open failed");
+ mParent->mLock.unlock();
+ return 0;
+ }
+
mParent->mLock.unlock();
continue;
}
@@ -512,7 +452,11 @@
else {
read += static_cast<ssize_t>((period_size));
read_pending -= period_size;
- buffer += period_size;
+ //Set mute by cleanning buffers read
+ if (mParent->mMicMute) {
+ memset(buffer, 0, period_size);
+ }
+ buffer = ((uint8_t *)buffer) + period_size;
}
} while (mHandle->handle && read < bytes);
@@ -544,10 +488,10 @@
(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
if((mParent->mVoipStreamCount)) {
#ifdef QCOM_USBAUDIO_ENABLED
- ALOGV("musbRecordingState: %d, mVoipStreamCount:%d",mParent->musbRecordingState,
+ ALOGD("musbRecordingState: %d, mVoipStreamCount:%d",mParent->musbRecordingState,
mParent->mVoipStreamCount );
if(mParent->mVoipStreamCount == 1) {
- ALOGV("Deregistering VOIP Call bit, musbPlaybackState:%d,"
+ ALOGD("Deregistering VOIP Call bit, musbPlaybackState:%d,"
"musbRecordingState:%d", mParent->musbPlaybackState, mParent->musbRecordingState);
mParent->musbPlaybackState &= ~USBPLAYBACKBIT_VOIPCALL;
mParent->musbRecordingState &= ~USBRECBIT_VOIPCALL;
@@ -558,7 +502,6 @@
return NO_ERROR;
}
mParent->mVoipStreamCount = 0;
- mParent->mVoipMicMute = 0;
#ifdef QCOM_USBAUDIO_ENABLED
} else {
ALOGD("Deregistering REC bit, musbRecordingState:%d", mParent->musbRecordingState);
diff --git a/alsa_sound/AudioStreamOutALSA.cpp b/alsa_sound/AudioStreamOutALSA.cpp
index 05c71ae..2adb5d8 100644
--- a/alsa_sound/AudioStreamOutALSA.cpp
+++ b/alsa_sound/AudioStreamOutALSA.cpp
@@ -1,7 +1,7 @@
/* AudioStreamOutALSA.cpp
**
** Copyright 2008-2009 Wind River Systems
- ** Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ ** Copyright (c) 2011, Code Aurora Forum. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -53,19 +53,12 @@
AudioStreamOutALSA::AudioStreamOutALSA(AudioHardwareALSA *parent, alsa_handle_t *handle) :
ALSAStreamOps(parent, handle),
mParent(parent),
- mFrameCount(0),
- mUseCase(AudioHardwareALSA::USECASE_NONE)
+ mFrameCount(0)
{
}
AudioStreamOutALSA::~AudioStreamOutALSA()
{
- if (mParent->mRouteAudioToA2dp) {
- status_t err = mParent->stopA2dpPlayback(mUseCase);
- if (err) {
- ALOGE("stopA2dpPlayback return err %d", err);
- }
- }
close();
}
@@ -91,7 +84,21 @@
}
vol = lrint((volume * 0x2000)+0.5);
- if(!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL,
+ if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER) ||
+ !strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) {
+ ALOGV("setLpaVolume(%f)\n", volume);
+ ALOGV("Setting LPA volume to %d (available range is 0 to 100)\n", vol);
+ mHandle->module->setLpaVolume(vol);
+ return status;
+ }
+ else if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL) ||
+ !strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL)) {
+ ALOGV("setCompressedVolume(%f)\n", volume);
+ ALOGV("Setting Compressed volume to %d (available range is 0 to 100)\n", vol);
+ mHandle->module->setCompressedVolume(vol);
+ return status;
+ }
+ else if(!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL,
sizeof(mHandle->useCase)) || !strncmp(mHandle->useCase,
SND_USE_CASE_MOD_PLAY_VOIP, sizeof(mHandle->useCase))) {
ALOGV("Avoid Software volume by returning success\n");
@@ -113,103 +120,98 @@
int write_pending = bytes;
- if((strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) &&
- (strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
+ if((mHandle->handle == NULL) && (mHandle->rxHandle == NULL) &&
+ (strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) &&
+ (strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
mParent->mLock.lock();
- /* PCM handle might be closed and reopened immediately to flush
- * the buffers, recheck and break if PCM handle is valid */
- if (mHandle->handle == NULL && mHandle->rxHandle == NULL) {
- ALOGV("mDevices =0x%x", mDevices);
- if(mDevices & AudioSystem::DEVICE_OUT_ALL_A2DP) {
- ALOGV("StreamOut write - mRouteAudioToA2dp = %d ", mParent->mRouteAudioToA2dp);
- mParent->mRouteAudioToA2dp = true;
+
+ ALOGD("mHandle->useCase: %s", mHandle->useCase);
+ snd_use_case_get(mHandle->ucMgr, "_verb", (const char **)&use_case);
+ if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
+ if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)){
+ strlcpy(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL,
+ sizeof(SND_USE_CASE_VERB_IP_VOICECALL));
+ } else if(!strcmp(mHandle->useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) {
+ strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI2,
+ sizeof(SND_USE_CASE_MOD_PLAY_MUSIC2));
+ } else if (!strcmp(mHandle->useCase,SND_USE_CASE_MOD_PLAY_MUSIC)){
+ strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI,
+ sizeof(SND_USE_CASE_MOD_PLAY_MUSIC));
+ } else if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) {
+ strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
+ sizeof(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC));
}
- ALOGV("write: mHandle->useCase: %s", mHandle->useCase);
- snd_use_case_get(mHandle->ucMgr, "_verb", (const char **)&use_case);
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)){
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL,sizeof(mHandle->useCase));
- } else if (mHandle->isFastOutput){
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, sizeof(mHandle->useCase));
- } else {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI, sizeof(mHandle->useCase));
- }
- } else {
- if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP,sizeof(mHandle->useCase));
- } else if (mHandle->isFastOutput){
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, sizeof(mHandle->useCase));
- } else {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC, sizeof(mHandle->useCase));
- }
+ } else {
+ if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)){
+ strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP,
+ sizeof(SND_USE_CASE_MOD_PLAY_VOIP));
+ } else if(!strcmp(mHandle->useCase,SND_USE_CASE_VERB_HIFI2)) {
+ strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
+ sizeof(SND_USE_CASE_MOD_PLAY_MUSIC2));
+ } else if (!strcmp(mHandle->useCase,SND_USE_CASE_VERB_HIFI)){
+ strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
+ sizeof(SND_USE_CASE_MOD_PLAY_MUSIC));
+ } else if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) {
+ strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
+ sizeof(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC));
}
- free(use_case);
+ }
+ free(use_case);
+ if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
+ (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
+#ifdef QCOM_USBAUDIO_ENABLED
+ if((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
+ (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
+ (mDevices & AudioSystem::DEVICE_OUT_PROXY)) {
+ mDevices |= AudioSystem::DEVICE_OUT_PROXY;
+ mHandle->module->route(mHandle, mDevices , mParent->mode());
+ }else
+#endif
+ {
+ mHandle->module->route(mHandle, mDevices , AudioSystem::MODE_IN_COMMUNICATION);
+ }
+#ifdef QCOM_USBAUDIO_ENABLED
+ } else if((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
+ (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
+ (mDevices & AudioSystem::DEVICE_OUT_PROXY)) {
+ mDevices |= AudioSystem::DEVICE_OUT_PROXY;
+ mHandle->module->route(mHandle, mDevices , mParent->mode());
+#endif
+ } else {
+ mHandle->module->route(mHandle, mDevices , mParent->mode());
+ }
+ if (!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI) ||
+ !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI2) ||
+ !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC) ||
+ !strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
+ snd_use_case_set(mHandle->ucMgr, "_verb", mHandle->useCase);
+ } else {
+ snd_use_case_set(mHandle->ucMgr, "_enamod", mHandle->useCase);
+ }
+ if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
+ (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
+ err = mHandle->module->startVoipCall(mHandle);
+ }
+ else
+ mHandle->module->open(mHandle);
+ if(mHandle->handle == NULL) {
+ ALOGE("write:: device open failed");
+ mParent->mLock.unlock();
+ return bytes;
+ }
+#ifdef QCOM_USBAUDIO_ENABLED
+ if((mHandle->devices == AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET)||
+ (mHandle->devices == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)){
if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
-#ifdef QCOM_USBAUDIO_ENABLED
- if((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
- (mDevices & AudioSystem::DEVICE_OUT_PROXY)) {
- mHandle->module->route(mHandle, mDevices , mParent->mode());
- }else
-#endif
- {
- mHandle->module->route(mHandle, mDevices , AUDIO_MODE_IN_COMMUNICATION);
- }
-#ifdef QCOM_USBAUDIO_ENABLED
- } else if((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
- (mDevices & AudioSystem::DEVICE_OUT_PROXY)) {
- mHandle->module->route(mHandle, mDevices , mParent->mode());
-#endif
+ mParent->musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
} else {
- mHandle->module->route(mHandle, mDevices , mParent->mode());
- }
- if (!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI2) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
- snd_use_case_set(mHandle->ucMgr, "_verb", mHandle->useCase);
- } else {
- snd_use_case_set(mHandle->ucMgr, "_enamod", mHandle->useCase);
- }
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- err = mHandle->module->startVoipCall(mHandle);
- }
- else
- mHandle->module->open(mHandle);
- if(mHandle->handle == NULL) {
- ALOGE("write:: device open failed");
- mParent->mLock.unlock();
- return bytes;
- }
-#ifdef QCOM_USBAUDIO_ENABLED
- if((mHandle->devices == AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET)||
- (mHandle->devices == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)){
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- mParent->musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
- } else {
- mParent->startUsbPlaybackIfNotStarted();
- mParent->musbPlaybackState |= USBPLAYBACKBIT_MUSIC;
- }
- }
-#endif
- }
- if (mParent->mRouteAudioToA2dp) {
- mUseCase = mParent->useCaseStringToEnum(mHandle->useCase);
- if (! (mParent->getA2DPActiveUseCases_l() & mUseCase )){
- ALOGD("startA2dpPlayback_l from write :: useCase = %s", mHandle->useCase);
- status_t err = NO_ERROR;
- err = mParent->startA2dpPlayback_l(mUseCase);
- if(err) {
- ALOGE("startA2dpPlayback_l from write return err = %d", err);
- mParent->mLock.unlock();
- return err;
- }
+ mParent->startUsbPlaybackIfNotStarted();
+ mParent->musbPlaybackState |= USBPLAYBACKBIT_MUSIC;
}
}
+#endif
+
mParent->mLock.unlock();
}
@@ -222,7 +224,7 @@
ALOGV("Starting playback on USB");
if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL) ||
!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
- ALOGV("Setting VOIPCALL bit here, musbPlaybackState %d", mParent->musbPlaybackState);
+ ALOGD("Setting VOIPCALL bit here, musbPlaybackState %d", mParent->musbPlaybackState);
mParent->musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
}else{
ALOGV("enabling music, musbPlaybackState: %d ", mParent->musbPlaybackState);
@@ -308,24 +310,16 @@
mParent->musbRecordingState &= ~USBRECBIT_VOIPCALL;
mParent->closeUsbPlaybackIfNothingActive();
mParent->closeUsbRecordingIfNothingActive();
-
- if (mParent->mRouteAudioToA2dp) {
- //TODO: HANDLE VOIP A2DP
- }
}
#endif
return NO_ERROR;
}
mParent->mVoipStreamCount = 0;
- mParent->mVoipMicMute = 0;
}
#ifdef QCOM_USBAUDIO_ENABLED
else if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LPA))) {
mParent->musbPlaybackState &= ~USBPLAYBACKBIT_LPA;
- } else if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
- mParent->musbPlaybackState &= ~USBPLAYBACKBIT_TUNNEL;
} else {
mParent->musbPlaybackState &= ~USBPLAYBACKBIT_MUSIC;
}
@@ -333,14 +327,6 @@
mParent->closeUsbPlaybackIfNothingActive();
#endif
- if (mParent->mRouteAudioToA2dp) {
- ALOGD("close-suspendA2dpPlayback_l::mUseCase = %d",mUseCase);
- status_t err = mParent->suspendA2dpPlayback_l(mUseCase);
- if(err) {
- ALOGE("suspendA2dpPlayback from hardware output close return err = %d", err);
- return err;
- }
- }
ALSAStreamOps::close();
return NO_ERROR;
@@ -362,10 +348,6 @@
(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LPA))) {
ALOGV("Deregistering LPA bit");
mParent->musbPlaybackState &= ~USBPLAYBACKBIT_LPA;
- } else if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
- ALOGD("Deregistering Tunnel Player bit");
- mParent->musbPlaybackState &= ~USBPLAYBACKBIT_TUNNEL;
} else {
ALOGV("Deregistering MUSIC bit, musbPlaybackState: %d", mParent->musbPlaybackState);
mParent->musbPlaybackState &= ~USBPLAYBACKBIT_MUSIC;
@@ -373,12 +355,6 @@
#endif
mHandle->module->standby(mHandle);
- if (mParent->mRouteAudioToA2dp) {
- status_t err = mParent->stopA2dpPlayback_l(mUseCase);
- if(err) {
- ALOGE("stopA2dpPlayback return err %d", err);
- }
- }
#ifdef QCOM_USBAUDIO_ENABLED
mParent->closeUsbPlaybackIfNothingActive();
diff --git a/alsa_sound/AudioUsbALSA.cpp b/alsa_sound/AudioUsbALSA.cpp
index 02847dc..3316e3e 100644
--- a/alsa_sound/AudioUsbALSA.cpp
+++ b/alsa_sound/AudioUsbALSA.cpp
@@ -1,6 +1,5 @@
/* AudioUsbALSA.cpp
-
-Copyright (c) 2012, The Linux Foundation. All rights reserved.
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -55,9 +54,6 @@
#define USB_PERIOD_SIZE 2048
#define PROXY_PERIOD_SIZE 3072
-#define PROXY_SUPPORTED_RATE_8000 8000
-#define PROXY_SUPPORTED_RATE_16000 16000
-#define PROXY_SUPPORTED_RATE_48000 48000
namespace android_audio_legacy
{
@@ -67,10 +63,6 @@
musbpfdPlayback = -1;
mkillPlayBackThread = false;
mkillRecordingThread = false;
- musbRecordingHandle = NULL;
- mproxyRecordingHandle = NULL;
- musbPlaybackHandle = NULL;
- mproxyPlaybackHandle = NULL;
}
AudioUsbALSA::~AudioUsbALSA()
@@ -125,11 +117,7 @@
fileSize = st.st_size;
- if ((read_buf = (char *)malloc(BUFFSIZE)) == NULL) {
- ALOGE("ERROR: Unable to allocate memory to hold stream caps");
- close(fd);
- return NO_MEMORY;
- }
+ read_buf = (char *)malloc(BUFFSIZE);
memset(read_buf, 0x0, BUFFSIZE);
err = read(fd, read_buf, BUFFSIZE);
str_start = strstr(read_buf, type);
@@ -187,19 +175,8 @@
return UNKNOWN_ERROR;
}
size = target - ratesStrStart;
- if ((ratesStr = (char *)malloc(size + 1)) == NULL) {
- ALOGE("ERROR: Unable to allocate memory to hold sample rate strings");
- close(fd);
- free(read_buf);
- return NO_MEMORY;
- }
- if ((ratesStrForVal = (char *)malloc(size + 1)) == NULL) {
- ALOGE("ERROR: Unable to allocate memory to hold sample rate string");
- close(fd);
- free(ratesStr);
- free(read_buf);
- return NO_MEMORY;
- }
+ ratesStr = (char *)malloc(size + 1) ;
+ ratesStrForVal = (char *)malloc(size + 1) ;
memcpy(ratesStr, ratesStrStart, size);
memcpy(ratesStrForVal, ratesStrStart, size);
ratesStr[size] = '\0';
@@ -228,22 +205,16 @@
}
ratesSupported[0] = atoi(nextSRString);
- ALOGV("ratesSupported[0] for playback: %d", ratesSupported[0]);
for (i = 1; i<size; i++) {
nextSRString = strtok_r(NULL, " ,.-", &temp_ptr);
ratesSupported[i] = atoi(nextSRString);
ALOGV("ratesSupported[%d] for playback: %d",i, ratesSupported[i]);
}
- for (i = 0; i<size; i++) {
- if ((ratesSupported[i] > sampleRate) && (ratesSupported[i] <= 48000)) {
- // Sample Rate should be one of the proxy supported rates only
- // This is because proxy port is used to read from/write to DSP .
- if ((ratesSupported[i] == PROXY_SUPPORTED_RATE_8000) ||
- (ratesSupported[i] == PROXY_SUPPORTED_RATE_16000) ||
- (ratesSupported[i] == PROXY_SUPPORTED_RATE_48000)) {
- sampleRate = ratesSupported[i];
- }
+ for (i = 0; i<=size; i++) {
+ if (ratesSupported[i] <= 48000) {
+ sampleRate = ratesSupported[i];
+ break;
}
}
ALOGD("sampleRate: %d", sampleRate);
@@ -261,60 +232,42 @@
void AudioUsbALSA::exitPlaybackThread(uint64_t writeVal)
{
ALOGD("exitPlaybackThread, mproxypfdPlayback: %d", mproxypfdPlayback);
- mkillPlayBackThread = true;
+ if (writeVal == SIGNAL_EVENT_KILLTHREAD) {
+ int err;
+
+ err = closeDevice(mproxyPlaybackHandle);
+ if (err) {
+ ALOGE("Info: Could not close proxy %p", mproxyPlaybackHandle);
+ }
+ err = closeDevice(musbPlaybackHandle);
+ if (err) {
+ ALOGE("Info: Could not close USB device %p", musbPlaybackHandle);
+ }
+ }
if ((mproxypfdPlayback != -1) && (musbpfdPlayback != -1)) {
write(mproxypfdPlayback, &writeVal, sizeof(uint64_t));
write(musbpfdPlayback, &writeVal, sizeof(uint64_t));
+ mkillPlayBackThread = true;
pthread_join(mPlaybackUsb,NULL);
- mPlaybackUsb = NULL;
- }
- if (writeVal == SIGNAL_EVENT_KILLTHREAD) {
- int err;
- {
- Mutex::Autolock autoLock(mLock);
- err = closeDevice(mproxyPlaybackHandle);
- if (err) {
- ALOGE("Info: Could not close proxy %p", mproxyPlaybackHandle);
- }
- err = closeDevice(musbPlaybackHandle);
- if (err) {
- ALOGE("Info: Could not close USB device %p", musbPlaybackHandle);
- }
- }
}
}
void AudioUsbALSA::exitRecordingThread(uint64_t writeVal)
{
- //TODO: Need to use userspace fd to kill the thread.
- // Not a valid assumption to blindly close the thread.
ALOGD("exitRecordingThread");
- mkillRecordingThread = true;
-
- if ((pfdProxyRecording[0].fd != -1) && (pfdUsbRecording[0].fd != -1)) {
- write(pfdProxyRecording[0].fd, &writeVal, sizeof(uint64_t));
- write(pfdUsbRecording[0].fd, &writeVal, sizeof(uint64_t));
- pthread_join(mRecordingUsb,NULL);
- mRecordingUsb = NULL;
- }
- if (writeVal == SIGNAL_EVENT_KILLTHREAD ) {
+ if (writeVal == SIGNAL_EVENT_KILLTHREAD) {
int err;
- {
- Mutex::Autolock autoLock(mLock);
- err = closeDevice(mproxyRecordingHandle);
- if (err) {
- ALOGE("Info: Could not close proxy for recording %p", mproxyRecordingHandle);
- } else {
- mproxyRecordingHandle = NULL;
- }
- err = closeDevice(musbRecordingHandle);
- if (err) {
- ALOGE("Info: Could not close USB recording device %p", musbRecordingHandle);
- } else {
- musbRecordingHandle = NULL;
- }
+
+ err = closeDevice(mproxyRecordingHandle);
+ if (err) {
+ ALOGE("Info: Could not close proxy for recording %p", mproxyRecordingHandle);
+ }
+ err = closeDevice(musbRecordingHandle);
+ if (err) {
+ ALOGE("Info: Could not close USB recording device %p", musbRecordingHandle);
}
}
+ mkillRecordingThread = true;
}
void AudioUsbALSA::setkillUsbRecordingThread(bool val){
@@ -355,7 +308,6 @@
if (param_set_hw_params(txHandle, params)) {
ALOGE("ERROR: cannot set hw params");
- free(params);
return NO_INIT;
}
@@ -369,7 +321,6 @@
txHandle->buffer_size, txHandle->period_size,
txHandle->period_cnt);
- free(params);
return NO_ERROR;
}
@@ -396,8 +347,7 @@
params->start_threshold = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
params->xfer_align = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
}
- //Setting stop threshold to a huge value to avoid trigger stop being called internally
- params->stop_threshold = 0x0FFFFFFF;
+ params->stop_threshold = pcm->buffer_size;
params->xfer_align = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
params->silence_size = 0;
@@ -405,10 +355,9 @@
if (param_set_sw_params(pcm, params)) {
ALOGE("ERROR: cannot set sw params");
- free(params);
return NO_INIT;
}
- free(params);
+
return NO_ERROR;
}
@@ -434,6 +383,7 @@
long frames;
static int start = 0;
struct snd_xferi x;
+ int filed;
unsigned avail, bufsize;
int bytes_written;
uint32_t sampleRate;
@@ -441,8 +391,8 @@
u_int8_t *srcUsb_addr = NULL;
u_int8_t *dstProxy_addr = NULL;
int err;
- pfdProxyRecording[0].fd = -1;
- pfdUsbRecording[0].fd = -1 ;
+ const char *fn = "/data/RecordPcm.pcm";
+ filed = open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, 0664);
err = getCap((char *)"Capture:", mchannelsCapture, msampleRateCapture);
if (err) {
@@ -470,13 +420,7 @@
msampleRateCapture, mchannelsCapture,768,false);
if (!mproxyRecordingHandle) {
ALOGE("ERROR: Could not configure Proxy for recording");
- {
- Mutex::Autolock autoLock(mLock);
- err = closeDevice(musbRecordingHandle);
- if(err == OK) {
- musbRecordingHandle = NULL;
- }
- }
+ closeDevice(musbRecordingHandle);
return;
} else {
ALOGD("Proxy Configured for recording");
@@ -614,7 +558,7 @@
bytes_written = mproxyRecordingHandle->sync_ptr->c.control.appl_ptr - mproxyRecordingHandle->sync_ptr->s.status.hw_ptr;
if ((bytes_written >= mproxyRecordingHandle->sw_p->start_threshold) && (!mproxyRecordingHandle->start)) {
- if (!mkillRecordingThread) {
+ if (!mkillPlayBackThread) {
err = startDevice(mproxyRecordingHandle, &mkillRecordingThread);
if (err == EPIPE) {
continue;
@@ -627,19 +571,9 @@
}
/*************** End sync up after write -- Proxy *********************/
if (mkillRecordingThread) {
- {
- Mutex::Autolock autoLock(mLock);
- err = closeDevice(mproxyRecordingHandle);
- if(err == OK) {
- mproxyRecordingHandle = NULL;
- }
- err = closeDevice(musbRecordingHandle);
- if(err == OK) {
- musbRecordingHandle = NULL;
- }
- }
+ closeDevice(mproxyRecordingHandle);
+ closeDevice(musbRecordingHandle);
}
- mRecordingUsb = NULL;
ALOGD("Exiting USB Recording thread");
}
@@ -672,41 +606,29 @@
err = setHardwareParams(handle, sampleRate, channelCount,periodSize);
if (err != NO_ERROR) {
ALOGE("ERROR: setHardwareParams failed");
- {
- Mutex::Autolock autoLock(mLock);
- closeDevice(handle);
- return NULL;
- }
+ closeDevice(handle);
+ return NULL;
}
err = setSoftwareParams(handle, playback);
if (err != NO_ERROR) {
ALOGE("ERROR: setSoftwareParams failed");
- {
- Mutex::Autolock autoLock(mLock);
- closeDevice(handle);
- return NULL;
- }
+ closeDevice(handle);
+ return NULL;
}
err = mmap_buffer(handle);
if (err) {
ALOGE("ERROR: mmap_buffer failed");
- {
- Mutex::Autolock autoLock(mLock);
- closeDevice(handle);
- return NULL;
- }
+ closeDevice(handle);
+ return NULL;
}
err = pcm_prepare(handle);
if (err) {
ALOGE("ERROR: pcm_prepare failed");
- {
- Mutex::Autolock autoLock(mLock);
- closeDevice(handle);
- return NULL;
- }
+ closeDevice(handle);
+ return NULL;
}
return handle;
@@ -834,7 +756,7 @@
return;
}
- if (pfdUsbPlayback[0].revents & POLLERR || pfdUsbPlayback[0].revents & POLLHUP ||
+ if (pfdUsbPlayback[0].revents & POLLERR || pfdProxyPlayback[0].revents & POLLHUP ||
pfdUsbPlayback[0].revents & POLLNVAL) {
ALOGE("Info: usb throwing error");
mkillPlayBackThread = true;
@@ -858,6 +780,8 @@
unsigned int tmp;
int numOfBytesWritten;
int err;
+ int filed;
+ const char *fn = "/data/test.pcm";
mdstUsb_addr = NULL;
msrcProxy_addr = NULL;
@@ -877,13 +801,7 @@
msampleRatePlayback, mchannelsPlayback, USB_PERIOD_SIZE, true);
if (!musbPlaybackHandle) {
ALOGE("ERROR: configureUsbDevice failed, returning");
- {
- Mutex::Autolock autoLock(mLock);
- err = closeDevice(musbPlaybackHandle);
- if(err == OK) {
- musbPlaybackHandle = NULL;
- }
- }
+ closeDevice(musbPlaybackHandle);
return;
} else {
ALOGD("USB Configured for playback");
@@ -901,13 +819,7 @@
msampleRatePlayback, mchannelsPlayback, PROXY_PERIOD_SIZE, false);
if (!mproxyPlaybackHandle) {
ALOGE("ERROR: Could not configure Proxy, returning");
- {
- Mutex::Autolock autoLock(mLock);
- err = closeDevice(musbPlaybackHandle);
- if(err == OK) {
- musbPlaybackHandle = NULL;
- }
- }
+ closeDevice(musbPlaybackHandle);
return;
} else {
ALOGD("Proxy Configured for playback");
@@ -921,7 +833,7 @@
pfdProxyPlayback[0].events = (POLLIN); // | POLLERR | POLLNVAL);
mproxypfdPlayback = eventfd(0,0);
pfdProxyPlayback[1].fd = mproxypfdPlayback;
- pfdProxyPlayback[1].events = (POLLIN | POLLERR | POLLNVAL);
+ pfdProxyPlayback[1].events = (POLLIN | POLLOUT| POLLERR | POLLNVAL);
}
frames = (mproxyPlaybackHandle->flags & PCM_MONO) ? (proxyPeriod / 2) : (proxyPeriod / 4);
@@ -930,17 +842,9 @@
u_int8_t *proxybuf = ( u_int8_t *) malloc(PROXY_PERIOD_SIZE);
u_int8_t *usbbuf = ( u_int8_t *) malloc(USB_PERIOD_SIZE);
+ memset(proxybuf, 0x0, PROXY_PERIOD_SIZE);
+ memset(usbbuf, 0x0, USB_PERIOD_SIZE);
- if (proxybuf == NULL || usbbuf == NULL) {
- ALOGE("ERROR: Unable to allocate USB audio buffer(s): proxybuf=%p, usbbuf=%p",
- proxybuf, usbbuf);
- /* Don't run the playback loop if we failed to allocate either of these buffers.
- If either pointer is non-NULL they'll be freed after the end of the loop. */
- mkillPlayBackThread = true;
- } else {
- memset(proxybuf, 0x0, PROXY_PERIOD_SIZE);
- memset(usbbuf, 0x0, USB_PERIOD_SIZE);
- }
/***********************keep reading from proxy and writing to USB******************************************/
while (mkillPlayBackThread != true) {
@@ -1024,12 +928,12 @@
err = syncPtr(mproxyPlaybackHandle, &mkillPlayBackThread);
if (err == EPIPE) {
continue;
- } else if (err != NO_ERROR && err != ENODEV) {
+ } else if (err != NO_ERROR) {
break;
}
}
}
- //ALOGV("usbSizeFilled %d, proxySizeRemaining %d ",usbSizeFilled,proxySizeRemaining);
+ //ALOGE("usbSizeFilled %d, proxySizeRemaining %d ",usbSizeFilled,proxySizeRemaining);
if (usbPeriod - usbSizeFilled <= proxySizeRemaining) {
memcpy(usbbuf + usbSizeFilled, proxybuf + proxyPeriod - proxySizeRemaining, usbPeriod - usbSizeFilled);
proxySizeRemaining -= (usbPeriod - usbSizeFilled);
@@ -1096,20 +1000,20 @@
err = syncPtr(musbPlaybackHandle, &mkillPlayBackThread);
if (err == EPIPE) {
continue;
- } else if (err != NO_ERROR && err != ENODEV ) {
+ } else if (err != NO_ERROR) {
break;
}
}
bytes_written = musbPlaybackHandle->sync_ptr->c.control.appl_ptr - musbPlaybackHandle->sync_ptr->s.status.hw_ptr;
- ALOGV("Appl ptr %lu , hw_ptr %lu, difference %d",musbPlaybackHandle->sync_ptr->c.control.appl_ptr, musbPlaybackHandle->sync_ptr->s.status.hw_ptr, bytes_written);
+ ALOGE("Appl ptr %d , hw_ptr %d, difference %d",musbPlaybackHandle->sync_ptr->c.control.appl_ptr, musbPlaybackHandle->sync_ptr->s.status.hw_ptr, bytes_written);
/*
Following is the check to prevent USB from going to bad state.
This happens in case of an underrun where there is not enough
data from the proxy
*/
- if (bytes_written <= usbPeriod && musbPlaybackHandle->start) {
+ if (bytes_written <= usbPeriod && musbPlaybackHandle->start) {
ioctl(musbPlaybackHandle->fd, SNDRV_PCM_IOCTL_PAUSE,1);
pcm_prepare(musbPlaybackHandle);
musbPlaybackHandle->start = false;
@@ -1129,36 +1033,16 @@
/*************** End sync up after write -- USB *********************/
}
}
- if (proxybuf)
- free(proxybuf);
- if (usbbuf)
- free(usbbuf);
- if(mproxypfdPlayback != -1) {
- close(mproxypfdPlayback);
+ if (mkillPlayBackThread) {
+ if (proxybuf)
+ free(proxybuf);
+ if (usbbuf)
+ free(usbbuf);
mproxypfdPlayback = -1;
- }
- if(musbpfdPlayback != -1) {
- close(musbpfdPlayback);
musbpfdPlayback = -1;
+ closeDevice(mproxyPlaybackHandle);
+ closeDevice(musbPlaybackHandle);
}
- if(mkillPlayBackThread) {
- {
- Mutex::Autolock autoLock(mLock);
- err = closeDevice(mproxyPlaybackHandle);
- if(err == OK) {
- mproxyPlaybackHandle = NULL;
- } else {
- ALOGE("mproxyPlaybackHandle - err = %d", err);
- }
- err = closeDevice(musbPlaybackHandle);
- if(err == OK) {
- musbPlaybackHandle = NULL;
- } else {
- ALOGE("musbPlaybackHandle - err = %d", err);
- }
- }
- }
- mPlaybackUsb = NULL;
ALOGD("Exiting USB Playback Thread");
}
diff --git a/alsa_sound/AudioUsbALSA.h b/alsa_sound/AudioUsbALSA.h
index d408d1e..4204eb0 100644
--- a/alsa_sound/AudioUsbALSA.h
+++ b/alsa_sound/AudioUsbALSA.h
@@ -1,6 +1,6 @@
/* AudioUsbALSA.h
- Copyright (c) 2012, The Linux Foundation. All rights reserved.
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -85,7 +85,6 @@
pthread_t mPlaybackUsb;
pthread_t mRecordingUsb;
snd_use_case_mgr_t *mUcMgr;
- Mutex mLock;
//Helper functions
struct pcm * configureDevice(unsigned flags, char* hw, int sampleRate, int channelCount, int periodSize, bool playback);
diff --git a/alsa_sound/AudioUtil.cpp b/alsa_sound/AudioUtil.cpp
index 98131e9..3549f24 100644
--- a/alsa_sound/AudioUtil.cpp
+++ b/alsa_sound/AudioUtil.cpp
@@ -1,6 +1,6 @@
/* AudioUtil.cpp
*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/alsa_sound/AudioUtil.h b/alsa_sound/AudioUtil.h
index 70e5194..6575315 100644
--- a/alsa_sound/AudioUtil.h
+++ b/alsa_sound/AudioUtil.h
@@ -1,6 +1,6 @@
/* AudioUtil.h
*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/alsa_sound/alsa_default.cpp b/alsa_sound/alsa_default.cpp
new file mode 100644
index 0000000..7f477b5
--- /dev/null
+++ b/alsa_sound/alsa_default.cpp
@@ -0,0 +1,1798 @@
+/* alsa_default.cpp
+ **
+ ** Copyright 2009 Wind River Systems
+ ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ **
+ ** 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 "ALSAModule"
+//#define LOG_NDEBUG 0
+#define LOG_NDDEBUG 0
+#include <utils/Log.h>
+#include <cutils/properties.h>
+#include <linux/ioctl.h>
+#include "AudioUtil.h"
+#include "AudioHardwareALSA.h"
+#include <media/AudioRecord.h>
+#include <dlfcn.h>
+#ifdef QCOM_CSDCLIENT_ENABLED
+extern "C" {
+static int (*csd_disable_device)();
+static int (*csd_enable_device)(int, int, uint32_t);
+static int (*csd_volume)(int);
+static int (*csd_mic_mute)(int);
+static int (*csd_wide_voice)(uint8_t);
+static int (*csd_slow_talk)(uint8_t);
+static int (*csd_fens)(uint8_t);
+static int (*csd_start_voice)();
+static int (*csd_stop_voice)();
+}
+#endif
+
+#ifndef ALSA_DEFAULT_SAMPLE_RATE
+#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
+#endif
+
+#define BTSCO_RATE_16KHZ 16000
+#define USECASE_TYPE_RX 1
+#define USECASE_TYPE_TX 2
+#define MAX_HDMI_CHANNEL_CNT 6
+
+namespace android_audio_legacy
+{
+
+static int s_device_open(const hw_module_t*, const char*, hw_device_t**);
+static int s_device_close(hw_device_t*);
+static status_t s_init(alsa_device_t *, ALSAHandleList &);
+static status_t s_open(alsa_handle_t *);
+static status_t s_close(alsa_handle_t *);
+static status_t s_standby(alsa_handle_t *);
+static status_t s_route(alsa_handle_t *, uint32_t, int);
+static status_t s_start_voice_call(alsa_handle_t *);
+static status_t s_start_voip_call(alsa_handle_t *);
+static status_t s_start_fm(alsa_handle_t *);
+static void s_set_voice_volume(int);
+static void s_set_voip_volume(int);
+static void s_set_mic_mute(int);
+static void s_set_voip_mic_mute(int);
+static void s_set_voip_config(int, int);
+static status_t s_set_fm_vol(int);
+static void s_set_btsco_rate(int);
+static status_t s_set_lpa_vol(int);
+static void s_enable_wide_voice(bool flag);
+static void s_enable_fens(bool flag);
+static void s_set_flags(uint32_t flags);
+static status_t s_set_compressed_vol(int);
+static void s_enable_slow_talk(bool flag);
+static void s_set_voc_rec_mode(uint8_t mode);
+static void s_set_volte_mic_mute(int state);
+static void s_set_volte_volume(int vol);
+#ifdef SEPERATED_AUDIO_INPUT
+static void s_setInput(int);
+
+static int input_source;
+#endif
+#ifdef QCOM_CSDCLIENT_ENABLED
+static void s_set_csd_handle(void*);
+#endif
+
+static char mic_type[25];
+static char curRxUCMDevice[50];
+static char curTxUCMDevice[50];
+static int fluence_mode;
+static int fmVolume;
+#ifdef USES_FLUENCE_INCALL
+static uint32_t mDevSettingsFlag = TTY_OFF | DMIC_FLAG;
+#else
+static uint32_t mDevSettingsFlag = TTY_OFF;
+#endif
+static int btsco_samplerate = 8000;
+static ALSAUseCaseList mUseCaseList;
+static void *csd_handle;
+
+static hw_module_methods_t s_module_methods = {
+ open : s_device_open
+};
+
+extern "C" {
+hw_module_t HAL_MODULE_INFO_SYM = {
+ tag : HARDWARE_MODULE_TAG,
+ version_major : 1,
+ version_minor : 0,
+ id : ALSA_HARDWARE_MODULE_ID,
+ name : "QCOM ALSA module",
+ author : "QuIC Inc",
+ methods : &s_module_methods,
+ dso : 0,
+ reserved : {0,},
+};
+}
+
+static int s_device_open(const hw_module_t* module, const char* name,
+ hw_device_t** device)
+{
+ char value[128];
+ alsa_device_t *dev;
+ dev = (alsa_device_t *) malloc(sizeof(*dev));
+ if (!dev) return -ENOMEM;
+
+ memset(dev, 0, sizeof(*dev));
+
+ /* initialize the procs */
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = (hw_module_t *) module;
+ dev->common.close = s_device_close;
+ dev->init = s_init;
+ dev->open = s_open;
+ dev->close = s_close;
+ dev->route = s_route;
+ dev->standby = s_standby;
+ dev->startVoiceCall = s_start_voice_call;
+ dev->startVoipCall = s_start_voip_call;
+ dev->startFm = s_start_fm;
+ dev->setVoiceVolume = s_set_voice_volume;
+ dev->setVoipVolume = s_set_voip_volume;
+ dev->setMicMute = s_set_mic_mute;
+ dev->setVoipMicMute = s_set_voip_mic_mute;
+ dev->setVoipConfig = s_set_voip_config;
+ dev->setFmVolume = s_set_fm_vol;
+ dev->setBtscoRate = s_set_btsco_rate;
+ dev->setLpaVolume = s_set_lpa_vol;
+ dev->enableWideVoice = s_enable_wide_voice;
+ dev->enableFENS = s_enable_fens;
+ dev->setFlags = s_set_flags;
+ dev->setCompressedVolume = s_set_compressed_vol;
+ dev->enableSlowTalk = s_enable_slow_talk;
+ dev->setVocRecMode = s_set_voc_rec_mode;
+ dev->setVoLTEMicMute = s_set_volte_mic_mute;
+ dev->setVoLTEVolume = s_set_volte_volume;
+#ifdef SEPERATED_AUDIO_INPUT
+ dev->setInput = s_setInput;
+#endif
+#ifdef QCOM_CSDCLIENT_ENABLED
+ dev->setCsdHandle = s_set_csd_handle;
+#endif
+ *device = &dev->common;
+
+ property_get("persist.audio.handset.mic",value,"0");
+ strlcpy(mic_type, value, sizeof(mic_type));
+ property_get("persist.audio.fluence.mode",value,"0");
+ if (!strcmp("broadside", value)) {
+ fluence_mode = FLUENCE_MODE_BROADSIDE;
+ } else {
+ fluence_mode = FLUENCE_MODE_ENDFIRE;
+ }
+ strlcpy(curRxUCMDevice, "None", sizeof(curRxUCMDevice));
+ strlcpy(curTxUCMDevice, "None", sizeof(curTxUCMDevice));
+ ALOGV("ALSA module opened");
+
+ return 0;
+}
+
+static int s_device_close(hw_device_t* device)
+{
+ free(device);
+ device = NULL;
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
+
+static void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode);
+static char *getUCMDevice(uint32_t devices, int input, char *rxDevice);
+static void disableDevice(alsa_handle_t *handle);
+int getUseCaseType(const char *useCase);
+
+static int callMode = AudioSystem::MODE_NORMAL;
+// ----------------------------------------------------------------------------
+
+bool platform_is_Fusion3()
+{
+ char platform[128], baseband[128];
+ property_get("ro.board.platform", platform, "");
+ property_get("ro.baseband", baseband, "");
+ if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband))
+ return true;
+ else
+ return false;
+}
+
+int deviceName(alsa_handle_t *handle, unsigned flags, char **value)
+{
+ int ret = 0;
+ char ident[70];
+
+ if (flags & PCM_IN) {
+ strlcpy(ident, "CapturePCM/", sizeof(ident));
+ } else {
+ strlcpy(ident, "PlaybackPCM/", sizeof(ident));
+ }
+ strlcat(ident, handle->useCase, sizeof(ident));
+ ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value);
+ ALOGD("Device value returned is %s", (*value));
+ return ret;
+}
+
+status_t setHDMIChannelCount()
+{
+ status_t err = NO_ERROR;
+ int channel_count = 0;
+ const char *channel_cnt_str = NULL;
+ EDID_AUDIO_INFO info = { 0 };
+
+ ALSAControl control("/dev/snd/controlC0");
+ if (AudioUtil::getHDMIAudioSinkCaps(&info)) {
+ for (int i = 0; i < info.nAudioBlocks && i < MAX_EDID_BLOCKS; i++) {
+ if (info.AudioBlocksArray[i].nChannels > channel_count &&
+ info.AudioBlocksArray[i].nChannels <= MAX_HDMI_CHANNEL_CNT) {
+ channel_count = info.AudioBlocksArray[i].nChannels;
+ }
+ }
+ }
+
+ switch (channel_count) {
+ case 6: channel_cnt_str = "Six"; break;
+ case 5: channel_cnt_str = "Five"; break;
+ case 4: channel_cnt_str = "Four"; break;
+ case 3: channel_cnt_str = "Three"; break;
+ default: channel_cnt_str = "Two"; break;
+ }
+ ALOGD("HDMI channel count: %s", channel_cnt_str);
+ control.set("HDMI_RX Channels", channel_cnt_str);
+
+ return err;
+}
+
+status_t setHardwareParams(alsa_handle_t *handle)
+{
+ struct snd_pcm_hw_params *params;
+ unsigned long bufferSize, reqBuffSize;
+ unsigned int periodTime, bufferTime;
+ unsigned int requestedRate = handle->sampleRate;
+ int status = 0;
+ int channels = handle->channels;
+ snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE;
+
+ params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
+ if (!params) {
+ ALOGE("Failed to allocate ALSA hardware parameters!");
+ return NO_INIT;
+ }
+
+ reqBuffSize = handle->bufferSize;
+ ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d",
+ (int) reqBuffSize, handle->channels, handle->sampleRate);
+
+#ifdef QCOM_SSR_ENABLED
+ if (channels == 6) {
+ if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
+ || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
+ ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
+ channels = 4;
+ }
+ }
+#endif
+
+ param_init(params);
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
+ SNDRV_PCM_ACCESS_RW_INTERLEAVED);
+ if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
+ if (handle->format == AudioSystem::AMR_NB
+ || handle->format == AudioSystem::AMR_WB
+#ifdef QCOM_QCHAT_ENABLED
+ || handle->format == AudioSystem::EVRC
+ || handle->format == AudioSystem::EVRCB
+ || handle->format == AudioSystem::EVRCWB
+#endif
+ )
+ format = SNDRV_PCM_FORMAT_SPECIAL;
+ }
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ format);
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
+ SNDRV_PCM_SUBFORMAT_STD);
+ param_set_int(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
+ param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
+ param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
+ channels * 16);
+ param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
+ channels);
+ param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
+ param_set_hw_refine(handle->handle, params);
+
+ if (param_set_hw_params(handle->handle, params)) {
+ ALOGE("cannot set hw params");
+ return NO_INIT;
+ }
+ param_dump(params);
+
+ handle->handle->buffer_size = pcm_buffer_size(params);
+ handle->handle->period_size = pcm_period_size(params);
+ handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
+ ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
+ handle->handle->buffer_size, handle->handle->period_size,
+ handle->handle->period_cnt);
+ handle->handle->rate = handle->sampleRate;
+ handle->handle->channels = handle->channels;
+ handle->periodSize = handle->handle->period_size;
+ if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
+ strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
+ (6 != handle->channels)) {
+ //Do not update buffersize for 5.1 recording
+ handle->bufferSize = handle->handle->period_size;
+ }
+
+ return NO_ERROR;
+}
+
+status_t setSoftwareParams(alsa_handle_t *handle)
+{
+ struct snd_pcm_sw_params* params;
+ struct pcm* pcm = handle->handle;
+
+ unsigned long periodSize = pcm->period_size;
+ int channels = handle->channels;
+
+ params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
+ if (!params) {
+ LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
+ return NO_INIT;
+ }
+
+#ifdef QCOM_SSR_ENABLED
+ if (channels == 6) {
+ if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
+ || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
+ ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
+ channels = 4;
+ }
+ }
+#endif
+
+ // Get the current software parameters
+ params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
+ params->period_step = 1;
+ if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
+ (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
+ ALOGV("setparam: start & stop threshold for Voip ");
+ params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
+ params->start_threshold = periodSize/2;
+ params->stop_threshold = INT_MAX;
+ } else {
+ params->avail_min = periodSize/(channels * 2);
+ params->start_threshold = periodSize/(channels * 2);
+ params->stop_threshold = INT_MAX;
+ }
+ params->silence_threshold = 0;
+ params->silence_size = 0;
+
+ if (param_set_sw_params(handle->handle, params)) {
+ ALOGE("cannot set sw params");
+ return NO_INIT;
+ }
+ return NO_ERROR;
+}
+
+void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
+{
+ const char **mods_list;
+ use_case_t useCaseNode;
+ unsigned usecase_type = 0;
+ bool inCallDevSwitch = false;
+ char *rxDevice, *txDevice, ident[70], *use_case = NULL;
+ int err = 0, index, mods_size;
+ int rx_dev_id, tx_dev_id;
+ ALOGD("%s: device %d mode:%d", __FUNCTION__, devices, mode);
+
+ if ((mode == AudioSystem::MODE_IN_CALL) || (mode == AudioSystem::MODE_IN_COMMUNICATION)) {
+ if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
+ (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
+ devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
+ AudioSystem::DEVICE_IN_WIRED_HEADSET);
+ } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
+ devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
+ AudioSystem::DEVICE_IN_BUILTIN_MIC);
+ } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
+ if (mode == AudioSystem::MODE_IN_CALL) {
+ devices |= AudioSystem::DEVICE_OUT_EARPIECE;
+//use QCOM_BACK_MIC_ENABLED only when BACK_MIC is supported by HW
+#ifdef QCOM_BACK_MIC_ENABLED
+ } else if (mode == AudioSystem::MODE_IN_COMMUNICATION) {
+ if (!strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER, MAX_LEN(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER))) {
+ devices &= ~AudioSystem::DEVICE_IN_BUILTIN_MIC;
+ devices |= AudioSystem::DEVICE_IN_BACK_MIC;
+ }
+#endif
+ }
+ } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
+ devices = devices | AudioSystem::DEVICE_IN_BUILTIN_MIC;
+ } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
+#ifdef QCOM_BACK_MIC_ENABLED
+ devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC |
+#else
+ devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
+#endif
+ AudioSystem::DEVICE_OUT_SPEAKER);
+ } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
+ (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
+ (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
+ devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET |
+ AudioSystem::DEVICE_OUT_BLUETOOTH_SCO);
+#ifdef QCOM_ANC_HEADSET_ENABLED
+ } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
+ (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
+ devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET |
+ AudioSystem::DEVICE_IN_ANC_HEADSET);
+ } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) {
+ devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE |
+ AudioSystem::DEVICE_IN_BUILTIN_MIC);
+#endif
+ } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
+ if (mode == AudioSystem::MODE_IN_CALL)
+#ifdef QCOM_BACK_MIC_ENABLED
+ devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC |
+#else
+ devices = devices | (AudioSystem::DEVICE_IN_BUILTIN_MIC |
+#endif
+ AudioSystem::DEVICE_OUT_SPEAKER);
+ else
+ devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
+#ifdef QCOM_BACK_MIC_ENABLED
+ AudioSystem::DEVICE_IN_BACK_MIC);
+#else
+ AudioSystem::DEVICE_IN_BUILTIN_MIC);
+#endif
+#ifdef QCOM_PROXY_DEVICE_ENABLED
+ } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
+ (devices & AudioSystem::DEVICE_IN_PROXY)) {
+ devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
+ AudioSystem::DEVICE_IN_PROXY);
+#endif
+ }
+ }
+#ifdef QCOM_SSR_ENABLED
+ if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
+ if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
+ || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
+ ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
+ s_set_flags(SSRQMIC_FLAG);
+ }
+ }
+#endif
+
+ rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
+ txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
+
+ if ((rxDevice != NULL) && (txDevice != NULL)) {
+ if (((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) ||
+ (strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN))) &&
+ ((mode == AudioSystem::MODE_IN_CALL) ||
+ (mode == AudioSystem::MODE_IN_COMMUNICATION)))
+ inCallDevSwitch = true;
+ }
+
+#ifdef QCOM_CSDCLIENT_ENABLED
+ if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
+ if (csd_disable_device == NULL) {
+ ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
+ } else {
+ err = csd_disable_device();
+ if (err < 0)
+ {
+ ALOGE("csd_client_disable_device, failed, error %d", err);
+ }
+ }
+ }
+#endif
+
+ snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
+ mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
+ if (rxDevice != NULL) {
+ if ((strncmp(curRxUCMDevice, "None", 4)) &&
+ ((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
+ if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
+ strlen(SND_USE_CASE_VERB_INACTIVE)))) {
+ usecase_type = getUseCaseType(use_case);
+ if (usecase_type & USECASE_TYPE_RX) {
+ ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
+ strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
+ snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
+ mUseCaseList.push_front(useCaseNode);
+ }
+ }
+ if (mods_size) {
+ for(index = 0; index < mods_size; index++) {
+ usecase_type = getUseCaseType(mods_list[index]);
+ if (usecase_type & USECASE_TYPE_RX) {
+ ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
+ strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
+ snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
+ mUseCaseList.push_back(useCaseNode);
+ }
+ }
+ }
+ snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
+ }
+ }
+ if (txDevice != NULL) {
+ if ((strncmp(curTxUCMDevice, "None", 4)) &&
+ ((strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
+ if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
+ strlen(SND_USE_CASE_VERB_INACTIVE)))) {
+ usecase_type = getUseCaseType(use_case);
+ if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
+ ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
+ strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
+ snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
+ mUseCaseList.push_front(useCaseNode);
+ }
+ }
+ if (mods_size) {
+ for(index = 0; index < mods_size; index++) {
+ usecase_type = getUseCaseType(mods_list[index]);
+ if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
+ ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
+ strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
+ snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
+ mUseCaseList.push_back(useCaseNode);
+ }
+ }
+ }
+ snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
+ }
+ }
+ ALOGD("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, curRxUCMDevice, curTxUCMDevice);
+
+ if (rxDevice != NULL) {
+ snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
+ strlcpy(curRxUCMDevice, rxDevice, sizeof(curRxUCMDevice));
+#ifdef QCOM_FM_ENABLED
+ if (devices & AudioSystem::DEVICE_OUT_FM)
+ s_set_fm_vol(fmVolume);
+#endif
+ }
+ if (txDevice != NULL) {
+ snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
+ strlcpy(curTxUCMDevice, txDevice, sizeof(curTxUCMDevice));
+ }
+ for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
+ ALOGD("Route use case %s\n", it->useCase);
+ if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
+ strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
+ snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
+ } else {
+ snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
+ }
+ }
+ if (!mUseCaseList.empty())
+ mUseCaseList.clear();
+ if (use_case != NULL) {
+ free(use_case);
+ use_case = NULL;
+ }
+ ALOGD("switchDevice: curTxUCMDevivce %s curRxDevDevice %s", curTxUCMDevice, curRxUCMDevice);
+
+ if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
+ /* get tx acdb id */
+ memset(&ident,0,sizeof(ident));
+ strlcpy(ident, "ACDBID/", sizeof(ident));
+ strlcat(ident, curTxUCMDevice, sizeof(ident));
+ tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
+
+ /* get rx acdb id */
+ memset(&ident,0,sizeof(ident));
+ strlcpy(ident, "ACDBID/", sizeof(ident));
+ strlcat(ident, curRxUCMDevice, sizeof(ident));
+ rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
+
+ if (((rx_dev_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID ) || (rx_dev_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID ))
+ && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
+ tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
+ }
+
+#ifdef QCOM_CSDCLIENT_ENABLED
+ ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
+ if (csd_enable_device == NULL) {
+ ALOGE("dlsym:Error:%s Loading csd_client_enable_device", dlerror());
+ } else {
+ err = csd_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag);
+ if (err < 0)
+ {
+ ALOGE("csd_client_disable_device failed, error %d", err);
+ }
+ }
+#endif
+ }
+
+ if (rxDevice != NULL) {
+ free(rxDevice);
+ rxDevice = NULL;
+ }
+ if (txDevice != NULL) {
+ free(txDevice);
+ txDevice = NULL;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+static status_t s_init(alsa_device_t *module, ALSAHandleList &list)
+{
+ ALOGV("s_init: Initializing devices for ALSA module");
+
+ list.clear();
+
+ return NO_ERROR;
+}
+
+static status_t s_open(alsa_handle_t *handle)
+{
+ char *devName;
+ unsigned flags = 0;
+ int err = NO_ERROR;
+
+ if(handle->devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
+ err = setHDMIChannelCount();
+ if(err != OK) {
+ ALOGE("setHDMIChannelCount err = %d", err);
+ return err;
+ }
+ }
+ /* No need to call s_close for LPA as pcm device open and close is handled by LPAPlayer in stagefright */
+ if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA))
+ ||(!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
+ ALOGV("s_open: Opening LPA /Tunnel playback");
+ return NO_ERROR;
+ }
+
+ s_close(handle);
+
+ ALOGV("s_open: handle %p", handle);
+
+ // ASoC multicomponent requires a valid path (frontend/backend) for
+ // the device to be opened
+
+ // The PCM stream is opened in blocking mode, per ALSA defaults. The
+ // AudioFlinger seems to assume blocking mode too, so asynchronous mode
+ // should not be used.
+ if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
+ ALOGV("LPA/tunnel use case");
+ flags |= PCM_MMAP;
+ flags |= DEBUG_ON;
+ } else if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI2)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) {
+ ALOGV("Music case");
+ flags = PCM_OUT;
+ } else {
+ flags = PCM_IN;
+ }
+ if (handle->channels == 1) {
+ flags |= PCM_MONO;
+ }
+ else if (handle->channels == 4 ) {
+ flags |= PCM_QUAD;
+ } else if (handle->channels == 6 ) {
+#ifdef QCOM_SSR_ENABLED
+ if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
+ || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
+ flags |= PCM_QUAD;
+ } else {
+ flags |= PCM_5POINT1;
+ }
+#else
+ flags |= PCM_5POINT1;
+#endif
+ }
+ else {
+ flags |= PCM_STEREO;
+ }
+ if (deviceName(handle, flags, &devName) < 0) {
+ ALOGE("Failed to get pcm device node: %s", devName);
+ return NO_INIT;
+ }
+ if (devName != NULL) {
+ handle->handle = pcm_open(flags, (char*)devName);
+ } else {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+
+ if (!handle->handle) {
+ ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
+ free(devName);
+ return NO_INIT;
+ }
+
+ handle->handle->flags = flags;
+ err = setHardwareParams(handle);
+
+ if (err == NO_ERROR) {
+ err = setSoftwareParams(handle);
+ }
+
+ if(err != NO_ERROR) {
+ ALOGE("Set HW/SW params failed: Closing the pcm stream");
+ s_standby(handle);
+ }
+
+ free(devName);
+ return NO_ERROR;
+}
+
+static status_t s_start_voip_call(alsa_handle_t *handle)
+{
+
+ char* devName;
+ char* devName1;
+ unsigned flags = 0;
+ int err = NO_ERROR;
+ uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE];
+
+ s_close(handle);
+ flags = PCM_OUT;
+ flags |= PCM_MONO;
+ ALOGV("s_open:s_start_voip_call handle %p", handle);
+
+ if (deviceName(handle, flags, &devName) < 0) {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+
+ if (devName != NULL) {
+ handle->handle = pcm_open(flags, (char*)devName);
+ } else {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+
+ if (!handle->handle) {
+ free(devName);
+ ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
+ return NO_INIT;
+ }
+
+ if (!pcm_ready(handle->handle)) {
+ ALOGE(" pcm ready failed");
+ }
+
+ handle->handle->flags = flags;
+ err = setHardwareParams(handle);
+
+ if (err == NO_ERROR) {
+ err = setSoftwareParams(handle);
+ }
+
+ err = pcm_prepare(handle->handle);
+ if(err != NO_ERROR) {
+ ALOGE("DEVICE_OUT_DIRECTOUTPUT: pcm_prepare failed");
+ }
+
+ /* first write required start dsp */
+ memset(&voc_pkt,0,sizeof(voc_pkt));
+ pcm_write(handle->handle,&voc_pkt,handle->handle->period_size);
+ handle->rxHandle = handle->handle;
+ free(devName);
+ ALOGV("s_open: DEVICE_IN_COMMUNICATION ");
+ flags = PCM_IN;
+ flags |= PCM_MONO;
+ handle->handle = 0;
+
+ if (deviceName(handle, flags, &devName1) < 0) {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+ if (devName != NULL) {
+ handle->handle = pcm_open(flags, (char*)devName1);
+ } else {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+
+ if (!handle->handle) {
+ free(devName);
+ ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
+ return NO_INIT;
+ }
+
+ if (!pcm_ready(handle->handle)) {
+ ALOGE(" pcm ready in failed");
+ }
+
+ handle->handle->flags = flags;
+
+ err = setHardwareParams(handle);
+
+ if (err == NO_ERROR) {
+ err = setSoftwareParams(handle);
+ }
+
+
+ err = pcm_prepare(handle->handle);
+ if(err != NO_ERROR) {
+ ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed");
+ }
+
+ /* first read required start dsp */
+ memset(&voc_pkt,0,sizeof(voc_pkt));
+ pcm_read(handle->handle,&voc_pkt,handle->handle->period_size);
+ return NO_ERROR;
+}
+
+static status_t s_start_voice_call(alsa_handle_t *handle)
+{
+ char* devName;
+ unsigned flags = 0;
+ int err = NO_ERROR;
+
+ ALOGV("s_start_voice_call: handle %p", handle);
+
+ // ASoC multicomponent requires a valid path (frontend/backend) for
+ // the device to be opened
+
+ flags = PCM_OUT | PCM_MONO;
+ if (deviceName(handle, flags, &devName) < 0) {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+ if (devName != NULL) {
+ handle->handle = pcm_open(flags, (char*)devName);
+ } else {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+ if (!handle->handle) {
+ ALOGE("s_start_voicecall: could not open PCM device");
+ goto Error;
+ }
+
+ handle->handle->flags = flags;
+ err = setHardwareParams(handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_voice_call: setHardwareParams failed");
+ goto Error;
+ }
+
+ err = setSoftwareParams(handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_voice_call: setSoftwareParams failed");
+ goto Error;
+ }
+
+ err = pcm_prepare(handle->handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_voice_call: pcm_prepare failed");
+ goto Error;
+ }
+
+ if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
+ ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
+ goto Error;
+ }
+
+ // Store the PCM playback device pointer in rxHandle
+ handle->rxHandle = handle->handle;
+ free(devName);
+
+ // Open PCM capture device
+ flags = PCM_IN | PCM_MONO;
+ if (deviceName(handle, flags, &devName) < 0) {
+ ALOGE("Failed to get pcm device node");
+ goto Error;
+ }
+ if (devName != NULL) {
+ handle->handle = pcm_open(flags, (char*)devName);
+ } else {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+ if (!handle->handle) {
+ free(devName);
+ goto Error;
+ }
+
+ handle->handle->flags = flags;
+ err = setHardwareParams(handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_voice_call: setHardwareParams failed");
+ goto Error;
+ }
+
+ err = setSoftwareParams(handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_voice_call: setSoftwareParams failed");
+ goto Error;
+ }
+
+ err = pcm_prepare(handle->handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_voice_call: pcm_prepare failed");
+ goto Error;
+ }
+
+ if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
+ ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
+ goto Error;
+ }
+
+ if (platform_is_Fusion3()) {
+#ifdef QCOM_CSDCLIENT_ENABLED
+ if (csd_start_voice == NULL) {
+ ALOGE("dlsym:Error:%s Loading csd_client_start_voice", dlerror());
+ } else {
+ err = csd_start_voice();
+ if (err < 0){
+ ALOGE("s_start_voice_call: csd_client error %d\n", err);
+ goto Error;
+ }
+ }
+#endif
+ }
+
+ free(devName);
+ return NO_ERROR;
+
+Error:
+ ALOGE("s_start_voice_call: Failed to initialize ALSA device '%s'", devName);
+ free(devName);
+ s_close(handle);
+ return NO_INIT;
+}
+
+static status_t s_start_fm(alsa_handle_t *handle)
+{
+ char *devName;
+ unsigned flags = 0;
+ int err = NO_ERROR;
+
+ ALOGV("s_start_fm: handle %p", handle);
+
+ // ASoC multicomponent requires a valid path (frontend/backend) for
+ // the device to be opened
+
+ flags = PCM_OUT | PCM_STEREO;
+ if (deviceName(handle, flags, &devName) < 0) {
+ ALOGE("Failed to get pcm device node");
+ goto Error;
+ }
+ if (devName != NULL) {
+ handle->handle = pcm_open(flags, (char*)devName);
+ } else {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+ if (!handle->handle) {
+ ALOGE("s_start_fm: could not open PCM device");
+ goto Error;
+ }
+
+ handle->handle->flags = flags;
+ err = setHardwareParams(handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_fm: setHardwareParams failed");
+ goto Error;
+ }
+
+ err = setSoftwareParams(handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_fm: setSoftwareParams failed");
+ goto Error;
+ }
+
+ err = pcm_prepare(handle->handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_fm: setSoftwareParams failed");
+ goto Error;
+ }
+
+ if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
+ ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
+ goto Error;
+ }
+
+ // Store the PCM playback device pointer in rxHandle
+ handle->rxHandle = handle->handle;
+ free(devName);
+
+ // Open PCM capture device
+ flags = PCM_IN | PCM_STEREO;
+ if (deviceName(handle, flags, &devName) < 0) {
+ ALOGE("Failed to get pcm device node");
+ goto Error;
+ }
+ if (devName != NULL) {
+ handle->handle = pcm_open(flags, (char*)devName);
+ } else {
+ ALOGE("Failed to get pcm device node");
+ return NO_INIT;
+ }
+ if (!handle->handle) {
+ goto Error;
+ }
+
+ handle->handle->flags = flags;
+ err = setHardwareParams(handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_fm: setHardwareParams failed");
+ goto Error;
+ }
+
+ err = setSoftwareParams(handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_fm: setSoftwareParams failed");
+ goto Error;
+ }
+
+ err = pcm_prepare(handle->handle);
+ if(err != NO_ERROR) {
+ ALOGE("s_start_fm: pcm_prepare failed");
+ goto Error;
+ }
+
+ if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
+ ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
+ goto Error;
+ }
+
+ s_set_fm_vol(fmVolume);
+ free(devName);
+ return NO_ERROR;
+
+Error:
+ free(devName);
+ s_close(handle);
+ return NO_INIT;
+}
+
+static status_t s_set_fm_vol(int value)
+{
+ status_t err = NO_ERROR;
+
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("Internal FM RX Volume",value,0);
+ fmVolume = value;
+
+ return err;
+}
+
+static status_t s_set_lpa_vol(int value)
+{
+ status_t err = NO_ERROR;
+
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("LPA RX Volume",value,0);
+
+ return err;
+}
+
+static status_t s_start(alsa_handle_t *handle)
+{
+ status_t err = NO_ERROR;
+
+ if(!handle->handle) {
+ ALOGE("No active PCM driver to start");
+ return err;
+ }
+
+ err = pcm_prepare(handle->handle);
+
+ return err;
+}
+
+static status_t s_close(alsa_handle_t *handle)
+{
+ int ret;
+ status_t err = NO_ERROR;
+ struct pcm *h = handle->rxHandle;
+
+ handle->rxHandle = 0;
+ ALOGV("s_close: handle %p h %p", handle, h);
+ if (h) {
+ if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) ||
+ !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) &&
+ platform_is_Fusion3()) {
+#ifdef QCOM_CSDCLIENT_ENABLED
+ if (csd_stop_voice == NULL) {
+ ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
+ } else {
+ err = csd_stop_voice();
+ if (err < 0) {
+ ALOGE("s_close: csd_client error %d\n", err);
+ }
+ }
+#endif
+ }
+
+ ALOGV("s_close rxHandle\n");
+ err = pcm_close(h);
+ if(err != NO_ERROR) {
+ ALOGE("s_close: pcm_close failed for rxHandle with err %d", err);
+ }
+ }
+
+ h = handle->handle;
+ handle->handle = 0;
+
+ if (h) {
+ ALOGV("s_close handle h %p\n", h);
+ err = pcm_close(h);
+ if(err != NO_ERROR) {
+ ALOGE("s_close: pcm_close failed for handle with err %d", err);
+ }
+
+ disableDevice(handle);
+ } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))){
+ disableDevice(handle);
+ }
+
+ return err;
+}
+
+/*
+ this is same as s_close, but don't discard
+ the device/mode info. This way we can still
+ close the device, hit idle and power-save, reopen the pcm
+ for the same device/mode after resuming
+*/
+static status_t s_standby(alsa_handle_t *handle)
+{
+ int ret;
+ status_t err = NO_ERROR;
+ struct pcm *h = handle->rxHandle;
+ handle->rxHandle = 0;
+ ALOGV("s_standby: handle %p h %p", handle, h);
+ if (h) {
+ ALOGD("s_standby rxHandle\n");
+ err = pcm_close(h);
+ if(err != NO_ERROR) {
+ ALOGE("s_standby: pcm_close failed for rxHandle with err %d", err);
+ }
+ }
+
+ h = handle->handle;
+ handle->handle = 0;
+
+ if (h) {
+ ALOGV("s_standby handle h %p\n", h);
+ err = pcm_close(h);
+ if(err != NO_ERROR) {
+ ALOGE("s_standby: pcm_close failed for handle with err %d", err);
+ }
+ disableDevice(handle);
+ } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
+ (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
+ disableDevice(handle);
+ }
+
+ return err;
+}
+
+static status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode)
+{
+ status_t status = NO_ERROR;
+
+ ALOGD("s_route: devices 0x%x in mode %d", devices, mode);
+ callMode = mode;
+ switchDevice(handle, devices, mode);
+ return status;
+}
+
+int getUseCaseType(const char *useCase)
+{
+ ALOGD("use case is %s\n", useCase);
+ if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
+ MAX_LEN(useCase, SND_USE_CASE_VERB_HIFI2)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI2)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
+ MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LPA)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_FM))) {
+ return USECASE_TYPE_RX;
+ } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_REC)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_FM_REC)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_FM_A2DP_REC)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_FM)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
+ return USECASE_TYPE_TX;
+ } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_VOICECALL)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_IP_VOICECALL)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_DL_REC)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_UL_DL_REC)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_INCALL_REC,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_INCALL_REC)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOICE)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
+ MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
+ MAX_LEN(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
+ !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
+ MAX_LEN(useCase,SND_USE_CASE_VERB_VOLTE)) ||
+ !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
+ MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_VOLTE))) {
+ return (USECASE_TYPE_RX | USECASE_TYPE_TX);
+ } else {
+ ALOGE("unknown use case %s\n", useCase);
+ return 0;
+ }
+}
+
+static void disableDevice(alsa_handle_t *handle)
+{
+ unsigned usecase_type = 0;
+ int i, mods_size;
+ char *useCase;
+ const char **mods_list;
+
+ snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
+ if (useCase != NULL) {
+ if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
+ snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
+ } else {
+ snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
+ }
+ free(useCase);
+ snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
+ if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
+ strlen(SND_USE_CASE_VERB_INACTIVE)))
+ usecase_type |= getUseCaseType(useCase);
+ mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
+ ALOGV("Number of modifiers %d\n", mods_size);
+ if (mods_size) {
+ for(i = 0; i < mods_size; i++) {
+ ALOGV("index %d modifier %s\n", i, mods_list[i]);
+ usecase_type |= getUseCaseType(mods_list[i]);
+ }
+ }
+ ALOGV("usecase_type is %d\n", usecase_type);
+ if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(curTxUCMDevice, "None", 4)))
+ snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
+ if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(curRxUCMDevice, "None", 4)))
+ snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
+ } else {
+ ALOGE("Invalid state, no valid use case found to disable");
+ }
+ free(useCase);
+}
+
+char *getUCMDevice(uint32_t devices, int input, char *rxDevice)
+{
+ if (!input) {
+ if (!(mDevSettingsFlag & TTY_OFF) &&
+ (callMode == AudioSystem::MODE_IN_CALL) &&
+ ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
+ (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
+#ifdef QCOM_ANC_HEADSET_ENABLED
+ ||
+ (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
+ (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
+#endif
+ if (mDevSettingsFlag & TTY_VCO) {
+ return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
+ } else if (mDevSettingsFlag & TTY_FULL) {
+ return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
+ } else if (mDevSettingsFlag & TTY_HCO) {
+ return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
+ }
+ }else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
+ (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) {
+ return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
+ } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
+ ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
+ (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
+ if (mDevSettingsFlag & ANC_FLAG) {
+ return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
+ } else {
+ return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
+ }
+ } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
+ ((devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL))) {
+ return strdup(SND_USE_CASE_DEV_HDMI_SPEAKER);
+#ifdef QCOM_ANC_HEADSET_ENABLED
+ } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
+ ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
+ (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
+ return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
+ } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
+ (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
+ return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
+#endif
+ } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
+ if (callMode == AudioSystem::MODE_IN_CALL) {
+ return strdup(SND_USE_CASE_DEV_VOC_EARPIECE); /* Voice HANDSET RX */
+ } else
+ return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
+ } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
+ if (callMode == AudioSystem::MODE_IN_CALL) {
+ return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */
+ } else
+ return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
+ } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
+ (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
+ if (mDevSettingsFlag & ANC_FLAG) {
+ if (callMode == AudioSystem::MODE_IN_CALL) {
+ return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
+ } else
+ return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
+ } else {
+ if (callMode == AudioSystem::MODE_IN_CALL) {
+ return strdup(SND_USE_CASE_DEV_VOC_HEADPHONE); /* Voice HEADSET RX */
+ } else
+ return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */
+ }
+#ifdef QCOM_ANC_HEADSET_ENABLED
+ } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
+ (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
+ if (callMode == AudioSystem::MODE_IN_CALL) {
+ return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
+ } else
+ return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
+#endif
+ } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
+ (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
+ (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
+ if (btsco_samplerate == BTSCO_RATE_16KHZ)
+ return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
+ else
+ return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
+ } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP) ||
+ (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
+#ifdef QCOM_VOIP_ENABLED
+ (devices & AudioSystem::DEVICE_OUT_DIRECTOUTPUT) ||
+#endif
+ (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) {
+ /* Nothing to be done, use current active device */
+ if (strncmp(curRxUCMDevice, "None", 4)) {
+ return strdup(curRxUCMDevice);
+ }
+ } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
+ return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
+#ifdef QCOM_PROXY_DEVICE_ENABLED
+ } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
+ return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
+#endif
+#ifdef QCOM_FM_TX_ENABLED
+ } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
+ return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
+#endif
+ } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
+ if (callMode == AudioSystem::MODE_IN_CALL) {
+ return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */
+ } else
+ return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
+ } else {
+ ALOGD("No valid output device: %u", devices);
+ }
+ } else {
+ if (!(mDevSettingsFlag & TTY_OFF) &&
+ (callMode == AudioSystem::MODE_IN_CALL) &&
+ ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET))) {
+#ifdef QCOM_ANC_HEADSET_ENABLED
+ ||(devices & AudioSystem::DEVICE_IN_ANC_HEADSET))) {
+#endif
+ if (mDevSettingsFlag & TTY_HCO) {
+ return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
+ } else if (mDevSettingsFlag & TTY_FULL) {
+ return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
+ } else if (mDevSettingsFlag & TTY_VCO) {
+ if (!strncmp(mic_type, "analog", 6)) {
+ return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
+ } else {
+ return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
+ }
+ }
+ } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
+ if (!strncmp(mic_type, "analog", 6)) {
+ return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
+ } else {
+ if (mDevSettingsFlag & DMIC_FLAG) {
+#ifdef USES_FLUENCE_INCALL
+ if(callMode == AudioSystem::MODE_IN_CALL) {
+ if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
+ return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
+ } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
+ return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
+ } else {
+ return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
+ }
+ }
+#else
+ if (((rxDevice != NULL) &&
+ !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
+ (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
+ !strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
+ (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) {
+ if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
+ return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
+ } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
+ return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
+ }
+ } else {
+ if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
+ return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
+ } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
+ return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
+ }
+ }
+#endif
+ } else if (mDevSettingsFlag & QMIC_FLAG){
+ return strdup(SND_USE_CASE_DEV_QUAD_MIC);
+ }
+#ifdef QCOM_SSR_ENABLED
+ else if (mDevSettingsFlag & SSRQMIC_FLAG){
+ ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
+ // Mapping for quad mic input device.
+ return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
+ }
+#endif
+#ifdef SEPERATED_AUDIO_INPUT
+ if(input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
+ return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */
+ }
+#endif
+ else {
+#ifdef QCOM_BACK_MIC_ENABLED
+ return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
+#else
+ return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
+#endif
+ }
+ }
+ } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
+ return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
+#ifdef QCOM_ANC_HEADSET_ENABLED
+ } else if (devices & AudioSystem::DEVICE_IN_ANC_HEADSET) {
+ return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
+#endif
+ } else if (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
+ if (callMode == AudioSystem::MODE_IN_CALL) {
+ return strdup(SND_USE_CASE_DEV_VOC_HEADSET); /* Voice HEADSET TX */
+ } else
+ return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
+ } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
+ if (btsco_samplerate == BTSCO_RATE_16KHZ)
+ return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
+ else
+ return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
+#ifdef QCOM_USBAUDIO_ENABLED
+ } else if ((devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
+ (devices & AudioSystem::DEVICE_IN_PROXY)) {
+ return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
+#endif
+ } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
+ (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
+ /* Nothing to be done, use current active device */
+ if (strncmp(curTxUCMDevice, "None", 4)) {
+ return strdup(curTxUCMDevice);
+ }
+#ifdef QCOM_FM_ENABLED
+ } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
+ (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
+ /* Nothing to be done, use current tx device or set dummy device */
+ if (strncmp(curTxUCMDevice, "None", 4)) {
+ return strdup(curTxUCMDevice);
+ } else {
+ return strdup(SND_USE_CASE_DEV_DUMMY_TX);
+ }
+#endif
+ } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
+ (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
+ ALOGI("No proper mapping found with UCM device list, setting default");
+ if (!strncmp(mic_type, "analog", 6)) {
+ return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
+ } else {
+ if (callMode == AudioSystem::MODE_IN_CALL) {
+ return strdup(SND_USE_CASE_DEV_VOC_LINE); /* Voice BUILTIN-MIC TX */
+#ifdef SEPERATED_AUDIO_INPUT
+ } else if(input_source == AUDIO_SOURCE_CAMCORDER) {
+ return strdup(SND_USE_CASE_DEV_CAMCORDER_TX ); /* CAMCORDER TX */
+#endif
+ } else
+ return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
+ }
+ } else {
+ ALOGD("No valid input device: %u", devices);
+ }
+ }
+ return NULL;
+}
+
+void s_set_voice_volume(int vol)
+{
+ int err = 0;
+ ALOGV("s_set_voice_volume: volume %d", vol);
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("Voice Rx Volume", vol, 0);
+
+ if (platform_is_Fusion3()) {
+#ifdef QCOM_CSDCLIENT_ENABLED
+ if (csd_volume == NULL) {
+ ALOGE("dlsym:Error:%s Loading csd_client_volume", dlerror());
+ } else {
+ err = csd_volume(vol);
+ if (err < 0) {
+ ALOGE("s_set_voice_volume: csd_client error %d", err);
+ }
+ }
+#endif
+ }
+}
+
+void s_set_volte_volume(int vol)
+{
+ ALOGV("s_set_volte_volume: volume %d", vol);
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("VoLTE Rx Volume", vol, 0);
+}
+
+
+void s_set_voip_volume(int vol)
+{
+ ALOGV("s_set_voip_volume: volume %d", vol);
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("Voip Rx Volume", vol, 0);
+}
+void s_set_mic_mute(int state)
+{
+ int err = 0;
+ ALOGV("s_set_mic_mute: state %d", state);
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("Voice Tx Mute", state, 0);
+
+ if (platform_is_Fusion3()) {
+#ifdef QCOM_CSDCLIENT_ENABLED
+ if (csd_mic_mute == NULL) {
+ ALOGE("dlsym:Error:%s Loading csd_mic_mute", dlerror());
+ } else {
+ err=csd_mic_mute(state);
+ if (err < 0) {
+ ALOGE("s_set_mic_mute: csd_client error %d", err);
+ }
+ }
+#endif
+ }
+}
+void s_set_volte_mic_mute(int state)
+{
+ ALOGV("s_set_volte_mic_mute: state %d", state);
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("VoLTE Tx Mute", state, 0);
+}
+
+void s_set_voip_mic_mute(int state)
+{
+ ALOGV("s_set_voip_mic_mute: state %d", state);
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("Voip Tx Mute", state, 0);
+}
+
+void s_set_voip_config(int mode, int rate)
+{
+ ALOGV("s_set_voip_config: mode %d,rate %d", mode, rate);
+ ALSAControl control("/dev/snd/controlC0");
+ char** setValues;
+ setValues = (char**)malloc(2*sizeof(char*));
+ if (setValues == NULL) {
+ return;
+ }
+ setValues[0] = (char*)malloc(4*sizeof(char));
+ if (setValues[0] == NULL) {
+ free(setValues);
+ return;
+ }
+
+ setValues[1] = (char*)malloc(8*sizeof(char));
+ if (setValues[1] == NULL) {
+ free(setValues);
+ free(setValues[0]);
+ return;
+ }
+
+ sprintf(setValues[0], "%d",mode);
+ sprintf(setValues[1], "%d",rate);
+
+ control.setext("Voip Mode Rate Config", 2, setValues);
+ free(setValues[1]);
+ free(setValues[0]);
+ free(setValues);
+ return;
+}
+
+void s_set_btsco_rate(int rate)
+{
+ btsco_samplerate = rate;
+}
+
+void s_enable_wide_voice(bool flag)
+{
+ int err = 0;
+
+ ALOGV("s_enable_wide_voice: flag %d", flag);
+ ALSAControl control("/dev/snd/controlC0");
+ if(flag == true) {
+ control.set("Widevoice Enable", 1, 0);
+ } else {
+ control.set("Widevoice Enable", 0, 0);
+ }
+
+ if (platform_is_Fusion3()) {
+#ifdef QCOM_CSDCLIENT_ENABLED
+ if (csd_wide_voice == NULL) {
+ ALOGE("dlsym:Error:%s Loading csd_wide_voice", dlerror());
+ } else {
+ err = csd_wide_voice(flag);
+ if (err < 0) {
+ ALOGE("enableWideVoice: csd_client_wide_voice error %d", err);
+ }
+ }
+#endif
+ }
+}
+
+void s_set_voc_rec_mode(uint8_t mode)
+{
+ ALOGV("s_set_voc_rec_mode: mode %d", mode);
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("Incall Rec Mode", mode, 0);
+}
+
+void s_enable_fens(bool flag)
+{
+ int err = 0;
+
+ ALOGV("s_enable_fens: flag %d", flag);
+ ALSAControl control("/dev/snd/controlC0");
+ if(flag == true) {
+ control.set("FENS Enable", 1, 0);
+ } else {
+ control.set("FENS Enable", 0, 0);
+ }
+
+ if (platform_is_Fusion3()) {
+#ifdef QCOM_CSDCLIENT_ENABLED
+ if (csd_fens == NULL) {
+ ALOGE("dlsym:Error:%s Loading csd_fens", dlerror());
+ } else {
+ err = csd_fens(flag);
+ if (err < 0) {
+ ALOGE("s_enable_fens: csd_client error %d", err);
+ }
+ }
+#endif
+ }
+}
+
+void s_enable_slow_talk(bool flag)
+{
+ int err = 0;
+
+ ALOGV("s_enable_slow_talk: flag %d", flag);
+ ALSAControl control("/dev/snd/controlC0");
+ if(flag == true) {
+ control.set("Slowtalk Enable", 1, 0);
+ } else {
+ control.set("Slowtalk Enable", 0, 0);
+ }
+
+ if (platform_is_Fusion3()) {
+#ifdef QCOM_CSDCLIENT_ENABLED
+ if (csd_slow_talk == NULL) {
+ ALOGE("dlsym:Error:%s Loading csd_slow_talk", dlerror());
+ } else {
+ err = csd_slow_talk(flag);
+ if (err < 0) {
+ ALOGE("s_enable_slow_talk: csd_client error %d", err);
+ }
+ }
+#endif
+ }
+}
+
+void s_set_flags(uint32_t flags)
+{
+ ALOGV("s_set_flags: flags %d", flags);
+ mDevSettingsFlag = flags;
+}
+
+static status_t s_set_compressed_vol(int value)
+{
+ status_t err = NO_ERROR;
+
+ ALSAControl control("/dev/snd/controlC0");
+ control.set("COMPRESSED RX Volume",value,0);
+
+ return err;
+}
+
+#ifdef SEPERATED_AUDIO_INPUT
+void s_setInput(int input)
+{
+ input_source = input;
+ ALOGD("s_setInput() : input_source = %d",input_source);
+}
+#endif
+
+#ifdef QCOM_CSDCLIENT_ENABLED
+static void s_set_csd_handle(void* handle)
+{
+ csd_handle = static_cast<void*>(handle);
+ ALOGI("%s csd_handle: %p", __func__, csd_handle);
+
+ csd_disable_device = (int (*)())::dlsym(csd_handle,"csd_client_disable_device");
+ csd_enable_device = (int (*)(int,int,uint32_t))::dlsym(csd_handle,"csd_client_enable_device");
+ csd_start_voice = (int (*)())::dlsym(csd_handle,"csd_client_start_voice");
+ csd_stop_voice = (int (*)())::dlsym(csd_handle,"csd_client_stop_voice");
+ csd_volume = (int (*)(int))::dlsym(csd_handle,"csd_client_volume");
+ csd_mic_mute = (int (*)(int))::dlsym(csd_handle,"csd_client_mic_mute");
+ csd_wide_voice = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_wide_voice");
+ csd_fens = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_fens");
+ csd_slow_talk = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_slow_talk");
+}
+#endif
+
+}
diff --git a/alsa_sound/audio_hw_hal.cpp b/alsa_sound/audio_hw_hal.cpp
index 8e7f208..ab15e27 100644
--- a/alsa_sound/audio_hw_hal.cpp
+++ b/alsa_sound/audio_hw_hal.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 The Android Open Source Project
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -76,14 +76,23 @@
{ 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 },
#ifdef QCOM_ANC_HEADSET_ENABLED
{ AudioSystem::DEVICE_OUT_ANC_HEADSET, AUDIO_DEVICE_OUT_ANC_HEADSET },
{ AudioSystem::DEVICE_OUT_ANC_HEADPHONE, AUDIO_DEVICE_OUT_ANC_HEADPHONE },
#endif
+#ifdef QCOM_FM_ENABLED
+ { AudioSystem::DEVICE_OUT_FM, AUDIO_DEVICE_OUT_FM },
+#endif
+#ifdef QCOM_FM_TX_ENABLED
+ { AudioSystem::DEVICE_OUT_FM_TX, AUDIO_DEVICE_OUT_FM_TX },
+#endif
+#ifdef QCOM_VOIP_ENABLED
+ { AudioSystem::DEVICE_OUT_DIRECTOUTPUT, AUDIO_DEVICE_OUT_DIRECTOUTPUT },
+#endif
#ifdef QCOM_PROXY_DEVICE_ENABLED
{ AudioSystem::DEVICE_OUT_PROXY, AUDIO_DEVICE_OUT_PROXY },
#endif
- { 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 },
@@ -93,20 +102,16 @@
{ 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 },
#ifdef QCOM_ANC_HEADSET_ENABLED
{ AudioSystem::DEVICE_IN_ANC_HEADSET, AUDIO_DEVICE_IN_ANC_HEADSET },
#endif
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- { AudioSystem::DEVICE_IN_PROXY, AUDIO_DEVICE_IN_PROXY },
+#ifdef QCOM_FM_ENABLED
+ { AudioSystem::DEVICE_IN_FM_RX, AUDIO_DEVICE_IN_FM_RX },
+ { AudioSystem::DEVICE_IN_FM_RX_A2DP, AUDIO_DEVICE_IN_FM_RX_A2DP },
#endif
- { AudioSystem::DEVICE_IN_DEFAULT, AUDIO_DEVICE_IN_DEFAULT },
};
-// the "audio_devices" enumeration defined in hardware/libhardware_legacy is obsolete,
-// use type "audio_devices_t" and audio device enumeration from system/audio.h instead.
-// Do not use convert_audio_device if audio hal uses device definition from system/core
-// There's no need to conver audio device if HAL uses AUDIO_DEVICE_XXX defintions instead
-// of AudioSystem::Device_XXX.
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;
@@ -146,7 +151,7 @@
struct qcom_stream_out *out =
reinterpret_cast<struct qcom_stream_out *>(stream);
- ALOGV("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
+ ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
/* TODO: implement this */
return 0;
}
@@ -176,7 +181,7 @@
{
struct qcom_stream_out *out =
reinterpret_cast<struct qcom_stream_out *>(stream);
- ALOGV("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
+ ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
/* TODO: implement me */
return 0;
}
@@ -296,7 +301,7 @@
struct qcom_stream_in *in =
reinterpret_cast<struct qcom_stream_in *>(stream);
- ALOGV("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
+ ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
/* TODO: implement this */
return 0;
}
@@ -326,7 +331,7 @@
{
struct qcom_stream_in *in =
reinterpret_cast<struct qcom_stream_in *>(stream);
- ALOGV("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
+ ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
/* TODO: implement me */
return 0;
}
@@ -431,69 +436,6 @@
return reinterpret_cast<const struct qcom_audio_device *>(dev);
}
-static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev)
-{
- /* XXX: The old AudioHardwareInterface interface is not smart enough to
- * tell us this, so we'll lie and basically tell AF that we support the
- * below input/output devices and cross our fingers. To do things properly,
- * audio hardware interfaces that need advanced features (like this) should
- * convert to the new HAL interface and not use this wrapper. */
- return (/* OUT */
- AUDIO_DEVICE_OUT_EARPIECE |
- AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
- AUDIO_DEVICE_OUT_AUX_DIGITAL |
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_USB_ACCESSORY |
- AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX |
-#ifdef QCOM_ANC_HEADSET_ENABLED
- AUDIO_DEVICE_OUT_ANC_HEADSET |
- AUDIO_DEVICE_OUT_ANC_HEADPHONE |
-#endif
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- AUDIO_DEVICE_OUT_PROXY |
-#endif
-#ifdef QCOM_FM_ENABLED
- AUDIO_DEVICE_OUT_FM |
- AUDIO_DEVICE_OUT_FM_TX |
-#endif
- AUDIO_DEVICE_OUT_DEFAULT |
- /* IN */
- AUDIO_DEVICE_IN_COMMUNICATION |
- AUDIO_DEVICE_IN_AMBIENT |
- AUDIO_DEVICE_IN_BUILTIN_MIC |
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_IN_WIRED_HEADSET |
- AUDIO_DEVICE_IN_AUX_DIGITAL |
- AUDIO_DEVICE_IN_VOICE_CALL |
- AUDIO_DEVICE_IN_BACK_MIC |
- AUDIO_DEVICE_IN_REMOTE_SUBMIX |
- AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET |
- AUDIO_DEVICE_IN_USB_ACCESSORY |
- AUDIO_DEVICE_IN_USB_DEVICE |
-#ifdef QCOM_ANC_HEADSET_ENABLED
- AUDIO_DEVICE_IN_ANC_HEADSET |
-#endif
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- AUDIO_DEVICE_IN_PROXY |
-#endif
-#ifdef QCOM_FM_ENABLED
- AUDIO_DEVICE_IN_FM_RX |
- AUDIO_DEVICE_IN_FM_RX_A2DP |
-#endif
- AUDIO_DEVICE_IN_DEFAULT);
-}
-
static int adev_init_check(const struct audio_hw_device *dev)
{
const struct qcom_audio_device *qadev = to_cladev(dev);
@@ -569,6 +511,43 @@
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;
+
+ 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
static int adev_open_output_stream(struct audio_hw_device *dev,
audio_io_handle_t handle,
@@ -590,9 +569,6 @@
status = static_cast<audio_output_flags_t> (flags);
out->qcom_out = qadev->hwif->openOutputStream(devices,
-#ifdef QCOM_OUTPUT_FLAGS_ENABLED
- flags,
-#endif
(int *)&config->format,
&config->channel_mask,
&config->sample_rate,
@@ -745,7 +721,6 @@
qadev->device.common.module = const_cast<hw_module_t*>(module);
qadev->device.common.close = qcom_adev_close;
- qadev->device.get_supported_devices = adev_get_supported_devices;
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;
@@ -760,6 +735,9 @@
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
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;
diff --git a/alsa_sound/audio_policy_hal.cpp b/alsa_sound/audio_policy_hal.cpp
index 4657295..1057a0f 100644
--- a/alsa_sound/audio_policy_hal.cpp
+++ b/alsa_sound/audio_policy_hal.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -125,6 +125,45 @@
return qap->apm->initCheck();
}
+#ifdef QCOM_TUNNEL_LPA_ENABLED
+static audio_io_handle_t ap_get_session(struct audio_policy *pol,
+ audio_stream_type_t stream,
+ audio_format_t format,
+ audio_policy_output_flags_t flags,
+ int sessionId,
+ uint32_t samplingRate,
+ uint32_t channels)
+{
+ struct qcom_audio_policy *qap = to_qap(pol);
+
+ ALOGV("%s: tid %d", __func__, gettid());
+ return qap->apm->getSession((AudioSystem::stream_type)stream,
+ format, (AudioSystem::output_flags)flags,
+ sessionId,
+ samplingRate,
+ channels);
+}
+
+static void ap_pause_session(struct audio_policy *pol, audio_io_handle_t output,
+ audio_stream_type_t stream)
+{
+ struct qcom_audio_policy *qap = to_qap(pol);
+ qap->apm->pauseSession(output, (AudioSystem::stream_type)stream);
+}
+
+static void ap_resume_session(struct audio_policy *pol, audio_io_handle_t output,
+ audio_stream_type_t stream)
+{
+ struct qcom_audio_policy *qap = to_qap(pol);
+ qap->apm->resumeSession(output, (AudioSystem::stream_type)stream);
+}
+
+static void ap_release_session(struct audio_policy *pol, audio_io_handle_t output)
+{
+ struct qcom_audio_policy *qap = to_qap(pol);
+ qap->apm->releaseSession(output);
+}
+#endif
static audio_io_handle_t ap_get_output(struct audio_policy *pol,
audio_stream_type_t stream,
@@ -209,7 +248,7 @@
struct qcom_audio_policy *qap = to_qap(pol);
return qap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream,
index,
- AUDIO_DEVICE_OUT_DEFAULT);
+ AUDIO_DEVICE_OUT_DEFAULT);
}
static int ap_get_stream_volume_index(const struct audio_policy *pol,
@@ -259,14 +298,14 @@
}
static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol,
- const struct effect_descriptor_s *desc)
+ 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,
+ struct effect_descriptor_s *desc,
audio_io_handle_t io,
uint32_t strategy,
int session,
@@ -288,7 +327,7 @@
return qap->apm->setEffectEnabled(id, enabled);
}
-static bool ap_is_stream_active(const struct audio_policy *pol,
+static bool ap_is_stream_active(const struct audio_policy *pol,
audio_stream_type_t stream,
uint32_t in_past_ms)
{
@@ -326,6 +365,12 @@
ap_set_can_mute_enforced_audible;
qap->policy.init_check = ap_init_check;
qap->policy.get_output = ap_get_output;
+#ifdef QCOM_TUNNEL_LPA_ENABLED
+ qap->policy.get_session = ap_get_session;
+ qap->policy.pause_session = ap_pause_session;
+ qap->policy.resume_session = ap_resume_session;
+ qap->policy.release_session = ap_release_session;
+#endif
qap->policy.start_output = ap_start_output;
qap->policy.stop_output = ap_stop_output;
qap->policy.release_output = ap_release_output;
diff --git a/libalsa-intf/Android.mk b/libalsa-intf/Android.mk
index cadfa32..5d509b3 100644
--- a/libalsa-intf/Android.mk
+++ b/libalsa-intf/Android.mk
@@ -2,25 +2,20 @@
ifeq ($(strip $(BOARD_USES_ALSA_AUDIO)),true)
# Any prebuilt files with default TAGS can use the below:
+
include $(CLEAR_VARS)
#LOCAL_SRC_FILES:= aplay.c alsa_pcm.c alsa_mixer.c
LOCAL_SRC_FILES:= aplay.c
LOCAL_MODULE:= aplay
LOCAL_SHARED_LIBRARIES:= libc libcutils libalsa-intf
-LOCAL_C_INCLUDES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_MODULE_TAGS:= debug
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
#LOCAL_SRC_FILES:= arec.c alsa_pcm.c
LOCAL_SRC_FILES:= arec.c
-LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_MODULE:= arec
LOCAL_SHARED_LIBRARIES:= libc libcutils libalsa-intf
-LOCAL_C_INCLUDES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_MODULE_TAGS:= debug
include $(BUILD_EXECUTABLE)
@@ -28,8 +23,6 @@
LOCAL_SRC_FILES:= amix.c
LOCAL_MODULE:= amix
LOCAL_SHARED_LIBRARIES := libc libcutils libalsa-intf
-LOCAL_C_INCLUDES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_MODULE_TAGS:= debug
include $(BUILD_EXECUTABLE)
@@ -37,8 +30,6 @@
LOCAL_SRC_FILES:= alsaucm_test.c
LOCAL_MODULE:= alsaucm_test
LOCAL_SHARED_LIBRARIES:= libc libcutils libalsa-intf
-LOCAL_C_INCLUDES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_MODULE_TAGS:= debug
include $(BUILD_EXECUTABLE)
@@ -51,14 +42,8 @@
LOCAL_MODULE:= libalsa-intf
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES:= libc libcutils #libutils #libmedia libhardware_legacy
-LOCAL_C_INCLUDES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-ifeq ($(strip $(TARGET_USES_QCOM_MM_AUDIO)),true)
LOCAL_CFLAGS := -DQC_PROP -DCONFIG_DIR=\"/system/etc/snd_soc_msm/\"
-LOCAL_CFLAGS += -DCONFIG_DIR=\"/system/etc/snd_soc_msm/\"
-LOCAL_SHARED_LIBRARIES += libacdbloader
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-acdb-util
-endif
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
ifeq ($(TARGET_SIMULATOR),true)
LOCAL_LDLIBS += -ldl
else
diff --git a/libalsa-intf/Makefile.am b/libalsa-intf/Makefile.am
index 58cb7ca..a05d073 100644
--- a/libalsa-intf/Makefile.am
+++ b/libalsa-intf/Makefile.am
@@ -27,25 +27,15 @@
libalsa_intfdir = $(prefix)/snd_soc_msm
dist_libalsa_intf_DATA = snd_soc_msm/snd_soc_msm \
snd_soc_msm/snd_soc_msm_2x \
- snd_soc_msm/snd_soc_msm_2x_mpq \
snd_soc_msm/snd_soc_msm_2x_Fusion3 \
- snd_soc_msm/snd_soc_msm_Sitar \
- snd_soc_msm/snd_soc_msm_I2S \
- snd_soc_msm/snd_soc_msm_auxpcm \
- snd_soc_msm/snd_soc_msm_2x_auxpcm \
- snd_soc_msm/snd_soc_msm_2x_mpq_auxpcm \
- snd_soc_msm/snd_soc_msm_2x_Fusion3_auxpcm \
- snd_soc_msm/snd_soc_msm_Sitar_auxpcm \
- snd_soc_msm/snd_soc_msm_I2SFusion \
- snd_soc_msm/snd_soc_msm_Taiko \
- snd_soc_msm/snd_soc_msm_Taiko_liquid
+ snd_soc_msm/snd_soc_msm_Sitar
libalsa_intf_la_CFLAGS = $(AM_CFLAGS) -DUSE_GLIB @GLIB_CFLAGS@ -DCONFIG_DIR=\"/etc/snd_soc_msm/\"
libalsa_intf_la_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_GLIB @GLIB_CFLAGS@
libalsa_intf_la_LDFLAGS = $(ACDBLOADER_LIBS) -lm -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
requiredlibs = libalsa_intf.la
-bin_PROGRAMS = aplay amix arec alsaucm_test
+bin_PROGRAMS = aplay amix arec
aplay_SOURCES = aplay.c
aplay_LDADD = -lpthread $(requiredlibs)
@@ -55,6 +45,3 @@
arec_SOURCES = arec.c
arec_LDADD = -lpthread $(requiredlibs)
-
-alsaucm_test_SOURCES = alsaucm_test.c
-alsaucm_test_LDADD = -lpthread $(requiredlibs)
diff --git a/libalsa-intf/alsa_audio.h b/libalsa-intf/alsa_audio.h
index bc6225a..7f2acf0 100644
--- a/libalsa-intf/alsa_audio.h
+++ b/libalsa-intf/alsa_audio.h
@@ -43,6 +43,12 @@
int device_no;
int start;
};
+
+enum decoder_alias {
+ FORMAT_MP3,
+ FORMAT_AC3_PASS_THROUGH = 2,
+};
+
#define FORMAT(v) SNDRV_PCM_FORMAT_##v
#define PCM_OUT 0x00000000
@@ -52,7 +58,6 @@
#define PCM_MONO 0x01000000
#define PCM_QUAD 0x02000000
#define PCM_5POINT1 0x04000000
-#define PCM_7POINT1 0x08000000
#define PCM_44100HZ 0x00000000
#define PCM_48000HZ 0x00100000
@@ -144,12 +149,9 @@
int param_set_hw_refine(struct pcm *pcm, struct snd_pcm_hw_params *params);
int param_set_hw_params(struct pcm *pcm, struct snd_pcm_hw_params *params);
int param_set_sw_params(struct pcm *pcm, struct snd_pcm_sw_params *sparams);
-int get_compressed_format(const char *format);
void param_dump(struct snd_pcm_hw_params *p);
int pcm_prepare(struct pcm *pcm);
long pcm_avail(struct pcm *pcm);
-int pcm_set_channel_map(struct pcm *pcm, struct mixer *mixer,
- int max_channels, char *chmap);
/* Returns a human readable reason for the last error. */
const char *pcm_error(struct pcm *pcm);
@@ -186,4 +188,104 @@
#define MAX_NUM_CODECS 32
+/* compressed audio support */
+#ifdef QCOM_COMPRESSED_AUDIO_ENABLED
+struct snd_compr_caps {
+ __u32 num_codecs;
+ __u32 min_fragment_size;
+ __u32 max_fragment_size;
+ __u32 min_fragments;
+ __u32 max_fragments;
+ __u32 codecs[MAX_NUM_CODECS];
+ __u32 reserved[11];
+};
+
+struct snd_enc_wma {
+ __u32 super_block_align; /* WMA Type-specific data */
+ __u32 bits_per_sample;
+ __u32 channelmask;
+ __u32 encodeopt;
+};
+
+struct snd_enc_vorbis {
+ int quality;
+ __u32 managed;
+ __u32 max_bit_rate;
+ __u32 min_bit_rate;
+ __u32 downmix;
+};
+
+struct snd_enc_real {
+ __u32 quant_bits;
+ __u32 start_region;
+ __u32 num_regions;
+};
+
+struct snd_enc_flac {
+ __u32 num;
+ __u32 gain;
+};
+
+struct snd_enc_generic {
+ __u32 bw; /* encoder bandwidth */
+ int reserved[15];
+};
+
+union snd_codec_options {
+ struct snd_enc_wma wma;
+ struct snd_enc_vorbis vorbis;
+ struct snd_enc_real real;
+ struct snd_enc_flac flac;
+ struct snd_enc_generic generic;
+};
+
+struct snd_codec {
+ __u32 id;
+ __u32 ch_in;
+ __u32 ch_out;
+ __u32 sample_rate;
+ __u32 bit_rate;
+ __u32 rate_control;
+ __u32 profile;
+ __u32 level;
+ __u32 ch_mode;
+ __u32 format;
+ __u32 align;
+ union snd_codec_options options;
+ __u32 reserved[3];
+};
+
+struct snd_compressed_buffer {
+ size_t fragment_size;
+ int fragments;
+};
+
+/* */
+struct snd_compr_params {
+ struct snd_compressed_buffer buffer;
+ struct snd_codec codec;
+};
+
+struct snd_compr_tstamp {
+ size_t copied_bytes;
+ size_t copied_total;
+ size_t decoded;
+ size_t rendered;
+ __u32 sampling_rate;
+ uint64_t timestamp;
+};
+
+#define SNDRV_COMPRESS_GET_CAPS _IOWR('C', 0x00, struct snd_compr_caps *)
+#define SNDRV_COMPRESS_GET_CODEC_CAPS _IOWR('C', 0x01, struct snd_compr_codec_caps *)
+#define SNDRV_COMPRESS_SET_PARAMS _IOW('C', 0x02, struct snd_compr_params *)
+#define SNDRV_COMPRESS_GET_PARAMS _IOR('C', 0x03, struct snd_compr_params *)
+#define SNDRV_COMPRESS_TSTAMP _IOR('C', 0x10, struct snd_compr_tstamp *)
+#define SNDRV_COMPRESS_AVAIL _IOR('C', 0x11, struct snd_compr_avail *)
+#define SNDRV_COMPRESS_PAUSE _IO('C', 0x20)
+#define SNDRV_COMPRESS_RESUME _IO('C', 0x21)
+#define SNDRV_COMPRESS_START _IO('C', 0x22)
+#define SNDRV_COMPRESS_STOP _IO('C', 0x23)
+#define SNDRV_COMPRESS_DRAIN _IO('C', 0x24)
+#endif
+
#endif
diff --git a/libalsa-intf/alsa_mixer.c b/libalsa-intf/alsa_mixer.c
index 81817d9..cdcdcea 100644
--- a/libalsa-intf/alsa_mixer.c
+++ b/libalsa-intf/alsa_mixer.c
@@ -488,6 +488,7 @@
if (count < ctl->info->count || count > ctl->info->count)
return -EINVAL;
+
memset(&ev, 0, sizeof(ev));
ev.id.numid = ctl->info->id.numid;
switch (ctl->info->type) {
@@ -510,13 +511,6 @@
}
break;
}
- case SNDRV_CTL_ELEM_TYPE_ENUMERATED: {
- for (n = 0; n < ctl->info->count; n++) {
- fprintf( stderr, "Value: %d idx:%d\n", atoi(argv[n]), n);
- ev.value.enumerated.item[n] = (unsigned int)atoi(argv[n]);
- }
- break;
- }
default:
errno = EINVAL;
return errno;
diff --git a/libalsa-intf/alsa_pcm.c b/libalsa-intf/alsa_pcm.c
index 175b5a7..a814ae8 100644
--- a/libalsa-intf/alsa_pcm.c
+++ b/libalsa-intf/alsa_pcm.c
@@ -43,7 +43,7 @@
#include <sys/poll.h>
#include <linux/ioctl.h>
#include <linux/types.h>
-#include <sound/compress_params.h>
+
#include "alsa_audio.h"
#define __force
@@ -78,7 +78,7 @@
IMA_ADPCM,
MPEG,
GSM,
- SPECIAL = 31,
+ SPECIAL = 31,
S24_3LE,
S24_3BE,
U24_3LE,
@@ -118,7 +118,7 @@
{"A_LAW", "A-Law"},
{"IMA_ADPCM", "Ima-ADPCM"},
{"MPEG", "MPEG"},
- {"GSM", "GSM"},
+ {"GSM", "GSM"},
[31] = {"SPECIAL", "Special"},
{"S24_3LE", "Signed 24 bit Little Endian in 3bytes"},
{"S24_3BE", "Signed 24 bit Big Endian in 3bytes"},
@@ -133,18 +133,6 @@
{"U18_3LE", "Unsigned 18 bit Little Endian in 3bytes"},
{"U18_3BE", "Unsigned 18 bit Big Endian in 3bytes"},
};
-enum decoder_alias {
- FORMAT_MP3 = SND_AUDIOCODEC_MP3,
- FORMAT_AAC = SND_AUDIOCODEC_AAC,
- FORMAT_AC3_PASS_THROUGH = SND_AUDIOCODEC_AC3_PASS_THROUGH,
- FORMAT_WMA = SND_AUDIOCODEC_WMA,
- FORMAT_WMA_PRO = SND_AUDIOCODEC_WMA_PRO,
- FORMAT_DTS = SND_AUDIOCODEC_DTS,
- FORMAT_DTS_LBR = SND_AUDIOCODEC_DTS_LBR,
- FORMAT_DTS_PASS_THROUGH = SND_AUDIOCODEC_DTS_PASS_THROUGH,
- FORMAT_AMRWB = SND_AUDIOCODEC_AMRWB,
- FORMAT_AMRWB_PLUS = SND_AUDIOCODEC_AMRWBPLUS
-};
int get_compressed_format(const char *format)
{
@@ -155,30 +143,6 @@
} else if (strcmp(ch, "AC3_PASS_THROUGH") == 0) {
printf("AC3 PASS THROUGH is selected\n");
return FORMAT_AC3_PASS_THROUGH;
- } else if (strcmp(ch, "AAC") == 0) {
- printf("AAC is selected\n");
- return FORMAT_AAC;
- } else if (strcmp(ch, "AC3_PASS_THROUGH") == 0) {
- printf("AC3_PASS_THROUGH is selected\n");
- return FORMAT_AC3_PASS_THROUGH;
- } else if (strcmp(ch, "WMA") == 0) {
- printf("WMA is selected\n");
- return FORMAT_WMA;
- }else if (strcmp(ch, "WMA_PRO") == 0) {
- printf("WMA_PRO is selected\n");
- return FORMAT_WMA_PRO;
- }else if (strcmp(ch, "DTS") == 0) {
- printf("DTS is selected\n");
- return FORMAT_DTS;
- } else if (strcmp(ch, "DTS_LBR") == 0) {
- printf("DTS_LBR is selected\n");
- return FORMAT_DTS_LBR;
- } else if (strcmp(ch, "AMR_WB") == 0) {
- printf("AMR_WB is selected\n");
- return FORMAT_AMRWB;
- }else if (strcmp(ch, "AMR_WB_PLUS") == 0) {
- printf("FORMAT_AMRWB_PLUS is selected\n");
- return FORMAT_AMRWB_PLUS;
} else {
printf("invalid format\n");
return -1;
@@ -445,20 +409,7 @@
avail += pcm->sw_p->boundary;
return avail;
} else {
- int buffer_size = 0;
- long avail;
- if(pcm->flags & PCM_MONO)
- buffer_size = pcm->buffer_size/2;
- else if(pcm->flags & PCM_QUAD)
- buffer_size = pcm->buffer_size/8;
- else if(pcm->flags & PCM_5POINT1)
- buffer_size = pcm->buffer_size/12;
- else if(pcm->flags & PCM_7POINT1)
- buffer_size = pcm->buffer_size/16;
- else
- buffer_size = pcm->buffer_size/4;
-
- avail = sync_ptr->s.status.hw_ptr - sync_ptr->c.control.appl_ptr + buffer_size;
+ long avail = sync_ptr->s.status.hw_ptr - sync_ptr->c.control.appl_ptr + ((pcm->flags & PCM_MONO) ? pcm->buffer_size/2 : pcm->buffer_size/4);
if (avail < 0)
avail += pcm->sw_p->boundary;
else if ((unsigned long) avail >= pcm->sw_p->boundary)
@@ -486,18 +437,7 @@
char *ptr;
unsigned size;
struct snd_pcm_channel_info ch;
- int channels;
-
- if(pcm->flags & PCM_MONO)
- channels = 1;
- else if(pcm->flags & PCM_QUAD)
- channels = 4;
- else if(pcm->flags & PCM_5POINT1)
- channels = 6;
- else if(pcm->flags & PCM_7POINT1)
- channels = 8;
- else
- channels = 2;
+ int channels = (pcm->flags & PCM_MONO) ? 1 : 2;
size = pcm->buffer_size;
if (pcm->flags & DEBUG_ON)
@@ -521,19 +461,8 @@
unsigned long pcm_offset = 0;
struct snd_pcm_sync_ptr *sync_ptr = pcm->sync_ptr;
unsigned int appl_ptr = 0;
- int channels;
- if(pcm->flags & PCM_MONO)
- channels = 1;
- else if(pcm->flags & PCM_QUAD)
- channels = 4;
- else if(pcm->flags & PCM_5POINT1)
- channels = 6;
- else if(pcm->flags & PCM_7POINT1)
- channels = 8;
- else
- channels = 2;
- appl_ptr = sync_ptr->c.control.appl_ptr*2*channels;
+ appl_ptr = (pcm->flags & PCM_MONO) ? sync_ptr->c.control.appl_ptr*2 : sync_ptr->c.control.appl_ptr*4;
pcm_offset = (appl_ptr % (unsigned long)pcm->buffer_size);
return pcm->addr + pcm_offset;
@@ -546,17 +475,7 @@
unsigned size;
u_int8_t *dst_addr, *mmaped_addr;
u_int8_t *src_addr = data;
- int channels;
- if(pcm->flags & PCM_MONO)
- channels = 1;
- else if(pcm->flags & PCM_QUAD)
- channels = 4;
- else if(pcm->flags & PCM_5POINT1)
- channels = 6;
- else if(pcm->flags & PCM_7POINT1)
- channels = 8;
- else
- channels = 2;
+ int channels = (pcm->flags & PCM_MONO) ? 1 : 2;
dst_addr = dst_address(pcm);
@@ -578,20 +497,9 @@
unsigned size;
u_int8_t *dst_addr, *mmaped_addr;
u_int8_t *src_addr;
- int channels;
- unsigned int tmp;
+ int channels = (pcm->flags & PCM_MONO) ? 1 : 2;
+ unsigned int tmp = (pcm->flags & PCM_MONO) ? sync_ptr->c.control.appl_ptr*2 : sync_ptr->c.control.appl_ptr*4;
- if(pcm->flags & PCM_MONO)
- channels = 1;
- else if(pcm->flags & PCM_QUAD)
- channels = 4;
- else if(pcm->flags & PCM_5POINT1)
- channels = 6;
- else if(pcm->flags & PCM_7POINT1)
- channels = 8;
- else
- channels = 2;
- tmp = sync_ptr->c.control.appl_ptr*2*channels;
pcm_offset = (tmp % (unsigned long)pcm->buffer_size);
dst_addr = data;
src_addr = pcm->addr + pcm_offset;
@@ -620,18 +528,8 @@
long frames;
int err;
int bytes_written;
- int channels;
- if(pcm->flags & PCM_MONO)
- channels = 1;
- else if(pcm->flags & PCM_QUAD)
- channels = 4;
- else if(pcm->flags & PCM_5POINT1)
- channels = 6;
- else if(pcm->flags & PCM_7POINT1)
- channels = 8;
- else
- channels = 2;
- frames = count / (2*channels);
+
+ frames = (pcm->flags & PCM_MONO) ? (count / 2) : (count / 4);
pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
err = sync_ptr(pcm);
@@ -678,17 +576,7 @@
static int pcm_write_nmmap(struct pcm *pcm, void *data, unsigned count)
{
struct snd_xferi x;
- int channels;
- if(pcm->flags & PCM_MONO)
- channels = 1;
- else if(pcm->flags & PCM_QUAD)
- channels = 4;
- else if(pcm->flags & PCM_5POINT1)
- channels = 6;
- else if(pcm->flags & PCM_7POINT1)
- channels = 8;
- else
- channels = 2;
+ int channels = (pcm->flags & PCM_MONO) ? 1 : ((pcm->flags & PCM_5POINT1)? 6 : 2 );
if (pcm->flags & PCM_IN)
return -EINVAL;
@@ -738,8 +626,6 @@
x.frames = (count / 8);
} else if (pcm->flags & PCM_5POINT1) {
x.frames = (count / 12);
- } else if (pcm->flags & PCM_7POINT1) {
- x.frames = (count / 16);
} else {
x.frames = (count / 4);
}
@@ -761,20 +647,6 @@
pcm->underruns++;
pcm->running = 0;
continue;
- } else if (errno == ESTRPIPE) {
- ALOGV("Resume from suspended\n");
- for (;;) {
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_RESUME)) {
- if (errno == EAGAIN ) {
- if (pcm_prepare(pcm))
- return -errno;
- }
- /* send resume command again */
- continue;
- } else
- break;
- }
- continue;
}
ALOGE("Arec: error%d\n", errno);
return -errno;
@@ -982,46 +854,3 @@
{
return pcm->fd >= 0;
}
-
-int pcm_set_channel_map(struct pcm *pcm, struct mixer *mixer,
- int max_channels, char *chmap)
-{
- struct mixer_ctl *ctl;
- char control_name[44]; // max length of name is 44 as defined
- char device_num[3]; // device number upto 2 digit
- char **set_values;
- int i;
-
- ALOGV("pcm_set_channel_map");
- set_values = (char**)malloc(max_channels*sizeof(char*));
- if(set_values) {
- for(i=0; i< max_channels; i++) {
- set_values[i] = (char*)malloc(4*sizeof(char));
- if(set_values[i]) {
- sprintf(set_values[i],"%d",chmap[i]);
- } else {
- ALOGE("memory allocation for set channel map failed");
- return -1;
- }
- }
- } else {
- ALOGE("memory allocation for set channel map failed");
- return -1;
- }
- strlcpy(control_name, "Playback Channel Map", sizeof(control_name));
- sprintf(device_num, "%d", pcm->device_no);
- strcat(control_name, device_num);
- ALOGV("pcm_set_channel_map: control name:%s", control_name);
- ctl = mixer_get_control(mixer, control_name, 0);
- if(ctl == NULL) {
- ALOGE(stderr, "Could not get the mixer control\n");
- return -1;
- }
- mixer_ctl_set_value(ctl, max_channels, set_values);
- for(i=0; i< max_channels; i++)
- if(set_values[i])
- free(set_values[i]);
- if(set_values)
- free(set_values);
- return 0;
-}
diff --git a/libalsa-intf/alsa_ucm.c b/libalsa-intf/alsa_ucm.c
index 0886d54..3548f67 100644
--- a/libalsa-intf/alsa_ucm.c
+++ b/libalsa-intf/alsa_ucm.c
@@ -58,15 +58,13 @@
#include <sys/time.h>
#include <sys/poll.h>
#include <stdint.h>
+#include <dlfcn.h>
#include <linux/ioctl.h>
#include "msm8960_use_cases.h"
#if defined(QC_PROP)
- #include "acdb-loader.h"
-#else
- #define acdb_loader_send_voice_cal(rxacdb_id, txacdb_id) (-EPERM)
- #define acdb_loader_send_audio_cal(acdb_id, capability) (-EPERM)
- #define acdb_loader_send_anc_cal(acdb_id) (-EPERM)
+ static void (*acdb_send_audio_cal)(int,int);
+ static void (*acdb_send_voice_cal)(int,int);
#endif
#define PARSE_DEBUG 0
@@ -444,42 +442,6 @@
ret = -ENODEV;
}
}
- } else if (!strncmp(ident1, "EC_REF_RXMixerCTL", 17)) {
- ident2 = strtok_r(NULL, "/", &temp_ptr);
- index = 0; verb_index = 0;
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- if((verb_index < 0) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_UCM_END_OF_LIST, 3)) ||
- (verb_list[verb_index].verb_ctrls == NULL)) {
- ALOGE("Invalid current verb value: %s - %d",
- uc_mgr->card_ctxt_ptr->current_verb, verb_index);
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
- ctrl_list = verb_list[verb_index].device_ctrls;
- if (ident2 != NULL) {
- while(strncmp(ctrl_list[index].case_name, ident2, strlen(ident2)+1)) {
- if (!strncmp(ctrl_list[index].case_name, SND_UCM_END_OF_LIST,
- strlen(SND_UCM_END_OF_LIST))){
- ret = -EINVAL;
- break;
- } else {
- index++;
- }
- }
- }
- if (ret < 0) {
- ALOGE("No valid device/modifier found with given identifier: %s",
- ident2);
- } else {
- if (verb_list[verb_index].device_ctrls[index].ec_ref_rx_mixer_ctl) {
- *value = strdup(verb_list[verb_index].device_ctrls[index].ec_ref_rx_mixer_ctl);
- } else {
- *value = NULL;
- ret = -ENODEV;
- }
- }
} else {
ALOGE("Unsupported identifier value: %s", ident1);
*value = NULL;
@@ -581,18 +543,10 @@
if ((!strncmp(use_case, SND_USE_CASE_VERB_VOICECALL,
strlen(SND_USE_CASE_VERB_VOICECALL))) ||
- (!strncmp(use_case, SND_USE_CASE_VERB_SGLTECALL,
- strlen(SND_USE_CASE_VERB_SGLTECALL))) ||
- (!strncmp(use_case, SND_USE_CASE_VERB_VOLTE,
- strlen(SND_USE_CASE_VERB_VOLTE))) ||
(!strncmp(use_case, SND_USE_CASE_VERB_IP_VOICECALL,
strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
(!strncmp(use_case, SND_USE_CASE_MOD_PLAY_VOICE,
strlen(SND_USE_CASE_MOD_PLAY_VOICE))) ||
- (!strncmp(use_case, SND_USE_CASE_MOD_PLAY_SGLTE,
- strlen(SND_USE_CASE_MOD_PLAY_SGLTE))) ||
- (!strncmp(use_case, SND_USE_CASE_MOD_PLAY_VOLTE,
- strlen(SND_USE_CASE_MOD_PLAY_VOLTE))) ||
(!strncmp(use_case, SND_USE_CASE_MOD_PLAY_VOIP,
strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
ALOGV("check_devices_for_voice_call(): voice cap detected\n");
@@ -630,12 +584,8 @@
/* Check if voice call use case/modifier exists */
if ((!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_VOLTE, strlen(SND_USE_CASE_VERB_VOLTE))) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
SND_USE_CASE_VERB_VOICECALL, strlen(SND_USE_CASE_VERB_VOICECALL))) ||
(!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_SGLTECALL, strlen(SND_USE_CASE_VERB_SGLTECALL))) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
SND_USE_CASE_VERB_IP_VOICECALL,
strlen(SND_USE_CASE_VERB_IP_VOICECALL)))) {
voice_acdb = 1;
@@ -647,12 +597,8 @@
if ((ident_value =
snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
index))) {
- if ((!strncmp(ident_value, SND_USE_CASE_MOD_PLAY_VOLTE,
- strlen(SND_USE_CASE_MOD_PLAY_VOLTE))) ||
- (!strncmp(ident_value, SND_USE_CASE_MOD_PLAY_VOICE,
+ if ((!strncmp(ident_value, SND_USE_CASE_MOD_PLAY_VOICE,
strlen(SND_USE_CASE_MOD_PLAY_VOICE))) ||
- (!strncmp(ident_value, SND_USE_CASE_MOD_PLAY_SGLTE,
- strlen(SND_USE_CASE_MOD_PLAY_SGLTE))) ||
(!strncmp(ident_value, SND_USE_CASE_MOD_PLAY_VOIP,
strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
voice_acdb = 1;
@@ -727,8 +673,15 @@
ALOGD("Voice acdb: rx id %d tx id %d",
uc_mgr->current_rx_device,
uc_mgr->current_tx_device);
- acdb_loader_send_voice_cal(uc_mgr->current_rx_device,
- uc_mgr->current_tx_device);
+ if (uc_mgr->acdb_handle) {
+ acdb_send_voice_cal = dlsym(uc_mgr->acdb_handle,"acdb_loader_send_voice_cal");
+ if (acdb_send_voice_cal == NULL) {
+ ALOGE("ucm: dlsym: Error:%s Loading acdb_loader_send_voice_cal", dlerror());
+ }else {
+ acdb_send_voice_cal(uc_mgr->current_rx_device,
+ uc_mgr->current_tx_device);
+ }
+ }
} else {
ALOGV("Voice acdb: Required acdb already pushed \
rx id %d tx id %d", uc_mgr->current_rx_device,
@@ -839,15 +792,22 @@
(check_devices_for_voice_call(uc_mgr, use_case) != NULL))
return ret;
ALOGD("Set mixer controls for %s enable %d", use_case, enable);
- if ((ctrl_list[uc_index].acdb_id >= 0) && ctrl_list[uc_index].capability) {
+ if (ctrl_list[uc_index].acdb_id && ctrl_list[uc_index].capability) {
if (enable) {
- snd_use_case_apply_voice_acdb(uc_mgr, uc_index);
- ALOGD("acdb_id %d cap %d enable %d",
- ctrl_list[uc_index].acdb_id,
- ctrl_list[uc_index].capability, enable);
- acdb_loader_send_audio_cal(
+ if (snd_use_case_apply_voice_acdb(uc_mgr, uc_index)) {
+ ALOGV("acdb_id %d cap %d enable %d",
ctrl_list[uc_index].acdb_id,
- ctrl_list[uc_index].capability);
+ ctrl_list[uc_index].capability, enable);
+ if (uc_mgr->acdb_handle) {
+ acdb_send_audio_cal = dlsym(uc_mgr->acdb_handle,"acdb_loader_send_audio_cal");
+ if (acdb_send_audio_cal == NULL) {
+ ALOGE("ucm:dlsym:Error:%s Loading acdb_loader_send_audio_cal", dlerror());
+ } else {
+ acdb_send_audio_cal(ctrl_list[uc_index].acdb_id,
+ ctrl_list[uc_index].capability);
+ }
+ }
+ }
}
}
if (enable) {
@@ -866,7 +826,7 @@
mixer_list[index].control_name, 0);
if (ctl) {
if (mixer_list[index].type == TYPE_INT) {
- ALOGD("Setting mixer control: %s, value: %d",
+ ALOGV("Setting mixer control: %s, value: %d",
mixer_list[index].control_name,
mixer_list[index].value);
ret = mixer_ctl_set(ctl, mixer_list[index].value);
@@ -879,7 +839,7 @@
ALOGE("Failed to set multi value control %s\n",
mixer_list[index].control_name);
} else {
- ALOGD("Setting mixer control: %s, value: %s",
+ ALOGV("Setting mixer control: %s, value: %s",
mixer_list[index].control_name,
mixer_list[index].string);
ret = mixer_ctl_select(ctl, mixer_list[index].string);
@@ -925,12 +885,8 @@
MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
!strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL2,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_TUNNEL2)) ||
!strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI2)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI3,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI3)) ||
!strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
MAX_LEN(useCase,SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
!strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
@@ -939,41 +895,25 @@
MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
!strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC3,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC3)) ||
!strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LPA)) ||
!strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL2,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_TUNNEL2)) ||
!strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_FM))||
- !strncmp(useCase, SND_USE_CASE_MOD_PSEUDO_TUNNEL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PSEUDO_TUNNEL))||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_PSEUDO_TUNNEL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_PSEUDO_TUNNEL))) {
+ MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_FM))) {
return CAP_RX;
} else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC2,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_REC2)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC_COMPRESSED,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_REC_COMPRESSED)) ||
!strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
MAX_LEN(useCase,SND_USE_CASE_VERB_FM_REC)) ||
!strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
MAX_LEN(useCase,SND_USE_CASE_VERB_FM_A2DP_REC)) ||
!strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC2,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_MUSIC2)) ||
!strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
!strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED)) ||
!strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_FM)) ||
!strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
@@ -981,34 +921,22 @@
return CAP_TX;
} else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
MAX_LEN(useCase,SND_USE_CASE_VERB_VOICECALL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_SGLTECALL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_SGLTECALL)) ||
!strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
MAX_LEN(useCase,SND_USE_CASE_VERB_IP_VOICECALL)) ||
!strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
MAX_LEN(useCase,SND_USE_CASE_VERB_DL_REC)) ||
!strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
MAX_LEN(useCase,SND_USE_CASE_VERB_UL_DL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL)) ||
!strncmp(useCase, SND_USE_CASE_VERB_INCALL_REC,
MAX_LEN(useCase,SND_USE_CASE_VERB_INCALL_REC)) ||
!strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOICE)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_SGLTE,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_SGLTE)) ||
!strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
!strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
!strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL)) ||
!strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
MAX_LEN(useCase,SND_USE_CASE_VERB_VOLTE)) ||
!strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
@@ -1032,7 +960,7 @@
card_mctrl_t *dev_list, *uc_list;
char *current_device, use_case[MAX_UC_LEN];
int list_size, index, uc_index, ret = 0, intdev_flag = 0;
- int verb_index, capability = 0, ident_cap = 0, dev_cap = 0;
+ int verb_index, capability = 0, ident_cap = 0, dev_cap =0;
ALOGV("set_use_case_ident_for_all_devices(): %s", ident);
if ((verb_index = uc_mgr->card_ctxt_ptr->current_verb_index) < 0)
@@ -1054,50 +982,49 @@
current_device =
snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head, index);
if (current_device != NULL) {
- if ((uc_index = get_use_case_index(uc_mgr, current_device,
- CTRL_LIST_DEVICE)) < 0) {
- ALOGE("No valid device found: %s", current_device);
- continue;
- }
+ uc_index = get_use_case_index(uc_mgr, current_device,
+ CTRL_LIST_DEVICE);
dev_cap = dev_list[uc_index].capability;
if (!capability) {
capability = dev_list[uc_index].capability;
} else if (capability != dev_list[uc_index].capability) {
capability = CAP_VOICE;
}
- if (ident_cap == CAP_VOICE || dev_cap == ident_cap) {
+ if (ident_cap == CAP_VOICE || ident_cap == dev_cap) {
if (enable) {
if (!snd_ucm_get_status_at_index(
uc_mgr->card_ctxt_ptr->dev_list_head, current_device)) {
if (uc_index >= 0) {
ALOGV("Applying mixer controls for device: %s",
- current_device);
+ current_device);
ret = snd_use_case_apply_mixer_controls(uc_mgr,
- current_device, enable, CTRL_LIST_DEVICE,
- uc_index);
+ current_device, enable, CTRL_LIST_DEVICE, uc_index);
if (!ret)
snd_ucm_set_status_at_index(
uc_mgr->card_ctxt_ptr->dev_list_head,
current_device, enable, dev_cap);
}
- } else if (ident_cap == CAP_VOICE) {
+ } else if (ident_cap == CAP_VOICE) {
snd_use_case_apply_voice_acdb(uc_mgr, uc_index);
- }
- }
- strlcpy(use_case, ident, sizeof(use_case));
- strlcat(use_case, current_device, sizeof(use_case));
- ALOGV("Applying mixer controls for use case: %s", use_case);
- if ((uc_index =
- get_use_case_index(uc_mgr, use_case, ctrl_list_type)) < 0) {
- ALOGV("No valid use case found: %s", use_case);
- intdev_flag++;
- } else {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
- enable, ctrl_list_type, uc_index);
- }
- use_case[0] = 0;
- free(current_device);
- }
+ }
+ }
+ strlcpy(use_case, ident, sizeof(use_case));
+ strlcat(use_case, current_device, sizeof(use_case));
+ ALOGV("Applying mixer controls for use case: %s", use_case);
+ if ((uc_index =
+ get_use_case_index(uc_mgr, use_case, ctrl_list_type)) < 0) {
+ ALOGV("No valid use case found: %s", use_case);
+ intdev_flag++;
+ } else {
+ if (capability == CAP_VOICE || ident_cap == CAP_VOICE ||
+ capability == ident_cap) {
+ ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
+ enable, ctrl_list_type, uc_index);
+ }
+ }
+ use_case[0] = 0;
+ free(current_device);
+ }
}
}
if (intdev_flag) {
@@ -1137,11 +1064,7 @@
uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
if (device != NULL) {
if (enable) {
- if ((dev_index =
- get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE)) < 0) {
- ALOGE("No valid device found: %s", device);
- return dev_index;
- }
+ dev_index = get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE);
capability = dev_list[dev_index].capability;
if (!snd_ucm_get_status_at_index(
uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
@@ -1155,14 +1078,10 @@
}
strlcpy(use_case, ident, sizeof(use_case));
strlcat(use_case, device, sizeof(use_case));
- ALOGV("Applying mixer controls for use case: %s", use_case);
+ ALOGV("Applying mixer controls for use case: %s", use_case);
if ((uc_index = get_use_case_index(uc_mgr, use_case, ctrl_list_type)) < 0) {
ALOGV("No valid use case found: %s", use_case );
- if ((uc_index =
- get_use_case_index(uc_mgr, ident, ctrl_list_type)) < 0) {
- ALOGE("No valid use case found: %s", ident);
- return uc_index;
- }
+ uc_index = get_use_case_index(uc_mgr, ident, ctrl_list_type);
if (snd_use_case_apply_mixer_controls(uc_mgr, ident, enable,
ctrl_list_type, uc_index) < 0) {
ALOGV("use case %s not valid without device combination also",
@@ -1173,11 +1092,7 @@
ctrl_list_type, uc_index);
}
} else {
- if ((uc_index =
- get_use_case_index(uc_mgr, ident, ctrl_list_type)) < 0) {
- ALOGE("No valid use case found: %s", ident);
- return uc_index;
- }
+ uc_index = get_use_case_index(uc_mgr, ident, ctrl_list_type);
if (snd_use_case_apply_mixer_controls(uc_mgr, ident, enable,
ctrl_list_type, uc_index) < 0) {
ALOGV("use case %s not valid without device combination also",
@@ -1206,11 +1121,7 @@
verb_index = 0;
dev_list =
uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
- if ((dev_index =
- get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE)) < 0) {
- ALOGE("No valid device %s found", device);
- return dev_index;
- }
+ dev_index = get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE);
if (dev_index >= 0)
capability = dev_list[dev_index].capability;
if (strncmp(uc_mgr->card_ctxt_ptr->current_verb, SND_USE_CASE_VERB_INACTIVE,
@@ -1264,10 +1175,8 @@
use_case[0] = 0;
strlcpy(use_case, uc_mgr->card_ctxt_ptr->current_verb,
sizeof(use_case));
- if ((uc_index =
- get_use_case_index(uc_mgr, use_case, CTRL_LIST_VERB)) < 0) {
- ALOGE("No valid use case %s found", use_case);
- } else if (capability == CAP_VOICE ||
+ uc_index = get_use_case_index(uc_mgr, use_case, CTRL_LIST_VERB);
+ if (capability == CAP_VOICE ||
capability ==
getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) ||
getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) ==
@@ -1337,11 +1246,9 @@
}
use_case[0] = 0;
strlcpy(use_case, ident_value, sizeof(use_case));
- if ((uc_index =
- get_use_case_index(uc_mgr, ident_value,
- CTRL_LIST_MODIFIER)) < 0) {
- ALOGE("No valid use case %s found", ident_value);
- } else if (capability == CAP_VOICE ||
+ uc_index =
+ get_use_case_index(uc_mgr, ident_value, CTRL_LIST_MODIFIER);
+ if (capability == CAP_VOICE ||
capability == getUseCaseType(ident_value) ||
getUseCaseType(ident_value) == CAP_VOICE) {
ALOGV("set %d for use case value: %s", enable, use_case);
@@ -1411,29 +1318,14 @@
verb_index = 0;
dev_list =
uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
- if ((dev_index =
- get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE)) < 0) {
- ALOGE("No valid device %s found", device);
- return dev_index;
- }
+ dev_index = get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE);
capability = dev_list[dev_index].capability;
if (usecase != NULL) {
strlcpy(use_case, usecase, sizeof(use_case));
strlcat(use_case, device, sizeof(use_case));
if ((uc_index = get_use_case_index(uc_mgr, use_case,
get_usecase_type(uc_mgr, usecase))) < 0) {
- ALOGV("No valid use case found: %s,\
- set %d for use case value: %s",use_case, enable, usecase);
- if ((uc_index =
- get_use_case_index(uc_mgr, usecase, get_usecase_type(uc_mgr, usecase))) < 0) {
- ALOGE("No valid use case found: %s", usecase);
- } else {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, usecase, enable,
- get_usecase_type(uc_mgr, usecase), uc_index);
- if (ret != 0)
- ALOGE("No valid controls exists for usecase %s and device %s, \
- enable: %d", usecase, device, enable);
- }
+ ALOGV("No valid use case found: %s", use_case);
} else {
if (enable) {
if (!snd_ucm_get_status_at_index(
@@ -1647,15 +1539,10 @@
ALOGE("Invalid device: Device not part of enabled device list");
} else {
ALOGV("disdev: device value to be disabled: %s", value);
- if ((index =
- get_use_case_index(uc_mgr, value, CTRL_LIST_DEVICE)) < 0) {
- ALOGE("Device %s not found", value);
- ret = -EINVAL;
- } else {
- /* Apply Mixer controls for device and modifier */
- ret = snd_use_case_apply_mixer_controls(uc_mgr, value, 0,
+ index = get_use_case_index(uc_mgr, value, CTRL_LIST_DEVICE);
+ /* Apply Mixer controls for corresponding device and modifier */
+ ret = snd_use_case_apply_mixer_controls(uc_mgr, value, 0,
CTRL_LIST_DEVICE, index);
- }
}
}
} else if (!strncmp(identifier, "_enamod", 7)) {
@@ -2410,14 +2297,13 @@
close(fd);
return -EINVAL;
}
- read_buf = (char *) mmap(0, st.st_size+1, PROT_READ | PROT_WRITE,
+ read_buf = (char *) mmap(0, st.st_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
if (read_buf == MAP_FAILED) {
ALOGE("failed to mmap file error %d\n", errno);
close(fd);
return -EINVAL;
}
- read_buf[st.st_size] = '\0';
current_str = read_buf;
verb_count = get_verb_count(current_str);
(*uc_mgr)->card_ctxt_ptr->use_case_verb_list =
@@ -3357,7 +3243,6 @@
list->acdb_id = 0;
list->capability = 0;
list->effects_mixer_ctl = NULL;
- list->ec_ref_rx_mixer_ctl = NULL;
current_str = *cur_str; next_str = *nxt_str;
while(strncasecmp(current_str, "EndSection", 10)) {
current_str = next_str;
@@ -3415,14 +3300,7 @@
&list->effects_mixer_ctl);
if (ret < 0)
break;
- ALOGV("Effects mixer ctl: %s:\n", list->effects_mixer_ctl);
- } else if (strcasestr(current_str, "EC_REF_RXMixerCTL") != NULL) {
- ret = snd_ucm_extract_ec_ref_rx_mixer_ctl(current_str,
- &list->ec_ref_rx_mixer_ctl);
- ALOGV("EC_REF_RX mixer ctl: ret:%d\n", ret);
- if (ret < 0)
- break;
- ALOGE("EC_REF_RX mixer ctl: %s\n", list->ec_ref_rx_mixer_ctl);
+ ALOGV("Effects mixer ctl: %s: %d\n", list->effects_mixer_ctl);
}
if (strcasestr(current_str, "EnableSequence") != NULL) {
controls_count = get_controls_count(next_str);
@@ -3542,32 +3420,6 @@
return ret;
}
-
-/* Extract Effects Mixer ID of device from config file
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_extract_ec_ref_rx_mixer_ctl(char *buf, char **mixer_name)
-{
- int ret = 0;
- char *p, *name = *mixer_name, *temp_ptr;
-
- p = strtok_r(buf, "\"", &temp_ptr);
- while (p != NULL) {
- p = strtok_r(NULL, "\"", &temp_ptr);
- if (p == NULL)
- break;
- name = (char *)malloc((strlen(p)+1)*sizeof(char));
- if(name == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(name, p, (strlen(p)+1)*sizeof(char));
- *mixer_name = name;
- break;
- }
- return ret;
-}
-
/* Extract a playback and capture device name of use case from config file
* Returns 0 on sucess, negative error code otherwise
*/
@@ -3787,9 +3639,6 @@
if(list[case_index].effects_mixer_ctl) {
list[case_index].effects_mixer_ctl = NULL;
}
- if(list[case_index].ec_ref_rx_mixer_ctl) {
- list[case_index].ec_ref_rx_mixer_ctl = NULL;
- }
}
}
diff --git a/libalsa-intf/alsa_ucm.h b/libalsa-intf/alsa_ucm.h
index d83275c..a72ca27 100644
--- a/libalsa-intf/alsa_ucm.h
+++ b/libalsa-intf/alsa_ucm.h
@@ -102,7 +102,6 @@
#define SND_USE_CASE_VERB_VOICE "Voice"
#define SND_USE_CASE_VERB_VOICE_LOW_POWER "Voice Low Power"
#define SND_USE_CASE_VERB_VOICECALL "Voice Call"
-#define SND_USE_CASE_VERB_SGLTECALL "SGLTE"
#define SND_USE_CASE_VERB_IP_VOICECALL "Voice Call IP"
#define SND_USE_CASE_VERB_ANALOG_RADIO "FM Analog Radio"
#define SND_USE_CASE_VERB_DIGITAL_RADIO "FM Digital Radio"
@@ -150,7 +149,6 @@
#define SND_USE_CASE_MOD_CAPTURE_MUSIC "Capture Music"
#define SND_USE_CASE_MOD_PLAY_MUSIC "Play Music"
#define SND_USE_CASE_MOD_PLAY_VOICE "Play Voice"
-#define SND_USE_CASE_MOD_PLAY_SGLTE "Play SGLTE"
#define SND_USE_CASE_MOD_PLAY_TONE "Play Tone"
#define SND_USE_CASE_MOD_ECHO_REF "Echo Reference"
/* add new modifiers to end of list */
diff --git a/libalsa-intf/alsaucm_test.c b/libalsa-intf/alsaucm_test.c
index e7d927d..e01cf59 100644
--- a/libalsa-intf/alsaucm_test.c
+++ b/libalsa-intf/alsaucm_test.c
@@ -36,11 +36,6 @@
#include <errno.h>
#include <stdlib.h>
-#ifndef ANDROID
-#include <stdint.h>
-#define strlcat g_strlcat
-#endif
-
#include "alsa_ucm.h"
#include "msm8960_use_cases.h"
@@ -213,6 +208,7 @@
fprintf(stderr, "%s: error failed to open sound card %s: %d\n", cmd->cmd_str, identifier, err);
return err;
}
+ snd_use_case_mgr_wait_for_parsing(uc_mgr);
break;
case UCM_LISTCARDS:
diff --git a/libalsa-intf/aplay.c b/libalsa-intf/aplay.c
index acc1fc5..c060277 100644
--- a/libalsa-intf/aplay.c
+++ b/libalsa-intf/aplay.c
@@ -27,8 +27,6 @@
#include <getopt.h>
#include <sound/asound.h>
-#include <sound/compress_params.h>
-#include <sound/compress_offload.h>
#include "alsa_audio.h"
#ifndef ANDROID
@@ -43,28 +41,14 @@
#define FORMAT_PCM 1
#define LOG_NDEBUG 1
-
-struct output_metadata_handle_t {
- uint32_t metadataLength;
- uint32_t bufferLength;
- uint64_t timestamp;
- uint32_t reserved[12];
-};
-
-static struct output_metadata_handle_t outputMetadataTunnel;
-
static pcm_flag = 1;
static debug = 0;
static uint32_t play_max_sz = 2147483648LL;
static int format = SNDRV_PCM_FORMAT_S16_LE;
static int period = 0;
static int compressed = 0;
-static int set_channel_map = 0;
-static char channel_map[8];
static char *compr_codec;
static int piped = 0;
-static int outputMetadataLength = 0;
-static int eosSet = 0;
static struct option long_options[] =
{
@@ -77,7 +61,6 @@
{"format", 1, 0, 'F'},
{"period", 1, 0, 'B'},
{"compressed", 0, 0, 'T'},
- {"channelMap", 0, 0, 'X'},
{0, 0, 0, 0}
};
@@ -97,13 +80,6 @@
uint32_t data_sz;
};
-
-void updateMetaData(size_t bytes) {
- outputMetadataTunnel.metadataLength = sizeof(outputMetadataTunnel);
- outputMetadataTunnel.timestamp = 0;
- outputMetadataTunnel.bufferLength = bytes;
- fprintf(stderr, "bytes = %d\n", bytes);
-}
static int set_params(struct pcm *pcm)
{
struct snd_pcm_hw_params *params;
@@ -112,17 +88,7 @@
unsigned long periodSize, bufferSize, reqBuffSize;
unsigned int periodTime, bufferTime;
unsigned int requestedRate = pcm->rate;
- int channels;
- if(pcm->flags & PCM_MONO)
- channels = 1;
- else if(pcm->flags & PCM_QUAD)
- channels = 4;
- else if(pcm->flags & PCM_5POINT1)
- channels = 6;
- else if(pcm->flags & PCM_7POINT1)
- channels = 8;
- else
- channels = 2;
+ int channels = (pcm->flags & PCM_MONO) ? 1 : ((pcm->flags & PCM_5POINT1)? 6 : 2 );
params = (struct snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
if (!params) {
@@ -195,25 +161,6 @@
return 0;
}
-void send_channel_map_driver(struct pcm *pcm)
-{
- int i, ret;
- struct mixer *mixer;
- const char* device = "/dev/snd/controlC0";
-
- mixer = mixer_open(device);
- if (!mixer) {
- fprintf(stderr,"oops: %s: %d\n", strerror(errno), __LINE__);
- return;
- }
- ret = pcm_set_channel_map(pcm, mixer, 8, channel_map);
- if (ret < 0)
- fprintf(stderr, "could not set channel mask\n");
- mixer_close(mixer);
-
- return;
-}
-
static int play_file(unsigned rate, unsigned channels, int fd,
unsigned flags, const char *device, unsigned data_sz)
{
@@ -236,12 +183,8 @@
if (channels == 1)
flags |= PCM_MONO;
- else if (channels == 4)
- flags |= PCM_QUAD;
else if (channels == 6)
flags |= PCM_5POINT1;
- else if (channels == 8)
- flags |= PCM_7POINT1;
else
flags |= PCM_STEREO;
@@ -259,6 +202,7 @@
return -EBADFD;
}
+#ifdef QCOM_COMPRESSED_AUDIO_ENABLED
if (compressed) {
struct snd_compr_caps compr_cap;
struct snd_compr_params compr_params;
@@ -270,16 +214,12 @@
if (!period)
period = compr_cap.min_fragment_size;
switch (get_compressed_format(compr_codec)) {
- case SND_AUDIOCODEC_MP3:
- compr_params.codec.id = SND_AUDIOCODEC_MP3;
+ case FORMAT_MP3:
+ compr_params.codec.id = compr_cap.codecs[FORMAT_MP3];
break;
- case SND_AUDIOCODEC_AC3_PASS_THROUGH:
- compr_params.codec.id = SND_AUDIOCODEC_AC3_PASS_THROUGH;
- printf("codec -d = %x\n", SND_AUDIOCODEC_AC3_PASS_THROUGH);
- break;
- case SND_AUDIOCODEC_AAC:
- compr_params.codec.id = SND_AUDIOCODEC_AAC;
- printf("codec -d = %x\n", SND_AUDIOCODEC_AAC);
+ case FORMAT_AC3_PASS_THROUGH:
+ compr_params.codec.id = compr_cap.codecs[FORMAT_AC3_PASS_THROUGH];
+ printf("codec -d = %x\n", compr_params.codec.id);
break;
default:
break;
@@ -289,12 +229,8 @@
pcm_close(pcm);
return -errno;
}
- outputMetadataLength = sizeof(struct output_metadata_handle_t);
- } else if (channels > 2) {
- if(set_channel_map) {
- send_channel_map_driver(pcm);
- }
}
+#endif
pcm->channels = channels;
pcm->rate = rate;
pcm->flags = flags;
@@ -342,7 +278,7 @@
pfd[0].fd = pcm->timer_fd;
pfd[0].events = POLLIN;
- frames = bufsize / (2*channels);
+ frames = (pcm->flags & PCM_MONO) ? (bufsize / 2) : (bufsize / 4);
for (;;) {
if (!pcm->running) {
if (pcm_prepare(pcm)) {
@@ -402,23 +338,16 @@
if (data_sz && !piped) {
if (remainingData < bufsize) {
bufsize = remainingData;
- frames = remainingData / (2*channels);
+ frames = (pcm->flags & PCM_MONO) ? (remainingData / 2) : (remainingData / 4);
}
}
- fprintf(stderr, "addr = %d, size = %d \n", (dst_addr + outputMetadataLength),(bufsize - outputMetadataLength));
- err = read(fd, (dst_addr + outputMetadataLength) , (bufsize - outputMetadataLength));
- if(compressed) {
- updateMetaData(err);
- memcpy(dst_addr, &outputMetadataTunnel, outputMetadataLength);
- }
+ err = read(fd, dst_addr , bufsize);
if (debug)
fprintf(stderr, "read %d bytes from file\n", err);
- if (err <= 0 ) {
- fprintf(stderr," EOS set\n ");
- eosSet = 1;
+ if (err <= 0)
break;
- }
+
if (data_sz && !piped) {
remainingData -= bufsize;
if (remainingData <= 0)
@@ -445,13 +374,15 @@
fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld sync_ptr->c.control.appl_ptr %ld\n",
pcm->sync_ptr->s.status.hw_ptr,
pcm->sync_ptr->c.control.appl_ptr);
+#ifdef QCOM_COMPRESSED_AUDIO_ENABLED
if (compressed && start) {
struct snd_compr_tstamp tstamp;
- if (ioctl(pcm->fd, SNDRV_COMPRESS_TSTAMP, &tstamp))
- fprintf(stderr, "Aplay: failed SNDRV_COMPRESS_TSTAMP\n");
+ if (ioctl(pcm->fd, SNDRV_COMPRESS_TSTAMP, &tstamp))
+ fprintf(stderr, "Aplay: failed SNDRV_COMPRESS_TSTAMP\n");
else
- fprintf(stderr, "timestamp = %lld\n", tstamp.timestamp);
- }
+ fprintf(stderr, "timestamp = %lld\n", tstamp.timestamp);
+ }
+#endif
}
/*
* If we have reached start threshold of buffer prefill,
@@ -478,7 +409,6 @@
start_done:
offset += frames;
}
-
while(1) {
pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC;
sync_ptr(pcm);
@@ -490,14 +420,6 @@
fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld sync_ptr->c.control.appl_ptr %ld\n",
pcm->sync_ptr->s.status.hw_ptr,
pcm->sync_ptr->c.control.appl_ptr);
-
- if(compressed && eosSet) {
- fprintf(stderr,"Audio Drain DONE ++\n");
- if ( ioctl(pcm->fd, SNDRV_COMPRESS_DRAIN) < 0 ) {
- fprintf(stderr,"Audio Drain failed\n");
- }
- fprintf(stderr,"Audio Drain DONE --\n");
- }
break;
} else
poll(pfd, nfds, TIMEOUT_INFINITE);
@@ -569,7 +491,7 @@
flag = PCM_NMMAP;
fprintf(stderr, "aplay: Playing '%s': format %s ch = %d\n",
- fn, get_format_desc(format), ch );
+ fn, get_format_desc(format), ch );
return play_file(rate, ch, fd, flag, device, 0);
}
@@ -634,45 +556,6 @@
return play_file(hdr.sample_rate, hdr.num_channels, fd, flag, device, hdr.data_sz);
}
-char get_channel_map_val(char *string)
-{
- char retval = 0;
- if( !strncmp(string, "RRC", sizeof(string)) )
- retval = 16;
- else if( !strncmp(string, "RLC", sizeof(string)) )
- retval = 15;
- else if( !strncmp(string, "FRC", sizeof(string)) )
- retval = 14;
- else if( !strncmp(string, "FLC", sizeof(string)) )
- retval = 13;
- else if( !strncmp(string, "MS", sizeof(string)) )
- retval = 12;
- else if( !strncmp(string, "CVH", sizeof(string)) )
- retval = 11;
- else if( !strncmp(string, "TS", sizeof(string)) )
- retval = 10;
- else if( !strncmp(string, "RB", sizeof(string)) )
- retval = 9;
- else if( !strncmp(string, "LB", sizeof(string)) )
- retval = 8;
- else if( !strncmp(string, "CS", sizeof(string)) )
- retval = 7;
- else if( !strncmp(string, "LFE", sizeof(string)) )
- retval = 6;
- else if( !strncmp(string, "RS", sizeof(string)) )
- retval = 5;
- else if( !strncmp(string, "LS", sizeof(string)) )
- retval = 4;
- else if( !strncmp(string, "FC", sizeof(string)) )
- retval = 3;
- else if( !strncmp(string, "FR", sizeof(string)) )
- retval = 2;
- else if( !strncmp(string, "FL", sizeof(string)) )
- retval = 1;
-
- return retval;
-}
-
int main(int argc, char **argv)
{
int option_index = 0;
@@ -682,25 +565,20 @@
char *mmap = "N";
char *device = "hw:0,0";
char *filename;
- char *ptr;
int rc = 0;
if (argc <2) {
printf("\nUsage: aplay [options] <file>\n"
"options:\n"
- "-D <hw:C,D> -- Alsa PCM by name\n"
- "-M -- Mmap stream\n"
- "-P -- Hostless steam[No PCM]\n"
- "-C -- Channels\n"
- "-R -- Rate\n"
- "-V -- verbose\n"
- "-F -- Format\n"
+ "-D <hw:C,D> -- Alsa PCM by name\n"
+ "-M -- Mmap stream\n"
+ "-P -- Hostless steam[No PCM]\n"
+ "-C -- Channels\n"
+ "-R -- Rate\n"
+ "-V -- verbose\n"
+ "-F -- Format\n"
"-B -- Period\n"
"-T <MP3, AAC, AC3_PASS_THROUGH> -- Compressed\n"
- "-X <\"FL,FR,FC,Ls,Rs,LFE\" for 5.1 configuration\n"
- " supported channels: \n"
- " FL, FR, FC, LS, RS, LFE, CS, TS \n"
- " LB, RB, FLC, FRC, RLC, RRC, CVH, MS\n"
"<file> \n");
fprintf(stderr, "Formats Supported:\n");
for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; ++i)
@@ -709,7 +587,7 @@
fprintf(stderr, "\nSome of these may not be available on selected hardware\n");
return 0;
}
- while ((c = getopt_long(argc, argv, "PVMD:R:C:F:B:T:X:", long_options, &option_index)) != -1) {
+ while ((c = getopt_long(argc, argv, "PVMD:R:C:F:B:T:", long_options, &option_index)) != -1) {
switch (c) {
case 'P':
pcm_flag = 0;
@@ -741,35 +619,18 @@
printf("compressed codec type requested = %s\n", optarg);
compr_codec = optarg;
break;
- case 'X':
- set_channel_map = 1; i = 0;
- memset(channel_map, 0, sizeof(channel_map));
- ptr = strtok(optarg, ",");
- while((ptr != NULL) && (i < sizeof(channel_map))) {
- channel_map[i] = get_channel_map_val(ptr);
- if (channel_map[i] < 0 || channel_map[i] > 16) {
- set_channel_map = 0;
- break;
- }
- ptr = strtok(NULL,","); i++;
- }
- break;
default:
printf("\nUsage: aplay [options] <file>\n"
"options:\n"
- "-D <hw:C,D> -- Alsa PCM by name\n"
- "-M -- Mmap stream\n"
- "-P -- Hostless steam[No PCM]\n"
- "-V -- verbose\n"
- "-C -- Channels\n"
- "-R -- Rate\n"
- "-F -- Format\n"
+ "-D <hw:C,D> -- Alsa PCM by name\n"
+ "-M -- Mmap stream\n"
+ "-P -- Hostless steam[No PCM]\n"
+ "-V -- verbose\n"
+ "-C -- Channels\n"
+ "-R -- Rate\n"
+ "-F -- Format\n"
"-B -- Period\n"
"-T -- Compressed\n"
- "-X <\"FL,FR,FC,Ls,Rs,LFE\" for 5.1 configuration\n"
- " supported channels: \n"
- " FL, FR, FC, LS, RS, LFE, CS, TS \n"
- " LB, RB, FLC, FRC, RLC, RRC, CVH, MS\n"
"<file> \n");
fprintf(stderr, "Formats Supported:\n");
for (i = 0; i < SNDRV_PCM_FORMAT_LAST; ++i)
@@ -793,7 +654,7 @@
}
if (pcm_flag) {
- if (format == SNDRV_PCM_FORMAT_S16_LE)
+ if (format == SNDRV_PCM_FORMAT_S16_LE)
rc = play_wav(mmap, rate, ch, device, filename);
else
rc = play_raw(mmap, rate, ch, device, filename);
diff --git a/libalsa-intf/arec.c b/libalsa-intf/arec.c
index dde0ce9..cab88f1 100644
--- a/libalsa-intf/arec.c
+++ b/libalsa-intf/arec.c
@@ -28,10 +28,6 @@
#include <getopt.h>
#include <limits.h>
-#include <sound/asound.h>
-#include <sound/compress_params.h>
-#include <sound/compress_offload.h>
-
#include "alsa_audio.h"
#define ID_RIFF 0x46464952
@@ -46,20 +42,17 @@
#define strlcpy g_strlcpy
#endif
-#define COMPR_META_DATA_SIZE 64
static struct wav_header hdr;
static int fd;
static struct pcm *pcm;
-static debug = 0;
-static pcm_flag = 1;
-static duration = 0;
+static int debug = 0;
+static int pcm_flag = 1;
+static int duration = 0;
static char *filename;
static char *data;
static int format = SNDRV_PCM_FORMAT_S16_LE;
static int period = 0;
static int piped = 0;
-static int compressed = 0;
-static char *compr_codec;
static struct option long_options[] =
{
@@ -72,7 +65,6 @@
{"duration", 1, 0, 'T'},
{"format", 1, 0, 'F'},
{"period", 1, 0, 'B'},
- {"compressed", 1, 0, 'K'},
{0, 0, 0, 0}
};
@@ -185,7 +177,7 @@
int record_file(unsigned rate, unsigned channels, int fd, unsigned count, unsigned flags, const char *device)
{
- unsigned xfer, bufsize, framesize;
+ unsigned xfer, bufsize;
int r, avail;
int nfds = 1;
static int start = 0;
@@ -195,7 +187,7 @@
int err;
struct pollfd pfd[1];
int rec_size = 0;
- framesize = 0;
+
flags |= PCM_IN;
if (channels == 1)
@@ -212,41 +204,6 @@
pcm_close(pcm);
goto fail;
}
-
- if (compressed) {
- struct snd_compr_caps compr_cap;
- struct snd_compr_params compr_params;
- printf("SNDRV_COMPRESS_GET_CAPS= 0x%X\n", SNDRV_COMPRESS_GET_CAPS);
- if (ioctl(pcm->fd, SNDRV_COMPRESS_GET_CAPS, &compr_cap)) {
- fprintf(stderr, "AREC: SNDRV_COMPRESS_GET_CAPS, failed Error no %d \n", errno);
- pcm_close(pcm);
- return -errno;
- }
- if (!period)
- period = compr_cap.min_fragment_size;
- switch (get_compressed_format(compr_codec)) {
- case SND_AUDIOCODEC_MP3:
- compr_params.codec.id = SND_AUDIOCODEC_MP3;
- break;
- case SND_AUDIOCODEC_AC3_PASS_THROUGH:
- compr_params.codec.id = SND_AUDIOCODEC_AC3_PASS_THROUGH;
- printf("codec -d = %x\n", compr_params.codec.id);
- break;
- case SND_AUDIOCODEC_AMRWB:
- compr_params.codec.id = SND_AUDIOCODEC_AMRWB;
- compr_params.codec.options.generic.reserved[0] = 8; /*band mode - 23.85 kbps*/
- compr_params.codec.options.generic.reserved[1] = 0; /*dtx mode - disable*/
- printf("codec -d = %x\n", compr_params.codec.id);
- break;
- default:
- break;
- }
- if (ioctl(pcm->fd, SNDRV_COMPRESS_SET_PARAMS, &compr_params)) {
- fprintf(stderr, "AREC: SNDRV_COMPRESS_SET_PARAMS,failed Error no %d \n", errno);
- pcm_close(pcm);
- return -errno;
- }
- }
pcm->channels = channels;
pcm->rate = rate;
pcm->flags = flags;
@@ -291,18 +248,17 @@
}
bufsize = pcm->period_size;
-
if (debug)
- fprintf(stderr, "Arec:bufsize = %d\n", bufsize);
+ fprintf(stderr, "Arec:bufsize = %d\n", bufsize);
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
- if (errno == EPIPE) {
+ if (errno == EPIPE) {
fprintf(stderr, "Arec:Failed in SNDRV_PCM_IOCTL_START\n");
/* we failed to make our window -- try to restart */
pcm->running = 0;
- } else {
- fprintf(stderr, "Arec:Error no %d \n", errno);
- return -errno;
- }
+ } else {
+ fprintf(stderr, "Arec:Error no %d \n", errno);
+ return -errno;
+ }
}
pfd[0].fd = pcm->fd;
@@ -320,20 +276,20 @@
}
x.frames = frames;
for(;;) {
- if (!pcm->running) {
- if (pcm_prepare(pcm))
- return --errno;
- start = 0;
- }
- /* Sync the current Application pointer from the kernel */
- pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;/*SNDRV_PCM_SYNC_PTR_HWSYNC;*/
- err = sync_ptr(pcm);
- if (err == EPIPE) {
- fprintf(stderr, "Arec:Failed in sync_ptr \n");
- /* we failed to make our window -- try to restart */
- //pcm->overruns++;
- pcm->running = 0;
- continue;
+ if (!pcm->running) {
+ if (pcm_prepare(pcm))
+ return --errno;
+ start = 0;
+ }
+ /* Sync the current Application pointer from the kernel */
+ pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC;
+ err = sync_ptr(pcm);
+ if (err == EPIPE) {
+ fprintf(stderr, "Arec:Failed in sync_ptr \n");
+ /* we failed to make our window -- try to restart */
+ //pcm->overruns++;
+ pcm->running = 0;
+ continue;
}
/*
* Check for the available data in driver. If available data is
@@ -341,16 +297,14 @@
*/
avail = pcm_avail(pcm);
if (debug)
- fprintf(stderr, "Arec:avail 1 = %d frames = %ld, avail_min = %d,"
- "x.frames = %d, bufsize = %d, dst_addr = %p\n",avail, frames,
- (int)pcm->sw_p->avail_min, (int)x.frames, bufsize, dst_addr);
+ fprintf(stderr, "Arec:avail 1 = %d frames = %ld\n",avail, frames);
if (avail < 0)
return avail;
if (avail < pcm->sw_p->avail_min) {
poll(pfd, nfds, TIMEOUT_INFINITE);
continue;
}
- if (x.frames > avail)
+ if (x.frames > avail)
frames = avail;
/*
* Now that we have data size greater than avail_min available to
@@ -358,31 +312,18 @@
* start reading from.
*/
dst_addr = dst_address(pcm);
- if (compressed) {
- framesize = (unsigned)(dst_addr[3] << 24) + (unsigned)(dst_addr[2] << 16) +
- (unsigned) (dst_addr[1] << 8) + (unsigned)dst_addr[0];
- if (debug)
- fprintf(stderr, "Arec:dst_addr[0] = %d, dst_addr[1] = %d,"
- "dst_addr[2] = %d, dst_addr[3] = %d, dst_addr[4] = %d,"
- "dst_addr[5] = %d, dst_addr = %p, bufsize = %d, framesize = %d\n",
- dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3], dst_addr[4],
- dst_addr[5],dst_addr, bufsize, framesize);
- dst_addr += COMPR_META_DATA_SIZE;
- } else {
- framesize = bufsize;
- }
/*
* Write to the file at the destination address from kernel mmaped buffer
* This reduces a extra copy of intermediate buffer.
*/
- if (write(fd, dst_addr, framesize) != framesize) {
- fprintf(stderr, "Arec:could not write %d bytes\n", framesize);
+ if (write(fd, dst_addr, bufsize) != bufsize) {
+ fprintf(stderr, "Arec:could not write %d bytes\n", bufsize);
return -errno;
}
x.frames -= frames;
pcm->sync_ptr->c.control.appl_ptr += frames;
- pcm->sync_ptr->flags = 0;
+ pcm->sync_ptr->flags = 0;
err = sync_ptr(pcm);
if (err == EPIPE) {
fprintf(stderr, "Arec:Failed in sync_ptr \n");
@@ -391,14 +332,12 @@
continue;
}
rec_size += bufsize;
- if (!compressed) {
- hdr.data_sz += bufsize;
- hdr.riff_sz = hdr.data_sz + 44 - 8;
- if (!piped) {
- lseek(fd, 0, SEEK_SET);
- write(fd, &hdr, sizeof(hdr));
- lseek(fd, 0, SEEK_END);
- }
+ hdr.data_sz += bufsize;
+ hdr.riff_sz = hdr.data_sz + 44 - 8;
+ if (!piped) {
+ lseek(fd, 0, SEEK_SET);
+ write(fd, &hdr, sizeof(hdr));
+ lseek(fd, 0, SEEK_END);
}
if (rec_size >= count)
break;
@@ -452,7 +391,7 @@
uint32_t rec_max_sz = 2147483648LL;
uint32_t count;
int i = 0;
- printf("rec_raw-> pcm_flag = %d\n", pcm_flag);
+
if (!fn) {
fd = fileno(stdout);
piped = 1;
@@ -488,60 +427,53 @@
uint32_t rec_max_sz = 2147483648LL;
uint32_t count = 0;
int i = 0;
- printf("rec_wav-> pcm_flag = %d\n", pcm_flag);
- if (pcm_flag) {
- if (!fn) {
- fd = fileno(stdout);
- piped = 1;
- } else {
- fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
- if (fd < 0) {
- fprintf(stderr, "Arec:arec: cannot open '%s'\n", fn);
- return -EBADFD;
- }
- }
- if (compressed) {
- printf("rec_wav-> compressed = %d\n", compressed);
+ if (pcm_flag) {
+ if (!fn) {
+ fd = fileno(stdout);
+ piped = 1;
+ } else {
+ fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
+ if (fd < 0) {
+ fprintf(stderr, "Arec:arec: cannot open '%s'\n", fn);
+ return -EBADFD;
+ }
+ }
+ memset(&hdr, 0, sizeof(struct wav_header));
+ hdr.riff_id = ID_RIFF;
+ hdr.riff_fmt = ID_WAVE;
+ hdr.fmt_id = ID_FMT;
+ hdr.fmt_sz = 16;
+ hdr.audio_format = FORMAT_PCM;
+ hdr.num_channels = ch;
+ hdr.sample_rate = rate;
+ hdr.bits_per_sample = 16;
+ hdr.byte_rate = (rate * ch * hdr.bits_per_sample) / 8;
+ hdr.block_align = ( hdr.bits_per_sample * ch ) / 8;
+ hdr.data_id = ID_DATA;
+ hdr.data_sz = 0;
+
+ if (duration == 0) {
+ count = rec_max_sz;
+ } else {
+ count = rate * ch * 2;
+ count *= (uint32_t)duration;
+ }
+ hdr.riff_sz = hdr.data_sz + 44 - 8;
+ if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+ if (debug)
+ fprintf(stderr, "arec: cannot write header\n");
+ return -errno;
+ }
+ if (debug)
+ fprintf(stderr, "arec: %d ch, %d hz, %d bit, %s\n",
+ hdr.num_channels, hdr.sample_rate, hdr.bits_per_sample,
+ hdr.audio_format == FORMAT_PCM ? "PCM" : "unknown");
+ } else {
hdr.sample_rate = rate;
hdr.num_channels = ch;
- goto ignore_header;
- }
- memset(&hdr, 0, sizeof(struct wav_header));
- hdr.riff_id = ID_RIFF;
- hdr.riff_fmt = ID_WAVE;
- hdr.fmt_id = ID_FMT;
- hdr.fmt_sz = 16;
- hdr.audio_format = FORMAT_PCM;
- hdr.num_channels = ch;
- hdr.sample_rate = rate;
- hdr.bits_per_sample = 16;
- hdr.byte_rate = (rate * ch * hdr.bits_per_sample) / 8;
- hdr.block_align = ( hdr.bits_per_sample * ch ) / 8;
- hdr.data_id = ID_DATA;
- hdr.data_sz = 0;
- hdr.riff_sz = hdr.data_sz + 44 - 8;
- if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- if (debug)
- fprintf(stderr, "arec: cannot write header\n");
- return -errno;
- }
- if (debug)
- fprintf(stderr, "arec: %d ch, %d hz, %d bit, %s\n",
- hdr.num_channels, hdr.sample_rate, hdr.bits_per_sample,
- hdr.audio_format == FORMAT_PCM ? "PCM" : "unknown");
- } else {
- hdr.sample_rate = rate;
- hdr.num_channels = ch;
}
-ignore_header:
- if (duration == 0) {
- count = rec_max_sz;
- } else {
- count = rate * ch * 2;
- count *= (uint32_t)duration;
- }
if (!strncmp(fg, "M", sizeof("M"))) {
flag = PCM_MMAP;
} else if (!strncmp(fg, "N", sizeof("N"))) {
@@ -589,26 +521,25 @@
int rc = 0;
if (argc < 2) {
- printf("\nUsage: arec [options] <file>\n"
- "options:\n"
- "-D <hw:C,D> -- Alsa PCM by name\n"
- "-M -- Mmap stream\n"
- "-P -- Hostless steam[No PCM]\n"
- "-V -- verbose\n"
- "-C -- Channels\n"
- "-R -- Rate\n"
- "-T -- Time in seconds for recording\n"
- "-F -- Format\n"
- "-B -- Period\n"
- "-K <AC3,DTS,etc> -- compressed\n"
- "<file> \n");
+ printf("\nUsage: arec [options] <file>\n"
+ "options:\n"
+ "-D <hw:C,D> -- Alsa PCM by name\n"
+ "-M -- Mmap stream\n"
+ "-P -- Hostless steam[No PCM]\n"
+ "-V -- verbose\n"
+ "-C -- Channels\n"
+ "-R -- Rate\n"
+ "-T -- Time in seconds for recording\n"
+ "-F -- Format\n"
+ "-B -- Period\n"
+ "<file> \n");
for (i = 0; i < SNDRV_PCM_FORMAT_LAST; ++i)
if (get_format_name(i))
fprintf(stderr, "%s ", get_format_name(i));
fprintf(stderr, "\nSome of these may not be available on selected hardware\n");
return 0;
}
- while ((c = getopt_long(argc, argv, "PVMD:R:C:T:F:B:K:", long_options, &option_index)) != -1) {
+ while ((c = getopt_long(argc, argv, "PVMD:R:C:T:F:B:", long_options, &option_index)) != -1) {
switch (c) {
case 'P':
pcm_flag = 0;
@@ -637,24 +568,18 @@
case 'B':
period = (int)strtol(optarg, NULL, 0);
break;
- case 'K':
- compressed = 1;
- printf("compressed codec type requested = %s\n", optarg);
- compr_codec = optarg;
- break;
default:
printf("\nUsage: arec [options] <file>\n"
"options:\n"
- "-D <hw:C,D> -- Alsa PCM by name\n"
- "-M -- Mmap stream\n"
- "-P -- Hostless steam[No PCM]\n"
- "-V -- verbose\n"
- "-C -- Channels\n"
- "-R -- Rate\n"
- "-T -- Time in seconds for recording\n"
- "-F -- Format\n"
- "-B -- Period\n"
- "-K <AC3,DTS,etc> -- compressed\n"
+ "-D <hw:C,D> -- Alsa PCM by name\n"
+ "-M -- Mmap stream\n"
+ "-P -- Hostless steam[No PCM]\n"
+ "-V -- verbose\n"
+ "-C -- Channels\n"
+ "-R -- Rate\n"
+ "-T -- Time in seconds for recording\n"
+ "-F -- Format\n"
+ "-B -- Period\n"
"<file> \n");
for (i = 0; i < SNDRV_PCM_FORMAT_LAST; ++i)
if (get_format_name(i))
diff --git a/libalsa-intf/msm8960_use_cases.h b/libalsa-intf/msm8960_use_cases.h
index 784aa72..ed58d8a 100644
--- a/libalsa-intf/msm8960_use_cases.h
+++ b/libalsa-intf/msm8960_use_cases.h
@@ -44,7 +44,6 @@
#define CAP_VOICE 0x4
#define DEVICE_HANDSET_RX_ACDB_ID 7 // HANDSET_SPKR
#define DEVICE_HANDSET_TX_ACDB_ID 4 // HANDSET_MIC
-#define DEVICE_SPEAKER_RX_ACDB_ID 15// SPKR_PHONE_SPKR_STEREO
#define DEVICE_SPEAKER_MONO_RX_ACDB_ID 14// SPKR_PHONE_SPKR_MONO
#define DEVICE_SPEAKER_STEREO_RX_ACDB_ID 15// SPKR_PHONE_SPKR_STEREO
#define DEVICE_SPEAKER_TX_ACDB_ID 11// SPKR_PHONE_MIC
@@ -54,8 +53,6 @@
#define DEVICE_DUALMIC_HANDSET_TX_ENDFIRE_ACDB_ID 6 // HANDSET_MIC_ENDFIRE
#define DEVICE_DUALMIC_SPEAKER_TX_BROADSIDE_ACDB_ID 12// SPKR_PHONE_MIC_BROADSIDE
#define DEVICE_DUALMIC_SPEAKER_TX_ENDFIRE_ACDB_ID 13// SPKR_PHONE_MIC_ENDFIRE
-#define DEVICE_DUALMIC_HANDSET_STEREO_ACDB_ID 34
-#define DEVICE_DUALMIC_SPEAKER_PHONE_STEREO_ACDB_ID 35
#define DEVICE_TTY_HEADSET_MONO_RX_ACDB_ID 17// TTY_HEADSET_SPKR
#define DEVICE_TTY_HEADSET_MONO_TX_ACDB_ID 16// TTY_HEADSET_MIC
#define DEVICE_BT_SCO_RX_ACDB_ID 22// BT_SCO_SPKR
@@ -69,10 +66,10 @@
#define DEVICE_PROXY_RX_ACDB_ID DEVICE_HDMI_STEREO_RX_ACDB_ID
#define DEVICE_TTY_VCO_HANDSET_TX_ACDB_ID 36// TTY_VCO_HANDSET_MIC
#define DEVICE_TTY_HCO_HANDSET_RX_ACDB_ID 37// TTY_HCO_HANDSET_SPRK
-#define DEVICE_HANDSET_TX_FV5_ACDB_ID 40
-#define DEVICE_DUALMIC_HANDSET_TX_ENDFIRE_FV5_ACDB_ID 41
-#define DEVICE_SPEAKER_TX_FV5_ACDB_ID 42
-#define DEVICE_DUALMIC_SPEAKER_TX_ENDFIRE_FV5_ACDB_ID 43
+#define DEVICE_HANDSET_TX_FV5_ACDB_ID 50
+#define DEVICE_DUALMIC_HANDSET_TX_ENDFIRE_FV5_ACDB_ID 51
+#define DEVICE_SPEAKER_TX_FV5_ACDB_ID 52
+#define DEVICE_DUALMIC_SPEAKER_TX_ENDFIRE_FV5_ACDB_ID 53
#define DEVICE_INCALL_VOICE_RECORD_STEREO_ACDB_ID 45
#define DEVICE_INCALL_MUSIC_DELIVERY_MONO_ACDB_ID 46
#define DEVICE_INCALL_VOICE_RECORD_MONO_ACDB_ID 47
@@ -120,7 +117,6 @@
int acdb_id;
int capability;
char *effects_mixer_ctl;
- char *ec_ref_rx_mixer_ctl;
}card_mctrl_t;
/* identifier node structure for identifier list*/
@@ -172,6 +168,7 @@
int current_rx_device;
card_ctxt_t *card_ctxt_ptr;
pthread_t thr;
+ void *acdb_handle;
};
#define MAX_NUM_CARDS (sizeof(card_list)/sizeof(char *))
@@ -180,16 +177,8 @@
static const char *card_list[] = {
"snd_soc_msm",
"snd_soc_msm_2x",
- "snd_soc_msm_2x_mpq",
"snd_soc_msm_2x_Fusion3",
"snd_soc_msm_Sitar",
- "snd_soc_msm_I2S",
- "snd_soc_msm_Taiko",
- "snd_soc_msm_Taiko_CDP",
- "snd_soc_msm_Taiko_Fluid",
- "snd_soc_msm_Taiko_liquid",
- "snd_soc_msm_I2SFusion",
- "us_soc_msm",
};
typedef struct card_mapping {
@@ -201,16 +190,8 @@
static card_mapping_t card_mapping_list[] = {
{"snd_soc_msm", 0},
{"snd_soc_msm_2x", 0},
- {"snd_soc_msm_2x_mpq", 0},
{"snd_soc_msm_2x_Fusion3", 0},
{"snd_soc_msm_Sitar", 0},
- {"snd_soc_msm_I2S", 0},
- {"snd_soc_msm_Taiko", 0},
- {"snd_soc_msm_Taiko_CDP", 0},
- {"snd_soc_msm_Taiko_Fluid", 0},
- {"snd_soc_msm_Taiko_liquid", 0},
- {"snd_soc_msm_I2SFusion", 0},
- {"us_soc_msm", 0},
};
/* New use cases, devices and modifiers added
@@ -222,8 +203,6 @@
#define SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC "HiFi Lowlatency Rec"
#define SND_USE_CASE_VERB_DL_REC "DL REC"
#define SND_USE_CASE_VERB_UL_DL_REC "UL DL REC"
-#define SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_DL "Compressed DL REC"
-#define SND_USE_CASE_VERB_CAPTURE_COMPRESSED_VOICE_UL_DL "Compressed UL DL REC"
#define SND_USE_CASE_VERB_HIFI_TUNNEL "HiFi Tunnel"
#define SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC "HiFi Lowlatency"
#define SND_USE_CASE_VERB_HIFI2 "HiFi2"
@@ -231,11 +210,6 @@
#define SND_USE_CASE_VERB_MI2S "MI2S"
#define SND_USE_CASE_VERB_VOLTE "VoLTE"
#define SND_USE_CASE_VERB_ADSP_TESTFWK "ADSP testfwk"
-#define SND_USE_CASE_VERB_HIFI_REC2 "HiFi Rec2"
-#define SND_USE_CASE_VERB_HIFI_REC_COMPRESSED "HiFi Rec Compressed"
-#define SND_USE_CASE_VERB_HIFI3 "HiFi3"
-#define SND_USE_CASE_VERB_HIFI_TUNNEL2 "HiFi Tunnel2"
-#define SND_USE_CASE_VERB_HIFI_PSEUDO_TUNNEL "HiFi Pseudo Tunnel"
#define SND_USE_CASE_DEV_FM_TX "FM Tx"
#define SND_USE_CASE_DEV_ANC_HEADSET "ANC Headset"
@@ -255,25 +229,16 @@
#define SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX "TTY Handset Analog Tx"
#define SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE "DMIC Broadside"
#define SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE "DMIC Endfire"
-#define SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE_SGLTE "DMIC Endfire SGLTE"
-#define SND_USE_CASE_DEV_DUAL_MIC_HANDSET_STEREO "Handset DMIC Stereo"
-#define SND_USE_CASE_DEV_DUAL_MIC_HANDSET_STEREO_SGLTE "Handset DMIC Stereo SGLTE"
#define SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE "Speaker DMIC Broadside"
#define SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE "Speaker DMIC Endfire"
-#define SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE_SGLTE "Speaker DMIC Endfire SGLTE"
-#define SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_STEREO "Speaker DMIC Stereo"
-#define SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_STEREO_SGLTE "Speaker DMIC Stereo SGLTE"
#define SND_USE_CASE_DEV_HDMI_TX "HDMI Tx"
#define SND_USE_CASE_DEV_HDMI_SPDIF "HDMI SPDIF"
-#define SND_USE_CASE_DEV_HDMI_SPDIF_SPEAKER "HDMI SPDIF Speaker"
#define SND_USE_CASE_DEV_QUAD_MIC "QMIC"
#define SND_USE_CASE_DEV_SSR_QUAD_MIC "SSR QMIC"
#define SND_USE_CASE_DEV_PROXY_RX "PROXY Rx"
#define SND_USE_CASE_DEV_PROXY_TX "PROXY Tx"
-#define SND_USE_CASE_DEV_USB_PROXY_RX "USB PROXY Rx"
-#define SND_USE_CASE_DEV_USB_PROXY_TX "USB PROXY Tx"
+#define SND_USE_CASE_DEV_HDMI_SPEAKER "HDMI Speaker"
#define SND_USE_CASE_DEV_SPDIF_SPEAKER "SPDIF Speaker"
-#define SND_USE_CASE_DEV_HDMI_SPEAKER "HDMI Speaker"
#define SND_USE_CASE_DEV_SPDIF_HANDSET "SPDIF Earpiece"
#define SND_USE_CASE_DEV_SPDIF_HEADSET "SPDIF Headphones"
#define SND_USE_CASE_DEV_SPDIF_ANC_HEADSET "SPDIF ANC Headset"
@@ -304,20 +269,11 @@
#define SND_USE_CASE_MOD_CAPTURE_VOIP "Capture VOIP"
#define SND_USE_CASE_MOD_CAPTURE_VOICE_DL "Capture Voice Downlink"
#define SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL "Capture Voice Uplink Downlink"
-#define SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_DL "Capture Compressed Voice DL"
-#define SND_USE_CASE_MOD_CAPTURE_COMPRESSED_VOICE_UL_DL "Capture Compressed Voice UL DL"
#define SND_USE_CASE_MOD_PLAY_TUNNEL "Play Tunnel"
#define SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC "Play Lowlatency Music"
#define SND_USE_CASE_MOD_PLAY_MUSIC2 "Play Music2"
#define SND_USE_CASE_MOD_PLAY_MI2S "Play MI2S"
#define SND_USE_CASE_MOD_PLAY_VOLTE "Play VoLTE"
-#define SND_USE_CASE_MOD_CAPTURE_MUSIC2 "Capture Music2"
-#define SND_USE_CASE_MOD_CAPTURE_MUSIC_COMPRESSED "Capture Music Compressed"
-#define SND_USE_CASE_MOD_PLAY_MUSIC3 "Play Music3"
-#define SND_USE_CASE_MOD_PLAY_TUNNEL1 "Play Tunnel1"
-#define SND_USE_CASE_MOD_PLAY_TUNNEL2 "Play Tunnel2"
-#define SND_USE_CASE_MOD_PSEUDO_TUNNEL "Pseudo Tunnel"
-
/* List utility functions for maintaining enabled devices and modifiers */
static int snd_ucm_add_ident_to_list(struct snd_ucm_ident_node **head, const char *value);
@@ -346,7 +302,6 @@
static int snd_ucm_extract_name(char *buf, char **case_name);
static int snd_ucm_extract_acdb(char *buf, int *id, int *cap);
static int snd_ucm_extract_effects_mixer_ctl(char *buf, char **mixer_name);
-static int snd_ucm_extract_ec_ref_rx_mixer_ctl(char *buf, char **mixer_name);
static int snd_ucm_extract_dev_name(char *buf, char **dev_name);
static int snd_ucm_extract_controls(char *buf, mixer_control_t **mixer_list, int count);
static int snd_ucm_print(snd_use_case_mgr_t *uc_mgr);